From 19fed8d8d84b6f17b6f75c25c1ac98893dc07936 Mon Sep 17 00:00:00 2001
From: Volker Schukai <volker.schukai@schukai.com>
Date: Wed, 26 Jun 2024 19:58:18 +0200
Subject: [PATCH] chore: tidy and stylings

---
 development/issues/closed/192.html            |   4 +-
 development/scripts/buildStylesheets.mjs      |   5 -
 source/components/datatable/dataset.mjs       | 544 ++++++------
 .../components/datatable/datasource/dom.mjs   |   4 +-
 .../components/datatable/datasource/rest.mjs  | 818 +++++++++---------
 source/components/datatable/filter.mjs        |   1 -
 source/components/form/field-set.mjs          | 438 +++++-----
 source/components/form/form.mjs               | 324 +++----
 source/components/form/reload.mjs             | 422 ++++-----
 source/components/form/select.mjs             |  25 +-
 source/data/datasource/server.mjs             | 212 ++---
 source/data/datasource/server/restapi.mjs     | 384 ++++----
 12 files changed, 1563 insertions(+), 1618 deletions(-)

diff --git a/development/issues/closed/192.html b/development/issues/closed/192.html
index 9e63deee2..faa0e8d8b 100644
--- a/development/issues/closed/192.html
+++ b/development/issues/closed/192.html
@@ -16,8 +16,8 @@
     <main>
           <div id="error-message" data-monster-error="this is the error">This control has an error</div>
         
-        <monster-context-error>error1</monster-context-error>
-        <monster-context-error></monster-context-error>
+        <monster-context-error>error1</monster-context-error> das ist ein test
+        <monster-context-error></monster-context-error> dieser hat keine fehlermeldung und damit keinen fehler.
     </main>
 
 </body>
diff --git a/development/scripts/buildStylesheets.mjs b/development/scripts/buildStylesheets.mjs
index 99cd7b750..2e20a5507 100644
--- a/development/scripts/buildStylesheets.mjs
+++ b/development/scripts/buildStylesheets.mjs
@@ -15,11 +15,6 @@ if (!filename.endsWith(".pcss")) {
     process.exit(1);
 }
 
-if (existsSync(`${projectRoot}/dist`) === false) {
-    console.error("Creating dist directory");
-    process.exit(1);
-}
-
 buildCSS(filename, createScriptFilenameFromStyleFilename(filename)).then(() => {
 }).catch((e) => {
     console.error(e.message);
diff --git a/source/components/datatable/dataset.mjs b/source/components/datatable/dataset.mjs
index 8ba57d289..142239a47 100644
--- a/source/components/datatable/dataset.mjs
+++ b/source/components/datatable/dataset.mjs
@@ -12,33 +12,33 @@
  * SPDX-License-Identifier: AGPL-3.0
  */
 
-import {instanceSymbol, internalSymbol} from "../../constants.mjs";
-import {Pathfinder} from "../../data/pathfinder.mjs";
-import {getLinkedObjects, hasObjectLink} from "../../dom/attributes.mjs";
-import {customElementUpdaterLinkSymbol} from "../../dom/constants.mjs";
+import { instanceSymbol, internalSymbol } from "../../constants.mjs";
+import { Pathfinder } from "../../data/pathfinder.mjs";
+import { getLinkedObjects, hasObjectLink } from "../../dom/attributes.mjs";
+import { customElementUpdaterLinkSymbol } 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} from "../../types/is.mjs";
-import {Observer} from "../../types/observer.mjs";
-import {clone} from "../../util/clone.mjs";
+import { findElementWithSelectorUpwards } from "../../dom/util.mjs";
+import { isString } from "../../types/is.mjs";
+import { Observer } from "../../types/observer.mjs";
+import { clone } from "../../util/clone.mjs";
 import {
-    ATTRIBUTE_DATASOURCE_SELECTOR,
-    ATTRIBUTE_DATATABLE_INDEX,
+	ATTRIBUTE_DATASOURCE_SELECTOR,
+	ATTRIBUTE_DATATABLE_INDEX,
 } from "./constants.mjs";
-import {Datasource} from "./datasource.mjs";
-import {DatasetStyleSheet} from "./stylesheet/dataset.mjs";
+import { Datasource } from "./datasource.mjs";
+import { DatasetStyleSheet } from "./stylesheet/dataset.mjs";
 import {
-    handleDataSourceChanges,
-    datasourceLinkedElementSymbol,
+	handleDataSourceChanges,
+	datasourceLinkedElementSymbol,
 } from "./util.mjs";
-import {FormStyleSheet} from "../stylesheet/form.mjs";
+import { FormStyleSheet } from "../stylesheet/form.mjs";
 
-export {DataSet};
+export { DataSet };
 
 /**
  * The data set component is used to show the data of a data source.
@@ -79,219 +79,221 @@ export {DataSet};
  * @summary A data set
  */
 class DataSet extends CustomElement {
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/components/dataset@@instance");
-    }
-
-    /**
-     * This method determines which attributes are to be monitored by `attributeChangedCallback()`.
-     *
-     * @return {string[]}
-     * @since 1.15.0
-     */
-    static get observedAttributes() {
-        const attributes = super.observedAttributes;
-        attributes.push(ATTRIBUTE_DATATABLE_INDEX);
-        return attributes;
-    }
-
-    /**
-     * 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 {object} mapping The mapping
-     * @property {string} mapping.data The data
-     * @property {number} mapping.index The index
-     * @property {Array} data The data
-     */
-    get defaults() {
-        const obj = Object.assign({}, super.defaults, {
-            templates: {
-                main: getTemplate(),
-            },
-
-            datasource: {
-                selector: null,
-            },
-
-            mapping: {
-                data: "dataset",
-                index: 0,
-            },
-
-            features: {
-                /**
-                 * @since 3.70.0
-                 * @type {boolean}
-                 */
-                refreshOnMutation: true,
-            },
-
-            /**
-             * @since 3.70.0
-             * @type {boolean}
-             */
-            refreshOnMutation: {
-                selector: "input, select, textarea"
-            },
-
-            data: {},
-        });
-
-        updateOptionsFromArguments.call(this, obj);
-        return obj;
-    }
-
-    /**
-     *
-     * @return {string}
-     */
-    static getTag() {
-        return "monster-dataset";
-    }
-
-    /**
-     * This method is called when the component is created.
-     * @since 3.70.0
-     * @returns {DataSet}
-     */
-    refresh() {
-        // makes sure that handleDataSourceChanges is called
-        this.setOption("data", {});
-        return this;
-    }
-
-    /**
-     *
-     * @returns {Promise<unknown>}
-     */
-    write() {
-        return new Promise((resolve, reject) => {
-            if (!this[datasourceLinkedElementSymbol]) {
-                reject(new Error("No datasource"));
-                return;
-            }
-
-            const internalUpdateCloneData = this.getInternalUpdateCloneData();
-            if (!internalUpdateCloneData) {
-                reject(new Error("No update data"));
-                return;
-            }
-
-            const internalData = internalUpdateCloneData?.["data"];
-            if (
-                internalData === undefined ||
-                internalData === null ||
-                internalData === ""
-            ) {
-                reject(new Error("No data"));
-                return;
-            }
-
-            setTimeout(() => {
-                const path = this.getOption("mapping.data");
-                const index = this.getOption("mapping.index");
-
-                let pathWithIndex;
-
-                if (isString(path) && path !== "") {
-                    pathWithIndex = path + "." + index;
-                } else {
-                    pathWithIndex = String(index);
-                }
-
-                const data = this[datasourceLinkedElementSymbol].data;
-                const unref = JSON.stringify(data);
-                const ref = JSON.parse(unref);
-
-                new Pathfinder(ref).setVia(pathWithIndex, internalData);
-
-                this[datasourceLinkedElementSymbol].data = ref;
-
-                resolve();
-            }, 0);
-        });
-    }
-
-    /**
-     * 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]();
-
-        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)),
-            );
-        }
-
-        this.attachObserver(
-            new Observer(() => {
-                handleDataSourceChanges.call(this);
-            }),
-        );
-        
-        if (this.getOption("features.refreshOnMutation")&&this.getOption("refreshOnMutation.selector")) {
-            initMutationObserver.call(this);
-        }
-		
-    }
-
-    /**
-     * @return [CSSStyleSheet]
-     */
-    static getCSSStyleSheet() {
-        return [FormStyleSheet, DatasetStyleSheet];
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/components/dataset@@instance");
+	}
+
+	/**
+	 * This method determines which attributes are to be monitored by `attributeChangedCallback()`.
+	 *
+	 * @return {string[]}
+	 * @since 1.15.0
+	 */
+	static get observedAttributes() {
+		const attributes = super.observedAttributes;
+		attributes.push(ATTRIBUTE_DATATABLE_INDEX);
+		return attributes;
+	}
+
+	/**
+	 * 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 {object} mapping The mapping
+	 * @property {string} mapping.data The data
+	 * @property {number} mapping.index The index
+	 * @property {Array} data The data
+	 */
+	get defaults() {
+		const obj = Object.assign({}, super.defaults, {
+			templates: {
+				main: getTemplate(),
+			},
+
+			datasource: {
+				selector: null,
+			},
+
+			mapping: {
+				data: "dataset",
+				index: 0,
+			},
+
+			features: {
+				/**
+				 * @since 3.70.0
+				 * @type {boolean}
+				 */
+				refreshOnMutation: true,
+			},
+
+			/**
+			 * @since 3.70.0
+			 * @type {boolean}
+			 */
+			refreshOnMutation: {
+				selector: "input, select, textarea",
+			},
+
+			data: {},
+		});
+
+		updateOptionsFromArguments.call(this, obj);
+		return obj;
+	}
+
+	/**
+	 *
+	 * @return {string}
+	 */
+	static getTag() {
+		return "monster-dataset";
+	}
+
+	/**
+	 * This method is called when the component is created.
+	 * @since 3.70.0
+	 * @returns {DataSet}
+	 */
+	refresh() {
+		// makes sure that handleDataSourceChanges is called
+		this.setOption("data", {});
+		return this;
+	}
+
+	/**
+	 *
+	 * @returns {Promise<unknown>}
+	 */
+	write() {
+		return new Promise((resolve, reject) => {
+			if (!this[datasourceLinkedElementSymbol]) {
+				reject(new Error("No datasource"));
+				return;
+			}
+
+			const internalUpdateCloneData = this.getInternalUpdateCloneData();
+			if (!internalUpdateCloneData) {
+				reject(new Error("No update data"));
+				return;
+			}
+
+			const internalData = internalUpdateCloneData?.["data"];
+			if (
+				internalData === undefined ||
+				internalData === null ||
+				internalData === ""
+			) {
+				reject(new Error("No data"));
+				return;
+			}
+
+			setTimeout(() => {
+				const path = this.getOption("mapping.data");
+				const index = this.getOption("mapping.index");
+
+				let pathWithIndex;
+
+				if (isString(path) && path !== "") {
+					pathWithIndex = path + "." + index;
+				} else {
+					pathWithIndex = String(index);
+				}
+
+				const data = this[datasourceLinkedElementSymbol].data;
+				const unref = JSON.stringify(data);
+				const ref = JSON.parse(unref);
+
+				new Pathfinder(ref).setVia(pathWithIndex, internalData);
+
+				this[datasourceLinkedElementSymbol].data = ref;
+
+				resolve();
+			}, 0);
+		});
+	}
+
+	/**
+	 * 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]();
+
+		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)),
+			);
+		}
+
+		this.attachObserver(
+			new Observer(() => {
+				handleDataSourceChanges.call(this);
+			}),
+		);
+
+		if (
+			this.getOption("features.refreshOnMutation") &&
+			this.getOption("refreshOnMutation.selector")
+		) {
+			initMutationObserver.call(this);
+		}
+	}
+
+	/**
+	 * @return [CSSStyleSheet]
+	 */
+	static getCSSStyleSheet() {
+		return [FormStyleSheet, DatasetStyleSheet];
+	}
 }
 
 /**
  * @private
  */
 function initEventHandler() {
-    this[attributeObserverSymbol][ATTRIBUTE_DATATABLE_INDEX] = () => {
-        const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX);
-        if (index) {
-            this.setOption("mapping.index", parseInt(index, 10));
-        }
-    };
+	this[attributeObserverSymbol][ATTRIBUTE_DATATABLE_INDEX] = () => {
+		const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX);
+		if (index) {
+			this.setOption("mapping.index", parseInt(index, 10));
+		}
+	};
 }
 
 /**
@@ -299,67 +301,65 @@ function initEventHandler() {
  * @param {Object} options
  */
 function updateOptionsFromArguments(options) {
-    const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX);
+	const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX);
 
