From abc332923d7edcd49a79b0483e47adc2ad57a67e Mon Sep 17 00:00:00 2001
From: Volker Schukai <volker.schukai@schukai.com>
Date: Wed, 31 Jul 2024 11:35:06 +0200
Subject: [PATCH] fix: improvement of the tree menu to avoid recursion. #230

---
 .idea/misc.xml                              |    2 +-
 CHANGELOG.md                                |    3 +-
 development/config/import.mjs               |    4 +-
 development/issues/closed/230.html          |   52 +
 development/issues/closed/230.mjs           |   19 +
 development/issues/open/229.html            |   24 +
 development/issues/open/229.mjs             |   15 +
 development/mock/issue-230.js               | 1285 +++++++++++++++++++
 development/mockoon/issues.json             |   85 ++
 flake.lock                                  |    6 +-
 nix/config/release.nix                      |    2 +-
 nix/scripts/go-task.nix                     |   12 +
 nix/scripts/start-server.nix                |    3 +-
 package.json                                |    3 +-
 source/components/datatable/save-button.mjs |  526 ++++----
 source/components/form/button.mjs           |    1 -
 source/components/form/select.mjs           |  116 +-
 source/components/tree-menu/tree-menu.mjs   |    4 +-
 source/data/buildtree.mjs                   |  121 +-
 source/types/node.mjs                       |  278 ++--
 test/cases/data/buildtree.mjs               |   49 +
 test/cases/dom/resource/data.mjs            |    2 +-
 test/cases/dom/resource/link.mjs            |    2 +-
 test/cases/dom/resource/link/stylesheet.mjs |    2 +-
 test/cases/dom/resource/script.mjs          |    2 +-
 25 files changed, 2064 insertions(+), 554 deletions(-)
 create mode 100644 development/issues/closed/230.html
 create mode 100644 development/issues/closed/230.mjs
 create mode 100644 development/issues/open/229.html
 create mode 100644 development/issues/open/229.mjs
 create mode 100644 development/mock/issue-230.js
 create mode 100644 development/mockoon/issues.json

diff --git a/.idea/misc.xml b/.idea/misc.xml
index 4ff1fd4bd..0b42db999 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
-  <component name="ProjectRootManager">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_22" project-jdk-name="17 (2)" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/out" />
   </component>
   <component name="accountSettings">
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7a63cf5f9..51b25a2f6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,12 +1,11 @@
 # Changelog
 
 
-
 ## [3.73.5] - 2024-07-02
 
 ### Bug Fixes
 
-- originValues in the savebutton is now reset.
+- originValues in the save button is now reset.
 
 ## [3.73.4] - 2024-07-02
 
diff --git a/development/config/import.mjs b/development/config/import.mjs
index ebf1f2425..8de0f078e 100644
--- a/development/config/import.mjs
+++ b/development/config/import.mjs
@@ -1,8 +1,8 @@
 export const projectRoot = "/home/vs/workspaces/oss/monster/monster";
 export const sourcePath = "/home/vs/workspaces/oss/monster/monster/source";
 export const developmentPath = "/home/vs/workspaces/oss/monster/monster/development";
-export const pnpxBin = "/nix/store/r9h39llf5vwzmyj2mdqdx790ssggwlzb-pnpm-8.15.5/bin/pnpx";
-export const nodeBin = "/nix/store/6ridy27nr6drh8qqpsm2fj3879xr6yib-nodejs-20.12.2/bin/node";
+export const pnpxBin = "/nix/store/p77wj35xjj2ay96bsg4s916lyaa6jxrv-pnpm-8.15.5/bin/pnpx";
+export const nodeBin = "/nix/store/9cwyl546mzksfbvk6gdpjddc7z7m6ixv-nodejs-20.15.1/bin/node";
 export const license = "/**" + "\n" +
     " * Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved." + "\n" +
     " * Node module: @schukai/monster" + "\n" +
diff --git a/development/issues/closed/230.html b/development/issues/closed/230.html
new file mode 100644
index 000000000..253319aa2
--- /dev/null
+++ b/development/issues/closed/230.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>optimize tree-menu #230</title>
+    <script src="./230.mjs" type="module"></script>
+</head>
+<body>
+    <h1>optimize tree-menu #230</h1>
+    <p>The tree menu is displaying an error in the blueprint. This should be investigated and optimized if necessary.</p>
+    <ul>
+        <li><a href="https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/230">Issue #230</a></li>
+        <li><a href="/">Back to overview</a></li>
+    </ul>
+    <main>
+
+        <monster-datasource-rest id="menu-rest" data-monster-option-read-path="dataset" data-monster-option-features-autoinit="true" data-monster-option-read-url="/issue-230.json">
+        </monster-datasource-rest>
+
+        <monster-tree-menu id="main-menu" data-monster-option-mapping-idtemplate="id" data-monster-option-mapping-parentkey="parent_id" data-monster-option-mapping-labeltemplate="${title}" data-monster-option-mapping-valuetemplate="${path:url | tostring}" data-monster-option-mapping-icontemplate="${path:icon | default:default}" data-monster-option-datasource-selector="#menu-rest" value="">
+
+            <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
+                <symbol id="box" viewBox="0 0 16 16">
+                    <path d="M6 9a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3A.5.5 0 0 1 6 9M3.854 4.146a.5.5 0 1 0-.708.708L4.793 6.5 3.146 8.146a.5.5 0 1 0 .708.708l2-2a.5.5 0 0 0 0-.708z"></path>
+                    <path d="M2 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm12 1a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1z"></path>
+                </symbol>
+
+                <symbol id="default" viewBox="0 0 16 16">
+                    <path d="M11 2a3 3 0 0 1 3 3v6a3 3 0 0 1-3 3H5a3 3 0 0 1-3-3V5a3 3 0 0 1 3-3zM5 1a4 4 0 0 0-4 4v6a4 4 0 0 0 4 4h6a4 4 0 0 0 4-4V5a4 4 0 0 0-4-4z"></path>
+                </symbol>
+
+                <symbol id="balloon" viewBox="0 0 16 16">
+                    <path d="M8 9.984C10.403 9.506 12 7.48 12 5a4 4 0 0 0-8 0c0 2.48 1.597 4.506 4 4.984M13 5c0 2.837-1.789 5.227-4.52 5.901l.244.487a.25.25 0 1 1-.448.224l-.008-.017c.008.11.02.202.037.29.054.27.161.488.419 1.003.288.578.235 1.15.076 1.629-.157.469-.422.867-.588 1.115l-.004.007a.25.25 0 1 1-.416-.278c.168-.252.4-.6.533-1.003.133-.396.163-.824-.049-1.246l-.013-.028c-.24-.48-.38-.758-.448-1.102a3 3 0 0 1-.052-.45l-.04.08a.25.25 0 1 1-.447-.224l.244-.487C4.789 10.227 3 7.837 3 5a5 5 0 0 1 10 0m-6.938-.495a2 2 0 0 1 1.443-1.443C7.773 2.994 8 2.776 8 2.5s-.226-.504-.498-.459a3 3 0 0 0-2.46 2.461c-.046.272.182.498.458.498s.494-.227.562-.495"></path>
+                </symbol>
+
+                <symbol id="cart" viewBox="0 0 16 16">
+                    <path d="M8 1a2.5 2.5 0 0 1 2.5 2.5V4h-5v-.5A2.5 2.5 0 0 1 8 1m3.5 3v-.5a3.5 3.5 0 1 0-7 0V4H1v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4zM2 5h12v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1z"></path>
+                </symbol>
+
+                <symbol id="box2" viewBox="0 0 16 16">
+                    <path d="M8 7.982C9.664 6.309 13.825 9.236 8 13 2.175 9.236 6.336 6.31 8 7.982"></path>
+                    <path d="M3.75 0a1 1 0 0 0-.8.4L.1 4.2a.5.5 0 0 0-.1.3V15a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1V4.5a.5.5 0 0 0-.1-.3L13.05.4a1 1 0 0 0-.8-.4zm0 1H7.5v3h-6zM8.5 4V1h3.75l2.25 3zM15 5v10H1V5z"></path>
+                </symbol>
+
+
+            </svg>
+        </monster-tree-menu>
+
+    </main>
+</body>
+</html>
diff --git a/development/issues/closed/230.mjs b/development/issues/closed/230.mjs
new file mode 100644
index 000000000..4ac5fea91
--- /dev/null
+++ b/development/issues/closed/230.mjs
@@ -0,0 +1,19 @@
+/**
+* @file development/issues/open/230.mjs
+* @url https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/230
+* @description optimize tree-menu
+* @issue 230
+*/
+
+import "../../../source/components/style/property.pcss";
+import "../../../source/components/style/link.pcss";
+import "../../../source/components/style/color.pcss";
+import "../../../source/components/style/theme.pcss";
+import "../../../source/components/style/normalize.pcss";
+import "../../../source/components/style/typography.pcss";
+import "../../../source/components/tree-menu/tree-menu.mjs";
+import "../../../source/components/layout/split-panel.mjs";
+import "../../../source/components/layout/panel.mjs";
+import "../../../source/components/datatable/datasource/dom.mjs";
+import "../../../source/components/datatable/datasource/rest.mjs";
+
diff --git a/development/issues/open/229.html b/development/issues/open/229.html
new file mode 100644
index 000000000..374f881f5
--- /dev/null
+++ b/development/issues/open/229.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>select's performance seems to be slow for many entries #229</title>
+    <script src="./229.mjs" type="module"></script>
+</head>
+<body>
+    <h1>select's performance seems to be slow for many entries #229</h1>
+    <p></p>
+    <ul>
+        <li><a href="https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/229">Issue #229</a></li>
+        <li><a href="/">Back to overview</a></li>
+    </ul>
+    <main>
+
+          <monster-select>
+              <monster-option value="1">Option 1</monster-option>
+          </monster-select>
+
+    </main>
+</body>
+</html>
diff --git a/development/issues/open/229.mjs b/development/issues/open/229.mjs
new file mode 100644
index 000000000..534a76530
--- /dev/null
+++ b/development/issues/open/229.mjs
@@ -0,0 +1,15 @@
+/**
+* @file development/issues/open/229.mjs
+* @url https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/229
+* @description select's performance seems to be slow for many entries
+* @issue 229
+*/
+
+import "../../../source/components/style/property.pcss";
+import "../../../source/components/style/link.pcss";
+import "../../../source/components/style/color.pcss";
+import "../../../source/components/style/theme.pcss";
+import "../../../source/components/style/normalize.pcss";
+import "../../../source/components/style/typography.pcss";
+import "../../../source/components/form/select.mjs";
+
diff --git a/development/mock/issue-230.js b/development/mock/issue-230.js
new file mode 100644
index 000000000..76714826b
--- /dev/null
+++ b/development/mock/issue-230.js
@@ -0,0 +1,1285 @@
+const json = 
+    `{
+    "dataset": [
+        {
+            "id": 100001,
+            "parent_id": 200001,
+            "title": "eBay",
+            "url": "/",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 100001,
+            "parent_id": 200001,
+            "title": "alvineconsole",
+            "url": "",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 100466,
+            "parent_id": 200466,
+            "title": "countries",
+            "url": "/alvine/?cmd=466",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 101023,
+            "parent_id": 201023,
+            "title": "itemlist",
+            "url": "/alvine/?cmd=1023",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 101100,
+            "parent_id": 205111,
+            "title": "published",
+            "url": "/alvine/?cmd=1100",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 101400,
+            "parent_id": 201400,
+            "title": "album",
+            "url": "/alvine/?cmd=1400",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 105059,
+            "parent_id": 205059,
+            "title": "pluginlocale",
+            "url": "/alvine/?cmd=5059",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 105064,
+            "parent_id": 205064,
+            "title": "pluginlocale",
+            "url": "/alvine/?cmd=5064",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 105111,
+            "parent_id": 205111,
+            "title": "pages",
+            "url": "/",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108019,
+            "parent_id": 208019,
+            "title": "datev",
+            "url": "/alvine/?cmd=8019",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108023,
+            "parent_id": 308023,
+            "title": "deliveries",
+            "url": "/alvine/?cmd=8023",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108113,
+            "parent_id": 208124,
+            "title": "brands",
+            "url": "/alvine/?cmd=8113",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109211,
+            "parent_id": 209211,
+            "title": "avises",
+            "url": "/alvine/?cmd=9211",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109221,
+            "parent_id": 209221,
+            "title": "retoure",
+            "url": "/alvine/?cmd=9221",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109231,
+            "parent_id": 209231,
+            "title": "partner",
+            "url": "/alvine/?cmd=9231",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 126012,
+            "parent_id": 226012,
+            "title": "productexport",
+            "url": "/alvine/?cmd=26012",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 126036,
+            "parent_id": 226036,
+            "title": "productimport",
+            "url": "/alvine/?cmd=26036",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 128006,
+            "parent_id": 228006,
+            "title": "salesstatistic",
+            "url": "/alvine/?cmd=28006",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 140017,
+            "parent_id": 226036,
+            "title": "importfilter",
+            "url": "/alvine/?cmd=40017",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 141024,
+            "parent_id": 241024,
+            "title": "dailystatementaction",
+            "url": "/alvine/?cmd=41024",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 151001,
+            "parent_id": 251001,
+            "title": "dunning",
+            "url": "/alvine/?cmd=51001",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 200001,
+            "parent_id": 200000,
+            "title": "developer",
+            "url": "",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 208124,
+            "parent_id": 201023,
+            "title": "catalog",
+            "url": "/",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 209221,
+            "parent_id": 209211,
+            "title": "retoure",
+            "url": "/",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 226036,
+            "parent_id": 2026036,
+            "title": "import",
+            "url": "/",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 241024,
+            "parent_id": 208023,
+            "title": "dailystatement",
+            "url": "",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 300001,
+            "parent_id": 200466,
+            "title": "taskstream",
+            "url": "/apps/commerce/task-stream",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 308023,
+            "parent_id": 208023,
+            "title": "deliveries",
+            "url": "/apps/commerce/delivery-list",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 50039,
+            "parent_id": 226036,
+            "title": "userimport",
+            "url": "/alvine/?cmd=50039",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 100002,
+            "parent_id": 200001,
+            "title": "Amazon",
+            "url": "/",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 100002,
+            "parent_id": 200001,
+            "title": "alvineframework",
+            "url": "",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 100220,
+            "parent_id": 300125,
+            "title": "tickets",
+            "url": "/alvine/?cmd=220",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 101053,
+            "parent_id": 201400,
+            "title": "article",
+            "url": "/alvine/?cmd=1053",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 105075,
+            "parent_id": 205059,
+            "title": "systemlocale",
+            "url": "/alvine/?cmd=5075",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 105076,
+            "parent_id": 205064,
+            "title": "systemlocale",
+            "url": "/alvine/?cmd=5076",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 105077,
+            "parent_id": 205111,
+            "title": "clearcache",
+            "url": "/alvine/?cmd=5077",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108003,
+            "parent_id": 308004,
+            "title": "Orders search",
+            "url": "/alvine/?cmd=8003",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108004,
+            "parent_id": 308004,
+            "title": "orders",
+            "url": "/alvine/?cmd=8004",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108047,
+            "parent_id": 308023,
+            "title": "deliveryresubmission",
+            "url": "/alvine/?cmd=8047",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108064,
+            "parent_id": 209211,
+            "title": "avisescan",
+            "url": "/alvine/?cmd=8064",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109010,
+            "parent_id": 208124,
+            "title": "department",
+            "url": "/alvine/?cmd=9010",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109037,
+            "parent_id": 209221,
+            "title": "retouredailystatementaction",
+            "url": "/alvine/?cmd=9037",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109101,
+            "parent_id": 228006,
+            "title": "itemsalesstatistic",
+            "url": "/alvine/?cmd=9101",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109700,
+            "parent_id": 308004,
+            "title": "visual check",
+            "url": "/alvine/?cmd=9700",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 122002,
+            "parent_id": 209231,
+            "title": "voucher",
+            "url": "/alvine/?cmd=22002",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 126001,
+            "parent_id": 200466,
+            "title": "payments",
+            "url": "/alvine/?cmd=26001",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 131531,
+            "parent_id": 201023,
+            "title": "storageposition",
+            "url": "/alvine/?cmd=31531",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 141002,
+            "parent_id": 241024,
+            "title": "importdhlpaketfile",
+            "url": "/alvine/?cmd=41024",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 150038,
+            "parent_id": 226012,
+            "title": "userexport",
+            "url": "/alvine/?cmd=50039",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 151023,
+            "parent_id": 208019,
+            "title": "datevopos",
+            "url": "/alvine/?cmd=51023",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 208019,
+            "parent_id": 251001,
+            "title": "datev",
+            "url": "/",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 226012,
+            "parent_id": 2026036,
+            "title": "export",
+            "url": "/",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 301053,
+            "parent_id": 201400,
+            "title": "article",
+            "url": "/apps/commerce/article-list",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 308004,
+            "parent_id": 0,
+            "title": "orders",
+            "url": "/apps/commerce/order-list",
+            "weight": 2,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 100003,
+            "parent_id": 200001,
+            "title": "alvinebootstrap",
+            "url": "",
+            "weight": 3,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 100125,
+            "parent_id": 300125,
+            "title": "customers",
+            "url": "/alvine/?cmd=125",
+            "weight": 3,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 100600,
+            "parent_id": 209231,
+            "title": "serialletter",
+            "url": "/alvine/?cmd=600",
+            "weight": 3,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 101073,
+            "parent_id": 201400,
+            "title": "listofdates",
+            "url": "/alvine/?cmd=1073",
+            "weight": 3,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 105049,
+            "parent_id": 205111,
+            "title": "textandimages",
+            "url": "/alvine/?cmd=5049",
+            "weight": 3,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108007,
+            "parent_id": 308004,
+            "title": "Orders backtemplate",
+            "url": "/alvine/?cmd=8007",
+            "weight": 3,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108124,
+            "parent_id": 208124,
+            "title": "colors",
+            "url": "/alvine/?cmd=8124",
+            "weight": 3,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108210,
+            "parent_id": 308023,
+            "title": "picklists",
+            "url": "/alvine/?cmd=8210",
+            "weight": 3,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109076,
+            "parent_id": 226012,
+            "title": "categoryexport",
+            "url": "/alvine/?cmd=9076",
+            "weight": 3,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109077,
+            "parent_id": 226036,
+            "title": "categoryimport",
+            "url": "/alvine/?cmd=9077",
+            "weight": 3,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109201,
+            "parent_id": 209211,
+            "title": "deliveries",
+            "url": "/alvine/?cmd=9201",
+            "weight": 3,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 124013,
+            "parent_id": 300125,
+            "title": "customerblacklist",
+            "url": "/alvine/?cmd=24013",
+            "weight": 3,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 128003,
+            "parent_id": 228006,
+            "title": "transactions",
+            "url": "/alvine/?cmd=28003",
+            "weight": 3,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 141006,
+            "parent_id": 200466,
+            "title": "deliveryconditions",
+            "url": "/alvine/?cmd=41006",
+            "weight": 3,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 201400,
+            "parent_id": 205111,
+            "title": "contenttypes",
+            "url": "/",
+            "weight": 3,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 300125,
+            "parent_id": 0,
+            "title": "customers",
+            "url": "/apps/commerce/user-list",
+            "weight": 3,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 100004,
+            "parent_id": 200001,
+            "title": "alvinejQuery",
+            "url": "",
+            "weight": 4,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 100117,
+            "parent_id": 300125,
+            "title": "groups",
+            "url": "/alvine/?cmd=117",
+            "weight": 4,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 100320,
+            "parent_id": 209231,
+            "title": "blacklist",
+            "url": "/alvine/?cmd=320",
+            "weight": 4,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 100487,
+            "parent_id": 205111,
+            "title": "mailtemplates",
+            "url": "/alvine/?cmd=487",
+            "weight": 4,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 101153,
+            "parent_id": 201400,
+            "title": "yellowpages",
+            "url": "/alvine/?cmd=1153",
+            "weight": 4,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108073,
+            "parent_id": 308004,
+            "title": "Incoming Payment",
+            "url": "/alvine/?cmd=8073",
+            "weight": 4,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108135,
+            "parent_id": 200466,
+            "title": "ordercondition",
+            "url": "/alvine/?cmd=8135",
+            "weight": 4,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108157,
+            "parent_id": 201023,
+            "title": "billofmaterial",
+            "url": "/alvine/?cmd=8157",
+            "weight": 4,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108218,
+            "parent_id": 208023,
+            "title": "scanpicklist",
+            "url": "/alvine/?cmd=8218",
+            "weight": 4,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108218,
+            "parent_id": 308023,
+            "title": "scanpicklist",
+            "url": "/alvine/?cmd=8218",
+            "weight": 4,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109076,
+            "parent_id": 226012,
+            "title": "colorexport",
+            "url": "/alvine/?cmd=9076",
+            "weight": 4,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109077,
+            "parent_id": 226036,
+            "title": "colorimport",
+            "url": "/alvine/?cmd=9077",
+            "weight": 4,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109102,
+            "parent_id": 228006,
+            "title": "salesperpassword",
+            "url": "/alvine/?cmd=9102",
+            "weight": 4,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109119,
+            "parent_id": 208124,
+            "title": "raster",
+            "url": "/alvine/?cmd=9119",
+            "weight": 4,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 141005,
+            "parent_id": 241024,
+            "title": "importglspaketfile",
+            "url": "/alvine/?cmd=41005",
+            "weight": 4,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 209231,
+            "parent_id": 0,
+            "title": "marketing",
+            "url": "/alvine/?cmd=209231",
+            "weight": 4,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 101185,
+            "parent_id": 201400,
+            "title": "files",
+            "url": "/alvine/?cmd=1185",
+            "weight": 5,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 105022,
+            "parent_id": 205111,
+            "title": "templateversion",
+            "url": "/alvine/?cmd=5022",
+            "weight": 5,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 105141,
+            "parent_id": 205111,
+            "title": "metadata",
+            "url": "/alvine/?cmd=5141",
+            "weight": 5,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109025,
+            "parent_id": 201023,
+            "title": "variants",
+            "url": "/alvine/?cmd=9025",
+            "weight": 5,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109056,
+            "parent_id": 228006,
+            "title": "inventorylist",
+            "url": "/alvine/?cmd=9056",
+            "weight": 5,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109076,
+            "parent_id": 226012,
+            "title": "stylesexport",
+            "url": "/alvine/?cmd=9076",
+            "weight": 5,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109077,
+            "parent_id": 226036,
+            "title": "stylesimport",
+            "url": "/alvine/?cmd=9077",
+            "weight": 5,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109081,
+            "parent_id": 208124,
+            "title": "style",
+            "url": "/alvine/?cmd=9081",
+            "weight": 5,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 110000,
+            "parent_id": 200466,
+            "title": "shoppingcartconditions",
+            "url": "/alvine/?cmd=10000",
+            "weight": 5,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 114000,
+            "parent_id": 308004,
+            "title": "offers",
+            "url": "/alvine/?cmd=14000",
+            "weight": 5,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 126038,
+            "parent_id": 300125,
+            "title": "customerrating",
+            "url": "/alvine/?cmd=26038",
+            "weight": 5,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 150040,
+            "parent_id": 209231,
+            "title": "campaign",
+            "url": "/alvine/?cmd=50040",
+            "weight": 5,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 200001,
+            "parent_id": 0,
+            "title": "distributionchannels",
+            "url": "/",
+            "weight": 5,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 100113,
+            "parent_id": 205111,
+            "title": "calendar",
+            "url": "/alvine/?cmd=113",
+            "weight": 6,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 100330,
+            "parent_id": 209231,
+            "title": "marketingaddresses",
+            "url": "/alvine/?cmd=330",
+            "weight": 6,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 101142,
+            "parent_id": 201400,
+            "title": "faq",
+            "url": "/alvine/?cmd=1142",
+            "weight": 6,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108181,
+            "parent_id": 300125,
+            "title": "favouriteslist",
+            "url": "/alvine/?cmd=8181",
+            "weight": 6,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109050,
+            "parent_id": 228006,
+            "title": "inventoryreport",
+            "url": "/alvine/?cmd=9050",
+            "weight": 6,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109130,
+            "parent_id": 208124,
+            "title": "material",
+            "url": "/alvine/?cmd=9130",
+            "weight": 6,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 131500,
+            "parent_id": 200466,
+            "title": "storeposition",
+            "url": "/alvine/?cmd=31500",
+            "weight": 6,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 131600,
+            "parent_id": 308004,
+            "title": "orderrulesets",
+            "url": "/alvine/?cmd=31600",
+            "weight": 6,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 141028,
+            "parent_id": 241024,
+            "title": "importdpdpaketfile",
+            "url": "/alvine/?cmd=41028",
+            "weight": 6,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 150053,
+            "parent_id": 226012,
+            "title": "marketingadressexport",
+            "url": "/alvine/?cmd=50053",
+            "weight": 6,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 150054,
+            "parent_id": 226036,
+            "title": "marketingadressimport",
+            "url": "/alvine/?cmd=50054",
+            "weight": 6,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 201023,
+            "parent_id": 0,
+            "title": "products",
+            "url": "/",
+            "weight": 6,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 101131,
+            "parent_id": 200466,
+            "title": "objecttargets",
+            "url": "/alvine/?cmd=1131",
+            "weight": 7,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 101174,
+            "parent_id": 201400,
+            "title": "jobadvertisements",
+            "url": "/alvine/?cmd=1174",
+            "weight": 7,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 108053,
+            "parent_id": 208124,
+            "title": "collection",
+            "url": "/alvine/?cmd=8053",
+            "weight": 7,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109058,
+            "parent_id": 201023,
+            "title": "categories",
+            "url": "/alvine/?cmd=9058",
+            "weight": 7,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 205059,
+            "parent_id": 226012,
+            "title": "localeexport",
+            "url": "/",
+            "weight": 7,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 205064,
+            "parent_id": 226036,
+            "title": "localeimport",
+            "url": "/",
+            "weight": 7,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 208023,
+            "parent_id": 0,
+            "title": "outgoinggoods",
+            "url": "",
+            "weight": 7,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 126013,
+            "parent_id": 208124,
+            "title": "season",
+            "url": "/alvine/?cmd=26013",
+            "weight": 8,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 126035,
+            "parent_id": 201023,
+            "title": "bulkactions",
+            "url": "/alvine/?cmd=26035",
+            "weight": 8,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 131520,
+            "parent_id": 200466,
+            "title": "storelocations",
+            "url": "/alvine/?cmd=31520",
+            "weight": 8,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 209211,
+            "parent_id": 0,
+            "title": "incominggoods",
+            "url": "/",
+            "weight": 8,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 100386,
+            "parent_id": 200466,
+            "title": "client",
+            "url": "/alvine/?cmd=386",
+            "weight": 9,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109258,
+            "parent_id": 208124,
+            "title": "assignment1",
+            "url": "/alvine/?cmd=9258",
+            "weight": 9,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 110000,
+            "parent_id": 201023,
+            "title": "conditions",
+            "url": "/alvine/?cmd=10000",
+            "weight": 9,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 251001,
+            "parent_id": 0,
+            "title": "finances",
+            "url": "/",
+            "weight": 9,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109269,
+            "parent_id": 208124,
+            "title": "assignment2",
+            "url": "/alvine/?cmd=9269",
+            "weight": 10,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 109310,
+            "parent_id": 208124,
+            "title": "assignment3",
+            "url": "/alvine/?cmd=9310",
+            "weight": 10,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 120008,
+            "parent_id": 200466,
+            "title": "pricelists",
+            "url": "/alvine/?cmd=20008",
+            "weight": 10,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 228006,
+            "parent_id": 0,
+            "title": "reports",
+            "url": "/",
+            "weight": 10,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 100350,
+            "parent_id": 200466,
+            "title": "objectproperties",
+            "url": "/alvine/?cmd=350",
+            "weight": 11,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 205111,
+            "parent_id": 0,
+            "title": "contentmanagement",
+            "url": "/",
+            "weight": 11,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 2026036,
+            "parent_id": 0,
+            "title": "importexport",
+            "url": "/",
+            "weight": 12,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 200466,
+            "parent_id": 0,
+            "title": "settings",
+            "url": "/",
+            "weight": 13,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 200000,
+            "parent_id": 0,
+            "title": "documentation",
+            "url": "",
+            "weight": 14,
+            "css_styles": "",
+            "css_classes": ""
+        }
+    ],
+    "sys": {
+        "code": 200,
+        "result": {},
+        "api_version": "1"
+    }
+}`;
+
+
+// check if json is valid
+JSON.parse(json)
+
+const json400Error=`[
+                {
+                    "sys": {
+                        "type": "Error",
+                        "message": "Invalid request"
+                    }
+                }
+            ]`
+
+// check if json is valid
+JSON.parse(json400Error)
+
+
+const json200Error=`[
+                {
+                    "sys": {
+                        "type": "Error",
+                        "message": "Invalid request"
+                    }
+                }
+            ]`
+
+// check if json is valid
+JSON.parse(json200Error)
+
+export default [
+    {
+        url: '/issue-230.json',
+        method: 'get',
+        rawResponse: async (req, res) => {
+            res.setHeader('Content-Type', 'application/json')
+            res.statusCode = 200
+
+            setTimeout(function() {
+                res.end(json)
+            }, 10);
+        },
+    },
+
+    {
+        url: '/issue-230',
+        method: 'post',
+        rawResponse: async (req, res) => {
+            res.setHeader('Content-Type', 'application/json')
+            res.statusCode = 400
+
+            setTimeout(function() {
+                res.end(json400Error)
+            }, 10);
+        },
+    }
+
+  
+
+];
\ No newline at end of file
diff --git a/development/mockoon/issues.json b/development/mockoon/issues.json
new file mode 100644
index 000000000..f256f2a09
--- /dev/null
+++ b/development/mockoon/issues.json
@@ -0,0 +1,85 @@
+{
+  "uuid": "66fb8768-0d50-484e-a3bc-1a251bb1fb59",
+  "lastMigration": 32,
+  "name": "Issues",
+  "endpointPrefix": "",
+  "latency": 0,
+  "port": 3000,
+  "hostname": "",
+  "folders": [],
+  "routes": [
+    {
+      "uuid": "d9f0436c-e07a-4967-bf5a-7d15ef2f5f74",
+      "type": "http",
+      "documentation": "",
+      "method": "get",
+      "endpoint": "navigation",
+      "responses": [
+        {
+          "uuid": "bcdb940b-184c-4ba5-a6ab-bf082d1f4c99",
+          "body": "{\n    \"dataset\": [\n        {\n            \"id\": 100001,\n            \"parent_id\": 200001,\n            \"title\": \"eBay\",\n            \"url\": \"/\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 100001,\n            \"parent_id\": 200001,\n            \"title\": \"alvineconsole\",\n            \"url\": \"\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 100466,\n            \"parent_id\": 200466,\n            \"title\": \"countries\",\n            \"url\": \"/alvine/?cmd=466\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 101023,\n            \"parent_id\": 201023,\n            \"title\": \"itemlist\",\n            \"url\": \"/alvine/?cmd=1023\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 101100,\n            \"parent_id\": 205111,\n            \"title\": \"published\",\n            \"url\": \"/alvine/?cmd=1100\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 101400,\n            \"parent_id\": 201400,\n            \"title\": \"album\",\n            \"url\": \"/alvine/?cmd=1400\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 105059,\n            \"parent_id\": 205059,\n            \"title\": \"pluginlocale\",\n            \"url\": \"/alvine/?cmd=5059\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 105064,\n            \"parent_id\": 205064,\n            \"title\": \"pluginlocale\",\n            \"url\": \"/alvine/?cmd=5064\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 105111,\n            \"parent_id\": 205111,\n            \"title\": \"pages\",\n            \"url\": \"/\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108019,\n            \"parent_id\": 208019,\n            \"title\": \"datev\",\n            \"url\": \"/alvine/?cmd=8019\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108023,\n            \"parent_id\": 308023,\n            \"title\": \"deliveries\",\n            \"url\": \"/alvine/?cmd=8023\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108113,\n            \"parent_id\": 208124,\n            \"title\": \"brands\",\n            \"url\": \"/alvine/?cmd=8113\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109211,\n            \"parent_id\": 209211,\n            \"title\": \"avises\",\n            \"url\": \"/alvine/?cmd=9211\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109221,\n            \"parent_id\": 209221,\n            \"title\": \"retoure\",\n            \"url\": \"/alvine/?cmd=9221\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109231,\n            \"parent_id\": 209231,\n            \"title\": \"partner\",\n            \"url\": \"/alvine/?cmd=9231\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 126012,\n            \"parent_id\": 226012,\n            \"title\": \"productexport\",\n            \"url\": \"/alvine/?cmd=26012\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 126036,\n            \"parent_id\": 226036,\n            \"title\": \"productimport\",\n            \"url\": \"/alvine/?cmd=26036\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 128006,\n            \"parent_id\": 228006,\n            \"title\": \"salesstatistic\",\n            \"url\": \"/alvine/?cmd=28006\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 140017,\n            \"parent_id\": 226036,\n            \"title\": \"importfilter\",\n            \"url\": \"/alvine/?cmd=40017\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 141024,\n            \"parent_id\": 241024,\n            \"title\": \"dailystatementaction\",\n            \"url\": \"/alvine/?cmd=41024\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 151001,\n            \"parent_id\": 251001,\n            \"title\": \"dunning\",\n            \"url\": \"/alvine/?cmd=51001\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 200001,\n            \"parent_id\": 200000,\n            \"title\": \"developer\",\n            \"url\": \"\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 208124,\n            \"parent_id\": 201023,\n            \"title\": \"catalog\",\n            \"url\": \"/\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 209221,\n            \"parent_id\": 209211,\n            \"title\": \"retoure\",\n            \"url\": \"/\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 226036,\n            \"parent_id\": 2026036,\n            \"title\": \"import\",\n            \"url\": \"/\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 241024,\n            \"parent_id\": 208023,\n            \"title\": \"dailystatement\",\n            \"url\": \"\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 300001,\n            \"parent_id\": 200466,\n            \"title\": \"taskstream\",\n            \"url\": \"/apps/commerce/task-stream\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 308023,\n            \"parent_id\": 208023,\n            \"title\": \"deliveries\",\n            \"url\": \"/apps/commerce/delivery-list\",\n            \"weight\": 1,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 0,\n            \"parent_id\": 0,\n            \"title\": \"Yes\",\n            \"url\": \"/apps/test\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 50039,\n            \"parent_id\": 226036,\n            \"title\": \"userimport\",\n            \"url\": \"/alvine/?cmd=50039\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 100002,\n            \"parent_id\": 200001,\n            \"title\": \"Amazon\",\n            \"url\": \"/\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 100002,\n            \"parent_id\": 200001,\n            \"title\": \"alvineframework\",\n            \"url\": \"\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 100220,\n            \"parent_id\": 300125,\n            \"title\": \"tickets\",\n            \"url\": \"/alvine/?cmd=220\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 101053,\n            \"parent_id\": 201400,\n            \"title\": \"article\",\n            \"url\": \"/alvine/?cmd=1053\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 105075,\n            \"parent_id\": 205059,\n            \"title\": \"systemlocale\",\n            \"url\": \"/alvine/?cmd=5075\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 105076,\n            \"parent_id\": 205064,\n            \"title\": \"systemlocale\",\n            \"url\": \"/alvine/?cmd=5076\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 105077,\n            \"parent_id\": 205111,\n            \"title\": \"clearcache\",\n            \"url\": \"/alvine/?cmd=5077\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108003,\n            \"parent_id\": 308004,\n            \"title\": \"Orders search\",\n            \"url\": \"/alvine/?cmd=8003\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108004,\n            \"parent_id\": 308004,\n            \"title\": \"orders\",\n            \"url\": \"/alvine/?cmd=8004\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108047,\n            \"parent_id\": 308023,\n            \"title\": \"deliveryresubmission\",\n            \"url\": \"/alvine/?cmd=8047\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108064,\n            \"parent_id\": 209211,\n            \"title\": \"avisescan\",\n            \"url\": \"/alvine/?cmd=8064\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109010,\n            \"parent_id\": 208124,\n            \"title\": \"department\",\n            \"url\": \"/alvine/?cmd=9010\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109037,\n            \"parent_id\": 209221,\n            \"title\": \"retouredailystatementaction\",\n            \"url\": \"/alvine/?cmd=9037\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109101,\n            \"parent_id\": 228006,\n            \"title\": \"itemsalesstatistic\",\n            \"url\": \"/alvine/?cmd=9101\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109700,\n            \"parent_id\": 308004,\n            \"title\": \"visual check\",\n            \"url\": \"/alvine/?cmd=9700\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 122002,\n            \"parent_id\": 209231,\n            \"title\": \"voucher\",\n            \"url\": \"/alvine/?cmd=22002\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 126001,\n            \"parent_id\": 200466,\n            \"title\": \"payments\",\n            \"url\": \"/alvine/?cmd=26001\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 131531,\n            \"parent_id\": 201023,\n            \"title\": \"storageposition\",\n            \"url\": \"/alvine/?cmd=31531\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 141002,\n            \"parent_id\": 241024,\n            \"title\": \"importdhlpaketfile\",\n            \"url\": \"/alvine/?cmd=41024\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 150038,\n            \"parent_id\": 226012,\n            \"title\": \"userexport\",\n            \"url\": \"/alvine/?cmd=50039\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 151023,\n            \"parent_id\": 208019,\n            \"title\": \"datevopos\",\n            \"url\": \"/alvine/?cmd=51023\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 208019,\n            \"parent_id\": 251001,\n            \"title\": \"datev\",\n            \"url\": \"/\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 226012,\n            \"parent_id\": 2026036,\n            \"title\": \"export\",\n            \"url\": \"/\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 301053,\n            \"parent_id\": 201400,\n            \"title\": \"article\",\n            \"url\": \"/apps/commerce/article-list\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 308004,\n            \"parent_id\": 0,\n            \"title\": \"orders\",\n            \"url\": \"/apps/commerce/order-list\",\n            \"weight\": 2,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 100003,\n            \"parent_id\": 200001,\n            \"title\": \"alvinebootstrap\",\n            \"url\": \"\",\n            \"weight\": 3,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 100125,\n            \"parent_id\": 300125,\n            \"title\": \"customers\",\n            \"url\": \"/alvine/?cmd=125\",\n            \"weight\": 3,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 100600,\n            \"parent_id\": 209231,\n            \"title\": \"serialletter\",\n            \"url\": \"/alvine/?cmd=600\",\n            \"weight\": 3,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 101073,\n            \"parent_id\": 201400,\n            \"title\": \"listofdates\",\n            \"url\": \"/alvine/?cmd=1073\",\n            \"weight\": 3,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 105049,\n            \"parent_id\": 205111,\n            \"title\": \"textandimages\",\n            \"url\": \"/alvine/?cmd=5049\",\n            \"weight\": 3,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108007,\n            \"parent_id\": 308004,\n            \"title\": \"Orders backtemplate\",\n            \"url\": \"/alvine/?cmd=8007\",\n            \"weight\": 3,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108124,\n            \"parent_id\": 208124,\n            \"title\": \"colors\",\n            \"url\": \"/alvine/?cmd=8124\",\n            \"weight\": 3,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108210,\n            \"parent_id\": 308023,\n            \"title\": \"picklists\",\n            \"url\": \"/alvine/?cmd=8210\",\n            \"weight\": 3,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109076,\n            \"parent_id\": 226012,\n            \"title\": \"categoryexport\",\n            \"url\": \"/alvine/?cmd=9076\",\n            \"weight\": 3,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109077,\n            \"parent_id\": 226036,\n            \"title\": \"categoryimport\",\n            \"url\": \"/alvine/?cmd=9077\",\n            \"weight\": 3,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109201,\n            \"parent_id\": 209211,\n            \"title\": \"deliveries\",\n            \"url\": \"/alvine/?cmd=9201\",\n            \"weight\": 3,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 124013,\n            \"parent_id\": 300125,\n            \"title\": \"customerblacklist\",\n            \"url\": \"/alvine/?cmd=24013\",\n            \"weight\": 3,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 128003,\n            \"parent_id\": 228006,\n            \"title\": \"transactions\",\n            \"url\": \"/alvine/?cmd=28003\",\n            \"weight\": 3,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 141006,\n            \"parent_id\": 200466,\n            \"title\": \"deliveryconditions\",\n            \"url\": \"/alvine/?cmd=41006\",\n            \"weight\": 3,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 201400,\n            \"parent_id\": 205111,\n            \"title\": \"contenttypes\",\n            \"url\": \"/\",\n            \"weight\": 3,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 300125,\n            \"parent_id\": 0,\n            \"title\": \"customers\",\n            \"url\": \"/apps/commerce/user-list\",\n            \"weight\": 3,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 100004,\n            \"parent_id\": 200001,\n            \"title\": \"alvinejQuery\",\n            \"url\": \"\",\n            \"weight\": 4,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 100117,\n            \"parent_id\": 300125,\n            \"title\": \"groups\",\n            \"url\": \"/alvine/?cmd=117\",\n            \"weight\": 4,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 100320,\n            \"parent_id\": 209231,\n            \"title\": \"blacklist\",\n            \"url\": \"/alvine/?cmd=320\",\n            \"weight\": 4,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 100487,\n            \"parent_id\": 205111,\n            \"title\": \"mailtemplates\",\n            \"url\": \"/alvine/?cmd=487\",\n            \"weight\": 4,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 101153,\n            \"parent_id\": 201400,\n            \"title\": \"yellowpages\",\n            \"url\": \"/alvine/?cmd=1153\",\n            \"weight\": 4,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108073,\n            \"parent_id\": 308004,\n            \"title\": \"Incoming Payment\",\n            \"url\": \"/alvine/?cmd=8073\",\n            \"weight\": 4,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108135,\n            \"parent_id\": 200466,\n            \"title\": \"ordercondition\",\n            \"url\": \"/alvine/?cmd=8135\",\n            \"weight\": 4,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108157,\n            \"parent_id\": 201023,\n            \"title\": \"billofmaterial\",\n            \"url\": \"/alvine/?cmd=8157\",\n            \"weight\": 4,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108218,\n            \"parent_id\": 208023,\n            \"title\": \"scanpicklist\",\n            \"url\": \"/alvine/?cmd=8218\",\n            \"weight\": 4,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108218,\n            \"parent_id\": 308023,\n            \"title\": \"scanpicklist\",\n            \"url\": \"/alvine/?cmd=8218\",\n            \"weight\": 4,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109076,\n            \"parent_id\": 226012,\n            \"title\": \"colorexport\",\n            \"url\": \"/alvine/?cmd=9076\",\n            \"weight\": 4,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109077,\n            \"parent_id\": 226036,\n            \"title\": \"colorimport\",\n            \"url\": \"/alvine/?cmd=9077\",\n            \"weight\": 4,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109102,\n            \"parent_id\": 228006,\n            \"title\": \"salesperpassword\",\n            \"url\": \"/alvine/?cmd=9102\",\n            \"weight\": 4,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109119,\n            \"parent_id\": 208124,\n            \"title\": \"raster\",\n            \"url\": \"/alvine/?cmd=9119\",\n            \"weight\": 4,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 141005,\n            \"parent_id\": 241024,\n            \"title\": \"importglspaketfile\",\n            \"url\": \"/alvine/?cmd=41005\",\n            \"weight\": 4,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 209231,\n            \"parent_id\": 0,\n            \"title\": \"marketing\",\n            \"url\": \"/alvine/?cmd=209231\",\n            \"weight\": 4,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 101185,\n            \"parent_id\": 201400,\n            \"title\": \"files\",\n            \"url\": \"/alvine/?cmd=1185\",\n            \"weight\": 5,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 105022,\n            \"parent_id\": 205111,\n            \"title\": \"templateversion\",\n            \"url\": \"/alvine/?cmd=5022\",\n            \"weight\": 5,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 105141,\n            \"parent_id\": 205111,\n            \"title\": \"metadata\",\n            \"url\": \"/alvine/?cmd=5141\",\n            \"weight\": 5,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109025,\n            \"parent_id\": 201023,\n            \"title\": \"variants\",\n            \"url\": \"/alvine/?cmd=9025\",\n            \"weight\": 5,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109056,\n            \"parent_id\": 228006,\n            \"title\": \"inventorylist\",\n            \"url\": \"/alvine/?cmd=9056\",\n            \"weight\": 5,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109076,\n            \"parent_id\": 226012,\n            \"title\": \"stylesexport\",\n            \"url\": \"/alvine/?cmd=9076\",\n            \"weight\": 5,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109077,\n            \"parent_id\": 226036,\n            \"title\": \"stylesimport\",\n            \"url\": \"/alvine/?cmd=9077\",\n            \"weight\": 5,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109081,\n            \"parent_id\": 208124,\n            \"title\": \"style\",\n            \"url\": \"/alvine/?cmd=9081\",\n            \"weight\": 5,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 110000,\n            \"parent_id\": 200466,\n            \"title\": \"shoppingcartconditions\",\n            \"url\": \"/alvine/?cmd=10000\",\n            \"weight\": 5,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 114000,\n            \"parent_id\": 308004,\n            \"title\": \"offers\",\n            \"url\": \"/alvine/?cmd=14000\",\n            \"weight\": 5,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 126038,\n            \"parent_id\": 300125,\n            \"title\": \"customerrating\",\n            \"url\": \"/alvine/?cmd=26038\",\n            \"weight\": 5,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 150040,\n            \"parent_id\": 209231,\n            \"title\": \"campaign\",\n            \"url\": \"/alvine/?cmd=50040\",\n            \"weight\": 5,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 200001,\n            \"parent_id\": 0,\n            \"title\": \"distributionchannels\",\n            \"url\": \"/\",\n            \"weight\": 5,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 100113,\n            \"parent_id\": 205111,\n            \"title\": \"calendar\",\n            \"url\": \"/alvine/?cmd=113\",\n            \"weight\": 6,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 100330,\n            \"parent_id\": 209231,\n            \"title\": \"marketingaddresses\",\n            \"url\": \"/alvine/?cmd=330\",\n            \"weight\": 6,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 101142,\n            \"parent_id\": 201400,\n            \"title\": \"faq\",\n            \"url\": \"/alvine/?cmd=1142\",\n            \"weight\": 6,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108181,\n            \"parent_id\": 300125,\n            \"title\": \"favouriteslist\",\n            \"url\": \"/alvine/?cmd=8181\",\n            \"weight\": 6,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109050,\n            \"parent_id\": 228006,\n            \"title\": \"inventoryreport\",\n            \"url\": \"/alvine/?cmd=9050\",\n            \"weight\": 6,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109130,\n            \"parent_id\": 208124,\n            \"title\": \"material\",\n            \"url\": \"/alvine/?cmd=9130\",\n            \"weight\": 6,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 131500,\n            \"parent_id\": 200466,\n            \"title\": \"storeposition\",\n            \"url\": \"/alvine/?cmd=31500\",\n            \"weight\": 6,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 131600,\n            \"parent_id\": 308004,\n            \"title\": \"orderrulesets\",\n            \"url\": \"/alvine/?cmd=31600\",\n            \"weight\": 6,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 141028,\n            \"parent_id\": 241024,\n            \"title\": \"importdpdpaketfile\",\n            \"url\": \"/alvine/?cmd=41028\",\n            \"weight\": 6,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 150053,\n            \"parent_id\": 226012,\n            \"title\": \"marketingadressexport\",\n            \"url\": \"/alvine/?cmd=50053\",\n            \"weight\": 6,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 150054,\n            \"parent_id\": 226036,\n            \"title\": \"marketingadressimport\",\n            \"url\": \"/alvine/?cmd=50054\",\n            \"weight\": 6,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 201023,\n            \"parent_id\": 0,\n            \"title\": \"products\",\n            \"url\": \"/\",\n            \"weight\": 6,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 101131,\n            \"parent_id\": 200466,\n            \"title\": \"objecttargets\",\n            \"url\": \"/alvine/?cmd=1131\",\n            \"weight\": 7,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 101174,\n            \"parent_id\": 201400,\n            \"title\": \"jobadvertisements\",\n            \"url\": \"/alvine/?cmd=1174\",\n            \"weight\": 7,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 108053,\n            \"parent_id\": 208124,\n            \"title\": \"collection\",\n            \"url\": \"/alvine/?cmd=8053\",\n            \"weight\": 7,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109058,\n            \"parent_id\": 201023,\n            \"title\": \"categories\",\n            \"url\": \"/alvine/?cmd=9058\",\n            \"weight\": 7,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 205059,\n            \"parent_id\": 226012,\n            \"title\": \"localeexport\",\n            \"url\": \"/\",\n            \"weight\": 7,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 205064,\n            \"parent_id\": 226036,\n            \"title\": \"localeimport\",\n            \"url\": \"/\",\n            \"weight\": 7,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 208023,\n            \"parent_id\": 0,\n            \"title\": \"outgoinggoods\",\n            \"url\": \"\",\n            \"weight\": 7,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 126013,\n            \"parent_id\": 208124,\n            \"title\": \"season\",\n            \"url\": \"/alvine/?cmd=26013\",\n            \"weight\": 8,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 126035,\n            \"parent_id\": 201023,\n            \"title\": \"bulkactions\",\n            \"url\": \"/alvine/?cmd=26035\",\n            \"weight\": 8,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 131520,\n            \"parent_id\": 200466,\n            \"title\": \"storelocations\",\n            \"url\": \"/alvine/?cmd=31520\",\n            \"weight\": 8,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 209211,\n            \"parent_id\": 0,\n            \"title\": \"incominggoods\",\n            \"url\": \"/\",\n            \"weight\": 8,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 100386,\n            \"parent_id\": 200466,\n            \"title\": \"client\",\n            \"url\": \"/alvine/?cmd=386\",\n            \"weight\": 9,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109258,\n            \"parent_id\": 208124,\n            \"title\": \"assignment1\",\n            \"url\": \"/alvine/?cmd=9258\",\n            \"weight\": 9,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 110000,\n            \"parent_id\": 201023,\n            \"title\": \"conditions\",\n            \"url\": \"/alvine/?cmd=10000\",\n            \"weight\": 9,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 251001,\n            \"parent_id\": 0,\n            \"title\": \"finances\",\n            \"url\": \"/\",\n            \"weight\": 9,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109269,\n            \"parent_id\": 208124,\n            \"title\": \"assignment2\",\n            \"url\": \"/alvine/?cmd=9269\",\n            \"weight\": 10,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 109310,\n            \"parent_id\": 208124,\n            \"title\": \"assignment3\",\n            \"url\": \"/alvine/?cmd=9310\",\n            \"weight\": 10,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 120008,\n            \"parent_id\": 200466,\n            \"title\": \"pricelists\",\n            \"url\": \"/alvine/?cmd=20008\",\n            \"weight\": 10,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 228006,\n            \"parent_id\": 0,\n            \"title\": \"reports\",\n            \"url\": \"/\",\n            \"weight\": 10,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 100350,\n            \"parent_id\": 200466,\n            \"title\": \"objectproperties\",\n            \"url\": \"/alvine/?cmd=350\",\n            \"weight\": 11,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 205111,\n            \"parent_id\": 0,\n            \"title\": \"contentmanagement\",\n            \"url\": \"/\",\n            \"weight\": 11,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 2026036,\n            \"parent_id\": 0,\n            \"title\": \"importexport\",\n            \"url\": \"/\",\n            \"weight\": 12,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 200466,\n            \"parent_id\": 0,\n            \"title\": \"settings\",\n            \"url\": \"/\",\n            \"weight\": 13,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        },\n        {\n            \"id\": 200000,\n            \"parent_id\": 0,\n            \"title\": \"documentation\",\n            \"url\": \"\",\n            \"weight\": 14,\n            \"css_styles\": \"\",\n            \"css_classes\": \"\"\n        }\n    ],\n    \"sys\": {\n        \"code\": 200,\n        \"result\": {},\n        \"api_version\": \"1\"\n    }\n}",
+          "latency": 0,
+          "statusCode": 200,
+          "label": "",
+          "headers": [
+            {
+              "key": "Content-Type",
+              "value": "application/json"
+            }
+          ],
+          "bodyType": "INLINE",
+          "filePath": "",
+          "databucketID": "",
+          "sendFileAsBody": false,
+          "rules": [],
+          "rulesOperator": "OR",
+          "disableTemplating": false,
+          "fallbackTo404": false,
+          "default": true,
+          "crudKey": "id",
+          "callbacks": []
+        }
+      ],
+      "responseMode": null
+    }
+  ],
+  "rootChildren": [
+    {
+      "type": "route",
+      "uuid": "d9f0436c-e07a-4967-bf5a-7d15ef2f5f74"
+    }
+  ],
+  "proxyMode": false,
+  "proxyHost": "",
+  "proxyRemovePrefix": false,
+  "tlsOptions": {
+    "enabled": false,
+    "type": "CERT",
+    "pfxPath": "",
+    "certPath": "",
+    "keyPath": "",
+    "caPath": "",
+    "passphrase": ""
+  },
+  "cors": true,
+  "headers": [
+    {
+      "key": "Content-Type",
+      "value": "application/json"
+    }
+  ],
+  "proxyReqHeaders": [
+    {
+      "key": "",
+      "value": ""
+    }
+  ],
+  "proxyResHeaders": [
+    {
+      "key": "",
+      "value": ""
+    }
+  ],
+  "data": [],
+  "callbacks": []
+}
\ No newline at end of file
diff --git a/flake.lock b/flake.lock
index 8e1a71f7f..beb5a08ce 100644
--- a/flake.lock
+++ b/flake.lock
@@ -55,11 +55,11 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1719426051,
-        "narHash": "sha256-yJL9VYQhaRM7xs0M867ZFxwaONB9T2Q4LnGo1WovuR4=",
+        "lastModified": 1722221733,
+        "narHash": "sha256-sga9SrrPb+pQJxG1ttJfMPheZvDOxApFfwXCFO0H9xw=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "89c49874fb15f4124bf71ca5f42a04f2ee5825fd",
+        "rev": "12bf09802d77264e441f48e25459c10c93eada2e",
         "type": "github"
       },
       "original": {
diff --git a/nix/config/release.nix b/nix/config/release.nix
index c369d979b..fcbc8670b 100644
--- a/nix/config/release.nix
+++ b/nix/config/release.nix
@@ -3,4 +3,4 @@
   commit = "efa3cf498dd40ccbb114cb0074409c1adf2bf6a7";
   name = "Monster";
   mnemonic = "monster";
-}
\ No newline at end of file
+}
diff --git a/nix/scripts/go-task.nix b/nix/scripts/go-task.nix
index aff37a699..ef7fc566d 100644
--- a/nix/scripts/go-task.nix
+++ b/nix/scripts/go-task.nix
@@ -159,6 +159,18 @@
             silent: true
             aliases:
               - r