-    if (index !== null && index !== undefined) {
-        options.mapping.index = parseInt(index, 10);
-    }
+	if (index !== null && index !== undefined) {
+		options.mapping.index = parseInt(index, 10);
+	}
 
-    const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR);
+	const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR);
 
-    if (selector) {
-        options.datasource.selector = selector;
-    }
+	if (selector) {
+		options.datasource.selector = selector;
+	}
 }
 
 /**
  * @private
  */
 function initMutationObserver() {
-
-    const config = {attributes: false, childList: true, subtree: true};
-
-    const callback = (mutationList, observer) => {
-
-        if (mutationList.length === 0) {
-            return;
-        }
-
-        let doneFlag = false;
-        for (const mutation of mutationList) {
-
-            if (mutation.type === "childList") {
-                for (const node of mutation.addedNodes) {
-                    if(node instanceof HTMLElement && node.matches(this.getOption("refreshOnMutation.selector"))) {
-                        doneFlag = true;
-                        break;
-                    }
-                }
-                
-                if (doneFlag) {
-                    break;
-                }
-            }
-        }
-
-        if (doneFlag) {
-            this.refresh();
-        }
-    };
-
-    const observer = new MutationObserver(callback);
-    observer.observe(this, config);
-
+	const config = { attributes: false, childList: true, subtree: true };
+
+	const callback = (mutationList, observer) => {
+		if (mutationList.length === 0) {
+			return;
+		}
+
+		let doneFlag = false;
+		for (const mutation of mutationList) {
+			if (mutation.type === "childList") {
+				for (const node of mutation.addedNodes) {
+					if (
+						node instanceof HTMLElement &&
+						node.matches(this.getOption("refreshOnMutation.selector"))
+					) {
+						doneFlag = true;
+						break;
+					}
+				}
+
+				if (doneFlag) {
+					break;
+				}
+			}
+		}
+
+		if (doneFlag) {
+			this.refresh();
+		}
+	};
+
+	const observer = new MutationObserver(callback);
+	observer.observe(this, config);
 }
 