+              
+
+          tool-mockoon:
+            desc: Run example
+            aliases:
+              - m
+              - mockoon
+            cmds:
+              - ${pkgs'.mockoon}/bin/mockoon
+            silent: true
+            env:
+              USER_WORKING_DIR: "{{.USER_WORKING_DIR}}"              
 
 
     '';
diff --git a/nix/scripts/start-server.nix b/nix/scripts/start-server.nix
index 1032c2e31..763d3bc95 100644
--- a/nix/scripts/start-server.nix
+++ b/nix/scripts/start-server.nix
@@ -49,7 +49,8 @@ in
        exit 1
     fi
 
-    if ! ${pkgs'.nodePackages.pnpm}/bin/pnpx vite --config "./config/vite.config.mjs"; then
+    ##  --inspect-brk (debug flag) 
+    if ! ${pkgs'.nodejs_22}/bin/node "$WORKING_DIR/node_modules/vite/bin/vite.js" --config "./config/vite.config.mjs"; then
         echo_fail "Vite build failed, check your JS!"
         exit 1
     fi
diff --git a/package.json b/package.json
index 6201ce53c..684b5793f 100644
--- a/package.json
+++ b/package.json
@@ -96,5 +96,6 @@
     "vite-plugin-mock": "^3.0.2",
     "vite-plugin-terminal": "^1.2.0",
     "ws": "^8.17.1"
-  }
+  },
+  "packageManager": "pnpm@9.4.0+sha256.b6fd0bfda555e7e584ad7e56b30c68b01d5a04f9ee93989f4b93ca8473c49c74"
 }