-
 /**
  * @private
  * @return {string}
  */
 function getTemplate() {
-    // language=HTML
-    return `
+	// language=HTML
+	return `
         <div data-monster-role="control" part="control">
             <slot></slot>
         </div>
diff --git a/source/components/datatable/datasource/dom.mjs b/source/components/datatable/datasource/dom.mjs
index c713294db..ed6e00890 100644
--- a/source/components/datatable/datasource/dom.mjs
+++ b/source/components/datatable/datasource/dom.mjs
@@ -12,7 +12,7 @@
  * SPDX-License-Identifier: AGPL-3.0
  */
 
-import {Datasource, dataSourceSymbol} from "../datasource.mjs";
+import { Datasource, dataSourceSymbol } from "../datasource.mjs";
 import { DatasourceStyleSheet } from "../stylesheet/datasource.mjs";
 import { instanceSymbol } from "../../../constants.mjs";
 import {
@@ -180,7 +180,7 @@ function updateDataSource() {
 		data = [];
 	}
 
-	this.data=data;
+	this.data = data;
 }
 
 /**
diff --git a/source/components/datatable/datasource/rest.mjs b/source/components/datatable/datasource/rest.mjs
index e24ee30c6..9ee1a49b7 100644
--- a/source/components/datatable/datasource/rest.mjs
+++ b/source/components/datatable/datasource/rest.mjs
@@ -12,27 +12,27 @@
  * SPDX-License-Identifier: AGPL-3.0
  */
 
-import {diff} from "../../../data/diff.mjs";
-import {addAttributeToken} from "../../../dom/attributes.mjs";
-import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs";
-import {isArray} from "../../../types/is.mjs";
-import {Datasource, dataSourceSymbol} from "../datasource.mjs";
-import {DatasourceStyleSheet} from "../stylesheet/datasource.mjs";
-import {instanceSymbol} from "../../../constants.mjs";
+import { diff } from "../../../data/diff.mjs";
+import { addAttributeToken } from "../../../dom/attributes.mjs";
+import { ATTRIBUTE_ERRORMESSAGE } from "../../../dom/constants.mjs";
+import { isArray } from "../../../types/is.mjs";
+import { Datasource, dataSourceSymbol } from "../datasource.mjs";
+import { DatasourceStyleSheet } from "../stylesheet/datasource.mjs";
+import { instanceSymbol } from "../../../constants.mjs";
 import {
-    assembleMethodSymbol,
-    registerCustomElement,
+	assembleMethodSymbol,
+	registerCustomElement,
 } from "../../../dom/customelement.mjs";
-import {RestAPI} from "../../../data/datasource/server/restapi.mjs";
-import {Formatter} from "../../../text/formatter.mjs";
-import {clone} from "../../../util/clone.mjs";
-import {validateBoolean} from "../../../types/validate.mjs";
-import {findElementWithIdUpwards} from "../../../dom/util.mjs";
-import {Observer} from "../../../types/observer.mjs";
-import {Pathfinder} from "../../../data/pathfinder.mjs";
-import {fireCustomEvent} from "../../../dom/events.mjs";
+import { RestAPI } from "../../../data/datasource/server/restapi.mjs";
+import { Formatter } from "../../../text/formatter.mjs";
+import { clone } from "../../../util/clone.mjs";
+import { validateBoolean } from "../../../types/validate.mjs";
+import { findElementWithIdUpwards } from "../../../dom/util.mjs";
+import { Observer } from "../../../types/observer.mjs";
+import { Pathfinder } from "../../../data/pathfinder.mjs";
+import { fireCustomEvent } from "../../../dom/events.mjs";
 
-export {Rest};
+export { Rest };
 
 /**
  * @private
@@ -46,7 +46,7 @@ const intersectionObserverHandlerSymbol = Symbol("intersectionObserverHandler");
  * @type {symbol}
  */
 const rawDataSymbol = Symbol.for(
-    "@schukai/monster/data/datasource/server/restapi/rawdata",
+	"@schukai/monster/data/datasource/server/restapi/rawdata",
 );
 
 /**
@@ -54,7 +54,7 @@ const rawDataSymbol = Symbol.for(
  * @type {symbol}
  */
 const intersectionObserverObserverSymbol = Symbol(
-    "intersectionObserverObserver",
+	"intersectionObserverObserver",
 );
 
 /**
@@ -83,23 +83,23 @@ const filterObserverSymbol = Symbol("filterObserver");
  * @summary A rest api datasource
  */
 class Rest extends Datasource {
-    /**
-     * the constructor of the class
-     */
-    constructor() {
-        super();
-        this[dataSourceSymbol] = new RestAPI();
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/components/datasource/rest@@instance");
-    }
-
-    /**
+	/**
+	 * the constructor of the class
+	 */
+	constructor() {
+		super();
+		this[dataSourceSymbol] = new RestAPI();
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/components/datasource/rest@@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}
      *
@@ -130,409 +130,407 @@ class Rest extends Datasource {
      * @property {Object} write Write configuration
 
      */
-    get defaults() {
-        const restOptions = new RestAPI().defaults;
-
-        restOptions.read.parameters = {
-            filter: undefined,
-            oderBy: undefined,
-            page: "1",
-        };
-
-        return Object.assign({}, super.defaults, restOptions, {
-            templates: {
-                main: getTemplate(),
-            },
-
-            features: {
-                autoInit: false,
-                filter: false,
-            },
-
-            autoInit: {
-                intersectionObserver: false,
-                oneTime: true,
-            },
-
-            filter: {
-                id: undefined,
-            },
-
-            datatable: {
-                id: undefined,
-            },
-
-            response: {
-                path: {
-                    message: "sys.message",
-                    code: "sys.code",
-                },
-            },
-        });
-    }
-
-    /**
-     *
-     * @param {string} page
-     * @param {string} query
-     * @param {string} orderBy
-     * @returns {Monster.Components.Datatable.Datasource.Rest}
-     */
-    setParameters({page, query, orderBy}) {
-        const parameters = this.getOption("read.parameters");
-        if (query !== undefined) {
-            parameters.query = `${query}`;
-            parameters.page = "1";
-        }
-
-        // after a query the page is set to 1, so if the page is not set, it is set to 1
-        if (page !== undefined) parameters.page = `${page}`;
-        if (orderBy !== undefined) parameters.order = `${orderBy}`;
-        this.setOption("read.parameters", parameters);
-        return this;
-    }
-
-    /**
-     * @return {void}
-     */
-    [assembleMethodSymbol]() {
-        super[assembleMethodSymbol]();
-
-        initEventHandler.call(this);
-        initAutoInit.call(this);
-    }
-
-    /**
-     * @deprecated 2023-06-25
-     * @returns {Promise<never>|*}
-     */
-    reload() {
-        return this.fetch();
-    }
-
-    /**
-     * Fetches the data from the rest api
-     * @returns {Promise<never>|*}
-     */
-    fetch() {
-        const opt = clone(this.getOption("read"));
-        this[dataSourceSymbol].setOption("read", opt);
-
-        let url = this.getOption("read.url");
-        const formatter = new Formatter(this.getOption("read.parameters"));
-
-        if (!url) {
-            return Promise.reject(new Error("No url defined"));
-        }
-
-        url = formatter.format(url);
-
-        this[dataSourceSymbol].setOption("read.url", url);
-
-        return new Promise((resolve, reject) => {
-            fireCustomEvent(this, "monster-datasource-fetch", {
-                datasource: this,
-            });
-
-            setTimeout(() => {
-                this[dataSourceSymbol]
-                    .read()
-                    .then((response) => {
-                        fireCustomEvent(this, "monster-datasource-fetched", {
-                            datasource: this,
-                        });
-
-                        resolve(response);
-                    })
-                    .catch((error) => {
-                        fireCustomEvent(this, "monster-datasource-error", {
-                            error: error,
-                        });
-
-                        addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error.toString());
-                        reject(error);
-                    });
-            }, 0);
-        });
-    }
-
-    /**
-     *
-     * @return {CSSStyleSheet[]}
-     */
-    static getCSSStyleSheet() {
-        return [DatasourceStyleSheet];
-    }
-
-    /**
-     * @private
-     * @return {string}
-     */
-    static getTag() {
-        return "monster-datasource-rest";
-    }
-
-    /**
-     * This method activates the intersection observer manually.
-     * For this purpose, the option `autoInit.intersectionObserver` must be set to `false`.
-     *
-     * @returns {Monster.Components.Datatable.Datasource.Rest}
-     */
-    initIntersectionObserver() {
-        initIntersectionObserver.call(this);
-        return this;
-    }
-
-    /**
-     * @private
-     */
-    connectedCallback() {
-        super.connectedCallback();
-
-        setTimeout(() => {
-            if (this.getOption("features.filter", false) === true) {
-                initFilter.call(this);
-            }
-        }, 0);
-    }
-
-    /**
-     * @private
-     */
-    disconnectedCallback() {
-        super.disconnectedCallback();
-        removeFilter.call(this);
-    }
-
-    /**
-     * @returns {Promise<never>|*}
-     */
-    read() {
-        return this.fetch();
-    }
-
-    /**
-     * Fetches the data from the rest api
-     * @returns {Promise<never>|*}
-     */
-    write() {
-        const opt = clone(this.getOption("write"));
-        this[dataSourceSymbol].setOption("write", opt);
-
-        let url = this.getOption("write.url");
-        const formatter = new Formatter(this.getOption("write.parameters"));
-
-        if (!url) {
-            return Promise.reject(new Error("No url defined"));
-        }
-
-        url = formatter.format(url);
-
-        this[dataSourceSymbol].setOption("write.url", url);
-
-        return new Promise((resolve, reject) => {
-            fireCustomEvent(this, "monster-datasource-fetch", {
-                datasource: this,
-            });
-            
-            setTimeout(() => {
-                this[dataSourceSymbol]
-                    .write()
-                    .then((response) => {
-                        fireCustomEvent(this, "monster-datasource-fetched", {
-                            datasource: this,
-                        });
-
-                        resolve(response);
-                    })
-                    .catch((error) => {
-                        fireCustomEvent(this, "monster-datasource-error", {
-                            error: error,
-                        });
-
-                        addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error.toString());
-                        reject(error);
-                    });
-            }, 0);
-        });
-    }
+	get defaults() {
+		const restOptions = new RestAPI().defaults;
+
+		restOptions.read.parameters = {
+			filter: undefined,
+			oderBy: undefined,
+			page: "1",
+		};
+
+		return Object.assign({}, super.defaults, restOptions, {
+			templates: {
+				main: getTemplate(),
+			},
+
+			features: {
+				autoInit: false,
+				filter: false,
+			},
+
+			autoInit: {
+				intersectionObserver: false,
+				oneTime: true,
+			},
+
+			filter: {
+				id: undefined,
+			},
+
+			datatable: {
+				id: undefined,
+			},
+
+			response: {
+				path: {
+					message: "sys.message",
+					code: "sys.code",
+				},
+			},
+		});
+	}
+
+	/**
+	 *
+	 * @param {string} page
+	 * @param {string} query
+	 * @param {string} orderBy
+	 * @returns {Monster.Components.Datatable.Datasource.Rest}
+	 */
+	setParameters({ page, query, orderBy }) {
+		const parameters = this.getOption("read.parameters");
+		if (query !== undefined) {
+			parameters.query = `${query}`;
+			parameters.page = "1";
+		}
+
+		// after a query the page is set to 1, so if the page is not set, it is set to 1
+		if (page !== undefined) parameters.page = `${page}`;
+		if (orderBy !== undefined) parameters.order = `${orderBy}`;
+		this.setOption("read.parameters", parameters);
+		return this;
+	}
+
+	/**
+	 * @return {void}
+	 */
+	[assembleMethodSymbol]() {
+		super[assembleMethodSymbol]();
+
+		initEventHandler.call(this);
+		initAutoInit.call(this);
+	}
+
+	/**
+	 * @deprecated 2023-06-25
+	 * @returns {Promise<never>|*}
+	 */
+	reload() {
+		return this.fetch();
+	}
+
+	/**
+	 * Fetches the data from the rest api
+	 * @returns {Promise<never>|*}
+	 */
+	fetch() {
+		const opt = clone(this.getOption("read"));
+		this[dataSourceSymbol].setOption("read", opt);
+
+		let url = this.getOption("read.url");
+		const formatter = new Formatter(this.getOption("read.parameters"));
+
+		if (!url) {
+			return Promise.reject(new Error("No url defined"));
+		}
+
+		url = formatter.format(url);
+
+		this[dataSourceSymbol].setOption("read.url", url);
+
+		return new Promise((resolve, reject) => {
+			fireCustomEvent(this, "monster-datasource-fetch", {
+				datasource: this,
+			});
+
+			setTimeout(() => {
+				this[dataSourceSymbol]
+					.read()
+					.then((response) => {
+						fireCustomEvent(this, "monster-datasource-fetched", {
+							datasource: this,
+						});
+
+						resolve(response);
+					})
+					.catch((error) => {
+						fireCustomEvent(this, "monster-datasource-error", {
+							error: error,
+						});
+
+						addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error.toString());
+						reject(error);
+					});
+			}, 0);
+		});
+	}
+
+	/**
+	 *
+	 * @return {CSSStyleSheet[]}
+	 */
+	static getCSSStyleSheet() {
+		return [DatasourceStyleSheet];
+	}
+
+	/**
+	 * @private
+	 * @return {string}
+	 */
+	static getTag() {
+		return "monster-datasource-rest";
+	}
+
+	/**
+	 * This method activates the intersection observer manually.
+	 * For this purpose, the option `autoInit.intersectionObserver` must be set to `false`.
+	 *
+	 * @returns {Monster.Components.Datatable.Datasource.Rest}
+	 */
+	initIntersectionObserver() {
+		initIntersectionObserver.call(this);
+		return this;
+	}
+
+	/**
+	 * @private
+	 */
+	connectedCallback() {
+		super.connectedCallback();
+
+		setTimeout(() => {
+			if (this.getOption("features.filter", false) === true) {
+				initFilter.call(this);
+			}
+		}, 0);
+	}
+
+	/**
+	 * @private
+	 */
+	disconnectedCallback() {
+		super.disconnectedCallback();
+		removeFilter.call(this);
+	}
+
+	/**
+	 * @returns {Promise<never>|*}
+	 */
+	read() {
+		return this.fetch();
+	}
+
+	/**
+	 * Fetches the data from the rest api
+	 * @returns {Promise<never>|*}
+	 */
+	write() {
+		const opt = clone(this.getOption("write"));
+		this[dataSourceSymbol].setOption("write", opt);
+
+		let url = this.getOption("write.url");
+		const formatter = new Formatter(this.getOption("write.parameters"));
+
+		if (!url) {
+			return Promise.reject(new Error("No url defined"));
+		}
+
+		url = formatter.format(url);
+
+		this[dataSourceSymbol].setOption("write.url", url);
+
+		return new Promise((resolve, reject) => {
+			fireCustomEvent(this, "monster-datasource-fetch", {
+				datasource: this,
+			});
+
+			setTimeout(() => {
+				this[dataSourceSymbol]
+					.write()
+					.then((response) => {
+						fireCustomEvent(this, "monster-datasource-fetched", {
+							datasource: this,
+						});
+
+						resolve(response);
+					})
+					.catch((error) => {
+						fireCustomEvent(this, "monster-datasource-error", {
+							error: error,
+						});
+
+						addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error.toString());
+						reject(error);
+					});
+			}, 0);
+		});
+	}
 }
 
 /**
  * @private
  */
 function removeFilter() {
-    const filterID = this.getOption("filter.id", undefined);
-    if (!filterID) return;
+	const filterID = this.getOption("filter.id", undefined);
+	if (!filterID) return;
 
-    const filterControl = findElementWithIdUpwards(this, filterID);
+	const filterControl = findElementWithIdUpwards(this, filterID);
 
-    if (filterControl && this[filterObserverSymbol]) {
-        filterControl?.detachObserver(this[filterObserverSymbol]);
-    }
+	if (filterControl && this[filterObserverSymbol]) {
+		filterControl?.detachObserver(this[filterObserverSymbol]);
+	}
 }
 
 /**
  * @private
  */
 function initFilter() {
-    const filterID = this.getOption("filter.id", undefined);
-
-    if (!filterID)
-        throw new Error("filter feature is enabled but no filter id is defined");
-
-    const filterControl = findElementWithIdUpwards(this, filterID);
-    if (!filterControl)
-        throw new Error(
-            "filter feature is enabled but no filter control with id " +
-            filterID +
-            " is found",
-        );
-
-    this[filterObserverSymbol] = new Observer(() => {
-        const query = filterControl.getOption("query");
-        if (query === undefined) {
-            return;
-        }
-        this.setParameters({query: query});
-        this.fetch()
-            .then((response) => {
-                if (!(response instanceof Response)) {
-                    throw new Error("Response is not an instance of Response");
-                }
-
-                if (response?.ok === true) {
-                    this.dispatchEvent(new CustomEvent("reload", {bubbles: true}));
-                    filterControl?.showSuccess();
-                }
-
-                if (response.bodyUsed === true) {
-                    return handleIntersectionObserver.call(
-                        this,
-                        response[rawDataSymbol],
-                        response,
-                        filterControl,
-                    );
-                }
-
-                response
-                    .text()
-                    .then((jsonAsText) => {
-                        let json;
-                        try {
-                            json = JSON.parse(jsonAsText);
-                        } catch (e) {
-                            const message = e instanceof Error ? e.message : `${e}`;
-                            filterControl?.showFailureMessage(message);
-                            return Promise.reject(e);
-                        }
-
-                        return handleIntersectionObserver.call(
-                            this,
-                            json,
-                            response,
-                            filterControl,
-                        );
-                    })
-                    .catch((e) => {
-                        filterControl?.showFailureMessage(e.message);
-                    });
-            })
-            .catch((e) => {
-                this.dispatchEvent(
-                    new CustomEvent("error", {bubbles: true, detail: e}),
-                );
-
-                if (!(e instanceof Error)) {
-                    e = new Error(e);
-                }
-
-                filterControl?.showFailureMessage(e.message);
-                return Promise.reject(e);
-            });
-    });
-
-    filterControl.attachObserver(this[filterObserverSymbol]);
+	const filterID = this.getOption("filter.id", undefined);
+
+	if (!filterID)
+		throw new Error("filter feature is enabled but no filter id is defined");
+
+	const filterControl = findElementWithIdUpwards(this, filterID);
+	if (!filterControl)
+		throw new Error(
+			"filter feature is enabled but no filter control with id " +
+				filterID +
+				" is found",
+		);
+
+	this[filterObserverSymbol] = new Observer(() => {
+		const query = filterControl.getOption("query");
+		if (query === undefined) {
+			return;
+		}
+		this.setParameters({ query: query });
+		this.fetch()
+			.then((response) => {
+				if (!(response instanceof Response)) {
+					throw new Error("Response is not an instance of Response");
+				}
+
+				if (response?.ok === true) {
+					this.dispatchEvent(new CustomEvent("reload", { bubbles: true }));
+					filterControl?.showSuccess();
+				}
+
+				if (response.bodyUsed === true) {
+					return handleIntersectionObserver.call(
+						this,
+						response[rawDataSymbol],
+						response,
+						filterControl,
+					);
+				}
+
+				response
+					.text()
+					.then((jsonAsText) => {
+						let json;
+						try {
+							json = JSON.parse(jsonAsText);
+						} catch (e) {
+							const message = e instanceof Error ? e.message : `${e}`;
+							filterControl?.showFailureMessage(message);
+							return Promise.reject(e);
+						}
+
+						return handleIntersectionObserver.call(
+							this,
+							json,
+							response,
+							filterControl,
+						);
+					})
+					.catch((e) => {
+						filterControl?.showFailureMessage(e.message);
+					});
+			})
+			.catch((e) => {
+				this.dispatchEvent(
+					new CustomEvent("error", { bubbles: true, detail: e }),
+				);
+
+				if (!(e instanceof Error)) {
+					e = new Error(e);
+				}
+
+				filterControl?.showFailureMessage(e.message);
+				return Promise.reject(e);
+			});
+	});
+
+	filterControl.attachObserver(this[filterObserverSymbol]);
 }
 
 function handleIntersectionObserver(json, response, filterControl) {
-    const path = new Pathfinder(json);
-
-    const codePath = this.getOption("response.path.code");
-
-    if (path.exists(codePath)) {
-        const code = `${path.getVia(codePath)}`;
-        if (code && code === "200") {
-            filterControl?.showSuccess();
-            return Promise.resolve(response);
-        }
-
-        const messagePath = this.getOption("response.path.message");
-        if (path.exists(messagePath)) {
-            const message = path.getVia(messagePath);
-            filterControl?.showFailureMessage(message);
-            return Promise.reject(new Error(message));
-        }
-
-        return Promise.reject(new Error("Response code is not 200"));
-    }
+	const path = new Pathfinder(json);
+
+	const codePath = this.getOption("response.path.code");
+
+	if (path.exists(codePath)) {
+		const code = `${path.getVia(codePath)}`;
+		if (code && code === "200") {
+			filterControl?.showSuccess();
+			return Promise.resolve(response);
+		}
+
+		const messagePath = this.getOption("response.path.message");
+		if (path.exists(messagePath)) {
+			const message = path.getVia(messagePath);
+			filterControl?.showFailureMessage(message);
+			return Promise.reject(new Error(message));
+		}
+
+		return Promise.reject(new Error("Response code is not 200"));
+	}
 }
 
 /**
  * @private
  */
 function initAutoInit() {
+	const autoInit = this.getOption("features.autoInit");
+	validateBoolean(autoInit);
 
-    const autoInit = this.getOption("features.autoInit");
-    validateBoolean(autoInit);
-
-    if (autoInit !== true) return;
+	if (autoInit !== true) return;
 
-    if (this.getOption("autoInit.intersectionObserver") === true) {
-        initIntersectionObserver.call(this);
-        return;
-    }
+	if (this.getOption("autoInit.intersectionObserver") === true) {
+		initIntersectionObserver.call(this);
+		return;
+	}
 
-    setTimeout(() => {
-        this.fetch().catch(() => {
-        });
-    }, 0);
+	setTimeout(() => {
+		this.fetch().catch(() => {});
+	}, 0);
 }
 
 function initEventHandler() {
-    this[intersectionObserverHandlerSymbol] = (entries) => {
-        entries.forEach((entry) => {
-            if (entry.isIntersecting) {
-                if (entry.intersectionRatio > 0) {
-                    this.fetch();
-                }
-
-                // only load once
-                if (
-                    this.getOption("autoInit.oneTime") === true &&
-                    this[intersectionObserverObserverSymbol] !== undefined
-                ) {
-                    this[intersectionObserverObserverSymbol].unobserve(this);
-                }
-            }
-        });
-    };
+	this[intersectionObserverHandlerSymbol] = (entries) => {
+		entries.forEach((entry) => {
+			if (entry.isIntersecting) {
+				if (entry.intersectionRatio > 0) {
+					this.fetch();
+				}
+
+				// only load once
+				if (
+					this.getOption("autoInit.oneTime") === true &&
+					this[intersectionObserverObserverSymbol] !== undefined
+				) {
+					this[intersectionObserverObserverSymbol].unobserve(this);
+				}
+			}
+		});
+	};
 }
 
 function initIntersectionObserver() {
-    this.classList.add("intersection-observer");
-
-    const options = {
-        root: null,
-        rootMargin: "0px",
-        threshold: 0.1,
-    };
-
-    this[intersectionObserverObserverSymbol] = new IntersectionObserver(
-        this[intersectionObserverHandlerSymbol],
-        options,
-    );
-    this[intersectionObserverObserverSymbol].observe(this);
+	this.classList.add("intersection-observer");
+
+	const options = {
+		root: null,
+		rootMargin: "0px",
+		threshold: 0.1,
+	};
+
+	this[intersectionObserverObserverSymbol] = new IntersectionObserver(
+		this[intersectionObserverHandlerSymbol],
+		options,
+	);
+	this[intersectionObserverObserverSymbol].observe(this);
 }
 
 /**
@@ -540,8 +538,8 @@ function initIntersectionObserver() {
  * @return {string}
  */
 function getTemplate() {
-    // language=HTML
-    return `
+	// language=HTML
+	return `
         <slot></slot>`;
 }
 
diff --git a/source/components/datatable/filter.mjs b/source/components/datatable/filter.mjs
index 2247a316a..b125a85ff 100644
--- a/source/components/datatable/filter.mjs
+++ b/source/components/datatable/filter.mjs
@@ -238,7 +238,6 @@ class Filter extends CustomElement {
 				},
 			},
 			labels: {
-
 				search: "Search",
 				reset: "Reset",
 				save: "Save",
diff --git a/source/components/form/field-set.mjs b/source/components/form/field-set.mjs
index 70e89935a..ec1e31cd6 100644
--- a/source/components/form/field-set.mjs
+++ b/source/components/form/field-set.mjs
@@ -12,25 +12,25 @@
  * SPDX-License-Identifier: AGPL-3.0
  */
 
-import {instanceSymbol} from "../../constants.mjs";
-import {addAttributeToken} from "../../dom/attributes.mjs";
+import { instanceSymbol } from "../../constants.mjs";
+import { addAttributeToken } from "../../dom/attributes.mjs";
 import {
-    ATTRIBUTE_ERRORMESSAGE,
-    ATTRIBUTE_ROLE,
+	ATTRIBUTE_ERRORMESSAGE,
+	ATTRIBUTE_ROLE,
 } from "../../dom/constants.mjs";
-import {CustomControl} from "../../dom/customcontrol.mjs";
+import { CustomControl } from "../../dom/customcontrol.mjs";
 import {
-    assembleMethodSymbol,
-    getSlottedElements,
-    registerCustomElement,
+	assembleMethodSymbol,
+	getSlottedElements,
+	registerCustomElement,
 } from "../../dom/customelement.mjs";
-import {isFunction} from "../../types/is.mjs";
-import {FieldSetStyleSheet} from "./stylesheet/field-set.mjs";
+import { isFunction } from "../../types/is.mjs";
+import { FieldSetStyleSheet } from "./stylesheet/field-set.mjs";
 import "../layout/collapse.mjs";
 import "./toggle-switch.mjs";
 
-export {FieldSet};
- 
+export { FieldSet };
+
 /**
  * @private
  * @type {symbol}
@@ -101,178 +101,178 @@ const extendedSwitchElementSymbol = Symbol("extendedSwitchElement");
  * @summary A simple FieldSet
  */
 class FieldSet extends CustomControl {
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/components/form/fieldset@@instance");
-    }
-
-    /**
-     * @return {Components.Form.FieldSet
-     */
-    [assembleMethodSymbol]() {
-        super[assembleMethodSymbol]();
-        initControlReferences.call(this);
-        initEventHandler.call(this);
-        updateExtendedFields.call(this);
-        return this;
-    }
-
-    /**
-     * 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} labels Label definitions
-     * @property {Object} actions Callbacks
-     * @property {string} actions.click="throw Error" Callback when clicked
-     * @property {Object} features Features
-     * @property {Object} classes CSS classes
-     * @property {boolean} disabled=false Disabled state
-     */
-    get defaults() {
-        return Object.assign({}, super.defaults, {
-            templates: {
-                main: getTemplate(),
-            },
-            labels: {
-                "toggle-switch-on": "✔",
-                "toggle-switch-off": "✖",
-                "toggle-switch-label": "Expand",
-                title: "",
-            },
-            classes: {},
-            disabled: false,
-            features: {},
-            actions: {
-                click: () => {
-                    throw new Error("the click action is not defined");
-                },
-            },
-            value: null,
-        });
-    }
-
-    /**
-     *
-     * @return {string}
-     */
-    static getTag() {
-        return "monster-field-set";
-    }
-
-    /**
-     *
-     * @return {CSSStyleSheet[]}
-     */
-    static getCSSStyleSheet() {
-        return [FieldSetStyleSheet];
-    }
-
-    /**
-     * The FieldSet.click() method simulates a click on the internal element.
-     *
-     * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click}
-     */
-    click() {
-        if (this.getOption("disabled") === true) {
-            return;
-        }
-
-        if (
-            this[fieldSetElementSymbol] &&
-            isFunction(this[fieldSetElementSymbol].click)
-        ) {
-            this[fieldSetElementSymbol].click();
-        }
-    }
-
-    /**
-     * The Button.focus() method sets focus on the internal element.
-     *
-     * @param {Object} options
-     * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus}
-     */
-    focus(options) {
-        if (this.getOption("disabled") === true) {
-            return;
-        }
-
-        if (
-            this[fieldSetElementSymbol] &&
-            isFunction(this[fieldSetElementSymbol].focus)
-        ) {
-            this[fieldSetElementSymbol].focus(options);
-        }
-    }
-
-    /**
-     * The Button.blur() method removes focus from the internal element.
-     */
-    blur() {
-        if (
-            this[fieldSetElementSymbol] &&
-            isFunction(this[fieldSetElementSymbol].blur)
-        ) {
-            this[fieldSetElementSymbol].blur();
-        }
-    }
-
-    /**
-     * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals}
-     * @return {boolean}
-     */
-    static get formAssociated() {
-        return true;
-    }
-
-    /**
-     * The current value of the form control.
-     *
-     * ```js
-     * e = document.querySelector('monster-field-set');
-     * console.log(e.value)
-     * ```
-     *
-     * @property {string}
-     */
-    get value() {
-        return this.getOption("value");
-    }
-
-    /**
-     * Set value of the form control.
-     *
-     * ```
-     * e = document.querySelector('monster-field-set');
-     * e.value=1
-     * ```
-     *
-     * @property {string} value
-     * @throws {Error} unsupported type
-     */
-    set value(value) {
-        this.setOption("value", value);
-        try {
-            this?.setFormValue(this.value);
-        } catch (e) {
-            addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
-        }
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/components/form/fieldset@@instance");
+	}
+
+	/**
+	 * @return {Components.Form.FieldSet
+	 */
+	[assembleMethodSymbol]() {
+		super[assembleMethodSymbol]();
+		initControlReferences.call(this);
+		initEventHandler.call(this);
+		updateExtendedFields.call(this);
+		return this;
+	}
+
+	/**
+	 * 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} labels Label definitions
+	 * @property {Object} actions Callbacks
+	 * @property {string} actions.click="throw Error" Callback when clicked
+	 * @property {Object} features Features
+	 * @property {Object} classes CSS classes
+	 * @property {boolean} disabled=false Disabled state
+	 */
+	get defaults() {
+		return Object.assign({}, super.defaults, {
+			templates: {
+				main: getTemplate(),
+			},
+			labels: {
+				"toggle-switch-on": "✔",
+				"toggle-switch-off": "✖",
+				"toggle-switch-label": "Expand",
+				title: "",
+			},
+			classes: {},
+			disabled: false,
+			features: {},
+			actions: {
+				click: () => {
+					throw new Error("the click action is not defined");
+				},
+			},
+			value: null,
+		});
+	}
+
+	/**
+	 *
+	 * @return {string}
+	 */
+	static getTag() {
+		return "monster-field-set";
+	}
+
+	/**
+	 *
+	 * @return {CSSStyleSheet[]}
+	 */
+	static getCSSStyleSheet() {
+		return [FieldSetStyleSheet];
+	}
+
+	/**
+	 * The FieldSet.click() method simulates a click on the internal element.
+	 *
+	 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click}
+	 */
+	click() {
+		if (this.getOption("disabled") === true) {
+			return;
+		}
+
+		if (
+			this[fieldSetElementSymbol] &&
+			isFunction(this[fieldSetElementSymbol].click)
+		) {
+			this[fieldSetElementSymbol].click();
+		}
+	}
+
+	/**
+	 * The Button.focus() method sets focus on the internal element.
+	 *
+	 * @param {Object} options
+	 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus}
+	 */
+	focus(options) {
+		if (this.getOption("disabled") === true) {
+			return;
+		}
+
+		if (
+			this[fieldSetElementSymbol] &&
+			isFunction(this[fieldSetElementSymbol].focus)
+		) {
+			this[fieldSetElementSymbol].focus(options);
+		}
+	}
+
+	/**
+	 * The Button.blur() method removes focus from the internal element.
+	 */
+	blur() {
+		if (
+			this[fieldSetElementSymbol] &&
+			isFunction(this[fieldSetElementSymbol].blur)
+		) {
+			this[fieldSetElementSymbol].blur();
+		}
+	}
+
+	/**
+	 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals}
+	 * @return {boolean}
+	 */
+	static get formAssociated() {
+		return true;
+	}
+
+	/**
+	 * The current value of the form control.
+	 *
+	 * ```js
+	 * e = document.querySelector('monster-field-set');
+	 * console.log(e.value)
+	 * ```
+	 *
+	 * @property {string}
+	 */
+	get value() {
+		return this.getOption("value");
+	}
+
+	/**
+	 * Set value of the form control.
+	 *
+	 * ```
+	 * e = document.querySelector('monster-field-set');
+	 * e.value=1
+	 * ```
+	 *
+	 * @property {string} value
+	 * @throws {Error} unsupported type
+	 */
+	set value(value) {
+		this.setOption("value", value);
+		try {
+			this?.setFormValue(this.value);
+		} catch (e) {
+			addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
+		}
+	}
 }
 
 function updateExtendedFields() {
-    const nodes = getSlottedElements.call(this, "", "extended");
-    if (nodes.size > 0) {
-        this[extendedSwitchSymbol].classList.remove("hidden");
-    } else {
-        this[extendedSwitchSymbol].classList.add("hidden");
-    }
+	const nodes = getSlottedElements.call(this, "", "extended");
+	if (nodes.size > 0) {
+		this[extendedSwitchSymbol].classList.remove("hidden");
+	} else {
+		this[extendedSwitchSymbol].classList.add("hidden");
+	}
 }
 
 /**
@@ -281,53 +281,53 @@ function updateExtendedFields() {
  * @fires Monster.Components.Form.event:monster-field-set-clicked
  */
 function initEventHandler() {
-    this[toggleSwitchElementSymbol].setOption(
-        "labels.toggle-switch-on",
-        this.getOption("labels.toggle-switch-on"),
-    );
-    this[toggleSwitchElementSymbol].setOption(
-        "labels.toggle-switch-off",
-        this.getOption("labels.toggle-switch-off"),
-    );
-
-    this[toggleSwitchElementSymbol].setOption("actions.on", () => {
-        this[collapseElementSymbol].open();
-    });
-
-    this[toggleSwitchElementSymbol].setOption("actions.off", () => {
-        this[collapseElementSymbol].close();
-    });
-
-    return this;
+	this[toggleSwitchElementSymbol].setOption(
+		"labels.toggle-switch-on",
+		this.getOption("labels.toggle-switch-on"),
+	);
+	this[toggleSwitchElementSymbol].setOption(
+		"labels.toggle-switch-off",
+		this.getOption("labels.toggle-switch-off"),
+	);
+
+	this[toggleSwitchElementSymbol].setOption("actions.on", () => {
+		this[collapseElementSymbol].open();
+	});
+
+	this[toggleSwitchElementSymbol].setOption("actions.off", () => {
+		this[collapseElementSymbol].close();
+	});
+
+	return this;
 }
 
 /**
  * @private
  */
 function initControlReferences() {
-    this[fieldSetElementSymbol] = this.shadowRoot.querySelector(
-        `[${ATTRIBUTE_ROLE}="control"]`,
-    );
+	this[fieldSetElementSymbol] = this.shadowRoot.querySelector(
+		`[${ATTRIBUTE_ROLE}="control"]`,
+	);
 
-    this[extendedSwitchElementSymbol] = this.shadowRoot.querySelector(
-        `[${ATTRIBUTE_ROLE}="extended-switch"]`,
-    );
+	this[extendedSwitchElementSymbol] = this.shadowRoot.querySelector(
+		`[${ATTRIBUTE_ROLE}="extended-switch"]`,
+	);
 
-    this[collapseElementSymbol] = this.shadowRoot.querySelector(
-        `[${ATTRIBUTE_ROLE}="collapse"]`,
-    );
+	this[collapseElementSymbol] = this.shadowRoot.querySelector(
+		`[${ATTRIBUTE_ROLE}="collapse"]`,
+	);
 
-    this[headerElementSymbol] = this.shadowRoot.querySelector(
-        `[${ATTRIBUTE_ROLE}="header"]`,
-    );
+	this[headerElementSymbol] = this.shadowRoot.querySelector(
+		`[${ATTRIBUTE_ROLE}="header"]`,
+	);
 
-    this[extendedSwitchSymbol] = this.shadowRoot.querySelector(
-        `[${ATTRIBUTE_ROLE}="extended-switch"]`,
-    );
+	this[extendedSwitchSymbol] = this.shadowRoot.querySelector(
+		`[${ATTRIBUTE_ROLE}="extended-switch"]`,
+	);
 
-    this[toggleSwitchElementSymbol] = this.shadowRoot.querySelector(
-        `monster-toggle-switch`,
-    );
+	this[toggleSwitchElementSymbol] = this.shadowRoot.querySelector(
+		`monster-toggle-switch`,
+	);
 }
 
 /**
@@ -335,8 +335,8 @@ function initControlReferences() {
  * @return {string}
  */
 function getTemplate() {
-    // language=HTML
-    return `
+	// language=HTML
+	return `
         <div data-monster-role="control" part="control">
             <div data-monster-role="header">
                 <div data-monster-replace="path:labels.title" data-monster-role="title"></div>
diff --git a/source/components/form/form.mjs b/source/components/form/form.mjs
index 7d7f02ead..dc64c68f1 100644
--- a/source/components/form/form.mjs
+++ b/source/components/form/form.mjs
@@ -12,49 +12,16 @@
  * SPDX-License-Identifier: AGPL-3.0
  */
 
-import {instanceSymbol} from "../../constants.mjs";
-import {internalSymbol} from "../../constants.mjs";
-import {TokenList} from "../../types/tokenlist.mjs";
-import {DeadMansSwitch} from "../../util/deadmansswitch.mjs";
-import {DataSet} from "../datatable/dataset.mjs";
-//import { Datasource } from "../../data/datasource.mjs";
-import {RestAPI} from "../../data/datasource/server/restapi.mjs";
-import {WebConnect} from "../../data/datasource/server/webconnect.mjs";
-import {WriteError} from "../../data/datasource/server/restapi/writeerror.mjs";
-import {LocalStorage} from "../../data/datasource/storage/localstorage.mjs";
-import {SessionStorage} from "../../data/datasource/storage/sessionstorage.mjs";
+import { DeadMansSwitch } from "../../util/deadmansswitch.mjs";
+import { DataSet } from "../datatable/dataset.mjs";
 import {
-    ATTRIBUTE_DISABLED,
-    ATTRIBUTE_ERRORMESSAGE,
-    ATTRIBUTE_PREFIX,
-    ATTRIBUTE_UPDATER_ATTRIBUTES,
-    ATTRIBUTE_UPDATER_INSERT,
-    ATTRIBUTE_UPDATER_REMOVE,
-    ATTRIBUTE_UPDATER_REPLACE,
-} from "../../dom/constants.mjs";
-import {
-    assembleMethodSymbol,
-    CustomElement,
-    registerCustomElement,
-    getSlottedElements,
+	assembleMethodSymbol,
+	registerCustomElement,
+	getSlottedElements,
 } from "../../dom/customelement.mjs";
-import {addObjectWithUpdaterToElement} from "../../dom/updater.mjs";
-import {findElementWithSelectorUpwards} from "../../dom/util.mjs";
-import {isFunction, isString} from "../../types/is.mjs";
-import {Observer} from "../../types/observer.mjs";
-import {ProxyObserver} from "../../types/proxyobserver.mjs";
-import {Processing} from "../../util/processing.mjs";
-import {datasourceLinkedElementSymbol, handleDataSourceChanges} from "../datatable/util.mjs";
-import {MessageStateButton} from "./message-state-button.mjs";
-import {
-    ATTRIBUTE_FORM_DATASOURCE,
-    ATTRIBUTE_FORM_DATASOURCE_ARGUMENTS,
-} from "./constants.mjs";
-import {StateButton} from "./state-button.mjs";
-import {FormStyleSheet} from "./stylesheet/form.mjs";
-
-export {Form};
+import { FormStyleSheet } from "./stylesheet/form.mjs";
 
+export { Form };
 
 /**
  * @private
@@ -63,155 +30,138 @@ export {Form};
 const debounceCallbackSymbol = Symbol("timerCallback");
 
 class Form extends DataSet {
-
-    /**
-     *
-     * @returns {{shadowMode: string, templates: {main: *}, display: string, disabled: boolean, delegatesFocus: boolean, templateMapping: {}} & {templates: {main: string}, classes: {form: string}}}
-     */
-    get defaults() {
-        const obj = Object.assign(
-            {},
-            super.defaults,
-            {
-                templates: {
-                    main: getTemplate(),
-                },
-
-                classes: {
-                    form: "",
-                },
-
-                writeBack: {
-                    events: ["change", "input", "keyup"]
-                },
-
-                reportValidity: {
-                    selector: "input,select,textarea",
-                }
-
-            }
-        );
-
-        obj['features']['mutationObserver'] = false;
-        obj['features']['writeBack'] = true;
-
-        return obj;
-
-    }
-
-
-    /**
-     *
-     * @return {string}
-     */
-    static getTag() {
-        return "monster-form";
-    }
-
-    /**
-     * @return {CSSStyleSheet[]}
-     */
-    static getCSSStyleSheet() {
-        return [FormStyleSheet];
-    }
-
-    /**
-     *
-     */
-    [assembleMethodSymbol]() {
-        super[assembleMethodSymbol]();
-
-        initControlReferences.call(this);
-        initEventHandler.call(this);
-        initDataSourceHandler.call(this);
-
-    }
-
-    /**
-     * This method is called when the component is created.
-     * @since 3.70.0
-     * @returns {DataSet}
-     */
-    refresh() {
-        this.write();
-        super.refresh();
-        return this;
-    }
-
-    /**
-     * Run reportValidation on all child html form controls.
-     *
-     * @since 2.10.0
-     * @returns {boolean}
-     */
-    reportValidity() {
-        let valid = true;
-
-        const selector = this.getOption("reportValidity.selector");
-        const nodes = getSlottedElements.call(this, selector);
-
-        nodes.forEach((node) => {
-            if (typeof node.reportValidity === "function") {
-                if (node.reportValidity() === false) {
-                    valid = false;
-                }
-            }
-        });
-
-        return valid;
-    }
-
+	/**
+	 *
+	 * @returns {{shadowMode: string, templates: {main: *}, display: string, disabled: boolean, delegatesFocus: boolean, templateMapping: {}} & {templates: {main: string}, classes: {form: string}}}
+	 */
+	get defaults() {
+		const obj = Object.assign({}, super.defaults, {
+			templates: {
+				main: getTemplate(),
+			},
+
+			classes: {
+				form: "",
+			},
+
+			writeBack: {
+				events: ["change", "input", "keyup"],
+			},
+
+			reportValidity: {
+				selector: "input,select,textarea",
+			},
+		});
+
+		obj["features"]["mutationObserver"] = false;
+		obj["features"]["writeBack"] = true;
+
+		return obj;
+	}
+
+	/**
+	 *
+	 * @return {string}
+	 */
+	static getTag() {
+		return "monster-form";
+	}
+
+	/**
+	 * @return {CSSStyleSheet[]}
+	 */
+	static getCSSStyleSheet() {
+		return [FormStyleSheet];
+	}
+
+	/**
+	 *
+	 */
+	[assembleMethodSymbol]() {
+		super[assembleMethodSymbol]();
+
+		initControlReferences.call(this);
+		initEventHandler.call(this);
+		initDataSourceHandler.call(this);
+	}
+
+	/**
+	 * This method is called when the component is created.
+	 * @since 3.70.0
+	 * @returns {DataSet}
+	 */
+	refresh() {
+		this.write();
+		super.refresh();
+		return this;
+	}
+
+	/**
+	 * Run reportValidation on all child html form controls.
+	 *
+	 * @since 2.10.0
+	 * @returns {boolean}
+	 */
+	reportValidity() {
+		let valid = true;
+
+		const selector = this.getOption("reportValidity.selector");
+		const nodes = getSlottedElements.call(this, selector);
+
+		nodes.forEach((node) => {
+			if (typeof node.reportValidity === "function") {
+				if (node.reportValidity() === false) {
+					valid = false;
+				}
+			}
+		});
+
+		return valid;
+	}
 }
 
-function initDataSourceHandler() {
-
-}
+function initDataSourceHandler() {}
 
 /**
  * @private
  * @returns {initEventHandler}
  */
 function initEventHandler() {
-
-    if (this.getOption("features.writeBack") === true) {
-        const events = this.getOption("writeBack.events");
-        for (const event of events) {
-
-            this.addEventListener(event, (e) => {
-
-                if (!this.reportValidity()) {
-
-                    this.classList.add("invalid");
-                    setTimeout(() => {
-                        this.classList.remove("invalid");
-                    }, 1000)
-
-                    return;
-                }
-
-                if (this[debounceCallbackSymbol] instanceof DeadMansSwitch) {
-                    try {
-                        this[debounceCallbackSymbol].touch();
-                        return;
-                    } catch (e) {
-                        if (e.message !== "has already run") {
-                            throw e;
-                        }
-                        delete this[debounceCallbackSymbol];
-                    }
-                }
-
-                this[debounceCallbackSymbol] = new DeadMansSwitch(200, () => {
-                    setTimeout(() => {
-                        this.write();
-                    }, 0);
-                });
-
-            });
-        }
-    }
-
-    return this;
+	if (this.getOption("features.writeBack") === true) {
+		const events = this.getOption("writeBack.events");
+		for (const event of events) {
+			this.addEventListener(event, (e) => {
+				if (!this.reportValidity()) {
+					this.classList.add("invalid");
+					setTimeout(() => {
+						this.classList.remove("invalid");
+					}, 1000);
+
+					return;
+				}
+
+				if (this[debounceCallbackSymbol] instanceof DeadMansSwitch) {
+					try {
+						this[debounceCallbackSymbol].touch();
+						return;
+					} catch (e) {
+						if (e.message !== "has already run") {
+							throw e;
+						}
+						delete this[debounceCallbackSymbol];
+					}
+				}
+
+				this[debounceCallbackSymbol] = new DeadMansSwitch(200, () => {
+					setTimeout(() => {
+						this.write();
+					}, 0);
+				});
+			});
+		}
+	}
+
+	return this;
 }
 
 /**
@@ -219,10 +169,10 @@ function initEventHandler() {
  * @return {FilterButton}
  */
 function initControlReferences() {
-    if (!this.shadowRoot) {
-        throw new Error("no shadow-root is defined");
-    }
-    return this;
+	if (!this.shadowRoot) {
+		throw new Error("no shadow-root is defined");
+	}
+	return this;
 }
 
 /**
@@ -230,8 +180,8 @@ function initControlReferences() {
  * @return {string}
  */
 function getTemplate() {
-    // language=HTML
-    return `
+	// language=HTML
+	return `
         <div data-monster-role="control" part="control">
             <form data-monster-attributes="disabled path:disabled | if:true, class path:classes.form"
                   data-monster-role="form"
diff --git a/source/components/form/reload.mjs b/source/components/form/reload.mjs
index 439af80e0..3d27a63ad 100644
--- a/source/components/form/reload.mjs
+++ b/source/components/form/reload.mjs
@@ -12,24 +12,24 @@
  * SPDX-License-Identifier: AGPL-3.0
  */
 
-import {instanceSymbol} from "../../constants.mjs";
-import {addAttributeToken} from "../../dom/attributes.mjs";
+import { instanceSymbol } from "../../constants.mjs";
+import { addAttributeToken } from "../../dom/attributes.mjs";
 import {
-    ATTRIBUTE_ERRORMESSAGE,
-    ATTRIBUTE_ROLE,
+	ATTRIBUTE_ERRORMESSAGE,
+	ATTRIBUTE_ROLE,
 } from "../../dom/constants.mjs";
 import {
-    assembleMethodSymbol,
-    attributeObserverSymbol,
-    CustomElement,
-    initMethodSymbol,
-    registerCustomElement,
+	assembleMethodSymbol,
+	attributeObserverSymbol,
+	CustomElement,
+	initMethodSymbol,
+	registerCustomElement,
 } from "../../dom/customelement.mjs";
-import {isString} from "../../types/is.mjs";
-import {ATTRIBUTE_FORM_RELOAD, ATTRIBUTE_FORM_URL} from "./constants.mjs";
-import {loadAndAssignContent} from "./util/fetch.mjs";
+import { isString } from "../../types/is.mjs";
+import { ATTRIBUTE_FORM_RELOAD, ATTRIBUTE_FORM_URL } from "./constants.mjs";
+import { loadAndAssignContent } from "./util/fetch.mjs";
 
-export {Reload};
+export { Reload };
 
 /**
  * @private
@@ -106,128 +106,128 @@ const intersectionObserverWasInitialized = Symbol("wasInitialized");
  * @fires Monster.Components.event:monster-fetched
  */
 class Reload extends CustomElement {
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/components/form/reload");
-    }
-
-    /**
-     * 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 {string} url=undefined
-     * @property {string} reload=undefined currently the values defined are `onshow` and `always`. The default `onshow` removes the IntersectionObserver. This means that the content is only loaded once. reloading of the content does not occur.
-     * @property {string} filter=undefined dom selectors to search for elements, if undefined then everything is taken
-     * @property {Monster.Components.Form.Processor[]} processors
-     * @property {Object} fetch Fetch [see Using Fetch mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
-     * @property {String} fetch.redirect=error
-     * @property {String} fetch.method=GET
-     * @property {String} fetch.mode=same-origin
-     * @property {String} fetch.credentials=same-origin
-     * @property {Object} fetch.headers={"accept":"text/html"}}
-     */
-    get defaults() {
-        return Object.assign(
-            {},
-            super.defaults,
-            {
-                templates: {
-                    main: getTemplate.call(this),
-                },
-                shadowMode: null,
-                url: null,
-                reload: "onshow",
-                filter: null,
-                fetch: {
-                    redirect: "error",
-                    method: "GET",
-                    mode: "same-origin",
-                    credentials: "same-origin",
-                    headers: {
-                        accept: "text/html",
-                    },
-                },
-            },
-            initOptionsFromArguments.call(this),
-        );
-    }
-
-    /**
-     * This method determines which attributes are to be monitored by `attributeChangedCallback()`.
-     *
-     * @return {string[]}
-     */
-    static get observedAttributes() {
-        const list = super.observedAttributes;
-        list.push(ATTRIBUTE_FORM_URL);
-        return list;
-    }
-
-    /**
-     * @return {void}
-     */
-    [initMethodSymbol]() {
-        super[initMethodSymbol]();
-
-        // data-monster-options
-        this[attributeObserverSymbol][ATTRIBUTE_FORM_URL] = (url) => {
-            if (this.hasAttribute(ATTRIBUTE_FORM_URL)) {
-                this.setOption("url", new URL(url, document.location).toString());
-            } else {
-                this.setOption("url", undefined);
-            }
-        };
-    }
-
-    /**
-     * This method is called internal and should not be called directly.
-     * @throws {Error} missing default slot
-     * @throws {Error} no shadow-root is defined
-     * @throws {Error} missing url
-     * @throws {Error} we won't be able to read the data
-     * @throws {Error} request failed
-     * @throws {Error} not found
-     * @throws {Error} undefined status or type
-     * @fires Monster.Components.event:monster-fetched
-     * @return {Monster.Components.Form.Form}
-     */
-    [assembleMethodSymbol]() {
-        super[assembleMethodSymbol]();
-        initIntersectionObserver.call(this);
-    }
-
-    /**
-     * This method is called internal and should not be called directly.
-     *
-     * @return {string}
-     */
-    static getTag() {
-        return "monster-reload";
-    }
-
-    /**
-     * load content from url
-     *
-     * It is important to know that with this function the loading is executed
-     * directly. it is loaded as well when the element is not visible.
-     *
-     * @param {string|undefined} url
-     */
-    fetch(url) {
-        if (isString(url) || url instanceof URL) {
-            this.setAttribute(ATTRIBUTE_FORM_URL, `${url}`);
-        }
-
-        return loadContent.call(this);
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/components/form/reload");
+	}
+
+	/**
+	 * 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 {string} url=undefined
+	 * @property {string} reload=undefined currently the values defined are `onshow` and `always`. The default `onshow` removes the IntersectionObserver. This means that the content is only loaded once. reloading of the content does not occur.
+	 * @property {string} filter=undefined dom selectors to search for elements, if undefined then everything is taken
+	 * @property {Monster.Components.Form.Processor[]} processors
+	 * @property {Object} fetch Fetch [see Using Fetch mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
+	 * @property {String} fetch.redirect=error
+	 * @property {String} fetch.method=GET
+	 * @property {String} fetch.mode=same-origin
+	 * @property {String} fetch.credentials=same-origin
+	 * @property {Object} fetch.headers={"accept":"text/html"}}
+	 */
+	get defaults() {
+		return Object.assign(
+			{},
+			super.defaults,
+			{
+				templates: {
+					main: getTemplate.call(this),
+				},
+				shadowMode: null,
+				url: null,
+				reload: "onshow",
+				filter: null,
+				fetch: {
+					redirect: "error",
+					method: "GET",
+					mode: "same-origin",
+					credentials: "same-origin",
+					headers: {
+						accept: "text/html",
+					},
+				},
+			},
+			initOptionsFromArguments.call(this),
+		);
+	}
+
+	/**
+	 * This method determines which attributes are to be monitored by `attributeChangedCallback()`.
+	 *
+	 * @return {string[]}
+	 */
+	static get observedAttributes() {
+		const list = super.observedAttributes;
+		list.push(ATTRIBUTE_FORM_URL);
+		return list;
+	}
+
+	/**
+	 * @return {void}
+	 */
+	[initMethodSymbol]() {
+		super[initMethodSymbol]();
+
+		// data-monster-options
+		this[attributeObserverSymbol][ATTRIBUTE_FORM_URL] = (url) => {
+			if (this.hasAttribute(ATTRIBUTE_FORM_URL)) {
+				this.setOption("url", new URL(url, document.location).toString());
+			} else {
+				this.setOption("url", undefined);
+			}
+		};
+	}
+
+	/**
+	 * This method is called internal and should not be called directly.
+	 * @throws {Error} missing default slot
+	 * @throws {Error} no shadow-root is defined
+	 * @throws {Error} missing url
+	 * @throws {Error} we won't be able to read the data
+	 * @throws {Error} request failed
+	 * @throws {Error} not found
+	 * @throws {Error} undefined status or type
+	 * @fires Monster.Components.event:monster-fetched
+	 * @return {Monster.Components.Form.Form}
+	 */
+	[assembleMethodSymbol]() {
+		super[assembleMethodSymbol]();
+		initIntersectionObserver.call(this);
+	}
+
+	/**
+	 * This method is called internal and should not be called directly.
+	 *
+	 * @return {string}
+	 */
+	static getTag() {
+		return "monster-reload";
+	}
+
+	/**
+	 * load content from url
+	 *
+	 * It is important to know that with this function the loading is executed
+	 * directly. it is loaded as well when the element is not visible.
+	 *
+	 * @param {string|undefined} url
+	 */
+	fetch(url) {
+		if (isString(url) || url instanceof URL) {
+			this.setAttribute(ATTRIBUTE_FORM_URL, `${url}`);
+		}
+
+		return loadContent.call(this);
+	}
 }
 
 /**
@@ -241,19 +241,19 @@ class Reload extends CustomElement {
  * @return {object}
  */
 function initOptionsFromArguments() {
-    const options = {};
+	const options = {};
 
-    const url = this.getAttribute(ATTRIBUTE_FORM_URL);
+	const url = this.getAttribute(ATTRIBUTE_FORM_URL);
 
-    if (isString(url)) {
-        options["url"] = new URL(url, document.location).toString();
-    }
+	if (isString(url)) {
+		options["url"] = new URL(url, document.location).toString();
+	}
 
-    if (this.hasAttribute(ATTRIBUTE_FORM_RELOAD)) {
-        options["reload"] = this.getAttribute(ATTRIBUTE_FORM_RELOAD).toLowerCase();
-    }
+	if (this.hasAttribute(ATTRIBUTE_FORM_RELOAD)) {
+		options["reload"] = this.getAttribute(ATTRIBUTE_FORM_RELOAD).toLowerCase();
+	}
 
-    return options;
+	return options;
 }
 
 /**
@@ -268,37 +268,37 @@ function initOptionsFromArguments() {
  * @fires Monster.Components.event:monster-fetched
  */
 function initIntersectionObserver() {
-    if (this[intersectionObserverWasInitialized] === true) {
-        return;
-    }
-
-    this[intersectionObserverWasInitialized] = true;
-
-    const options = {
-        threshold: [0.5],
-    };
-
-    const callback = (entries, observer) => {
-        for (const [, entry] of entries.entries()) {
-            if (entry.isIntersecting === true) {
-                // undefined or always do the same
-                if (this.getOption("reload") === "onshow") {
-                    observer.disconnect();
-                }
-
-                try {
-                    loadContent.call(this).catch((e) => {
-                        addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.toString());
-                    });
-                } catch (e) {
-                    addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.toString());
-                }
-            }
-        }
-    };
-
-    const observer = new IntersectionObserver(callback, options);
-    observer.observe(this);
+	if (this[intersectionObserverWasInitialized] === true) {
+		return;
+	}
+
+	this[intersectionObserverWasInitialized] = true;
+
+	const options = {
+		threshold: [0.5],
+	};
+
+	const callback = (entries, observer) => {
+		for (const [, entry] of entries.entries()) {
+			if (entry.isIntersecting === true) {
+				// undefined or always do the same
+				if (this.getOption("reload") === "onshow") {
+					observer.disconnect();
+				}
+
+				try {
+					loadContent.call(this).catch((e) => {
+						addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.toString());
+					});
+				} catch (e) {
+					addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.toString());
+				}
+			}
+		}
+	};
+
+	const observer = new IntersectionObserver(callback, options);
+	observer.observe(this);
 }
 
 /**
@@ -318,41 +318,41 @@ function initIntersectionObserver() {
  * @return {Promise}
  */
 function loadContent() {
-    const url = this.getOption("url", undefined);
-    if (!isString(url) || url === "") {
-        throw new Error("missing url");
-    }
-
-    const options = this.getOption("fetch", {});
-
-    let parentNode = this;
-    if (this.shadowRoot) {
-        parentNode = this.shadowRoot;
-    }
-
-    let container = parentNode.querySelector(`[${ATTRIBUTE_ROLE}=container]`);
-    let currentDisplayMode = container?.style?.display;
-
-    if (currentDisplayMode === undefined) {
-        currentDisplayMode = "inherit";
-    }
-
-    if (!(container instanceof HTMLElement)) {
-        container = document.createElement("div");
-        container.style.display = "none";
-        container.setAttribute(ATTRIBUTE_ROLE, "container");
-        parentNode.appendChild(container);
-    }
-
-    return loadAndAssignContent(container, url, options, this.getOption("filter"))
-        .then(() => {
-            if (currentDisplayMode !== undefined) {
-                container.style.display = currentDisplayMode;
-            }
-        })
-        .catch((e) => {
-            throw e;
-        });
+	const url = this.getOption("url", undefined);
+	if (!isString(url) || url === "") {
+		throw new Error("missing url");
+	}
+
+	const options = this.getOption("fetch", {});
+
+	let parentNode = this;
+	if (this.shadowRoot) {
+		parentNode = this.shadowRoot;
+	}
+
+	let container = parentNode.querySelector(`[${ATTRIBUTE_ROLE}=container]`);
+	let currentDisplayMode = container?.style?.display;
+
+	if (currentDisplayMode === undefined) {
+		currentDisplayMode = "inherit";
+	}
+
+	if (!(container instanceof HTMLElement)) {
+		container = document.createElement("div");
+		container.style.display = "none";
+		container.setAttribute(ATTRIBUTE_ROLE, "container");
+		parentNode.appendChild(container);
+	}
+
+	return loadAndAssignContent(container, url, options, this.getOption("filter"))
+		.then(() => {
+			if (currentDisplayMode !== undefined) {
+				container.style.display = currentDisplayMode;
+			}
+		})
+		.catch((e) => {
+			throw e;
+		});
 }
 
 /**
@@ -360,7 +360,7 @@ function loadContent() {
  * @return {string}
  */
 function getTemplate() {
-    return this.innerHTML;
+	return this.innerHTML;
 }
 
 registerCustomElement(Reload);
diff --git a/source/components/form/select.mjs b/source/components/form/select.mjs
index 57a1e9f63..44ae5a2d4 100644
--- a/source/components/form/select.mjs
+++ b/source/components/form/select.mjs
@@ -698,7 +698,7 @@ class Select extends CustomControl {
 							const selection = this.getOption("selection");
 							let newValue = [];
 							if (selection) {
-								newValue = selection
+								newValue = selection;
 							} else if (this.hasAttribute("value")) {
 								newValue = this.getAttribute("value");
 							}
@@ -710,7 +710,7 @@ class Select extends CustomControl {
 								resolve(result);
 							}, 10);
 
-							return
+							return;
 						}
 
 						setStatusOrRemoveBadges.call(this, "error");
@@ -1866,7 +1866,6 @@ function areOptionsAvailableAndInit() {
  * @throws {Error} no shadow-root is defined
  */
 function checkOptionState() {
-	
 	if (!this.shadowRoot) {
 		throw new Error("no shadow-root is defined");
 	}
@@ -1891,8 +1890,6 @@ function checkOptionState() {
 			if (e.checked !== false) e.checked = false;
 		}
 	}
-	
-	
 }
 
 /**
@@ -1976,8 +1973,8 @@ function setSelection(selection) {
 		selection = [];
 	}
 
-	validateArray(selection)
-	
+	validateArray(selection);
+
 	for (let i = 0; i < selection.length; i++) {
 		selection[i] = {
 			label: getSelectionLabel.call(this, selection[i].value),
@@ -2112,14 +2109,16 @@ function show() {
 	if (lazyLoadFlag === true) {
 		this[lazyLoadDoneSymbol] = true;
 		setStatusOrRemoveBadges.call(this, "loading");
-		
+
 		new Processing(200, () => {
-			this.fetch().then(() => {
+			this.fetch()
+				.then(() => {
 					checkOptionState.call(this);
-				}).catch((e) => {
-				addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
-				setStatusOrRemoveBadges.call(this, "error");
-			});
+				})
+				.catch((e) => {
+					addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
+					setStatusOrRemoveBadges.call(this, "error");
+				});
 		})
 			.run()
 			.catch((e) => {
diff --git a/source/data/datasource/server.mjs b/source/data/datasource/server.mjs
index d7dc4ca5e..d0cfe053b 100644
--- a/source/data/datasource/server.mjs
+++ b/source/data/datasource/server.mjs
@@ -12,15 +12,14 @@
  * SPDX-License-Identifier: AGPL-3.0
  */
 
-import {instanceSymbol} from "../../constants.mjs";
-import {isArray, isFunction, isObject} from "../../types/is.mjs";
-import {Datasource} from "../datasource.mjs";
-import {diff} from "../diff.mjs";
-import {Pathfinder} from "../pathfinder.mjs";
-import {Pipe} from "../pipe.mjs";
-
-export {Server};
+import { instanceSymbol } from "../../constants.mjs";
+import { isArray, isFunction, isObject } from "../../types/is.mjs";
+import { Datasource } from "../datasource.mjs";
+import { diff } from "../diff.mjs";
+import { Pathfinder } from "../pathfinder.mjs";
+import { Pipe } from "../pipe.mjs";
 
+export { Server };
 
 /**
  * @private
@@ -38,82 +37,85 @@ const serverVersionSymbol = Symbol("serverVersion");
  * @summary The Server class encapsulates the access to a server datasource
  */
 class Server extends Datasource {
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/data/datasource/server");
-    }
-
-    /**
-     * This prepares the data that comes from the server.
-     * Should not be called directly.
-     *
-     * @private
-     * @param {Object} payload
-     * @returns {Object}
-     */
-    transformServerPayload(payload) {
-        payload = doTransform.call(this, "read", payload);
-        this[serverVersionSymbol] = payload;
-
-        const dataPath = this.getOption("read.path");
-        if (dataPath) {
-            payload = new Pathfinder(payload).getVia(dataPath);
-        }
-
-        return payload;
-    }
-
-    /**
-     * This prepares the data for writing and should not be called directly.
-     *
-     * @private
-     * @param {Object} payload
-     * @returns {Object}
-     */
-    prepareServerPayload(payload) {
-        payload = doTransform.call(this, "write", payload);
-        payload = doDiff.call(this, payload);
-
-        const sheathingObject = this.getOption("write.sheathing.object");
-        const sheathingPath = this.getOption("write.sheathing.path");
-
-        if (sheathingObject && sheathingPath) {
-            const sub = payload;
-            payload = sheathingObject;
-            new Pathfinder(payload).setVia(sheathingPath, sub);
-        }
-
-        return payload;
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/data/datasource/server");
+	}
+
+	/**
+	 * This prepares the data that comes from the server.
+	 * Should not be called directly.
+	 *
+	 * @private
+	 * @param {Object} payload
+	 * @returns {Object}
+	 */
+	transformServerPayload(payload) {
+		payload = doTransform.call(this, "read", payload);
+		this[serverVersionSymbol] = payload;
+
+		const dataPath = this.getOption("read.path");
+		if (dataPath) {
+			payload = new Pathfinder(payload).getVia(dataPath);
+		}
+
+		return payload;
+	}
+
+	/**
+	 * This prepares the data for writing and should not be called directly.
+	 *
+	 * @private
+	 * @param {Object} payload
+	 * @returns {Object}
+	 */
+	prepareServerPayload(payload) {
+		payload = doTransform.call(this, "write", payload);
+		payload = doDiff.call(this, payload);
+
+		const sheathingObject = this.getOption("write.sheathing.object");
+		const sheathingPath = this.getOption("write.sheathing.path");
+
+		if (sheathingObject && sheathingPath) {
+			const sub = payload;
+			payload = sheathingObject;
+			new Pathfinder(payload).setVia(sheathingPath, sub);
+		}
+
+		return payload;
+	}
 }
 
 /**
- * 
+ *
  * @param obj
  * @returns {*}
  */
 function doDiff(obj) {
-    if (this[serverVersionSymbol] === null || this[serverVersionSymbol] === undefined) {
-        return obj;
-    }
-
-    const callback = this.getOption("write.partial.callback");
-    if (!isFunction(callback)) {
-        return obj;
-    }
-
-    const results = diff(this[serverVersionSymbol], obj);
-    if (!results) {
-        return obj;
-    }
-
-    obj = callback(obj, results);
-    this[serverVersionSymbol] = obj;
-
-    return obj;
+	if (
+		this[serverVersionSymbol] === null ||
+		this[serverVersionSymbol] === undefined
+	) {
+		return obj;
+	}
+
+	const callback = this.getOption("write.partial.callback");
+	if (!isFunction(callback)) {
+		return obj;
+	}
+
+	const results = diff(this[serverVersionSymbol], obj);
+	if (!results) {
+		return obj;
+	}
+
+	obj = callback(obj, results);
+	this[serverVersionSymbol] = obj;
+
+	return obj;
 }
 
 /**
@@ -123,32 +125,32 @@ function doDiff(obj) {
  * @returns {Object}
  */
 function doTransform(type, obj) {
-    const transformation = this.getOption(`${type}.mapping.transformer`);
-    if (transformation !== undefined && transformation !== null) {
-        const pipe = new Pipe(transformation);
-        const callbacks = this.getOption(`${type}.mapping.callbacks`);
-
-        if (isArray(callbacks)) {
-            for (const callback of callbacks) {
-                if (typeof callback === "function") {
-                    pipe.setCallback(callback);
-                }
-            }
-        }
-
-        if (isObject(callbacks)) {
-            for (const key in callbacks) {
-                if (
-                    callbacks.hasOwnProperty(key) &&
-                    typeof callbacks[key] === "function"
-                ) {
-                    pipe.setCallback(key, callbacks[key]);
-                }
-            }
-        }
-
-        obj = pipe.run(obj);
-    }
-
-    return obj;
+	const transformation = this.getOption(`${type}.mapping.transformer`);
+	if (transformation !== undefined && transformation !== null) {
+		const pipe = new Pipe(transformation);
+		const callbacks = this.getOption(`${type}.mapping.callbacks`);
+
+		if (isArray(callbacks)) {
+			for (const callback of callbacks) {
+				if (typeof callback === "function") {
+					pipe.setCallback(callback);
+				}
+			}
+		}
+
+		if (isObject(callbacks)) {
+			for (const key in callbacks) {
+				if (
+					callbacks.hasOwnProperty(key) &&
+					typeof callbacks[key] === "function"
+				) {
+					pipe.setCallback(key, callbacks[key]);
+				}
+			}
+		}
+
+		obj = pipe.run(obj);
+	}
+
+	return obj;
 }
diff --git a/source/data/datasource/server/restapi.mjs b/source/data/datasource/server/restapi.mjs
index d6f92235f..e2ab688f4 100644
--- a/source/data/datasource/server/restapi.mjs
+++ b/source/data/datasource/server/restapi.mjs
@@ -12,14 +12,14 @@
  * SPDX-License-Identifier: AGPL-3.0
  */
 
-import {internalSymbol, instanceSymbol} from "../../../constants.mjs";
-import {isObject, isFunction, isArray} from "../../../types/is.mjs";
-import {diff} from "../../diff.mjs";
-import {Server} from "../server.mjs";
-import {WriteError} from "./restapi/writeerror.mjs";
-import {DataFetchError} from "./restapi/data-fetch-error.mjs";
+import { internalSymbol, instanceSymbol } from "../../../constants.mjs";
+import { isObject, isFunction, isArray } from "../../../types/is.mjs";
+import { diff } from "../../diff.mjs";
+import { Server } from "../server.mjs";
+import { WriteError } from "./restapi/writeerror.mjs";
+import { DataFetchError } from "./restapi/data-fetch-error.mjs";
 
-export {RestAPI};
+export { RestAPI };
 
 /**
  * @type {symbol}
@@ -28,10 +28,9 @@ export {RestAPI};
  * @since 3.12.0
  */
 const rawDataSymbol = Symbol.for(
-    "@schukai/monster/data/datasource/server/restapi/rawdata",
+	"@schukai/monster/data/datasource/server/restapi/rawdata",
 );
 
-
 /**
  * The RestAPI is a class that enables a REST API server.
  *
@@ -43,145 +42,145 @@ const rawDataSymbol = Symbol.for(
  * @summary The RestAPI is a class that binds a REST API server.
  */
 class RestAPI extends Server {
-    /**
-     *
-     * @param {Object} [options] options contains definitions for the datasource.
-     */
-    constructor(options) {
-        super();
-
-        if (isObject(options)) {
-            this.setOptions(options);
-        }
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/data/datasource/server/restapi");
-    }
-
-    /**
-     * @property {Object} write={} Options
-     * @property {Object} write.init={} An options object containing any custom settings that you want to apply to the request. The parameters are identical to those of the {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request|Request constructor}
-     * @property {string} write.init.method=POST
-     * @property {Object} write.init.headers Object containing any custom headers that you want to apply to the request.
-     * @property {string} write.responseCallback Callback function to be executed after the request has been completed.
-     * @property {string} write.acceptedStatus=[200,201]
-     * @property {string} write.url URL
-     * @property {Object} write.mapping the mapping is applied before writing.
-     * @property {String} write.mapping.transformer Transformer to select the appropriate entries
-     * @property {Monster.Data.Datasource~exampleCallback[]} write.mapping.callback with the help of the callback, the structures can be adjusted before writing.
-     * @property {Object} write.report
-     * @property {String} write.report.path Path to validations
-     * @property {Object} write.partial
-     * @property {Function} write.partial.callback Callback function to be executed after the request has been completed. (obj, diffResult) => obj
-     * @property {Object} write.sheathing
-     * @property {Object} write.sheathing.object Object to be wrapped
-     * @property {string} write.sheathing.path Path to the data
-     * @property {Object} read={} Options
-     * @property {Object} read.init={} An options object containing any custom settings that you want to apply to the request. The parameters are identical to those of the {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request|Request constructor}
-     * @property {string} read.init.method=GET
-     * @property {string} read.acceptedStatus=[200]
-     * @property {string} read.url URL
-     * @property {Object} read.mapping the mapping is applied after reading.
-     * @property {String} read.mapping.transformer Transformer to select the appropriate entries
-     * @property {Monster.Data.Datasource~exampleCallback[]} read.mapping.callback with the help of the callback, the structures can be adjusted after reading.
-     */
-    get defaults() {
-        return Object.assign({}, super.defaults, {
-            write: {
-                init: {
-                    method: "POST",
-                },
-                responseCallback: undefined,
-                acceptedStatus: [200, 201],
-                url: null,
-                mapping: {
-                    transformer: undefined,
-                    callbacks: [],
-                },
-                sheathing: {
-                    object: undefined,
-                    path: undefined,
-                },
-                report: {
-                    path: undefined,
-                },
-
-                partial: {
-                    callback: null,
-                }
-            },
-            read: {
-                init: {
-                    method: "GET",
-                },
-                responseCallback: undefined,
-                acceptedStatus: [200],
-                url: null,
-                mapping: {
-                    transformer: undefined,
-                    callbacks: [],
-                },
-            },
-        });
-    }
-
-    /**
-     * @return {Promise}
-     * @throws {Error} the options does not contain a valid json definition
-     * @throws {TypeError} value is not a object
-     * @throws {Error} the data cannot be read
-     */
-    read() {
-        let init = this.getOption("read.init");
-        if (!isObject(init)) init = {};
-        if (!init["method"]) init["method"] = "GET";
-
-        let callback = this.getOption("read.responseCallback");
-        if (!callback) {
-            callback = (obj) => {
-                this.set(this.transformServerPayload.call(this, obj));
-            };
-        }
-
-        return fetchData.call(this, init, "read", callback);
-    }
-
-    /**
-     * @return {Promise}
-     * @throws {WriteError} the data cannot be written
-     */
-    write() {
-        let init = this.getOption("write.init");
-        if (!isObject(init)) init = {};
-        if (typeof init["headers"] !== "object") {
-            init["headers"] = {
-                "Content-Type": "application/json",
-            };
-        }
-        if (!init["method"]) init["method"] = "POST";
-
-        const obj = this.prepareServerPayload(this.get());
-        init["body"] = JSON.stringify(obj);
-
-        const callback = this.getOption("write.responseCallback");
-        return fetchData.call(this, init, "write", callback);
-    }
-
-    /**
-     * @return {RestAPI}
-     */
-    getClone() {
-        return new RestAPI(
-            this[internalSymbol].getRealSubject()["options"].read,
-            this[internalSymbol].getRealSubject()["options"].write,
-        );
-    }
+	/**
+	 *
+	 * @param {Object} [options] options contains definitions for the datasource.
+	 */
+	constructor(options) {
+		super();
+
+		if (isObject(options)) {
+			this.setOptions(options);
+		}
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/data/datasource/server/restapi");
+	}
+
+	/**
+	 * @property {Object} write={} Options
+	 * @property {Object} write.init={} An options object containing any custom settings that you want to apply to the request. The parameters are identical to those of the {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request|Request constructor}
+	 * @property {string} write.init.method=POST
+	 * @property {Object} write.init.headers Object containing any custom headers that you want to apply to the request.
+	 * @property {string} write.responseCallback Callback function to be executed after the request has been completed.
+	 * @property {string} write.acceptedStatus=[200,201]
+	 * @property {string} write.url URL
+	 * @property {Object} write.mapping the mapping is applied before writing.
+	 * @property {String} write.mapping.transformer Transformer to select the appropriate entries
+	 * @property {Monster.Data.Datasource~exampleCallback[]} write.mapping.callback with the help of the callback, the structures can be adjusted before writing.
+	 * @property {Object} write.report
+	 * @property {String} write.report.path Path to validations
+	 * @property {Object} write.partial
+	 * @property {Function} write.partial.callback Callback function to be executed after the request has been completed. (obj, diffResult) => obj
+	 * @property {Object} write.sheathing
+	 * @property {Object} write.sheathing.object Object to be wrapped
+	 * @property {string} write.sheathing.path Path to the data
+	 * @property {Object} read={} Options
+	 * @property {Object} read.init={} An options object containing any custom settings that you want to apply to the request. The parameters are identical to those of the {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request|Request constructor}
+	 * @property {string} read.init.method=GET
+	 * @property {string} read.acceptedStatus=[200]
+	 * @property {string} read.url URL
+	 * @property {Object} read.mapping the mapping is applied after reading.
+	 * @property {String} read.mapping.transformer Transformer to select the appropriate entries
+	 * @property {Monster.Data.Datasource~exampleCallback[]} read.mapping.callback with the help of the callback, the structures can be adjusted after reading.
+	 */
+	get defaults() {
+		return Object.assign({}, super.defaults, {
+			write: {
+				init: {
+					method: "POST",
+				},
+				responseCallback: undefined,
+				acceptedStatus: [200, 201],
+				url: null,
+				mapping: {
+					transformer: undefined,
+					callbacks: [],
+				},
+				sheathing: {
+					object: undefined,
+					path: undefined,
+				},
+				report: {
+					path: undefined,
+				},
+
+				partial: {
+					callback: null,
+				},
+			},
+			read: {
+				init: {
+					method: "GET",
+				},
+				responseCallback: undefined,
+				acceptedStatus: [200],
+				url: null,
+				mapping: {
+					transformer: undefined,
+					callbacks: [],
+				},
+			},
+		});
+	}
+
+	/**
+	 * @return {Promise}
+	 * @throws {Error} the options does not contain a valid json definition
+	 * @throws {TypeError} value is not a object
+	 * @throws {Error} the data cannot be read
+	 */
+	read() {
+		let init = this.getOption("read.init");
+		if (!isObject(init)) init = {};
+		if (!init["method"]) init["method"] = "GET";
+
+		let callback = this.getOption("read.responseCallback");
+		if (!callback) {
+			callback = (obj) => {
+				this.set(this.transformServerPayload.call(this, obj));
+			};
+		}
+
+		return fetchData.call(this, init, "read", callback);
+	}
+
+	/**
+	 * @return {Promise}
+	 * @throws {WriteError} the data cannot be written
+	 */
+	write() {
+		let init = this.getOption("write.init");
+		if (!isObject(init)) init = {};
+		if (typeof init["headers"] !== "object") {
+			init["headers"] = {
+				"Content-Type": "application/json",
+			};
+		}
+		if (!init["method"]) init["method"] = "POST";
+
+		const obj = this.prepareServerPayload(this.get());
+		init["body"] = JSON.stringify(obj);
+
+		const callback = this.getOption("write.responseCallback");
+		return fetchData.call(this, init, "write", callback);
+	}
+
+	/**
+	 * @return {RestAPI}
+	 */
+	getClone() {
+		return new RestAPI(
+			this[internalSymbol].getRealSubject()["options"].read,
+			this[internalSymbol].getRealSubject()["options"].write,
+		);
+	}
 }
 
 /**
@@ -192,47 +191,50 @@ class RestAPI extends Server {
  * @returns {Promise<string>}
  */
 function fetchData(init, key, callback) {
-    let response;
-
-    return fetch(this.getOption(`${key}.url`), init)
-        .then((resp) => {
-            response = resp;
-
-            const acceptedStatus = this.getOption(`${key}.acceptedStatus`, [200]).map(Number);
-
-            if (acceptedStatus.indexOf(resp.status) === -1) {
-                throw new DataFetchError(
-                    `the response does not contain an accepted status (actual: ${resp.status}).`,
-                    response,
-                );
-            }
-
-            return resp.text();
-        })
-        .then((body) => {
-            let obj;
-
-            try {
-                obj = JSON.parse(body);
-
-                response[rawDataSymbol] = obj;
-            } catch (e) {
-                if (body.length > 100) {
-                    body = `${body.substring(0, 97)}...`;
-                }
-
-                throw new DataFetchError(
-                    `the response does not contain a valid json (actual: ${body}).`,
-                    response,
-                );
-            }
-
-            if (callback && isFunction(callback)) {
-                callback(obj);
-            }
-
-            return response;
-        }).catch((e) => {
-            throw e;
-        });
+	let response;
+
+	return fetch(this.getOption(`${key}.url`), init)
+		.then((resp) => {
+			response = resp;
+
+			const acceptedStatus = this.getOption(`${key}.acceptedStatus`, [200]).map(
+				Number,
+			);
+
+			if (acceptedStatus.indexOf(resp.status) === -1) {
+				throw new DataFetchError(
+					`the response does not contain an accepted status (actual: ${resp.status}).`,
+					response,
+				);
+			}
+
+			return resp.text();
+		})
+		.then((body) => {
+			let obj;
+
+			try {
+				obj = JSON.parse(body);
+
+				response[rawDataSymbol] = obj;
+			} catch (e) {
+				if (body.length > 100) {
+					body = `${body.substring(0, 97)}...`;
+				}
+
+				throw new DataFetchError(
+					`the response does not contain a valid json (actual: ${body}).`,
+					response,
+				);
+			}
+
+			if (callback && isFunction(callback)) {
+				callback(obj);
+			}
+
+			return response;
+		})
+		.catch((e) => {
+			throw e;
+		});
 }
-- 
GitLab