diff --git a/source/components/datatable/save-button.mjs b/source/components/datatable/save-button.mjs
index 83a347c1b..646a496aa 100644
--- a/source/components/datatable/save-button.mjs
+++ b/source/components/datatable/save-button.mjs
@@ -12,33 +12,33 @@
  * SPDX-License-Identifier: AGPL-3.0
  */
 
-import {instanceSymbol, internalSymbol} from "../../constants.mjs";
-import {diff} from "../../data/diff.mjs";
-import {addAttributeToken} from "../../dom/attributes.mjs";
-import {ATTRIBUTE_ERRORMESSAGE} from "../../dom/constants.mjs";
+import { instanceSymbol, internalSymbol } from "../../constants.mjs";
+import { diff } from "../../data/diff.mjs";
+import { addAttributeToken } from "../../dom/attributes.mjs";
+import { ATTRIBUTE_ERRORMESSAGE } from "../../dom/constants.mjs";
 import {
-    assembleMethodSymbol,
-    CustomElement,
-    attributeObserverSymbol,
-    registerCustomElement,
+	assembleMethodSymbol,
+	CustomElement,
+	attributeObserverSymbol,
+	registerCustomElement,
 } from "../../dom/customelement.mjs";
-import {findElementWithSelectorUpwards} from "../../dom/util.mjs";
-import {isString, isArray} from "../../types/is.mjs";
-import {Observer} from "../../types/observer.mjs";
-import {TokenList} from "../../types/tokenlist.mjs";
-import {clone} from "../../util/clone.mjs";
-import {State} from "../form/types/state.mjs";
-import {ATTRIBUTE_DATASOURCE_SELECTOR} from "./constants.mjs";
-import {Datasource} from "./datasource.mjs";
-import {BadgeStyleSheet} from "../stylesheet/badge.mjs";
-import {SaveButtonStyleSheet} from "./stylesheet/save-button.mjs";
+import { findElementWithSelectorUpwards } from "../../dom/util.mjs";
+import { isString, isArray } from "../../types/is.mjs";
+import { Observer } from "../../types/observer.mjs";
+import { TokenList } from "../../types/tokenlist.mjs";
+import { clone } from "../../util/clone.mjs";
+import { State } from "../form/types/state.mjs";
+import { ATTRIBUTE_DATASOURCE_SELECTOR } from "./constants.mjs";
+import { Datasource } from "./datasource.mjs";
+import { BadgeStyleSheet } from "../stylesheet/badge.mjs";
+import { SaveButtonStyleSheet } from "./stylesheet/save-button.mjs";
 
 import {
-    handleDataSourceChanges,
-    datasourceLinkedElementSymbol,
+	handleDataSourceChanges,
+	datasourceLinkedElementSymbol,
 } from "./util.mjs";
 
-export {SaveButton};
+export { SaveButton };
 
 /**
  * @private
@@ -59,185 +59,187 @@ const originValuesSymbol = Symbol("originValues");
 const badgeElementSymbol = Symbol("badgeElement");
 
 class SaveButton extends CustomElement {
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for(
-            "@schukai/monster/components/datasource/save-button@@instance",
-        );
-    }
-
-    /**
-     * To set the options via the html tag the attribute `data-monster-options` must be used.
-     * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
-     *
-     * The individual configuration values can be found in the table.
-     *
-     * @property {Object} templates Template definitions
-     * @property {string} templates.main Main template
-     * @property {object} datasource The datasource
-     * @property {string} datasource.selector The selector of the datasource
-     * @property {string} labels.button The button label
-     * @property {Object} classes The classes
-     * @property {string} classes.bar The bar class
-     * @property {string} classes.badge The badge class
-     * @property {Array} ignoreChanges The ignore changes (regex)
-     * @property {Array} data The data
-     * @return {Object}
-     */
-    get defaults() {
-        const obj = Object.assign({}, super.defaults, {
-            templates: {
-                main: getTemplate(),
-            },
-
-            labels: {
-                button: "save",
-            },
-
-            classes: {
-                bar: "monster-button-primary",
-                badge: "monster-badge-secondary hidden",
-            },
-
-            datasource: {
-                selector: null,
-            },
-
-            changes: "0",
-
-            ignoreChanges: [],
-
-            data: {},
-
-            disabled: false,
-        });
-
-        updateOptionsFromArguments.call(this, obj);
-        return obj;
-    }
-
-    /**
-     *
-     * @return {string}
-     */
-    static getTag() {
-        return "monster-datasource-save-button";
-    }
-
-    /**
-     * This method is responsible for assembling the component.
-     *
-     * It calls the parent's assemble method first, then initializes control references and event handlers.
-     * If the `datasource.selector` option is provided and is a string, it searches for the corresponding
-     * element in the DOM using that selector.
-     *
-     * If the selector matches exactly one element, it checks if the element is an instance of the `Datasource` class.
-     *
-     * If it is, the component's `datasourceLinkedElementSymbol` property is set to the element, and the component
-     * attaches an observer to the datasource's changes.
-     *
-     * The observer is a function that calls the `handleDataSourceChanges` method in the context of the component.
-     * Additionally, the component attaches an observer to itself, which also calls the `handleDataSourceChanges`
-     * method in the component's context.
-     */
-    [assembleMethodSymbol]() {
-        super[assembleMethodSymbol]();
-        const self = this;
-
-        initControlReferences.call(this);
-        initEventHandler.call(this);
-
-        const selector = this.getOption("datasource.selector");
-
-        if (isString(selector)) {
-            const element = findElementWithSelectorUpwards(this, selector);
-            if (element === null) {
-                throw new Error("the selector must match exactly one element");
-            }
-
-            if (!(element instanceof Datasource)) {
-                throw new TypeError("the element must be a datasource");
-            }
-
-            this[datasourceLinkedElementSymbol] = element;
-            element.datasource.attachObserver(
-                new Observer(handleDataSourceChanges.bind(this)),
-            );
-
-            self[originValuesSymbol] = null;
-
-            element.datasource.attachObserver(
-                new Observer(function () {
-                    if (!self[originValuesSymbol]) {
-                        self[originValuesSymbol] = clone(self[datasourceLinkedElementSymbol].data);
-                    }
-
-                    const currentValues = this.getRealSubject();
-                    const ignoreChanges = self.getOption("ignoreChanges");
-
-                    const result = diff(self[originValuesSymbol], currentValues);
-                    if (isArray(ignoreChanges) && ignoreChanges.length > 0) {
-                        const itemsToRemove = [];
-                        for (const item of result) {
-                            for (const ignorePattern of ignoreChanges) {
-                                const p = new RegExp(ignorePattern);
-                                if (p.test(item.path)) {
-                                    itemsToRemove.push(item);
-                                    break;
-                                }
-                            }
-                        }
-
-                        for (const itemToRemove of itemsToRemove) {
-                            const index = result.indexOf(itemToRemove);
-                            if (index > -1) {
-                                result.splice(index, 1);
-                            }
-                        }
-                    }
-
-                    if (isArray(result) && result.length > 0) {
-                        self[stateButtonElementSymbol].setState("changed");
-                        self[stateButtonElementSymbol].setOption("disabled", false);
-                        self.setOption("changes", result.length);
-                        self.setOption(
-                            "classes.badge",
-                            new TokenList(self.getOption("classes.badge"))
-                                .remove("hidden")
-                                .toString(),
-                        );
-                    } else {
-                        self[stateButtonElementSymbol].removeState();
-                        self[stateButtonElementSymbol].setOption("disabled", true);
-                        self.setOption("changes", 0);
-                        self.setOption(
-                            "classes.badge",
-                            new TokenList(self.getOption("classes.badge"))
-                                .add("hidden")
-                                .toString(),
-                        );
-                    }
-                }),
-            );
-        }
-
-        this.attachObserver(
-            new Observer(() => {
-                handleDataSourceChanges.call(this);
-            }),
-        );
-    }
-
-    /**
-     *
-     * @return [CSSStyleSheet]
-     */
-    static getCSSStyleSheet() {
-        return [SaveButtonStyleSheet, BadgeStyleSheet];
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for(
+			"@schukai/monster/components/datasource/save-button@@instance",
+		);
+	}
+
+	/**
+	 * To set the options via the html tag the attribute `data-monster-options` must be used.
+	 * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
+	 *
+	 * The individual configuration values can be found in the table.
+	 *
+	 * @property {Object} templates Template definitions
+	 * @property {string} templates.main Main template
+	 * @property {object} datasource The datasource
+	 * @property {string} datasource.selector The selector of the datasource
+	 * @property {string} labels.button The button label
+	 * @property {Object} classes The classes
+	 * @property {string} classes.bar The bar class
+	 * @property {string} classes.badge The badge class
+	 * @property {Array} ignoreChanges The ignore changes (regex)
+	 * @property {Array} data The data
+	 * @return {Object}
+	 */
+	get defaults() {
+		const obj = Object.assign({}, super.defaults, {
+			templates: {
+				main: getTemplate(),
+			},
+
+			labels: {
+				button: "save",
+			},
+
+			classes: {
+				bar: "monster-button-primary",
+				badge: "monster-badge-secondary hidden",
+			},
+
+			datasource: {
+				selector: null,
+			},
+
+			changes: "0",
+
+			ignoreChanges: [],
+
+			data: {},
+
+			disabled: false,
+		});
+
+		updateOptionsFromArguments.call(this, obj);
+		return obj;
+	}
+
+	/**
+	 *
+	 * @return {string}
+	 */
+	static getTag() {
+		return "monster-datasource-save-button";
+	}
+
+	/**
+	 * This method is responsible for assembling the component.
+	 *
+	 * It calls the parent's assemble method first, then initializes control references and event handlers.
+	 * If the `datasource.selector` option is provided and is a string, it searches for the corresponding
+	 * element in the DOM using that selector.
+	 *
+	 * If the selector matches exactly one element, it checks if the element is an instance of the `Datasource` class.
+	 *
+	 * If it is, the component's `datasourceLinkedElementSymbol` property is set to the element, and the component
+	 * attaches an observer to the datasource's changes.
+	 *
+	 * The observer is a function that calls the `handleDataSourceChanges` method in the context of the component.
+	 * Additionally, the component attaches an observer to itself, which also calls the `handleDataSourceChanges`
+	 * method in the component's context.
+	 */
+	[assembleMethodSymbol]() {
+		super[assembleMethodSymbol]();
+		const self = this;
+
+		initControlReferences.call(this);
+		initEventHandler.call(this);
+
+		const selector = this.getOption("datasource.selector");
+
+		if (isString(selector)) {
+			const element = findElementWithSelectorUpwards(this, selector);
+			if (element === null) {
+				throw new Error("the selector must match exactly one element");
+			}
+
+			if (!(element instanceof Datasource)) {
+				throw new TypeError("the element must be a datasource");
+			}
+
+			this[datasourceLinkedElementSymbol] = element;
+			element.datasource.attachObserver(
+				new Observer(handleDataSourceChanges.bind(this)),
+			);
+
+			self[originValuesSymbol] = null;
+
+			element.datasource.attachObserver(
+				new Observer(function () {
+					if (!self[originValuesSymbol]) {
+						self[originValuesSymbol] = clone(
+							self[datasourceLinkedElementSymbol].data,
+						);
+					}
+
+					const currentValues = this.getRealSubject();
+					const ignoreChanges = self.getOption("ignoreChanges");
+
+					const result = diff(self[originValuesSymbol], currentValues);
+					if (isArray(ignoreChanges) && ignoreChanges.length > 0) {
+						const itemsToRemove = [];
+						for (const item of result) {
+							for (const ignorePattern of ignoreChanges) {
+								const p = new RegExp(ignorePattern);
+								if (p.test(item.path)) {
+									itemsToRemove.push(item);
+									break;
+								}
+							}
+						}
+
+						for (const itemToRemove of itemsToRemove) {
+							const index = result.indexOf(itemToRemove);
+							if (index > -1) {
+								result.splice(index, 1);
+							}
+						}
+					}
+
+					if (isArray(result) && result.length > 0) {
+						self[stateButtonElementSymbol].setState("changed");
+						self[stateButtonElementSymbol].setOption("disabled", false);
+						self.setOption("changes", result.length);
+						self.setOption(
+							"classes.badge",
+							new TokenList(self.getOption("classes.badge"))
+								.remove("hidden")
+								.toString(),
+						);
+					} else {
+						self[stateButtonElementSymbol].removeState();
+						self[stateButtonElementSymbol].setOption("disabled", true);
+						self.setOption("changes", 0);
+						self.setOption(
+							"classes.badge",
+							new TokenList(self.getOption("classes.badge"))
+								.add("hidden")
+								.toString(),
+						);
+					}
+				}),
+			);
+		}
+
+		this.attachObserver(
+			new Observer(() => {
+				handleDataSourceChanges.call(this);
+			}),
+		);
+	}
+
+	/**
+	 *
+	 * @return [CSSStyleSheet]
+	 */
+	static getCSSStyleSheet() {
+		return [SaveButtonStyleSheet, BadgeStyleSheet];
+	}
 }
 
 /**
@@ -245,78 +247,78 @@ class SaveButton extends CustomElement {
  * @return {Monster.Components.Datatable.Form}
  */
 function initControlReferences() {
-    if (!this.shadowRoot) {
-        throw new Error("no shadow-root is defined");
-    }
-
-    this[stateButtonElementSymbol] = this.shadowRoot.querySelector(
-        "[data-monster-role=state-button]",
-    );
-
-    this[badgeElementSymbol] = this.shadowRoot.querySelector(
-        "[data-monster-role=badge]",
-    );
-
-    if (this[stateButtonElementSymbol]) {
-        setTimeout(() => {
-            const states = {
-                changed: new State(
-                    "changed",
-                    '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-cloud-arrow-up" viewBox="0 0 16 16">\n' +
-                    '  <path fill-rule="evenodd" d="M7.646 5.146a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1-.708.708L8.5 6.707V10.5a.5.5 0 0 1-1 0V6.707L6.354 7.854a.5.5 0 1 1-.708-.708z"/>\n' +
-                    '  <path d="M4.406 3.342A5.53 5.53 0 0 1 8 2c2.69 0 4.923 2 5.166 4.579C14.758 6.804 16 8.137 16 9.773 16 11.569 14.502 13 12.687 13H3.781C1.708 13 0 11.366 0 9.318c0-1.763 1.266-3.223 2.942-3.593.143-.863.698-1.723 1.464-2.383m.653.757c-.757.653-1.153 1.44-1.153 2.056v.448l-.445.049C2.064 6.805 1 7.952 1 9.318 1 10.785 2.23 12 3.781 12h8.906C13.98 12 15 10.988 15 9.773c0-1.216-1.02-2.228-2.313-2.228h-.5v-.5C12.188 4.825 10.328 3 8 3a4.53 4.53 0 0 0-2.941 1.1z"/>\n' +
-                    "</svg>",
-                ),
-            };
-
-            this[stateButtonElementSymbol].removeState();
-            this[stateButtonElementSymbol].setOption("disabled", "disabled");
-            this[stateButtonElementSymbol].setOption("states", states);
-            this[stateButtonElementSymbol].setOption(
-                "labels.button",
-                this.getOption("labels.button"),
-            );
-        }, 1);
-    }
-
-    return this;
+	if (!this.shadowRoot) {
+		throw new Error("no shadow-root is defined");
+	}
+
+	this[stateButtonElementSymbol] = this.shadowRoot.querySelector(
+		"[data-monster-role=state-button]",
+	);
+
+	this[badgeElementSymbol] = this.shadowRoot.querySelector(
+		"[data-monster-role=badge]",
+	);
+
+	if (this[stateButtonElementSymbol]) {
+		setTimeout(() => {
+			const states = {
+				changed: new State(
+					"changed",
+					'<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-cloud-arrow-up" viewBox="0 0 16 16">\n' +
+						'  <path fill-rule="evenodd" d="M7.646 5.146a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1-.708.708L8.5 6.707V10.5a.5.5 0 0 1-1 0V6.707L6.354 7.854a.5.5 0 1 1-.708-.708z"/>\n' +
+						'  <path d="M4.406 3.342A5.53 5.53 0 0 1 8 2c2.69 0 4.923 2 5.166 4.579C14.758 6.804 16 8.137 16 9.773 16 11.569 14.502 13 12.687 13H3.781C1.708 13 0 11.366 0 9.318c0-1.763 1.266-3.223 2.942-3.593.143-.863.698-1.723 1.464-2.383m.653.757c-.757.653-1.153 1.44-1.153 2.056v.448l-.445.049C2.064 6.805 1 7.952 1 9.318 1 10.785 2.23 12 3.781 12h8.906C13.98 12 15 10.988 15 9.773c0-1.216-1.02-2.228-2.313-2.228h-.5v-.5C12.188 4.825 10.328 3 8 3a4.53 4.53 0 0 0-2.941 1.1z"/>\n' +
+						"</svg>",
+				),
+			};
+
+			this[stateButtonElementSymbol].removeState();
+			this[stateButtonElementSymbol].setOption("disabled", "disabled");
+			this[stateButtonElementSymbol].setOption("states", states);
+			this[stateButtonElementSymbol].setOption(
+				"labels.button",
+				this.getOption("labels.button"),
+			);
+		}, 1);
+	}
+
+	return this;
 }
 
 /**
  * @private
  */
 function initEventHandler() {
-    setTimeout(() => {
-        this[stateButtonElementSymbol].setOption("actions.click", () => {
-            this[datasourceLinkedElementSymbol]
-                .write()
-                .then(() => {
-                    this[originValuesSymbol] = null;
-                    this[stateButtonElementSymbol].removeState();
-                    this[stateButtonElementSymbol].setOption("disabled", true);
-                    this.setOption("changes", 0);
-                    this.setOption(
-                        "classes.badge",
-                        new TokenList(this.getOption("classes.badge"))
-                            .add("hidden")
-                            .toString(),
-                    );
-                })
-                .catch((error) => {
-                    addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error.toString());
-                });
-        });
-    }, 1);
+	setTimeout(() => {
+		this[stateButtonElementSymbol].setOption("actions.click", () => {
+			this[datasourceLinkedElementSymbol]
+				.write()
+				.then(() => {
+					this[originValuesSymbol] = null;
+					this[stateButtonElementSymbol].removeState();
+					this[stateButtonElementSymbol].setOption("disabled", true);
+					this.setOption("changes", 0);
+					this.setOption(
+						"classes.badge",
+						new TokenList(this.getOption("classes.badge"))
+							.add("hidden")
+							.toString(),
+					);
+				})
+				.catch((error) => {
+					addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error.toString());
+				});
+		});
+	}, 1);
 }
 
 /**
  * @param {Object} options
  */
 function updateOptionsFromArguments(options) {
-    const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR);
-    if (selector) {
-        options.datasource.selector = selector;
-    }
+	const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR);
+	if (selector) {
+		options.datasource.selector = selector;
+	}
 }
 
 /**
@@ -324,8 +326,8 @@ function updateOptionsFromArguments(options) {
  * @return {string}
  */
 function getTemplate() {
-    // language=HTML
-    return `
+	// language=HTML
+	return `
         <div data-monster-role="control" part="control"
              data-monster-attributes="disabled path:disabled | if:true">
             <monster-state-button data-monster-role="state-button">save</monster-state-button>
diff --git a/source/components/form/button.mjs b/source/components/form/button.mjs
index 887244577..c7626242b 100644
--- a/source/components/form/button.mjs
+++ b/source/components/form/button.mjs
@@ -51,7 +51,6 @@ export const buttonElementSymbol = Symbol("buttonElement");
  * @copyright schukai GmbH
  * @summary A beautiful button that can make your life easier and also looks good.
  * @fires monster-button-clicked this event is triggered when the button is clicked. It contains the field {button} with the button instance.
- *
  */
 class Button extends CustomControl {
 	/**
diff --git a/source/components/form/select.mjs b/source/components/form/select.mjs
index 44ae5a2d4..b109d8da8 100644
--- a/source/components/form/select.mjs
+++ b/source/components/form/select.mjs
@@ -32,7 +32,6 @@ import {
 	assembleMethodSymbol,
 	getSlottedElements,
 	registerCustomElement,
-	updaterTransformerMethodsSymbol,
 } from "../../dom/customelement.mjs";
 import {
 	findTargetElementFromEvent,
@@ -84,120 +83,120 @@ const clickToLoadOptionsMessage = "Click to load options.";
 
 /**
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const timerCallbackSymbol = Symbol("timerCallback");
 
 /**
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const keyFilterEventSymbol = Symbol("keyFilterEvent");
 
 /**
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const lazyLoadDoneSymbol = Symbol("lazyLoadDone");
 
 /**
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const isLoadingSymbol = Symbol("isLoading");
 
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const closeEventHandler = Symbol("closeEventHandler");
 
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const clearOptionEventHandler = Symbol("clearOptionEventHandler");
 
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const resizeObserverSymbol = Symbol("resizeObserver");
 
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const keyEventHandler = Symbol("keyEventHandler");
 
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const lastFetchedDataSymbol = Symbol("lastFetchedData");
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const inputEventHandler = Symbol("inputEventHandler");
 
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const changeEventHandler = Symbol("changeEventHandler");
 
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const controlElementSymbol = Symbol("controlElement");
 
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const selectionElementSymbol = Symbol("selectionElement");
 
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const containerElementSymbol = Symbol("containerElement");
 
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const popperElementSymbol = Symbol("popperElement");
 
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const inlineFilterElementSymbol = Symbol("inlineFilterElement");
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const popperFilterElementSymbol = Symbol("popperFilterElement");
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const popperFilterContainerElementSymbol = Symbol(
 	"popperFilterContainerElement",
@@ -206,27 +205,27 @@ const popperFilterContainerElementSymbol = Symbol(
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const optionsElementSymbol = Symbol("optionsElement");
 
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const noOptionsAvailableElementSymbol = Symbol("noOptionsAvailableElement");
 
 /**
  * local symbol
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const statusOrRemoveBadgesElementSymbol = Symbol("statusOrRemoveBadgesElement");
 
 /**
  * @private
- * @type {symbol}
+ * @type {Symbol}
  */
 const areOptionsAvailableAndInitSymbol = Symbol("@@areOptionsAvailableAndInit");
 
@@ -271,69 +270,20 @@ const FILTER_POSITION_POPPER = "popper";
 const FILTER_POSITION_INLINE = "inline";
 
 /**
- * @typedef {Object} Selection
- * @property {*} value
- * @property {String} label
- * @memberOf Monster.Components.Form
- * @since 1.2.0
- */
-
-/**
- * This CustomControl creates a select element with a variety of options.
- * It supports filtering, local and remote, multiple selection and has a
- * template system for displaying the options.
- *
- * <img src="./images/select.png">
+ * A select control that can be used to select one or more options from a list.
  *
- * Dependencies: the system uses functions of the [monsterjs](https://monsterjs.org/) library
- * as well as [pooperjs](https://popper.js.org/docs/v2/).
+ * @fragments /fragments/components/form/select/
  *
- * You can create this control either by specifying the HTML tag `<monster-select />` directly in the HTML or using
- * Javascript via the `document.createElement('monster-select');` method.
- *
- * ```html
- * <monster-select></monster-select>
- * ```
- *
- * Or you can create this CustomControl directly in Javascript:
- *
- * ```js
- * import {Select} from '@schukai/component-form/source/select.js';
- * document.createElement('monster-select');
- * ```
- *
- * ## Events
- *
- * The event `monster-change` is sent as soon as someone has clicked on a input control.
- * `monster-changed` is sent as soon as the control has processed this input.
- * The `monster-changed` event is sent when setting a selection. If the options have been set, the `monster-options-set` event is sent.
- *
- * The CustomEvent has the property [`detail`](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail).
- *
- * ```
- * node.addEventListener('monster-change',(e)=>console.log(e.detail))
- * node.addEventListener('monster-changed',(e)=>console.log(e.detail))
- * node.addEventListener('monster-selected',(e)=>console.log(e.detail))
- * node.addEventListener('monster-options-set',(e)=>console.log(e.detail))
- * ```
- *
- * @externalExample ../../../example/components/form/select.mjs
- * @startuml select.png
- * skinparam monochrome true
- * skinparam shadowing false
- * HTMLElement <|-- CustomElement
- * CustomElement <|-- CustomControl
- * CustomControl <|-- Select
- * @enduml
+ * @example /examples/components/form/select-simple
+ * @example /examples/components/form/select-with-options
  *
  * @since 1.0.0
  * @copyright schukai GmbH
- * @memberOf Monster.Components.Form
- * @summary A highly configurable select control
- * @fires Monster.Components.Form.event:monster-options-set
- * @fires Monster.Components.Form.event:monster-selected
- * @fires Monster.Components.Form.event:monster-change
- * @fires Monster.Components.Form.event:monster-changed
+ * @summary A beautiful select control that can make your life easier and also looks good.
+ * @fires monster-options-set
+ * @fires monster-selected
+ * @fires monster-change
+ * @fires monster-changed
  */
 class Select extends CustomControl {
 	/**
@@ -346,7 +296,7 @@ class Select extends CustomControl {
 
 	/**
 	 * This method is called by the `instanceof` operator.
-	 * @returns {symbol}
+	 * @returns {Symbol}
 	 * @since 2.1.0
 	 */
 	static get [instanceSymbol]() {
@@ -540,7 +490,7 @@ class Select extends CustomControl {
 	}
 
 	/**
-	 * @return {Monster.Components.Form.Select}
+	 * @return {Select}
 	 */
 	[assembleMethodSymbol]() {
 		const self = this;
diff --git a/source/components/tree-menu/tree-menu.mjs b/source/components/tree-menu/tree-menu.mjs
index 914c32f7d..6b91af5d6 100644
--- a/source/components/tree-menu/tree-menu.mjs
+++ b/source/components/tree-menu/tree-menu.mjs
@@ -431,7 +431,7 @@ function initEventHandler() {
 	}
 
 	return this;
-}
+} 
 
 /**
  * @private
@@ -469,6 +469,7 @@ function importEntries() {
 		});
 	} catch (error) {
 		addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, String(error));
+		return this;
 	}
 
 	const options = [];
@@ -500,7 +501,6 @@ function importEntries() {
 	}
 
 	this.setOption("entries", options);
-
 	return this;
 }
 
diff --git a/source/data/buildtree.mjs b/source/data/buildtree.mjs
index ae67c1326..c88d2d590 100644
--- a/source/data/buildtree.mjs
+++ b/source/data/buildtree.mjs
@@ -12,13 +12,14 @@
  * SPDX-License-Identifier: AGPL-3.0
  */
 
-import { isArray, isObject } from "../types/is.mjs";
-import { Node } from "../types/node.mjs";
-import { NodeList } from "../types/nodelist.mjs";
-import { assembleParts } from "./buildmap.mjs";
-import { extend } from "./extend.mjs";
+import {isArray, isObject} from "../types/is.mjs";
+import {Node} from "../types/node.mjs";
+import {NodeList} from "../types/nodelist.mjs";
+import {clone} from "../util/clone.mjs";
+import {assembleParts} from "./buildmap.mjs";
+import {extend} from "./extend.mjs";
 
-export { buildTree };
+export {buildTree};
 
 /**
  * @private
@@ -139,63 +140,69 @@ const rootSymbol = Symbol("root");
  * @since 1.26.0
  */
 function buildTree(subject, selector, idKey, parentIDKey, options) {
-	const nodes = new Map();
-
-	if (!isObject(options)) {
-		options = {};
-	}
-
-	options = extend(
-		{},
-		{
-			rootReferences: [null, undefined],
-			filter: undefined,
-		},
-		options,
-	);
-
-	const filter = options?.filter;
-	let rootReferences = options.rootReferences;
-	if (!isArray(rootReferences)) {
-		rootReferences = [rootReferences];
-	}
-
-	const childMap = assembleParts(subject, selector, filter, function (o, k, m) {
-		const key = o?.[idKey];
-		let ref = o?.[parentIDKey];
-		if (rootReferences.indexOf(ref) !== -1) ref = rootSymbol;
-
-		if (key === undefined) {
-			throw new Error("the object has no value for the specified id");
-		}
-
-		o[parentSymbol] = ref;
-
-		const node = new Node(o);
-		this.has(ref)
-			? this.get(ref).add(node)
-			: this.set(ref, new NodeList().add(node));
-		nodes.set(key, node);
-	});
-
-	nodes.forEach((node) => {
+    const nodes = new Map();
+
+    const maxDepth = 100;
+
+    if (!isObject(options)) {
+        options = {};
+    }
+
+    options = extend(
+        {},
+        {
+            rootReferences: [null, undefined],
+            filter: undefined,
+        },
+        options,
+    );
+
+    const filter = options?.filter;
+    let rootReferences = options.rootReferences;
+    if (!isArray(rootReferences)) {
+        rootReferences = [rootReferences];
+    }
+
+    const childMap = assembleParts(subject, selector, filter, function (o, k, m) {
+        const key = o?.[idKey];
+        let ref = o?.[parentIDKey];
+        if (rootReferences.indexOf(ref) !== -1) ref = rootSymbol;
+
+        if (key === undefined) {
+            throw new Error("the object has no value for the specified id");
+        }
+
+        o[parentSymbol] = ref;
+
+        const node = new Node(o);
+        this.has(ref)
+            ? this.get(ref).add(node)
+            : this.set(ref, new NodeList().add(node));
+        nodes.set(key, node);
+    });
+
+    nodes.forEach((node) => {
 		const id = node?.["value"]?.[idKey];
 
+        if (id === undefined) {
+            throw new Error("the object has no value for the specified id");
+        }
+
 		if (childMap.has(id)) {
-			node.childNodes = childMap.get(id);
-			childMap.delete(id);
+            node.childNodes = childMap.get(id);
+            childMap.delete(id);
 		}
 	});
 
-	const list = new NodeList();
+    const list = new NodeList();
 
-	childMap.forEach((s) => {
-		if (s instanceof Set) {
-			s.forEach((n) => {
-				list.add(n);
-			});
-		}
-	});
+    childMap.forEach((s) => {
+        if (s instanceof Set) {
+            s.forEach((n) => {
+                list.add(n);
+            });
+        }
+    });
 
-	return list;
+    return list;
 }
diff --git a/source/types/node.mjs b/source/types/node.mjs
index e7265ecab..216035bbd 100644
--- a/source/types/node.mjs
+++ b/source/types/node.mjs
@@ -12,13 +12,13 @@
  * SPDX-License-Identifier: AGPL-3.0
  */
 
-import { Base } from "./base.mjs";
-import { isPrimitive } from "./is.mjs";
-import { NodeList } from "./nodelist.mjs";
-import { validateInstance } from "./validate.mjs";
-import { instanceSymbol } from "../constants.mjs";
+import {Base} from "./base.mjs";
+import {isPrimitive} from "./is.mjs";
+import {NodeList} from "./nodelist.mjs";
+import {validateInstance} from "./validate.mjs";
+import {instanceSymbol} from "../constants.mjs";
 
-export { Node };
+export {Node};
 
 /**
  * @private
@@ -43,120 +43,120 @@ const treeStructureSymbol = Symbol("treeStructure");
  * @see https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Iteration_protocols
  */
 class Node extends Base {
-	/**
-	 * @param {*} [value]
-	 */
-	constructor(value) {
-		super();
-		this[internalValueSymbol] = value;
-
-		this[treeStructureSymbol] = {
-			parent: null,
-			childNodes: new NodeList(),
-			level: 0,
-		};
-	}
-
-	/**
-	 * This method is called by the `instanceof` operator.
-	 * @returns {symbol}
-	 * @since 2.1.0
-	 */
-	static get [instanceSymbol]() {
-		return Symbol.for("@schukai/monster/types/node");
-	}
-
-	/**
-	 * @property {*}
-	 */
-	get value() {
-		return this[internalValueSymbol];
-	}
-
-	/**
-	 * @property {*}
-	 */
-	set value(value) {
-		this[internalValueSymbol] = value;
-	}
-
-	/**
-	 * @property {Monster.Types.Node|null}
-	 */
-	get parent() {
-		return this[treeStructureSymbol].parent;
-	}
-
-	/**
-	 * @property {integer}
-	 */
-	get level() {
-		return this[treeStructureSymbol].level;
-	}
-
-	/**
-	 *
-	 * @property {NodeList}
-	 */
-	get childNodes() {
-		return this[treeStructureSymbol].childNodes;
-	}
-
-	/**
-	 *
-	 * @property {NodeList}
-	 */
-	set childNodes(childNodes) {
-		this[treeStructureSymbol].childNodes = validateInstance(
-			childNodes,
-			NodeList,
-		);
-		setChildLevelAndParent.call(this, this, 1);
-	}
-
-	/**
-	 * @return {Monster.Types.Node}
-	 * @param {Node} node
-	 */
-	appendChild(node) {
-		this[treeStructureSymbol].childNodes.add(validateInstance(node, Node));
-		node[treeStructureSymbol].parent = this;
-
-		node[treeStructureSymbol].level = this.level + 1;
-		setChildLevelAndParent.call(this, node, 1);
-		return this;
-	}
-
-	/**
-	 * @return {Monster.Types.Node}
-	 * @param {Node} node
-	 */
-	removeChild(node) {
-		this[treeStructureSymbol].childNodes.remove(validateInstance(node, Node));
-		node[treeStructureSymbol].parent = null;
-
-		node[treeStructureSymbol].level = 0;
-		setChildLevelAndParent.call(this, node, -1);
-		return this;
-	}
-
-	/**
-	 *
-	 * @return {boolean}
-	 */
-	hasChildNodes() {
-		return this[treeStructureSymbol].childNodes.length > 0;
-	}
-
-	/**
-	 * @return {Monster.Types.Node}
-	 * @param {Node} node
-	 */
-	hasChild(node) {
-		return this[treeStructureSymbol].childNodes.has(
-			validateInstance(node, Node),
-		);
-	}
+    /**
+     * @param {*} [value]
+     */
+    constructor(value) {
+        super();
+        this[internalValueSymbol] = value;
+
+        this[treeStructureSymbol] = {
+            parent: null,
+            childNodes: new NodeList(),
+            level: 0,
+        };
+    }
+
+    /**
+     * This method is called by the `instanceof` operator.
+     * @returns {symbol}
+     * @since 2.1.0
+     */
+    static get [instanceSymbol]() {
+        return Symbol.for("@schukai/monster/types/node");
+    }
+
+    /**
+     * @property {*}
+     */
+    get value() {
+        return this[internalValueSymbol];
+    }
+
+    /**
+     * @property {*}
+     */
+    set value(value) {
+        this[internalValueSymbol] = value;
+    }
+
+    /**
+     * @property {Monster.Types.Node|null}
+     */
+    get parent() {
+        return this[treeStructureSymbol].parent;
+    }
+
+    /**
+     * @property {integer}
+     */
+    get level() {
+        return this[treeStructureSymbol].level;
+    }
+
+    /**
+     *
+     * @property {NodeList}
+     */
+    get childNodes() {
+        return this[treeStructureSymbol].childNodes;
+    }
+
+    /**
+     *
+     * @property {NodeList}
+     */
+    set childNodes(childNodes) {
+        this[treeStructureSymbol].childNodes = validateInstance(
+            childNodes,
+            NodeList,
+        );
+        setChildLevelAndParent.call(this, this, 1, new Set());
+    }
+
+    /**
+     * @return {Monster.Types.Node}
+     * @param {Node} node
+     */
+    appendChild(node) {
+        this[treeStructureSymbol].childNodes.add(validateInstance(node, Node));
+        node[treeStructureSymbol].parent = this;
+
+        node[treeStructureSymbol].level = this.level + 1;
+        setChildLevelAndParent.call(this, node, 1, new Set());
+        return this;
+    }
+
+    /**
+     * @return {Monster.Types.Node}
+     * @param {Node} node
+     */
+    removeChild(node) {
+        this[treeStructureSymbol].childNodes.remove(validateInstance(node, Node));
+        node[treeStructureSymbol].parent = null;
+
+        node[treeStructureSymbol].level = 0;
+        setChildLevelAndParent.call(this, node, -1, new Set());
+        return this;
+    }
+
+    /**
+     *
+     * @return {boolean}
+     */
+    hasChildNodes() {
+        return this[treeStructureSymbol].childNodes.length > 0;
+    }
+
+    /**
+     * @return {Monster.Types.Node}
+     * @param {Node} node
+     */
+    hasChild(node) {
+        return this[treeStructureSymbol].childNodes.has(
+            validateInstance(node, Node),
+        );
+    }
 
 	/**
 	 * @since 1.28.0
@@ -192,24 +192,34 @@ class Node extends Base {
 	}
 }
 
+
 /**
  * @private
  * @param {Node} node
  * @param {int} operand
+ * @param {Set} visitedNodes
  * @return {setChildLevelAndParent}
  */
-function setChildLevelAndParent(node, operand) {
-	const self = this;
-
-	if (node !== this) {
-		node[treeStructureSymbol].parent = this;
-	}
-
-	node[treeStructureSymbol].childNodes.forEach(function (child) {
-		child[treeStructureSymbol].parent = node;
-		child[treeStructureSymbol].level =
-			node[treeStructureSymbol].level + operand;
-		setChildLevelAndParent.call(self, child, operand);
-	});
-	return this;
+function setChildLevelAndParent(node, operand, visitedNodes) {
+    const self = this;
+
+    if (visitedNodes.has(node)) {
+        throw new Error(
+            "the node has already been visited and cannot be traversed again",
+        )
+    }
+
+    visitedNodes.add(node);
+
+    if (node !== this) {
+        node[treeStructureSymbol].parent = this;
+    }
+
+    node[treeStructureSymbol].childNodes.forEach(function (child) {
+        child[treeStructureSymbol].parent = node;
+        child[treeStructureSymbol].level =
+            node[treeStructureSymbol].level + operand;
+        setChildLevelAndParent.call(self, child, operand, visitedNodes);
+    });
+    return this;
 }
diff --git a/test/cases/data/buildtree.mjs b/test/cases/data/buildtree.mjs
index e6ff5aa19..e066daaf0 100644
--- a/test/cases/data/buildtree.mjs
+++ b/test/cases/data/buildtree.mjs
@@ -7,6 +7,52 @@ import {NodeList} from "../../../source/types/nodelist.mjs";
 
 describe('buildTree', function () {
 
+
+    describe('legacy navigation example (issue #230)', function () {
+
+        it('should run example', function () {
+
+            const objects = JSON.parse(`{
+    "dataset": [
+        {
+            "id": 100001,
+            "parent_id": 200001,
+            "title": "eBay",
+            "url": "/",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        },
+        {
+            "id": 200001,
+            "parent_id": 200001,
+            "title": "alvineconsole",
+            "url": "",
+            "weight": 1,
+            "css_styles": "",
+            "css_classes": ""
+        }
+    ],
+    "sys": {
+        "code": 200,
+        "result": {},
+        "api_version": "1"
+    }
+}`);
+
+            try {
+                buildTree(objects, 'dataset.*', 'id', 'parent_id');    
+            } catch (error) {
+                expect(error).to.be.instanceOf(Error);
+            }
+            
+
+            
+
+        })
+    })    
+    
+
     describe('example', function () {
 
         it('should run example', function () {
@@ -207,6 +253,9 @@ describe('buildTree', function () {
 
 
     });
+    
+    
+    
 
 
 });
diff --git a/test/cases/dom/resource/data.mjs b/test/cases/dom/resource/data.mjs
index 1d11b3066..a54286b06 100644
--- a/test/cases/dom/resource/data.mjs
+++ b/test/cases/dom/resource/data.mjs
@@ -76,7 +76,7 @@ describe('Data', function () {
     describe('External Data', () => {
 
         let id = new ID('data').toString();
-        let server, data, url = 'https://monsterjs.org/assets/empty.js?' + id;
+        let server, data, url = 'data:text/javascript;base64,SGVsbG8sIFdvcmxkIQo=';
 
         beforeEach(() => {
 
diff --git a/test/cases/dom/resource/link.mjs b/test/cases/dom/resource/link.mjs
index 781a44b51..c7790a5ce 100644
--- a/test/cases/dom/resource/link.mjs
+++ b/test/cases/dom/resource/link.mjs
@@ -51,7 +51,7 @@ describe('Link', function () {
         this.timeout(5000);
 
         let id = new ID('link').toString();
-        let link, url = 'https://monsterjs.org/assets/empty.css?' + id;
+        let link, url = 'data:text/css;base64,SGVsbG8sIFdvcmxkIQo=';
 
         beforeEach(() => {
 
diff --git a/test/cases/dom/resource/link/stylesheet.mjs b/test/cases/dom/resource/link/stylesheet.mjs
index 9499b93f8..95c699744 100644
--- a/test/cases/dom/resource/link/stylesheet.mjs
+++ b/test/cases/dom/resource/link/stylesheet.mjs
@@ -54,7 +54,7 @@ describe('Stylesheet', function () {
     describe('External Stylesheet', () => {
 
         let id = new ID('Stylesheet').toString();
-        let stylesheet, url = 'https://monsterjs.org/assets/empty.css?' + id;
+        let stylesheet, url = 'data:text/css;base64,SGVsbG8sIFdvcmxkIQo=';
 
         beforeEach(() => {
 
diff --git a/test/cases/dom/resource/script.mjs b/test/cases/dom/resource/script.mjs
index 4ca53e800..a5b8332f7 100644
--- a/test/cases/dom/resource/script.mjs
+++ b/test/cases/dom/resource/script.mjs
@@ -60,7 +60,7 @@ describe('Script', function () {
     describe('External JS', () => {
 
         let id = new ID('script').toString();
-        let server, script, url = 'https://monsterjs.org/assets/empty.js?' + id;
+        let server, script, url = 'data:text/javascript;base64,SGVsbG8sIFdvcmxkIQo=';
 
         beforeEach(() => {
 
-- 
GitLab