diff --git a/README.md b/README.md
index 331c9772e1e04b397e29395982a9c98334451619..2be7f483c20ac2dce27372dbc0dd323f633ea375 100644
--- a/README.md
+++ b/README.md
@@ -1,18 +1,21 @@
 # Monster
 
-Monster is perfectly suited for the creation of beautiful and fast  
-user interfaces and websites.
+Monster is an ideal choice for building visually appealing and high-performance web interfaces 
+and websites using modern JavaScript web development techniques.
 
-Monster relies on proven concepts mixed with many new JavaScript concepts such as 
-classes, WeakRef, WeakMaps, proxies or the MutationObserver interface, just to name a few.
+Leveraging cutting-edge JavaScript features such as classes, WeakRef, WeakMaps, proxies, 
+and the MutationObserver interface, Monster offers a blend of tried-and-true methods and 
+innovative web components.
 
-Monster integrates easily into your existing websites without taking over everything.
+Designed for seamless integration, Monster complements your existing web projects 
+without dominating the entire architecture.
 
-It is not the goal of Monster to pull in an entirely new abstraction
-with its own language, but to combine the existing techniques of HTML,  
-CSS and JavaScript in a meaningful way.
+Unlike solutions that introduce a whole new layer of abstraction and proprietary 
+languages, Monster focuses on enhancing the native capabilities of HTML, CSS, and 
+JavaScript for web development.
 
-One design target is to reach the shiny sun with as little JavaScript as possible.
+With a design objective to optimize performance and achieve stellar outcomes, 
+Monster aims to accomplish this using minimal JavaScript code.
 
 Monster was built with ES6 modules and uses [import](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/import)  
 and [export](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export).
@@ -73,7 +76,7 @@ We do try to work around some browser bugs, but on the whole we don't use polyfi
 However, many functions can be mapped via [polyfill.io](https://polyfill.io/) and thus the compatibility can be increased.
 
 ```html
-<script id="polyfill" src="https://polyfill.io/v3/polyfill.min.js?features=Array.from,Array.isArray,Array.prototype.entries,Array.prototype.fill,Array.prototype.filter,Array.prototype.forEach,Array.prototype.includes,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.sort,ArrayBuffer,atob,Blob,CustomEvent,DataView,document,Document,DocumentFragment,Element,Event,fetch,globalThis,HTMLDocument,HTMLTemplateElement,Intl,JSON,Map,Math.log2,MutationObserver,Number.isInteger,Object.assign,Object.defineProperty,Object.entries,Object.freeze,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.keys,Promise,Reflect,Reflect.defineProperty,Reflect.get,Reflect.getOwnPropertyDescriptor,Reflect.setPrototypeOf,Set,String.prototype.endsWith,String.prototype.includes,String.prototype.matchAll,String.prototype.padStart,String.prototype.startsWith,String.prototype.trim,Symbol,Symbol.for,Symbol.hasInstance,Symbol.iterator,Uint16Array,Uint8Array,URL,WeakMap,WeakSet"
+<script id="polyfill" src="https://Set"
        crossorigin="anonymous"
        referrerpolicy="no-referrer"></script>
 ```
@@ -99,4 +102,4 @@ You can also purchase a commercial license.
 ## Changelog
 
 Detailed changes for each release are documented in
-the [CHANGELOG](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/blob/master/application/CHANGELOG).
+the [CHANGELOG](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/blob/master/application/CHANGELOG.md).
diff --git a/source/constraints/abstract.mjs b/source/constraints/abstract.mjs
index 319cd227bf6aca90e48f353d9e1a990826dba7d0..01cf37e7d2684afb0b146bee65274393941e8685 100644
--- a/source/constraints/abstract.mjs
+++ b/source/constraints/abstract.mjs
@@ -26,29 +26,29 @@ export { AbstractConstraint };
  * @summary The abstract constraint
  */
 class AbstractConstraint extends Base {
-    /**
-     *
-     */
-    constructor() {
-        super();
-    }
+	/**
+	 *
+	 */
+	constructor() {
+		super();
+	}
 
-    /**
-     * this method must return a promise containing the result of the check.
-     *
-     * @param {*} value
-     * @returns {Promise}
-     */
-    isValid(value) {
-        return Promise.reject(value);
-    }
+	/**
+	 * this method must return a promise containing the result of the check.
+	 *
+	 * @param {*} value
+	 * @returns {Promise}
+	 */
+	isValid(value) {
+		return Promise.reject(value);
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/constraints/abstract-constraint");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/constraints/abstract-constraint");
+	}
 }
diff --git a/source/constraints/abstractoperator.mjs b/source/constraints/abstractoperator.mjs
index a35762a47d09318b1f2333e7e28e9520890ef9c9..8c2f9c3c69de49b16cb48549a08fc65b97921970 100644
--- a/source/constraints/abstractoperator.mjs
+++ b/source/constraints/abstractoperator.mjs
@@ -24,29 +24,34 @@ export { AbstractOperator };
  * @summary The abstract operator constraint
  */
 class AbstractOperator extends AbstractConstraint {
-    /**
-     *
-     * @param {AbstractConstraint} operantA
-     * @param {AbstractConstraint} operantB
-     * @throws {TypeError} "parameters must be from type AbstractConstraint"
-     */
-    constructor(operantA, operantB) {
-        super();
+	/**
+	 *
+	 * @param {AbstractConstraint} operantA
+	 * @param {AbstractConstraint} operantB
+	 * @throws {TypeError} "parameters must be from type AbstractConstraint"
+	 */
+	constructor(operantA, operantB) {
+		super();
 
-        if (!(operantA instanceof AbstractConstraint && operantB instanceof AbstractConstraint)) {
-            throw new TypeError("parameters must be from type AbstractConstraint");
-        }
+		if (
+			!(
+				operantA instanceof AbstractConstraint &&
+				operantB instanceof AbstractConstraint
+			)
+		) {
+			throw new TypeError("parameters must be from type AbstractConstraint");
+		}
 
-        this.operantA = operantA;
-        this.operantB = operantB;
-    }
+		this.operantA = operantA;
+		this.operantB = operantB;
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/constraints/abstract-operator");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/constraints/abstract-operator");
+	}
 }
diff --git a/source/constraints/andoperator.mjs b/source/constraints/andoperator.mjs
index cf8b3ea0cb78a4128ddc4193bbd43311d3af9feb..d2f03788efdce7841d8ca7ee0cb1e0003dd1ee50 100644
--- a/source/constraints/andoperator.mjs
+++ b/source/constraints/andoperator.mjs
@@ -24,22 +24,25 @@ export { AndOperator };
  * @summary A and operator constraint
  */
 class AndOperator extends AbstractOperator {
-    /**
-     * this method return a promise containing the result of the check.
-     *
-     * @param {*} value
-     * @returns {Promise}
-     */
-    isValid(value) {
-        return Promise.all([this.operantA.isValid(value), this.operantB.isValid(value)]);
-    }
+	/**
+	 * this method return a promise containing the result of the check.
+	 *
+	 * @param {*} value
+	 * @returns {Promise}
+	 */
+	isValid(value) {
+		return Promise.all([
+			this.operantA.isValid(value),
+			this.operantB.isValid(value),
+		]);
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/constraints/and-operator");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/constraints/and-operator");
+	}
 }
diff --git a/source/constraints/invalid.mjs b/source/constraints/invalid.mjs
index a79faf373df22151c5723e10c4accc6bf2d795d2..2ca75ab90b53018c4a85dddf483c24a5957fe270 100644
--- a/source/constraints/invalid.mjs
+++ b/source/constraints/invalid.mjs
@@ -24,22 +24,22 @@ export { Invalid };
  * @summary A constraint that always invalid
  */
 class Invalid extends AbstractConstraint {
-    /**
-     * this method return a rejected promise
-     *
-     * @param {*} value
-     * @returns {Promise}
-     */
-    isValid(value) {
-        return Promise.reject(value);
-    }
+	/**
+	 * this method return a rejected promise
+	 *
+	 * @param {*} value
+	 * @returns {Promise}
+	 */
+	isValid(value) {
+		return Promise.reject(value);
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/constraints/invalid");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/constraints/invalid");
+	}
 }
diff --git a/source/constraints/isarray.mjs b/source/constraints/isarray.mjs
index 5ccd4aad2953ed681e9b5373a3f91bf382793ede..791728c18debb47ce9a584633e07ee25a7752154 100644
--- a/source/constraints/isarray.mjs
+++ b/source/constraints/isarray.mjs
@@ -23,26 +23,26 @@ export { IsArray };
  * @summary A constraint to check if a value is an array
  */
 class IsArray extends AbstractConstraint {
-    /**
-     * this method return a promise containing the result of the check.
-     *
-     * @param {*} value
-     * @returns {Promise}
-     */
-    isValid(value) {
-        if (isArray(value)) {
-            return Promise.resolve(value);
-        }
+	/**
+	 * this method return a promise containing the result of the check.
+	 *
+	 * @param {*} value
+	 * @returns {Promise}
+	 */
+	isValid(value) {
+		if (isArray(value)) {
+			return Promise.resolve(value);
+		}
 
-        return Promise.reject(value);
-    }
+		return Promise.reject(value);
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/constraint/is-array");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/constraint/is-array");
+	}
 }
diff --git a/source/constraints/isobject.mjs b/source/constraints/isobject.mjs
index 7c829f77616d3ce959e7b9abdf648c556ea94a0f..158685e32dd9ad6b9f9dcf9a6494a1166a3ce11e 100644
--- a/source/constraints/isobject.mjs
+++ b/source/constraints/isobject.mjs
@@ -23,26 +23,26 @@ export { IsObject };
  * @summary A constraint to check if a value is an object
  */
 class IsObject extends AbstractConstraint {
-    /**
-     * this method return a promise containing the result of the check.
-     *
-     * @param {*} value
-     * @returns {Promise}
-     */
-    isValid(value) {
-        if (isObject(value)) {
-            return Promise.resolve(value);
-        }
+	/**
+	 * this method return a promise containing the result of the check.
+	 *
+	 * @param {*} value
+	 * @returns {Promise}
+	 */
+	isValid(value) {
+		if (isObject(value)) {
+			return Promise.resolve(value);
+		}
 
-        return Promise.reject(value);
-    }
+		return Promise.reject(value);
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/constraint/is-object");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/constraint/is-object");
+	}
 }
diff --git a/source/constraints/oroperator.mjs b/source/constraints/oroperator.mjs
index f1de51399da6f21891286192942edc7920d755a5..df931873f8012a51e3a077e0ebe92b87a17a6042 100644
--- a/source/constraints/oroperator.mjs
+++ b/source/constraints/oroperator.mjs
@@ -24,53 +24,53 @@ export { OrOperator };
  * @summary A or operator
  */
 class OrOperator extends AbstractOperator {
-    /**
-     * this method return a promise containing the result of the check.
-     *
-     * @param {*} value
-     * @returns {Promise}
-     */
-    isValid(value) {
-        var self = this;
+	/**
+	 * this method return a promise containing the result of the check.
+	 *
+	 * @param {*} value
+	 * @returns {Promise}
+	 */
+	isValid(value) {
+		var self = this;
 
-        return new Promise(function (resolve, reject) {
-            let a;
-            let b;
+		return new Promise(function (resolve, reject) {
+			let a;
+			let b;
 
-            self.operantA
-                .isValid(value)
-                .then(function () {
-                    resolve();
-                })
-                .catch(function () {
-                    a = false;
-                    /** b has already been evaluated and was not true */
-                    if (b === false) {
-                        reject();
-                    }
-                });
+			self.operantA
+				.isValid(value)
+				.then(function () {
+					resolve();
+				})
+				.catch(function () {
+					a = false;
+					/** b has already been evaluated and was not true */
+					if (b === false) {
+						reject();
+					}
+				});
 
-            self.operantB
-                .isValid(value)
-                .then(function () {
-                    resolve();
-                })
-                .catch(function () {
-                    b = false;
-                    /** b has already been evaluated and was not true */
-                    if (a === false) {
-                        reject();
-                    }
-                });
-        });
-    }
+			self.operantB
+				.isValid(value)
+				.then(function () {
+					resolve();
+				})
+				.catch(function () {
+					b = false;
+					/** b has already been evaluated and was not true */
+					if (a === false) {
+						reject();
+					}
+				});
+		});
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/constraints/or-operator");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/constraints/or-operator");
+	}
 }
diff --git a/source/constraints/valid.mjs b/source/constraints/valid.mjs
index cec2c287a486d7dd70176fb1f5ddc8b0134aac85..7ca7a2bf8cfd77d16a6fc3dcb9160fa6453fe7c8 100644
--- a/source/constraints/valid.mjs
+++ b/source/constraints/valid.mjs
@@ -24,22 +24,22 @@ export { Valid };
  * @summary A constraint that always valid
  */
 class Valid extends AbstractConstraint {
-    /**
-     * this method return a promise containing the result of the check.
-     *
-     * @param {*} value
-     * @returns {Promise}
-     */
-    isValid(value) {
-        return Promise.resolve(value);
-    }
+	/**
+	 * this method return a promise containing the result of the check.
+	 *
+	 * @param {*} value
+	 * @returns {Promise}
+	 */
+	isValid(value) {
+		return Promise.resolve(value);
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/constraints/valid");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/constraints/valid");
+	}
 }
diff --git a/source/data/buildmap.mjs b/source/data/buildmap.mjs
index a6c4b9821e8a56d96b1ab611b1e1bc56196f9fca..e39b69c9738c95c11298e16c6093ca2e98798ce7 100644
--- a/source/data/buildmap.mjs
+++ b/source/data/buildmap.mjs
@@ -40,11 +40,11 @@ const PARENT = "^";
  * @throws {TypeError} - If the selector callback does not return a map.
  **/
 function buildMap(subject, selector, valueTemplate, keyTemplate, filter) {
-    return assembleParts(subject, selector, filter, function (v, k, m) {
-        k = build(v, keyTemplate, k);
-        v = build(v, valueTemplate);
-        this.set(k, v);
-    });
+	return assembleParts(subject, selector, filter, function (v, k, m) {
+		k = build(v, keyTemplate, k);
+		v = build(v, valueTemplate);
+		this.set(k, v);
+	});
 }
 
 /**
@@ -110,34 +110,34 @@ function buildMap(subject, selector, valueTemplate, keyTemplate, filter) {
  * @memberOf Monster.Data
  */
 function assembleParts(subject, selector, filter, callback) {
-    const result = new Map();
-
-    let map;
-    if (isFunction(selector)) {
-        map = selector(subject);
-        if (!(map instanceof Map)) {
-            throw new TypeError("the selector callback must return a map");
-        }
-    } else if (isString(selector)) {
-        map = new Map();
-        buildFlatMap.call(map, subject, selector);
-    } else {
-        throw new TypeError("selector is neither a string nor a function");
-    }
-
-    if (!(map instanceof Map)) {
-        return result;
-    }
-
-    map.forEach((v, k, m) => {
-        if (isFunction(filter)) {
-            if (filter.call(m, v, k) !== true) return;
-        }
-
-        callback.call(result, v, k, m);
-    });
-
-    return result;
+	const result = new Map();
+
+	let map;
+	if (isFunction(selector)) {
+		map = selector(subject);
+		if (!(map instanceof Map)) {
+			throw new TypeError("the selector callback must return a map");
+		}
+	} else if (isString(selector)) {
+		map = new Map();
+		buildFlatMap.call(map, subject, selector);
+	} else {
+		throw new TypeError("selector is neither a string nor a function");
+	}
+
+	if (!(map instanceof Map)) {
+		return result;
+	}
+
+	map.forEach((v, k, m) => {
+		if (isFunction(filter)) {
+			if (filter.call(m, v, k) !== true) return;
+		}
+
+		callback.call(result, v, k, m);
+	});
+
+	return result;
 }
 
 /**
@@ -149,58 +149,64 @@ function assembleParts(subject, selector, filter, callback) {
  * @return {*}
  */
 function buildFlatMap(subject, selector, key, parentMap) {
-    const result = this;
-    const currentMap = new Map();
-
-    const resultLength = result.size;
-
-    if (key === undefined) key = [];
-
-    let parts = selector.split(DELIMITER);
-    let current = "";
-    let currentPath = [];
-    do {
-        current = parts.shift();
-        currentPath.push(current);
-
-        if (current === WILDCARD) {
-            let finder = new Pathfinder(subject);
-            let map;
-
-            try {
-                map = finder.getVia(currentPath.join(DELIMITER));
-            } catch (e) {
-                let a = e;
-                map = new Map();
-            }
-
-            for (const [k, o] of map) {
-                let copyKey = clone(key);
-
-                currentPath.map((a) => {
-                    copyKey.push(a === WILDCARD ? k : a);
-                });
-
-                let kk = copyKey.join(DELIMITER);
-                let sub = buildFlatMap.call(result, o, parts.join(DELIMITER), copyKey, o);
-
-                if (isObject(sub) && parentMap !== undefined) {
-                    sub[PARENT] = parentMap;
-                }
-
-                currentMap.set(kk, sub);
-            }
-        }
-    } while (parts.length > 0);
-
-    // no set in child run
-    if (resultLength === result.size) {
-        for (const [k, o] of currentMap) {
-            result.set(k, o);
-        }
-    }
-
-    return subject;
+	const result = this;
+	const currentMap = new Map();
+
+	const resultLength = result.size;
+
+	if (key === undefined) key = [];
+
+	let parts = selector.split(DELIMITER);
+	let current = "";
+	let currentPath = [];
+	do {
+		current = parts.shift();
+		currentPath.push(current);
+
+		if (current === WILDCARD) {
+			let finder = new Pathfinder(subject);
+			let map;
+
+			try {
+				map = finder.getVia(currentPath.join(DELIMITER));
+			} catch (e) {
+				let a = e;
+				map = new Map();
+			}
+
+			for (const [k, o] of map) {
+				let copyKey = clone(key);
+
+				currentPath.map((a) => {
+					copyKey.push(a === WILDCARD ? k : a);
+				});
+
+				let kk = copyKey.join(DELIMITER);
+				let sub = buildFlatMap.call(
+					result,
+					o,
+					parts.join(DELIMITER),
+					copyKey,
+					o,
+				);
+
+				if (isObject(sub) && parentMap !== undefined) {
+					sub[PARENT] = parentMap;
+				}
+
+				currentMap.set(kk, sub);
+			}
+		}
+	} while (parts.length > 0);
+
+	// no set in child run
+	if (resultLength === result.size) {
+		for (const [k, o] of currentMap) {
+			result.set(k, o);
+		}
+	}
+
+	return subject;
 }
 
 /**
@@ -354,30 +360,30 @@ function buildFlatMap(subject, selector, key, parentMap) {
  * @return {*}
  */
 function build(subject, definition, defaultValue) {
-    if (definition === undefined) return defaultValue ? defaultValue : subject;
-    validateString(definition);
+	if (definition === undefined) return defaultValue ? defaultValue : subject;
+	validateString(definition);
 
-    const regexp = /(?<placeholder>\${(?<path>[a-z\^A-Z.\-_0-9]*)})/gm;
-    const array = [...definition.matchAll(regexp)];
+	const regexp = /(?<placeholder>\${(?<path>[a-z\^A-Z.\-_0-9]*)})/gm;
+	const array = [...definition.matchAll(regexp)];
 
-    let finder = new Pathfinder(subject);
+	let finder = new Pathfinder(subject);
 
-    if (array.length === 0) {
-        return finder.getVia(definition);
-    }
+	if (array.length === 0) {
+		return finder.getVia(definition);
+	}
 
-    array.forEach((a) => {
-        let groups = a?.["groups"];
-        let placeholder = groups?.["placeholder"];
-        if (placeholder === undefined) return;
+	array.forEach((a) => {
+		let groups = a?.["groups"];
+		let placeholder = groups?.["placeholder"];
+		if (placeholder === undefined) return;
 
-        let path = groups?.["path"];
+		let path = groups?.["path"];
 
-        let v = finder.getVia(path);
-        if (v === undefined) v = defaultValue;
+		let v = finder.getVia(path);
+		if (v === undefined) v = defaultValue;
 
-        definition = definition.replaceAll(placeholder, v);
-    });
+		definition = definition.replaceAll(placeholder, v);
+	});
 
-    return definition;
+	return definition;
 }
diff --git a/source/data/buildtree.mjs b/source/data/buildtree.mjs
index 3a36a9c1041abd3a51c4cc95716ab9dedf31ec48..a477e50f11a7c37d07a2a71025e813b7bbe82c8e 100644
--- a/source/data/buildtree.mjs
+++ b/source/data/buildtree.mjs
@@ -132,61 +132,63 @@ const rootSymbol = Symbol("root");
  * @since 1.26.0
  */
 function buildTree(subject, selector, idKey, parentIDKey, options) {
-    const nodes = new Map();
-
-    if (!isObject(options)) {
-        options = {};
-    }
-
-    options = extend(
-        {},
-        {
-            rootReferences: [null, undefined],
-            filter: undefined,
-        },
-        options,
-    );
-
-    const filter = options?.filter;
-    let rootReferences = options.rootReferences;
-    if (!isArray(rootReferences)) {
-        rootReferences = [rootReferences];
-    }
-
-    const childMap = assembleParts(subject, selector, filter, function (o, k, m) {
-        const key = o?.[idKey];
-        let ref = o?.[parentIDKey];
-        if (rootReferences.indexOf(ref) !== -1) ref = rootSymbol;
-
-        if (key === undefined) {
-            throw new Error("the object has no value for the specified id");
-        }
-
-        o[parentSymbol] = ref;
-
-        const node = new Node(o);
-        this.has(ref) ? this.get(ref).add(node) : this.set(ref, new NodeList().add(node));
-        nodes.set(key, node);
-    });
-
-    nodes.forEach((node) => {
-        let id = node?.["value"]?.[idKey];
-
-        if (childMap.has(id)) {
-            node.childNodes = childMap.get(id);
-            childMap.delete(id);
-        }
-    });
-
-    const list = new NodeList();
-
-    childMap.forEach((s) => {
-        if (s instanceof Set) {
-            s.forEach((n) => {
-                list.add(n);
-            });
-        }
-    });
-
-    return list;
+	const nodes = new Map();
+
+	if (!isObject(options)) {
+		options = {};
+	}
+
+	options = extend(
+		{},
+		{
+			rootReferences: [null, undefined],
+			filter: undefined,
+		},
+		options,
+	);
+
+	const filter = options?.filter;
+	let rootReferences = options.rootReferences;
+	if (!isArray(rootReferences)) {
+		rootReferences = [rootReferences];
+	}
+
+	const childMap = assembleParts(subject, selector, filter, function (o, k, m) {
+		const key = o?.[idKey];
+		let ref = o?.[parentIDKey];
+		if (rootReferences.indexOf(ref) !== -1) ref = rootSymbol;
+
+		if (key === undefined) {
+			throw new Error("the object has no value for the specified id");
+		}
+
+		o[parentSymbol] = ref;
+
+		const node = new Node(o);
+		this.has(ref)
+			? this.get(ref).add(node)
+			: this.set(ref, new NodeList().add(node));
+		nodes.set(key, node);
+	});
+
+	nodes.forEach((node) => {
+		let id = node?.["value"]?.[idKey];
+
+		if (childMap.has(id)) {
+			node.childNodes = childMap.get(id);
+			childMap.delete(id);
+		}
+	});
+
+	const list = new NodeList();
+
+	childMap.forEach((s) => {
+		if (s instanceof Set) {
+			s.forEach((n) => {
+				list.add(n);
+			});
+		}
+	});
+
+	return list;
 }
diff --git a/source/data/datasource.mjs b/source/data/datasource.mjs
index 31f4d20de61fddf73338c8504691d2961d8f2aae..40bdea95f8f6968153c8edd79d0f593502bf0a62 100644
--- a/source/data/datasource.mjs
+++ b/source/data/datasource.mjs
@@ -34,7 +34,9 @@ export { Datasource };
  * @license AGPLv3
  * @since 1.24.0
  */
-const internalDataSymbol = Symbol.for("@schukai/monster/data/datasource/@@data");
+const internalDataSymbol = Symbol.for(
+	"@schukai/monster/data/datasource/@@data",
+);
 
 /**
  * The datasource class is the basis for dealing with different data sources.
@@ -47,155 +49,164 @@ const internalDataSymbol = Symbol.for("@schukai/monster/data/datasource/@@data")
  * @summary The datasource class encapsulates the access to data objects.
  */
 class Datasource extends Base {
-    /**
-     * creates a new datasource
-     *
-     */
-    constructor() {
-        super();
-
-        this[internalSymbol] = new ProxyObserver({
-            options: extend({}, this.defaults),
-        });
-
-        this[internalDataSymbol] = new ProxyObserver({});
-    }
-
-    /**
-     * attach a new observer
-     *
-     * @param {Observer} observer
-     * @returns {Datasource}
-     */
-    attachObserver(observer) {
-        this[internalDataSymbol].attachObserver(observer);
-        return this;
-    }
-
-    /**
-     * detach a observer
-     *
-     * @param {Observer} observer
-     * @returns {Datasource}
-     */
-    detachObserver(observer) {
-        this[internalDataSymbol].detachObserver(observer);
-        return this;
-    }
-
-    /**
-     * @param {Observer} observer
-     * @returns {boolean}
-     */
-    containsObserver(observer) {
-        return this[internalDataSymbol].containsObserver(observer);
-    }
-
-    /**
-     * Derived classes can override and extend this method as follows.
-     *
-     * ```
-     * get defaults() {
-     *    return Object.assign({}, super.defaults, {
-     *        myValue:true
-     *    });
-     * }
-     * ```
-     */
-    get defaults() {
-        return {};
-    }
-
-    /**
-     * Set option
-     *
-     * @param {string} path
-     * @param {*} value
-     * @return {Datasource}
-     */
-    setOption(path, value) {
-        new Pathfinder(this[internalSymbol].getSubject()["options"]).setVia(path, value);
-        return this;
-    }
-
-    /**
-     * @param {string|object} options
-     * @return {Datasource}
-     * @throws {Error} the options does not contain a valid json definition
-     */
-    setOptions(options) {
-        if (isString(options)) {
-            options = parseOptionsJSON(options);
-        }
-
-        const self = this;
-        extend(self[internalSymbol].getSubject()["options"], self.defaults, options);
-
-        return self;
-    }
-
-    /**
-     * nested options can be specified by path `a.b.c`
-     *
-     * @param {string} path
-     * @param {*} defaultValue
-     * @return {*}
-     */
-    getOption(path, defaultValue) {
-        let value;
-
-        try {
-            value = new Pathfinder(this[internalSymbol].getRealSubject()["options"]).getVia(path);
-        } catch (e) {}
-
-        if (value === undefined) return defaultValue;
-        return value;
-    }
-
-    /**
-     * @throws {Error} this method must be implemented by derived classes.
-     * @return {Promise}
-     */
-    read() {
-        throw new Error("this method must be implemented by derived classes");
-    }
-
-    /**
-     * @throws {Error} this method must be implemented by derived classes.
-     * @return {Promise}
-     */
-    write() {
-        throw new Error("this method must be implemented by derived classes");
-    }
-
-    /**
-     * Returns real object
-     *
-     * @return {Object|Array}
-     */
-    get() {
-        const self = this;
-        return self[internalDataSymbol].getRealSubject();
-    }
-
-    /**
-     * @param {Object|Array} data
-     * @return {Datasource}
-     */
-    set(data) {
-        const self = this;
-        self[internalDataSymbol].setSubject(data);
-        return self;
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/data/datasource");
-    }
+	/**
+	 * creates a new datasource
+	 *
+	 */
+	constructor() {
+		super();
+
+		this[internalSymbol] = new ProxyObserver({
+			options: extend({}, this.defaults),
+		});
+
+		this[internalDataSymbol] = new ProxyObserver({});
+	}
+
+	/**
+	 * attach a new observer
+	 *
+	 * @param {Observer} observer
+	 * @returns {Datasource}
+	 */
+	attachObserver(observer) {
+		this[internalDataSymbol].attachObserver(observer);
+		return this;
+	}
+
+	/**
+	 * detach a observer
+	 *
+	 * @param {Observer} observer
+	 * @returns {Datasource}
+	 */
+	detachObserver(observer) {
+		this[internalDataSymbol].detachObserver(observer);
+		return this;
+	}
+
+	/**
+	 * @param {Observer} observer
+	 * @returns {boolean}
+	 */
+	containsObserver(observer) {
+		return this[internalDataSymbol].containsObserver(observer);
+	}
+
+	/**
+	 * Derived classes can override and extend this method as follows.
+	 *
+	 * ```
+	 * get defaults() {
+	 *    return Object.assign({}, super.defaults, {
+	 *        myValue:true
+	 *    });
+	 * }
+	 * ```
+	 */
+	get defaults() {
+		return {};
+	}
+
+	/**
+	 * Set option
+	 *
+	 * @param {string} path
+	 * @param {*} value
+	 * @return {Datasource}
+	 */
+	setOption(path, value) {
+		new Pathfinder(this[internalSymbol].getSubject()["options"]).setVia(
+			path,
+			value,
+		);
+		return this;
+	}
+
+	/**
+	 * @param {string|object} options
+	 * @return {Datasource}
+	 * @throws {Error} the options does not contain a valid json definition
+	 */
+	setOptions(options) {
+		if (isString(options)) {
+			options = parseOptionsJSON(options);
+		}
+
+		const self = this;
+		extend(
+			self[internalSymbol].getSubject()["options"],
+			self.defaults,
+			options,
+		);
+
+		return self;
+	}
+
+	/**
+	 * nested options can be specified by path `a.b.c`
+	 *
+	 * @param {string} path
+	 * @param {*} defaultValue
+	 * @return {*}
+	 */
+	getOption(path, defaultValue) {
+		let value;
+
+		try {
+			value = new Pathfinder(
+				this[internalSymbol].getRealSubject()["options"],
+			).getVia(path);
+		} catch (e) {}
+
+		if (value === undefined) return defaultValue;
+		return value;
+	}
+
+	/**
+	 * @throws {Error} this method must be implemented by derived classes.
+	 * @return {Promise}
+	 */
+	read() {
+		throw new Error("this method must be implemented by derived classes");
+	}
+
+	/**
+	 * @throws {Error} this method must be implemented by derived classes.
+	 * @return {Promise}
+	 */
+	write() {
+		throw new Error("this method must be implemented by derived classes");
+	}
+
+	/**
+	 * Returns real object
+	 *
+	 * @return {Object|Array}
+	 */
+	get() {
+		const self = this;
+		return self[internalDataSymbol].getRealSubject();
+	}
+
+	/**
+	 * @param {Object|Array} data
+	 * @return {Datasource}
+	 */
+	set(data) {
+		const self = this;
+		self[internalDataSymbol].setSubject(data);
+		return self;
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/data/datasource");
+	}
 }
 
 /**
@@ -205,21 +216,23 @@ class Datasource extends Base {
  * @throws {Error} the options does not contain a valid json definition
  */
 function parseOptionsJSON(data) {
-    if (isString(data)) {
-        // the configuration can be specified as a data url.
-        try {
-            let dataUrl = parseDataURL(data);
-            data = dataUrl.content;
-        } catch (e) {}
-
-        try {
-            let obj = JSON.parse(data);
-            validateObject(obj);
-            return obj;
-        } catch (e) {
-            throw new Error(`the options does not contain a valid json definition (actual: ${data}).`);
-        }
-    }
-
-    return {};
+	if (isString(data)) {
+		// the configuration can be specified as a data url.
+		try {
+			let dataUrl = parseDataURL(data);
+			data = dataUrl.content;
+		} catch (e) {}
+
+		try {
+			let obj = JSON.parse(data);
+			validateObject(obj);
+			return obj;
+		} catch (e) {
+			throw new Error(
+				`the options does not contain a valid json definition (actual: ${data}).`,
+			);
+		}
+	}
+
+	return {};
 }
diff --git a/source/data/datasource/dom.mjs b/source/data/datasource/dom.mjs
index 749ab68f55f015b8185264fad1308a077055d846..8dc566d88777698379761be733c2fe48c9297fe1 100644
--- a/source/data/datasource/dom.mjs
+++ b/source/data/datasource/dom.mjs
@@ -19,97 +19,97 @@ export { DomStorage };
  * @memberOf Monster.Data.Datasource
  */
 class DomStorage extends Datasource {
-    /**
-     * @param {Object} [options] options contains definitions for the datasource.
-     */
-    constructor(options) {
-        super();
+	/**
+	 * @param {Object} [options] options contains definitions for the datasource.
+	 */
+	constructor(options) {
+		super();
 
-        if (isObject(options)) {
-            this.setOptions(options);
-        }
-    }
+		if (isObject(options)) {
+			this.setOptions(options);
+		}
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/data/datasource/storage/dom-storage");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/data/datasource/storage/dom-storage");
+	}
 
-    /**
-     * @property {Object} defaults
-     * @property {Object} defaults.read
-     * @property {string} defaults.read.selector
-     * @property {Object} defaults.write
-     * @property {string} defaults.write.selector
-     */
-    get defaults() {
-        return Object.assign({}, super.defaults, {
-            read: {
-                selector: undefined,
-            },
-            write: {
-                selector: undefined,
-            },
-        });
-    }
+	/**
+	 * @property {Object} defaults
+	 * @property {Object} defaults.read
+	 * @property {string} defaults.read.selector
+	 * @property {Object} defaults.write
+	 * @property {string} defaults.write.selector
+	 */
+	get defaults() {
+		return Object.assign({}, super.defaults, {
+			read: {
+				selector: undefined,
+			},
+			write: {
+				selector: undefined,
+			},
+		});
+	}
 
-    /**
-     * @return {Promise}
-     * @throws {Error} The read selector is not defined
-     * @throws {Error} There are no storage element
-     */
-    read() {
-        const self = this;
+	/**
+	 * @return {Promise}
+	 * @throws {Error} The read selector is not defined
+	 * @throws {Error} There are no storage element
+	 */
+	read() {
+		const self = this;
 
-        let selector = self.getOption("read.selector", undefined);
-        if (!selector) {
-            throw new Error("The read selector is not defined");
-        }
+		let selector = self.getOption("read.selector", undefined);
+		if (!selector) {
+			throw new Error("The read selector is not defined");
+		}
 
-        let storage = document.querySelector(selector);
-        if (!storage) {
-            throw new Error("There are no storage element");
-        }
+		let storage = document.querySelector(selector);
+		if (!storage) {
+			throw new Error("There are no storage element");
+		}
 
-        return new Promise((resolve, reject) => {
-            try {
-                let data = JSON.parse(storage.innerHTML);
-                self.set(data);
-                resolve(data);
-            } catch (e) {
-                reject(e);
-            }
-        });
-    }
+		return new Promise((resolve, reject) => {
+			try {
+				let data = JSON.parse(storage.innerHTML);
+				self.set(data);
+				resolve(data);
+			} catch (e) {
+				reject(e);
+			}
+		});
+	}
 
-    /**
-     * @return {Promise}
-     * @throws {Error} The write selector is not defined
-     * @throws {Error} There are no storage element
-     */
-    write() {
-        const self = this;
+	/**
+	 * @return {Promise}
+	 * @throws {Error} The write selector is not defined
+	 * @throws {Error} There are no storage element
+	 */
+	write() {
+		const self = this;
 
-        let selector = self.getOption("write.selector");
-        if (!selector) {
-            throw new Error("The write selector is not defined");
-        }
+		let selector = self.getOption("write.selector");
+		if (!selector) {
+			throw new Error("The write selector is not defined");
+		}
 
-        let storage = document.querySelector(selector);
-        if (!storage) {
-            throw new Error("There are no storage element");
-        }
+		let storage = document.querySelector(selector);
+		if (!storage) {
+			throw new Error("There are no storage element");
+		}
 
-        return new Promise((resolve, reject) => {
-            try {
-                storage.innerHTML = JSON.stringify(self.get());
-                resolve(storage);
-            } catch (e) {
-                reject(e);
-            }
-        });
-    }
+		return new Promise((resolve, reject) => {
+			try {
+				storage.innerHTML = JSON.stringify(self.get());
+				resolve(storage);
+			} catch (e) {
+				reject(e);
+			}
+		});
+	}
 }
diff --git a/source/data/datasource/server.mjs b/source/data/datasource/server.mjs
index c0a2c11eeebc6a74821a297660cb51bc7bbaaa2e..29840708ed8a6033415086647f9f46d9a0b4fe40 100644
--- a/source/data/datasource/server.mjs
+++ b/source/data/datasource/server.mjs
@@ -23,57 +23,57 @@ export { Server };
  * @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 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) {
-        const self = this;
-        payload = doTransform.call(self, "read", payload);
+	/**
+	 * This prepares the data that comes from the server.
+	 * Should not be called directly.
+	 *
+	 * @private
+	 * @param {Object} payload
+	 * @returns {Object}
+	 */
+	transformServerPayload(payload) {
+		const self = this;
+		payload = doTransform.call(self, "read", payload);
 
-        const dataPath = self.getOption("read.path");
-        if (dataPath) {
-            payload = new Pathfinder(payload).getVia(dataPath);
-        }
+		const dataPath = self.getOption("read.path");
+		if (dataPath) {
+			payload = new Pathfinder(payload).getVia(dataPath);
+		}
 
-        return payload;
-    }
+		return payload;
+	}
 
-    /**
-     * This prepares the data for writing and should not be called directly.
-     *
-     * @private
-     * @param {Object} payload
-     * @returns {Object}
-     */
-    prepareServerPayload(payload) {
-        const self = this;
+	/**
+	 * This prepares the data for writing and should not be called directly.
+	 *
+	 * @private
+	 * @param {Object} payload
+	 * @returns {Object}
+	 */
+	prepareServerPayload(payload) {
+		const self = this;
 
-        payload = doTransform.call(self, "write", payload);
+		payload = doTransform.call(self, "write", payload);
 
-        let sheathingObject = self.getOption("write.sheathing.object");
-        let sheathingPath = self.getOption("write.sheathing.path");
+		let sheathingObject = self.getOption("write.sheathing.object");
+		let sheathingPath = self.getOption("write.sheathing.path");
 
-        if (sheathingObject && sheathingPath) {
-            const sub = payload;
-            payload = sheathingObject;
-            new Pathfinder(payload).setVia(sheathingPath, sub);
-        }
+		if (sheathingObject && sheathingPath) {
+			const sub = payload;
+			payload = sheathingObject;
+			new Pathfinder(payload).setVia(sheathingPath, sub);
+		}
 
-        return payload;
-    }
+		return payload;
+	}
 }
 
 /**
@@ -83,22 +83,25 @@ class Server extends Datasource {
  * @returns {*}
  */
 function doTransform(type, obj) {
-    const self = this;
-    let transformation = self.getOption(`${type}.mapping.transformer`);
-    if (transformation !== undefined) {
-        const pipe = new Pipe(transformation);
-        const callbacks = self.getOption(`${type}.mapping.callbacks`);
+	const self = this;
+	let transformation = self.getOption(`${type}.mapping.transformer`);
+	if (transformation !== undefined) {
+		const pipe = new Pipe(transformation);
+		const callbacks = self.getOption(`${type}.mapping.callbacks`);
 
-        if (isObject(callbacks)) {
-            for (const key in callbacks) {
-                if (callbacks.hasOwnProperty(key) && typeof callbacks[key] === "function") {
-                    pipe.setCallback(key, callbacks[key]);
-                }
-            }
-        }
+		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);
-    }
+		obj = pipe.run(obj);
+	}
 
-    return obj;
+	return obj;
 }
diff --git a/source/data/datasource/server/restapi.mjs b/source/data/datasource/server/restapi.mjs
index d476fbc96b2088a6206bc6ed37e3d9405161970b..5d8f108191c8459ccf9e3e1c79f2c6d56d2df3d0 100644
--- a/source/data/datasource/server/restapi.mjs
+++ b/source/data/datasource/server/restapi.mjs
@@ -19,7 +19,9 @@ export { RestAPI };
  * @license AGPLv3
  * @since 3.12.0
  */
-const rawDataSymbol = Symbol.for("@schukai/monster/data/datasource/server/restapi/rawdata");
+const rawDataSymbol = Symbol.for(
+	"@schukai/monster/data/datasource/server/restapi/rawdata",
+);
 
 /**
  * The RestAPI is a class that enables a REST API server.
@@ -32,143 +34,143 @@ const rawDataSymbol = Symbol.for("@schukai/monster/data/datasource/server/restap
  * @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.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: undefined,
-                mapping: {
-                    transformer: undefined,
-                    callbacks: [],
-                },
-                sheathing: {
-                    object: undefined,
-                    path: undefined,
-                },
-                report: {
-                    path: undefined,
-                },
-            },
-            read: {
-                init: {
-                    method: "GET",
-                },
-                responseCallback: undefined,
-                acceptedStatus: [200],
-                url: undefined,
-                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() {
-        const self = this;
-
-        let init = self.getOption("read.init");
-        if (!isObject(init)) init = {};
-        if (!init["method"]) init["method"] = "GET";
-
-        let callback = self.getOption("read.responseCallback");
-        if (!callback)
-            callback = (obj) => {
-                self.set(self.transformServerPayload.call(self, obj));
-            };
-
-        return fetchData.call(this, init, "read", callback);
-    }
-
-    /**
-     * @return {Promise}
-     * @throws {WriteError} the data cannot be written
-     */
-    write() {
-        const self = this;
-
-        let init = self.getOption("write.init");
-        if (!isObject(init)) init = {};
-        if (typeof init["headers"] !== "object") {
-            init["headers"] = {
-                "Content-Type": "application/json",
-            };
-        }
-        if (!init["method"]) init["method"] = "POST";
-
-        let obj = self.prepareServerPayload(self.get());
-        init["body"] = JSON.stringify(obj);
-
-        let callback = self.getOption("write.responseCallback");
-        return fetchData.call(this, init, "write", callback);
-    }
-
-    /**
-     * @return {RestAPI}
-     */
-    getClone() {
-        const self = this;
-        return new RestAPI(
-            self[internalSymbol].getRealSubject()["options"].read,
-            self[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.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: undefined,
+				mapping: {
+					transformer: undefined,
+					callbacks: [],
+				},
+				sheathing: {
+					object: undefined,
+					path: undefined,
+				},
+				report: {
+					path: undefined,
+				},
+			},
+			read: {
+				init: {
+					method: "GET",
+				},
+				responseCallback: undefined,
+				acceptedStatus: [200],
+				url: undefined,
+				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() {
+		const self = this;
+
+		let init = self.getOption("read.init");
+		if (!isObject(init)) init = {};
+		if (!init["method"]) init["method"] = "GET";
+
+		let callback = self.getOption("read.responseCallback");
+		if (!callback)
+			callback = (obj) => {
+				self.set(self.transformServerPayload.call(self, obj));
+			};
+
+		return fetchData.call(this, init, "read", callback);
+	}
+
+	/**
+	 * @return {Promise}
+	 * @throws {WriteError} the data cannot be written
+	 */
+	write() {
+		const self = this;
+
+		let init = self.getOption("write.init");
+		if (!isObject(init)) init = {};
+		if (typeof init["headers"] !== "object") {
+			init["headers"] = {
+				"Content-Type": "application/json",
+			};
+		}
+		if (!init["method"]) init["method"] = "POST";
+
+		let obj = self.prepareServerPayload(self.get());
+		init["body"] = JSON.stringify(obj);
+
+		let callback = self.getOption("write.responseCallback");
+		return fetchData.call(this, init, "write", callback);
+	}
+
+	/**
+	 * @return {RestAPI}
+	 */
+	getClone() {
+		const self = this;
+		return new RestAPI(
+			self[internalSymbol].getRealSubject()["options"].read,
+			self[internalSymbol].getRealSubject()["options"].write,
+		);
+	}
 }
 
 /**
@@ -179,43 +181,46 @@ class RestAPI extends Server {
  * @returns {Promise<string>}
  */
 function fetchData(init, key, callback) {
-    const self = this;
-    let response;
-
-    return fetch(self.getOption(`${key}.url`), init)
-        .then((resp) => {
-            response = resp;
-
-            const acceptedStatus = self.getOption(`${key}.acceptedStatus`, [200]);
-
-            if (acceptedStatus.indexOf(resp.status) === -1) {
-                throw new DataFetchError(
-                    `the response does not contain a 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;
-        });
+	const self = this;
+	let response;
+
+	return fetch(self.getOption(`${key}.url`), init)
+		.then((resp) => {
+			response = resp;
+
+			const acceptedStatus = self.getOption(`${key}.acceptedStatus`, [200]);
+
+			if (acceptedStatus.indexOf(resp.status) === -1) {
+				throw new DataFetchError(
+					`the response does not contain a 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;
+		});
 }
diff --git a/source/data/datasource/server/restapi/data-fetch-error.mjs b/source/data/datasource/server/restapi/data-fetch-error.mjs
index 1e8b7c69427ad7101b0fe1135aca6a87b1eb17bc..87c3eb27f4f583c2148018020a1892ff294bf1d5 100644
--- a/source/data/datasource/server/restapi/data-fetch-error.mjs
+++ b/source/data/datasource/server/restapi/data-fetch-error.mjs
@@ -19,31 +19,33 @@ export { DataFetchError };
  * @summary the error is thrown by the rest api in case of error
  */
 class DataFetchError extends Error {
-    /**
-     *
-     * @param {string} message
-     * @param {Response} response
-     */
-    constructor(message, response) {
-        super(message);
-        this[internalSymbol] = {
-            response: response,
-        };
-    }
+	/**
+	 *
+	 * @param {string} message
+	 * @param {Response} response
+	 */
+	constructor(message, response) {
+		super(message);
+		this[internalSymbol] = {
+			response: response,
+		};
+	}
 
-    /**
-     * 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/datafetcherror@@instance");
-    }
+	/**
+	 * 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/datafetcherror@@instance",
+		);
+	}
 
-    /**
-     * @return {Response}
-     */
-    getResponse() {
-        return this[internalSymbol]["response"];
-    }
+	/**
+	 * @return {Response}
+	 */
+	getResponse() {
+		return this[internalSymbol]["response"];
+	}
 }
diff --git a/source/data/datasource/server/restapi/writeerror.mjs b/source/data/datasource/server/restapi/writeerror.mjs
index f4796b4929f5a6057b64ba184e74b39c4b99ad33..307308dc2326c718a431ff3646fd257b8fde3b4e 100644
--- a/source/data/datasource/server/restapi/writeerror.mjs
+++ b/source/data/datasource/server/restapi/writeerror.mjs
@@ -19,39 +19,41 @@ export { WriteError };
  * @summary the error is thrown by the rest api in case of error
  */
 class WriteError extends Error {
-    /**
-     *
-     * @param {string} message
-     * @param {Response} response
-     */
-    constructor(message, response, validation) {
-        super(message);
-        this[internalSymbol] = {
-            response: response,
-            validation: validation,
-        };
-    }
+	/**
+	 *
+	 * @param {string} message
+	 * @param {Response} response
+	 */
+	constructor(message, response, validation) {
+		super(message);
+		this[internalSymbol] = {
+			response: response,
+			validation: validation,
+		};
+	}
 
-    /**
-     * 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/writeerror");
-    }
+	/**
+	 * 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/writeerror",
+		);
+	}
 
-    /**
-     * @return {Response}
-     */
-    getResponse() {
-        return this[internalSymbol]["response"];
-    }
+	/**
+	 * @return {Response}
+	 */
+	getResponse() {
+		return this[internalSymbol]["response"];
+	}
 
-    /**
-     * @return {Object}
-     */
-    getValidation() {
-        return this[internalSymbol]["validation"];
-    }
+	/**
+	 * @return {Object}
+	 */
+	getValidation() {
+		return this[internalSymbol]["validation"];
+	}
 }
diff --git a/source/data/datasource/server/webconnect.mjs b/source/data/datasource/server/webconnect.mjs
index d866716d33164e7eb96167b42c8af7e0570f45a8..614c149b053563bfacd7a9dc3c53a02d28af528e 100644
--- a/source/data/datasource/server/webconnect.mjs
+++ b/source/data/datasource/server/webconnect.mjs
@@ -32,159 +32,159 @@ const webConnectSymbol = Symbol("connection");
  * @summary The LocalStorage class encapsulates the access to data objects.
  */
 class WebConnect extends Server {
-    /**
-     *
-     * @param {Object} [options] options contains definitions for the datasource.
-     */
-    constructor(options) {
-        super();
-
-        const self = this;
-
-        if (isString(options)) {
-            options = { url: options };
-        }
-
-        if (!isObject(options)) options = {};
-        this.setOptions(options);
-        this[webConnectSymbol] = new NetWebConnect({
-            url: self.getOption("url"),
-            connection: {
-                timeout: self.getOption("connection.timeout"),
-                reconnect: {
-                    timeout: self.getOption("connection.reconnect.timeout"),
-                    attempts: self.getOption("connection.reconnect.attempts"),
-                    enabled: self.getOption("connection.reconnect.enabled"),
-                },
-            },
-        });
-    }
-
-    /**
-     *
-     * @returns {Promise}
-     */
-    connect() {
-        return this[webConnectSymbol].connect();
-    }
-
-    /**
-     * @returns {boolean}
-     */
-    isConnected() {
-        return this[webConnectSymbol].isConnected();
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/data/datasource/server/webconnect");
-    }
-
-    /**
-     * @property {string} url=undefined Defines the resource that you wish to fetch.
-     * @property {Object} connection
-     * @property {Object} connection.timeout=5000 Defines the timeout for the connection.
-     * @property {Number} connection.reconnect.timeout The timeout in milliseconds for the reconnect.
-     * @property {Number} connection.reconnect.attempts The maximum number of reconnects.
-     * @property {Bool} connection.reconnect.enabled If the reconnect is enabled.
-     * @property {Object} write={} Options
-     * @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.sheathing
-     * @property {Object} write.sheathing.object Object to be wrapped
-     * @property {string} write.sheathing.path Path to the data
-     * @property {Object} read={} Options
-     * @property {String} read.path Path to data
-     * @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, {
-            url: undefined,
-            write: {
-                mapping: {
-                    transformer: undefined,
-                    callbacks: {},
-                },
-                sheathing: {
-                    object: undefined,
-                    path: undefined,
-                },
-            },
-            read: {
-                mapping: {
-                    transformer: undefined,
-                    callbacks: {},
-                },
-                path: undefined,
-            },
-            connection: {
-                timeout: 5000,
-                reconnect: {
-                    timeout: 1000,
-                    attempts: 1,
-                    enabled: false,
-                },
-            },
-        });
-    }
-
-    /**
-     * This method closes the connection.
-     *
-     * @returns {Promise}
-     */
-    close() {
-        return this[webConnectSymbol].close();
-    }
-
-    /**
-     * @return {Promise}
-     */
-    read() {
-        const self = this;
-
-        return new Promise((resolve, reject) => {
-            while (this[webConnectSymbol].dataReceived() === true) {
-                let obj = this[webConnectSymbol].poll();
-                if (!isObject(obj)) {
-                    reject(new Error("The received data is not an object."));
-                    return;
-                }
-
-                if (!(obj instanceof Message)) {
-                    reject(new Error("The received data is not a Message."));
-                    return;
-                }
-
-                obj = obj.getData();
-                obj = self.transformServerPayload.call(self, obj);
-                self.set(obj);
-            }
-
-            resolve(self.get());
-        });
-    }
-
-    /**
-     * @return {Promise}
-     */
-    write() {
-        const self = this;
-        let obj = self.prepareServerPayload(self.get());
-        return self[webConnectSymbol].send(obj);
-    }
-
-    /**
-     * @return {RestAPI}
-     */
-    getClone() {
-        const self = this;
-        return new WebConnect(self[internalSymbol].getRealSubject()["options"]);
-    }
+	/**
+	 *
+	 * @param {Object} [options] options contains definitions for the datasource.
+	 */
+	constructor(options) {
+		super();
+
+		const self = this;
+
+		if (isString(options)) {
+			options = { url: options };
+		}
+
+		if (!isObject(options)) options = {};
+		this.setOptions(options);
+		this[webConnectSymbol] = new NetWebConnect({
+			url: self.getOption("url"),
+			connection: {
+				timeout: self.getOption("connection.timeout"),
+				reconnect: {
+					timeout: self.getOption("connection.reconnect.timeout"),
+					attempts: self.getOption("connection.reconnect.attempts"),
+					enabled: self.getOption("connection.reconnect.enabled"),
+				},
+			},
+		});
+	}
+
+	/**
+	 *
+	 * @returns {Promise}
+	 */
+	connect() {
+		return this[webConnectSymbol].connect();
+	}
+
+	/**
+	 * @returns {boolean}
+	 */
+	isConnected() {
+		return this[webConnectSymbol].isConnected();
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/data/datasource/server/webconnect");
+	}
+
+	/**
+	 * @property {string} url=undefined Defines the resource that you wish to fetch.
+	 * @property {Object} connection
+	 * @property {Object} connection.timeout=5000 Defines the timeout for the connection.
+	 * @property {Number} connection.reconnect.timeout The timeout in milliseconds for the reconnect.
+	 * @property {Number} connection.reconnect.attempts The maximum number of reconnects.
+	 * @property {Bool} connection.reconnect.enabled If the reconnect is enabled.
+	 * @property {Object} write={} Options
+	 * @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.sheathing
+	 * @property {Object} write.sheathing.object Object to be wrapped
+	 * @property {string} write.sheathing.path Path to the data
+	 * @property {Object} read={} Options
+	 * @property {String} read.path Path to data
+	 * @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, {
+			url: undefined,
+			write: {
+				mapping: {
+					transformer: undefined,
+					callbacks: {},
+				},
+				sheathing: {
+					object: undefined,
+					path: undefined,
+				},
+			},
+			read: {
+				mapping: {
+					transformer: undefined,
+					callbacks: {},
+				},
+				path: undefined,
+			},
+			connection: {
+				timeout: 5000,
+				reconnect: {
+					timeout: 1000,
+					attempts: 1,
+					enabled: false,
+				},
+			},
+		});
+	}
+
+	/**
+	 * This method closes the connection.
+	 *
+	 * @returns {Promise}
+	 */
+	close() {
+		return this[webConnectSymbol].close();
+	}
+
+	/**
+	 * @return {Promise}
+	 */
+	read() {
+		const self = this;
+
+		return new Promise((resolve, reject) => {
+			while (this[webConnectSymbol].dataReceived() === true) {
+				let obj = this[webConnectSymbol].poll();
+				if (!isObject(obj)) {
+					reject(new Error("The received data is not an object."));
+					return;
+				}
+
+				if (!(obj instanceof Message)) {
+					reject(new Error("The received data is not a Message."));
+					return;
+				}
+
+				obj = obj.getData();
+				obj = self.transformServerPayload.call(self, obj);
+				self.set(obj);
+			}
+
+			resolve(self.get());
+		});
+	}
+
+	/**
+	 * @return {Promise}
+	 */
+	write() {
+		const self = this;
+		let obj = self.prepareServerPayload(self.get());
+		return self[webConnectSymbol].send(obj);
+	}
+
+	/**
+	 * @return {RestAPI}
+	 */
+	getClone() {
+		const self = this;
+		return new WebConnect(self[internalSymbol].getRealSubject()["options"]);
+	}
 }
diff --git a/source/data/datasource/storage.mjs b/source/data/datasource/storage.mjs
index 4cd6a6135c6a12aa3c9a1e59b5a90de7a9d4733f..e1f510257c9f9c435d1914985e239c7a4b54dc90 100644
--- a/source/data/datasource/storage.mjs
+++ b/source/data/datasource/storage.mjs
@@ -15,7 +15,9 @@ export { Storage, storageObjectSymbol };
  * @private
  * @type {symbol}
  */
-const storageObjectSymbol = Symbol.for("@schukai/monster/data/datasource/storage/@@storageObject");
+const storageObjectSymbol = Symbol.for(
+	"@schukai/monster/data/datasource/storage/@@storageObject",
+);
 
 /**
  * The class represents a record.
@@ -27,87 +29,87 @@ const storageObjectSymbol = Symbol.for("@schukai/monster/data/datasource/storage
  * @summary The Storage class encapsulates the access to data objects over WebStorageAPI.
  */
 class Storage extends Datasource {
-    /**
-     *
-     * @param {string} key LocalStorage Key
-     * @throws {TypeError} value is not a string
-     */
-    constructor(key) {
-        super();
-        this.setOption("key", validateString(key));
-    }
+	/**
+	 *
+	 * @param {string} key LocalStorage Key
+	 * @throws {TypeError} value is not a string
+	 */
+	constructor(key) {
+		super();
+		this.setOption("key", validateString(key));
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/data/datasource/storage");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/data/datasource/storage");
+	}
 
-    /**
-     * @property {string} key=undefined LocalStorage Key
-     */
-    get defaults() {
-        return Object.assign({}, super.defaults, {
-            key: undefined,
-        });
-    }
+	/**
+	 * @property {string} key=undefined LocalStorage Key
+	 */
+	get defaults() {
+		return Object.assign({}, super.defaults, {
+			key: undefined,
+		});
+	}
 
-    /**
-     * @throws {Error} this method must be implemented by derived classes.
-     * @return {external:Storage}
-     * @private
-     */
-    [storageObjectSymbol]() {
-        throw new Error("this method must be implemented by derived classes");
-    }
+	/**
+	 * @throws {Error} this method must be implemented by derived classes.
+	 * @return {external:Storage}
+	 * @private
+	 */
+	[storageObjectSymbol]() {
+		throw new Error("this method must be implemented by derived classes");
+	}
 
-    /**
-     * @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() {
-        const self = this;
+	/**
+	 * @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() {
+		const self = this;
 
-        const storage = self[storageObjectSymbol]();
+		const storage = self[storageObjectSymbol]();
 
-        return new Promise(function (resolve) {
-            const data = JSON.parse(storage.getItem(self.getOption("key")));
-            self.set(data ?? {});
-            resolve();
-        });
-    }
+		return new Promise(function (resolve) {
+			const data = JSON.parse(storage.getItem(self.getOption("key")));
+			self.set(data ?? {});
+			resolve();
+		});
+	}
 
-    /**
-     * @return {Storage}
-     * @throws {Error} the data cannot be written
-     */
-    write() {
-        const self = this;
+	/**
+	 * @return {Storage}
+	 * @throws {Error} the data cannot be written
+	 */
+	write() {
+		const self = this;
 
-        const storage = self[storageObjectSymbol]();
+		const storage = self[storageObjectSymbol]();
 
-        return new Promise(function (resolve) {
-            const data = self.get();
-            if (data === undefined) {
-                storage.removeItem(self.getOption("key"));
-            } else {
-                storage.setItem(self.getOption("key"), JSON.stringify(data));
-            }
+		return new Promise(function (resolve) {
+			const data = self.get();
+			if (data === undefined) {
+				storage.removeItem(self.getOption("key"));
+			} else {
+				storage.setItem(self.getOption("key"), JSON.stringify(data));
+			}
 
-            resolve();
-        });
-    }
+			resolve();
+		});
+	}
 
-    /**
-     * @return {Storage}
-     */
-    getClone() {
-        const self = this;
-        return new Storage(self[internalSymbol].getRealSubject()["options"].key);
-    }
+	/**
+	 * @return {Storage}
+	 */
+	getClone() {
+		const self = this;
+		return new Storage(self[internalSymbol].getRealSubject()["options"].key);
+	}
 }
diff --git a/source/data/datasource/storage/localstorage.mjs b/source/data/datasource/storage/localstorage.mjs
index 842d27cb1f2d5ca4dcf695ef2a97d79f28565b03..bf219dc9761cde3ae6b5a27089a1bbc8c0186fe9 100644
--- a/source/data/datasource/storage/localstorage.mjs
+++ b/source/data/datasource/storage/localstorage.mjs
@@ -22,30 +22,32 @@ export { LocalStorage };
  * @summary The LocalStorage class encapsulates the access to data objects.
  */
 class LocalStorage extends Storage {
-    /**
-     * @throws {Error} this method must be implemented by derived classes.
-     * @return {external:localStorage}
-     * @private
-     */
-    [storageObjectSymbol]() {
-        return getGlobalObject("localStorage");
-    }
+	/**
+	 * @throws {Error} this method must be implemented by derived classes.
+	 * @return {external:localStorage}
+	 * @private
+	 */
+	[storageObjectSymbol]() {
+		return getGlobalObject("localStorage");
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/data/datasource/storage/localstorage");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/data/datasource/storage/localstorage");
+	}
 
-    /**
-     * Create clone
-     * @return {LocalStorage}
-     */
-    getClone() {
-        const self = this;
-        return new LocalStorage(self[internalSymbol].getRealSubject()["options"].key);
-    }
+	/**
+	 * Create clone
+	 * @return {LocalStorage}
+	 */
+	getClone() {
+		const self = this;
+		return new LocalStorage(
+			self[internalSymbol].getRealSubject()["options"].key,
+		);
+	}
 }
diff --git a/source/data/datasource/storage/sessionstorage.mjs b/source/data/datasource/storage/sessionstorage.mjs
index c2928e9d7c8136d96f93684bf028e541c1d9938c..91da76dfe1697e338b98ecbad71533a7866623ce 100644
--- a/source/data/datasource/storage/sessionstorage.mjs
+++ b/source/data/datasource/storage/sessionstorage.mjs
@@ -22,31 +22,35 @@ export { SessionStorage };
  * @summary The LocalStorage class encapsulates the access to data objects.
  */
 class SessionStorage extends Storage {
-    /**
-     * @throws {Error} this method must be implemented by derived classes.
-     * @return {external:sessionStorage}
-     * @private
-     */
-    [storageObjectSymbol]() {
-        return getGlobalObject("sessionStorage");
-    }
+	/**
+	 * @throws {Error} this method must be implemented by derived classes.
+	 * @return {external:sessionStorage}
+	 * @private
+	 */
+	[storageObjectSymbol]() {
+		return getGlobalObject("sessionStorage");
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/data/datasource/storage/session-storage");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for(
+			"@schukai/monster/data/datasource/storage/session-storage",
+		);
+	}
 
-    /**
-     * Create Clone
-     *
-     * @return {SessionStorage}
-     */
-    getClone() {
-        const self = this;
-        return new SessionStorage(self[internalSymbol].getRealSubject()["options"].key);
-    }
+	/**
+	 * Create Clone
+	 *
+	 * @return {SessionStorage}
+	 */
+	getClone() {
+		const self = this;
+		return new SessionStorage(
+			self[internalSymbol].getRealSubject()["options"].key,
+		);
+	}
 }
diff --git a/source/data/diff.mjs b/source/data/diff.mjs
index 8b72b97e1018c99d6fe75ab72bdf9b6d41c52e14..1600a0c93d112c1dc07dfcb2b491742994231a5e 100644
--- a/source/data/diff.mjs
+++ b/source/data/diff.mjs
@@ -25,7 +25,7 @@ export { diff };
  * @memberOf Monster.Data
  */
 function diff(first, second) {
-    return doDiff(first, second);
+	return doDiff(first, second);
 }
 
 /**
@@ -36,13 +36,14 @@ function diff(first, second) {
  * @return {Set<string>|Set<number>}
  */
 function getKeys(a, b, type) {
-    if (isArray(type)) {
-        const keys = a.length > b.length ? new Array(a.length) : new Array(b.length);
-        keys.fill(0);
-        return new Set(keys.map((_, i) => i));
-    }
-
-    return new Set(Object.keys(a).concat(Object.keys(b)));
+	if (isArray(type)) {
+		const keys =
+			a.length > b.length ? new Array(a.length) : new Array(b.length);
+		keys.fill(0);
+		return new Set(keys.map((_, i) => i));
+	}
+
+	return new Set(Object.keys(a).concat(Object.keys(b)));
 }
 
 /**
@@ -54,30 +55,30 @@ function getKeys(a, b, type) {
  * @return {array}
  */
 function doDiff(a, b, path, diff) {
-    let typeA = typeOf(a);
-    let typeB = typeOf(b);
-
-    const currPath = path || [];
-    const currDiff = diff || [];
-
-    if (typeA === typeB && (typeA === "object" || typeA === "array")) {
-        getKeys(a, b, typeA).forEach((v) => {
-            if (!Object.prototype.hasOwnProperty.call(a, v)) {
-                currDiff.push(buildResult(a[v], b[v], "add", currPath.concat(v)));
-            } else if (!Object.prototype.hasOwnProperty.call(b, v)) {
-                currDiff.push(buildResult(a[v], b[v], "delete", currPath.concat(v)));
-            } else {
-                doDiff(a[v], b[v], currPath.concat(v), currDiff);
-            }
-        });
-    } else {
-        const o = getOperator(a, b, typeA, typeB);
-        if (o !== undefined) {
-            currDiff.push(buildResult(a, b, o, path));
-        }
-    }
-
-    return currDiff;
+	let typeA = typeOf(a);
+	let typeB = typeOf(b);
+
+	const currPath = path || [];
+	const currDiff = diff || [];
+
+	if (typeA === typeB && (typeA === "object" || typeA === "array")) {
+		getKeys(a, b, typeA).forEach((v) => {
+			if (!Object.prototype.hasOwnProperty.call(a, v)) {
+				currDiff.push(buildResult(a[v], b[v], "add", currPath.concat(v)));
+			} else if (!Object.prototype.hasOwnProperty.call(b, v)) {
+				currDiff.push(buildResult(a[v], b[v], "delete", currPath.concat(v)));
+			} else {
+				doDiff(a[v], b[v], currPath.concat(v), currDiff);
+			}
+		});
+	} else {
+		const o = getOperator(a, b, typeA, typeB);
+		if (o !== undefined) {
+			currDiff.push(buildResult(a, b, o, path));
+		}
+	}
+
+	return currDiff;
 }
 
 /**
@@ -90,40 +91,40 @@ function doDiff(a, b, path, diff) {
  * @private
  */
 function buildResult(a, b, operator, path) {
-    const result = {
-        operator,
-        path,
-    };
-
-    if (operator !== "add") {
-        result.first = {
-            value: a,
-            type: typeof a,
-        };
-
-        if (isObject(a)) {
-            const name = Object.getPrototypeOf(a)?.constructor?.name;
-            if (name !== undefined) {
-                result.first.instance = name;
-            }
-        }
-    }
-
-    if (operator === "add" || operator === "update") {
-        result.second = {
-            value: b,
-            type: typeof b,
-        };
-
-        if (isObject(b)) {
-            const name = Object.getPrototypeOf(b)?.constructor?.name;
-            if (name !== undefined) {
-                result.second.instance = name;
-            }
-        }
-    }
-
-    return result;
+	const result = {
+		operator,
+		path,
+	};
+
+	if (operator !== "add") {
+		result.first = {
+			value: a,
+			type: typeof a,
+		};
+
+		if (isObject(a)) {
+			const name = Object.getPrototypeOf(a)?.constructor?.name;
+			if (name !== undefined) {
+				result.first.instance = name;
+			}
+		}
+	}
+
+	if (operator === "add" || operator === "update") {
+		result.second = {
+			value: b,
+			type: typeof b,
+		};
+
+		if (isObject(b)) {
+			const name = Object.getPrototypeOf(b)?.constructor?.name;
+			if (name !== undefined) {
+				result.second.instance = name;
+			}
+		}
+	}
+
+	return result;
 }
 
 /**
@@ -133,15 +134,15 @@ function buildResult(a, b, operator, path) {
  * @return {boolean}
  */
 function isNotEqual(a, b) {
-    if (typeof a !== typeof b) {
-        return true;
-    }
+	if (typeof a !== typeof b) {
+		return true;
+	}
 
-    if (a instanceof Date && b instanceof Date) {
-        return a.getTime() !== b.getTime();
-    }
+	if (a instanceof Date && b instanceof Date) {
+		return a.getTime() !== b.getTime();
+	}
 
-    return a !== b;
+	return a !== b;
 }
 
 /**
@@ -151,28 +152,28 @@ function isNotEqual(a, b) {
  * @return {string|undefined}
  */
 function getOperator(a, b) {
-    /**
-     * @type {string|undefined}
-     */
-    let operator;
-
-    /**
-     * @type {string}
-     */
-    let typeA = typeof a;
-
-    /**
-     * @type {string}
-     */
-    let typeB = typeof b;
-
-    if (typeA === "undefined" && typeB !== "undefined") {
-        operator = "add";
-    } else if (typeA !== "undefined" && typeB === "undefined") {
-        operator = "delete";
-    } else if (isNotEqual(a, b)) {
-        operator = "update";
-    }
-
-    return operator;
+	/**
+	 * @type {string|undefined}
+	 */
+	let operator;
+
+	/**
+	 * @type {string}
+	 */
+	let typeA = typeof a;
+
+	/**
+	 * @type {string}
+	 */
+	let typeB = typeof b;
+
+	if (typeA === "undefined" && typeB !== "undefined") {
+		operator = "add";
+	} else if (typeA !== "undefined" && typeB === "undefined") {
+		operator = "delete";
+	} else if (isNotEqual(a, b)) {
+		operator = "update";
+	}
+
+	return operator;
 }
diff --git a/source/data/extend.mjs b/source/data/extend.mjs
index 649f24142af30958a1019a46aab354f3d229a46a..5b1f70d7d7533d98bdf5cebf658062e26d5aeba4 100644
--- a/source/data/extend.mjs
+++ b/source/data/extend.mjs
@@ -26,55 +26,55 @@ export { extend };
  * @throws {Error} unsupported argument
  */
 function extend(...args) {
-    let o;
-    let i;
+	let o;
+	let i;
 
-    if (typeof args !== "object" || args[0] === null) {
-        throw new Error(`unsupported argument ${JSON.stringify(args[0])}`);
-    }
+	if (typeof args !== "object" || args[0] === null) {
+		throw new Error(`unsupported argument ${JSON.stringify(args[0])}`);
+	}
 
-    for (i = 0; i < args.length; i++) {
-        let a = args[i];
+	for (i = 0; i < args.length; i++) {
+		let a = args[i];
 
-        if (!(isObject(a) || isArray(a))) {
-            throw new Error(`unsupported argument ${JSON.stringify(a)}`);
-        }
+		if (!(isObject(a) || isArray(a))) {
+			throw new Error(`unsupported argument ${JSON.stringify(a)}`);
+		}
 
-        if (o === undefined) {
-            o = a;
-            continue;
-        }
+		if (o === undefined) {
+			o = a;
+			continue;
+		}
 
-        for (let k in a) {
-            let v = a?.[k];
+		for (let k in a) {
+			let v = a?.[k];
 
-            if (v === o?.[k]) {
-                continue;
-            }
+			if (v === o?.[k]) {
+				continue;
+			}
 
-            if ((isObject(v) && typeOf(v) === "object") || isArray(v)) {
-                if (o[k] === undefined) {
-                    if (isArray(v)) {
-                        o[k] = [];
-                    } else {
-                        o[k] = {};
-                    }
-                } else {
-                    if (typeOf(o[k]) !== typeOf(v)) {
-                        throw new Error(
-                            `type mismatch: ${JSON.stringify(o[k])}(${typeOf(o[k])}) != ${JSON.stringify(v)}(${typeOf(
-                                v,
-                            )})`,
-                        );
-                    }
-                }
+			if ((isObject(v) && typeOf(v) === "object") || isArray(v)) {
+				if (o[k] === undefined) {
+					if (isArray(v)) {
+						o[k] = [];
+					} else {
+						o[k] = {};
+					}
+				} else {
+					if (typeOf(o[k]) !== typeOf(v)) {
+						throw new Error(
+							`type mismatch: ${JSON.stringify(o[k])}(${typeOf(
+								o[k],
+							)}) != ${JSON.stringify(v)}(${typeOf(v)})`,
+						);
+					}
+				}
 
-                o[k] = extend(o[k], v);
-            } else {
-                o[k] = v;
-            }
-        }
-    }
+				o[k] = extend(o[k], v);
+			} else {
+				o[k] = v;
+			}
+		}
+	}
 
-    return o;
+	return o;
 }
diff --git a/source/data/pathfinder.mjs b/source/data/pathfinder.mjs
index 8673210dd7d2284f0f0261ef7f3c3833c54d9636..602bad7cbad4c91842308ffe635af90fc3c2929b 100644
--- a/source/data/pathfinder.mjs
+++ b/source/data/pathfinder.mjs
@@ -6,9 +6,19 @@
  */
 
 import { Base } from "../types/base.mjs";
-import { isArray, isInteger, isObject, isPrimitive, isString } from "../types/is.mjs";
+import {
+	isArray,
+	isInteger,
+	isObject,
+	isPrimitive,
+	isString,
+} from "../types/is.mjs";
 import { Stack } from "../types/stack.mjs";
-import { validateInteger, validateBoolean, validateString } from "../types/validate.mjs";
+import {
+	validateInteger,
+	validateBoolean,
+	validateString,
+} from "../types/validate.mjs";
 
 export { Pathfinder, DELIMITER, WILDCARD };
 
@@ -72,99 +82,99 @@ const WILDCARD = "*";
  * @memberOf Monster.Data
  */
 class Pathfinder extends Base {
-    /**
-     * @param {array|object|Map|Set} value
-     * @since 1.4.0
-     * @throws  {Error} the parameter must not be a simple type
-     **/
-    constructor(object) {
-        super();
-
-        if (isPrimitive(object)) {
-            throw new Error("the parameter must not be a simple type");
-        }
-
-        this.object = object;
-        this.wildCard = WILDCARD;
-    }
-
-    /**
-     * set wildcard
-     *
-     * @param {string} wildcard
-     * @return {Pathfinder}
-     * @since 1.7.0
-     */
-    setWildCard(wildcard) {
-        validateString(wildcard);
-        this.wildCard = wildcard;
-        return this;
-    }
-
-    /**
-     *
-     * @param {string|array} path
-     * @since 1.4.0
-     * @returns {*}
-     * @throws {TypeError} unsupported type
-     * @throws {Error} the journey is not at its end
-     * @throws {TypeError} value is not a string
-     * @throws {TypeError} value is not an integer
-     * @throws {Error} unsupported action for this data type
-     */
-    getVia(path) {
-        return getValueViaPath.call(this, this.object, path);
-    }
-
-    /**
-     *
-     * @param {string|array} path
-     * @param {*} value
-     * @returns {Pathfinder}
-     * @since 1.4.0
-     * @throws {TypeError} unsupported type
-     * @throws {TypeError} value is not a string
-     * @throws {TypeError} value is not an integer
-     * @throws {Error} unsupported action for this data type
-     */
-    setVia(path, value) {
-        setValueViaPath.call(this, this.object, path, value);
-        return this;
-    }
-
-    /**
-     * Delete Via Path
-     *
-     * @param {string|array} path
-     * @returns {Pathfinder}
-     * @since 1.6.0
-     * @throws {TypeError} unsupported type
-     * @throws {TypeError} value is not a string
-     * @throws {TypeError} value is not an integer
-     * @throws {Error} unsupported action for this data type
-     */
-    deleteVia(path) {
-        deleteValueViaPath.call(this, this.object, path);
-        return this;
-    }
-
-    /**
-     *
-     * @param {string|array} path
-     * @return {bool}
-     * @throws {TypeError} unsupported type
-     * @throws {TypeError} value is not a string
-     * @throws {TypeError} value is not an integer
-     * @since 1.4.0
-     */
-    exists(path) {
-        try {
-            getValueViaPath.call(this, this.object, path, true);
-            return true;
-        } catch (e) {}
-
-        return false;
-    }
+	/**
+	 * @param {array|object|Map|Set} value
+	 * @since 1.4.0
+	 * @throws  {Error} the parameter must not be a simple type
+	 **/
+	constructor(object) {
+		super();
+
+		if (isPrimitive(object)) {
+			throw new Error("the parameter must not be a simple type");
+		}
+
+		this.object = object;
+		this.wildCard = WILDCARD;
+	}
+
+	/**
+	 * set wildcard
+	 *
+	 * @param {string} wildcard
+	 * @return {Pathfinder}
+	 * @since 1.7.0
+	 */
+	setWildCard(wildcard) {
+		validateString(wildcard);
+		this.wildCard = wildcard;
+		return this;
+	}
+
+	/**
+	 *
+	 * @param {string|array} path
+	 * @since 1.4.0
+	 * @returns {*}
+	 * @throws {TypeError} unsupported type
+	 * @throws {Error} the journey is not at its end
+	 * @throws {TypeError} value is not a string
+	 * @throws {TypeError} value is not an integer
+	 * @throws {Error} unsupported action for this data type
+	 */
+	getVia(path) {
+		return getValueViaPath.call(this, this.object, path);
+	}
+
+	/**
+	 *
+	 * @param {string|array} path
+	 * @param {*} value
+	 * @returns {Pathfinder}
+	 * @since 1.4.0
+	 * @throws {TypeError} unsupported type
+	 * @throws {TypeError} value is not a string
+	 * @throws {TypeError} value is not an integer
+	 * @throws {Error} unsupported action for this data type
+	 */
+	setVia(path, value) {
+		setValueViaPath.call(this, this.object, path, value);
+		return this;
+	}
+
+	/**
+	 * Delete Via Path
+	 *
+	 * @param {string|array} path
+	 * @returns {Pathfinder}
+	 * @since 1.6.0
+	 * @throws {TypeError} unsupported type
+	 * @throws {TypeError} value is not a string
+	 * @throws {TypeError} value is not an integer
+	 * @throws {Error} unsupported action for this data type
+	 */
+	deleteVia(path) {
+		deleteValueViaPath.call(this, this.object, path);
+		return this;
+	}
+
+	/**
+	 *
+	 * @param {string|array} path
+	 * @return {bool}
+	 * @throws {TypeError} unsupported type
+	 * @throws {TypeError} value is not a string
+	 * @throws {TypeError} value is not an integer
+	 * @since 1.4.0
+	 */
+	exists(path) {
+		try {
+			getValueViaPath.call(this, this.object, path, true);
+			return true;
+		} catch (e) {}
+
+		return false;
+	}
 }
 
 /**
@@ -179,27 +189,27 @@ class Pathfinder extends Base {
  * @private
  */
 function iterate(subject, path, check) {
-    if (check === undefined) {
-        check = false;
-    }
-    validateBoolean(check);
-
-    const result = new Map();
-
-    if (isArray(path)) {
-        path = path.join(DELIMITER);
-    }
-
-    if (isObject(subject) || isArray(subject)) {
-        for (const [key, value] of Object.entries(subject)) {
-            result.set(key, getValueViaPath.call(this, value, path, check));
-        }
-    } else {
-        let key = path.split(DELIMITER).shift();
-        result.set(key, getValueViaPath.call(this, subject, path, check));
-    }
-
-    return result;
+	if (check === undefined) {
+		check = false;
+	}
+	validateBoolean(check);
+
+	const result = new Map();
+
+	if (isArray(path)) {
+		path = path.join(DELIMITER);
+	}
+
+	if (isObject(subject) || isArray(subject)) {
+		for (const [key, value] of Object.entries(subject)) {
+			result.set(key, getValueViaPath.call(this, value, path, check));
+		}
+	} else {
+		let key = path.split(DELIMITER).shift();
+		result.set(key, getValueViaPath.call(this, subject, path, check));
+	}
+
+	return result;
 }
 
 /**
@@ -214,68 +224,71 @@ function iterate(subject, path, check) {
  * @private
  */
 function getValueViaPath(subject, path, check) {
-    if (check === undefined) {
-        check = false;
-    }
-    validateBoolean(check);
-
-    if (!(isArray(path) || isString(path))) {
-        throw new Error("type error: path must be a string or an array");
-    }
-
-    let parts;
-    if (isString(path)) {
-        if (path === "") {
-            return subject;
-        }
-
-        parts = path.split(DELIMITER);
-    }
-
-    let current = parts.shift();
-
-    if (current === this.wildCard) {
-        return iterate.call(this, subject, parts.join(DELIMITER), check);
-    }
-
-    if (isObject(subject) || isArray(subject)) {
-        let anchor;
-        if (subject instanceof Map || subject instanceof WeakMap) {
-            anchor = subject.get(current);
-        } else if (subject instanceof Set || subject instanceof WeakSet) {
-            current = parseInt(current);
-            validateInteger(current);
-            anchor = [...subject]?.[current];
-        } else if (typeof WeakRef === "function" && subject instanceof WeakRef) {
-            throw Error("unsupported action for this data type");
-        } else if (isArray(subject)) {
-            current = parseInt(current);
-            validateInteger(current);
-            anchor = subject?.[current];
-        } else {
-            anchor = subject?.[current];
-        }
-
-        if (isObject(anchor) || isArray(anchor)) {
-            return getValueViaPath.call(this, anchor, parts.join(DELIMITER), check);
-        }
-
-        if (parts.length > 0) {
-            throw Error(`the journey is not at its end (${parts.join(DELIMITER)})`);
-        }
-
-        if (check === true) {
-            const descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(subject), current);
-
-            if (!subject.hasOwnProperty(current) && descriptor === undefined) {
-                throw Error("unknown value");
-            }
-        }
-
-        return anchor;
-    }
-
-    throw TypeError(`unsupported type ${typeof subject}`);
+	if (check === undefined) {
+		check = false;
+	}
+	validateBoolean(check);
+
+	if (!(isArray(path) || isString(path))) {
+		throw new Error("type error: path must be a string or an array");
+	}
+
+	let parts;
+	if (isString(path)) {
+		if (path === "") {
+			return subject;
+		}
+
+		parts = path.split(DELIMITER);
+	}
+
+	let current = parts.shift();
+
+	if (current === this.wildCard) {
+		return iterate.call(this, subject, parts.join(DELIMITER), check);
+	}
+
+	if (isObject(subject) || isArray(subject)) {
+		let anchor;
+		if (subject instanceof Map || subject instanceof WeakMap) {
+			anchor = subject.get(current);
+		} else if (subject instanceof Set || subject instanceof WeakSet) {
+			current = parseInt(current);
+			validateInteger(current);
+			anchor = [...subject]?.[current];
+		} else if (typeof WeakRef === "function" && subject instanceof WeakRef) {
+			throw Error("unsupported action for this data type");
+		} else if (isArray(subject)) {
+			current = parseInt(current);
+			validateInteger(current);
+			anchor = subject?.[current];
+		} else {
+			anchor = subject?.[current];
+		}
+
+		if (isObject(anchor) || isArray(anchor)) {
+			return getValueViaPath.call(this, anchor, parts.join(DELIMITER), check);
+		}
+
+		if (parts.length > 0) {
+			throw Error(`the journey is not at its end (${parts.join(DELIMITER)})`);
+		}
+
+		if (check === true) {
+			const descriptor = Object.getOwnPropertyDescriptor(
+				Object.getPrototypeOf(subject),
+				current,
+			);
+
+			if (!subject.hasOwnProperty(current) && descriptor === undefined) {
+				throw Error("unknown value");
+			}
+		}
+
+		return anchor;
+	}
+
+	throw TypeError(`unsupported type ${typeof subject}`);
 }
 
 /**
@@ -291,72 +304,72 @@ function getValueViaPath(subject, path, check) {
  * @private
  */
 function setValueViaPath(subject, path, value) {
-    if (!(isArray(path) || isString(path))) {
-        throw new Error("type error: path must be a string or an array");
-    }
-
-    let parts;
-    if (isArray(path)) {
-        if (path.length === 0) {
-            return subject;
-        }
-
-        parts = path;
-    } else {
-        parts = path.split(DELIMITER);
-    }
-
-    let last = parts.pop();
-    let subpath = parts.join(DELIMITER);
-
-    let stack = new Stack();
-    let current = subpath;
-    while (true) {
-        try {
-            getValueViaPath.call(this, subject, current, true);
-            break;
-        } catch (e) {}
-
-        stack.push(current);
-        parts.pop();
-        current = parts.join(DELIMITER);
-
-        if (current === "") break;
-    }
-
-    while (!stack.isEmpty()) {
-        current = stack.pop();
-        let obj = {};
-
-        if (!stack.isEmpty()) {
-            let n = stack.peek().split(DELIMITER).pop();
-            if (isInteger(parseInt(n))) {
-                obj = [];
-            }
-        }
-
-        setValueViaPath.call(this, subject, current, obj);
-    }
-
-    let anchor = getValueViaPath.call(this, subject, subpath);
-
-    if (!(isObject(subject) || isArray(subject))) {
-        throw TypeError(`unsupported type: ${typeof subject}`);
-    }
-
-    if (anchor instanceof Map || anchor instanceof WeakMap) {
-        anchor.set(last, value);
-    } else if (anchor instanceof Set || anchor instanceof WeakSet) {
-        anchor.append(value);
-    } else if (typeof WeakRef === "function" && anchor instanceof WeakRef) {
-        throw Error("unsupported action for this data type");
-    } else if (isArray(anchor)) {
-        last = parseInt(last);
-        validateInteger(last);
-        assignProperty(anchor, last, value);
-    } else {
-        assignProperty(anchor, last, value);
-    }
+	if (!(isArray(path) || isString(path))) {
+		throw new Error("type error: path must be a string or an array");
+	}
+
+	let parts;
+	if (isArray(path)) {
+		if (path.length === 0) {
+			return subject;
+		}
+
+		parts = path;
+	} else {
+		parts = path.split(DELIMITER);
+	}
+
+	let last = parts.pop();
+	let subpath = parts.join(DELIMITER);
+
+	let stack = new Stack();
+	let current = subpath;
+	while (true) {
+		try {
+			getValueViaPath.call(this, subject, current, true);
+			break;
+		} catch (e) {}
+
+		stack.push(current);
+		parts.pop();
+		current = parts.join(DELIMITER);
+
+		if (current === "") break;
+	}
+
+	while (!stack.isEmpty()) {
+		current = stack.pop();
+		let obj = {};
+
+		if (!stack.isEmpty()) {
+			let n = stack.peek().split(DELIMITER).pop();
+			if (isInteger(parseInt(n))) {
+				obj = [];
+			}
+		}
+
+		setValueViaPath.call(this, subject, current, obj);
+	}
+
+	let anchor = getValueViaPath.call(this, subject, subpath);
+
+	if (!(isObject(subject) || isArray(subject))) {
+		throw TypeError(`unsupported type: ${typeof subject}`);
+	}
+
+	if (anchor instanceof Map || anchor instanceof WeakMap) {
+		anchor.set(last, value);
+	} else if (anchor instanceof Set || anchor instanceof WeakSet) {
+		anchor.append(value);
+	} else if (typeof WeakRef === "function" && anchor instanceof WeakRef) {
+		throw Error("unsupported action for this data type");
+	} else if (isArray(anchor)) {
+		last = parseInt(last);
+		validateInteger(last);
+		assignProperty(anchor, last, value);
+	} else {
+		assignProperty(anchor, last, value);
+	}
 }
 
 /**
@@ -366,16 +379,16 @@ function setValueViaPath(subject, path, value) {
  * @param {*} value
  */
 function assignProperty(object, key, value) {
-    if (!object.hasOwnProperty(key)) {
-        object[key] = value;
-        return;
-    }
+	if (!object.hasOwnProperty(key)) {
+		object[key] = value;
+		return;
+	}
 
-    if (value === undefined) {
-        delete object[key];
-    }
+	if (value === undefined) {
+		delete object[key];
+	}
 
-    object[key] = value;
+	object[key] = value;
 }
 
 /**
@@ -392,40 +405,40 @@ function assignProperty(object, key, value) {
  * @private
  */
 function deleteValueViaPath(subject, path) {
-    if (!(isArray(path) || isString(path))) {
-        throw new Error("type error: path must be a string or an array");
-    }
-
-    let parts;
-    if (isArray(path)) {
-        if (path.length === 0) {
-            return subject;
-        }
-
-        parts = path;
-    } else {
-        parts = path.split(DELIMITER);
-    }
-
-    let last = parts.pop();
-    const subpath = parts.join(DELIMITER);
-
-    const anchor = getValueViaPath.call(this, subject, subpath);
-
-    if (anchor instanceof Map) {
-        anchor.delete(last);
-    } else if (
-        anchor instanceof Set ||
-        anchor instanceof WeakMap ||
-        anchor instanceof WeakSet ||
-        (typeof WeakRef === "function" && anchor instanceof WeakRef)
-    ) {
-        throw Error("unsupported action for this data type");
-    } else if (isArray(anchor)) {
-        last = parseInt(last);
-        validateInteger(last);
-        delete anchor[last];
-    } else {
-        delete anchor[last];
-    }
+	if (!(isArray(path) || isString(path))) {
+		throw new Error("type error: path must be a string or an array");
+	}
+
+	let parts;
+	if (isArray(path)) {
+		if (path.length === 0) {
+			return subject;
+		}
+
+		parts = path;
+	} else {
+		parts = path.split(DELIMITER);
+	}
+
+	let last = parts.pop();
+	const subpath = parts.join(DELIMITER);
+
+	const anchor = getValueViaPath.call(this, subject, subpath);
+
+	if (anchor instanceof Map) {
+		anchor.delete(last);
+	} else if (
+		anchor instanceof Set ||
+		anchor instanceof WeakMap ||
+		anchor instanceof WeakSet ||
+		(typeof WeakRef === "function" && anchor instanceof WeakRef)
+	) {
+		throw Error("unsupported action for this data type");
+	} else if (isArray(anchor)) {
+		last = parseInt(last);
+		validateInteger(last);
+		delete anchor[last];
+	} else {
+		delete anchor[last];
+	}
 }
diff --git a/source/data/pipe.mjs b/source/data/pipe.mjs
index e78a290118a686441d49ce2c6d1db944ab3a51c4..a97b5907390d761f8a612b53918ceccac133a6c9 100644
--- a/source/data/pipe.mjs
+++ b/source/data/pipe.mjs
@@ -32,44 +32,44 @@ const DELIMITER = "|";
  * @memberOf Monster.Data
  */
 class Pipe extends Base {
-    /**
-     * @param {string} pipe a pipe consists of commands whose input and output are connected with the pipe symbol `|`.
-     * @throws {TypeError}
-     */
-    constructor(pipe) {
-        super();
-        validateString(pipe);
+	/**
+	 * @param {string} pipe a pipe consists of commands whose input and output are connected with the pipe symbol `|`.
+	 * @throws {TypeError}
+	 */
+	constructor(pipe) {
+		super();
+		validateString(pipe);
 
-        this.pipe = pipe.split(DELIMITER).map((v) => {
-            return new Transformer(v);
-        });
-    }
+		this.pipe = pipe.split(DELIMITER).map((v) => {
+			return new Transformer(v);
+		});
+	}
 
-    /**
-     * @param {string} name
-     * @param {function} callback
-     * @param {object} context
-     * @returns {Transformer}
-     * @throws {TypeError} value is not a string
-     * @throws {TypeError} value is not a function
-     */
-    setCallback(name, callback, context) {
-        for (const [, t] of Object.entries(this.pipe)) {
-            t.setCallback(name, callback, context);
-        }
+	/**
+	 * @param {string} name
+	 * @param {function} callback
+	 * @param {object} context
+	 * @returns {Transformer}
+	 * @throws {TypeError} value is not a string
+	 * @throws {TypeError} value is not a function
+	 */
+	setCallback(name, callback, context) {
+		for (const [, t] of Object.entries(this.pipe)) {
+			t.setCallback(name, callback, context);
+		}
 
-        return this;
-    }
+		return this;
+	}
 
-    /**
-     * run a pipe
-     *
-     * @param {*} value
-     * @returns {*}
-     */
-    run(value) {
-        return this.pipe.reduce((accumulator, transformer, currentIndex, array) => {
-            return transformer.run(accumulator);
-        }, value);
-    }
+	/**
+	 * run a pipe
+	 *
+	 * @param {*} value
+	 * @returns {*}
+	 */
+	run(value) {
+		return this.pipe.reduce((accumulator, transformer, currentIndex, array) => {
+			return transformer.run(accumulator);
+		}, value);
+	}
 }
diff --git a/source/data/transformer.mjs b/source/data/transformer.mjs
index 72f7d3119874e35b79bd786efcda937db7e31c32..bc9d55541130bfcf08943d7a773389503637674c 100644
--- a/source/data/transformer.mjs
+++ b/source/data/transformer.mjs
@@ -10,14 +10,17 @@ import { Base } from "../types/base.mjs";
 import { getGlobal, getGlobalObject } from "../types/global.mjs";
 import { ID } from "../types/id.mjs";
 import { isArray, isObject, isString, isPrimitive } from "../types/is.mjs";
-import { getDocumentTranslations, Translations } from "../i18n/translations.mjs";
 import {
-    validateFunction,
-    validateInteger,
-    validateObject,
-    validatePrimitive,
-    validateString,
-    validateBoolean,
+	getDocumentTranslations,
+	Translations,
+} from "../i18n/translations.mjs";
+import {
+	validateFunction,
+	validateInteger,
+	validateObject,
+	validatePrimitive,
+	validateString,
+	validateBoolean,
 } from "../types/validate.mjs";
 import { clone } from "../util/clone.mjs";
 import { Pathfinder } from "./pathfinder.mjs";
@@ -42,53 +45,53 @@ export { Transformer };
  * @memberOf Monster.Data
  */
 class Transformer extends Base {
-    /**
-     *
-     * @param {string} definition
-     */
-    constructor(definition) {
-        super();
-        this.args = disassemble(definition);
-        this.command = this.args.shift();
-        this.callbacks = new Map();
-    }
-
-    /**
-     *
-     * @param {string} name
-     * @param {function} callback
-     * @param {object} context
-     * @returns {Transformer}
-     * @throws {TypeError} value is not a string
-     * @throws {TypeError} value is not a function
-     */
-    setCallback(name, callback, context) {
-        validateString(name);
-        validateFunction(callback);
-
-        if (context !== undefined) {
-            validateObject(context);
-        }
-
-        this.callbacks.set(name, {
-            callback: callback,
-            context: context,
-        });
-
-        return this;
-    }
-
-    /**
-     *
-     * @param {*} value
-     * @returns {*}
-     * @throws {Error} unknown command
-     * @throws {TypeError} unsupported type
-     * @throws {Error} type not supported
-     */
-    run(value) {
-        return transform.apply(this, [value]);
-    }
+	/**
+	 *
+	 * @param {string} definition
+	 */
+	constructor(definition) {
+		super();
+		this.args = disassemble(definition);
+		this.command = this.args.shift();
+		this.callbacks = new Map();
+	}
+
+	/**
+	 *
+	 * @param {string} name
+	 * @param {function} callback
+	 * @param {object} context
+	 * @returns {Transformer}
+	 * @throws {TypeError} value is not a string
+	 * @throws {TypeError} value is not a function
+	 */
+	setCallback(name, callback, context) {
+		validateString(name);
+		validateFunction(callback);
+
+		if (context !== undefined) {
+			validateObject(context);
+		}
+
+		this.callbacks.set(name, {
+			callback: callback,
+			context: context,
+		});
+
+		return this;
+	}
+
+	/**
+	 *
+	 * @param {*} value
+	 * @returns {*}
+	 * @throws {Error} unknown command
+	 * @throws {TypeError} unsupported type
+	 * @throws {Error} type not supported
+	 */
+	run(value) {
+		return transform.apply(this, [value]);
+	}
 }
 
 /**
@@ -98,41 +101,41 @@ class Transformer extends Base {
  * @private
  */
 function disassemble(command) {
-    validateString(command);
-
-    let placeholder = new Map();
-    const regex = /((?<pattern>\\(?<char>.)){1})/gim;
-
-    // The separator for args must be escaped
-    // undefined string which should not occur normally and is also not a regex
-    let result = command.matchAll(regex);
-
-    for (let m of result) {
-        let g = m?.["groups"];
-        if (!isObject(g)) {
-            continue;
-        }
-
-        let p = g?.["pattern"];
-        let c = g?.["char"];
-
-        if (p && c) {
-            let r = `__${new ID().toString()}__`;
-            placeholder.set(r, c);
-            command = command.replace(p, r);
-        }
-    }
-    let parts = command.split(":");
-
-    parts = parts.map(function (value) {
-        let v = value.trim();
-        for (let k of placeholder) {
-            v = v.replace(k[0], k[1]);
-        }
-        return v;
-    });
-
-    return parts;
+	validateString(command);
+
+	let placeholder = new Map();
+	const regex = /((?<pattern>\\(?<char>.)){1})/gim;
+
+	// The separator for args must be escaped
+	// undefined string which should not occur normally and is also not a regex
+	let result = command.matchAll(regex);
+
+	for (let m of result) {
+		let g = m?.["groups"];
+		if (!isObject(g)) {
+			continue;
+		}
+
+		let p = g?.["pattern"];
+		let c = g?.["char"];
+
+		if (p && c) {
+			let r = `__${new ID().toString()}__`;
+			placeholder.set(r, c);
+			command = command.replace(p, r);
+		}
+	}
+	let parts = command.split(":");
+
+	parts = parts.map(function (value) {
+		let v = value.trim();
+		for (let k of placeholder) {
+			v = v.replace(k[0], k[1]);
+		}
+		return v;
+	});
+
+	return parts;
 }
 
 /**
@@ -143,12 +146,12 @@ function disassemble(command) {
  * @private
  */
 function convertToString(value) {
-    if (isObject(value) && value.hasOwnProperty("toString")) {
-        value = value.toString();
-    }
+	if (isObject(value) && value.hasOwnProperty("toString")) {
+		value = value.toString();
+	}
 
-    validateString(value);
-    return value;
+	validateString(value);
+	return value;
 }
 
 /**
@@ -162,636 +165,649 @@ function convertToString(value) {
  * @throws {Error} missing key parameter
  */
 function transform(value) {
-    const console = getGlobalObject("console");
-
-    let args = clone(this.args);
-    let key;
-    let defaultValue;
-
-    let translations;
-    let date;
-    let locale;
-    let timestamp;
-    let map;
-    let keyValue;
-
-    switch (this.command) {
-        case "static":
-            return this.args.join(":");
-
-        case "tolower":
-        case "strtolower":
-        case "tolowercase":
-            validateString(value);
-            return value.toLowerCase();
-
-        case "contains":
-            if (isString(value)) {
-                return value.includes(args[0]);
-            }
-
-            if (isArray(value)) {
-                return value.includes(args[0]);
-            }
-
-            if (isObject(value)) {
-                return value.hasOwnProperty(args[0]);
-            }
-
-            return false;
-
-        case "has-entries":
-        case "hasentries":
-            if (isObject(value)) {
-                return Object.keys(value).length > 0;
-            }
-
-            if (isArray(value)) {
-                return value.length > 0;
-            }
-
-            return false;
-
-        case "isundefined":
-        case "is-undefined":
-            return value === undefined;
-
-        case "isnull":
-        case "is-null":
-            return value === null;
-
-        case "isset":
-        case "is-set":
-            return value !== undefined && value !== null;
-
-        case "isnumber":
-        case "is-number":
-            return isPrimitive(value) && !isNaN(value);
-
-        case "isinteger":
-        case "is-integer":
-            return isPrimitive(value) && !isNaN(value) && value % 1 === 0;
-
-        case "isfloat":
-        case "is-float":
-            return isPrimitive(value) && !isNaN(value) && value % 1 !== 0;
-
-        case "isobject":
-        case "is-object":
-            return isObject(value);
-
-        case "isarray":
-        case "is-array":
-            return Array.isArray(value);
-
-        case "not":
-            validateBoolean(value);
-            return !value;
-
-        case "toupper":
-        case "strtoupper":
-        case "touppercase":
-            validateString(value);
-            return value.toUpperCase();
-
-        case "tostring":
-            return `${value}`;
-
-        case "tointeger":
-            let n = parseInt(value);
-            validateInteger(n);
-            return n;
-
-        case "to-json":
-        case "tojson":
-            return JSON.stringify(value);
-
-        case "from-json":
-        case "fromjson":
-            return JSON.parse(value);
-
-        case "trim":
-            validateString(value);
-            return value.trim();
-
-        case "rawurlencode":
-            validateString(value);
-            return encodeURIComponent(value)
-                .replace(/!/g, "%21")
-                .replace(/'/g, "%27")
-                .replace(/\(/g, "%28")
-                .replace(/\)/g, "%29")
-                .replace(/\*/g, "%2A");
-
-        case "call":
-            /**
-             * callback-definition
-             * function callback(value, ...args) {
-             *   return value;
-             * }
-             */
-
-            let callback;
-            let callbackName = args.shift();
-            let context = getGlobal();
-
-            if (isObject(value) && value.hasOwnProperty(callbackName)) {
-                callback = value[callbackName];
-            } else if (this.callbacks.has(callbackName)) {
-                let s = this.callbacks.get(callbackName);
-                callback = s?.["callback"];
-                context = s?.["context"];
-            } else if (typeof window === "object" && window.hasOwnProperty(callbackName)) {
-                callback = window[callbackName];
-            }
-            validateFunction(callback);
-
-            args.unshift(value);
-            return callback.call(context, ...args);
-
-        case "plain":
-        case "plaintext":
-            validateString(value);
-            let doc = new DOMParser().parseFromString(value, "text/html");
-            return doc.body.textContent || "";
-
-        case "if":
-        case "?":
-            validatePrimitive(value);
-
-            let trueStatement = args.shift() || undefined;
-            let falseStatement = args.shift() || undefined;
-
-            if (trueStatement === "value") {
-                trueStatement = value;
-            }
-            if (trueStatement === "\\value") {
-                trueStatement = "value";
-            }
-
-            if (trueStatement === "\\undefined") {
-                trueStatement = undefined;
-            }
-
-            if (trueStatement === "\\null") {
-                trueStatement = null;
-            }
-
-            if (falseStatement === "value") {
-                falseStatement = value;
-            }
-            if (falseStatement === "\\value") {
-                falseStatement = "value";
-            }
-
-            if (falseStatement === "\\undefined") {
-                falseStatement = undefined;
-            }
-
-            if (falseStatement === "\\null") {
-                falseStatement = null;
-            }
-
-            let condition =
-                (value !== undefined && value !== "" && value !== "off" && value !== "false" && value !== false) ||
-                value === "on" ||
-                value === "true" ||
-                value === true;
-            return condition ? trueStatement : falseStatement;
-
-        case "ucfirst":
-            validateString(value);
-
-            let firstchar = value.charAt(0).toUpperCase();
-            return firstchar + value.substr(1);
-        case "ucwords":
-            validateString(value);
-
-            return value.replace(/^([a-z\u00E0-\u00FC])|\s+([a-z\u00E0-\u00FC])/g, function (v) {
-                return v.toUpperCase();
-            });
-
-        case "count":
-        case "length":
-            if ((isString(value) || isObject(value) || isArray(value)) && value.hasOwnProperty("length")) {
-                return value.length;
-            }
-
-            throw new TypeError(`unsupported type ${typeof value}`);
-
-        case "to-base64":
-        case "btoa":
-        case "base64":
-            return btoa(convertToString(value));
-
-        case "atob":
-        case "from-base64":
-            return atob(convertToString(value));
-
-        case "empty":
-            return "";
-
-        case "undefined":
-            return undefined;
-
-        case "debug":
-            if (isObject(console)) {
-                console.log(value);
-            }
-
-            return value;
-
-        case "prefix":
-            validateString(value);
-            let prefix = args?.[0];
-            return prefix + value;
-
-        case "suffix":
-            validateString(value);
-            let suffix = args?.[0];
-            return value + suffix;
-
-        case "uniqid":
-            return new ID().toString();
-
-        case "first-key":
-        case "last-key":
-        case "nth-last-key":
-        case "nth-key":
-            if (!isObject(value)) {
-                throw new Error("type not supported");
-            }
-
-            const keys = Object.keys(value).sort();
-
-            if (this.command === "first-key") {
-                key = 0;
-            } else if (this.command === "last-key") {
-                key = keys.length - 1;
-            } else {
-                key = validateInteger(parseInt(args.shift()));
-
-                if (this.command === "nth-last-key") {
-                    key = keys.length - key - 1;
-                }
-            }
-
-            defaultValue = args.shift() || "";
-
-            let useKey = keys?.[key];
-
-            if (value?.[useKey]) {
-                return value?.[useKey];
-            }
-
-            return defaultValue;
-
-        case "key":
-        case "property":
-        case "index":
-            key = args.shift() || undefined;
-
-            if (key === undefined) {
-                throw new Error("missing key parameter");
-            }
-
-            defaultValue = args.shift() || undefined;
-
-            if (value instanceof Map) {
-                if (!value.has(key)) {
-                    return defaultValue;
-                }
-                return value.get(key);
-            }
-
-            if (isObject(value) || isArray(value)) {
-                if (value?.[key]) {
-                    return value?.[key];
-                }
-
-                return defaultValue;
-            }
-
-            throw new Error("type not supported");
-
-        case "path-exists":
-            key = args.shift();
-            if (key === undefined) {
-                throw new Error("missing key parameter");
-            }
-
-            return new Pathfinder(value).exists(key);
-
-        case "concat":
-            let pf2 = new Pathfinder(value);
-            let concat = "";
-            while (args.length > 0) {
-                key = args.shift();
-                if (key === undefined) {
-                    throw new Error("missing key parameter");
-                }
-
-                // add empty strings
-                if (isString(key) && key.trim() === "") {
-                    concat += key;
-                    continue;
-                }
-
-                if (!pf2.exists(key)) {
-                    concat += key;
-                    continue;
-                }
-                let v = pf2.getVia(key);
-                if (!isPrimitive(v)) {
-                    throw new Error("value is not primitive");
-                }
-
-                concat += v;
-            }
-
-            return concat;
-        case "path":
-            key = args.shift();
-            if (key === undefined) {
-                throw new Error("missing key parameter");
-            }
-
-            let pf = new Pathfinder(value);
-
-            if (!pf.exists(key)) {
-                return undefined;
-            }
-
-            return pf.getVia(key);
-
-        case "substring":
-            validateString(value);
-
-            let start = parseInt(args[0]) || 0;
-            let end = (parseInt(args[1]) || 0) + start;
-
-            return value.substring(start, end);
-
-        case "nop":
-            return value;
-
-        case "??":
-        case "default":
-            if (value !== undefined && value !== null) {
-                return value;
-            }
-
-            defaultValue = args.shift();
-            let defaultType = args.shift();
-            if (defaultType === undefined) {
-                defaultType = "string";
-            }
-
-            switch (defaultType) {
-                case "int":
-                case "integer":
-                    return parseInt(defaultValue);
-                case "float":
-                    return parseFloat(defaultValue);
-                case "undefined":
-                    return undefined;
-                case "bool":
-                case "boolean":
-                    defaultValue = defaultValue.toLowerCase();
-                    return (
-                        (defaultValue !== "undefined" &&
-                            defaultValue !== "" &&
-                            defaultValue !== "off" &&
-                            defaultValue !== "false" &&
-                            defaultValue !== "false") ||
-                        defaultValue === "on" ||
-                        defaultValue === "true" ||
-                        defaultValue === "true"
-                    );
-                case "string":
-                    return `${defaultValue}`;
-                case "object":
-                    return JSON.parse(atob(defaultValue));
-            }
-
-            throw new Error("type not supported");
-
-        case "map":
-            map = new Map();
-            while (args.length > 0) {
-                keyValue = args.shift();
-                if (keyValue === undefined) {
-                    throw new Error("missing key parameter");
-                }
-
-                keyValue = keyValue.split("=");
-                map.set(keyValue[0], keyValue[1]);
-            }
-
-            return map.get(value);
-
-        case "equals":
-            if (args.length === 0) {
-                throw new Error("missing value parameter");
-            }
-
-            validatePrimitive(value);
-
-            const equalsValue = args.shift();
-
-            /**
-             * The history of “typeof null”
-             * https://2ality.com/2013/10/typeof-null.html
-             * In JavaScript, typeof null is 'object', which incorrectly suggests
-             * that null is an object.
-             */
-            if (value === null) {
-                if (equalsValue === "null") {
-                    return true;
-                }
-                return false;
-            }
-
-            const typeOfValue = typeof value;
-
-            switch (typeOfValue) {
-                case "string":
-                    return value === equalsValue;
-                case "number":
-                    return value === parseFloat(equalsValue);
-                case "boolean":
-                    return value === (equalsValue === "true" || equalsValue === "on");
-                case "undefined":
-                    return equalsValue === "undefined";
-                default:
-                    throw new Error("type not supported");
-            }
-
-        case "money":
-        case "currency":
-            try {
-                locale = getLocaleOfDocument();
-            } catch (e) {
-                throw new Error(`unsupported locale or missing format (${e.message})`);
-            }
-
-            const currency = value.substring(0, 3);
-            if (!currency) {
-                throw new Error("missing currency parameter");
-            }
-
-            const maximumFractionDigits = args?.[0] || 2;
-            const roundingIncrement = args?.[1] || 5;
-
-            const nf = new Intl.NumberFormat(locale, {
-                style: "currency",
-                currency: currency,
-                maximumFractionDigits: maximumFractionDigits,
-                roundingIncrement: roundingIncrement,
-            });
-
-            return nf.format(value.substring(3));
-
-        case "timestamp":
-            date = new Date(value);
-            timestamp = date.getTime();
-            if (isNaN(timestamp)) {
-                throw new Error("invalid date");
-            }
-            return timestamp;
-
-        case "time":
-            date = new Date(value);
-            if (isNaN(date.getTime())) {
-                throw new Error("invalid date");
-            }
-
-            try {
-                locale = getLocaleOfDocument();
-                return date.toLocaleTimeString(locale);
-            } catch (e) {
-                throw new Error(`unsupported locale or missing format (${e.message})`);
-            }
-
-        case "datetimeformat":
-            date = new Date(value);
-            if (isNaN(date.getTime())) {
-                throw new Error("invalid date");
-            }
-
-            const options = {
-                dateStyle: args.shift() || "medium",
-                timeStyle: args.shift() || "medium",
-            };
-
-            try {
-                locale = getLocaleOfDocument();
-                return new Intl.DateTimeFormat(locale, options).format(date);
-            } catch (e) {
-                throw new Error(`unsupported locale or missing format (${e.message})`);
-            }
-
-        case "datetime":
-            date = new Date(value);
-            if (isNaN(date.getTime())) {
-                throw new Error("invalid date");
-            }
-
-            try {
-                locale = getLocaleOfDocument();
-                return date.toLocaleString(locale);
-            } catch (e) {
-                throw new Error(`unsupported locale or missing format (${e.message})`);
-            }
-
-        case "date":
-            date = new Date(value);
-            if (isNaN(date.getTime())) {
-                throw new Error("invalid date");
-            }
-
-            try {
-                locale = getLocaleOfDocument();
-                return date.toLocaleDateString(locale);
-            } catch (e) {
-                throw new Error(`unsupported locale or missing format (${e.message})`);
-            }
-
-        case "year":
-            date = new Date(value);
-            if (isNaN(date.getTime())) {
-                throw new Error("invalid date");
-            }
-
-            return date.getFullYear();
-
-        case "month":
-            date = new Date(value);
-            if (isNaN(date.getTime())) {
-                throw new Error("invalid date");
-            }
-
-            return date.getMonth() + 1;
-
-        case "day":
-            date = new Date(value);
-            if (isNaN(date.getTime())) {
-                throw new Error("invalid date");
-            }
-
-            return date.getDate();
-
-        case "weekday":
-            date = new Date(value);
-            if (isNaN(date.getTime())) {
-                throw new Error("invalid date");
-            }
-
-            return date.getDay();
-
-        case "hour":
-        case "hours":
-            date = new Date(value);
-            if (isNaN(date.getTime())) {
-                throw new Error("invalid date");
-            }
-
-            return date.getHours();
-
-        case "minute":
-        case "minutes":
-            date = new Date(value);
-            if (isNaN(date.getTime())) {
-                throw new Error("invalid date");
-            }
-
-            return date.getMinutes();
-
-        case "second":
-        case "seconds":
-            date = new Date(value);
-            if (isNaN(date.getTime())) {
-                throw new Error("invalid date");
-            }
-
-            return date.getSeconds();
-
-        case "i18n":
-        case "translation":
-            translations = getDocumentTranslations();
-            if (!(translations instanceof Translations)) {
-                throw new Error("missing translations");
-            }
-
-            key = args.shift() || undefined;
-            if (key === undefined) {
-                key = value;
-            }
-
-            defaultValue = args.shift() || undefined;
-            return translations.getText(key, defaultValue);
-
-        default:
-            throw new Error(`unknown command ${this.command}`);
-    }
+	const console = getGlobalObject("console");
+
+	let args = clone(this.args);
+	let key;
+	let defaultValue;
+
+	let translations;
+	let date;
+	let locale;
+	let timestamp;
+	let map;
+	let keyValue;
+
+	switch (this.command) {
+		case "static":
+			return this.args.join(":");
+
+		case "tolower":
+		case "strtolower":
+		case "tolowercase":
+			validateString(value);
+			return value.toLowerCase();
+
+		case "contains":
+			if (isString(value)) {
+				return value.includes(args[0]);
+			}
+
+			if (isArray(value)) {
+				return value.includes(args[0]);
+			}
+
+			if (isObject(value)) {
+				return value.hasOwnProperty(args[0]);
+			}
+
+			return false;
+
+		case "has-entries":
+		case "hasentries":
+			if (isObject(value)) {
+				return Object.keys(value).length > 0;
+			}
+
+			if (isArray(value)) {
+				return value.length > 0;
+			}
+
+			return false;
+
+		case "isundefined":
+		case "is-undefined":
+			return value === undefined;
+
+		case "isnull":
+		case "is-null":
+			return value === null;
+
+		case "isset":
+		case "is-set":
+			return value !== undefined && value !== null;
+
+		case "isnumber":
+		case "is-number":
+			return isPrimitive(value) && !isNaN(value);
+
+		case "isinteger":
+		case "is-integer":
+			return isPrimitive(value) && !isNaN(value) && value % 1 === 0;
+
+		case "isfloat":
+		case "is-float":
+			return isPrimitive(value) && !isNaN(value) && value % 1 !== 0;
+
+		case "isobject":
+		case "is-object":
+			return isObject(value);
+
+		case "isarray":
+		case "is-array":
+			return Array.isArray(value);
+
+		case "not":
+			validateBoolean(value);
+			return !value;
+
+		case "toupper":
+		case "strtoupper":
+		case "touppercase":
+			validateString(value);
+			return value.toUpperCase();
+
+		case "tostring":
+			return `${value}`;
+
+		case "tointeger":
+			let n = parseInt(value);
+			validateInteger(n);
+			return n;
+
+		case "to-json":
+		case "tojson":
+			return JSON.stringify(value);
+
+		case "from-json":
+		case "fromjson":
+			return JSON.parse(value);
+
+		case "trim":
+			validateString(value);
+			return value.trim();
+
+		case "rawurlencode":
+			validateString(value);
+			return encodeURIComponent(value)
+				.replace(/!/g, "%21")
+				.replace(/'/g, "%27")
+				.replace(/\(/g, "%28")
+				.replace(/\)/g, "%29")
+				.replace(/\*/g, "%2A");
+
+		case "call":
+			/**
+			 * callback-definition
+			 * function callback(value, ...args) {
+			 *   return value;
+			 * }
+			 */
+
+			let callback;
+			let callbackName = args.shift();
+			let context = getGlobal();
+
+			if (isObject(value) && value.hasOwnProperty(callbackName)) {
+				callback = value[callbackName];
+			} else if (this.callbacks.has(callbackName)) {
+				let s = this.callbacks.get(callbackName);
+				callback = s?.["callback"];
+				context = s?.["context"];
+			} else if (
+				typeof window === "object" &&
+				window.hasOwnProperty(callbackName)
+			) {
+				callback = window[callbackName];
+			}
+			validateFunction(callback);
+
+			args.unshift(value);
+			return callback.call(context, ...args);
+
+		case "plain":
+		case "plaintext":
+			validateString(value);
+			let doc = new DOMParser().parseFromString(value, "text/html");
+			return doc.body.textContent || "";
+
+		case "if":
+		case "?":
+			validatePrimitive(value);
+
+			let trueStatement = args.shift() || undefined;
+			let falseStatement = args.shift() || undefined;
+
+			if (trueStatement === "value") {
+				trueStatement = value;
+			}
+			if (trueStatement === "\\value") {
+				trueStatement = "value";
+			}
+
+			if (trueStatement === "\\undefined") {
+				trueStatement = undefined;
+			}
+
+			if (trueStatement === "\\null") {
+				trueStatement = null;
+			}
+
+			if (falseStatement === "value") {
+				falseStatement = value;
+			}
+			if (falseStatement === "\\value") {
+				falseStatement = "value";
+			}
+
+			if (falseStatement === "\\undefined") {
+				falseStatement = undefined;
+			}
+
+			if (falseStatement === "\\null") {
+				falseStatement = null;
+			}
+
+			let condition =
+				(value !== undefined &&
+					value !== "" &&
+					value !== "off" &&
+					value !== "false" &&
+					value !== false) ||
+				value === "on" ||
+				value === "true" ||
+				value === true;
+			return condition ? trueStatement : falseStatement;
+
+		case "ucfirst":
+			validateString(value);
+
+			let firstchar = value.charAt(0).toUpperCase();
+			return firstchar + value.substr(1);
+		case "ucwords":
+			validateString(value);
+
+			return value.replace(
+				/^([a-z\u00E0-\u00FC])|\s+([a-z\u00E0-\u00FC])/g,
+				function (v) {
+					return v.toUpperCase();
+				},
+			);
+
+		case "count":
+		case "length":
+			if (
+				(isString(value) || isObject(value) || isArray(value)) &&
+				value.hasOwnProperty("length")
+			) {
+				return value.length;
+			}
+
+			throw new TypeError(`unsupported type ${typeof value}`);
+
+		case "to-base64":
+		case "btoa":
+		case "base64":
+			return btoa(convertToString(value));
+
+		case "atob":
+		case "from-base64":
+			return atob(convertToString(value));
+
+		case "empty":
+			return "";
+
+		case "undefined":
+			return undefined;
+
+		case "debug":
+			if (isObject(console)) {
+				console.log(value);
+			}
+
+			return value;
+
+		case "prefix":
+			validateString(value);
+			let prefix = args?.[0];
+			return prefix + value;
+
+		case "suffix":
+			validateString(value);
+			let suffix = args?.[0];
+			return value + suffix;
+
+		case "uniqid":
+			return new ID().toString();
+
+		case "first-key":
+		case "last-key":
+		case "nth-last-key":
+		case "nth-key":
+			if (!isObject(value)) {
+				throw new Error("type not supported");
+			}
+
+			const keys = Object.keys(value).sort();
+
+			if (this.command === "first-key") {
+				key = 0;
+			} else if (this.command === "last-key") {
+				key = keys.length - 1;
+			} else {
+				key = validateInteger(parseInt(args.shift()));
+
+				if (this.command === "nth-last-key") {
+					key = keys.length - key - 1;
+				}
+			}
+
+			defaultValue = args.shift() || "";
+
+			let useKey = keys?.[key];
+
+			if (value?.[useKey]) {
+				return value?.[useKey];
+			}
+
+			return defaultValue;
+
+		case "key":
+		case "property":
+		case "index":
+			key = args.shift() || undefined;
+
+			if (key === undefined) {
+				throw new Error("missing key parameter");
+			}
+
+			defaultValue = args.shift() || undefined;
+
+			if (value instanceof Map) {
+				if (!value.has(key)) {
+					return defaultValue;
+				}
+				return value.get(key);
+			}
+
+			if (isObject(value) || isArray(value)) {
+				if (value?.[key]) {
+					return value?.[key];
+				}
+
+				return defaultValue;
+			}
+
+			throw new Error("type not supported");
+
+		case "path-exists":
+			key = args.shift();
+			if (key === undefined) {
+				throw new Error("missing key parameter");
+			}
+
+			return new Pathfinder(value).exists(key);
+
+		case "concat":
+			let pf2 = new Pathfinder(value);
+			let concat = "";
+			while (args.length > 0) {
+				key = args.shift();
+				if (key === undefined) {
+					throw new Error("missing key parameter");
+				}
+
+				// add empty strings
+				if (isString(key) && key.trim() === "") {
+					concat += key;
+					continue;
+				}
+
+				if (!pf2.exists(key)) {
+					concat += key;
+					continue;
+				}
+				let v = pf2.getVia(key);
+				if (!isPrimitive(v)) {
+					throw new Error("value is not primitive");
+				}
+
+				concat += v;
+			}
+
+			return concat;
+		case "path":
+			key = args.shift();
+			if (key === undefined) {
+				throw new Error("missing key parameter");
+			}
+
+			let pf = new Pathfinder(value);
+
+			if (!pf.exists(key)) {
+				return undefined;
+			}
+
+			return pf.getVia(key);
+
+		case "substring":
+			validateString(value);
+
+			let start = parseInt(args[0]) || 0;
+			let end = (parseInt(args[1]) || 0) + start;
+
+			return value.substring(start, end);
+
+		case "nop":
+			return value;
+
+		case "??":
+		case "default":
+			if (value !== undefined && value !== null) {
+				return value;
+			}
+
+			defaultValue = args.shift();
+			let defaultType = args.shift();
+			if (defaultType === undefined) {
+				defaultType = "string";
+			}
+
+			switch (defaultType) {
+				case "int":
+				case "integer":
+					return parseInt(defaultValue);
+				case "float":
+					return parseFloat(defaultValue);
+				case "undefined":
+					return undefined;
+				case "bool":
+				case "boolean":
+					defaultValue = defaultValue.toLowerCase();
+					return (
+						(defaultValue !== "undefined" &&
+							defaultValue !== "" &&
+							defaultValue !== "off" &&
+							defaultValue !== "false" &&
+							defaultValue !== "false") ||
+						defaultValue === "on" ||
+						defaultValue === "true" ||
+						defaultValue === "true"
+					);
+				case "string":
+					return `${defaultValue}`;
+				case "object":
+					return JSON.parse(atob(defaultValue));
+			}
+
+			throw new Error("type not supported");
+
+		case "map":
+			map = new Map();
+			while (args.length > 0) {
+				keyValue = args.shift();
+				if (keyValue === undefined) {
+					throw new Error("missing key parameter");
+				}
+
+				keyValue = keyValue.split("=");
+				map.set(keyValue[0], keyValue[1]);
+			}
+
+			return map.get(value);
+
+		case "equals":
+			if (args.length === 0) {
+				throw new Error("missing value parameter");
+			}
+
+			validatePrimitive(value);
+
+			const equalsValue = args.shift();
+
+			/**
+			 * The history of “typeof null”
+			 * https://2ality.com/2013/10/typeof-null.html
+			 * In JavaScript, typeof null is 'object', which incorrectly suggests
+			 * that null is an object.
+			 */
+			if (value === null) {
+				if (equalsValue === "null") {
+					return true;
+				}
+				return false;
+			}
+
+			const typeOfValue = typeof value;
+
+			switch (typeOfValue) {
+				case "string":
+					return value === equalsValue;
+				case "number":
+					return value === parseFloat(equalsValue);
+				case "boolean":
+					return value === (equalsValue === "true" || equalsValue === "on");
+				case "undefined":
+					return equalsValue === "undefined";
+				default:
+					throw new Error("type not supported");
+			}
+
+		case "money":
+		case "currency":
+			try {
+				locale = getLocaleOfDocument();
+			} catch (e) {
+				throw new Error(`unsupported locale or missing format (${e.message})`);
+			}
+
+			const currency = value.substring(0, 3);
+			if (!currency) {
+				throw new Error("missing currency parameter");
+			}
+
+			const maximumFractionDigits = args?.[0] || 2;
+			const roundingIncrement = args?.[1] || 5;
+
+			const nf = new Intl.NumberFormat(locale, {
+				style: "currency",
+				currency: currency,
+				maximumFractionDigits: maximumFractionDigits,
+				roundingIncrement: roundingIncrement,
+			});
+
+			return nf.format(value.substring(3));
+
+		case "timestamp":
+			date = new Date(value);
+			timestamp = date.getTime();
+			if (isNaN(timestamp)) {
+				throw new Error("invalid date");
+			}
+			return timestamp;
+
+		case "time":
+			date = new Date(value);
+			if (isNaN(date.getTime())) {
+				throw new Error("invalid date");
+			}
+
+			try {
+				locale = getLocaleOfDocument();
+				return date.toLocaleTimeString(locale);
+			} catch (e) {
+				throw new Error(`unsupported locale or missing format (${e.message})`);
+			}
+
+		case "datetimeformat":
+			date = new Date(value);
+			if (isNaN(date.getTime())) {
+				throw new Error("invalid date");
+			}
+
+			const options = {
+				dateStyle: args.shift() || "medium",
+				timeStyle: args.shift() || "medium",
+			};
+
+			try {
+				locale = getLocaleOfDocument();
+				return new Intl.DateTimeFormat(locale, options).format(date);
+			} catch (e) {
+				throw new Error(`unsupported locale or missing format (${e.message})`);
+			}
+
+		case "datetime":
+			date = new Date(value);
+			if (isNaN(date.getTime())) {
+				throw new Error("invalid date");
+			}
+
+			try {
+				locale = getLocaleOfDocument();
+				return date.toLocaleString(locale);
+			} catch (e) {
+				throw new Error(`unsupported locale or missing format (${e.message})`);
+			}
+
+		case "date":
+			date = new Date(value);
+			if (isNaN(date.getTime())) {
+				throw new Error("invalid date");
+			}
+
+			try {
+				locale = getLocaleOfDocument();
+				return date.toLocaleDateString(locale);
+			} catch (e) {
+				throw new Error(`unsupported locale or missing format (${e.message})`);
+			}
+
+		case "year":
+			date = new Date(value);
+			if (isNaN(date.getTime())) {
+				throw new Error("invalid date");
+			}
+
+			return date.getFullYear();
+
+		case "month":
+			date = new Date(value);
+			if (isNaN(date.getTime())) {
+				throw new Error("invalid date");
+			}
+
+			return date.getMonth() + 1;
+
+		case "day":
+			date = new Date(value);
+			if (isNaN(date.getTime())) {
+				throw new Error("invalid date");
+			}
+
+			return date.getDate();
+
+		case "weekday":
+			date = new Date(value);
+			if (isNaN(date.getTime())) {
+				throw new Error("invalid date");
+			}
+
+			return date.getDay();
+
+		case "hour":
+		case "hours":
+			date = new Date(value);
+			if (isNaN(date.getTime())) {
+				throw new Error("invalid date");
+			}
+
+			return date.getHours();
+
+		case "minute":
+		case "minutes":
+			date = new Date(value);
+			if (isNaN(date.getTime())) {
+				throw new Error("invalid date");
+			}
+
+			return date.getMinutes();
+
+		case "second":
+		case "seconds":
+			date = new Date(value);
+			if (isNaN(date.getTime())) {
+				throw new Error("invalid date");
+			}
+
+			return date.getSeconds();
+
+		case "i18n":
+		case "translation":
+			translations = getDocumentTranslations();
+			if (!(translations instanceof Translations)) {
+				throw new Error("missing translations");
+			}
+
+			key = args.shift() || undefined;
+			if (key === undefined) {
+				key = value;
+			}
+
+			defaultValue = args.shift() || undefined;
+			return translations.getText(key, defaultValue);
+
+		default:
+			throw new Error(`unknown command ${this.command}`);
+	}
 }
diff --git a/source/dom/assembler.mjs b/source/dom/assembler.mjs
index 146702aeae7e20ee1cf8aca7d716a92fd96d0b4e..ee512cac92be0d4913209d579d52cd4e5314ba6f 100644
--- a/source/dom/assembler.mjs
+++ b/source/dom/assembler.mjs
@@ -30,52 +30,52 @@ const ATTRIBUTEPREFIX = "data-monster-";
  * @summary Allows you to build an html fragment
  */
 class Assembler extends Base {
-    /**
-     * @param {DocumentFragment} fragment
-     * @throws {TypeError} value is not an instance of
-     * @throws {TypeError} value is not a function
-     * @throws {Error} the function is not defined
-     */
-    constructor(fragment) {
-        super();
-        this.attributePrefix = ATTRIBUTEPREFIX;
-        validateInstance(fragment, getGlobalFunction("DocumentFragment"));
-        this.fragment = fragment;
-    }
+	/**
+	 * @param {DocumentFragment} fragment
+	 * @throws {TypeError} value is not an instance of
+	 * @throws {TypeError} value is not a function
+	 * @throws {Error} the function is not defined
+	 */
+	constructor(fragment) {
+		super();
+		this.attributePrefix = ATTRIBUTEPREFIX;
+		validateInstance(fragment, getGlobalFunction("DocumentFragment"));
+		this.fragment = fragment;
+	}
 
-    /**
-     *
-     * @param {string} prefix
-     * @returns {Assembler}
-     * @throws {TypeError} value is not a string
-     */
-    setAttributePrefix(prefix) {
-        validateString(prefix);
-        this.attributePrefix = prefix;
-        return this;
-    }
+	/**
+	 *
+	 * @param {string} prefix
+	 * @returns {Assembler}
+	 * @throws {TypeError} value is not a string
+	 */
+	setAttributePrefix(prefix) {
+		validateString(prefix);
+		this.attributePrefix = prefix;
+		return this;
+	}
 
-    /**
-     *
-     * @returns {string}
-     */
-    getAttributePrefix() {
-        return this.attributePrefix;
-    }
+	/**
+	 *
+	 * @returns {string}
+	 */
+	getAttributePrefix() {
+		return this.attributePrefix;
+	}
 
-    /**
-     *
-     * @param {ProxyObserver|undefined} data
-     * @return {DocumentFragment}
-     * @throws {TypeError} value is not an instance of
-     */
-    createDocumentFragment(data) {
-        if (data === undefined) {
-            data = new ProxyObserver({});
-        }
+	/**
+	 *
+	 * @param {ProxyObserver|undefined} data
+	 * @return {DocumentFragment}
+	 * @throws {TypeError} value is not an instance of
+	 */
+	createDocumentFragment(data) {
+		if (data === undefined) {
+			data = new ProxyObserver({});
+		}
 
-        validateInstance(data, ProxyObserver);
-        let fragment = this.fragment.cloneNode(true);
-        return fragment;
-    }
+		validateInstance(data, ProxyObserver);
+		let fragment = this.fragment.cloneNode(true);
+		return fragment;
+	}
 }
diff --git a/source/dom/attributes.mjs b/source/dom/attributes.mjs
index ff423286147018133122322018c4a158880358e8..c1ceacb648007018651ffba263debe384391378d 100644
--- a/source/dom/attributes.mjs
+++ b/source/dom/attributes.mjs
@@ -7,23 +7,27 @@
 
 import { getGlobalFunction } from "../types/global.mjs";
 import { TokenList } from "../types/tokenlist.mjs";
-import { validateInstance, validateString, validateSymbol } from "../types/validate.mjs";
+import {
+	validateInstance,
+	validateString,
+	validateSymbol,
+} from "../types/validate.mjs";
 import { ATTRIBUTE_OBJECTLINK } from "./constants.mjs";
 
 export {
-    findClosestObjectLink,
-    addToObjectLink,
-    removeObjectLink,
-    hasObjectLink,
-    getLinkedObjects,
-    toggleAttributeToken,
-    addAttributeToken,
-    removeAttributeToken,
-    containsAttributeToken,
-    replaceAttributeToken,
-    clearAttributeTokens,
-    findClosestByAttribute,
-    findClosestByClass,
+	findClosestObjectLink,
+	addToObjectLink,
+	removeObjectLink,
+	hasObjectLink,
+	getLinkedObjects,
+	toggleAttributeToken,
+	addAttributeToken,
+	removeAttributeToken,
+	containsAttributeToken,
+	replaceAttributeToken,
+	clearAttributeTokens,
+	findClosestByAttribute,
+	findClosestByClass,
 };
 
 /**
@@ -41,7 +45,7 @@ export {
  * @throws {TypeError} value is not an instance of HTMLElement
  */
 function findClosestObjectLink(element) {
-    return findClosestByAttribute(element, ATTRIBUTE_OBJECTLINK);
+	return findClosestByAttribute(element, ATTRIBUTE_OBJECTLINK);
 }
 
 /**
@@ -57,16 +61,16 @@ function findClosestObjectLink(element) {
  * @return {boolean}
  */
 function addToObjectLink(element, symbol, object) {
-    validateInstance(element, HTMLElement);
-    validateSymbol(symbol);
+	validateInstance(element, HTMLElement);
+	validateSymbol(symbol);
 
-    if (element?.[symbol] === undefined) {
-        element[symbol] = new Set();
-    }
+	if (element?.[symbol] === undefined) {
+		element[symbol] = new Set();
+	}
 
-    addAttributeToken(element, ATTRIBUTE_OBJECTLINK, symbol.toString());
-    element[symbol].add(object);
-    return element;
+	addAttributeToken(element, ATTRIBUTE_OBJECTLINK, symbol.toString());
+	element[symbol].add(object);
+	return element;
 }
 
 /**
@@ -81,16 +85,16 @@ function addToObjectLink(element, symbol, object) {
  * @return {boolean}
  */
 function removeObjectLink(element, symbol) {
-    validateInstance(element, HTMLElement);
-    validateSymbol(symbol);
+	validateInstance(element, HTMLElement);
+	validateSymbol(symbol);
 
-    if (element?.[symbol] === undefined) {
-        return element;
-    }
+	if (element?.[symbol] === undefined) {
+		return element;
+	}
 
-    removeAttributeToken(element, ATTRIBUTE_OBJECTLINK, symbol.toString());
-    delete element[symbol];
-    return element;
+	removeAttributeToken(element, ATTRIBUTE_OBJECTLINK, symbol.toString());
+	delete element[symbol];
+	return element;
 }
 
 /**
@@ -105,14 +109,18 @@ function removeObjectLink(element, symbol) {
  * @return {boolean}
  */
 function hasObjectLink(element, symbol) {
-    validateInstance(element, HTMLElement);
-    validateSymbol(symbol);
-
-    if (element?.[symbol] === undefined) {
-        return false;
-    }
-
-    return containsAttributeToken(element, ATTRIBUTE_OBJECTLINK, symbol.toString());
+	validateInstance(element, HTMLElement);
+	validateSymbol(symbol);
+
+	if (element?.[symbol] === undefined) {
+		return false;
+	}
+
+	return containsAttributeToken(
+		element,
+		ATTRIBUTE_OBJECTLINK,
+		symbol.toString(),
+	);
 }
 
 /**
@@ -133,14 +141,14 @@ function hasObjectLink(element, symbol) {
  * @throws {Error} there is no object link for symbol
  */
 function getLinkedObjects(element, symbol) {
-    validateInstance(element, HTMLElement);
-    validateSymbol(symbol);
+	validateInstance(element, HTMLElement);
+	validateSymbol(symbol);
 
-    if (element?.[symbol] === undefined) {
-        throw new Error(`there is no object link for ${symbol.toString()}`);
-    }
+	if (element?.[symbol] === undefined) {
+		throw new Error(`there is no object link for ${symbol.toString()}`);
+	}
 
-    return element?.[symbol][Symbol.iterator]();
+	return element?.[symbol][Symbol.iterator]();
 }
 
 /**
@@ -158,18 +166,21 @@ function getLinkedObjects(element, symbol) {
  * @return {HTMLElement}
  */
 function toggleAttributeToken(element, key, token) {
-    validateInstance(element, HTMLElement);
-    validateString(token);
-    validateString(key);
+	validateInstance(element, HTMLElement);
+	validateString(token);
+	validateString(key);
 
-    if (!element.hasAttribute(key)) {
-        element.setAttribute(key, token);
-        return element;
-    }
+	if (!element.hasAttribute(key)) {
+		element.setAttribute(key, token);
+		return element;
+	}
 
-    element.setAttribute(key, new TokenList(element.getAttribute(key)).toggle(token).toString());
+	element.setAttribute(
+		key,
+		new TokenList(element.getAttribute(key)).toggle(token).toString(),
+	);
 
-    return element;
+	return element;
 }
 
 /**
@@ -185,18 +196,21 @@ function toggleAttributeToken(element, key, token) {
  * @return {HTMLElement}
  */
 function addAttributeToken(element, key, token) {
-    validateInstance(element, HTMLElement);
-    validateString(token);
-    validateString(key);
+	validateInstance(element, HTMLElement);
+	validateString(token);
+	validateString(key);
 
-    if (!element.hasAttribute(key)) {
-        element.setAttribute(key, token);
-        return element;
-    }
+	if (!element.hasAttribute(key)) {
+		element.setAttribute(key, token);
+		return element;
+	}
 
-    element.setAttribute(key, new TokenList(element.getAttribute(key)).add(token).toString());
+	element.setAttribute(
+		key,
+		new TokenList(element.getAttribute(key)).add(token).toString(),
+	);
 
-    return element;
+	return element;
 }
 
 /**
@@ -214,17 +228,20 @@ function addAttributeToken(element, key, token) {
  * @return {HTMLElement}
  */
 function removeAttributeToken(element, key, token) {
-    validateInstance(element, HTMLElement);
-    validateString(token);
-    validateString(key);
+	validateInstance(element, HTMLElement);
+	validateString(token);
+	validateString(key);
 
-    if (!element.hasAttribute(key)) {
-        return element;
-    }
+	if (!element.hasAttribute(key)) {
+		return element;
+	}
 
-    element.setAttribute(key, new TokenList(element.getAttribute(key)).remove(token).toString());
+	element.setAttribute(
+		key,
+		new TokenList(element.getAttribute(key)).remove(token).toString(),
+	);
 
-    return element;
+	return element;
 }
 
 /**
@@ -242,15 +259,15 @@ function removeAttributeToken(element, key, token) {
  * @return {boolean}
  */
 function containsAttributeToken(element, key, token) {
-    validateInstance(element, HTMLElement);
-    validateString(token);
-    validateString(key);
+	validateInstance(element, HTMLElement);
+	validateString(token);
+	validateString(key);
 
-    if (!element.hasAttribute(key)) {
-        return false;
-    }
+	if (!element.hasAttribute(key)) {
+		return false;
+	}
 
-    return new TokenList(element.getAttribute(key)).contains(token);
+	return new TokenList(element.getAttribute(key)).contains(token);
 }
 
 /**
@@ -267,18 +284,21 @@ function containsAttributeToken(element, key, token) {
  * @return {HTMLElement}
  */
 function replaceAttributeToken(element, key, from, to) {
-    validateInstance(element, HTMLElement);
-    validateString(from);
-    validateString(to);
-    validateString(key);
+	validateInstance(element, HTMLElement);
+	validateString(from);
+	validateString(to);
+	validateString(key);
 
-    if (!element.hasAttribute(key)) {
-        return element;
-    }
+	if (!element.hasAttribute(key)) {
+		return element;
+	}
 
-    element.setAttribute(key, new TokenList(element.getAttribute(key)).replace(from, to).toString());
+	element.setAttribute(
+		key,
+		new TokenList(element.getAttribute(key)).replace(from, to).toString(),
+	);
 
-    return element;
+	return element;
 }
 
 /**
@@ -293,16 +313,16 @@ function replaceAttributeToken(element, key, from, to) {
  * @return {HTMLElement}
  */
 function clearAttributeTokens(element, key) {
-    validateInstance(element, HTMLElement);
-    validateString(key);
+	validateInstance(element, HTMLElement);
+	validateString(key);
 
-    if (!element.hasAttribute(key)) {
-        return element;
-    }
+	if (!element.hasAttribute(key)) {
+		return element;
+	}
 
-    element.setAttribute(key, "");
+	element.setAttribute(key, "");
 
-    return element;
+	return element;
 }
 
 /**
@@ -335,25 +355,25 @@ function clearAttributeTokens(element, key) {
  * @summary find closest node
  */
 function findClosestByAttribute(element, key, value) {
-    validateInstance(element, getGlobalFunction("HTMLElement"));
-
-    if (element.hasAttribute(key)) {
-        if (value === undefined) {
-            return element;
-        }
-
-        if (element.getAttribute(key) === value) {
-            return element;
-        }
-    }
-
-    let selector = validateString(key);
-    if (value !== undefined) selector += `=${validateString(value)}`;
-    let result = element.closest(`[${selector}]`);
-    if (result instanceof HTMLElement) {
-        return result;
-    }
-    return undefined;
+	validateInstance(element, getGlobalFunction("HTMLElement"));
+
+	if (element.hasAttribute(key)) {
+		if (value === undefined) {
+			return element;
+		}
+
+		if (element.getAttribute(key) === value) {
+			return element;
+		}
+	}
+
+	let selector = validateString(key);
+	if (value !== undefined) selector += `=${validateString(value)}`;
+	let result = element.closest(`[${selector}]`);
+	if (result instanceof HTMLElement) {
+		return result;
+	}
+	return undefined;
 }
 
 /**
@@ -388,16 +408,16 @@ function findClosestByAttribute(element, key, value) {
  * @summary find closest node
  */
 function findClosestByClass(element, className) {
-    validateInstance(element, getGlobalFunction("HTMLElement"));
+	validateInstance(element, getGlobalFunction("HTMLElement"));
 
-    if (element?.classList?.contains(validateString(className))) {
-        return element;
-    }
+	if (element?.classList?.contains(validateString(className))) {
+		return element;
+	}
 
-    let result = element.closest(`.${className}`);
-    if (result instanceof HTMLElement) {
-        return result;
-    }
+	let result = element.closest(`.${className}`);
+	if (result instanceof HTMLElement) {
+		return result;
+	}
 
-    return undefined;
+	return undefined;
 }
diff --git a/source/dom/constants.mjs b/source/dom/constants.mjs
index a3fe1b99271636f3b5a3bf1cf0c1568b884def36..0c7aae9e172c13aa047c9674a3b3a30cd5126cf9 100644
--- a/source/dom/constants.mjs
+++ b/source/dom/constants.mjs
@@ -6,62 +6,62 @@
  */
 
 export {
-    DEFAULT_THEME,
-    ATTRIBUTE_PREFIX,
-    ATTRIBUTE_OPTIONS,
-    ATTRIBUTE_OPTIONS_SELECTOR,
-    ATTRIBUTE_THEME_PREFIX,
-    ATTRIBUTE_THEME_NAME,
-    ATTRIBUTE_UPDATER_ATTRIBUTES,
-    ATTRIBUTE_UPDATER_SELECT_THIS,
-    ATTRIBUTE_UPDATER_REPLACE,
-    ATTRIBUTE_UPDATER_INSERT,
-    ATTRIBUTE_UPDATER_INSERT_REFERENCE,
-    ATTRIBUTE_UPDATER_REMOVE,
-    ATTRIBUTE_UPDATER_BIND,
-    ATTRIBUTE_TEMPLATE_PREFIX,
-    ATTRIBUTE_ROLE,
-    ATTRIBUTE_DISABLED,
-    ATTRIBUTE_VALUE,
-    ATTRIBUTE_OBJECTLINK,
-    ATTRIBUTE_ERRORMESSAGE,
-    TAG_SCRIPT,
-    TAG_STYLE,
-    TAG_LINK,
-    ATTRIBUTE_ID,
-    ATTRIBUTE_CLASS,
-    ATTRIBUTE_TITLE,
-    ATTRIBUTE_SRC,
-    ATTRIBUTE_HREF,
-    ATTRIBUTE_TYPE,
-    ATTRIBUTE_NONCE,
-    ATTRIBUTE_TRANSLATE,
-    ATTRIBUTE_TABINDEX,
-    ATTRIBUTE_SPELLCHECK,
-    ATTRIBUTE_SLOT,
-    ATTRIBUTE_PART,
-    ATTRIBUTE_LANG,
-    ATTRIBUTE_ITEMTYPE,
-    ATTRIBUTE_ITEMSCOPE,
-    ATTRIBUTE_ITEMREF,
-    ATTRIBUTE_ITEMID,
-    ATTRIBUTE_ITEMPROP,
-    ATTRIBUTE_IS,
-    ATTRIBUTE_INPUTMODE,
-    ATTRIBUTE_ACCESSKEY,
-    ATTRIBUTE_AUTOCAPITALIZE,
-    ATTRIBUTE_AUTOFOCUS,
-    ATTRIBUTE_CONTENTEDITABLE,
-    ATTRIBUTE_DIR,
-    ATTRIBUTE_DRAGGABLE,
-    ATTRIBUTE_ENTERKEYHINT,
-    ATTRIBUTE_EXPORTPARTS,
-    ATTRIBUTE_HIDDEN,
-    objectUpdaterLinkSymbol,
-    customElementUpdaterLinkSymbol,
-    initControlCallbackName,
-    ATTRIBUTE_SCRIPT_HOST,
-    ATTRIBUTE_INIT_CALLBACK,
+	DEFAULT_THEME,
+	ATTRIBUTE_PREFIX,
+	ATTRIBUTE_OPTIONS,
+	ATTRIBUTE_OPTIONS_SELECTOR,
+	ATTRIBUTE_THEME_PREFIX,
+	ATTRIBUTE_THEME_NAME,
+	ATTRIBUTE_UPDATER_ATTRIBUTES,
+	ATTRIBUTE_UPDATER_SELECT_THIS,
+	ATTRIBUTE_UPDATER_REPLACE,
+	ATTRIBUTE_UPDATER_INSERT,
+	ATTRIBUTE_UPDATER_INSERT_REFERENCE,
+	ATTRIBUTE_UPDATER_REMOVE,
+	ATTRIBUTE_UPDATER_BIND,
+	ATTRIBUTE_TEMPLATE_PREFIX,
+	ATTRIBUTE_ROLE,
+	ATTRIBUTE_DISABLED,
+	ATTRIBUTE_VALUE,
+	ATTRIBUTE_OBJECTLINK,
+	ATTRIBUTE_ERRORMESSAGE,
+	TAG_SCRIPT,
+	TAG_STYLE,
+	TAG_LINK,
+	ATTRIBUTE_ID,
+	ATTRIBUTE_CLASS,
+	ATTRIBUTE_TITLE,
+	ATTRIBUTE_SRC,
+	ATTRIBUTE_HREF,
+	ATTRIBUTE_TYPE,
+	ATTRIBUTE_NONCE,
+	ATTRIBUTE_TRANSLATE,
+	ATTRIBUTE_TABINDEX,
+	ATTRIBUTE_SPELLCHECK,
+	ATTRIBUTE_SLOT,
+	ATTRIBUTE_PART,
+	ATTRIBUTE_LANG,
+	ATTRIBUTE_ITEMTYPE,
+	ATTRIBUTE_ITEMSCOPE,
+	ATTRIBUTE_ITEMREF,
+	ATTRIBUTE_ITEMID,
+	ATTRIBUTE_ITEMPROP,
+	ATTRIBUTE_IS,
+	ATTRIBUTE_INPUTMODE,
+	ATTRIBUTE_ACCESSKEY,
+	ATTRIBUTE_AUTOCAPITALIZE,
+	ATTRIBUTE_AUTOFOCUS,
+	ATTRIBUTE_CONTENTEDITABLE,
+	ATTRIBUTE_DIR,
+	ATTRIBUTE_DRAGGABLE,
+	ATTRIBUTE_ENTERKEYHINT,
+	ATTRIBUTE_EXPORTPARTS,
+	ATTRIBUTE_HIDDEN,
+	objectUpdaterLinkSymbol,
+	customElementUpdaterLinkSymbol,
+	initControlCallbackName,
+	ATTRIBUTE_SCRIPT_HOST,
+	ATTRIBUTE_INIT_CALLBACK,
 };
 
 /**
@@ -253,7 +253,9 @@ const ATTRIBUTE_ERRORMESSAGE = `${ATTRIBUTE_PREFIX}error`;
  * @license AGPLv3
  * @since 1.24.0
  */
-const objectUpdaterLinkSymbol = Symbol.for("@schukai/monster/dom/@@object-updater-link");
+const objectUpdaterLinkSymbol = Symbol.for(
+	"@schukai/monster/dom/@@object-updater-link",
+);
 
 /**
  * @memberOf Monster.DOM
@@ -261,7 +263,9 @@ const objectUpdaterLinkSymbol = Symbol.for("@schukai/monster/dom/@@object-update
  * @license AGPLv3
  * @since 1.24.0
  */
-const customElementUpdaterLinkSymbol = Symbol.for("@schukai/monster/dom/custom-element@@options-updater-link");
+const customElementUpdaterLinkSymbol = Symbol.for(
+	"@schukai/monster/dom/custom-element@@options-updater-link",
+);
 
 /**
  * @memberOf Monster.DOM
diff --git a/source/dom/customcontrol.mjs b/source/dom/customcontrol.mjs
index d853f1c926d9df05e838cd331b8c5381ceda8367..d4ae138165b195fe9463d9ebff84c0928560cb79 100644
--- a/source/dom/customcontrol.mjs
+++ b/source/dom/customcontrol.mjs
@@ -49,293 +49,295 @@ const attachedInternalSymbol = Symbol("attachedInternal");
  * @extends Monster.DOM.CustomElement
  */
 class CustomControl extends CustomElement {
-    /**
-     * The constructor method of CustomControl, which is called when creating a new instance.
-     * It checks whether the element supports `attachInternals()` and initializes an internal form-associated element
-     * if supported. Additionally, it initializes a MutationObserver to watch for attribute changes.
-     *
-     * See the links below for more information:
-     * {@link https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-define|CustomElementRegistry.define()}
-     * {@link https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-get|CustomElementRegistry.get()}
-     * and {@link https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals|ElementInternals}
-     *
-     * @inheritdoc
-     * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
-     * @since 1.7.0
-     */
-    constructor() {
-        super();
-
-        // check if element supports `attachInternals()`
-        if (typeof this["attachInternals"] === "function") {
-            this[attachedInternalSymbol] = this.attachInternals();
-        } else {
-            // `attachInternals()` is not supported, so a polyfill is necessary
-            throw Error("the ElementInternals is not supported and a polyfill is necessary");
-        }
-
-        // initialize a MutationObserver to watch for attribute changes
-        initObserver.call(this);
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/dom/custom-control@@instance");
-    }
-
-    /**
-     * This method determines which attributes are to be monitored by `attributeChangedCallback()`.
-     *
-     * @return {string[]}
-     * @since 1.15.0
-     */
-    static get observedAttributes() {
-        return super.observedAttributes;
-    }
-
-    /**
-     * Adding a static `formAssociated` property, with a true value, makes an autonomous custom element a form-associated custom element.
-     *
-     * @see [attachInternals()]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals}
-     * @see [Custom Elements Face Example]{@link https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-face-example}
-     * @since 1.14.0
-     * @return {boolean}
-     */
-    static formAssociated = true;
-
-    /**
-     * @inheritdoc
-     * @since 1.14.0
-     **/
-    get defaults() {
-        return extend({}, super.defaults);
-    }
-
-    /**
-     * Must be overridden by a derived class and return the value of the control.
-     *
-     * This is a method of [internal API](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals), which is a part of the web standard for custom elements.
-     *
-     * @since 1.14.0
-     * @throws {Error} the value getter must be overwritten by the derived class
-     */
-    get value() {
-        throw Error("the value getter must be overwritten by the derived class");
-    }
-
-    /**
-     * Must be overridden by a derived class and set the value of the control.
-     *
-     * This is a method of [internal API](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals), which is a part of the web standard for custom elements.
-     *
-     * @param {*} value The value to set.
-     * @since 1.14.0
-     * @throws {Error} the value setter must be overwritten by the derived class
-     */
-    set value(value) {
-        throw Error("the value setter must be overwritten by the derived class");
-    }
-
-    /**
-     * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
-     *
-     * @return {NodeList}
-     * @since 1.14.0
-     * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/labels}
-     * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
-     */
-    get labels() {
-        return getInternal.call(this)?.labels;
-    }
-
-    /**
-     * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
-     *
-     * @return {string|null}
-     */
-    get name() {
-        return this.getAttribute("name");
-    }
-
-    /**
-     * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
-     *
-     * @return {string}
-     */
-    get type() {
-        return this.constructor.getTag();
-    }
-
-    /**
-     * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
-     *
-     * @return {ValidityState}
-     * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
-     * @see [ValidityState]{@link https://developer.mozilla.org/en-US/docs/Web/API/ValidityState}
-     * @see [validity]{@link https://developer.mozilla.org/en-US/docs/Web/API/validity}
-     */
-    get validity() {
-        return getInternal.call(this)?.validity;
-    }
-
-    /**
-     * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
-     *
-     * @return {string}
-     * @since 1.14.0
-     * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/validationMessage
-     * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
-     */
-    get validationMessage() {
-        return getInternal.call(this)?.validationMessage;
-    }
-
-    /**
-     * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
-     *
-     * @return {boolean}
-     * @since 1.14.0
-     * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/willValidate
-     * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
-     */
-    get willValidate() {
-        return getInternal.call(this)?.willValidate;
-    }
-
-    /**
-     * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
-     *
-     * @return {boolean}
-     * @since 1.14.0
-     * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/states
-     * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
-     */
-    get states() {
-        return getInternal.call(this)?.states;
-    }
-
-    /**
-     * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
-     *
-     * @return {HTMLFontElement|null}
-     * @since 1.14.0
-     * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/form
-     * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
-     */
-    get form() {
-        return getInternal.call(this)?.form;
-    }
-
-    /**
-     * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
-     *
-     * ```
-     * // Use the control's name as the base name for submitted data
-     * const n = this.getAttribute('name');
-     * const entries = new FormData();
-     * entries.append(n + '-first-name', this.firstName_);
-     * entries.append(n + '-last-name', this.lastName_);
-     * this.setFormValue(entries);
-     * ```
-     *
-     * @param {File|string|FormData} value
-     * @param {File|string|FormData} state
-     * @since 1.14.0
-     * @return {undefined}
-     * @throws {DOMException} NotSupportedError
-     * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
-     * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/setFormValue
-     */
-    setFormValue(value, state) {
-        getInternal.call(this).setFormValue(value, state);
-    }
-
-    /**
-     *
-     * @param {object} flags
-     * @param {string|undefined} message
-     * @param {HTMLElement} anchor
-     * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/setValidity
-     * @since 1.14.0
-     * @return {undefined}
-     * @throws {DOMException} NotSupportedError
-     * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
-     */
-    setValidity(flags, message, anchor) {
-        getInternal.call(this).setValidity(flags, message, anchor);
-    }
-
-    /**
-     * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
-     *
-     * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/checkValidity
-     * @since 1.14.0
-     * @return {boolean}
-     * @throws {DOMException} NotSupportedError
-     * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
-     */
-    checkValidity() {
-        return getInternal.call(this)?.checkValidity();
-    }
-
-    /**
-     * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
-     *
-     * @return {boolean}
-     * @since 1.14.0
-     * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/reportValidity
-     * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
-     * @throws {DOMException} NotSupportedError
-     */
-    reportValidity() {
-        return getInternal.call(this)?.reportValidity();
-    }
-
-    /**
-     * Sets the `form` attribute of the custom control to the `id` of the passed form element.
-     * If no form element is passed, removes the `form` attribute.
-     *
-     * @param {HTMLFormElement} form - The form element to associate with the control
-     */
-    formAssociatedCallback(form) {
-        if (form) {
-            if (form.id) {
-                this.setAttribute("form", form.id);
-            }
-        } else {
-            this.removeAttribute("form");
-        }
-    }
-
-    /**
-     * Sets or removes the `disabled` attribute of the custom control based on the passed value.
-     *
-     * @param {boolean} disabled - Whether or not the control should be disabled
-     */
-    formDisabledCallback(disabled) {
-        if (disabled) {
-            this.setAttribute("disabled", "");
-        } else {
-            this.removeAttribute("disabled");
-        }
-    }
-
-    /**
-     * @param {string} state
-     * @param {string} mode
-     */
-    formStateRestoreCallback(state, mode) {}
-
-    /**
-     *
-     */
-    formResetCallback() {
-        this.value = "";
-    }
+	/**
+	 * The constructor method of CustomControl, which is called when creating a new instance.
+	 * It checks whether the element supports `attachInternals()` and initializes an internal form-associated element
+	 * if supported. Additionally, it initializes a MutationObserver to watch for attribute changes.
+	 *
+	 * See the links below for more information:
+	 * {@link https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-define|CustomElementRegistry.define()}
+	 * {@link https://html.spec.whatwg.org/multipage/custom-elements.html#dom-customelementregistry-get|CustomElementRegistry.get()}
+	 * and {@link https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals|ElementInternals}
+	 *
+	 * @inheritdoc
+	 * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
+	 * @since 1.7.0
+	 */
+	constructor() {
+		super();
+
+		// check if element supports `attachInternals()`
+		if (typeof this["attachInternals"] === "function") {
+			this[attachedInternalSymbol] = this.attachInternals();
+		} else {
+			// `attachInternals()` is not supported, so a polyfill is necessary
+			throw Error(
+				"the ElementInternals is not supported and a polyfill is necessary",
+			);
+		}
+
+		// initialize a MutationObserver to watch for attribute changes
+		initObserver.call(this);
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/dom/custom-control@@instance");
+	}
+
+	/**
+	 * This method determines which attributes are to be monitored by `attributeChangedCallback()`.
+	 *
+	 * @return {string[]}
+	 * @since 1.15.0
+	 */
+	static get observedAttributes() {
+		return super.observedAttributes;
+	}
+
+	/**
+	 * Adding a static `formAssociated` property, with a true value, makes an autonomous custom element a form-associated custom element.
+	 *
+	 * @see [attachInternals()]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals}
+	 * @see [Custom Elements Face Example]{@link https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-face-example}
+	 * @since 1.14.0
+	 * @return {boolean}
+	 */
+	static formAssociated = true;
+
+	/**
+	 * @inheritdoc
+	 * @since 1.14.0
+	 **/
+	get defaults() {
+		return extend({}, super.defaults);
+	}
+
+	/**
+	 * Must be overridden by a derived class and return the value of the control.
+	 *
+	 * This is a method of [internal API](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals), which is a part of the web standard for custom elements.
+	 *
+	 * @since 1.14.0
+	 * @throws {Error} the value getter must be overwritten by the derived class
+	 */
+	get value() {
+		throw Error("the value getter must be overwritten by the derived class");
+	}
+
+	/**
+	 * Must be overridden by a derived class and set the value of the control.
+	 *
+	 * This is a method of [internal API](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals), which is a part of the web standard for custom elements.
+	 *
+	 * @param {*} value The value to set.
+	 * @since 1.14.0
+	 * @throws {Error} the value setter must be overwritten by the derived class
+	 */
+	set value(value) {
+		throw Error("the value setter must be overwritten by the derived class");
+	}
+
+	/**
+	 * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
+	 *
+	 * @return {NodeList}
+	 * @since 1.14.0
+	 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/labels}
+	 * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
+	 */
+	get labels() {
+		return getInternal.call(this)?.labels;
+	}
+
+	/**
+	 * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
+	 *
+	 * @return {string|null}
+	 */
+	get name() {
+		return this.getAttribute("name");
+	}
+
+	/**
+	 * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
+	 *
+	 * @return {string}
+	 */
+	get type() {
+		return this.constructor.getTag();
+	}
+
+	/**
+	 * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
+	 *
+	 * @return {ValidityState}
+	 * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
+	 * @see [ValidityState]{@link https://developer.mozilla.org/en-US/docs/Web/API/ValidityState}
+	 * @see [validity]{@link https://developer.mozilla.org/en-US/docs/Web/API/validity}
+	 */
+	get validity() {
+		return getInternal.call(this)?.validity;
+	}
+
+	/**
+	 * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
+	 *
+	 * @return {string}
+	 * @since 1.14.0
+	 * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/validationMessage
+	 * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
+	 */
+	get validationMessage() {
+		return getInternal.call(this)?.validationMessage;
+	}
+
+	/**
+	 * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
+	 *
+	 * @return {boolean}
+	 * @since 1.14.0
+	 * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/willValidate
+	 * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
+	 */
+	get willValidate() {
+		return getInternal.call(this)?.willValidate;
+	}
+
+	/**
+	 * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
+	 *
+	 * @return {boolean}
+	 * @since 1.14.0
+	 * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/states
+	 * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
+	 */
+	get states() {
+		return getInternal.call(this)?.states;
+	}
+
+	/**
+	 * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
+	 *
+	 * @return {HTMLFontElement|null}
+	 * @since 1.14.0
+	 * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/form
+	 * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
+	 */
+	get form() {
+		return getInternal.call(this)?.form;
+	}
+
+	/**
+	 * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
+	 *
+	 * ```
+	 * // Use the control's name as the base name for submitted data
+	 * const n = this.getAttribute('name');
+	 * const entries = new FormData();
+	 * entries.append(n + '-first-name', this.firstName_);
+	 * entries.append(n + '-last-name', this.lastName_);
+	 * this.setFormValue(entries);
+	 * ```
+	 *
+	 * @param {File|string|FormData} value
+	 * @param {File|string|FormData} state
+	 * @since 1.14.0
+	 * @return {undefined}
+	 * @throws {DOMException} NotSupportedError
+	 * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
+	 * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/setFormValue
+	 */
+	setFormValue(value, state) {
+		getInternal.call(this).setFormValue(value, state);
+	}
+
+	/**
+	 *
+	 * @param {object} flags
+	 * @param {string|undefined} message
+	 * @param {HTMLElement} anchor
+	 * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/setValidity
+	 * @since 1.14.0
+	 * @return {undefined}
+	 * @throws {DOMException} NotSupportedError
+	 * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
+	 */
+	setValidity(flags, message, anchor) {
+		getInternal.call(this).setValidity(flags, message, anchor);
+	}
+
+	/**
+	 * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
+	 *
+	 * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/checkValidity
+	 * @since 1.14.0
+	 * @return {boolean}
+	 * @throws {DOMException} NotSupportedError
+	 * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
+	 */
+	checkValidity() {
+		return getInternal.call(this)?.checkValidity();
+	}
+
+	/**
+	 * This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
+	 *
+	 * @return {boolean}
+	 * @since 1.14.0
+	 * @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/reportValidity
+	 * @throws {Error} the ElementInternals is not supported and a polyfill is necessary
+	 * @throws {DOMException} NotSupportedError
+	 */
+	reportValidity() {
+		return getInternal.call(this)?.reportValidity();
+	}
+
+	/**
+	 * Sets the `form` attribute of the custom control to the `id` of the passed form element.
+	 * If no form element is passed, removes the `form` attribute.
+	 *
+	 * @param {HTMLFormElement} form - The form element to associate with the control
+	 */
+	formAssociatedCallback(form) {
+		if (form) {
+			if (form.id) {
+				this.setAttribute("form", form.id);
+			}
+		} else {
+			this.removeAttribute("form");
+		}
+	}
+
+	/**
+	 * Sets or removes the `disabled` attribute of the custom control based on the passed value.
+	 *
+	 * @param {boolean} disabled - Whether or not the control should be disabled
+	 */
+	formDisabledCallback(disabled) {
+		if (disabled) {
+			this.setAttribute("disabled", "");
+		} else {
+			this.removeAttribute("disabled");
+		}
+	}
+
+	/**
+	 * @param {string} state
+	 * @param {string} mode
+	 */
+	formStateRestoreCallback(state, mode) {}
+
+	/**
+	 *
+	 */
+	formResetCallback() {
+		this.value = "";
+	}
 }
 
 /**
@@ -345,13 +347,15 @@ class CustomControl extends CustomElement {
  * @this CustomControl
  */
 function getInternal() {
-    const self = this;
+	const self = this;
 
-    if (!(attachedInternalSymbol in this)) {
-        throw new Error("ElementInternals is not supported and a polyfill is necessary");
-    }
+	if (!(attachedInternalSymbol in this)) {
+		throw new Error(
+			"ElementInternals is not supported and a polyfill is necessary",
+		);
+	}
 
-    return self[attachedInternalSymbol];
+	return self[attachedInternalSymbol];
 }
 
 /**
@@ -360,10 +364,10 @@ function getInternal() {
  * @this CustomControl
  */
 function initObserver() {
-    const self = this;
+	const self = this;
 
-    // value
-    self[attributeObserverSymbol]["value"] = () => {
-        self.setOption("value", self.getAttribute("value"));
-    };
+	// value
+	self[attributeObserverSymbol]["value"] = () => {
+		self.setOption("value", self.getAttribute("value"));
+	};
 }
diff --git a/source/dom/customelement.mjs b/source/dom/customelement.mjs
index ba2afd73073dd169b2465e49965a403b2d24ccf3..be1f12afe3051f11154f3840101f3f0aebcfac88 100644
--- a/source/dom/customelement.mjs
+++ b/source/dom/customelement.mjs
@@ -13,37 +13,55 @@ import { Formatter } from "../text/formatter.mjs";
 
 import { parseDataURL } from "../types/dataurl.mjs";
 import { getGlobalObject } from "../types/global.mjs";
-import { isArray, isFunction, isIterable, isObject, isString } from "../types/is.mjs";
+import {
+	isArray,
+	isFunction,
+	isIterable,
+	isObject,
+	isString,
+} from "../types/is.mjs";
 import { Observer } from "../types/observer.mjs";
 import { ProxyObserver } from "../types/proxyobserver.mjs";
-import { validateFunction, validateInstance, validateObject, validateString } from "../types/validate.mjs";
+import {
+	validateFunction,
+	validateInstance,
+	validateObject,
+	validateString,
+} from "../types/validate.mjs";
 import { clone } from "../util/clone.mjs";
-import { addAttributeToken, getLinkedObjects, hasObjectLink } from "./attributes.mjs";
 import {
-    ATTRIBUTE_DISABLED,
-    ATTRIBUTE_ERRORMESSAGE,
-    ATTRIBUTE_OPTIONS,
-    ATTRIBUTE_INIT_CALLBACK,
-    ATTRIBUTE_OPTIONS_SELECTOR,
-    ATTRIBUTE_SCRIPT_HOST,
-    customElementUpdaterLinkSymbol,
-    initControlCallbackName,
+	addAttributeToken,
+	getLinkedObjects,
+	hasObjectLink,
+} from "./attributes.mjs";
+import {
+	ATTRIBUTE_DISABLED,
+	ATTRIBUTE_ERRORMESSAGE,
+	ATTRIBUTE_OPTIONS,
+	ATTRIBUTE_INIT_CALLBACK,
+	ATTRIBUTE_OPTIONS_SELECTOR,
+	ATTRIBUTE_SCRIPT_HOST,
+	customElementUpdaterLinkSymbol,
+	initControlCallbackName,
 } from "./constants.mjs";
 import { findDocumentTemplate, Template } from "./template.mjs";
 import { addObjectWithUpdaterToElement } from "./updater.mjs";
 import { instanceSymbol } from "../constants.mjs";
-import { getDocumentTranslations, Translations } from "../i18n/translations.mjs";
+import {
+	getDocumentTranslations,
+	Translations,
+} from "../i18n/translations.mjs";
 import { getSlottedElements } from "./slotted.mjs";
 import { initOptionsFromAttributes } from "./util/init-options-from-attributes.mjs";
 import { setOptionFromAttribute } from "./util/set-option-from-attribute.mjs";
 
 export {
-    CustomElement,
-    initMethodSymbol,
-    assembleMethodSymbol,
-    attributeObserverSymbol,
-    registerCustomElement,
-    getSlottedElements,
+	CustomElement,
+	initMethodSymbol,
+	assembleMethodSymbol,
+	attributeObserverSymbol,
+	registerCustomElement,
+	getSlottedElements,
 };
 
 /**
@@ -56,20 +74,26 @@ const initMethodSymbol = Symbol.for("@schukai/monster/dom/@@initMethodSymbol");
  * @memberOf Monster.DOM
  * @type {symbol}
  */
-const assembleMethodSymbol = Symbol.for("@schukai/monster/dom/@@assembleMethodSymbol");
+const assembleMethodSymbol = Symbol.for(
+	"@schukai/monster/dom/@@assembleMethodSymbol",
+);
 
 /**
  * this symbol holds the attribute observer callbacks. The key is the attribute name.
  * @memberOf Monster.DOM
  * @type {symbol}
  */
-const attributeObserverSymbol = Symbol.for("@schukai/monster/dom/@@attributeObserver");
+const attributeObserverSymbol = Symbol.for(
+	"@schukai/monster/dom/@@attributeObserver",
+);
 
 /**
  * @private
  * @type {symbol}
  */
-const attributeMutationObserverSymbol = Symbol("@schukai/monster/dom/@@mutationObserver");
+const attributeMutationObserverSymbol = Symbol(
+	"@schukai/monster/dom/@@mutationObserver",
+);
 
 /**
  * @private
@@ -201,458 +225,476 @@ const scriptHostElementSymbol = Symbol("scriptHostElement");
  * @summary A base class for HTML5 custom controls.
  */
 class CustomElement extends HTMLElement {
-    /**
-     * A new object is created. First the `initOptions` method is called. Here the
-     * options can be defined in derived classes. Subsequently, the shadowRoot is initialized.
-     *
-     * IMPORTANT: CustomControls instances are not created via the constructor, but either via a tag in the HTML or via <code>document.createElement()</code>.
-     *
-     * @throws {Error} the options attribute does not contain a valid json definition.
-     * @since 1.7.0
-     */
-    constructor() {
-        super();
-
-        this[attributeObserverSymbol] = {};
-        this[internalSymbol] = new ProxyObserver({
-            options: initOptionsFromAttributes(this, extend({}, this.defaults)),
-        });
-        this[initMethodSymbol]();
-        initOptionObserver.call(this);
-        this[scriptHostElementSymbol] = [];
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/dom/custom-element@@instance");
-    }
-
-    /**
-     * This method determines which attributes are to be
-     * monitored by `attributeChangedCallback()`. Unfortunately, this method is static.
-     * Therefore, the `observedAttributes` property cannot be changed during runtime.
-     *
-     * @return {string[]}
-     * @since 1.15.0
-     */
-    static get observedAttributes() {
-        return [];
-    }
-
-    /**
-     *
-     * @param attribute
-     * @param callback
-     * @returns {Monster.DOM.CustomElement}
-     */
-    addAttributeObserver(attribute, callback) {
-        validateFunction(callback);
-        this[attributeObserverSymbol][attribute] = callback;
-        return this;
-    }
-
-    /**
-     *
-     * @param attribute
-     * @returns {Monster.DOM.CustomElement}
-     */
-    removeAttributeObserver(attribute) {
-        delete this[attributeObserverSymbol][attribute];
-        return this;
-    }
-
-    /**
-     * The `defaults` property defines the default values for a control. If you want to override these,
-     * you can use various methods, which are described in the documentation available at
-     * {@link https://monsterjs.orgendocconfigurate-a-monster-control}.
-     *
-     * The individual configuration values are listed below:
-     *
-     * More information about the shadowRoot can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow),
-     * in the [HTML Standard](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements) or in the [WHATWG Wiki](https://wiki.whatwg.org/wiki/Custom_Elements).
-     *
-     * More information about the template element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template).
-     *
-     * More information about the slot element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot).
-     *
-     * @property {boolean} disabled=false Specifies whether the control is disabled. When present, it makes the element non-mutable, non-focusable, and non-submittable with the form.
-     * @property {string} shadowMode=open Specifies the mode of the shadow root. When set to `open`, elements in the shadow root are accessible from JavaScript outside the root, while setting it to `closed` denies access to the root's nodes from JavaScript outside it.
-     * @property {Boolean} delegatesFocus=true Specifies the behavior of the control with respect to focusability. When set to `true`, it mitigates custom element issues around focusability. When a non-focusable part of the shadow DOM is clicked, the first focusable part is given focus, and the shadow host is given any available :focus styling.
-     * @property {Object} templates Specifies the templates used by the control.
-     * @property {string} templates.main=undefined Specifies the main template used by the control.
-     * @property {Object} templateMapping Specifies the mapping of templates.
-     * @since 1.8.0
-     */
-    get defaults() {
-        return {
-            disabled: false,
-            shadowMode: "open",
-            delegatesFocus: true,
-            templates: {
-                main: undefined,
-            },
-            templateMapping: {},
-        };
-    }
-
-    /**
-     * This method updates the labels of the element.
-     * The labels are defined in the options object.
-     * The key of the label is used to retrieve the translation from the document.
-     * If the translation is different from the label, the label is updated.
-     *
-     * Before you can use this method, you must have loaded the translations.
-     *
-     * @returns {Monster.DOM.CustomElement}
-     * @throws {Error}  Cannot find element with translations. Add a translations object to the document.
-     */
-    updateI18n() {
-        const translations = getDocumentTranslations();
-        if (!translations) {
-            return this;
-        }
-
-        let labels = this.getOption("labels");
-        if (!(isObject(labels) || isIterable(labels))) {
-            return this;
-        }
-
-        for (const key in labels) {
-            const def = labels[key];
-
-            if (isString(def)) {
-                const text = translations.getText(key, def);
-                if (text !== def) {
-                    this.setOption(`labels.${key}`, text);
-                }
-                continue;
-            } else if (isObject(def)) {
-                for (const k in def) {
-                    const d = def[k];
-
-                    const text = translations.getPluralRuleText(key, k, d);
-                    if (!isString(text)) {
-                        throw new Error("Invalid labels definition");
-                    }
-                    if (text !== d) {
-                        this.setOption(`labels.${key}.${k}`, text);
-                    }
-                }
-                continue;
-            }
-
-            throw new Error("Invalid labels definition");
-        }
-        return this;
-    }
-
-    /**
-     * The `getTag()` method returns the tag name associated with the custom element. This method should be overwritten
-     * by the derived class.
-     *
-     * Note that there is no check on the name of the tag in this class. It is the responsibility of
-     * the developer to assign an appropriate tag name. If the name is not valid, the
-     * `registerCustomElement()` method will issue an error.
-     *
-     * @see https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
-     * @throws {Error} This method must be overridden by the derived class.
-     * @return {string} The tag name associated with the custom element.
-     * @since 1.7.0
-     */
-    static getTag() {
-        throw new Error("The method `getTag()` must be overridden by the derived class.");
-    }
-
-    /**
-     * The `getCSSStyleSheet()` method returns a `CSSStyleSheet` object that defines the styles for the custom element.
-     * If the environment does not support the `CSSStyleSheet` constructor, then an object can be built using the provided detour.
-     *
-     * If `undefined` is returned, then the shadow root does not receive a stylesheet.
-     *
-     * Example usage:
-     *
-     * ```js
-     * static getCSSStyleSheet() {
-     *     const sheet = new CSSStyleSheet();
-     *     sheet.replaceSync("p { color: red; }");
-     *     return sheet;
-     * }
-     * ```
-     *
-     * If the environment does not support the `CSSStyleSheet` constructor,
-     * you can use the following workaround to create the stylesheet:
-     *
-     * ```js
-     * const doc = document.implementation.createHTMLDocument('title');
-     * let style = doc.createElement("style");
-     * style.innerHTML = "p { color: red; }";
-     * style.appendChild(document.createTextNode(""));
-     * doc.head.appendChild(style);
-     * return doc.styleSheets[0];
-     * ```
-     *
-     * @return {CSSStyleSheet|CSSStyleSheet[]|string|undefined} A `CSSStyleSheet` object or an array of such objects that define the styles for the custom element, or `undefined` if no stylesheet should be applied.
-     */
-    static getCSSStyleSheet() {
-        return undefined;
-    }
-
-    /**
-     * attach a new observer
-     *
-     * @param {Observer} observer
-     * @returns {CustomElement}
-     */
-    attachObserver(observer) {
-        this[internalSymbol].attachObserver(observer);
-        return this;
-    }
-
-    /**
-     * detach a observer
-     *
-     * @param {Observer} observer
-     * @returns {CustomElement}
-     */
-    detachObserver(observer) {
-        this[internalSymbol].detachObserver(observer);
-        return this;
-    }
-
-    /**
-     * @param {Observer} observer
-     * @returns {ProxyObserver}
-     */
-    containsObserver(observer) {
-        return this[internalSymbol].containsObserver(observer);
-    }
-
-    /**
-     * nested options can be specified by path `a.b.c`
-     *
-     * @param {string} path
-     * @param {*} defaultValue
-     * @return {*}
-     * @since 1.10.0
-     */
-    getOption(path, defaultValue) {
-        let value;
-
-        try {
-            value = new Pathfinder(this[internalSymbol].getRealSubject()["options"]).getVia(path);
-        } catch (e) {}
-
-        if (value === undefined) return defaultValue;
-        return value;
-    }
-
-    /**
-     * Set option and inform elements
-     *
-     * @param {string} path
-     * @param {*} value
-     * @return {CustomElement}
-     * @since 1.14.0
-     */
-    setOption(path, value) {
-        new Pathfinder(this[internalSymbol].getSubject()["options"]).setVia(path, value);
-        return this;
-    }
-
-    /**
-     * @since 1.15.0
-     * @param {string|object} options
-     * @return {CustomElement}
-     */
-    setOptions(options) {
-        if (isString(options)) {
-            options = parseOptionsJSON.call(this, options);
-        }
-
-        const self = this;
-        extend(self[internalSymbol].getSubject()["options"], self.defaults, options);
-
-        return self;
-    }
-
-    /**
-     * Is called once via the constructor
-     *
-     * @return {CustomElement}
-     * @since 1.8.0
-     */
-    [initMethodSymbol]() {
-        return this;
-    }
-
-    /**
-     * This method is called once when the object is included in the DOM for the first time. It performs the following actions:
-     * 1. Extracts the options from the attributes and the script tag of the element and sets them.
-     * 2. Initializes the shadow root and its CSS stylesheet (if specified).
-     * 3. Initializes the HTML content of the element.
-     * 4. Initializes the custom elements inside the shadow root and the slotted elements.
-     * 5. Attaches a mutation observer to observe changes to the attributes of the element.
-     *
-     * @return {CustomElement} - The updated custom element.
-     * @since 1.8.0
-     */
-    [assembleMethodSymbol]() {
-        const self = this;
-        let elements;
-        let nodeList;
-
-        // Extract options from attributes and set them
-        const AttributeOptions = getOptionsFromAttributes.call(self);
-        if (isObject(AttributeOptions) && Object.keys(AttributeOptions).length > 0) {
-            self.setOptions(AttributeOptions);
-        }
-
-        // Extract options from script tag and set them
-        const ScriptOptions = getOptionsFromScriptTag.call(self);
-        if (isObject(ScriptOptions) && Object.keys(ScriptOptions).length > 0) {
-            self.setOptions(ScriptOptions);
-        }
-
-        // Initialize the shadow root and its CSS stylesheet
-        if (self.getOption("shadowMode", false) !== false) {
-            try {
-                initShadowRoot.call(self);
-                elements = self.shadowRoot.childNodes;
-            } catch (e) {
-                addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
-            }
-
-            try {
-                initCSSStylesheet.call(this);
-            } catch (e) {
-                addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
-            }
-        }
-
-        // If the elements are not found inside the shadow root, initialize the HTML content of the element
-        if (!(elements instanceof NodeList)) {
-            initHtmlContent.call(this);
-            elements = this.childNodes;
-        }
-
-        // Initialize the custom elements inside the shadow root and the slotted elements
-        initFromCallbackHost.call(this);
-        try {
-            nodeList = new Set([...elements, ...getSlottedElements.call(self)]);
-        } catch (e) {
-            nodeList = elements;
-        }
-        addObjectWithUpdaterToElement.call(
-            self,
-            nodeList,
-            customElementUpdaterLinkSymbol,
-            clone(self[internalSymbol].getRealSubject()["options"]),
-        );
-
-        // Attach a mutation observer to observe changes to the attributes of the element
-        attachAttributeChangeMutationObserver.call(this);
-
-        return self;
-    }
-
-    /**
-     * This method is called every time the element is inserted into the DOM. It checks if the custom element
-     * has already been initialized and if not, calls the assembleMethod to initialize it.
-     *
-     * @return {void}
-     * @since 1.7.0
-     * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/connectedCallback
-     */
-    connectedCallback() {
-        const self = this;
-
-        // Check if the object has already been initialized
-        if (!hasObjectLink(self, customElementUpdaterLinkSymbol)) {
-            // If not, call the assembleMethod to initialize the object
-            self[assembleMethodSymbol]();
-        }
-    }
-
-    /**
-     * Called every time the element is removed from the DOM. Useful for running clean up code.
-     *
-     * @return {void}
-     * @since 1.7.0
-     */
-    disconnectedCallback() {}
-
-    /**
-     * The custom element has been moved into a new document (e.g. someone called document.adoptNode(el)).
-     *
-     * @return {void}
-     * @since 1.7.0
-     */
-    adoptedCallback() {}
-
-    /**
-     * Called when an observed attribute has been added, removed, updated, or replaced. Also called for initial
-     * values when an element is created by the parser, or upgraded. Note: only attributes listed in the observedAttributes
-     * property will receive this callback.
-     *
-     * @param {string} attrName
-     * @param {string} oldVal
-     * @param {string} newVal
-     * @return {void}
-     * @since 1.15.0
-     */
-    attributeChangedCallback(attrName, oldVal, newVal) {
-        const self = this;
-
-        if (attrName.startsWith("data-monster-option-")) {
-            setOptionFromAttribute(self, attrName, this[internalSymbol].getSubject()["options"]);
-        }
-
-        const callback = self[attributeObserverSymbol]?.[attrName];
-        if (isFunction(callback)) {
-            try {
-                callback.call(self, newVal, oldVal);
-            } catch (e) {
-                addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
-            }
-        }
-    }
-
-    /**
-     *
-     * @param {Node} node
-     * @return {boolean}
-     * @throws {TypeError} value is not an instance of
-     * @since 1.19.0
-     */
-    hasNode(node) {
-        const self = this;
-
-        if (containChildNode.call(self, validateInstance(node, Node))) {
-            return true;
-        }
-
-        if (!(self.shadowRoot instanceof ShadowRoot)) {
-            return false;
-        }
-
-        return containChildNode.call(self.shadowRoot, node);
-    }
-
-    /**
-     * Calls a callback function if it exists.
-     *
-     * @param {string} name
-     * @param {*} args
-     * @returns {*}
-     */
-    callCallback(name, args) {
-        const self = this;
-        return callControlCallback.call(self, name, ...args);
-    }
+	/**
+	 * A new object is created. First the `initOptions` method is called. Here the
+	 * options can be defined in derived classes. Subsequently, the shadowRoot is initialized.
+	 *
+	 * IMPORTANT: CustomControls instances are not created via the constructor, but either via a tag in the HTML or via <code>document.createElement()</code>.
+	 *
+	 * @throws {Error} the options attribute does not contain a valid json definition.
+	 * @since 1.7.0
+	 */
+	constructor() {
+		super();
+
+		this[attributeObserverSymbol] = {};
+		this[internalSymbol] = new ProxyObserver({
+			options: initOptionsFromAttributes(this, extend({}, this.defaults)),
+		});
+		this[initMethodSymbol]();
+		initOptionObserver.call(this);
+		this[scriptHostElementSymbol] = [];
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/dom/custom-element@@instance");
+	}
+
+	/**
+	 * This method determines which attributes are to be
+	 * monitored by `attributeChangedCallback()`. Unfortunately, this method is static.
+	 * Therefore, the `observedAttributes` property cannot be changed during runtime.
+	 *
+	 * @return {string[]}
+	 * @since 1.15.0
+	 */
+	static get observedAttributes() {
+		return [];
+	}
+
+	/**
+	 *
+	 * @param attribute
+	 * @param callback
+	 * @returns {Monster.DOM.CustomElement}
+	 */
+	addAttributeObserver(attribute, callback) {
+		validateFunction(callback);
+		this[attributeObserverSymbol][attribute] = callback;
+		return this;
+	}
+
+	/**
+	 *
+	 * @param attribute
+	 * @returns {Monster.DOM.CustomElement}
+	 */
+	removeAttributeObserver(attribute) {
+		delete this[attributeObserverSymbol][attribute];
+		return this;
+	}
+
+	/**
+	 * The `defaults` property defines the default values for a control. If you want to override these,
+	 * you can use various methods, which are described in the documentation available at
+	 * {@link https://monsterjs.orgendocconfigurate-a-monster-control}.
+	 *
+	 * The individual configuration values are listed below:
+	 *
+	 * More information about the shadowRoot can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow),
+	 * in the [HTML Standard](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements) or in the [WHATWG Wiki](https://wiki.whatwg.org/wiki/Custom_Elements).
+	 *
+	 * More information about the template element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template).
+	 *
+	 * More information about the slot element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot).
+	 *
+	 * @property {boolean} disabled=false Specifies whether the control is disabled. When present, it makes the element non-mutable, non-focusable, and non-submittable with the form.
+	 * @property {string} shadowMode=open Specifies the mode of the shadow root. When set to `open`, elements in the shadow root are accessible from JavaScript outside the root, while setting it to `closed` denies access to the root's nodes from JavaScript outside it.
+	 * @property {Boolean} delegatesFocus=true Specifies the behavior of the control with respect to focusability. When set to `true`, it mitigates custom element issues around focusability. When a non-focusable part of the shadow DOM is clicked, the first focusable part is given focus, and the shadow host is given any available :focus styling.
+	 * @property {Object} templates Specifies the templates used by the control.
+	 * @property {string} templates.main=undefined Specifies the main template used by the control.
+	 * @property {Object} templateMapping Specifies the mapping of templates.
+	 * @since 1.8.0
+	 */
+	get defaults() {
+		return {
+			disabled: false,
+			shadowMode: "open",
+			delegatesFocus: true,
+			templates: {
+				main: undefined,
+			},
+			templateMapping: {},
+		};
+	}
+
+	/**
+	 * This method updates the labels of the element.
+	 * The labels are defined in the options object.
+	 * The key of the label is used to retrieve the translation from the document.
+	 * If the translation is different from the label, the label is updated.
+	 *
+	 * Before you can use this method, you must have loaded the translations.
+	 *
+	 * @returns {Monster.DOM.CustomElement}
+	 * @throws {Error}  Cannot find element with translations. Add a translations object to the document.
+	 */
+	updateI18n() {
+		const translations = getDocumentTranslations();
+		if (!translations) {
+			return this;
+		}
+
+		let labels = this.getOption("labels");
+		if (!(isObject(labels) || isIterable(labels))) {
+			return this;
+		}
+
+		for (const key in labels) {
+			const def = labels[key];
+
+			if (isString(def)) {
+				const text = translations.getText(key, def);
+				if (text !== def) {
+					this.setOption(`labels.${key}`, text);
+				}
+				continue;
+			} else if (isObject(def)) {
+				for (const k in def) {
+					const d = def[k];
+
+					const text = translations.getPluralRuleText(key, k, d);
+					if (!isString(text)) {
+						throw new Error("Invalid labels definition");
+					}
+					if (text !== d) {
+						this.setOption(`labels.${key}.${k}`, text);
+					}
+				}
+				continue;
+			}
+
+			throw new Error("Invalid labels definition");
+		}
+		return this;
+	}
+
+	/**
+	 * The `getTag()` method returns the tag name associated with the custom element. This method should be overwritten
+	 * by the derived class.
+	 *
+	 * Note that there is no check on the name of the tag in this class. It is the responsibility of
+	 * the developer to assign an appropriate tag name. If the name is not valid, the
+	 * `registerCustomElement()` method will issue an error.
+	 *
+	 * @see https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
+	 * @throws {Error} This method must be overridden by the derived class.
+	 * @return {string} The tag name associated with the custom element.
+	 * @since 1.7.0
+	 */
+	static getTag() {
+		throw new Error(
+			"The method `getTag()` must be overridden by the derived class.",
+		);
+	}
+
+	/**
+	 * The `getCSSStyleSheet()` method returns a `CSSStyleSheet` object that defines the styles for the custom element.
+	 * If the environment does not support the `CSSStyleSheet` constructor, then an object can be built using the provided detour.
+	 *
+	 * If `undefined` is returned, then the shadow root does not receive a stylesheet.
+	 *
+	 * Example usage:
+	 *
+	 * ```js
+	 * static getCSSStyleSheet() {
+	 *     const sheet = new CSSStyleSheet();
+	 *     sheet.replaceSync("p { color: red; }");
+	 *     return sheet;
+	 * }
+	 * ```
+	 *
+	 * If the environment does not support the `CSSStyleSheet` constructor,
+	 * you can use the following workaround to create the stylesheet:
+	 *
+	 * ```js
+	 * const doc = document.implementation.createHTMLDocument('title');
+	 * let style = doc.createElement("style");
+	 * style.innerHTML = "p { color: red; }";
+	 * style.appendChild(document.createTextNode(""));
+	 * doc.head.appendChild(style);
+	 * return doc.styleSheets[0];
+	 * ```
+	 *
+	 * @return {CSSStyleSheet|CSSStyleSheet[]|string|undefined} A `CSSStyleSheet` object or an array of such objects that define the styles for the custom element, or `undefined` if no stylesheet should be applied.
+	 */
+	static getCSSStyleSheet() {
+		return undefined;
+	}
+
+	/**
+	 * attach a new observer
+	 *
+	 * @param {Observer} observer
+	 * @returns {CustomElement}
+	 */
+	attachObserver(observer) {
+		this[internalSymbol].attachObserver(observer);
+		return this;
+	}
+
+	/**
+	 * detach a observer
+	 *
+	 * @param {Observer} observer
+	 * @returns {CustomElement}
+	 */
+	detachObserver(observer) {
+		this[internalSymbol].detachObserver(observer);
+		return this;
+	}
+
+	/**
+	 * @param {Observer} observer
+	 * @returns {ProxyObserver}
+	 */
+	containsObserver(observer) {
+		return this[internalSymbol].containsObserver(observer);
+	}
+
+	/**
+	 * nested options can be specified by path `a.b.c`
+	 *
+	 * @param {string} path
+	 * @param {*} defaultValue
+	 * @return {*}
+	 * @since 1.10.0
+	 */
+	getOption(path, defaultValue) {
+		let value;
+
+		try {
+			value = new Pathfinder(
+				this[internalSymbol].getRealSubject()["options"],
+			).getVia(path);
+		} catch (e) {}
+
+		if (value === undefined) return defaultValue;
+		return value;
+	}
+
+	/**
+	 * Set option and inform elements
+	 *
+	 * @param {string} path
+	 * @param {*} value
+	 * @return {CustomElement}
+	 * @since 1.14.0
+	 */
+	setOption(path, value) {
+		new Pathfinder(this[internalSymbol].getSubject()["options"]).setVia(
+			path,
+			value,
+		);
+		return this;
+	}
+
+	/**
+	 * @since 1.15.0
+	 * @param {string|object} options
+	 * @return {CustomElement}
+	 */
+	setOptions(options) {
+		if (isString(options)) {
+			options = parseOptionsJSON.call(this, options);
+		}
+
+		const self = this;
+		extend(
+			self[internalSymbol].getSubject()["options"],
+			self.defaults,
+			options,
+		);
+
+		return self;
+	}
+
+	/**
+	 * Is called once via the constructor
+	 *
+	 * @return {CustomElement}
+	 * @since 1.8.0
+	 */
+	[initMethodSymbol]() {
+		return this;
+	}
+
+	/**
+	 * This method is called once when the object is included in the DOM for the first time. It performs the following actions:
+	 * 1. Extracts the options from the attributes and the script tag of the element and sets them.
+	 * 2. Initializes the shadow root and its CSS stylesheet (if specified).
+	 * 3. Initializes the HTML content of the element.
+	 * 4. Initializes the custom elements inside the shadow root and the slotted elements.
+	 * 5. Attaches a mutation observer to observe changes to the attributes of the element.
+	 *
+	 * @return {CustomElement} - The updated custom element.
+	 * @since 1.8.0
+	 */
+	[assembleMethodSymbol]() {
+		const self = this;
+		let elements;
+		let nodeList;
+
+		// Extract options from attributes and set them
+		const AttributeOptions = getOptionsFromAttributes.call(self);
+		if (
+			isObject(AttributeOptions) &&
+			Object.keys(AttributeOptions).length > 0
+		) {
+			self.setOptions(AttributeOptions);
+		}
+
+		// Extract options from script tag and set them
+		const ScriptOptions = getOptionsFromScriptTag.call(self);
+		if (isObject(ScriptOptions) && Object.keys(ScriptOptions).length > 0) {
+			self.setOptions(ScriptOptions);
+		}
+
+		// Initialize the shadow root and its CSS stylesheet
+		if (self.getOption("shadowMode", false) !== false) {
+			try {
+				initShadowRoot.call(self);
+				elements = self.shadowRoot.childNodes;
+			} catch (e) {
+				addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
+			}
+
+			try {
+				initCSSStylesheet.call(this);
+			} catch (e) {
+				addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
+			}
+		}
+
+		// If the elements are not found inside the shadow root, initialize the HTML content of the element
+		if (!(elements instanceof NodeList)) {
+			initHtmlContent.call(this);
+			elements = this.childNodes;
+		}
+
+		// Initialize the custom elements inside the shadow root and the slotted elements
+		initFromCallbackHost.call(this);
+		try {
+			nodeList = new Set([...elements, ...getSlottedElements.call(self)]);
+		} catch (e) {
+			nodeList = elements;
+		}
+		addObjectWithUpdaterToElement.call(
+			self,
+			nodeList,
+			customElementUpdaterLinkSymbol,
+			clone(self[internalSymbol].getRealSubject()["options"]),
+		);
+
+		// Attach a mutation observer to observe changes to the attributes of the element
+		attachAttributeChangeMutationObserver.call(this);
+
+		return self;
+	}
+
+	/**
+	 * This method is called every time the element is inserted into the DOM. It checks if the custom element
+	 * has already been initialized and if not, calls the assembleMethod to initialize it.
+	 *
+	 * @return {void}
+	 * @since 1.7.0
+	 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/connectedCallback
+	 */
+	connectedCallback() {
+		const self = this;
+
+		// Check if the object has already been initialized
+		if (!hasObjectLink(self, customElementUpdaterLinkSymbol)) {
+			// If not, call the assembleMethod to initialize the object
+			self[assembleMethodSymbol]();
+		}
+	}
+
+	/**
+	 * Called every time the element is removed from the DOM. Useful for running clean up code.
+	 *
+	 * @return {void}
+	 * @since 1.7.0
+	 */
+	disconnectedCallback() {}
+
+	/**
+	 * The custom element has been moved into a new document (e.g. someone called document.adoptNode(el)).
+	 *
+	 * @return {void}
+	 * @since 1.7.0
+	 */
+	adoptedCallback() {}
+
+	/**
+	 * Called when an observed attribute has been added, removed, updated, or replaced. Also called for initial
+	 * values when an element is created by the parser, or upgraded. Note: only attributes listed in the observedAttributes
+	 * property will receive this callback.
+	 *
+	 * @param {string} attrName
+	 * @param {string} oldVal
+	 * @param {string} newVal
+	 * @return {void}
+	 * @since 1.15.0
+	 */
+	attributeChangedCallback(attrName, oldVal, newVal) {
+		const self = this;
+
+		if (attrName.startsWith("data-monster-option-")) {
+			setOptionFromAttribute(
+				self,
+				attrName,
+				this[internalSymbol].getSubject()["options"],
+			);
+		}
+
+		const callback = self[attributeObserverSymbol]?.[attrName];
+		if (isFunction(callback)) {
+			try {
+				callback.call(self, newVal, oldVal);
+			} catch (e) {
+				addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
+			}
+		}
+	}
+
+	/**
+	 *
+	 * @param {Node} node
+	 * @return {boolean}
+	 * @throws {TypeError} value is not an instance of
+	 * @since 1.19.0
+	 */
+	hasNode(node) {
+		const self = this;
+
+		if (containChildNode.call(self, validateInstance(node, Node))) {
+			return true;
+		}
+
+		if (!(self.shadowRoot instanceof ShadowRoot)) {
+			return false;
+		}
+
+		return containChildNode.call(self.shadowRoot, node);
+	}
+
+	/**
+	 * Calls a callback function if it exists.
+	 *
+	 * @param {string} name
+	 * @param {*} args
+	 * @returns {*}
+	 */
+	callCallback(name, args) {
+		const self = this;
+		return callControlCallback.call(self, name, ...args);
+	}
 }
 
 /**
@@ -661,48 +703,52 @@ class CustomElement extends HTMLElement {
  * @return {any}
  */
 function callControlCallback(callBackFunctionName, ...args) {
-    const self = this;
-
-    if (!isString(callBackFunctionName) || callBackFunctionName === "") {
-        return;
-    }
-
-    if (callBackFunctionName in self) {
-        return self[callBackFunctionName](self, ...args);
-    }
-
-    if (!self.hasAttribute(ATTRIBUTE_SCRIPT_HOST)) {
-        return;
-    }
-
-    if (self[scriptHostElementSymbol].length === 0) {
-        const targetId = self.getAttribute(ATTRIBUTE_SCRIPT_HOST);
-        if (!targetId) {
-            return;
-        }
-
-        const list = targetId.split(",");
-        for (const id of list) {
-            const host = findElementWithIdUpwards(self, targetId);
-            if (!(host instanceof HTMLElement)) {
-                continue;
-            }
-
-            self[scriptHostElementSymbol].push(host);
-        }
-    }
-
-    for (const host of self[scriptHostElementSymbol]) {
-        if (callBackFunctionName in host) {
-            try {
-                return host[callBackFunctionName](self, ...args);
-            } catch (e) {
-                addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
-            }
-        }
-    }
-
-    addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, `callback ${callBackFunctionName} not found`);
+	const self = this;
+
+	if (!isString(callBackFunctionName) || callBackFunctionName === "") {
+		return;
+	}
+
+	if (callBackFunctionName in self) {
+		return self[callBackFunctionName](self, ...args);
+	}
+
+	if (!self.hasAttribute(ATTRIBUTE_SCRIPT_HOST)) {
+		return;
+	}
+
+	if (self[scriptHostElementSymbol].length === 0) {
+		const targetId = self.getAttribute(ATTRIBUTE_SCRIPT_HOST);
+		if (!targetId) {
+			return;
+		}
+
+		const list = targetId.split(",");
+		for (const id of list) {
+			const host = findElementWithIdUpwards(self, targetId);
+			if (!(host instanceof HTMLElement)) {
+				continue;
+			}
+
+			self[scriptHostElementSymbol].push(host);
+		}
+	}
+
+	for (const host of self[scriptHostElementSymbol]) {
+		if (callBackFunctionName in host) {
+			try {
+				return host[callBackFunctionName](self, ...args);
+			} catch (e) {
+				addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
+			}
+		}
+	}
+
+	addAttributeToken(
+		self,
+		ATTRIBUTE_ERRORMESSAGE,
+		`callback ${callBackFunctionName} not found`,
+	);
 }
 
 /**
@@ -719,18 +765,18 @@ function callControlCallback(callBackFunctionName, ...args) {
  * @since 1.8.0
  */
 function initFromCallbackHost() {
-    const self = this;
+	const self = this;
 
-    // Set the default callback function name
-    let callBackFunctionName = initControlCallbackName;
+	// Set the default callback function name
+	let callBackFunctionName = initControlCallbackName;
 
-    // If the `data-monster-option-callback` attribute is set, use its value as the callback function name
-    if (self.hasAttribute(ATTRIBUTE_INIT_CALLBACK)) {
-        callBackFunctionName = self.getAttribute(ATTRIBUTE_INIT_CALLBACK);
-    }
+	// If the `data-monster-option-callback` attribute is set, use its value as the callback function name
+	if (self.hasAttribute(ATTRIBUTE_INIT_CALLBACK)) {
+		callBackFunctionName = self.getAttribute(ATTRIBUTE_INIT_CALLBACK);
+	}
 
-    // Call the callback function with the element as a parameter if it exists
-    callControlCallback.call(self, callBackFunctionName);
+	// Call the callback function with the element as a parameter if it exists
+	callControlCallback.call(self, callBackFunctionName);
 }
 
 /**
@@ -740,32 +786,35 @@ function initFromCallbackHost() {
  * @this CustomElement
  */
 function attachAttributeChangeMutationObserver() {
-    const self = this;
-
-    if (typeof self[attributeMutationObserverSymbol] !== "undefined") {
-        return;
-    }
-
-    self[attributeMutationObserverSymbol] = new MutationObserver(function (mutations, observer) {
-        for (const mutation of mutations) {
-            if (mutation.type === "attributes") {
-                self.attributeChangedCallback(
-                    mutation.attributeName,
-                    mutation.oldValue,
-                    mutation.target.getAttribute(mutation.attributeName),
-                );
-            }
-        }
-    });
-
-    try {
-        self[attributeMutationObserverSymbol].observe(self, {
-            attributes: true,
-            attributeOldValue: true,
-        });
-    } catch (e) {
-        addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
-    }
+	const self = this;
+
+	if (typeof self[attributeMutationObserverSymbol] !== "undefined") {
+		return;
+	}
+
+	self[attributeMutationObserverSymbol] = new MutationObserver(function (
+		mutations,
+		observer,
+	) {
+		for (const mutation of mutations) {
+			if (mutation.type === "attributes") {
+				self.attributeChangedCallback(
+					mutation.attributeName,
+					mutation.oldValue,
+					mutation.target.getAttribute(mutation.attributeName),
+				);
+			}
+		}
+	});
+
+	try {
+		self[attributeMutationObserverSymbol].observe(self, {
+			attributes: true,
+			attributeOldValue: true,
+		});
+	} catch (e) {
+		addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
+	}
 }
 
 /**
@@ -775,21 +824,21 @@ function attachAttributeChangeMutationObserver() {
  * @return {boolean}
  */
 function containChildNode(node) {
-    const self = this;
+	const self = this;
 
-    if (self.contains(node)) {
-        return true;
-    }
+	if (self.contains(node)) {
+		return true;
+	}
 
-    for (const [, e] of Object.entries(self.childNodes)) {
-        if (e.contains(node)) {
-            return true;
-        }
+	for (const [, e] of Object.entries(self.childNodes)) {
+		if (e.contains(node)) {
+			return true;
+		}
 
-        containChildNode.call(e, node);
-    }
+		containChildNode.call(e, node);
+	}
 
-    return false;
+	return false;
 }
 
 /**
@@ -799,86 +848,89 @@ function containChildNode(node) {
  * @this CustomElement
  */
 function initOptionObserver() {
-    const self = this;
-
-    let lastDisabledValue = undefined;
-    self.attachObserver(
-        new Observer(function () {
-            const flag = self.getOption("disabled");
-
-            if (flag === lastDisabledValue) {
-                return;
-            }
-
-            lastDisabledValue = flag;
-
-            if (!(self.shadowRoot instanceof ShadowRoot)) {
-                return;
-            }
-
-            const query =
-                "button, command, fieldset, keygen, optgroup, option, select, textarea, input, [data-monster-objectlink]";
-            const elements = self.shadowRoot.querySelectorAll(query);
-
-            let nodeList;
-            try {
-                nodeList = new Set([...elements, ...getSlottedElements.call(self, query)]);
-            } catch (e) {
-                nodeList = elements;
-            }
-
-            for (const element of [...nodeList]) {
-                if (flag === true) {
-                    element.setAttribute(ATTRIBUTE_DISABLED, "");
-                } else {
-                    element.removeAttribute(ATTRIBUTE_DISABLED);
-                }
-            }
-        }),
-    );
-
-    self.attachObserver(
-        new Observer(function () {
-            // not initialised
-            if (!hasObjectLink(self, customElementUpdaterLinkSymbol)) {
-                return;
-            }
-            // inform every element
-            const updaters = getLinkedObjects(self, customElementUpdaterLinkSymbol);
-
-            for (const list of updaters) {
-                for (const updater of list) {
-                    let d = clone(self[internalSymbol].getRealSubject()["options"]);
-                    Object.assign(updater.getSubject(), d);
-                }
-            }
-        }),
-    );
-
-    // disabled
-    self[attributeObserverSymbol][ATTRIBUTE_DISABLED] = () => {
-        if (self.hasAttribute(ATTRIBUTE_DISABLED)) {
-            self.setOption(ATTRIBUTE_DISABLED, true);
-        } else {
-            self.setOption(ATTRIBUTE_DISABLED, undefined);
-        }
-    };
-
-    // data-monster-options
-    self[attributeObserverSymbol][ATTRIBUTE_OPTIONS] = () => {
-        const options = getOptionsFromAttributes.call(self);
-        if (isObject(options) && Object.keys(options).length > 0) {
-            self.setOptions(options);
-        }
-    };
-
-    // data-monster-options-selector
-    self[attributeObserverSymbol][ATTRIBUTE_OPTIONS_SELECTOR] = () => {
-        const options = getOptionsFromScriptTag.call(self);
-        if (isObject(options) && Object.keys(options).length > 0) {
-            self.setOptions(options);
-        }
-    };
+	const self = this;
+
+	let lastDisabledValue = undefined;
+	self.attachObserver(
+		new Observer(function () {
+			const flag = self.getOption("disabled");
+
+			if (flag === lastDisabledValue) {
+				return;
+			}
+
+			lastDisabledValue = flag;
+
+			if (!(self.shadowRoot instanceof ShadowRoot)) {
+				return;
+			}
+
+			const query =
+				"button, command, fieldset, keygen, optgroup, option, select, textarea, input, [data-monster-objectlink]";
+			const elements = self.shadowRoot.querySelectorAll(query);
+
+			let nodeList;
+			try {
+				nodeList = new Set([
+					...elements,
+					...getSlottedElements.call(self, query),
+				]);
+			} catch (e) {
+				nodeList = elements;
+			}
+
+			for (const element of [...nodeList]) {
+				if (flag === true) {
+					element.setAttribute(ATTRIBUTE_DISABLED, "");
+				} else {
+					element.removeAttribute(ATTRIBUTE_DISABLED);
+				}
+			}
+		}),
+	);
+
+	self.attachObserver(
+		new Observer(function () {
+			// not initialised
+			if (!hasObjectLink(self, customElementUpdaterLinkSymbol)) {
+				return;
+			}
+			// inform every element
+			const updaters = getLinkedObjects(self, customElementUpdaterLinkSymbol);
+
+			for (const list of updaters) {
+				for (const updater of list) {
+					let d = clone(self[internalSymbol].getRealSubject()["options"]);
+					Object.assign(updater.getSubject(), d);
+				}
+			}
+		}),
+	);
+
+	// disabled
+	self[attributeObserverSymbol][ATTRIBUTE_DISABLED] = () => {
+		if (self.hasAttribute(ATTRIBUTE_DISABLED)) {
+			self.setOption(ATTRIBUTE_DISABLED, true);
+		} else {
+			self.setOption(ATTRIBUTE_DISABLED, undefined);
+		}
+	};
+
+	// data-monster-options
+	self[attributeObserverSymbol][ATTRIBUTE_OPTIONS] = () => {
+		const options = getOptionsFromAttributes.call(self);
+		if (isObject(options) && Object.keys(options).length > 0) {
+			self.setOptions(options);
+		}
+	};
+
+	// data-monster-options-selector
+	self[attributeObserverSymbol][ATTRIBUTE_OPTIONS_SELECTOR] = () => {
+		const options = getOptionsFromScriptTag.call(self);
+		if (isObject(options) && Object.keys(options).length > 0) {
+			self.setOptions(options);
+		}
+	};
 }
 
 /**
@@ -887,37 +939,39 @@ function initOptionObserver() {
  * @throws {TypeError} value is not a object
  */
 function getOptionsFromScriptTag() {
-    const self = this;
-
-    if (!self.hasAttribute(ATTRIBUTE_OPTIONS_SELECTOR)) {
-        return {};
-    }
-
-    const node = document.querySelector(self.getAttribute(ATTRIBUTE_OPTIONS_SELECTOR));
-    if (!(node instanceof HTMLScriptElement)) {
-        addAttributeToken(
-            self,
-            ATTRIBUTE_ERRORMESSAGE,
-            `the selector ${ATTRIBUTE_OPTIONS_SELECTOR} for options was specified (${self.getAttribute(
-                ATTRIBUTE_OPTIONS_SELECTOR,
-            )}) but not found.`,
-        );
-        return {};
-    }
-
-    let obj = {};
-
-    try {
-        obj = parseOptionsJSON.call(this, node.textContent.trim());
-    } catch (e) {
-        addAttributeToken(
-            self,
-            ATTRIBUTE_ERRORMESSAGE,
-            `when analyzing the configuration from the script tag there was an error. ${e}`,
-        );
-    }
-
-    return obj;
+	const self = this;
+
+	if (!self.hasAttribute(ATTRIBUTE_OPTIONS_SELECTOR)) {
+		return {};
+	}
+
+	const node = document.querySelector(
+		self.getAttribute(ATTRIBUTE_OPTIONS_SELECTOR),
+	);
+	if (!(node instanceof HTMLScriptElement)) {
+		addAttributeToken(
+			self,
+			ATTRIBUTE_ERRORMESSAGE,
+			`the selector ${ATTRIBUTE_OPTIONS_SELECTOR} for options was specified (${self.getAttribute(
+				ATTRIBUTE_OPTIONS_SELECTOR,
+			)}) but not found.`,
+		);
+		return {};
+	}
+
+	let obj = {};
+
+	try {
+		obj = parseOptionsJSON.call(this, node.textContent.trim());
+	} catch (e) {
+		addAttributeToken(
+			self,
+			ATTRIBUTE_ERRORMESSAGE,
+			`when analyzing the configuration from the script tag there was an error. ${e}`,
+		);
+	}
+
+	return obj;
 }
 
 /**
@@ -925,23 +979,23 @@ function getOptionsFromScriptTag() {
  * @return {object}
  */
 function getOptionsFromAttributes() {
-    const self = this;
-
-    if (this.hasAttribute(ATTRIBUTE_OPTIONS)) {
-        try {
-            return parseOptionsJSON.call(self, this.getAttribute(ATTRIBUTE_OPTIONS));
-        } catch (e) {
-            addAttributeToken(
-                self,
-                ATTRIBUTE_ERRORMESSAGE,
-                `the options attribute ${ATTRIBUTE_OPTIONS} does not contain a valid json definition (actual: ${this.getAttribute(
-                    ATTRIBUTE_OPTIONS,
-                )}).${e}`,
-            );
-        }
-    }
-
-    return {};
+	const self = this;
+
+	if (this.hasAttribute(ATTRIBUTE_OPTIONS)) {
+		try {
+			return parseOptionsJSON.call(self, this.getAttribute(ATTRIBUTE_OPTIONS));
+		} catch (e) {
+			addAttributeToken(
+				self,
+				ATTRIBUTE_ERRORMESSAGE,
+				`the options attribute ${ATTRIBUTE_OPTIONS} does not contain a valid json definition (actual: ${this.getAttribute(
+					ATTRIBUTE_OPTIONS,
+				)}).${e}`,
+			);
+		}
+	}
+
+	return {};
 }
 
 /**
@@ -950,25 +1004,25 @@ function getOptionsFromAttributes() {
  * @return {Object}
  */
 function parseOptionsJSON(data) {
-    let obj = {};
+	let obj = {};
 
-    if (!isString(data)) {
-        return obj;
-    }
+	if (!isString(data)) {
+		return obj;
+	}
 
-    // the configuration can be specified as a data url.
-    try {
-        let dataUrl = parseDataURL(data);
-        data = dataUrl.content;
-    } catch (e) {}
+	// the configuration can be specified as a data url.
+	try {
+		let dataUrl = parseDataURL(data);
+		data = dataUrl.content;
+	} catch (e) {}
 
-    try {
-        obj = JSON.parse(data);
-    } catch (e) {
-        throw e;
-    }
+	try {
+		obj = JSON.parse(data);
+	} catch (e) {
+		throw e;
+	}
 
-    return validateObject(obj);
+	return validateObject(obj);
 }
 
 /**
@@ -976,21 +1030,21 @@ function parseOptionsJSON(data) {
  * @return {initHtmlContent}
  */
 function initHtmlContent() {
-    try {
-        let template = findDocumentTemplate(this.constructor.getTag());
-        this.appendChild(template.createDocumentFragment());
-    } catch (e) {
-        let html = this.getOption("templates.main", "");
-        if (isString(html) && html.length > 0) {
-            const mapping = this.getOption("templateMapping", {});
-            if (isObject(mapping)) {
-                html = new Formatter(mapping).format(html);
-            }
-            this.innerHTML = html;
-        }
-    }
-
-    return this;
+	try {
+		let template = findDocumentTemplate(this.constructor.getTag());
+		this.appendChild(template.createDocumentFragment());
+	} catch (e) {
+		let html = this.getOption("templates.main", "");
+		if (isString(html) && html.length > 0) {
+			const mapping = this.getOption("templateMapping", {});
+			if (isObject(mapping)) {
+				html = new Formatter(mapping).format(html);
+			}
+			this.innerHTML = html;
+		}
+	}
+
+	return this;
 }
 
 /**
@@ -1003,51 +1057,51 @@ function initHtmlContent() {
  * @throws {TypeError} value is not an instance of
  */
 function initCSSStylesheet() {
-    const self = this;
-
-    if (!(this.shadowRoot instanceof ShadowRoot)) {
-        return self;
-    }
-
-    const styleSheet = this.constructor.getCSSStyleSheet();
-
-    if (styleSheet instanceof CSSStyleSheet) {
-        if (styleSheet.cssRules.length > 0) {
-            this.shadowRoot.adoptedStyleSheets = [styleSheet];
-        }
-    } else if (isArray(styleSheet)) {
-        const assign = [];
-        for (let s of styleSheet) {
-            if (isString(s)) {
-                let trimedStyleSheet = s.trim();
-                if (trimedStyleSheet !== "") {
-                    const style = document.createElement("style");
-                    style.innerHTML = trimedStyleSheet;
-                    self.shadowRoot.prepend(style);
-                }
-                continue;
-            }
-
-            validateInstance(s, CSSStyleSheet);
-
-            if (s.cssRules.length > 0) {
-                assign.push(s);
-            }
-        }
-
-        if (assign.length > 0) {
-            this.shadowRoot.adoptedStyleSheets = assign;
-        }
-    } else if (isString(styleSheet)) {
-        let trimedStyleSheet = styleSheet.trim();
-        if (trimedStyleSheet !== "") {
-            const style = document.createElement("style");
-            style.innerHTML = styleSheet;
-            self.shadowRoot.prepend(style);
-        }
-    }
-
-    return self;
+	const self = this;
+
+	if (!(this.shadowRoot instanceof ShadowRoot)) {
+		return self;
+	}
+
+	const styleSheet = this.constructor.getCSSStyleSheet();
+
+	if (styleSheet instanceof CSSStyleSheet) {
+		if (styleSheet.cssRules.length > 0) {
+			this.shadowRoot.adoptedStyleSheets = [styleSheet];
+		}
+	} else if (isArray(styleSheet)) {
+		const assign = [];
+		for (let s of styleSheet) {
+			if (isString(s)) {
+				let trimedStyleSheet = s.trim();
+				if (trimedStyleSheet !== "") {
+					const style = document.createElement("style");
+					style.innerHTML = trimedStyleSheet;
+					self.shadowRoot.prepend(style);
+				}
+				continue;
+			}
+
+			validateInstance(s, CSSStyleSheet);
+
+			if (s.cssRules.length > 0) {
+				assign.push(s);
+			}
+		}
+
+		if (assign.length > 0) {
+			this.shadowRoot.adoptedStyleSheets = assign;
+		}
+	} else if (isString(styleSheet)) {
+		let trimedStyleSheet = styleSheet.trim();
+		if (trimedStyleSheet !== "") {
+			const style = document.createElement("style");
+			style.innerHTML = styleSheet;
+			self.shadowRoot.prepend(style);
+		}
+	}
+
+	return self;
 }
 
 /**
@@ -1060,35 +1114,35 @@ function initCSSStylesheet() {
  * @since 1.8.0
  */
 function initShadowRoot() {
-    let template;
-    let html;
-
-    try {
-        template = findDocumentTemplate(this.constructor.getTag());
-    } catch (e) {
-        html = this.getOption("templates.main", "");
-        if (!isString(html) || html === undefined || html === "") {
-            throw new Error("html is not set.");
-        }
-    }
-
-    this.attachShadow({
-        mode: this.getOption("shadowMode", "open"),
-        delegatesFocus: this.getOption("delegatesFocus", true),
-    });
-
-    if (template instanceof Template) {
-        this.shadowRoot.appendChild(template.createDocumentFragment());
-        return this;
-    }
-
-    const mapping = this.getOption("templateMapping", {});
-    if (isObject(mapping)) {
-        html = new Formatter(mapping).format(html);
-    }
-
-    this.shadowRoot.innerHTML = html;
-    return this;
+	let template;
+	let html;
+
+	try {
+		template = findDocumentTemplate(this.constructor.getTag());
+	} catch (e) {
+		html = this.getOption("templates.main", "");
+		if (!isString(html) || html === undefined || html === "") {
+			throw new Error("html is not set.");
+		}
+	}
+
+	this.attachShadow({
+		mode: this.getOption("shadowMode", "open"),
+		delegatesFocus: this.getOption("delegatesFocus", true),
+	});
+
+	if (template instanceof Template) {
+		this.shadowRoot.appendChild(template.createDocumentFragment());
+		return this;
+	}
+
+	const mapping = this.getOption("templateMapping", {});
+	if (isObject(mapping)) {
+		html = new Formatter(mapping).format(html);
+	}
+
+	this.shadowRoot.innerHTML = html;
+	return this;
 }
 
 /**
@@ -1103,15 +1157,15 @@ function initShadowRoot() {
  * @throws {DOMException} Failed to execute 'define' on 'CustomElementRegistry': is not a valid custom element name
  */
 function registerCustomElement(element) {
-    validateFunction(element);
-    const customElements = getGlobalObject("customElements");
-    if (customElements === undefined) {
-        throw new Error("customElements is not supported.");
-    }
+	validateFunction(element);
+	const customElements = getGlobalObject("customElements");
+	if (customElements === undefined) {
+		throw new Error("customElements is not supported.");
+	}
 
-    if (customElements.get(element.getTag()) !== undefined) {
-        return;
-    }
+	if (customElements.get(element.getTag()) !== undefined) {
+		return;
+	}
 
-    customElements.define(element.getTag(), element);
+	customElements.define(element.getTag(), element);
 }
diff --git a/source/dom/dimension.mjs b/source/dom/dimension.mjs
index 07ef3c5da9250b73a55691b622cec44f4fa866d6..cd3eac78f30ff6799d28aa74dfaea92b9e28e769 100644
--- a/source/dom/dimension.mjs
+++ b/source/dom/dimension.mjs
@@ -19,13 +19,13 @@ export { convertToPixels, getDeviceDPI };
  * @type {number|function}
  */
 let CURRENT_DEVICE_DPI = function () {
-    let i = 0;
-    for (i = 56; i < 2000; i++) {
-        if (getWindow().matchMedia(`(max-resolution: ${i}dpi)`).matches === true) {
-            return i;
-        }
-    }
-    return i;
+	let i = 0;
+	for (i = 56; i < 2000; i++) {
+		if (getWindow().matchMedia(`(max-resolution: ${i}dpi)`).matches === true) {
+			return i;
+		}
+	}
+	return i;
 };
 
 /**
@@ -36,12 +36,12 @@ let CURRENT_DEVICE_DPI = function () {
  * @returns {number}
  */
 function getDeviceDPI() {
-    // only call the function once
-    if (typeof CURRENT_DEVICE_DPI === "function") {
-        CURRENT_DEVICE_DPI = CURRENT_DEVICE_DPI();
-    }
+	// only call the function once
+	if (typeof CURRENT_DEVICE_DPI === "function") {
+		CURRENT_DEVICE_DPI = CURRENT_DEVICE_DPI();
+	}
 
-    return getWindow().devicePixelRatio * CURRENT_DEVICE_DPI;
+	return getWindow().devicePixelRatio * CURRENT_DEVICE_DPI;
 }
 
 /**
@@ -74,42 +74,52 @@ function getDeviceDPI() {
  * @throws {Error} Invalid value format
  */
 
-function convertToPixels(value, parentElement = document.documentElement, fontSizeElement = document.documentElement) {
-    validateString(value);
+function convertToPixels(
+	value,
+	parentElement = document.documentElement,
+	fontSizeElement = document.documentElement,
+) {
+	validateString(value);
 
-    const regex = /^(-?[\d.]+)(.*)$/;
-    const matchResult = value.match(regex);
+	const regex = /^(-?[\d.]+)(.*)$/;
+	const matchResult = value.match(regex);
 
-    if (!matchResult) {
-        throw new Error(`Invalid value format: ${value}`);
-    }
+	if (!matchResult) {
+		throw new Error(`Invalid value format: ${value}`);
+	}
 
-    const [, num, unit] = matchResult;
-    const number = parseFloat(num);
-    const dpi = getDeviceDPI();
+	const [, num, unit] = matchResult;
+	const number = parseFloat(num);
+	const dpi = getDeviceDPI();
 
-    if (unit === "px") {
-        return number;
-    } else if (unit === "em") {
-        const fontSize = parseFloat(window.getComputedStyle(fontSizeElement).fontSize);
-        return number * fontSize;
-    } else if (unit === "rem") {
-        const rootFontSize = parseFloat(window.getComputedStyle(parentElement).fontSize);
-        return number * rootFontSize;
-    } else if (unit === "%") {
-        const parentWidth = parseFloat(window.getComputedStyle(parentElement).width);
-        return (number * parentWidth) / 100;
-    } else if (unit === "in") {
-        return number * dpi;
-    } else if (unit === "cm") {
-        return (number * dpi) / 2.54;
-    } else if (unit === "mm") {
-        return (number * dpi) / 25.4;
-    } else if (unit === "pt") {
-        return (number * dpi) / 72;
-    } else if (unit === "pc") {
-        return (number * dpi) / 6;
-    } else {
-        throw new Error(`Unsupported unit: ${unit}`);
-    }
+	if (unit === "px") {
+		return number;
+	} else if (unit === "em") {
+		const fontSize = parseFloat(
+			window.getComputedStyle(fontSizeElement).fontSize,
+		);
+		return number * fontSize;
+	} else if (unit === "rem") {
+		const rootFontSize = parseFloat(
+			window.getComputedStyle(parentElement).fontSize,
+		);
+		return number * rootFontSize;
+	} else if (unit === "%") {
+		const parentWidth = parseFloat(
+			window.getComputedStyle(parentElement).width,
+		);
+		return (number * parentWidth) / 100;
+	} else if (unit === "in") {
+		return number * dpi;
+	} else if (unit === "cm") {
+		return (number * dpi) / 2.54;
+	} else if (unit === "mm") {
+		return (number * dpi) / 25.4;
+	} else if (unit === "pt") {
+		return (number * dpi) / 72;
+	} else if (unit === "pc") {
+		return (number * dpi) / 6;
+	} else {
+		throw new Error(`Unsupported unit: ${unit}`);
+	}
 }
diff --git a/source/dom/events.mjs b/source/dom/events.mjs
index cdc3bd077fa265813a1a1036ea15e78ceb28962b..c173b00c300bf8f883cdc3545cae0b3df1088c86 100644
--- a/source/dom/events.mjs
+++ b/source/dom/events.mjs
@@ -25,29 +25,31 @@ export { fireEvent, fireCustomEvent, findTargetElementFromEvent };
  * @summary Construct and send and event
  */
 function fireEvent(element, type) {
-    const document = getDocument();
-
-    if (element instanceof HTMLElement) {
-        if (type === "click") {
-            element.click();
-            return;
-        }
-
-        // https://developer.mozilla.org/en-US/docs/Web/API/Event/Event
-        let event = new Event(validateString(type), {
-            bubbles: true,
-            cancelable: true,
-            composed: true,
-        });
-
-        element.dispatchEvent(event);
-    } else if (element instanceof HTMLCollection || element instanceof NodeList) {
-        for (let e of element) {
-            fireEvent(e, type);
-        }
-    } else {
-        throw new TypeError("value is not an instance of HTMLElement or HTMLCollection");
-    }
+	const document = getDocument();
+
+	if (element instanceof HTMLElement) {
+		if (type === "click") {
+			element.click();
+			return;
+		}
+
+		// https://developer.mozilla.org/en-US/docs/Web/API/Event/Event
+		let event = new Event(validateString(type), {
+			bubbles: true,
+			cancelable: true,
+			composed: true,
+		});
+
+		element.dispatchEvent(event);
+	} else if (element instanceof HTMLCollection || element instanceof NodeList) {
+		for (let e of element) {
+			fireEvent(e, type);
+		}
+	} else {
+		throw new TypeError(
+			"value is not an instance of HTMLElement or HTMLCollection",
+		);
+	}
 }
 
 /**
@@ -64,28 +66,30 @@ function fireEvent(element, type) {
  * @summary Construct and send and event
  */
 function fireCustomEvent(element, type, detail) {
-    const document = getDocument();
-
-    if (element instanceof HTMLElement) {
-        if (!isObject(detail)) {
-            detail = { detail };
-        }
-
-        let event = new CustomEvent(validateString(type), {
-            bubbles: true,
-            cancelable: true,
-            composed: true,
-            detail,
-        });
-
-        element.dispatchEvent(event);
-    } else if (element instanceof HTMLCollection || element instanceof NodeList) {
-        for (let e of element) {
-            fireCustomEvent(e, type, detail);
-        }
-    } else {
-        throw new TypeError("value is not an instance of HTMLElement or HTMLCollection");
-    }
+	const document = getDocument();
+
+	if (element instanceof HTMLElement) {
+		if (!isObject(detail)) {
+			detail = { detail };
+		}
+
+		let event = new CustomEvent(validateString(type), {
+			bubbles: true,
+			cancelable: true,
+			composed: true,
+			detail,
+		});
+
+		element.dispatchEvent(event);
+	} else if (element instanceof HTMLCollection || element instanceof NodeList) {
+		for (let e of element) {
+			fireCustomEvent(e, type, detail);
+		}
+	} else {
+		throw new TypeError(
+			"value is not an instance of HTMLElement or HTMLCollection",
+		);
+	}
 }
 
 /**
@@ -105,28 +109,29 @@ function fireCustomEvent(element, type, detail) {
  * @summary Help function to find the appropriate control
  */
 function findTargetElementFromEvent(event, attributeName, attributeValue) {
-    validateInstance(event, Event);
-
-    if (typeof event.composedPath !== "function") {
-        throw new Error("unsupported event");
-    }
-
-    const path = event.composedPath();
-
-    // closest cannot be used here, because closest is not correct for slotted elements
-    if (isArray(path)) {
-        for (let i = 0; i < path.length; i++) {
-            const o = path[i];
-
-            if (
-                o instanceof HTMLElement &&
-                o.hasAttribute(attributeName) &&
-                (attributeValue === undefined || o.getAttribute(attributeName) === attributeValue)
-            ) {
-                return o;
-            }
-        }
-    }
-
-    return undefined;
+	validateInstance(event, Event);
+
+	if (typeof event.composedPath !== "function") {
+		throw new Error("unsupported event");
+	}
+
+	const path = event.composedPath();
+
+	// closest cannot be used here, because closest is not correct for slotted elements
+	if (isArray(path)) {
+		for (let i = 0; i < path.length; i++) {
+			const o = path[i];
+
+			if (
+				o instanceof HTMLElement &&
+				o.hasAttribute(attributeName) &&
+				(attributeValue === undefined ||
+					o.getAttribute(attributeName) === attributeValue)
+			) {
+				return o;
+			}
+		}
+	}
+
+	return undefined;
 }
diff --git a/source/dom/focusmanager.mjs b/source/dom/focusmanager.mjs
index ef43920d844b30a2a231a4fdaf8d880ae1090cea..1686dd3da719997f1f2ce7f94ab8f9fddd23ef04 100644
--- a/source/dom/focusmanager.mjs
+++ b/source/dom/focusmanager.mjs
@@ -43,179 +43,179 @@ const stackSymbol = Symbol("stack");
  * @summary Handle the focus
  */
 class FocusManager extends BaseWithOptions {
-    /**
-     *
-     * @param {Object|undefined} options
-     */
-    constructor(options) {
-        super(options);
-        validateInstance(this.getOption(KEY_DOCUMENT), HTMLDocument);
-
-        this[stackSymbol] = new Stack();
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/dom/focusmanager");
-    }
-
-    /**
-     * @property {HTMLDocument} document the document object into which the node is to be appended
-     */
-    get defaults() {
-        return extend({}, super.defaults, {
-            [KEY_DOCUMENT]: getGlobalObject("document"),
-            [KEY_CONTEXT]: undefined,
-        });
-    }
-
-    /**
-     * Remembers the current focus on a stack.
-     * Several focus can be stored.
-     *
-     * @return {Monster.DOM.FocusManager}
-     */
-    storeFocus() {
-        const active = this.getActive();
-        if (active instanceof Node) {
-            this[stackSymbol].push(active);
-        }
-        return this;
-    }
-
-    /**
-     * The last focus on the stack is set again
-     *
-     * @return {Monster.DOM.FocusManager}
-     */
-    restoreFocus() {
-        const last = this[stackSymbol].pop();
-        if (last instanceof Node) {
-            this.focus(last);
-        }
-
-        return this;
-    }
-
-    /**
-     *
-     * @param {Node} element
-     * @param {boolean} preventScroll
-     * @throws {TypeError} value is not an instance of
-     * @return {Monster.DOM.FocusManager}
-     */
-    focus(element, preventScroll) {
-        validateInstance(element, Node);
-
-        element.focus({
-            preventScroll: preventScroll ?? false,
-        });
-
-        return this;
-    }
-
-    /**
-     *
-     * @return {Element}
-     */
-    getActive() {
-        return this.getOption(KEY_DOCUMENT).activeElement;
-    }
-
-    /**
-     * Select all elements that can be focused
-     *
-     * @param {string|undefined} query
-     * @return {array}
-     * @throws {TypeError} value is not an instance of
-     */
-    getFocusable(query) {
-        let contextElement = this.getOption(KEY_CONTEXT);
-        if (contextElement === undefined) {
-            contextElement = this.getOption(KEY_DOCUMENT);
-        }
-
-        validateInstance(contextElement, Node);
-
-        if (query !== undefined) {
-            validateString(query);
-        }
-
-        return [
-            ...contextElement.querySelectorAll(
-                'details, button, input, [tabindex]:not([tabindex="-1"]), select, textarea, a[href], body',
-            ),
-        ].filter((element) => {
-            if (query !== undefined && !element.matches(query)) {
-                return false;
-            }
-
-            if (element.hasAttribute("disabled")) return false;
-            if (element.getAttribute("aria-hidden") === "true") return false;
-
-            const rect = element.getBoundingClientRect();
-            if (rect.width === 0) return false;
-            if (rect.height === 0) return false;
-
-            return true;
-        });
-    }
-
-    /**
-     * @param {string} query
-     * @return {Monster.DOM.FocusManager}
-     */
-    focusNext(query) {
-        const current = this.getActive();
-        const focusable = this.getFocusable(query);
-
-        if (!isArray(focusable) || focusable.length === 0) {
-            return this;
-        }
-
-        if (current instanceof Node) {
-            let index = focusable.indexOf(current);
-
-            if (index > -1) {
-                this.focus(focusable[index + 1] || focusable[0]);
-            } else {
-                this.focus(focusable[0]);
-            }
-        } else {
-            this.focus(focusable[0]);
-        }
-
-        return this;
-    }
-
-    /**
-     * @param {string} query
-     * @return {Monster.DOM.FocusManager}
-     */
-    focusPrev(query) {
-        const current = this.getActive();
-        const focusable = this.getFocusable(query);
-
-        if (!isArray(focusable) || focusable.length === 0) {
-            return this;
-        }
-
-        if (current instanceof Node) {
-            let index = focusable.indexOf(current);
-
-            if (index > -1) {
-                this.focus(focusable[index - 1] || focusable[focusable.length - 1]);
-            } else {
-                this.focus(focusable[focusable.length - 1]);
-            }
-        } else {
-            this.focus(focusable[focusable.length - 1]);
-        }
-
-        return this;
-    }
+	/**
+	 *
+	 * @param {Object|undefined} options
+	 */
+	constructor(options) {
+		super(options);
+		validateInstance(this.getOption(KEY_DOCUMENT), HTMLDocument);
+
+		this[stackSymbol] = new Stack();
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/dom/focusmanager");
+	}
+
+	/**
+	 * @property {HTMLDocument} document the document object into which the node is to be appended
+	 */
+	get defaults() {
+		return extend({}, super.defaults, {
+			[KEY_DOCUMENT]: getGlobalObject("document"),
+			[KEY_CONTEXT]: undefined,
+		});
+	}
+
+	/**
+	 * Remembers the current focus on a stack.
+	 * Several focus can be stored.
+	 *
+	 * @return {Monster.DOM.FocusManager}
+	 */
+	storeFocus() {
+		const active = this.getActive();
+		if (active instanceof Node) {
+			this[stackSymbol].push(active);
+		}
+		return this;
+	}
+
+	/**
+	 * The last focus on the stack is set again
+	 *
+	 * @return {Monster.DOM.FocusManager}
+	 */
+	restoreFocus() {
+		const last = this[stackSymbol].pop();
+		if (last instanceof Node) {
+			this.focus(last);
+		}
+
+		return this;
+	}
+
+	/**
+	 *
+	 * @param {Node} element
+	 * @param {boolean} preventScroll
+	 * @throws {TypeError} value is not an instance of
+	 * @return {Monster.DOM.FocusManager}
+	 */
+	focus(element, preventScroll) {
+		validateInstance(element, Node);
+
+		element.focus({
+			preventScroll: preventScroll ?? false,
+		});
+
+		return this;
+	}
+
+	/**
+	 *
+	 * @return {Element}
+	 */
+	getActive() {
+		return this.getOption(KEY_DOCUMENT).activeElement;
+	}
+
+	/**
+	 * Select all elements that can be focused
+	 *
+	 * @param {string|undefined} query
+	 * @return {array}
+	 * @throws {TypeError} value is not an instance of
+	 */
+	getFocusable(query) {
+		let contextElement = this.getOption(KEY_CONTEXT);
+		if (contextElement === undefined) {
+			contextElement = this.getOption(KEY_DOCUMENT);
+		}
+
+		validateInstance(contextElement, Node);
+
+		if (query !== undefined) {
+			validateString(query);
+		}
+
+		return [
+			...contextElement.querySelectorAll(
+				'details, button, input, [tabindex]:not([tabindex="-1"]), select, textarea, a[href], body',
+			),
+		].filter((element) => {
+			if (query !== undefined && !element.matches(query)) {
+				return false;
+			}
+
+			if (element.hasAttribute("disabled")) return false;
+			if (element.getAttribute("aria-hidden") === "true") return false;
+
+			const rect = element.getBoundingClientRect();
+			if (rect.width === 0) return false;
+			if (rect.height === 0) return false;
+
+			return true;
+		});
+	}
+
+	/**
+	 * @param {string} query
+	 * @return {Monster.DOM.FocusManager}
+	 */
+	focusNext(query) {
+		const current = this.getActive();
+		const focusable = this.getFocusable(query);
+
+		if (!isArray(focusable) || focusable.length === 0) {
+			return this;
+		}
+
+		if (current instanceof Node) {
+			let index = focusable.indexOf(current);
+
+			if (index > -1) {
+				this.focus(focusable[index + 1] || focusable[0]);
+			} else {
+				this.focus(focusable[0]);
+			}
+		} else {
+			this.focus(focusable[0]);
+		}
+
+		return this;
+	}
+
+	/**
+	 * @param {string} query
+	 * @return {Monster.DOM.FocusManager}
+	 */
+	focusPrev(query) {
+		const current = this.getActive();
+		const focusable = this.getFocusable(query);
+
+		if (!isArray(focusable) || focusable.length === 0) {
+			return this;
+		}
+
+		if (current instanceof Node) {
+			let index = focusable.indexOf(current);
+
+			if (index > -1) {
+				this.focus(focusable[index - 1] || focusable[focusable.length - 1]);
+			} else {
+				this.focus(focusable[focusable.length - 1]);
+			}
+		} else {
+			this.focus(focusable[focusable.length - 1]);
+		}
+
+		return this;
+	}
 }
diff --git a/source/dom/locale.mjs b/source/dom/locale.mjs
index ffc4382bf162ed33337c6d171d8c777e295a1726..f2e07c93269389a4da823abeb5edab005f0a1fe8 100644
--- a/source/dom/locale.mjs
+++ b/source/dom/locale.mjs
@@ -37,22 +37,22 @@ const DEFAULT_LANGUAGE = "en";
  * @summary Tries to determine the locale used
  */
 function getLocaleOfDocument() {
-    const document = getDocument();
+	const document = getDocument();
 
-    let html = document.querySelector("html");
-    if (html instanceof HTMLElement && html.hasAttribute("lang")) {
-        let locale = html.getAttribute("lang");
-        if (locale) {
-            return new parseLocale(locale);
-        }
-    }
+	let html = document.querySelector("html");
+	if (html instanceof HTMLElement && html.hasAttribute("lang")) {
+		let locale = html.getAttribute("lang");
+		if (locale) {
+			return new parseLocale(locale);
+		}
+	}
 
-    let navigatorLanguage = getNavigatorLanguage();
-    if (navigatorLanguage) {
-        return parseLocale(navigatorLanguage);
-    }
+	let navigatorLanguage = getNavigatorLanguage();
+	if (navigatorLanguage) {
+		return parseLocale(navigatorLanguage);
+	}
 
-    return parseLocale(DEFAULT_LANGUAGE);
+	return parseLocale(DEFAULT_LANGUAGE);
 }
 
 /**
@@ -62,22 +62,22 @@ function getLocaleOfDocument() {
  * @see https://developer.mozilla.org/en-US/docs/Web/API/Navigator/languages
  */
 const getNavigatorLanguage = () => {
-    const navigator = getGlobalObject("navigator");
-    if (navigator === undefined) {
-        return undefined;
-    }
+	const navigator = getGlobalObject("navigator");
+	if (navigator === undefined) {
+		return undefined;
+	}
 
-    if (navigator.hasOwnProperty("language")) {
-        const language = navigator.language;
-        if (typeof language === "string" && language.length > 0) {
-            return language;
-        }
-    }
+	if (navigator.hasOwnProperty("language")) {
+		const language = navigator.language;
+		if (typeof language === "string" && language.length > 0) {
+			return language;
+		}
+	}
 
-    const languages = navigator?.languages;
-    if (Array.isArray(languages) && languages.length > 0) {
-        return languages[0];
-    }
+	const languages = navigator?.languages;
+	if (Array.isArray(languages) && languages.length > 0) {
+		return languages[0];
+	}
 
-    return undefined;
+	return undefined;
 };
diff --git a/source/dom/ready.mjs b/source/dom/ready.mjs
index ef03e22c62bfeb9574904eb3329f6d241699a64d..1465554f3a8cf7e07075769f56f4d25d621f55e1 100644
--- a/source/dom/ready.mjs
+++ b/source/dom/ready.mjs
@@ -29,13 +29,13 @@ export { domReady, windowReady };
  * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
  */
 const domReady = new Promise((resolve) => {
-    const document = getDocument();
+	const document = getDocument();
 
-    if (document.readyState === "loading") {
-        document.addEventListener("DOMContentLoaded", resolve);
-    } else {
-        resolve();
-    }
+	if (document.readyState === "loading") {
+		document.addEventListener("DOMContentLoaded", resolve);
+	} else {
+		resolve();
+	}
 });
 
 /**
@@ -54,12 +54,12 @@ const domReady = new Promise((resolve) => {
  * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
  */
 const windowReady = new Promise((resolve) => {
-    const document = getDocument();
-    const window = getWindow();
+	const document = getDocument();
+	const window = getWindow();
 
-    if (document.readyState === "complete") {
-        resolve();
-    } else {
-        window.addEventListener("load", resolve);
-    }
+	if (document.readyState === "complete") {
+		resolve();
+	} else {
+		window.addEventListener("load", resolve);
+	}
 });
diff --git a/source/dom/resource.mjs b/source/dom/resource.mjs
index 57500a21f2d91d5d3bf306ddb9d54931b9013aa7..d53793aace977f75539a523b66d6a73c05d81b0c 100644
--- a/source/dom/resource.mjs
+++ b/source/dom/resource.mjs
@@ -13,7 +13,11 @@ import { ID } from "../types/id.mjs";
 import { isString } from "../types/is.mjs";
 import { Observer } from "../types/observer.mjs";
 import { ProxyObserver } from "../types/proxyobserver.mjs";
-import { ATTRIBUTE_CLASS, ATTRIBUTE_ID, ATTRIBUTE_TITLE } from "./constants.mjs";
+import {
+	ATTRIBUTE_CLASS,
+	ATTRIBUTE_ID,
+	ATTRIBUTE_TITLE,
+} from "./constants.mjs";
 import { instanceSymbol } from "../constants.mjs";
 
 export { Resource, KEY_DOCUMENT, KEY_QUERY, referenceSymbol };
@@ -52,143 +56,143 @@ const referenceSymbol = Symbol("reference");
  * @summary A Resource class
  */
 class Resource extends BaseWithOptions {
-    /**
-     *
-     * @param {Object|undefined} options
-     */
-    constructor(options) {
-        super(options);
-
-        let uri = this.getOption(this.constructor.getURLAttribute());
-
-        if (uri === undefined) {
-            throw new Error("missing source");
-        } else if (uri instanceof URL) {
-            uri = uri.toString();
-        } else if (!isString(uri)) {
-            throw new Error("unsupported url type");
-        }
-
-        this[internalSymbol][this.constructor.getURLAttribute()] = uri;
-        this[internalStateSymbol] = new ProxyObserver({
-            loaded: false,
-            error: undefined,
-        });
-
-        this[referenceSymbol] = undefined;
-    }
-
-    /**
-     * @return {boolean}
-     */
-    isConnected() {
-        if (this[referenceSymbol] instanceof HTMLElement) {
-            return this[referenceSymbol].isConnected;
-        }
-
-        return false;
-    }
-
-    /**
-     * This method is overridden by the special classes and creates the DOM object.
-     * This method is also called implicitly, if not yet done explicitly, by calling `connect()`.
-     *
-     * @throws {Error} this method must be implemented by derived classes
-     * @return {Monster.DOM.Resource}
-     */
-    create() {
-        throw new Error("this method must be implemented by derived classes");
-    }
-
-    /**
-     * This method appends the HTMLElement to the specified document.
-     * If the element has not yet been created, `create()` is called implicitly.
-     *
-     * throws {Error} target not found
-     * @return {Monster.DOM.Resource}
-     */
-    connect() {
-        if (!(this[referenceSymbol] instanceof HTMLElement)) {
-            this.create();
-        }
-
-        appendToDocument.call(this);
-        return this;
-    }
-
-    /**
-     * @property {Document} document the document object into which the node is to be appended
-     * @property {string} src/href url to the corresponding resource
-     * @property {string} query defines the location where the resource is to be hooked into the dom.
-     * @property {string} id element attribute id
-     * @property {string} title element attribute title
-     * @property {string} class element attribute class
-     * @property {int} timeout timeout
-     */
-    get defaults() {
-        return extend({}, super.defaults, {
-            [this.constructor.getURLAttribute()]: undefined,
-            [KEY_DOCUMENT]: getGlobalObject("document"),
-            [KEY_QUERY]: "head",
-            [KEY_TIMEOUT]: 10000,
-            [ATTRIBUTE_ID]: new ID("resource").toString(),
-            [ATTRIBUTE_CLASS]: undefined,
-            [ATTRIBUTE_TITLE]: undefined,
-        });
-    }
-
-    /**
-     * With `available()` you can check if a resource is available.
-     * This is the case when the tag is included and the resource is loaded.
-     *
-     * @return {Promise}
-     */
-    available() {
-        const self = this;
-        if (!(self[referenceSymbol] instanceof HTMLElement)) {
-            return Promise.reject("no element");
-        }
-
-        if (!self.isConnected()) {
-            return Promise.reject("element not connected");
-        }
-
-        if (self[internalStateSymbol].getSubject()["loaded"] === true) {
-            if (self[internalStateSymbol].getSubject()["error"] !== undefined) {
-                return Promise.reject(self[internalStateSymbol].getSubject()["error"]);
-            }
-
-            return Promise.resolve();
-        }
-
-        return new Promise(function (resolve, reject) {
-            const timeout = setTimeout(() => {
-                reject("timeout");
-            }, self.getOption("timeout"));
-
-            const observer = new Observer(() => {
-                clearTimeout(timeout);
-                self[internalStateSymbol].detachObserver(observer);
-                resolve();
-            });
-
-            self[internalStateSymbol].attachObserver(observer);
-        });
-    }
-
-    /**
-     * @return {string}
-     */
-    static getURLAttribute() {
-        throw new Error("this method must be implemented by derived classes");
-    }
-
-    /**
-     * @return {symbol}
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/dom/resource");
-    }
+	/**
+	 *
+	 * @param {Object|undefined} options
+	 */
+	constructor(options) {
+		super(options);
+
+		let uri = this.getOption(this.constructor.getURLAttribute());
+
+		if (uri === undefined) {
+			throw new Error("missing source");
+		} else if (uri instanceof URL) {
+			uri = uri.toString();
+		} else if (!isString(uri)) {
+			throw new Error("unsupported url type");
+		}
+
+		this[internalSymbol][this.constructor.getURLAttribute()] = uri;
+		this[internalStateSymbol] = new ProxyObserver({
+			loaded: false,
+			error: undefined,
+		});
+
+		this[referenceSymbol] = undefined;
+	}
+
+	/**
+	 * @return {boolean}
+	 */
+	isConnected() {
+		if (this[referenceSymbol] instanceof HTMLElement) {
+			return this[referenceSymbol].isConnected;
+		}
+
+		return false;
+	}
+
+	/**
+	 * This method is overridden by the special classes and creates the DOM object.
+	 * This method is also called implicitly, if not yet done explicitly, by calling `connect()`.
+	 *
+	 * @throws {Error} this method must be implemented by derived classes
+	 * @return {Monster.DOM.Resource}
+	 */
+	create() {
+		throw new Error("this method must be implemented by derived classes");
+	}
+
+	/**
+	 * This method appends the HTMLElement to the specified document.
+	 * If the element has not yet been created, `create()` is called implicitly.
+	 *
+	 * throws {Error} target not found
+	 * @return {Monster.DOM.Resource}
+	 */
+	connect() {
+		if (!(this[referenceSymbol] instanceof HTMLElement)) {
+			this.create();
+		}
+
+		appendToDocument.call(this);
+		return this;
+	}
+
+	/**
+	 * @property {Document} document the document object into which the node is to be appended
+	 * @property {string} src/href url to the corresponding resource
+	 * @property {string} query defines the location where the resource is to be hooked into the dom.
+	 * @property {string} id element attribute id
+	 * @property {string} title element attribute title
+	 * @property {string} class element attribute class
+	 * @property {int} timeout timeout
+	 */
+	get defaults() {
+		return extend({}, super.defaults, {
+			[this.constructor.getURLAttribute()]: undefined,
+			[KEY_DOCUMENT]: getGlobalObject("document"),
+			[KEY_QUERY]: "head",
+			[KEY_TIMEOUT]: 10000,
+			[ATTRIBUTE_ID]: new ID("resource").toString(),
+			[ATTRIBUTE_CLASS]: undefined,
+			[ATTRIBUTE_TITLE]: undefined,
+		});
+	}
+
+	/**
+	 * With `available()` you can check if a resource is available.
+	 * This is the case when the tag is included and the resource is loaded.
+	 *
+	 * @return {Promise}
+	 */
+	available() {
+		const self = this;
+		if (!(self[referenceSymbol] instanceof HTMLElement)) {
+			return Promise.reject("no element");
+		}
+
+		if (!self.isConnected()) {
+			return Promise.reject("element not connected");
+		}
+
+		if (self[internalStateSymbol].getSubject()["loaded"] === true) {
+			if (self[internalStateSymbol].getSubject()["error"] !== undefined) {
+				return Promise.reject(self[internalStateSymbol].getSubject()["error"]);
+			}
+
+			return Promise.resolve();
+		}
+
+		return new Promise(function (resolve, reject) {
+			const timeout = setTimeout(() => {
+				reject("timeout");
+			}, self.getOption("timeout"));
+
+			const observer = new Observer(() => {
+				clearTimeout(timeout);
+				self[internalStateSymbol].detachObserver(observer);
+				resolve();
+			});
+
+			self[internalStateSymbol].attachObserver(observer);
+		});
+	}
+
+	/**
+	 * @return {string}
+	 */
+	static getURLAttribute() {
+		throw new Error("this method must be implemented by derived classes");
+	}
+
+	/**
+	 * @return {symbol}
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/dom/resource");
+	}
 }
 
 /**
@@ -197,17 +201,17 @@ class Resource extends BaseWithOptions {
  * throws {Error} target not found
  */
 function appendToDocument() {
-    const self = this;
+	const self = this;
 
-    const targetNode = document.querySelector(self.getOption(KEY_QUERY, "head"));
-    if (!(targetNode instanceof HTMLElement)) {
-        throw new Error("target not found");
-    }
+	const targetNode = document.querySelector(self.getOption(KEY_QUERY, "head"));
+	if (!(targetNode instanceof HTMLElement)) {
+		throw new Error("target not found");
+	}
 
-    addEvents.call(self);
-    targetNode.appendChild(self[referenceSymbol]);
+	addEvents.call(self);
+	targetNode.appendChild(self[referenceSymbol]);
 
-    return self;
+	return self;
 }
 
 /**
@@ -215,29 +219,31 @@ function appendToDocument() {
  * @return {addEvents}
  */
 function addEvents() {
-    const self = this;
+	const self = this;
 
-    const onError = () => {
-        self[referenceSymbol].removeEventListener("error", onError);
-        self[referenceSymbol].removeEventListener("load", onLoad);
+	const onError = () => {
+		self[referenceSymbol].removeEventListener("error", onError);
+		self[referenceSymbol].removeEventListener("load", onLoad);
 
-        self[internalStateSymbol].setSubject({
-            loaded: true,
-            error: `${self[referenceSymbol][self.constructor.getURLAttribute()]} is not available`,
-        });
+		self[internalStateSymbol].setSubject({
+			loaded: true,
+			error: `${
+				self[referenceSymbol][self.constructor.getURLAttribute()]
+			} is not available`,
+		});
 
-        return;
-    };
+		return;
+	};
 
-    const onLoad = () => {
-        self[referenceSymbol].removeEventListener("error", onError);
-        self[referenceSymbol].removeEventListener("load", onLoad);
-        self[internalStateSymbol].getSubject()["loaded"] = true;
-        return;
-    };
+	const onLoad = () => {
+		self[referenceSymbol].removeEventListener("error", onError);
+		self[referenceSymbol].removeEventListener("load", onLoad);
+		self[internalStateSymbol].getSubject()["loaded"] = true;
+		return;
+	};
 
-    self[referenceSymbol].addEventListener("load", onLoad, false);
-    self[referenceSymbol].addEventListener("error", onError, false);
+	self[referenceSymbol].addEventListener("load", onLoad, false);
+	self[referenceSymbol].addEventListener("error", onError, false);
 
-    return self;
+	return self;
 }
diff --git a/source/dom/resource/data.mjs b/source/dom/resource/data.mjs
index 7475dbe21837aa1402f725590f0520903f6b9cf8..4d73d34069df9c74d4b3ff7b62101adc2184ab66 100644
--- a/source/dom/resource/data.mjs
+++ b/source/dom/resource/data.mjs
@@ -9,15 +9,20 @@ import { internalStateSymbol } from "../../constants.mjs";
 import { extend } from "../../data/extend.mjs";
 import { getGlobalFunction } from "../../types/global.mjs";
 import {
-    ATTRIBUTE_CLASS,
-    ATTRIBUTE_ERRORMESSAGE,
-    ATTRIBUTE_ID,
-    ATTRIBUTE_SRC,
-    ATTRIBUTE_TITLE,
-    ATTRIBUTE_TYPE,
-    TAG_SCRIPT,
+	ATTRIBUTE_CLASS,
+	ATTRIBUTE_ERRORMESSAGE,
+	ATTRIBUTE_ID,
+	ATTRIBUTE_SRC,
+	ATTRIBUTE_TITLE,
+	ATTRIBUTE_TYPE,
+	TAG_SCRIPT,
 } from "../constants.mjs";
-import { KEY_DOCUMENT, KEY_QUERY, referenceSymbol, Resource } from "../resource.mjs";
+import {
+	KEY_DOCUMENT,
+	KEY_QUERY,
+	referenceSymbol,
+	Resource,
+} from "../resource.mjs";
 import { instanceSymbol } from "../../constants.mjs";
 export { Data };
 
@@ -31,58 +36,58 @@ export { Data };
  * @summary A Data Resource class
  */
 class Data extends Resource {
-    /**
-     * @property {string} mode=cors https://developer.mozilla.org/en-US/docs/Web/API/fetch
-     * @property {string} credentials=same-origin https://developer.mozilla.org/en-US/docs/Web/API/fetch
-     * @property {string} type=application/json {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type}
-     */
-    get defaults() {
-        return extend({}, super.defaults, {
-            mode: "cors",
-            credentials: "same-origin",
-            type: "application/json",
-        });
-    }
-
-    /**
-     *
-     * @return {Monster.DOM.Resource.Data}
-     */
-    create() {
-        createElement.call(this);
-        return this;
-    }
-
-    /**
-     * This method appends the HTMLElement to the specified document
-     *
-     * throws {Error} target not found
-     * @return {Monster.DOM.Resource}
-     */
-    connect() {
-        if (!(this[referenceSymbol] instanceof HTMLElement)) {
-            this.create();
-        }
-
-        appendToDocument.call(this);
-        return this;
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/dom/resource/data");
-    }
-
-    /**
-     * @return {string}
-     */
-    static getURLAttribute() {
-        return ATTRIBUTE_SRC;
-    }
+	/**
+	 * @property {string} mode=cors https://developer.mozilla.org/en-US/docs/Web/API/fetch
+	 * @property {string} credentials=same-origin https://developer.mozilla.org/en-US/docs/Web/API/fetch
+	 * @property {string} type=application/json {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type}
+	 */
+	get defaults() {
+		return extend({}, super.defaults, {
+			mode: "cors",
+			credentials: "same-origin",
+			type: "application/json",
+		});
+	}
+
+	/**
+	 *
+	 * @return {Monster.DOM.Resource.Data}
+	 */
+	create() {
+		createElement.call(this);
+		return this;
+	}
+
+	/**
+	 * This method appends the HTMLElement to the specified document
+	 *
+	 * throws {Error} target not found
+	 * @return {Monster.DOM.Resource}
+	 */
+	connect() {
+		if (!(this[referenceSymbol] instanceof HTMLElement)) {
+			this.create();
+		}
+
+		appendToDocument.call(this);
+		return this;
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/dom/resource/data");
+	}
+
+	/**
+	 * @return {string}
+	 */
+	static getURLAttribute() {
+		return ATTRIBUTE_SRC;
+	}
 }
 
 /**
@@ -90,18 +95,23 @@ class Data extends Resource {
  * @return {Monster.DOM.Resource.Data}
  */
 function createElement() {
-    const self = this;
-
-    const document = self.getOption(KEY_DOCUMENT);
-    self[referenceSymbol] = document.createElement(TAG_SCRIPT);
-
-    for (let key of [ATTRIBUTE_TYPE, ATTRIBUTE_ID, ATTRIBUTE_CLASS, ATTRIBUTE_TITLE]) {
-        if (self.getOption(key) !== undefined) {
-            self[referenceSymbol][key] = self.getOption(key);
-        }
-    }
-
-    return self;
+	const self = this;
+
+	const document = self.getOption(KEY_DOCUMENT);
+	self[referenceSymbol] = document.createElement(TAG_SCRIPT);
+
+	for (let key of [
+		ATTRIBUTE_TYPE,
+		ATTRIBUTE_ID,
+		ATTRIBUTE_CLASS,
+		ATTRIBUTE_TITLE,
+	]) {
+		if (self.getOption(key) !== undefined) {
+			self[referenceSymbol][key] = self.getOption(key);
+		}
+	}
+
+	return self;
 }
 
 /**
@@ -110,43 +120,43 @@ function createElement() {
  * throws {Error} target not found
  */
 function appendToDocument() {
-    const self = this;
-
-    const targetNode = document.querySelector(self.getOption(KEY_QUERY, "head"));
-    if (!(targetNode instanceof HTMLElement)) {
-        throw new Error("target not found");
-    }
-
-    targetNode.appendChild(self[referenceSymbol]);
-
-    getGlobalFunction("fetch")(self.getOption(ATTRIBUTE_SRC), {
-        method: "GET", // *GET, POST, PUT, DELETE, etc.
-        mode: self.getOption("mode", "cors"), // no-cors, *cors, same-origin
-        cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
-        credentials: self.getOption("credentials", "same-origin"), // include, *same-origin, omit
-        headers: {
-            Accept: self.getOption("type", "application/json"),
-        },
-        redirect: "follow", // manual, *follow, error
-        referrerPolicy: "no-referrer", // no-referrer,
-    })
-        .then((response) => {
-            return response.text();
-        })
-        .then((text) => {
-            const textNode = document.createTextNode(text);
-            self[referenceSymbol].appendChild(textNode);
-
-            self[internalStateSymbol].getSubject()["loaded"] = true;
-        })
-        .catch((e) => {
-            self[internalStateSymbol].setSubject({
-                loaded: true,
-                error: e.toString(),
-            });
-
-            targetNode.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.toString());
-        });
-
-    return self;
+	const self = this;
+
+	const targetNode = document.querySelector(self.getOption(KEY_QUERY, "head"));
+	if (!(targetNode instanceof HTMLElement)) {
+		throw new Error("target not found");
+	}
+
+	targetNode.appendChild(self[referenceSymbol]);
+
+	getGlobalFunction("fetch")(self.getOption(ATTRIBUTE_SRC), {
+		method: "GET", // *GET, POST, PUT, DELETE, etc.
+		mode: self.getOption("mode", "cors"), // no-cors, *cors, same-origin
+		cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
+		credentials: self.getOption("credentials", "same-origin"), // include, *same-origin, omit
+		headers: {
+			Accept: self.getOption("type", "application/json"),
+		},
+		redirect: "follow", // manual, *follow, error
+		referrerPolicy: "no-referrer", // no-referrer,
+	})
+		.then((response) => {
+			return response.text();
+		})
+		.then((text) => {
+			const textNode = document.createTextNode(text);
+			self[referenceSymbol].appendChild(textNode);
+
+			self[internalStateSymbol].getSubject()["loaded"] = true;
+		})
+		.catch((e) => {
+			self[internalStateSymbol].setSubject({
+				loaded: true,
+				error: e.toString(),
+			});
+
+			targetNode.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.toString());
+		});
+
+	return self;
 }
diff --git a/source/dom/resource/link.mjs b/source/dom/resource/link.mjs
index abc0696706739c75ab19d23becd7ca947b37e1d5..c76a4f3e46050e0d983db399ef118b3a18b9b990 100644
--- a/source/dom/resource/link.mjs
+++ b/source/dom/resource/link.mjs
@@ -7,14 +7,14 @@
 
 import { extend } from "../../data/extend.mjs";
 import {
-    ATTRIBUTE_CLASS,
-    ATTRIBUTE_HREF,
-    ATTRIBUTE_ID,
-    ATTRIBUTE_NONCE,
-    ATTRIBUTE_SRC,
-    ATTRIBUTE_TITLE,
-    ATTRIBUTE_TYPE,
-    TAG_LINK,
+	ATTRIBUTE_CLASS,
+	ATTRIBUTE_HREF,
+	ATTRIBUTE_ID,
+	ATTRIBUTE_NONCE,
+	ATTRIBUTE_SRC,
+	ATTRIBUTE_TITLE,
+	ATTRIBUTE_TYPE,
+	TAG_LINK,
 } from "../constants.mjs";
 import { KEY_DOCUMENT, referenceSymbol, Resource } from "../resource.mjs";
 import { instanceSymbol } from "../../constants.mjs";
@@ -31,67 +31,67 @@ export { Link };
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link
  */
 class Link extends Resource {
-    /**
-     * @property {string} as {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-as}
-     * @property {string} crossOrigin=anonymous {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-crossorigin}
-     * @property {boolean} disabled
-     * @property {string} href {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-href}
-     * @property {string} hreflang {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-hreflang}
-     * @property {string} imagesizes {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-imagesizes}
-     * @property {string} imagesrcset {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-imagesrcset}
-     * @property {string} integrity {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-integrity}
-     * @property {string} media {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-media}
-     * @property {string} prefetch {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-prefetch}
-     * @property {string} referrerpolicy {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-referrerpolicy}
-     * @property {string} rel {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-rel}
-     * @property {string} type {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-type}
-     * @property {string} sizes {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-sizes}
-     * @property {string} nonce {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-nonce}
-     */
-    get defaults() {
-        return extend({}, super.defaults, {
-            as: undefined,
-            crossOrigin: "anonymous",
-            disabled: undefined,
-            href: undefined,
-            hreflang: undefined,
-            imagesizes: undefined,
-            imagesrcset: undefined,
-            integrity: undefined,
-            media: undefined,
-            prefetch: undefined,
-            referrerpolicy: undefined,
-            rel: undefined,
-            sizes: undefined,
-            type: undefined,
-            nonce: undefined,
-        });
-    }
+	/**
+	 * @property {string} as {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-as}
+	 * @property {string} crossOrigin=anonymous {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-crossorigin}
+	 * @property {boolean} disabled
+	 * @property {string} href {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-href}
+	 * @property {string} hreflang {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-hreflang}
+	 * @property {string} imagesizes {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-imagesizes}
+	 * @property {string} imagesrcset {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-imagesrcset}
+	 * @property {string} integrity {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-integrity}
+	 * @property {string} media {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-media}
+	 * @property {string} prefetch {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-prefetch}
+	 * @property {string} referrerpolicy {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-referrerpolicy}
+	 * @property {string} rel {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-rel}
+	 * @property {string} type {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-type}
+	 * @property {string} sizes {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-sizes}
+	 * @property {string} nonce {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-nonce}
+	 */
+	get defaults() {
+		return extend({}, super.defaults, {
+			as: undefined,
+			crossOrigin: "anonymous",
+			disabled: undefined,
+			href: undefined,
+			hreflang: undefined,
+			imagesizes: undefined,
+			imagesrcset: undefined,
+			integrity: undefined,
+			media: undefined,
+			prefetch: undefined,
+			referrerpolicy: undefined,
+			rel: undefined,
+			sizes: undefined,
+			type: undefined,
+			nonce: undefined,
+		});
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/dom/resource/link");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/dom/resource/link");
+	}
 
-    /**
-     *
-     * @return {Monster.DOM.Resource.Link}
-     */
-    create() {
-        createElement.call(this);
-        return this;
-    }
+	/**
+	 *
+	 * @return {Monster.DOM.Resource.Link}
+	 */
+	create() {
+		createElement.call(this);
+		return this;
+	}
 
-    /**
-     * @return {string}
-     */
-    static getURLAttribute() {
-        return ATTRIBUTE_HREF;
-    }
+	/**
+	 * @return {string}
+	 */
+	static getURLAttribute() {
+		return ATTRIBUTE_HREF;
+	}
 }
 
 /**
@@ -99,36 +99,36 @@ class Link extends Resource {
  * @return {Monster.DOM.Resource.Link}
  */
 function createElement() {
-    const self = this;
+	const self = this;
 
-    const document = self.getOption(KEY_DOCUMENT);
-    self[referenceSymbol] = document.createElement(TAG_LINK);
+	const document = self.getOption(KEY_DOCUMENT);
+	self[referenceSymbol] = document.createElement(TAG_LINK);
 
-    for (let key of [
-        "as",
-        "crossOrigin",
-        "disabled",
-        "href",
-        "hreflang",
-        "imagesizes",
-        "imagesrcset",
-        "integrity",
-        "media",
-        "prefetch",
-        "referrerpolicy",
-        "sizes",
-        "rel",
-        "type",
-        ATTRIBUTE_HREF,
-        ATTRIBUTE_ID,
-        ATTRIBUTE_CLASS,
-        ATTRIBUTE_TITLE,
-        ATTRIBUTE_NONCE,
-    ]) {
-        if (self.getOption(key) !== undefined) {
-            self[referenceSymbol][key] = self.getOption(key);
-        }
-    }
+	for (let key of [
+		"as",
+		"crossOrigin",
+		"disabled",
+		"href",
+		"hreflang",
+		"imagesizes",
+		"imagesrcset",
+		"integrity",
+		"media",
+		"prefetch",
+		"referrerpolicy",
+		"sizes",
+		"rel",
+		"type",
+		ATTRIBUTE_HREF,
+		ATTRIBUTE_ID,
+		ATTRIBUTE_CLASS,
+		ATTRIBUTE_TITLE,
+		ATTRIBUTE_NONCE,
+	]) {
+		if (self.getOption(key) !== undefined) {
+			self[referenceSymbol][key] = self.getOption(key);
+		}
+	}
 
-    return self;
+	return self;
 }
diff --git a/source/dom/resource/link/stylesheet.mjs b/source/dom/resource/link/stylesheet.mjs
index 7fdd77d58fc12f621040f299b783e6ce82e1b245..c9eeec2fd97d8d2ef925fd74126e39b35b92e31b 100644
--- a/source/dom/resource/link/stylesheet.mjs
+++ b/source/dom/resource/link/stylesheet.mjs
@@ -21,21 +21,21 @@ export { Stylesheet };
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link
  */
 class Stylesheet extends Link {
-    /**
-     * @property {string} rel {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-rel}
-     */
-    get defaults() {
-        return extend({}, super.defaults, {
-            rel: "stylesheet",
-        });
-    }
+	/**
+	 * @property {string} rel {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-rel}
+	 */
+	get defaults() {
+		return extend({}, super.defaults, {
+			rel: "stylesheet",
+		});
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/dom/resource/link/stylesheet");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/dom/resource/link/stylesheet");
+	}
 }
diff --git a/source/dom/resource/script.mjs b/source/dom/resource/script.mjs
index 7b70287d77a2f62c9fbb96779c5fe3c4c0349df4..c62aa2184274d131376c9755ce9fa9e83ab2204f 100644
--- a/source/dom/resource/script.mjs
+++ b/source/dom/resource/script.mjs
@@ -7,13 +7,13 @@
 
 import { extend } from "../../data/extend.mjs";
 import {
-    ATTRIBUTE_CLASS,
-    ATTRIBUTE_ID,
-    ATTRIBUTE_NONCE,
-    ATTRIBUTE_SRC,
-    ATTRIBUTE_TITLE,
-    ATTRIBUTE_TYPE,
-    TAG_SCRIPT,
+	ATTRIBUTE_CLASS,
+	ATTRIBUTE_ID,
+	ATTRIBUTE_NONCE,
+	ATTRIBUTE_SRC,
+	ATTRIBUTE_TITLE,
+	ATTRIBUTE_TYPE,
+	TAG_SCRIPT,
 } from "../constants.mjs";
 import { KEY_DOCUMENT, referenceSymbol, Resource } from "../resource.mjs";
 import { instanceSymbol } from "../../constants.mjs";
@@ -29,53 +29,53 @@ export { Script };
  * @summary A Resource class
  */
 class Script extends Resource {
-    /**
-     * @property {boolean} async=true {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-async}
-     * @property {string} crossOrigin=anonymous {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-crossorigin}
-     * @property {boolean} defer=false {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer}
-     * @property {string} integrity {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-integrity}
-     * @property {boolean} nomodule {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-nomodule}
-     * @property {string} nonce {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-nonce}
-     * @property {string} referrerpolicy {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-referrerpolicy}
-     * @property {string} type {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type}
-     */
-    get defaults() {
-        return extend({}, super.defaults, {
-            async: true,
-            crossOrigin: "anonymous",
-            defer: false,
-            integrity: undefined,
-            nomodule: false,
-            nonce: undefined,
-            referrerpolicy: undefined,
-            type: "text/javascript",
-        });
-    }
+	/**
+	 * @property {boolean} async=true {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-async}
+	 * @property {string} crossOrigin=anonymous {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-crossorigin}
+	 * @property {boolean} defer=false {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer}
+	 * @property {string} integrity {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-integrity}
+	 * @property {boolean} nomodule {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-nomodule}
+	 * @property {string} nonce {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-nonce}
+	 * @property {string} referrerpolicy {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-referrerpolicy}
+	 * @property {string} type {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type}
+	 */
+	get defaults() {
+		return extend({}, super.defaults, {
+			async: true,
+			crossOrigin: "anonymous",
+			defer: false,
+			integrity: undefined,
+			nomodule: false,
+			nonce: undefined,
+			referrerpolicy: undefined,
+			type: "text/javascript",
+		});
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/dom/resource/script");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/dom/resource/script");
+	}
 
-    /**
-     *
-     * @return {Monster.DOM.Resource.Script}
-     */
-    create() {
-        createElement.call(this);
-        return this;
-    }
+	/**
+	 *
+	 * @return {Monster.DOM.Resource.Script}
+	 */
+	create() {
+		createElement.call(this);
+		return this;
+	}
 
-    /**
-     * @return {string}
-     */
-    static getURLAttribute() {
-        return ATTRIBUTE_SRC;
-    }
+	/**
+	 * @return {string}
+	 */
+	static getURLAttribute() {
+		return ATTRIBUTE_SRC;
+	}
 }
 
 /**
@@ -83,29 +83,29 @@ class Script extends Resource {
  * @return {Monster.DOM.Resource.Script}
  */
 function createElement() {
-    const self = this;
+	const self = this;
 
-    const document = self.getOption(KEY_DOCUMENT);
-    self[referenceSymbol] = document.createElement(TAG_SCRIPT);
+	const document = self.getOption(KEY_DOCUMENT);
+	self[referenceSymbol] = document.createElement(TAG_SCRIPT);
 
-    for (let key of [
-        "crossOrigin",
-        "defer",
-        "async",
-        "integrity",
-        "nomodule",
-        ATTRIBUTE_NONCE,
-        "referrerpolicy",
-        ATTRIBUTE_TYPE,
-        ATTRIBUTE_SRC,
-        ATTRIBUTE_ID,
-        ATTRIBUTE_CLASS,
-        ATTRIBUTE_TITLE,
-    ]) {
-        if (self.getOption(key) !== undefined) {
-            self[referenceSymbol][key] = self.getOption(key);
-        }
-    }
+	for (let key of [
+		"crossOrigin",
+		"defer",
+		"async",
+		"integrity",
+		"nomodule",
+		ATTRIBUTE_NONCE,
+		"referrerpolicy",
+		ATTRIBUTE_TYPE,
+		ATTRIBUTE_SRC,
+		ATTRIBUTE_ID,
+		ATTRIBUTE_CLASS,
+		ATTRIBUTE_TITLE,
+	]) {
+		if (self.getOption(key) !== undefined) {
+			self[referenceSymbol][key] = self.getOption(key);
+		}
+	}
 
-    return self;
+	return self;
 }
diff --git a/source/dom/resourcemanager.mjs b/source/dom/resourcemanager.mjs
index 3457de5a303cfa13e58a2bb0bba7eb478e53422a..d355a4b7b7e8bf0f629933e7c9f348ee90153adf 100644
--- a/source/dom/resourcemanager.mjs
+++ b/source/dom/resourcemanager.mjs
@@ -28,121 +28,121 @@ export { ResourceManager };
  * @summary A Resource class
  */
 class ResourceManager extends Base {
-    /**
-     *
-     * @param {Object} options
-     * throw {Error} unsupported document type
-     */
-    constructor(options) {
-        super(options);
-        equipWithInternal.call(this);
-
-        if (!(this.getOption("document") instanceof Document)) {
-            throw new Error("unsupported document type");
-        }
-    }
-
-    /**
-     * @deprecated since 3.15.0 use getInternal instead
-     * @property {string} baseurl
-     */
-    getOption(key) {
-        return this.getInternal(key);
-    }
-
-    /**
-     * @property {string} baseurl
-     */
-    getBaseURL() {
-        this.getOption("document")?.baseURL;
-    }
-
-    /**
-     * @property {string} baseurl
-     * @deprecated since 3.15.0 use internalDefaults instead
-     */
-    get defaults() {
-        return this.internalDefaults;
-    }
-
-    /**
-     *
-     * @property {HTMLDocument} document=document Document
-     * @property {Object} resources
-     * @property {Array} resources.scripts=[] array with {@link Monster.DOM.Resource.Script} objects
-     * @property {Array} resources.stylesheets=[] array with {@link Monster.DOM.Resource.Link.Stylesheet} objects
-     * @property {Array} resources.data=[] array with {@link Monster.DOM.Resource.Data} objects
-     */
-    get internalDefaults() {
-        return Object.assign(
-            {},
-            {
-                document: getGlobalObject("document"),
-                resources: {
-                    scripts: [],
-                    stylesheets: [],
-                    data: [],
-                },
-            },
-        );
-    }
-
-    /**
-     * Append Tags to DOM
-     *
-     * @return {Monster.DOM.ResourceManager}
-     * @throws {Error} unsupported resource definition
-     */
-    connect() {
-        runResourceMethod.call(this, "connect");
-        return this;
-    }
-
-    /**
-     * Check if available
-     *
-     * @return {Promise}
-     * @throws {Error} unsupported resource definition
-     */
-    available() {
-        return Promise.all(runResourceMethod.call(this, "available"));
-    }
-
-    /**
-     * Add a script
-     *
-     * @param {string|URL} url
-     * @param [Object|undefined} options
-     * @return {Monster.DOM.ResourceManager}
-     * @see Monster.DOM.Resource.Script
-     */
-    addScript(url, options) {
-        return addResource.call(this, "scripts", url, options);
-    }
-
-    /**
-     * Add Stylesheet
-     *
-     * @param {string|URL} url
-     * @param [Object|undefined} options
-     * @return {Monster.DOM.ResourceManager}
-     * @see Monster.DOM.Resource.Link.Stylesheet
-     */
-    addStylesheet(url, options) {
-        return addResource.call(this, "stylesheets", url, options);
-    }
-
-    /**
-     * Add Data Tag
-     *
-     * @param {string|URL} url
-     * @param [Object|undefined} options
-     * @return {Monster.DOM.ResourceManager}
-     * @see Monster.DOM.Resource.Data
-     */
-    addData(url, options) {
-        return addResource.call(this, "data", url, options);
-    }
+	/**
+	 *
+	 * @param {Object} options
+	 * throw {Error} unsupported document type
+	 */
+	constructor(options) {
+		super(options);
+		equipWithInternal.call(this);
+
+		if (!(this.getOption("document") instanceof Document)) {
+			throw new Error("unsupported document type");
+		}
+	}
+
+	/**
+	 * @deprecated since 3.15.0 use getInternal instead
+	 * @property {string} baseurl
+	 */
+	getOption(key) {
+		return this.getInternal(key);
+	}
+
+	/**
+	 * @property {string} baseurl
+	 */
+	getBaseURL() {
+		this.getOption("document")?.baseURL;
+	}
+
+	/**
+	 * @property {string} baseurl
+	 * @deprecated since 3.15.0 use internalDefaults instead
+	 */
+	get defaults() {
+		return this.internalDefaults;
+	}
+
+	/**
+	 *
+	 * @property {HTMLDocument} document=document Document
+	 * @property {Object} resources
+	 * @property {Array} resources.scripts=[] array with {@link Monster.DOM.Resource.Script} objects
+	 * @property {Array} resources.stylesheets=[] array with {@link Monster.DOM.Resource.Link.Stylesheet} objects
+	 * @property {Array} resources.data=[] array with {@link Monster.DOM.Resource.Data} objects
+	 */
+	get internalDefaults() {
+		return Object.assign(
+			{},
+			{
+				document: getGlobalObject("document"),
+				resources: {
+					scripts: [],
+					stylesheets: [],
+					data: [],
+				},
+			},
+		);
+	}
+
+	/**
+	 * Append Tags to DOM
+	 *
+	 * @return {Monster.DOM.ResourceManager}
+	 * @throws {Error} unsupported resource definition
+	 */
+	connect() {
+		runResourceMethod.call(this, "connect");
+		return this;
+	}
+
+	/**
+	 * Check if available
+	 *
+	 * @return {Promise}
+	 * @throws {Error} unsupported resource definition
+	 */
+	available() {
+		return Promise.all(runResourceMethod.call(this, "available"));
+	}
+
+	/**
+	 * Add a script
+	 *
+	 * @param {string|URL} url
+	 * @param [Object|undefined} options
+	 * @return {Monster.DOM.ResourceManager}
+	 * @see Monster.DOM.Resource.Script
+	 */
+	addScript(url, options) {
+		return addResource.call(this, "scripts", url, options);
+	}
+
+	/**
+	 * Add Stylesheet
+	 *
+	 * @param {string|URL} url
+	 * @param [Object|undefined} options
+	 * @return {Monster.DOM.ResourceManager}
+	 * @see Monster.DOM.Resource.Link.Stylesheet
+	 */
+	addStylesheet(url, options) {
+		return addResource.call(this, "stylesheets", url, options);
+	}
+
+	/**
+	 * Add Data Tag
+	 *
+	 * @param {string|URL} url
+	 * @param [Object|undefined} options
+	 * @return {Monster.DOM.ResourceManager}
+	 * @see Monster.DOM.Resource.Data
+	 */
+	addData(url, options) {
+		return addResource.call(this, "data", url, options);
+	}
 }
 
 /**
@@ -151,26 +151,26 @@ class ResourceManager extends Base {
  * @return {Array}
  */
 function runResourceMethod(method) {
-    const self = this;
+	const self = this;
 
-    const result = [];
+	const result = [];
 
-    for (const type of ["scripts", "stylesheets", "data"]) {
-        const resources = self.getOption(`resources.${type}`);
-        if (!isArray(resources)) {
-            continue;
-        }
+	for (const type of ["scripts", "stylesheets", "data"]) {
+		const resources = self.getOption(`resources.${type}`);
+		if (!isArray(resources)) {
+			continue;
+		}
 
-        for (const resource of resources) {
-            if (!(resource instanceof Resource)) {
-                throw new Error("unsupported resource definition");
-            }
+		for (const resource of resources) {
+			if (!(resource instanceof Resource)) {
+				throw new Error("unsupported resource definition");
+			}
 
-            result.push(resource[method]());
-        }
-    }
+			result.push(resource[method]());
+		}
+	}
 
-    return result;
+	return result;
 }
 
 /**
@@ -182,29 +182,29 @@ function runResourceMethod(method) {
  * @private
  */
 function addResource(type, url, options) {
-    const self = this;
-
-    if (url instanceof URL) {
-        url = url.toString();
-    }
-
-    options = options || {};
-
-    let resource;
-    switch (type) {
-        case "scripts":
-            resource = new Script(extend({}, options, { [ATTRIBUTE_SRC]: url }));
-            break;
-        case "stylesheets":
-            resource = new Stylesheet(extend({}, options, { [ATTRIBUTE_HREF]: url }));
-            break;
-        case "data":
-            resource = new Data(extend({}, options, { [ATTRIBUTE_SRC]: url }));
-            break;
-        default:
-            throw new Error(`unsupported type ${type}`);
-    }
-
-    self.getOption("resources")?.[type].push(resource);
-    return self;
+	const self = this;
+
+	if (url instanceof URL) {
+		url = url.toString();
+	}
+
+	options = options || {};
+
+	let resource;
+	switch (type) {
+		case "scripts":
+			resource = new Script(extend({}, options, { [ATTRIBUTE_SRC]: url }));
+			break;
+		case "stylesheets":
+			resource = new Stylesheet(extend({}, options, { [ATTRIBUTE_HREF]: url }));
+			break;
+		case "data":
+			resource = new Data(extend({}, options, { [ATTRIBUTE_SRC]: url }));
+			break;
+		default:
+			throw new Error(`unsupported type ${type}`);
+	}
+
+	self.getOption("resources")?.[type].push(resource);
+	return self;
 }
diff --git a/source/dom/slotted.mjs b/source/dom/slotted.mjs
index 53f8047bc78f7d25d4b7c4703a72d9949057851d..3a7445594683db575a0bb5c6720d1b3e5b886cc8 100644
--- a/source/dom/slotted.mjs
+++ b/source/dom/slotted.mjs
@@ -14,47 +14,47 @@ export { getSlottedElements, getSlottedNodes };
  * @throws {Error} query must be a string
  */
 function getSlottedNodes(query, name) {
-    const self = this;
-    const result = new Set();
-
-    if (!self.shadowRoot) {
-        return result;
-    }
-
-    let selector = "slot";
-    if (name !== undefined) {
-        if (name === null) {
-            selector += ":not([name])";
-        } else {
-            selector += `[name=${validateString(name)}]`;
-        }
-    }
-
-    const slots = self.shadowRoot.querySelectorAll(selector);
-
-    for (const [, slot] of Object.entries(slots)) {
-        slot.assignedNodes().forEach(function (node) {
-            if (node === null || node === undefined) {
-                return;
-            }
-
-            if (isString(query)) {
-                node.querySelectorAll(query).forEach(function (n) {
-                    result.add(n);
-                });
-
-                if (node.matches(query)) {
-                    result.add(node);
-                }
-            } else if (query !== undefined) {
-                throw new Error("query must be a string");
-            } else {
-                result.add(node);
-            }
-        });
-    }
-
-    return result;
+	const self = this;
+	const result = new Set();
+
+	if (!self.shadowRoot) {
+		return result;
+	}
+
+	let selector = "slot";
+	if (name !== undefined) {
+		if (name === null) {
+			selector += ":not([name])";
+		} else {
+			selector += `[name=${validateString(name)}]`;
+		}
+	}
+
+	const slots = self.shadowRoot.querySelectorAll(selector);
+
+	for (const [, slot] of Object.entries(slots)) {
+		slot.assignedNodes().forEach(function (node) {
+			if (node === null || node === undefined) {
+				return;
+			}
+
+			if (isString(query)) {
+				node.querySelectorAll(query).forEach(function (n) {
+					result.add(n);
+				});
+
+				if (node.matches(query)) {
+					result.add(node);
+				}
+			} else if (query !== undefined) {
+				throw new Error("query must be a string");
+			} else {
+				result.add(node);
+			}
+		});
+	}
+
+	return result;
 }
 
 /**
@@ -68,43 +68,43 @@ function getSlottedNodes(query, name) {
  * @throws {Error} query must be a string
  */
 function getSlottedElements(query, name) {
-    const self = this;
-    const result = new Set();
-
-    if (!(self.shadowRoot instanceof ShadowRoot)) {
-        return result;
-    }
-
-    let selector = "slot";
-    if (name !== undefined) {
-        if (name === null) {
-            selector += ":not([name])";
-        } else {
-            selector += `[name=${validateString(name)}]`;
-        }
-    }
-
-    const slots = self.shadowRoot.querySelectorAll(selector);
-
-    for (const [, slot] of Object.entries(slots)) {
-        slot.assignedElements().forEach(function (node) {
-            if (!(node instanceof HTMLElement)) return;
-
-            if (isString(query)) {
-                node.querySelectorAll(query).forEach(function (n) {
-                    result.add(n);
-                });
-
-                if (node.matches(query)) {
-                    result.add(node);
-                }
-            } else if (query !== undefined) {
-                throw new Error("query must be a string");
-            } else {
-                result.add(node);
-            }
-        });
-    }
-
-    return result;
+	const self = this;
+	const result = new Set();
+
+	if (!(self.shadowRoot instanceof ShadowRoot)) {
+		return result;
+	}
+
+	let selector = "slot";
+	if (name !== undefined) {
+		if (name === null) {
+			selector += ":not([name])";
+		} else {
+			selector += `[name=${validateString(name)}]`;
+		}
+	}
+
+	const slots = self.shadowRoot.querySelectorAll(selector);
+
+	for (const [, slot] of Object.entries(slots)) {
+		slot.assignedElements().forEach(function (node) {
+			if (!(node instanceof HTMLElement)) return;
+
+			if (isString(query)) {
+				node.querySelectorAll(query).forEach(function (n) {
+					result.add(n);
+				});
+
+				if (node.matches(query)) {
+					result.add(node);
+				}
+			} else if (query !== undefined) {
+				throw new Error("query must be a string");
+			} else {
+				result.add(node);
+			}
+		});
+	}
+
+	return result;
 }
diff --git a/source/dom/template.mjs b/source/dom/template.mjs
index e2ea3e880387749f9d2df219e0eaab37f6d589bf..5f10e0b73435333313f471ead87f1b14e561f58d 100644
--- a/source/dom/template.mjs
+++ b/source/dom/template.mjs
@@ -23,45 +23,45 @@ export { Template };
  * @summary A template class
  */
 class Template extends Base {
-    /**
-     *
-     * @param {HTMLTemplateElement} template
-     * @throws {TypeError} value is not an instance of
-     * @throws {TypeError} value is not a function
-     * @throws {Error} the function is not defined
-     */
-    constructor(template) {
-        super();
-        const HTMLTemplateElement = getGlobalFunction("HTMLTemplateElement");
-        validateInstance(template, HTMLTemplateElement);
-        this.template = template;
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/dom/resource/template");
-    }
-
-    /**
-     *
-     * @returns {HTMLTemplateElement}
-     */
-    getTemplateElement() {
-        return this.template;
-    }
-
-    /**
-     *
-     * @return {DocumentFragment}
-     * @throws {TypeError} value is not an instance of
-     */
-    createDocumentFragment() {
-        return this.template.content.cloneNode(true);
-    }
+	/**
+	 *
+	 * @param {HTMLTemplateElement} template
+	 * @throws {TypeError} value is not an instance of
+	 * @throws {TypeError} value is not a function
+	 * @throws {Error} the function is not defined
+	 */
+	constructor(template) {
+		super();
+		const HTMLTemplateElement = getGlobalFunction("HTMLTemplateElement");
+		validateInstance(template, HTMLTemplateElement);
+		this.template = template;
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/dom/resource/template");
+	}
+
+	/**
+	 *
+	 * @returns {HTMLTemplateElement}
+	 */
+	getTemplateElement() {
+		return this.template;
+	}
+
+	/**
+	 *
+	 * @return {DocumentFragment}
+	 * @throws {TypeError} value is not an instance of
+	 */
+	createDocumentFragment() {
+		return this.template.content.cloneNode(true);
+	}
 }
 
 /**
@@ -128,77 +128,91 @@ class Template extends Base {
  * @throws {TypeError} value is not a string
  */
 export function findDocumentTemplate(id, currentNode) {
-    validateString(id);
-
-    const document = getGlobalObject("document");
-    const HTMLTemplateElement = getGlobalFunction("HTMLTemplateElement");
-    const DocumentFragment = getGlobalFunction("DocumentFragment");
-    const Document = getGlobalFunction("Document");
-
-    let prefixID;
-
-    if (!(currentNode instanceof Document || currentNode instanceof DocumentFragment)) {
-        if (currentNode instanceof Node) {
-            if (currentNode.hasAttribute(ATTRIBUTE_TEMPLATE_PREFIX)) {
-                prefixID = currentNode.getAttribute(ATTRIBUTE_TEMPLATE_PREFIX);
-            }
-
-            currentNode = currentNode.getRootNode();
-
-            if (!(currentNode instanceof Document || currentNode instanceof DocumentFragment)) {
-                currentNode = currentNode.ownerDocument;
-            }
-        }
-
-        if (!(currentNode instanceof Document || currentNode instanceof DocumentFragment)) {
-            currentNode = document;
-        }
-    }
-
-    let template;
-    let theme = getDocumentTheme();
-
-    if (prefixID) {
-        let themedPrefixID = `${prefixID}-${id}-${theme.getName()}`;
-
-        // current + themedPrefixID
-        template = currentNode.getElementById(themedPrefixID);
-        if (template instanceof HTMLTemplateElement) {
-            return new Template(template);
-        }
-
-        // document + themedPrefixID
-        template = document.getElementById(themedPrefixID);
-        if (template instanceof HTMLTemplateElement) {
-            return new Template(template);
-        }
-    }
-
-    let themedID = `${id}-${theme.getName()}`;
-
-    // current + themedID
-    template = currentNode.getElementById(themedID);
-    if (template instanceof HTMLTemplateElement) {
-        return new Template(template);
-    }
-
-    // document + themedID
-    template = document.getElementById(themedID);
-    if (template instanceof HTMLTemplateElement) {
-        return new Template(template);
-    }
-
-    // current + ID
-    template = currentNode.getElementById(id);
-    if (template instanceof HTMLTemplateElement) {
-        return new Template(template);
-    }
-
-    // document + ID
-    template = document.getElementById(id);
-    if (template instanceof HTMLTemplateElement) {
-        return new Template(template);
-    }
-
-    throw new Error(`template ${id} not found.`);
+	validateString(id);
+
+	const document = getGlobalObject("document");
+	const HTMLTemplateElement = getGlobalFunction("HTMLTemplateElement");
+	const DocumentFragment = getGlobalFunction("DocumentFragment");
+	const Document = getGlobalFunction("Document");
+
+	let prefixID;
+
+	if (
+		!(
+			currentNode instanceof Document || currentNode instanceof DocumentFragment
+		)
+	) {
+		if (currentNode instanceof Node) {
+			if (currentNode.hasAttribute(ATTRIBUTE_TEMPLATE_PREFIX)) {
+				prefixID = currentNode.getAttribute(ATTRIBUTE_TEMPLATE_PREFIX);
+			}
+
+			currentNode = currentNode.getRootNode();
+
+			if (
+				!(
+					currentNode instanceof Document ||
+					currentNode instanceof DocumentFragment
+				)
+			) {
+				currentNode = currentNode.ownerDocument;
+			}
+		}
+
+		if (
+			!(
+				currentNode instanceof Document ||
+				currentNode instanceof DocumentFragment
+			)
+		) {
+			currentNode = document;
+		}
+	}
+
+	let template;
+	let theme = getDocumentTheme();
+
+	if (prefixID) {
+		let themedPrefixID = `${prefixID}-${id}-${theme.getName()}`;
+
+		// current + themedPrefixID
+		template = currentNode.getElementById(themedPrefixID);
+		if (template instanceof HTMLTemplateElement) {
+			return new Template(template);
+		}
+
+		// document + themedPrefixID
+		template = document.getElementById(themedPrefixID);
+		if (template instanceof HTMLTemplateElement) {
+			return new Template(template);
+		}
+	}
+
+	let themedID = `${id}-${theme.getName()}`;
+
+	// current + themedID
+	template = currentNode.getElementById(themedID);
+	if (template instanceof HTMLTemplateElement) {
+		return new Template(template);
+	}
+
+	// document + themedID
+	template = document.getElementById(themedID);
+	if (template instanceof HTMLTemplateElement) {
+		return new Template(template);
+	}
+
+	// current + ID
+	template = currentNode.getElementById(id);
+	if (template instanceof HTMLTemplateElement) {
+		return new Template(template);
+	}
+
+	// document + ID
+	template = document.getElementById(id);
+	if (template instanceof HTMLTemplateElement) {
+		return new Template(template);
+	}
+
+	throw new Error(`template ${id} not found.`);
 }
diff --git a/source/dom/theme.mjs b/source/dom/theme.mjs
index 9d2b4fce94ab137360b26c70efec248fcc153fc5..4cfa897fe9a3984cb18878cf6d6a33cf8935662a 100644
--- a/source/dom/theme.mjs
+++ b/source/dom/theme.mjs
@@ -23,33 +23,33 @@ export { Theme, getDocumentTheme };
  * @summary A theme class
  */
 class Theme extends Base {
-    /**
-     *
-     * @param name
-     * @throws {TypeError} value is not a string
-     */
-    constructor(name) {
-        super();
-        validateString(name);
-        this.name = name;
-    }
+	/**
+	 *
+	 * @param name
+	 * @throws {TypeError} value is not a string
+	 */
+	constructor(name) {
+		super();
+		validateString(name);
+		this.name = name;
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/dom/theme");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/dom/theme");
+	}
 
-    /**
-     *
-     * @returns {string}
-     */
-    getName() {
-        return this.name;
-    }
+	/**
+	 *
+	 * @returns {string}
+	 */
+	getName() {
+		return this.name;
+	}
 }
 
 /**
@@ -70,16 +70,16 @@ class Theme extends Base {
  * @since 1.7.0
  */
 function getDocumentTheme() {
-    let document = getGlobalObject("document");
-    let name = DEFAULT_THEME;
+	let document = getGlobalObject("document");
+	let name = DEFAULT_THEME;
 
-    let element = document.querySelector("html");
-    if (element instanceof HTMLElement) {
-        let theme = element.getAttribute(ATTRIBUTE_THEME_NAME);
-        if (theme) {
-            name = theme;
-        }
-    }
+	let element = document.querySelector("html");
+	if (element instanceof HTMLElement) {
+		let theme = element.getAttribute(ATTRIBUTE_THEME_NAME);
+		if (theme) {
+			name = theme;
+		}
+	}
 
-    return new Theme(name);
+	return new Theme(name);
 }
diff --git a/source/dom/updater.mjs b/source/dom/updater.mjs
index 40867df6102a4020e98bf3b14be76af312c331fa..8fa8a2d66b4e9a5db7196292e744eed93b018c98 100644
--- a/source/dom/updater.mjs
+++ b/source/dom/updater.mjs
@@ -10,14 +10,14 @@ import { diff } from "../data/diff.mjs";
 import { Pathfinder } from "../data/pathfinder.mjs";
 import { Pipe } from "../data/pipe.mjs";
 import {
-    ATTRIBUTE_ERRORMESSAGE,
-    ATTRIBUTE_UPDATER_ATTRIBUTES,
-    ATTRIBUTE_UPDATER_BIND,
-    ATTRIBUTE_UPDATER_INSERT,
-    ATTRIBUTE_UPDATER_INSERT_REFERENCE,
-    ATTRIBUTE_UPDATER_REMOVE,
-    ATTRIBUTE_UPDATER_REPLACE,
-    ATTRIBUTE_UPDATER_SELECT_THIS,
+	ATTRIBUTE_ERRORMESSAGE,
+	ATTRIBUTE_UPDATER_ATTRIBUTES,
+	ATTRIBUTE_UPDATER_BIND,
+	ATTRIBUTE_UPDATER_INSERT,
+	ATTRIBUTE_UPDATER_INSERT_REFERENCE,
+	ATTRIBUTE_UPDATER_REMOVE,
+	ATTRIBUTE_UPDATER_REPLACE,
+	ATTRIBUTE_UPDATER_SELECT_THIS,
 } from "./constants.mjs";
 
 import { Base } from "../types/base.mjs";
@@ -56,164 +56,174 @@ export { Updater, addObjectWithUpdaterToElement };
  * @summary The updater class connects an object with the dom
  */
 class Updater extends Base {
-    /**
-     * @since 1.8.0
-     * @param {HTMLElement} element
-     * @param {object|ProxyObserver|undefined} subject
-     * @throws {TypeError} value is not a object
-     * @throws {TypeError} value is not an instance of HTMLElement
-     * @see {@link Monster.DOM.findDocumentTemplate}
-     */
-    constructor(element, subject) {
-        super();
-
-        /**
-         * @type {HTMLElement}
-         */
-        if (subject === undefined) subject = {};
-        if (!isInstance(subject, ProxyObserver)) {
-            subject = new ProxyObserver(subject);
-        }
-
-        this[internalSymbol] = {
-            element: validateInstance(element, HTMLElement),
-            last: {},
-            callbacks: new Map(),
-            eventTypes: ["keyup", "click", "change", "drop", "touchend", "input"],
-            subject: subject,
-        };
-
-        this[internalSymbol].callbacks.set("checkstate", getCheckStateCallback.call(this));
-
-        this[internalSymbol].subject.attachObserver(
-            new Observer(() => {
-                const s = this[internalSymbol].subject.getRealSubject();
-
-                const diffResult = diff(this[internalSymbol].last, s);
-                this[internalSymbol].last = clone(s);
-
-                for (const [, change] of Object.entries(diffResult)) {
-                    removeElement.call(this, change);
-                    insertElement.call(this, change);
-                    updateContent.call(this, change);
-                    updateAttributes.call(this, change);
-                }
-            }),
-        );
-    }
-
-    /**
-     * Defaults: 'keyup', 'click', 'change', 'drop', 'touchend'
-     *
-     * @see {@link https://developer.mozilla.org/de/docs/Web/Events}
-     * @since 1.9.0
-     * @param {Array} types
-     * @return {Updater}
-     */
-    setEventTypes(types) {
-        this[internalSymbol].eventTypes = validateArray(types);
-        return this;
-    }
-
-    /**
-     * With this method, the eventlisteners are hooked in and the magic begins.
-     *
-     * ```
-     * updater.run().then(() => {
-     *   updater.enableEventProcessing();
-     * });
-     * ```
-     *
-     * @since 1.9.0
-     * @return {Updater}
-     * @throws {Error} the bind argument must start as a value with a path
-     */
-    enableEventProcessing() {
-        this.disableEventProcessing();
-
-        for (const type of this[internalSymbol].eventTypes) {
-            // @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
-            this[internalSymbol].element.addEventListener(type, getControlEventHandler.call(this), {
-                capture: true,
-                passive: true,
-            });
-        }
-
-        return this;
-    }
-
-    /**
-     * This method turns off the magic or who loves it more profane it removes the eventListener.
-     *
-     * @since 1.9.0
-     * @return {Updater}
-     */
-    disableEventProcessing() {
-        for (const type of this[internalSymbol].eventTypes) {
-            this[internalSymbol].element.removeEventListener(type, getControlEventHandler.call(this));
-        }
-
-        return this;
-    }
-
-    /**
-     * The run method must be called for the update to start working.
-     * The method ensures that changes are detected.
-     *
-     * ```
-     * updater.run().then(() => {
-     *   updater.enableEventProcessing();
-     * });
-     * ```
-     *
-     * @summary Let the magic begin
-     * @return {Promise}
-     */
-    run() {
-        // the key __init__has no further meaning and is only
-        // used to create the diff for empty objects.
-        this[internalSymbol].last = { __init__: true };
-        return this[internalSymbol].subject.notifyObservers();
-    }
-
-    /**
-     * Gets the values of bound elements and changes them in subject
-     *
-     * @since 1.27.0
-     * @return {Monster.DOM.Updater}
-     */
-    retrieve() {
-        retrieveFromBindings.call(this);
-        return this;
-    }
-
-    /**
-     * If you have passed a ProxyObserver in the constructor, you will get the object that the ProxyObserver manages here.
-     * However, if you passed a simple object, here you will get a proxy for that object.
-     *
-     * For changes the ProxyObserver must be used.
-     *
-     * @since 1.8.0
-     * @return {Proxy}
-     */
-    getSubject() {
-        return this[internalSymbol].subject.getSubject();
-    }
-
-    /**
-     * This method can be used to register commands that can be called via call: instruction.
-     * This can be used to provide a pipe with its own functionality.
-     *
-     * @param {string} name
-     * @param {function} callback
-     * @returns {Transformer}
-     * @throws {TypeError} value is not a string
-     * @throws {TypeError} value is not a function
-     */
-    setCallback(name, callback) {
-        this[internalSymbol].callbacks.set(name, callback);
-        return this;
-    }
+	/**
+	 * @since 1.8.0
+	 * @param {HTMLElement} element
+	 * @param {object|ProxyObserver|undefined} subject
+	 * @throws {TypeError} value is not a object
+	 * @throws {TypeError} value is not an instance of HTMLElement
+	 * @see {@link Monster.DOM.findDocumentTemplate}
+	 */
+	constructor(element, subject) {
+		super();
+
+		/**
+		 * @type {HTMLElement}
+		 */
+		if (subject === undefined) subject = {};
+		if (!isInstance(subject, ProxyObserver)) {
+			subject = new ProxyObserver(subject);
+		}
+
+		this[internalSymbol] = {
+			element: validateInstance(element, HTMLElement),
+			last: {},
+			callbacks: new Map(),
+			eventTypes: ["keyup", "click", "change", "drop", "touchend", "input"],
+			subject: subject,
+		};
+
+		this[internalSymbol].callbacks.set(
+			"checkstate",
+			getCheckStateCallback.call(this),
+		);
+
+		this[internalSymbol].subject.attachObserver(
+			new Observer(() => {
+				const s = this[internalSymbol].subject.getRealSubject();
+
+				const diffResult = diff(this[internalSymbol].last, s);
+				this[internalSymbol].last = clone(s);
+
+				for (const [, change] of Object.entries(diffResult)) {
+					removeElement.call(this, change);
+					insertElement.call(this, change);
+					updateContent.call(this, change);
+					updateAttributes.call(this, change);
+				}
+			}),
+		);
+	}
+
+	/**
+	 * Defaults: 'keyup', 'click', 'change', 'drop', 'touchend'
+	 *
+	 * @see {@link https://developer.mozilla.org/de/docs/Web/Events}
+	 * @since 1.9.0
+	 * @param {Array} types
+	 * @return {Updater}
+	 */
+	setEventTypes(types) {
+		this[internalSymbol].eventTypes = validateArray(types);
+		return this;
+	}
+
+	/**
+	 * With this method, the eventlisteners are hooked in and the magic begins.
+	 *
+	 * ```
+	 * updater.run().then(() => {
+	 *   updater.enableEventProcessing();
+	 * });
+	 * ```
+	 *
+	 * @since 1.9.0
+	 * @return {Updater}
+	 * @throws {Error} the bind argument must start as a value with a path
+	 */
+	enableEventProcessing() {
+		this.disableEventProcessing();
+
+		for (const type of this[internalSymbol].eventTypes) {
+			// @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
+			this[internalSymbol].element.addEventListener(
+				type,
+				getControlEventHandler.call(this),
+				{
+					capture: true,
+					passive: true,
+				},
+			);
+		}
+
+		return this;
+	}
+
+	/**
+	 * This method turns off the magic or who loves it more profane it removes the eventListener.
+	 *
+	 * @since 1.9.0
+	 * @return {Updater}
+	 */
+	disableEventProcessing() {
+		for (const type of this[internalSymbol].eventTypes) {
+			this[internalSymbol].element.removeEventListener(
+				type,
+				getControlEventHandler.call(this),
+			);
+		}
+
+		return this;
+	}
+
+	/**
+	 * The run method must be called for the update to start working.
+	 * The method ensures that changes are detected.
+	 *
+	 * ```
+	 * updater.run().then(() => {
+	 *   updater.enableEventProcessing();
+	 * });
+	 * ```
+	 *
+	 * @summary Let the magic begin
+	 * @return {Promise}
+	 */
+	run() {
+		// the key __init__has no further meaning and is only
+		// used to create the diff for empty objects.
+		this[internalSymbol].last = { __init__: true };
+		return this[internalSymbol].subject.notifyObservers();
+	}
+
+	/**
+	 * Gets the values of bound elements and changes them in subject
+	 *
+	 * @since 1.27.0
+	 * @return {Monster.DOM.Updater}
+	 */
+	retrieve() {
+		retrieveFromBindings.call(this);
+		return this;
+	}
+
+	/**
+	 * If you have passed a ProxyObserver in the constructor, you will get the object that the ProxyObserver manages here.
+	 * However, if you passed a simple object, here you will get a proxy for that object.
+	 *
+	 * For changes the ProxyObserver must be used.
+	 *
+	 * @since 1.8.0
+	 * @return {Proxy}
+	 */
+	getSubject() {
+		return this[internalSymbol].subject.getSubject();
+	}
+
+	/**
+	 * This method can be used to register commands that can be called via call: instruction.
+	 * This can be used to provide a pipe with its own functionality.
+	 *
+	 * @param {string} name
+	 * @param {function} callback
+	 * @returns {Transformer}
+	 * @throws {TypeError} value is not a string
+	 * @throws {TypeError} value is not a function
+	 */
+	setCallback(name, callback) {
+		this[internalSymbol].callbacks.set(name, callback);
+		return this;
+	}
 }
 
 /**
@@ -224,22 +234,22 @@ class Updater extends Base {
  * @this Updater
  */
 function getCheckStateCallback() {
-    const self = this;
-
-    return function (current) {
-        // this is a reference to the current object (therefore no array function here)
-        if (this instanceof HTMLInputElement) {
-            if (["radio", "checkbox"].indexOf(this.type) !== -1) {
-                return `${this.value}` === `${current}` ? "true" : undefined;
-            }
-        } else if (this instanceof HTMLOptionElement) {
-            if (isArray(current) && current.indexOf(this.value) !== -1) {
-                return "true";
-            }
-
-            return undefined;
-        }
-    };
+	const self = this;
+
+	return function (current) {
+		// this is a reference to the current object (therefore no array function here)
+		if (this instanceof HTMLInputElement) {
+			if (["radio", "checkbox"].indexOf(this.type) !== -1) {
+				return `${this.value}` === `${current}` ? "true" : undefined;
+			}
+		} else if (this instanceof HTMLOptionElement) {
+			if (isArray(current) && current.indexOf(this.value) !== -1) {
+				return "true";
+			}
+
+			return undefined;
+		}
+	};
 }
 
 /**
@@ -254,28 +264,28 @@ const symbol = Symbol("@schukai/monster/updater@@EventHandler");
  * @throws {Error} the bind argument must start as a value with a path
  */
 function getControlEventHandler() {
-    const self = this;
+	const self = this;
 
-    if (self[symbol]) {
-        return self[symbol];
-    }
+	if (self[symbol]) {
+		return self[symbol];
+	}
 
-    /**
-     * @throws {Error} the bind argument must start as a value with a path.
-     * @throws {Error} unsupported object
-     * @param {Event} event
-     */
-    self[symbol] = (event) => {
-        const element = findTargetElementFromEvent(event, ATTRIBUTE_UPDATER_BIND);
+	/**
+	 * @throws {Error} the bind argument must start as a value with a path.
+	 * @throws {Error} unsupported object
+	 * @param {Event} event
+	 */
+	self[symbol] = (event) => {
+		const element = findTargetElementFromEvent(event, ATTRIBUTE_UPDATER_BIND);
 
-        if (element === undefined) {
-            return;
-        }
+		if (element === undefined) {
+			return;
+		}
 
-        retrieveAndSetValue.call(self, element);
-    };
+		retrieveAndSetValue.call(self, element);
+	};
 
-    return self[symbol];
+	return self[symbol];
 }
 
 /**
@@ -286,67 +296,72 @@ function getControlEventHandler() {
  * @private
  */
 function retrieveAndSetValue(element) {
-    const self = this;
-
-    const pathfinder = new Pathfinder(self[internalSymbol].subject.getSubject());
-
-    let path = element.getAttribute(ATTRIBUTE_UPDATER_BIND);
-    if (path === null) throw new Error("the bind argument must start as a value with a path");
-
-    if (path.indexOf("path:") !== 0) {
-        throw new Error("the bind argument must start as a value with a path");
-    }
-
-    path = path.substring(5);
-
-    let value;
-
-    if (element instanceof HTMLInputElement) {
-        switch (element.type) {
-            case "checkbox":
-                value = element.checked ? element.value : undefined;
-                break;
-            default:
-                value = element.value;
-                break;
-        }
-    } else if (element instanceof HTMLTextAreaElement) {
-        value = element.value;
-    } else if (element instanceof HTMLSelectElement) {
-        switch (element.type) {
-            case "select-one":
-                value = element.value;
-                break;
-            case "select-multiple":
-                value = element.value;
-
-                let options = element?.selectedOptions;
-                if (options === undefined) options = element.querySelectorAll(":scope option:checked");
-                value = Array.from(options).map(({ value }) => value);
-
-                break;
-        }
-
-        // values from customelements
-    } else if (
-        (element?.constructor?.prototype &&
-            !!Object.getOwnPropertyDescriptor(element.constructor.prototype, "value")?.["get"]) ||
-        element.hasOwnProperty("value")
-    ) {
-        value = element?.["value"];
-    } else {
-        throw new Error("unsupported object");
-    }
-
-    const copy = clone(self[internalSymbol].subject.getRealSubject());
-    const pf = new Pathfinder(copy);
-    pf.setVia(path, value);
-
-    const diffResult = diff(copy, self[internalSymbol].subject.getRealSubject());
-
-    if (diffResult.length > 0) {
-        pathfinder.setVia(path, value);
-    }
+	const self = this;
+
+	const pathfinder = new Pathfinder(self[internalSymbol].subject.getSubject());
+
+	let path = element.getAttribute(ATTRIBUTE_UPDATER_BIND);
+	if (path === null)
+		throw new Error("the bind argument must start as a value with a path");
+
+	if (path.indexOf("path:") !== 0) {
+		throw new Error("the bind argument must start as a value with a path");
+	}
+
+	path = path.substring(5);
+
+	let value;
+
+	if (element instanceof HTMLInputElement) {
+		switch (element.type) {
+			case "checkbox":
+				value = element.checked ? element.value : undefined;
+				break;
+			default:
+				value = element.value;
+				break;
+		}
+	} else if (element instanceof HTMLTextAreaElement) {
+		value = element.value;
+	} else if (element instanceof HTMLSelectElement) {
+		switch (element.type) {
+			case "select-one":
+				value = element.value;
+				break;
+			case "select-multiple":
+				value = element.value;
+
+				let options = element?.selectedOptions;
+				if (options === undefined)
+					options = element.querySelectorAll(":scope option:checked");
+				value = Array.from(options).map(({ value }) => value);
+
+				break;
+		}
+
+		// values from customelements
+	} else if (
+		(element?.constructor?.prototype &&
+			!!Object.getOwnPropertyDescriptor(
+				element.constructor.prototype,
+				"value",
+			)?.["get"]) ||
+		element.hasOwnProperty("value")
+	) {
+		value = element?.["value"];
+	} else {
+		throw new Error("unsupported object");
+	}
+
+	const copy = clone(self[internalSymbol].subject.getRealSubject());
+	const pf = new Pathfinder(copy);
+	pf.setVia(path, value);
+
+	const diffResult = diff(copy, self[internalSymbol].subject.getRealSubject());
+
+	if (diffResult.length > 0) {
+		pathfinder.setVia(path, value);
+	}
 }
 
 /**
@@ -356,15 +371,17 @@ function retrieveAndSetValue(element) {
  * @private
  */
 function retrieveFromBindings() {
-    const self = this;
+	const self = this;
 
-    if (self[internalSymbol].element.matches(`[${ATTRIBUTE_UPDATER_BIND}]`)) {
-        retrieveAndSetValue.call(self, self[internalSymbol].element);
-    }
+	if (self[internalSymbol].element.matches(`[${ATTRIBUTE_UPDATER_BIND}]`)) {
+		retrieveAndSetValue.call(self, self[internalSymbol].element);
+	}
 
-    for (const [, element] of self[internalSymbol].element.querySelectorAll(`[${ATTRIBUTE_UPDATER_BIND}]`).entries()) {
-        retrieveAndSetValue.call(self, element);
-    }
+	for (const [, element] of self[internalSymbol].element
+		.querySelectorAll(`[${ATTRIBUTE_UPDATER_BIND}]`)
+		.entries()) {
+		retrieveAndSetValue.call(self, element);
+	}
 }
 
 /**
@@ -375,13 +392,13 @@ function retrieveFromBindings() {
  * @return {void}
  */
 function removeElement(change) {
-    const self = this;
+	const self = this;
 
-    for (const [, element] of self[internalSymbol].element
-        .querySelectorAll(`:scope [${ATTRIBUTE_UPDATER_REMOVE}]`)
-        .entries()) {
-        element.parentNode.removeChild(element);
-    }
+	for (const [, element] of self[internalSymbol].element
+		.querySelectorAll(`:scope [${ATTRIBUTE_UPDATER_REMOVE}]`)
+		.entries()) {
+		element.parentNode.removeChild(element);
+	}
 }
 
 /**
@@ -397,124 +414,134 @@ function removeElement(change) {
  * @this Updater
  */
 function insertElement(change) {
-    const self = this;
-    const subject = self[internalSymbol].subject.getRealSubject();
+	const self = this;
+	const subject = self[internalSymbol].subject.getRealSubject();
 
-    let mem = new WeakSet();
-    let wd = 0;
+	let mem = new WeakSet();
+	let wd = 0;
 
-    const container = self[internalSymbol].element;
-
-    while (true) {
-        let found = false;
-        wd++;
-
-        let p = clone(change?.["path"]);
-        if (!isArray(p)) return self;
-
-        while (p.length > 0) {
-            const current = p.join(".");
-
-            let iterator = new Set();
-            const query = `[${ATTRIBUTE_UPDATER_INSERT}*="path:${current}"]`;
-
-            const e = container.querySelectorAll(query);
-
-            if (e.length > 0) {
-                iterator = new Set([...e]);
-            }
-
-            if (container.matches(query)) {
-                iterator.add(container);
-            }
-
-            for (const [, containerElement] of iterator.entries()) {
-                if (mem.has(containerElement)) continue;
-                mem.add(containerElement);
-
-                found = true;
-
-                const attributes = containerElement.getAttribute(ATTRIBUTE_UPDATER_INSERT);
-                if (attributes === null) continue;
-
-                let def = trimSpaces(attributes);
-                let i = def.indexOf(" ");
-                let key = trimSpaces(def.substr(0, i));
-                let refPrefix = `${key}-`;
-                let cmd = trimSpaces(def.substr(i));
-
-                // this case is actually excluded by the query but is nevertheless checked again here
-                if (cmd.indexOf("|") > 0) {
-                    throw new Error("pipes are not allowed when cloning a node.");
-                }
-
-                let pipe = new Pipe(cmd);
-                self[internalSymbol].callbacks.forEach((f, n) => {
-                    pipe.setCallback(n, f);
-                });
-
-                let value;
-                try {
-                    containerElement.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
-                    value = pipe.run(subject);
-                } catch (e) {
-                    containerElement.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message);
-                }
-
-                let dataPath = cmd.split(":").pop();
-
-                let insertPoint;
-                if (containerElement.hasChildNodes()) {
-                    insertPoint = containerElement.lastChild;
-                }
-
-                if (!isIterable(value)) {
-                    throw new Error("the value is not iterable");
-                }
-
-                let available = new Set();
-
-                for (const [i, obj] of Object.entries(value)) {
-                    let ref = refPrefix + i;
-                    let currentPath = `${dataPath}.${i}`;
-
-                    available.add(ref);
-                    let refElement = containerElement.querySelector(`[${ATTRIBUTE_UPDATER_INSERT_REFERENCE}="${ref}"]`);
-
-                    if (refElement instanceof HTMLElement) {
-                        insertPoint = refElement;
-                        continue;
-                    }
-
-                    appendNewDocumentFragment(containerElement, key, ref, currentPath);
-                }
-
-                let nodes = containerElement.querySelectorAll(
-                    `[${ATTRIBUTE_UPDATER_INSERT_REFERENCE}*="${refPrefix}"]`,
-                );
-
-                for (const [, node] of Object.entries(nodes)) {
-                    if (!available.has(node.getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE))) {
-                        try {
-                            containerElement.removeChild(node);
-                        } catch (e) {
-                            containerElement.setAttribute(
-                                ATTRIBUTE_ERRORMESSAGE,
-                                `${containerElement.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${e.message}`.trim(),
-                            );
-                        }
-                    }
-                }
-            }
-
-            p.pop();
-        }
-
-        if (found === false) break;
-        if (wd++ > 200) {
-            throw new Error("the maximum depth for the recursion is reached.");
-        }
-    }
+	const container = self[internalSymbol].element;
+
+	while (true) {
+		let found = false;
+		wd++;
+
+		let p = clone(change?.["path"]);
+		if (!isArray(p)) return self;
+
+		while (p.length > 0) {
+			const current = p.join(".");
+
+			let iterator = new Set();
+			const query = `[${ATTRIBUTE_UPDATER_INSERT}*="path:${current}"]`;
+
+			const e = container.querySelectorAll(query);
+
+			if (e.length > 0) {
+				iterator = new Set([...e]);
+			}
+
+			if (container.matches(query)) {
+				iterator.add(container);
+			}
+
+			for (const [, containerElement] of iterator.entries()) {
+				if (mem.has(containerElement)) continue;
+				mem.add(containerElement);
+
+				found = true;
+
+				const attributes = containerElement.getAttribute(
+					ATTRIBUTE_UPDATER_INSERT,
+				);
+				if (attributes === null) continue;
+
+				let def = trimSpaces(attributes);
+				let i = def.indexOf(" ");
+				let key = trimSpaces(def.substr(0, i));
+				let refPrefix = `${key}-`;
+				let cmd = trimSpaces(def.substr(i));
+
+				// this case is actually excluded by the query but is nevertheless checked again here
+				if (cmd.indexOf("|") > 0) {
+					throw new Error("pipes are not allowed when cloning a node.");
+				}
+
+				let pipe = new Pipe(cmd);
+				self[internalSymbol].callbacks.forEach((f, n) => {
+					pipe.setCallback(n, f);
+				});
+
+				let value;
+				try {
+					containerElement.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
+					value = pipe.run(subject);
+				} catch (e) {
+					containerElement.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message);
+				}
+
+				let dataPath = cmd.split(":").pop();
+
+				let insertPoint;
+				if (containerElement.hasChildNodes()) {
+					insertPoint = containerElement.lastChild;
+				}
+
+				if (!isIterable(value)) {
+					throw new Error("the value is not iterable");
+				}
+
+				let available = new Set();
+
+				for (const [i, obj] of Object.entries(value)) {
+					let ref = refPrefix + i;
+					let currentPath = `${dataPath}.${i}`;
+
+					available.add(ref);
+					let refElement = containerElement.querySelector(
+						`[${ATTRIBUTE_UPDATER_INSERT_REFERENCE}="${ref}"]`,
+					);
+
+					if (refElement instanceof HTMLElement) {
+						insertPoint = refElement;
+						continue;
+					}
+
+					appendNewDocumentFragment(containerElement, key, ref, currentPath);
+				}
+
+				let nodes = containerElement.querySelectorAll(
+					`[${ATTRIBUTE_UPDATER_INSERT_REFERENCE}*="${refPrefix}"]`,
+				);
+
+				for (const [, node] of Object.entries(nodes)) {
+					if (
+						!available.has(
+							node.getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE),
+						)
+					) {
+						try {
+							containerElement.removeChild(node);
+						} catch (e) {
+							containerElement.setAttribute(
+								ATTRIBUTE_ERRORMESSAGE,
+								`${containerElement.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${
+									e.message
+								}`.trim(),
+							);
+						}
+					}
+				}
+			}
+
+			p.pop();
+		}
+
+		if (found === false) break;
+		if (wd++ > 200) {
+			throw new Error("the maximum depth for the recursion is reached.");
+		}
+	}
 }
 
 /**
@@ -529,17 +556,17 @@ function insertElement(change) {
  * @throws {Error} no template was found with the specified key.
  */
 function appendNewDocumentFragment(container, key, ref, path) {
-    let template = findDocumentTemplate(key, container);
+	let template = findDocumentTemplate(key, container);
 
-    let nodes = template.createDocumentFragment();
-    for (const [, node] of Object.entries(nodes.childNodes)) {
-        if (node instanceof HTMLElement) {
-            applyRecursive(node, key, path);
-            node.setAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE, ref);
-        }
+	let nodes = template.createDocumentFragment();
+	for (const [, node] of Object.entries(nodes.childNodes)) {
+		if (node instanceof HTMLElement) {
+			applyRecursive(node, key, path);
+			node.setAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE, ref);
+		}
 
-        container.appendChild(node);
-    }
+		container.appendChild(node);
+	}
 }
 
 /**
@@ -552,21 +579,27 @@ function appendNewDocumentFragment(container, key, ref, path) {
  * @return {void}
  */
 function applyRecursive(node, key, path) {
-    if (node instanceof HTMLElement) {
-        if (node.hasAttribute(ATTRIBUTE_UPDATER_REPLACE)) {
-            let value = node.getAttribute(ATTRIBUTE_UPDATER_REPLACE);
-            node.setAttribute(ATTRIBUTE_UPDATER_REPLACE, value.replaceAll(`path:${key}`, `path:${path}`));
-        }
-
-        if (node.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) {
-            let value = node.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES);
-            node.setAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES, value.replaceAll(`path:${key}`, `path:${path}`));
-        }
-
-        for (const [, child] of Object.entries(node.childNodes)) {
-            applyRecursive(child, key, path);
-        }
-    }
+	if (node instanceof HTMLElement) {
+		if (node.hasAttribute(ATTRIBUTE_UPDATER_REPLACE)) {
+			let value = node.getAttribute(ATTRIBUTE_UPDATER_REPLACE);
+			node.setAttribute(
+				ATTRIBUTE_UPDATER_REPLACE,
+				value.replaceAll(`path:${key}`, `path:${path}`),
+			);
+		}
+
+		if (node.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) {
+			let value = node.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES);
+			node.setAttribute(
+				ATTRIBUTE_UPDATER_ATTRIBUTES,
+				value.replaceAll(`path:${key}`, `path:${path}`),
+			);
+		}
+
+		for (const [, child] of Object.entries(node.childNodes)) {
+			applyRecursive(child, key, path);
+		}
+	}
 }
 
 /**
@@ -578,20 +611,20 @@ function applyRecursive(node, key, path) {
  * @this Updater
  */
 function updateContent(change) {
-    const self = this;
-    const subject = self[internalSymbol].subject.getRealSubject();
-
-    let p = clone(change?.["path"]);
-    runUpdateContent.call(this, this[internalSymbol].element, p, subject);
-
-    const slots = this[internalSymbol].element.querySelectorAll("slot");
-    if (slots.length > 0) {
-        for (const [, slot] of Object.entries(slots)) {
-            for (const [, element] of Object.entries(slot.assignedNodes())) {
-                runUpdateContent.call(this, element, p, subject);
-            }
-        }
-    }
+	const self = this;
+	const subject = self[internalSymbol].subject.getRealSubject();
+
+	let p = clone(change?.["path"]);
+	runUpdateContent.call(this, this[internalSymbol].element, p, subject);
+
+	const slots = this[internalSymbol].element.querySelectorAll("slot");
+	if (slots.length > 0) {
+		for (const [, slot] of Object.entries(slots)) {
+			for (const [, element] of Object.entries(slot.assignedNodes())) {
+				runUpdateContent.call(this, element, p, subject);
+			}
+		}
+	}
 }
 
 /**
@@ -604,67 +637,69 @@ function updateContent(change) {
  * @return {void}
  */
 function runUpdateContent(container, parts, subject) {
-    if (!isArray(parts)) return;
-    if (!(container instanceof HTMLElement)) return;
-    parts = clone(parts);
-
-    let mem = new WeakSet();
-
-    while (parts.length > 0) {
-        const current = parts.join(".");
-        parts.pop();
-
-        // Unfortunately, static data is always changed as well, since it is not possible to react to changes here.
-        const query = `[${ATTRIBUTE_UPDATER_REPLACE}^="path:${current}"], [${ATTRIBUTE_UPDATER_REPLACE}^="static:"], [${ATTRIBUTE_UPDATER_REPLACE}^="i18n:"]`;
-        const e = container.querySelectorAll(`${query}`);
-
-        const iterator = new Set([...e]);
-
-        if (container.matches(query)) {
-            iterator.add(container);
-        }
-
-        /**
-         * @type {HTMLElement}
-         */
-        for (const [element] of iterator.entries()) {
-            if (mem.has(element)) return;
-            mem.add(element);
-
-            const attributes = element.getAttribute(ATTRIBUTE_UPDATER_REPLACE);
-            let cmd = trimSpaces(attributes);
-
-            let pipe = new Pipe(cmd);
-            this[internalSymbol].callbacks.forEach((f, n) => {
-                pipe.setCallback(n, f);
-            });
-
-            let value;
-            try {
-                element.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
-                value = pipe.run(subject);
-            } catch (e) {
-                element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message);
-            }
-
-            if (value instanceof HTMLElement) {
-                while (element.firstChild) {
-                    element.removeChild(element.firstChild);
-                }
-
-                try {
-                    element.appendChild(value);
-                } catch (e) {
-                    element.setAttribute(
-                        ATTRIBUTE_ERRORMESSAGE,
-                        `${element.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${e.message}`.trim(),
-                    );
-                }
-            } else {
-                element.innerHTML = value;
-            }
-        }
-    }
+	if (!isArray(parts)) return;
+	if (!(container instanceof HTMLElement)) return;
+	parts = clone(parts);
+
+	let mem = new WeakSet();
+
+	while (parts.length > 0) {
+		const current = parts.join(".");
+		parts.pop();
+
+		// Unfortunately, static data is always changed as well, since it is not possible to react to changes here.
+		const query = `[${ATTRIBUTE_UPDATER_REPLACE}^="path:${current}"], [${ATTRIBUTE_UPDATER_REPLACE}^="static:"], [${ATTRIBUTE_UPDATER_REPLACE}^="i18n:"]`;
+		const e = container.querySelectorAll(`${query}`);
+
+		const iterator = new Set([...e]);
+
+		if (container.matches(query)) {
+			iterator.add(container);
+		}
+
+		/**
+		 * @type {HTMLElement}
+		 */
+		for (const [element] of iterator.entries()) {
+			if (mem.has(element)) return;
+			mem.add(element);
+
+			const attributes = element.getAttribute(ATTRIBUTE_UPDATER_REPLACE);
+			let cmd = trimSpaces(attributes);
+
+			let pipe = new Pipe(cmd);
+			this[internalSymbol].callbacks.forEach((f, n) => {
+				pipe.setCallback(n, f);
+			});
+
+			let value;
+			try {
+				element.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
+				value = pipe.run(subject);
+			} catch (e) {
+				element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message);
+			}
+
+			if (value instanceof HTMLElement) {
+				while (element.firstChild) {
+					element.removeChild(element.firstChild);
+				}
+
+				try {
+					element.appendChild(value);
+				} catch (e) {
+					element.setAttribute(
+						ATTRIBUTE_ERRORMESSAGE,
+						`${element.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${
+							e.message
+						}`.trim(),
+					);
+				}
+			} else {
+				element.innerHTML = value;
+			}
+		}
+	}
 }
 
 /**
@@ -676,9 +711,9 @@ function runUpdateContent(container, parts, subject) {
  * @return {void}
  */
 function updateAttributes(change) {
-    const subject = this[internalSymbol].subject.getRealSubject();
-    let p = clone(change?.["path"]);
-    runUpdateAttributes.call(this, this[internalSymbol].element, p, subject);
+	const subject = this[internalSymbol].subject.getRealSubject();
+	let p = clone(change?.["path"]);
+	runUpdateAttributes.call(this, this[internalSymbol].element, p, subject);
 }
 
 /**
@@ -690,72 +725,72 @@ function updateAttributes(change) {
  * @this Updater
  */
 function runUpdateAttributes(container, parts, subject) {
-    const self = this;
+	const self = this;
 
-    if (!isArray(parts)) return;
-    parts = clone(parts);
+	if (!isArray(parts)) return;
+	parts = clone(parts);
 
-    let mem = new WeakSet();
+	let mem = new WeakSet();
 
-    while (parts.length > 0) {
-        const current = parts.join(".");
-        parts.pop();
+	while (parts.length > 0) {
+		const current = parts.join(".");
+		parts.pop();
 
-        let iterator = new Set();
+		let iterator = new Set();
 
-        const query = `[${ATTRIBUTE_UPDATER_SELECT_THIS}][${ATTRIBUTE_UPDATER_ATTRIBUTES}], [${ATTRIBUTE_UPDATER_ATTRIBUTES}*="path:${current}"], [${ATTRIBUTE_UPDATER_ATTRIBUTES}^="static:"], [${ATTRIBUTE_UPDATER_ATTRIBUTES}^="i18n:"]`;
+		const query = `[${ATTRIBUTE_UPDATER_SELECT_THIS}][${ATTRIBUTE_UPDATER_ATTRIBUTES}], [${ATTRIBUTE_UPDATER_ATTRIBUTES}*="path:${current}"], [${ATTRIBUTE_UPDATER_ATTRIBUTES}^="static:"], [${ATTRIBUTE_UPDATER_ATTRIBUTES}^="i18n:"]`;
 
-        const e = container.querySelectorAll(query);
+		const e = container.querySelectorAll(query);
 
-        if (e.length > 0) {
-            iterator = new Set([...e]);
-        }
+		if (e.length > 0) {
+			iterator = new Set([...e]);
+		}
 
-        if (container.matches(query)) {
-            iterator.add(container);
-        }
+		if (container.matches(query)) {
+			iterator.add(container);
+		}
 
-        for (const [element] of iterator.entries()) {
-            if (mem.has(element)) return;
-            mem.add(element);
+		for (const [element] of iterator.entries()) {
+			if (mem.has(element)) return;
+			mem.add(element);
 
-            // this case occurs when the ATTRIBUTE_UPDATER_SELECT_THIS attribute is set
-            if (!element.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) {
-                continue;
-            }
+			// this case occurs when the ATTRIBUTE_UPDATER_SELECT_THIS attribute is set
+			if (!element.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) {
+				continue;
+			}
 
-            const attributes = element.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES);
+			const attributes = element.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES);
 
-            for (let [, def] of Object.entries(attributes.split(","))) {
-                def = trimSpaces(def);
-                let i = def.indexOf(" ");
-                let name = trimSpaces(def.substr(0, i));
-                let cmd = trimSpaces(def.substr(i));
+			for (let [, def] of Object.entries(attributes.split(","))) {
+				def = trimSpaces(def);
+				let i = def.indexOf(" ");
+				let name = trimSpaces(def.substr(0, i));
+				let cmd = trimSpaces(def.substr(i));
 
-                let pipe = new Pipe(cmd);
+				let pipe = new Pipe(cmd);
 
-                self[internalSymbol].callbacks.forEach((f, n) => {
-                    pipe.setCallback(n, f, element);
-                });
+				self[internalSymbol].callbacks.forEach((f, n) => {
+					pipe.setCallback(n, f, element);
+				});
 
-                let value;
-                try {
-                    element.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
-                    value = pipe.run(subject);
-                } catch (e) {
-                    element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message);
-                }
+				let value;
+				try {
+					element.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
+					value = pipe.run(subject);
+				} catch (e) {
+					element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message);
+				}
 
-                if (value === undefined) {
-                    element.removeAttribute(name);
-                } else if (element.getAttribute(name) !== value) {
-                    element.setAttribute(name, value);
-                }
+				if (value === undefined) {
+					element.removeAttribute(name);
+				} else if (element.getAttribute(name) !== value) {
+					element.setAttribute(name, value);
+				}
 
-                handleInputControlAttributeUpdate.call(this, element, name, value);
-            }
-        }
-    }
+				handleInputControlAttributeUpdate.call(this, element, name, value);
+			}
+		}
+	}
 }
 
 /**
@@ -768,68 +803,68 @@ function runUpdateAttributes(container, parts, subject) {
  */
 
 function handleInputControlAttributeUpdate(element, name, value) {
-    const self = this;
-
-    if (element instanceof HTMLSelectElement) {
-        switch (element.type) {
-            case "select-multiple":
-                for (const [index, opt] of Object.entries(element.options)) {
-                    if (value.indexOf(opt.value) !== -1) {
-                        opt.selected = true;
-                    } else {
-                        opt.selected = false;
-                    }
-                }
-
-                break;
-            case "select-one":
-                // Only one value may be selected
-
-                for (const [index, opt] of Object.entries(element.options)) {
-                    if (opt.value === value) {
-                        element.selectedIndex = index;
-                        break;
-                    }
-                }
-
-                break;
-        }
-    } else if (element instanceof HTMLInputElement) {
-        switch (element.type) {
-            case "radio":
-                if (name === "checked") {
-                    if (value !== undefined) {
-                        element.checked = true;
-                    } else {
-                        element.checked = false;
-                    }
-                }
-
-                break;
-
-            case "checkbox":
-                if (name === "checked") {
-                    if (value !== undefined) {
-                        element.checked = true;
-                    } else {
-                        element.checked = false;
-                    }
-                }
-
-                break;
-            case "text":
-            default:
-                if (name === "value") {
-                    element.value = value === undefined ? "" : value;
-                }
-
-                break;
-        }
-    } else if (element instanceof HTMLTextAreaElement) {
-        if (name === "value") {
-            element.value = value === undefined ? "" : value;
-        }
-    }
+	const self = this;
+
+	if (element instanceof HTMLSelectElement) {
+		switch (element.type) {
+			case "select-multiple":
+				for (const [index, opt] of Object.entries(element.options)) {
+					if (value.indexOf(opt.value) !== -1) {
+						opt.selected = true;
+					} else {
+						opt.selected = false;
+					}
+				}
+
+				break;
+			case "select-one":
+				// Only one value may be selected
+
+				for (const [index, opt] of Object.entries(element.options)) {
+					if (opt.value === value) {
+						element.selectedIndex = index;
+						break;
+					}
+				}
+
+				break;
+		}
+	} else if (element instanceof HTMLInputElement) {
+		switch (element.type) {
+			case "radio":
+				if (name === "checked") {
+					if (value !== undefined) {
+						element.checked = true;
+					} else {
+						element.checked = false;
+					}
+				}
+
+				break;
+
+			case "checkbox":
+				if (name === "checked") {
+					if (value !== undefined) {
+						element.checked = true;
+					} else {
+						element.checked = false;
+					}
+				}
+
+				break;
+			case "text":
+			default:
+				if (name === "value") {
+					element.value = value === undefined ? "" : value;
+				}
+
+				break;
+		}
+	} else if (element instanceof HTMLTextAreaElement) {
+		if (name === "value") {
+			element.value = value === undefined ? "" : value;
+		}
+	}
 }
 
 /**
@@ -845,45 +880,49 @@ function handleInputControlAttributeUpdate(element, name, value) {
  * @throws {TypeError} symbol must be an instance of Symbol
  */
 function addObjectWithUpdaterToElement(elements, symbol, object) {
-    const self = this;
-    if (!(self instanceof HTMLElement)) {
-        throw new TypeError("the context of this function must be an instance of HTMLElement");
-    }
-
-    if (!(typeof symbol === "symbol")) {
-        throw new TypeError("symbol must be an instance of Symbol");
-    }
-
-    const updaters = new Set();
-
-    if (elements instanceof NodeList) {
-        elements = new Set([...elements]);
-    } else if (elements instanceof HTMLElement) {
-        elements = new Set([elements]);
-    } else if (elements instanceof Set) {
-    } else {
-        throw new TypeError(`elements is not a valid type. (actual: ${typeof elements})`);
-    }
-
-    let result = [];
-
-    elements.forEach((element) => {
-        if (!(element instanceof HTMLElement)) return;
-        if (element instanceof HTMLTemplateElement) return;
-
-        const u = new Updater(element, object);
-        updaters.add(u);
-
-        result.push(
-            u.run().then(() => {
-                return u.enableEventProcessing();
-            }),
-        );
-    });
-
-    if (updaters.size > 0) {
-        addToObjectLink(self, symbol, updaters);
-    }
-
-    return result;
+	const self = this;
+	if (!(self instanceof HTMLElement)) {
+		throw new TypeError(
+			"the context of this function must be an instance of HTMLElement",
+		);
+	}
+
+	if (!(typeof symbol === "symbol")) {
+		throw new TypeError("symbol must be an instance of Symbol");
+	}
+
+	const updaters = new Set();
+
+	if (elements instanceof NodeList) {
+		elements = new Set([...elements]);
+	} else if (elements instanceof HTMLElement) {
+		elements = new Set([elements]);
+	} else if (elements instanceof Set) {
+	} else {
+		throw new TypeError(
+			`elements is not a valid type. (actual: ${typeof elements})`,
+		);
+	}
+
+	let result = [];
+
+	elements.forEach((element) => {
+		if (!(element instanceof HTMLElement)) return;
+		if (element instanceof HTMLTemplateElement) return;
+
+		const u = new Updater(element, object);
+		updaters.add(u);
+
+		result.push(
+			u.run().then(() => {
+				return u.enableEventProcessing();
+			}),
+		);
+	});
+
+	if (updaters.size > 0) {
+		addToObjectLink(self, symbol, updaters);
+	}
+
+	return result;
 }
diff --git a/source/dom/util.mjs b/source/dom/util.mjs
index 7e7c2ff2f4c1b8f58203dc931e231511967fd5ca..d32d2252048469775e7f1bf70257a39aaf786e5b 100644
--- a/source/dom/util.mjs
+++ b/source/dom/util.mjs
@@ -8,7 +8,13 @@
 import { getGlobal } from "../types/global.mjs";
 import { validateString } from "../types/validate.mjs";
 
-export { getDocument, getWindow, getDocumentFragmentFromString, findElementWithIdUpwards, getContainingDocument };
+export {
+	getDocument,
+	getWindow,
+	getDocumentFragmentFromString,
+	findElementWithIdUpwards,
+	getContainingDocument,
+};
 
 /**
  * This method fetches the document object
@@ -48,12 +54,12 @@ export { getDocument, getWindow, getDocumentFragmentFromString, findElementWithI
  * @throws {Error} not supported environment
  */
 function getDocument() {
-    let document = getGlobal()?.["document"];
-    if (typeof document !== "object") {
-        throw new Error("not supported environment");
-    }
+	let document = getGlobal()?.["document"];
+	if (typeof document !== "object") {
+		throw new Error("not supported environment");
+	}
 
-    return document;
+	return document;
 }
 
 /**
@@ -96,12 +102,12 @@ function getDocument() {
  * @throws {Error} not supported environment
  */
 function getWindow() {
-    let window = getGlobal()?.["window"];
-    if (typeof window !== "object") {
-        throw new Error("not supported environment");
-    }
+	let window = getGlobal()?.["window"];
+	if (typeof window !== "object") {
+		throw new Error("not supported environment");
+	}
 
-    return window;
+	return window;
 }
 
 /**
@@ -143,13 +149,13 @@ function getWindow() {
  * @throws {TypeError} value is not a string
  */
 function getDocumentFragmentFromString(html) {
-    validateString(html);
+	validateString(html);
 
-    const document = getDocument();
-    const template = document.createElement("template");
-    template.innerHTML = html;
+	const document = getDocument();
+	const template = document.createElement("template");
+	template.innerHTML = html;
 
-    return template.content;
+	return template.content;
 }
 
 /**
@@ -165,39 +171,39 @@ function getDocumentFragmentFromString(html) {
  * @copyright schukai GmbH
  */
 function findElementWithIdUpwards(element, targetId) {
-    if (!element) {
-        return null;
-    }
-
-    // Check if the current element has the target ID
-    if (element.id === targetId) {
-        return element;
-    }
-
-    // Search within the current element's shadow root, if it exists
-    if (element.shadowRoot) {
-        const target = element.shadowRoot.getElementById(targetId);
-        if (target) {
-            return target;
-        }
-    }
-
-    // If the current element is the document.documentElement, search within the main document
-    if (element === document.documentElement) {
-        const target = document.getElementById(targetId);
-        if (target) {
-            return target;
-        }
-    }
-
-    // If the current element is inside a shadow root, search its host's ancestors
-    const rootNode = element.getRootNode();
-    if (rootNode && rootNode instanceof ShadowRoot) {
-        return findElementWithIdUpwards(rootNode.host, targetId);
-    }
-
-    // Otherwise, search the current element's parent
-    return findElementWithIdUpwards(element.parentElement, targetId);
+	if (!element) {
+		return null;
+	}
+
+	// Check if the current element has the target ID
+	if (element.id === targetId) {
+		return element;
+	}
+
+	// Search within the current element's shadow root, if it exists
+	if (element.shadowRoot) {
+		const target = element.shadowRoot.getElementById(targetId);
+		if (target) {
+			return target;
+		}
+	}
+
+	// If the current element is the document.documentElement, search within the main document
+	if (element === document.documentElement) {
+		const target = document.getElementById(targetId);
+		if (target) {
+			return target;
+		}
+	}
+
+	// If the current element is inside a shadow root, search its host's ancestors
+	const rootNode = element.getRootNode();
+	if (rootNode && rootNode instanceof ShadowRoot) {
+		return findElementWithIdUpwards(rootNode.host, targetId);
+	}
+
+	// Otherwise, search the current element's parent
+	return findElementWithIdUpwards(element.parentElement, targetId);
 }
 
 /**
@@ -206,30 +212,34 @@ function findElementWithIdUpwards(element, targetId) {
  * @returns {HTMLElement|null}
  */
 function traverseShadowRoots(element) {
-    let currentRoot = element.shadowRoot;
-    let currentParent = element.parentNode;
-
-    while (
-        currentParent &&
-        currentParent.nodeType !== Node.DOCUMENT_NODE &&
-        currentParent.nodeType !== Node.DOCUMENT_FRAGMENT_NODE
-    ) {
-        if (currentRoot && currentRoot.parentNode) {
-            currentParent = currentRoot.parentNode;
-            currentRoot = currentParent.shadowRoot;
-        } else if (currentParent.parentNode) {
-            currentParent = currentParent.parentNode;
-            currentRoot = null;
-        } else if (currentRoot && currentRoot.host && currentRoot.host.nodeType === Node.DOCUMENT_NODE) {
-            currentParent = currentRoot.host;
-            currentRoot = null;
-        } else {
-            currentParent = null;
-            currentRoot = null;
-        }
-    }
-
-    return currentParent;
+	let currentRoot = element.shadowRoot;
+	let currentParent = element.parentNode;
+
+	while (
+		currentParent &&
+		currentParent.nodeType !== Node.DOCUMENT_NODE &&
+		currentParent.nodeType !== Node.DOCUMENT_FRAGMENT_NODE
+	) {
+		if (currentRoot && currentRoot.parentNode) {
+			currentParent = currentRoot.parentNode;
+			currentRoot = currentParent.shadowRoot;
+		} else if (currentParent.parentNode) {
+			currentParent = currentParent.parentNode;
+			currentRoot = null;
+		} else if (
+			currentRoot &&
+			currentRoot.host &&
+			currentRoot.host.nodeType === Node.DOCUMENT_NODE
+		) {
+			currentParent = currentRoot.host;
+			currentRoot = null;
+		} else {
+			currentParent = null;
+			currentRoot = null;
+		}
+	}
+
+	return currentParent;
 }
 
 /**
@@ -242,12 +252,15 @@ function traverseShadowRoots(element) {
  * @since 3.36.0
  */
 function getContainingDocument(element) {
-    if (
-        !element ||
-        !(element instanceof HTMLElement || element instanceof element.ownerDocument.defaultView.HTMLElement)
-    ) {
-        throw new Error("Invalid argument. Expected an HTMLElement.");
-    }
-
-    return traverseShadowRoots(element) || null;
+	if (
+		!element ||
+		!(
+			element instanceof HTMLElement ||
+			element instanceof element.ownerDocument.defaultView.HTMLElement
+		)
+	) {
+		throw new Error("Invalid argument. Expected an HTMLElement.");
+	}
+
+	return traverseShadowRoots(element) || null;
 }
diff --git a/source/dom/util/extract-keys.mjs b/source/dom/util/extract-keys.mjs
index 976be3a30eb70cfc372051605eff6bc93293433b..399945438881a43ae908755579b95c68327a97b7 100644
--- a/source/dom/util/extract-keys.mjs
+++ b/source/dom/util/extract-keys.mjs
@@ -17,28 +17,40 @@ export { extractKeys };
  * @param {string} valueSeparator
  * @returns {Map<any, any>}
  */
-function extractKeys(obj, keyPrefix = "", keySeparator = "-", valueSeparator = ".") {
-    const resultMap = new Map();
+function extractKeys(
+	obj,
+	keyPrefix = "",
+	keySeparator = "-",
+	valueSeparator = ".",
+) {
+	const resultMap = new Map();
 
-    function helper(currentObj, currentKeyPrefix, currentValuePrefix) {
-        for (const key in currentObj) {
-            if (currentObj[key] !== null && typeof currentObj[key] === "object" && !Array.isArray(currentObj[key])) {
-                const newKeyPrefix = currentKeyPrefix
-                    ? currentKeyPrefix + keySeparator + key.toLowerCase()
-                    : key.toLowerCase();
-                const newValuePrefix = currentValuePrefix ? currentValuePrefix + valueSeparator + key : key;
-                helper(currentObj[key], newKeyPrefix, newValuePrefix);
-            } else {
-                const finalKey = currentKeyPrefix
-                    ? currentKeyPrefix + keySeparator + key.toLowerCase()
-                    : key.toLowerCase();
-                const finalValue = currentValuePrefix ? currentValuePrefix + valueSeparator + key : key;
-                resultMap.set(finalKey, finalValue);
-            }
-        }
-    }
+	function helper(currentObj, currentKeyPrefix, currentValuePrefix) {
+		for (const key in currentObj) {
+			if (
+				currentObj[key] !== null &&
+				typeof currentObj[key] === "object" &&
+				!Array.isArray(currentObj[key])
+			) {
+				const newKeyPrefix = currentKeyPrefix
+					? currentKeyPrefix + keySeparator + key.toLowerCase()
+					: key.toLowerCase();
+				const newValuePrefix = currentValuePrefix
+					? currentValuePrefix + valueSeparator + key
+					: key;
+				helper(currentObj[key], newKeyPrefix, newValuePrefix);
+			} else {
+				const finalKey = currentKeyPrefix
+					? currentKeyPrefix + keySeparator + key.toLowerCase()
+					: key.toLowerCase();
+				const finalValue = currentValuePrefix
+					? currentValuePrefix + valueSeparator + key
+					: key;
+				resultMap.set(finalKey, finalValue);
+			}
+		}
+	}
 
-    helper(obj, keyPrefix, keyPrefix);
-    return resultMap;
+	helper(obj, keyPrefix, keyPrefix);
+	return resultMap;
 }
-
diff --git a/source/dom/util/init-options-from-attributes.mjs b/source/dom/util/init-options-from-attributes.mjs
index e428dbcebbc34937cfe538d68f36e257149a80e4..6286f4c9fa5bff78bd98db4c73c07625383912ed 100644
--- a/source/dom/util/init-options-from-attributes.mjs
+++ b/source/dom/util/init-options-from-attributes.mjs
@@ -41,50 +41,58 @@ export { initOptionsFromAttributes };
  * @returns {Object} - The initialized options object.
  * @this HTMLElement - The context of the DOM element.
  */
-function initOptionsFromAttributes(element, options, mapping = {}, prefix = "data-monster-option-") {
-    if (!(element instanceof HTMLElement)) return options;
-    if (!element.hasAttributes()) return options;
+function initOptionsFromAttributes(
+	element,
+	options,
+	mapping = {},
+	prefix = "data-monster-option-",
+) {
+	if (!(element instanceof HTMLElement)) return options;
+	if (!element.hasAttributes()) return options;
 
-    const keyMap = extractKeys(options);
+	const keyMap = extractKeys(options);
 
-    const finder = new Pathfinder(options);
+	const finder = new Pathfinder(options);
 
-    element.getAttributeNames().forEach((name) => {
-        if (!name.startsWith(prefix)) return;
+	element.getAttributeNames().forEach((name) => {
+		if (!name.startsWith(prefix)) return;
 
-        // check if the attribute name is a valid option.
-        // the mapping between the attribute is simple. The dash is replaced by a dot.
-        // e.g. data-monster-url => url
-        const optionName = keyMap.get(name.substring(prefix.length).toLowerCase());
-        if (!finder.exists(optionName)) return;
+		// check if the attribute name is a valid option.
+		// the mapping between the attribute is simple. The dash is replaced by a dot.
+		// e.g. data-monster-url => url
+		const optionName = keyMap.get(name.substring(prefix.length).toLowerCase());
+		if (!finder.exists(optionName)) return;
 
-        if (element.hasAttribute(name)) {
-            let value = element.getAttribute(name);
-            if (mapping.hasOwnProperty(optionName) && isFunction(mapping[optionName])) {
-                value = mapping[optionName](value);
-            }
+		if (element.hasAttribute(name)) {
+			let value = element.getAttribute(name);
+			if (
+				mapping.hasOwnProperty(optionName) &&
+				isFunction(mapping[optionName])
+			) {
+				value = mapping[optionName](value);
+			}
 
-            let optionValue = finder.getVia(optionName);
-            if (optionValue === null || optionValue === undefined) {
-                optionValue = value;
-            }
-                
-            const typeOfOptionValue = typeof optionValue;
-            if (optionValue === null || optionValue === undefined) {
-                value = null;
-            } else if (typeOfOptionValue === "boolean") {
-                value = value === "true";
-            } else if (typeOfOptionValue === "number") {
-                value = Number(value);
-            } else if (typeOfOptionValue === "string") {
-                value = String(value);
-            } else if (typeOfOptionValue === "object") {
-                value = JSON.parse(value);
-            }
+			let optionValue = finder.getVia(optionName);
+			if (optionValue === null || optionValue === undefined) {
+				optionValue = value;
+			}
 
-            finder.setVia(optionName, value);
-        }
-    });
+			const typeOfOptionValue = typeof optionValue;
+			if (optionValue === null || optionValue === undefined) {
+				value = null;
+			} else if (typeOfOptionValue === "boolean") {
+				value = value === "true";
+			} else if (typeOfOptionValue === "number") {
+				value = Number(value);
+			} else if (typeOfOptionValue === "string") {
+				value = String(value);
+			} else if (typeOfOptionValue === "object") {
+				value = JSON.parse(value);
+			}
 
-    return options;
+			finder.setVia(optionName, value);
+		}
+	});
+
+	return options;
 }
diff --git a/source/dom/util/set-option-from-attribute.mjs b/source/dom/util/set-option-from-attribute.mjs
index 21448b1a83e6ce4a510ef5207522733ecb861db0..dd717e1eee33c07715c0c9fcd97be544add3595b 100644
--- a/source/dom/util/set-option-from-attribute.mjs
+++ b/source/dom/util/set-option-from-attribute.mjs
@@ -42,40 +42,46 @@ export { setOptionFromAttribute };
  * @returns {Object} - The initialized options object.
  * @this HTMLElement - The context of the DOM element.
  */
-function setOptionFromAttribute(element, name, options, mapping = {}, prefix = "data-monster-option-") {
-    if (!(element instanceof HTMLElement)) return options;
-    if (!element.hasAttributes()) return options;
+function setOptionFromAttribute(
+	element,
+	name,
+	options,
+	mapping = {},
+	prefix = "data-monster-option-",
+) {
+	if (!(element instanceof HTMLElement)) return options;
+	if (!element.hasAttributes()) return options;
 
-    const keyMap = extractKeys(options);
-    const finder = new Pathfinder(options);
+	const keyMap = extractKeys(options);
+	const finder = new Pathfinder(options);
 
-    // check if the attribute name is a valid option.
-    // the mapping between the attribute is simple. The dash is replaced by a dot.
-    // e.g. data-monster-url => url
-    const optionName = keyMap.get(name.substring(prefix.length).toLowerCase());
-    if (!finder.exists(optionName)) return;
+	// check if the attribute name is a valid option.
+	// the mapping between the attribute is simple. The dash is replaced by a dot.
+	// e.g. data-monster-url => url
+	const optionName = keyMap.get(name.substring(prefix.length).toLowerCase());
+	if (!finder.exists(optionName)) return;
 
-    if (!element.hasAttribute(name)) {
-        return options;
-    }
+	if (!element.hasAttribute(name)) {
+		return options;
+	}
 
-    let value = element.getAttribute(name);
-    if (mapping.hasOwnProperty(optionName) && isFunction(mapping[optionName])) {
-        value = mapping[optionName](value);
-    }
+	let value = element.getAttribute(name);
+	if (mapping.hasOwnProperty(optionName) && isFunction(mapping[optionName])) {
+		value = mapping[optionName](value);
+	}
 
-    const typeOfOptionValue = typeof finder.getVia(optionName);
-    if (typeOfOptionValue === "boolean") {
-        value = value === "true";
-    } else if (typeOfOptionValue === "number") {
-        value = Number(value);
-    } else if (typeOfOptionValue === "string") {
-        value = String(value);
-    } else if (typeOfOptionValue === "object") {
-        value = JSON.parse(value);
-    }
+	const typeOfOptionValue = typeof finder.getVia(optionName);
+	if (typeOfOptionValue === "boolean") {
+		value = value === "true";
+	} else if (typeOfOptionValue === "number") {
+		value = Number(value);
+	} else if (typeOfOptionValue === "string") {
+		value = String(value);
+	} else if (typeOfOptionValue === "object") {
+		value = JSON.parse(value);
+	}
 
-    finder.setVia(optionName, value);
+	finder.setVia(optionName, value);
 
-    return options;
+	return options;
 }
diff --git a/source/dom/worker/factory.mjs b/source/dom/worker/factory.mjs
index 85b1fad0f3e07dfe1b0731bc7f718aaa241a779f..3fb46982dfa1e07c7d64c431bcc479fa1e2e9d01 100644
--- a/source/dom/worker/factory.mjs
+++ b/source/dom/worker/factory.mjs
@@ -23,87 +23,87 @@ export { Factory };
  * @summary A small factory to create worker
  */
 class Factory extends Base {
-    /**
-     *
-     */
-    constructor() {
-        super();
-        this[internalSymbol] = {
-            worker: new WeakMap(),
-        };
-    }
-
-    /**
-     * Creates a worker from a URL
-     *
-     * @param {string|URL} url
-     * @param {function} messageHandler
-     * @param {function} errorHandler
-     * @return {Worker}
-     */
-    createFromURL = function (url, messageHandler, errorHandler) {
-        if (url instanceof URL) {
-            url = url.toString();
-        }
-
-        const workerClass = getGlobalFunction("Worker");
-        var worker = new workerClass(validateString(url));
-
-        if (isFunction(messageHandler)) {
-            worker.onmessage = (event) => {
-                messageHandler.call(worker, event);
-            };
-        }
-
-        if (isFunction(errorHandler)) {
-            worker.onerror = (event) => {
-                errorHandler.call(worker, event);
-            };
-        }
-
-        return worker;
-    };
-
-    /**
-     * Creates a worker from a script
-     *
-     * @param {string} content
-     * @param {function} messageHandler
-     * @param {function} errorHandler
-     * @return {Worker}
-     * @see https://developer.mozilla.org/de/docs/Web/API/URL/createObjectURL
-     */
-    createFromScript = function (content, messageHandler, errorHandler) {
-        const blobFunction = new getGlobalFunction("Blob");
-        const blob = new blobFunction([validateString(content)], {
-            type: "script/javascript",
-        });
-
-        const url = getGlobalFunction("URL").createObjectURL(blob);
-        const worker = this.createFromURL(url, messageHandler, errorHandler);
-
-        this[internalSymbol]["worker"].set(worker, url);
-
-        return worker;
-    };
-
-    /**
-     * Terminate the worker and call revokeObjectURL if necessary.
-     *
-     * @param worker
-     * @return {Monster.DOM.Worker.Factory}
-     */
-    terminate(worker) {
-        const workerClass = getGlobalFunction("Worker");
-        validateInstance(worker, workerClass);
-
-        worker.terminate();
-
-        if (this[internalSymbol]["worker"].has(worker)) {
-            const url = this[internalSymbol]["worker"].get(worker);
-            URL.revokeObjectURL(url);
-        }
-
-        return this;
-    }
+	/**
+	 *
+	 */
+	constructor() {
+		super();
+		this[internalSymbol] = {
+			worker: new WeakMap(),
+		};
+	}
+
+	/**
+	 * Creates a worker from a URL
+	 *
+	 * @param {string|URL} url
+	 * @param {function} messageHandler
+	 * @param {function} errorHandler
+	 * @return {Worker}
+	 */
+	createFromURL = function (url, messageHandler, errorHandler) {
+		if (url instanceof URL) {
+			url = url.toString();
+		}
+
+		const workerClass = getGlobalFunction("Worker");
+		var worker = new workerClass(validateString(url));
+
+		if (isFunction(messageHandler)) {
+			worker.onmessage = (event) => {
+				messageHandler.call(worker, event);
+			};
+		}
+
+		if (isFunction(errorHandler)) {
+			worker.onerror = (event) => {
+				errorHandler.call(worker, event);
+			};
+		}
+
+		return worker;
+	};
+
+	/**
+	 * Creates a worker from a script
+	 *
+	 * @param {string} content
+	 * @param {function} messageHandler
+	 * @param {function} errorHandler
+	 * @return {Worker}
+	 * @see https://developer.mozilla.org/de/docs/Web/API/URL/createObjectURL
+	 */
+	createFromScript = function (content, messageHandler, errorHandler) {
+		const blobFunction = new getGlobalFunction("Blob");
+		const blob = new blobFunction([validateString(content)], {
+			type: "script/javascript",
+		});
+
+		const url = getGlobalFunction("URL").createObjectURL(blob);
+		const worker = this.createFromURL(url, messageHandler, errorHandler);
+
+		this[internalSymbol]["worker"].set(worker, url);
+
+		return worker;
+	};
+
+	/**
+	 * Terminate the worker and call revokeObjectURL if necessary.
+	 *
+	 * @param worker
+	 * @return {Monster.DOM.Worker.Factory}
+	 */
+	terminate(worker) {
+		const workerClass = getGlobalFunction("Worker");
+		validateInstance(worker, workerClass);
+
+		worker.terminate();
+
+		if (this[internalSymbol]["worker"].has(worker)) {
+			const url = this[internalSymbol]["worker"].get(worker);
+			URL.revokeObjectURL(url);
+		}
+
+		return this;
+	}
 }
diff --git a/source/i18n/formatter.mjs b/source/i18n/formatter.mjs
index 2ea43acb0fd051b5fab348351e6d7a7865dc9108..e659698ca8c205452d91eca0f1954735b09ebee4 100644
--- a/source/i18n/formatter.mjs
+++ b/source/i18n/formatter.mjs
@@ -30,85 +30,88 @@ const internalTranslationSymbol = Symbol("internalTranslation");
  * @memberOf Monster.I18n
  */
 class Formatter extends TextFormatter {
-    /**
-     * Default values for the markers are `${` and `}`
-     *
-     * @param {object} object
-     * @throws {TypeError} value is not a object
-     */
-    constructor(object, translation, options) {
-        super(object, options);
-        this[internalTranslationSymbol] = validateInstance(translation, Translations);
-    }
+	/**
+	 * Default values for the markers are `${` and `}`
+	 *
+	 * @param {object} object
+	 * @throws {TypeError} value is not a object
+	 */
+	constructor(object, translation, options) {
+		super(object, options);
+		this[internalTranslationSymbol] = validateInstance(
+			translation,
+			Translations,
+		);
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 3.27.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/i18n/formatter@@instance");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 3.27.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/i18n/formatter@@instance");
+	}
 
-    /**
-     * @property {object} marker
-     * @property {array} marker.open=["i18n{","${"]
-     * @property {array} marker.close=["${"]
-     * @property {object} parameter
-     * @property {string} parameter.delimiter="::"
-     * @property {string} parameter.assignment="="
-     * @property {object} callbacks
-     * @property {function} callbacks.i18n=()=>{}
-     */
-    get defaults() {
-        const self = this;
-        return extend({}, super.defaults, {
-            callbacks: {
-                i18n: (value) => {
-                    return self[internalTranslationSymbol].getText(validateString(value));
-                },
-            },
-            marker: {
-                open: ["i18n{", "${"],
-                close: ["}"],
-            },
-        });
-    }
+	/**
+	 * @property {object} marker
+	 * @property {array} marker.open=["i18n{","${"]
+	 * @property {array} marker.close=["${"]
+	 * @property {object} parameter
+	 * @property {string} parameter.delimiter="::"
+	 * @property {string} parameter.assignment="="
+	 * @property {object} callbacks
+	 * @property {function} callbacks.i18n=()=>{}
+	 */
+	get defaults() {
+		const self = this;
+		return extend({}, super.defaults, {
+			callbacks: {
+				i18n: (value) => {
+					return self[internalTranslationSymbol].getText(validateString(value));
+				},
+			},
+			marker: {
+				open: ["i18n{", "${"],
+				close: ["}"],
+			},
+		});
+	}
 
-    /**
-     *
-     * @param {string} text
-     * @return {string}
-     * @throws {TypeError} value is not a string
-     * @throws {Error} too deep nesting
-     * @throws {Error} key not found
-     * @throws {Error} the closing marker is missing
-     */
-    format(text) {
-        validateString(text);
+	/**
+	 *
+	 * @param {string} text
+	 * @return {string}
+	 * @throws {TypeError} value is not a string
+	 * @throws {Error} too deep nesting
+	 * @throws {Error} key not found
+	 * @throws {Error} the closing marker is missing
+	 */
+	format(text) {
+		validateString(text);
 
-        const openMarker = this[internalSymbol]["marker"]["open"]?.[0];
-        const closeMarker = this[internalSymbol]["marker"]["close"]?.[0];
+		const openMarker = this[internalSymbol]["marker"]["open"]?.[0];
+		const closeMarker = this[internalSymbol]["marker"]["close"]?.[0];
 
-        if (text.indexOf(openMarker) === 0) {
-            text = text.substring(openMarker.length);
+		if (text.indexOf(openMarker) === 0) {
+			text = text.substring(openMarker.length);
 
-            if (text.indexOf(closeMarker) === text.length - closeMarker.length) {
-                text = text.substring(0, text.length - closeMarker.length);
-            } else {
-                throw new Error("the closing marker is missing");
-            }
-        }
+			if (text.indexOf(closeMarker) === text.length - closeMarker.length) {
+				text = text.substring(0, text.length - closeMarker.length);
+			} else {
+				throw new Error("the closing marker is missing");
+			}
+		}
 
-        const parts = validateString(text).split("::");
-        const translationKey = parts.shift().trim(); // key value delimiter
-        const parameter = parts.join("::").trim();
+		const parts = validateString(text).split("::");
+		const translationKey = parts.shift().trim(); // key value delimiter
+		const parameter = parts.join("::").trim();
 
-        let assembledText = `${openMarker}static:${translationKey} | call:i18n`;
-        if (parameter.length > 0) {
-            assembledText += `::${parameter}`;
-        }
-        assembledText += closeMarker;
-        return super.format(assembledText);
-    }
+		let assembledText = `${openMarker}static:${translationKey} | call:i18n`;
+		if (parameter.length > 0) {
+			assembledText += `::${parameter}`;
+		}
+		assembledText += closeMarker;
+		return super.format(assembledText);
+	}
 }
diff --git a/source/i18n/locale.mjs b/source/i18n/locale.mjs
index 2511ba9c507325da3c4c3099956034ecba240f56..3f9adc9d11a410d994521c55130062ce47a505e4 100644
--- a/source/i18n/locale.mjs
+++ b/source/i18n/locale.mjs
@@ -65,115 +65,116 @@ const localeStringSymbol = Symbol("localeString");
  * @see https://datatracker.ietf.org/doc/html/rfc3066
  */
 class Locale extends Base {
-    /**
-     * @param {string} language
-     * @param {string} [region]
-     * @param {string} [script]
-     * @param {string} [variants]
-     * @param {string} [extlang]
-     * @param {string} [privateUse]
-     * @throws {Error} unsupported locale
-     */
-    constructor(language, region, script, variants, extlang, privateUse) {
-        super();
+	/**
+	 * @param {string} language
+	 * @param {string} [region]
+	 * @param {string} [script]
+	 * @param {string} [variants]
+	 * @param {string} [extlang]
+	 * @param {string} [privateUse]
+	 * @throws {Error} unsupported locale
+	 */
+	constructor(language, region, script, variants, extlang, privateUse) {
+		super();
 
-        this[propertiesSymbol] = {
-            language: language === undefined ? undefined : validateString(language),
-            script: script === undefined ? undefined : validateString(script),
-            region: region === undefined ? undefined : validateString(region),
-            variants: variants === undefined ? undefined : validateString(variants),
-            extlang: extlang === undefined ? undefined : validateString(extlang),
-            privateUse: privateUse === undefined ? undefined : validateString(privateUse),
-        };
+		this[propertiesSymbol] = {
+			language: language === undefined ? undefined : validateString(language),
+			script: script === undefined ? undefined : validateString(script),
+			region: region === undefined ? undefined : validateString(region),
+			variants: variants === undefined ? undefined : validateString(variants),
+			extlang: extlang === undefined ? undefined : validateString(extlang),
+			privateUse:
+				privateUse === undefined ? undefined : validateString(privateUse),
+		};
 
-        let s = [];
-        if (language !== undefined) s.push(language);
-        if (script !== undefined) s.push(script);
-        if (region !== undefined) s.push(region);
-        if (variants !== undefined) s.push(variants);
-        if (extlang !== undefined) s.push(extlang);
-        if (privateUse !== undefined) s.push(privateUse);
+		let s = [];
+		if (language !== undefined) s.push(language);
+		if (script !== undefined) s.push(script);
+		if (region !== undefined) s.push(region);
+		if (variants !== undefined) s.push(variants);
+		if (extlang !== undefined) s.push(extlang);
+		if (privateUse !== undefined) s.push(privateUse);
 
-        if (s.length === 0) {
-            throw new Error("unsupported locale");
-        }
+		if (s.length === 0) {
+			throw new Error("unsupported locale");
+		}
 
-        this[localeStringSymbol] = s.join("-");
-    }
+		this[localeStringSymbol] = s.join("-");
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 3.27.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/i18n/locale@@instance");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 3.27.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/i18n/locale@@instance");
+	}
 
-    /**
-     * @return {string}
-     */
-    get localeString() {
-        return this[localeStringSymbol];
-    }
+	/**
+	 * @return {string}
+	 */
+	get localeString() {
+		return this[localeStringSymbol];
+	}
 
-    /**
-     * @return {string|undefined}
-     */
-    get language() {
-        return this[propertiesSymbol].language;
-    }
+	/**
+	 * @return {string|undefined}
+	 */
+	get language() {
+		return this[propertiesSymbol].language;
+	}
 
-    /**
-     * @return {string|undefined}
-     */
-    get region() {
-        return this[propertiesSymbol].region;
-    }
+	/**
+	 * @return {string|undefined}
+	 */
+	get region() {
+		return this[propertiesSymbol].region;
+	}
 
-    /**
-     * @return {string|undefined}
-     */
-    get script() {
-        return this[propertiesSymbol].script;
-    }
+	/**
+	 * @return {string|undefined}
+	 */
+	get script() {
+		return this[propertiesSymbol].script;
+	}
 
-    /**
-     * @return {string|undefined}
-     */
-    get variants() {
-        return this[propertiesSymbol].variants;
-    }
+	/**
+	 * @return {string|undefined}
+	 */
+	get variants() {
+		return this[propertiesSymbol].variants;
+	}
 
-    /**
-     * @return {string|undefined}
-     */
-    get extlang() {
-        return this[propertiesSymbol].extlang;
-    }
+	/**
+	 * @return {string|undefined}
+	 */
+	get extlang() {
+		return this[propertiesSymbol].extlang;
+	}
 
-    /**
-     * @return {string|undefined}
-     */
-    get privateUse() {
-        return this[propertiesSymbol].privateValue;
-    }
+	/**
+	 * @return {string|undefined}
+	 */
+	get privateUse() {
+		return this[propertiesSymbol].privateValue;
+	}
 
-    /**
-     * @return {string}
-     */
-    toString() {
-        return `${this.localeString}`;
-    }
+	/**
+	 * @return {string}
+	 */
+	toString() {
+		return `${this.localeString}`;
+	}
 
-    /**
-     * The structure has the following: language, script, region, variants, extlang, privateUse
-     *
-     * @return {Monster.I18n.LocaleMap}
-     */
-    getMap() {
-        return clone(this[propertiesSymbol]);
-    }
+	/**
+	 * The structure has the following: language, script, region, variants, extlang, privateUse
+	 *
+	 * @return {Monster.I18n.LocaleMap}
+	 */
+	getMap() {
+		return clone(this[propertiesSymbol]);
+	}
 }
 
 /**
@@ -257,62 +258,63 @@ class Locale extends Base {
  * @throws {Error} unsupported locale
  */
 function parseLocale(locale) {
-    locale = validateString(locale).replace(/_/g, "-");
+	locale = validateString(locale).replace(/_/g, "-");
 
-    let language;
-    let region;
-    let variants;
-    let parts;
-    let script;
-    let extlang;
-    let regexRegular = "(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang)";
-    let regexIrregular =
-        "(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)";
-    let regexGrandfathered = `(${regexIrregular}|${regexRegular})`;
-    let regexPrivateUse = "(x(-[A-Za-z0-9]{1,8})+)";
-    let regexSingleton = "[0-9A-WY-Za-wy-z]";
-    let regexExtension = `(${regexSingleton}(-[A-Za-z0-9]{2,8})+)`;
-    let regexVariant = "([A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3})";
-    let regexRegion = "([A-Za-z]{2}|[0-9]{3})";
-    let regexScript = "([A-Za-z]{4})";
-    let regexExtlang = "([A-Za-z]{3}(-[A-Za-z]{3}){0,2})";
-    let regexLanguage = `(([A-Za-z]{2,3}(-${regexExtlang})?)|[A-Za-z]{4}|[A-Za-z]{5,8})`;
-    let regexLangtag = `(${regexLanguage}(-${regexScript})?(-${regexRegion})?(-${regexVariant})*(-${regexExtension})*(-${regexPrivateUse})?)`;
-    let regexLanguageTag = `^(${regexGrandfathered}|${regexLangtag}|${regexPrivateUse})$`;
-    let regex = new RegExp(regexLanguageTag);
-    let match;
+	let language;
+	let region;
+	let variants;
+	let parts;
+	let script;
+	let extlang;
+	let regexRegular =
+		"(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang)";
+	let regexIrregular =
+		"(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)";
+	let regexGrandfathered = `(${regexIrregular}|${regexRegular})`;
+	let regexPrivateUse = "(x(-[A-Za-z0-9]{1,8})+)";
+	let regexSingleton = "[0-9A-WY-Za-wy-z]";
+	let regexExtension = `(${regexSingleton}(-[A-Za-z0-9]{2,8})+)`;
+	let regexVariant = "([A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3})";
+	let regexRegion = "([A-Za-z]{2}|[0-9]{3})";
+	let regexScript = "([A-Za-z]{4})";
+	let regexExtlang = "([A-Za-z]{3}(-[A-Za-z]{3}){0,2})";
+	let regexLanguage = `(([A-Za-z]{2,3}(-${regexExtlang})?)|[A-Za-z]{4}|[A-Za-z]{5,8})`;
+	let regexLangtag = `(${regexLanguage}(-${regexScript})?(-${regexRegion})?(-${regexVariant})*(-${regexExtension})*(-${regexPrivateUse})?)`;
+	let regexLanguageTag = `^(${regexGrandfathered}|${regexLangtag}|${regexPrivateUse})$`;
+	let regex = new RegExp(regexLanguageTag);
+	let match;
 
-    if ((match = regex.exec(locale)) !== null) {
-        if (match.index === regex.lastIndex) {
-            regex.lastIndex++;
-        }
-    }
+	if ((match = regex.exec(locale)) !== null) {
+		if (match.index === regex.lastIndex) {
+			regex.lastIndex++;
+		}
+	}
 
-    if (match === undefined || match === null) {
-        throw new Error("unsupported locale");
-    }
+	if (match === undefined || match === null) {
+		throw new Error("unsupported locale");
+	}
 
-    if (match[6] !== undefined) {
-        language = match[6];
+	if (match[6] !== undefined) {
+		language = match[6];
 
-        parts = language.split("-");
-        if (parts.length > 1) {
-            language = parts[0];
-            extlang = parts[1];
-        }
-    }
+		parts = language.split("-");
+		if (parts.length > 1) {
+			language = parts[0];
+			extlang = parts[1];
+		}
+	}
 
-    if (match[14] !== undefined) {
-        region = match[14];
-    }
+	if (match[14] !== undefined) {
+		region = match[14];
+	}
 
-    if (match[12] !== undefined) {
-        script = match[12];
-    }
+	if (match[12] !== undefined) {
+		script = match[12];
+	}
 
-    if (match[16] !== undefined) {
-        variants = match[16];
-    }
+	if (match[16] !== undefined) {
+		variants = match[16];
+	}
 
-    return new Locale(language, region, script, variants, extlang);
+	return new Locale(language, region, script, variants, extlang);
 }
diff --git a/source/i18n/provider.mjs b/source/i18n/provider.mjs
index 8a5207d63b50ff3ea57eca066a188305e6483d96..a33e787a1e6004450e7f35bbe4e3133368b2ef61 100644
--- a/source/i18n/provider.mjs
+++ b/source/i18n/provider.mjs
@@ -6,7 +6,11 @@
  */
 
 import { instanceSymbol } from "../constants.mjs";
-import { hasObjectLink, getLinkedObjects, addToObjectLink } from "../dom/attributes.mjs";
+import {
+	hasObjectLink,
+	getLinkedObjects,
+	addToObjectLink,
+} from "../dom/attributes.mjs";
 import { getLocaleOfDocument } from "../dom/locale.mjs";
 import { BaseWithOptions } from "../types/basewithoptions.mjs";
 import { Locale } from "./locale.mjs";
@@ -21,7 +25,9 @@ export { Provider, translationsLinkSymbol };
  * @since 3.9.0
  * @private
  */
-const translationsLinkSymbol = Symbol.for("@schukai/monster/i18n/translations@@link");
+const translationsLinkSymbol = Symbol.for(
+	"@schukai/monster/i18n/translations@@link",
+);
 
 /**
  * A provider makes a translation object available.
@@ -33,76 +39,76 @@ const translationsLinkSymbol = Symbol.for("@schukai/monster/i18n/translations@@l
  * @see {@link https://datatracker.ietf.org/doc/html/rfc3066}
  */
 class Provider extends BaseWithOptions {
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 3.27.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/i18n/provider@@instance");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 3.27.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/i18n/provider@@instance");
+	}
 
-    /**
-     * @param {Locale|string} locale
-     * @return {Promise}
-     */
-    getTranslations(locale) {
-        if (locale === undefined) {
-            locale = getLocaleOfDocument();
-        }
+	/**
+	 * @param {Locale|string} locale
+	 * @return {Promise}
+	 */
+	getTranslations(locale) {
+		if (locale === undefined) {
+			locale = getLocaleOfDocument();
+		}
 
-        return new Promise((resolve, reject) => {
-            try {
-                resolve(new Translations(locale));
-            } catch (e) {
-                reject(e);
-            }
-        });
-    }
+		return new Promise((resolve, reject) => {
+			try {
+				resolve(new Translations(locale));
+			} catch (e) {
+				reject(e);
+			}
+		});
+	}
 
-    /**
-     * @param {Locale|string} locale
-     * @param {HTMLElement} element
-     * @return {Provider}
-     */
-    assignToElement(locale, element) {
-        if (locale === undefined) {
-            locale = getLocaleOfDocument();
-        }
+	/**
+	 * @param {Locale|string} locale
+	 * @param {HTMLElement} element
+	 * @return {Provider}
+	 */
+	assignToElement(locale, element) {
+		if (locale === undefined) {
+			locale = getLocaleOfDocument();
+		}
 
-        if (!(locale instanceof Locale)) {
-            throw new Error("Locale is not an instance of Locale");
-        }
+		if (!(locale instanceof Locale)) {
+			throw new Error("Locale is not an instance of Locale");
+		}
 
-        if (!(element instanceof HTMLElement)) {
-            element = document.querySelector("body");
-        }
+		if (!(element instanceof HTMLElement)) {
+			element = document.querySelector("body");
+		}
 
-        if (!(element instanceof HTMLElement)) {
-            throw new Error("Element is not an HTMLElement");
-        }
+		if (!(element instanceof HTMLElement)) {
+			throw new Error("Element is not an HTMLElement");
+		}
 
-        return this.getTranslations(locale).then((obj) => {
-            let translations = null;
-            if (hasObjectLink(element, translationsLinkSymbol)) {
-                const objects = getLinkedObjects(element, translationsLinkSymbol);
-                for (const o of objects) {
-                    if (o instanceof Translations) {
-                        translations = o;
-                        break;
-                    }
-                }
+		return this.getTranslations(locale).then((obj) => {
+			let translations = null;
+			if (hasObjectLink(element, translationsLinkSymbol)) {
+				const objects = getLinkedObjects(element, translationsLinkSymbol);
+				for (const o of objects) {
+					if (o instanceof Translations) {
+						translations = o;
+						break;
+					}
+				}
 
-                if (!(translations instanceof Translations)) {
-                    throw new Error("Object is not an instance of Translations");
-                }
+				if (!(translations instanceof Translations)) {
+					throw new Error("Object is not an instance of Translations");
+				}
 
-                translations.assignTranslations(obj);
-            } else {
-                addToObjectLink(element, translationsLinkSymbol, obj);
-            }
+				translations.assignTranslations(obj);
+			} else {
+				addToObjectLink(element, translationsLinkSymbol, obj);
+			}
 
-            return obj;
-        });
-    }
+			return obj;
+		});
+	}
 }
diff --git a/source/i18n/providers/embed.mjs b/source/i18n/providers/embed.mjs
index 00744830d700df57e1544eec9fbd5acae1bac650..79e49ea54dc66eab2ac186a682f06c942c0137b5 100644
--- a/source/i18n/providers/embed.mjs
+++ b/source/i18n/providers/embed.mjs
@@ -28,131 +28,140 @@ export { Embed };
  * @tutorial i18n-locale-and-formatter
  */
 class Embed extends Provider {
-    /**
-     * ```html
-     * <script id="translations" type="application/json">
-     * {
-     *     "hello": "Hallo"
-     * }
-     * </script>
-     * ```
-     *
-     *
-     * ```javascript
-     * new Embed('translations')
-     * ```
-     *
-     * @param {HTMLElement|string} elementOrId
-     * @param {Object} options
-     */
-    constructor(elementOrId, options) {
-        super(options);
-
-        if (options === undefined) {
-            options = {};
-        }
-
-        if (elementOrId instanceof HTMLElement) {
-            /**
-             * @property {HTMLElement|string}
-             */
-            this.translateElement = elementOrId;
-        } else {
-            /**
-             * @property {HTMLElement|string}
-             */
-            this.translateElement = getDocument().getElementById(validateString(elementOrId));
-        }
-
-        /**
-         * @private
-         * @property {Object} options
-         */
-        this[internalSymbol] = extend({}, super.defaults, this.defaults, validateObject(options));
-    }
-
-    /**
-     * Defaults
-     *
-     * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API}
-     */
-    get defaults() {
-        return extend({}, super.defaults);
-    }
-
-    /**
-     *
-     * @param {Locale|string} locale
-     * @return {Promise}
-     */
-    getTranslations(locale) {
-        if (isString(locale)) {
-            locale = parseLocale(locale);
-        }
-
-        return new Promise((resolve, reject) => {
-            if (this.translateElement === null) {
-                reject(new Error("Text not found"));
-                return;
-            }
-
-            if (!(this.translateElement instanceof HTMLScriptElement)) {
-                reject(new Error("Element is not a script tag"));
-                return;
-            }
-
-            if (this.translateElement.type !== "application/json") {
-                reject(new Error("Element is not a script tag with type application/json"));
-                return;
-            }
-
-            let translations = null;
-            try {
-                translations = JSON.parse(this.translateElement.innerHTML.trim());
-            } catch (e) {
-                reject(e);
-                return;
-            }
-
-            if (translations === null) {
-                reject(new Error("Translations not found or invalid"));
-                return;
-            }
-
-            const t = new Translations(locale);
-            t.assignTranslations(translations);
-
-            resolve(t);
-        });
-    }
-
-    /**
-     * Initializes the translations for the current document.
-     *
-     * `script[data-monster-role=translations]` is searched for and the translations are assigned to the element.
-     *
-     * @param element
-     * @returns {Promise<unknown[]>}
-     */
-    static assignTranslationsToElement(element) {
-        const d = getDocument();
-
-        if (!(element instanceof HTMLElement)) {
-            element = d.querySelector("body");
-        }
-
-        const list = d.querySelectorAll("script[data-monster-role=translations]");
-        if (list === null) {
-            return;
-        }
-
-        const promises = [];
-
-        list.forEach((translationElement) => {
-            const p = new Embed(translationElement);
-            promises.push(p.assignToElement(undefined, element));
-        });
-
-        return Promise.all(promises);
-    }
+	/**
+	 * ```html
+	 * <script id="translations" type="application/json">
+	 * {
+	 *     "hello": "Hallo"
+	 * }
+	 * </script>
+	 * ```
+	 *
+	 *
+	 * ```javascript
+	 * new Embed('translations')
+	 * ```
+	 *
+	 * @param {HTMLElement|string} elementOrId
+	 * @param {Object} options
+	 */
+	constructor(elementOrId, options) {
+		super(options);
+
+		if (options === undefined) {
+			options = {};
+		}
+
+		if (elementOrId instanceof HTMLElement) {
+			/**
+			 * @property {HTMLElement|string}
+			 */
+			this.translateElement = elementOrId;
+		} else {
+			/**
+			 * @property {HTMLElement|string}
+			 */
+			this.translateElement = getDocument().getElementById(
+				validateString(elementOrId),
+			);
+		}
+
+		/**
+		 * @private
+		 * @property {Object} options
+		 */
+		this[internalSymbol] = extend(
+			{},
+			super.defaults,
+			this.defaults,
+			validateObject(options),
+		);
+	}
+
+	/**
+	 * Defaults
+	 *
+	 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API}
+	 */
+	get defaults() {
+		return extend({}, super.defaults);
+	}
+
+	/**
+	 *
+	 * @param {Locale|string} locale
+	 * @return {Promise}
+	 */
+	getTranslations(locale) {
+		if (isString(locale)) {
+			locale = parseLocale(locale);
+		}
+
+		return new Promise((resolve, reject) => {
+			if (this.translateElement === null) {
+				reject(new Error("Text not found"));
+				return;
+			}
+
+			if (!(this.translateElement instanceof HTMLScriptElement)) {
+				reject(new Error("Element is not a script tag"));
+				return;
+			}
+
+			if (this.translateElement.type !== "application/json") {
+				reject(
+					new Error("Element is not a script tag with type application/json"),
+				);
+				return;
+			}
+
+			let translations = null;
+			try {
+				translations = JSON.parse(this.translateElement.innerHTML.trim());
+			} catch (e) {
+				reject(e);
+				return;
+			}
+
+			if (translations === null) {
+				reject(new Error("Translations not found or invalid"));
+				return;
+			}
+
+			const t = new Translations(locale);
+			t.assignTranslations(translations);
+
+			resolve(t);
+		});
+	}
+
+	/**
+	 * Initializes the translations for the current document.
+	 *
+	 * `script[data-monster-role=translations]` is searched for and the translations are assigned to the element.
+	 *
+	 * @param element
+	 * @returns {Promise<unknown[]>}
+	 */
+	static assignTranslationsToElement(element) {
+		const d = getDocument();
+
+		if (!(element instanceof HTMLElement)) {
+			element = d.querySelector("body");
+		}
+
+		const list = d.querySelectorAll("script[data-monster-role=translations]");
+		if (list === null) {
+			return;
+		}
+
+		const promises = [];
+
+		list.forEach((translationElement) => {
+			const p = new Embed(translationElement);
+			promises.push(p.assignToElement(undefined, element));
+		});
+
+		return Promise.all(promises);
+	}
 }
diff --git a/source/i18n/providers/fetch.mjs b/source/i18n/providers/fetch.mjs
index d0e4163e9cc330c49280216f6102051cd31b7290..266e51b7ac2eded4671a3bcab4249c39f3406e40 100644
--- a/source/i18n/providers/fetch.mjs
+++ b/source/i18n/providers/fetch.mjs
@@ -29,89 +29,97 @@ export { Fetch };
  * @tutorial i18n-locale-and-formatter
  */
 class Fetch extends Provider {
-    /**
-     * As options the key `fetch` can be passed. This config object is passed to the fetch method as init.
-     *
-     * The url may contain placeholders (language, script, region, variants, extlang, privateUse), so you can specify one url for all translations.
-     *
-     * ```
-     * new Fetch('https://www.example.com/assets/${language}.json')
-     * ```
-     *
-     * @param {string|URL} url
-     * @param {Object} options see {@link Monster.I18n.Providers.Fetch#defaults}
-     * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/fetch}
-     */
-    constructor(url, options) {
-        super(options);
+	/**
+	 * As options the key `fetch` can be passed. This config object is passed to the fetch method as init.
+	 *
+	 * The url may contain placeholders (language, script, region, variants, extlang, privateUse), so you can specify one url for all translations.
+	 *
+	 * ```
+	 * new Fetch('https://www.example.com/assets/${language}.json')
+	 * ```
+	 *
+	 * @param {string|URL} url
+	 * @param {Object} options see {@link Monster.I18n.Providers.Fetch#defaults}
+	 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/fetch}
+	 */
+	constructor(url, options) {
+		super(options);
 
-        if (isInstance(url, URL)) {
-            url = url.toString();
-        }
+		if (isInstance(url, URL)) {
+			url = url.toString();
+		}
 
-        if (options === undefined) {
-            options = {};
-        }
+		if (options === undefined) {
+			options = {};
+		}
 
-        validateString(url);
+		validateString(url);
 
-        /**
-         * @property {string}
-         */
-        this.url = url;
+		/**
+		 * @property {string}
+		 */
+		this.url = url;
 
-        /**
-         * @private
-         * @property {Object} options
-         */
-        this[internalSymbol] = extend({}, super.defaults, this.defaults, validateObject(options));
-    }
+		/**
+		 * @private
+		 * @property {Object} options
+		 */
+		this[internalSymbol] = extend(
+			{},
+			super.defaults,
+			this.defaults,
+			validateObject(options),
+		);
+	}
 
-    /**
-     * Defaults
-     *
-     * @property {Object} fetch
-     * @property {String} fetch.method=GET
-     * @property {String} fetch.mode=cors
-     * @property {String} fetch.cache=no-cache
-     * @property {String} fetch.credentials=omit
-     * @property {String} fetch.redirect=follow
-     * @property {String} fetch.referrerPolicy=no-referrer
-     *
-     * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API}
-     */
-    get defaults() {
-        return extend(
-            {
-                fetch: {
-                    method: "GET", // *GET, POST, PUT, DELETE, etc.
-                    mode: "cors", // no-cors, *cors, same-origin
-                    cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
-                    credentials: "omit", // include, *same-origin, omit
-                    redirect: "follow", // manual, *follow, error
-                    referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
-                },
-            },
-            super.defaults,
-        );
-    }
+	/**
+	 * Defaults
+	 *
+	 * @property {Object} fetch
+	 * @property {String} fetch.method=GET
+	 * @property {String} fetch.mode=cors
+	 * @property {String} fetch.cache=no-cache
+	 * @property {String} fetch.credentials=omit
+	 * @property {String} fetch.redirect=follow
+	 * @property {String} fetch.referrerPolicy=no-referrer
+	 *
+	 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API}
+	 */
+	get defaults() {
+		return extend(
+			{
+				fetch: {
+					method: "GET", // *GET, POST, PUT, DELETE, etc.
+					mode: "cors", // no-cors, *cors, same-origin
+					cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
+					credentials: "omit", // include, *same-origin, omit
+					redirect: "follow", // manual, *follow, error
+					referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
+				},
+			},
+			super.defaults,
+		);
+	}
 
-    /**
-     *
-     * @param {Locale|string} locale
-     * @return {Promise}
-     */
-    getTranslations(locale) {
-        if (isString(locale)) {
-            locale = parseLocale(locale);
-        }
+	/**
+	 *
+	 * @param {Locale|string} locale
+	 * @return {Promise}
+	 */
+	getTranslations(locale) {
+		if (isString(locale)) {
+			locale = parseLocale(locale);
+		}
 
-        let formatter = new Formatter(locale.getMap());
+		let formatter = new Formatter(locale.getMap());
 
-        return getGlobalFunction("fetch")(formatter.format(this.url), this.getOption("fetch", {}))
-            .then((response) => response.json())
-            .then((data) => {
-                return new Translations(locale).assignTranslations(data);
-            });
-    }
+		return getGlobalFunction("fetch")(
+			formatter.format(this.url),
+			this.getOption("fetch", {}),
+		)
+			.then((response) => response.json())
+			.then((data) => {
+				return new Translations(locale).assignTranslations(data);
+			});
+	}
 }
diff --git a/source/i18n/translations.mjs b/source/i18n/translations.mjs
index e7589ef211e9a9541e5ff52ee9cfe320a855de85..8c2281b15b0474b55fdd4f1d9497e9161bfa7a53 100644
--- a/source/i18n/translations.mjs
+++ b/source/i18n/translations.mjs
@@ -11,7 +11,11 @@ import { ATTRIBUTE_OBJECTLINK } from "../dom/constants.mjs";
 import { getDocument } from "../dom/util.mjs";
 import { Base } from "../types/base.mjs";
 import { isObject, isString } from "../types/is.mjs";
-import { validateInteger, validateObject, validateString } from "../types/validate.mjs";
+import {
+	validateInteger,
+	validateObject,
+	validateString,
+} from "../types/validate.mjs";
 import { Locale, parseLocale } from "./locale.mjs";
 import { translationsLinkSymbol } from "./provider.mjs";
 
@@ -28,174 +32,176 @@ export { Translations, getDocumentTranslations };
  * @see https://datatracker.ietf.org/doc/html/rfc3066
  */
 class Translations extends Base {
-    /**
-     *
-     * @param {Locale} locale
-     */
-    constructor(locale) {
-        super();
-
-        if (locale instanceof Locale) {
-            this.locale = locale;
-        } else {
-            this.locale = parseLocale(validateString(locale));
-        }
-
-        this.storage = new Map();
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 3.27.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/i18n/translations@@instance");
-    }
-
-    /**
-     * Fetches a text using the specified key.
-     * If no suitable key is found, `defaultText` is taken.
-     *
-     * @param {string} key
-     * @param {string|undefined} defaultText
-     * @return {string}
-     * @throws {Error} key not found
-     */
-    getText(key, defaultText) {
-        if (!this.storage.has(key)) {
-            if (defaultText === undefined) {
-                throw new Error(`key ${key} not found`);
-            }
-
-            return validateString(defaultText);
-        }
-
-        let r = this.storage.get(key);
-        if (isObject(r)) {
-            return this.getPluralRuleText(key, "other", defaultText);
-        }
-
-        return this.storage.get(key);
-    }
-
-    /**
-     * A number `count` can be passed to this method. In addition to a number, one of the keywords can also be passed directly.
-     * "zero", "one", "two", "few", "many" and "other". Remember: not every language has all rules.
-     *
-     * The appropriate text for this number is then selected. If no suitable key is found, `defaultText` is taken.
-     *
-     * @param {string} key
-     * @param {integer|count} count
-     * @param {string|undefined} defaultText
-     * @return {string}
-     */
-    getPluralRuleText(key, count, defaultText) {
-        if (!this.storage.has(key)) {
-            return validateString(defaultText);
-        }
-
-        let r = validateObject(this.storage.get(key));
-
-        let keyword;
-        if (isString(count)) {
-            keyword = count.toLocaleString();
-        } else {
-            count = validateInteger(count);
-            if (count === 0) {
-                // special handling for zero count
-                if (r.hasOwnProperty("zero")) {
-                    return validateString(r["zero"]);
-                }
-            }
-
-            keyword = new Intl.PluralRules(this.locale.toString()).select(validateInteger(count));
-        }
-
-        if (r.hasOwnProperty(keyword)) {
-            return validateString(r[keyword]);
-        }
-
-        // @deprecated since 2023-03-14
-        // DEFAULT_KEY is undefined
-        // if (r.hasOwnProperty(DEFAULT_KEY)) {
-        //     return validateString(r[DEFAULT_KEY]);
-        // }
-
-        return validateString(defaultText);
-    }
-
-    /**
-     * Set a text for a key
-     *
-     * ```
-     * translations.setText("text1", "Make my day!");
-     * // plural rules
-     * translations.setText("text6", {
-     *     "zero": "There are no files on Disk.",
-     *     "one": "There is one file on Disk.",
-     *     "other": "There are files on Disk."
-     *     "default": "There are files on Disk."
-     * });
-     * ```
-     *
-     * @param {string} key
-     * @param {string|object} text
-     * @return {Translations}
-     * @throws {TypeError} value is not a string or object
-     */
-    setText(key, text) {
-        if (isString(text) || isObject(text)) {
-            this.storage.set(validateString(key), text);
-            return this;
-        }
-
-        throw new TypeError("value is not a string or object");
-    }
-
-    /**
-     * This method can be used to transfer overlays from an object. The keys are transferred, and the values are entered
-     * as text.
-     *
-     * The values can either be character strings or, in the case of texts with plural forms, objects. The plural forms
-     * must be stored as text via a standard key "zero", "one", "two", "few", "many" and "other".
-     *
-     * Additionally, the key default can be specified, which will be used if no other key fits.
-     *
-     * In some languages, like for example in German, there is no own more number at the value 0. In these languages,
-     * the function applies additionally zero.
-     *
-     * ```
-     * translations.assignTranslations({
-     *   "text1": "Make my day!",
-     *   "text2": "I'll be back!",
-     *   "text6": {
-     *     "zero": "There are no files on Disk.",
-     *     "one": "There is one file on Disk.",
-     *     "other": "There are files on Disk."
-     *     "default": "There are files on Disk."
-     * });
-     * ```
-     *
-     * @param {object} translations
-     * @return {Translations}
-     */
-    assignTranslations(translations) {
-        validateObject(translations);
-
-        if (translations instanceof Translations) {
-            translations.storage.forEach((v, k) => {
-                this.setText(k, v);
-            });
-            return this;
-        }
-
-        for (const [k, v] of Object.entries(translations)) {
-            this.setText(k, v);
-        }
-
-        return this;
-    }
+	/**
+	 *
+	 * @param {Locale} locale
+	 */
+	constructor(locale) {
+		super();
+
+		if (locale instanceof Locale) {
+			this.locale = locale;
+		} else {
+			this.locale = parseLocale(validateString(locale));
+		}
+
+		this.storage = new Map();
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 3.27.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/i18n/translations@@instance");
+	}
+
+	/**
+	 * Fetches a text using the specified key.
+	 * If no suitable key is found, `defaultText` is taken.
+	 *
+	 * @param {string} key
+	 * @param {string|undefined} defaultText
+	 * @return {string}
+	 * @throws {Error} key not found
+	 */
+	getText(key, defaultText) {
+		if (!this.storage.has(key)) {
+			if (defaultText === undefined) {
+				throw new Error(`key ${key} not found`);
+			}
+
+			return validateString(defaultText);
+		}
+
+		let r = this.storage.get(key);
+		if (isObject(r)) {
+			return this.getPluralRuleText(key, "other", defaultText);
+		}
+
+		return this.storage.get(key);
+	}
+
+	/**
+	 * A number `count` can be passed to this method. In addition to a number, one of the keywords can also be passed directly.
+	 * "zero", "one", "two", "few", "many" and "other". Remember: not every language has all rules.
+	 *
+	 * The appropriate text for this number is then selected. If no suitable key is found, `defaultText` is taken.
+	 *
+	 * @param {string} key
+	 * @param {integer|count} count
+	 * @param {string|undefined} defaultText
+	 * @return {string}
+	 */
+	getPluralRuleText(key, count, defaultText) {
+		if (!this.storage.has(key)) {
+			return validateString(defaultText);
+		}
+
+		let r = validateObject(this.storage.get(key));
+
+		let keyword;
+		if (isString(count)) {
+			keyword = count.toLocaleString();
+		} else {
+			count = validateInteger(count);
+			if (count === 0) {
+				// special handling for zero count
+				if (r.hasOwnProperty("zero")) {
+					return validateString(r["zero"]);
+				}
+			}
+
+			keyword = new Intl.PluralRules(this.locale.toString()).select(
+				validateInteger(count),
+			);
+		}
+
+		if (r.hasOwnProperty(keyword)) {
+			return validateString(r[keyword]);
+		}
+
+		// @deprecated since 2023-03-14
+		// DEFAULT_KEY is undefined
+		// if (r.hasOwnProperty(DEFAULT_KEY)) {
+		//     return validateString(r[DEFAULT_KEY]);
+		// }
+
+		return validateString(defaultText);
+	}
+
+	/**
+	 * Set a text for a key
+	 *
+	 * ```
+	 * translations.setText("text1", "Make my day!");
+	 * // plural rules
+	 * translations.setText("text6", {
+	 *     "zero": "There are no files on Disk.",
+	 *     "one": "There is one file on Disk.",
+	 *     "other": "There are files on Disk."
+	 *     "default": "There are files on Disk."
+	 * });
+	 * ```
+	 *
+	 * @param {string} key
+	 * @param {string|object} text
+	 * @return {Translations}
+	 * @throws {TypeError} value is not a string or object
+	 */
+	setText(key, text) {
+		if (isString(text) || isObject(text)) {
+			this.storage.set(validateString(key), text);
+			return this;
+		}
+
+		throw new TypeError("value is not a string or object");
+	}
+
+	/**
+	 * This method can be used to transfer overlays from an object. The keys are transferred, and the values are entered
+	 * as text.
+	 *
+	 * The values can either be character strings or, in the case of texts with plural forms, objects. The plural forms
+	 * must be stored as text via a standard key "zero", "one", "two", "few", "many" and "other".
+	 *
+	 * Additionally, the key default can be specified, which will be used if no other key fits.
+	 *
+	 * In some languages, like for example in German, there is no own more number at the value 0. In these languages,
+	 * the function applies additionally zero.
+	 *
+	 * ```
+	 * translations.assignTranslations({
+	 *   "text1": "Make my day!",
+	 *   "text2": "I'll be back!",
+	 *   "text6": {
+	 *     "zero": "There are no files on Disk.",
+	 *     "one": "There is one file on Disk.",
+	 *     "other": "There are files on Disk."
+	 *     "default": "There are files on Disk."
+	 * });
+	 * ```
+	 *
+	 * @param {object} translations
+	 * @return {Translations}
+	 */
+	assignTranslations(translations) {
+		validateObject(translations);
+
+		if (translations instanceof Translations) {
+			translations.storage.forEach((v, k) => {
+				this.setText(k, v);
+			});
+			return this;
+		}
+
+		for (const [k, v] of Object.entries(translations)) {
+			this.setText(k, v);
+		}
+
+		return this;
+	}
 }
 
 /**
@@ -210,30 +216,34 @@ class Translations extends Base {
  * @memberOf Monster.I18n
  */
 function getDocumentTranslations(element) {
-    const d = getDocument();
-
-    if (!(element instanceof HTMLElement)) {
-        element = d.querySelector(`[${ATTRIBUTE_OBJECTLINK}~="${translationsLinkSymbol.toString()}"]`);
-        if (element === null) {
-            throw new Error("Cannot find element with translations. Add a translations object to the document.");
-        }
-    }
-
-    if (!(element instanceof HTMLElement)) {
-        throw new Error("Element is not an HTMLElement.");
-    }
-
-    if (!hasObjectLink(element, translationsLinkSymbol)) {
-        throw new Error("This element has no translations.");
-    }
-
-    let obj = getLinkedObjects(element, translationsLinkSymbol);
-
-    for (const t of obj) {
-        if (t instanceof Translations) {
-            return t;
-        }
-    }
-
-    throw new Error("Missing translations.");
+	const d = getDocument();
+
+	if (!(element instanceof HTMLElement)) {
+		element = d.querySelector(
+			`[${ATTRIBUTE_OBJECTLINK}~="${translationsLinkSymbol.toString()}"]`,
+		);
+		if (element === null) {
+			throw new Error(
+				"Cannot find element with translations. Add a translations object to the document.",
+			);
+		}
+	}
+
+	if (!(element instanceof HTMLElement)) {
+		throw new Error("Element is not an HTMLElement.");
+	}
+
+	if (!hasObjectLink(element, translationsLinkSymbol)) {
+		throw new Error("This element has no translations.");
+	}
+
+	let obj = getLinkedObjects(element, translationsLinkSymbol);
+
+	for (const t of obj) {
+		if (t instanceof Translations) {
+			return t;
+		}
+	}
+
+	throw new Error("Missing translations.");
 }
diff --git a/source/logging/handler.mjs b/source/logging/handler.mjs
index 7d92bc23bdcb97b3bc5c420239c63aac66799453..4737ca748a39a27b95e02ade860b86729457e940 100644
--- a/source/logging/handler.mjs
+++ b/source/logging/handler.mjs
@@ -21,144 +21,144 @@ export { Handler };
  * @memberOf Monster.Logging
  */
 class Handler extends Base {
-    constructor() {
-        super();
-
-        /**
-         * Loglevel
-         *
-         * @type {integer}
-         */
-        this.loglevel = OFF;
-    }
-
-    /**
-     * This is the central log function. this method must be
-     * overwritten by derived handlers with their own logic.
-     *
-     * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF  (ALL = 0xff;OFF = 0x00;
-     *
-     * @param {LogEntry} entry
-     * @returns {boolean}
-     */
-    log(entry) {
-        validateInstance(entry, LogEntry);
-
-        if (this.loglevel < entry.getLogLevel()) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * set loglevel
-     *
-     * @param {integer} loglevel
-     * @returns {Handler}
-     * @since 1.5.0
-     */
-    setLogLevel(loglevel) {
-        validateInteger(loglevel);
-        this.loglevel = loglevel;
-        return this;
-    }
-
-    /**
-     * get loglevel
-     *
-     * @returns {integer}
-     * @since 1.5.0
-     */
-    getLogLevel() {
-        return this.loglevel;
-    }
-
-    /**
-     *  Set log level to All
-     *
-     * @returns {Handler}
-     * @since 1.5.0
-     */
-    setAll() {
-        this.setLogLevel(ALL);
-        return this;
-    }
-
-    /**
-     * Set log level to Trace
-     *
-     * @returns {Handler}
-     * @since 1.5.0
-     */
-    setTrace() {
-        this.setLogLevel(TRACE);
-        return this;
-    }
-
-    /**
-     * Set log level to Debug
-     *
-     * @returns {Handler}
-     * @since 1.5.0
-     */
-    setDebug() {
-        this.setLogLevel(DEBUG);
-        return this;
-    }
-
-    /**
-     * Set log level to Info
-     *
-     * @returns {Handler}
-     * @since 1.5.0
-     */
-    setInfo() {
-        this.setLogLevel(INFO);
-        return this;
-    }
-
-    /**
-     * Set log level to Warn
-     *
-     * @returns {undefined}
-     * @since 1.5.0
-     */
-    setWarn() {
-        this.setLogLevel(WARN);
-        return this;
-    }
-
-    /**
-     * Set log level to Error
-     *
-     * @returns {Handler}
-     * @since 1.5.0
-     */
-    setError() {
-        this.setLogLevel(ERROR);
-        return this;
-    }
-
-    /**
-     * Set log level to Fatal
-     *
-     * @returns {Handler}
-     * @since 1.5.0
-     */
-    setFatal() {
-        this.setLogLevel(FATAL);
-        return this;
-    }
-
-    /**
-     * Set log level to Off
-     *
-     * @returns {Handler}
-     * @since 1.5.0
-     */
-    setOff() {
-        this.setLogLevel(OFF);
-        return this;
-    }
+	constructor() {
+		super();
+
+		/**
+		 * Loglevel
+		 *
+		 * @type {integer}
+		 */
+		this.loglevel = OFF;
+	}
+
+	/**
+	 * This is the central log function. this method must be
+	 * overwritten by derived handlers with their own logic.
+	 *
+	 * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF  (ALL = 0xff;OFF = 0x00;
+	 *
+	 * @param {LogEntry} entry
+	 * @returns {boolean}
+	 */
+	log(entry) {
+		validateInstance(entry, LogEntry);
+
+		if (this.loglevel < entry.getLogLevel()) {
+			return false;
+		}
+
+		return true;
+	}
+
+	/**
+	 * set loglevel
+	 *
+	 * @param {integer} loglevel
+	 * @returns {Handler}
+	 * @since 1.5.0
+	 */
+	setLogLevel(loglevel) {
+		validateInteger(loglevel);
+		this.loglevel = loglevel;
+		return this;
+	}
+
+	/**
+	 * get loglevel
+	 *
+	 * @returns {integer}
+	 * @since 1.5.0
+	 */
+	getLogLevel() {
+		return this.loglevel;
+	}
+
+	/**
+	 *  Set log level to All
+	 *
+	 * @returns {Handler}
+	 * @since 1.5.0
+	 */
+	setAll() {
+		this.setLogLevel(ALL);
+		return this;
+	}
+
+	/**
+	 * Set log level to Trace
+	 *
+	 * @returns {Handler}
+	 * @since 1.5.0
+	 */
+	setTrace() {
+		this.setLogLevel(TRACE);
+		return this;
+	}
+
+	/**
+	 * Set log level to Debug
+	 *
+	 * @returns {Handler}
+	 * @since 1.5.0
+	 */
+	setDebug() {
+		this.setLogLevel(DEBUG);
+		return this;
+	}
+
+	/**
+	 * Set log level to Info
+	 *
+	 * @returns {Handler}
+	 * @since 1.5.0
+	 */
+	setInfo() {
+		this.setLogLevel(INFO);
+		return this;
+	}
+
+	/**
+	 * Set log level to Warn
+	 *
+	 * @returns {undefined}
+	 * @since 1.5.0
+	 */
+	setWarn() {
+		this.setLogLevel(WARN);
+		return this;
+	}
+
+	/**
+	 * Set log level to Error
+	 *
+	 * @returns {Handler}
+	 * @since 1.5.0
+	 */
+	setError() {
+		this.setLogLevel(ERROR);
+		return this;
+	}
+
+	/**
+	 * Set log level to Fatal
+	 *
+	 * @returns {Handler}
+	 * @since 1.5.0
+	 */
+	setFatal() {
+		this.setLogLevel(FATAL);
+		return this;
+	}
+
+	/**
+	 * Set log level to Off
+	 *
+	 * @returns {Handler}
+	 * @since 1.5.0
+	 */
+	setOff() {
+		this.setLogLevel(OFF);
+		return this;
+	}
 }
diff --git a/source/logging/handler/console.mjs b/source/logging/handler/console.mjs
index d63afce6a57d36dd326a9fc4e0e64f4824e138e1..934d3a8c6661cf925bfded3a24a6c41e7b2d9f34 100644
--- a/source/logging/handler/console.mjs
+++ b/source/logging/handler/console.mjs
@@ -21,44 +21,44 @@ export { ConsoleHandler };
  * @memberOf Monster.Logging.Handler
  */
 class ConsoleHandler extends Handler {
-    /**
-     * This is the central log function. this method must be
-     * overwritten by derived handlers with their own logic.
-     *
-     * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF  (ALL = 0xff;OFF = 0x00;
-     *
-     * @param {LogEntry} entry
-     * @returns {boolean}
-     */
-    log(entry) {
-        if (super.log(entry)) {
-            let console = getGlobalObject("console");
-            if (!console) return false;
+	/**
+	 * This is the central log function. this method must be
+	 * overwritten by derived handlers with their own logic.
+	 *
+	 * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF  (ALL = 0xff;OFF = 0x00;
+	 *
+	 * @param {LogEntry} entry
+	 * @returns {boolean}
+	 */
+	log(entry) {
+		if (super.log(entry)) {
+			let console = getGlobalObject("console");
+			if (!console) return false;
 
-            if (!console.error) console.error = console.log;
-            if (!console.warn) console.warn = console.log;
+			if (!console.error) console.error = console.log;
+			if (!console.warn) console.warn = console.log;
 
-            switch (entry.getLogLevel()) {
-                case TRACE:
-                case DEBUG:
-                case INFO:
-                    console.log(entry.toString());
-                    break;
-                case FATAL:
-                case ERROR:
-                    console.error(entry.toString());
-                    break;
-                case WARN:
-                    console.warn(entry.toString());
-                    break;
-                default:
-                    console.log(entry.toString());
-                    break;
-            }
+			switch (entry.getLogLevel()) {
+				case TRACE:
+				case DEBUG:
+				case INFO:
+					console.log(entry.toString());
+					break;
+				case FATAL:
+				case ERROR:
+					console.error(entry.toString());
+					break;
+				case WARN:
+					console.warn(entry.toString());
+					break;
+				default:
+					console.log(entry.toString());
+					break;
+			}
 
-            return true;
-        }
+			return true;
+		}
 
-        return false;
-    }
+		return false;
+	}
 }
diff --git a/source/logging/logentry.mjs b/source/logging/logentry.mjs
index ff6df51f5e9fb27d15400d8beb1ae396e179f8a9..6c0f134db206c6a1a66f5c5e8948de717f3818f5 100644
--- a/source/logging/logentry.mjs
+++ b/source/logging/logentry.mjs
@@ -19,32 +19,32 @@ export { LogEntry };
  * @memberOf Monster.Logging
  */
 class LogEntry extends Base {
-    /**
-     *
-     * @param {Integer} loglevel
-     * @param {...*} args
-     */
-    constructor(loglevel, ...args) {
-        super();
-        validateInteger(loglevel);
+	/**
+	 *
+	 * @param {Integer} loglevel
+	 * @param {...*} args
+	 */
+	constructor(loglevel, ...args) {
+		super();
+		validateInteger(loglevel);
 
-        this.loglevel = loglevel;
-        this.arguments = args;
-    }
+		this.loglevel = loglevel;
+		this.arguments = args;
+	}
 
-    /**
-     *
-     * @returns {integerr}
-     */
-    getLogLevel() {
-        return this.loglevel;
-    }
+	/**
+	 *
+	 * @returns {integerr}
+	 */
+	getLogLevel() {
+		return this.loglevel;
+	}
 
-    /**
-     *
-     * @returns {array}
-     */
-    getArguments() {
-        return this.arguments;
-    }
+	/**
+	 *
+	 * @returns {array}
+	 */
+	getArguments() {
+		return this.arguments;
+	}
 }
diff --git a/source/logging/logger.mjs b/source/logging/logger.mjs
index 556b33de532078caa47ed9b4c6ef8b172827f262..b05ab99ab22cb5b27f0fb3de62ae531dcfbb268c 100644
--- a/source/logging/logger.mjs
+++ b/source/logging/logger.mjs
@@ -9,7 +9,11 @@ import { Handler } from "../logging/handler.mjs";
 import { LogEntry } from "../logging/logentry.mjs";
 
 import { Base } from "../types/base.mjs";
-import { validateInteger, validateObject, validateString } from "../types/validate.mjs";
+import {
+	validateInteger,
+	validateObject,
+	validateString,
+} from "../types/validate.mjs";
 
 export { Logger, ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF };
 
@@ -71,196 +75,196 @@ const OFF = 0;
  * @memberOf Monster.Logging
  */
 class Logger extends Base {
-    /**
-     *
-     */
-    constructor() {
-        super();
-        this.handler = new Set();
-    }
+	/**
+	 *
+	 */
+	constructor() {
+		super();
+		this.handler = new Set();
+	}
 
-    /**
-     *
-     * @param {Handler} handler
-     * @returns {Logger}
-     * @throws {Error} the handler must be an instance of Handler
-     */
-    addHandler(handler) {
-        validateObject(handler);
-        if (!(handler instanceof Handler)) {
-            throw new Error("the handler must be an instance of Handler");
-        }
+	/**
+	 *
+	 * @param {Handler} handler
+	 * @returns {Logger}
+	 * @throws {Error} the handler must be an instance of Handler
+	 */
+	addHandler(handler) {
+		validateObject(handler);
+		if (!(handler instanceof Handler)) {
+			throw new Error("the handler must be an instance of Handler");
+		}
 
-        this.handler.add(handler);
-        return this;
-    }
+		this.handler.add(handler);
+		return this;
+	}
 
-    /**
-     *
-     * @param {Handler} handler
-     * @returns {Logger}
-     * @throws {Error} the handler must be an instance of Handler
-     */
-    removeHandler(handler) {
-        validateObject(handler);
-        if (!(handler instanceof Handler)) {
-            throw new Error("the handler must be an instance of Handler");
-        }
+	/**
+	 *
+	 * @param {Handler} handler
+	 * @returns {Logger}
+	 * @throws {Error} the handler must be an instance of Handler
+	 */
+	removeHandler(handler) {
+		validateObject(handler);
+		if (!(handler instanceof Handler)) {
+			throw new Error("the handler must be an instance of Handler");
+		}
 
-        this.handler.delete(handler);
-        return this;
-    }
+		this.handler.delete(handler);
+		return this;
+	}
 
-    /**
-     * log Trace message
-     *
-     * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF  (ALL = 0xff;OFF = 0x00;
-     *
-     * @param {*} arguments
-     * @returns {Logger}
-     * @since 1.5.0
-     */
-    logTrace(...args) {
-        if (typeof args !== "object" || args[0] === null) {
-            throw new Error("the first argument must be an object");
-        }
+	/**
+	 * log Trace message
+	 *
+	 * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF  (ALL = 0xff;OFF = 0x00;
+	 *
+	 * @param {*} arguments
+	 * @returns {Logger}
+	 * @since 1.5.0
+	 */
+	logTrace(...args) {
+		if (typeof args !== "object" || args[0] === null) {
+			throw new Error("the first argument must be an object");
+		}
 
-        triggerLog.apply(this, [TRACE, ...args]);
-        return this;
-    }
+		triggerLog.apply(this, [TRACE, ...args]);
+		return this;
+	}
 
-    /**
-     * log Debug message
-     *
-     * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF  (ALL = 0xff;OFF = 0x00;
-     *
-     * @param {*} arguments
-     * @returns {Logger}
-     * @since 1.5.0
-     */
-    logDebug(...args) {
-        if (typeof args !== "object" || args[0] === null) {
-            throw new Error("the first argument must be an object");
-        }
+	/**
+	 * log Debug message
+	 *
+	 * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF  (ALL = 0xff;OFF = 0x00;
+	 *
+	 * @param {*} arguments
+	 * @returns {Logger}
+	 * @since 1.5.0
+	 */
+	logDebug(...args) {
+		if (typeof args !== "object" || args[0] === null) {
+			throw new Error("the first argument must be an object");
+		}
 
-        triggerLog.apply(this, [DEBUG, ...args]);
-        return this;
-    }
+		triggerLog.apply(this, [DEBUG, ...args]);
+		return this;
+	}
 
-    /**
-     * log Info message
-     *
-     * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF  (ALL = 0xff;OFF = 0x00;
-     *
-     *
-     * @param {*} arguments
-     * @returns {Logger}
-     * @since 1.5.0
-     */
-    logInfo(...args) {
-        if (typeof args !== "object" || args[0] === null) {
-            throw new Error("the first argument must be an object");
-        }
+	/**
+	 * log Info message
+	 *
+	 * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF  (ALL = 0xff;OFF = 0x00;
+	 *
+	 *
+	 * @param {*} arguments
+	 * @returns {Logger}
+	 * @since 1.5.0
+	 */
+	logInfo(...args) {
+		if (typeof args !== "object" || args[0] === null) {
+			throw new Error("the first argument must be an object");
+		}
 
-        triggerLog.apply(this, [INFO, ...args]);
-        return this;
-    }
+		triggerLog.apply(this, [INFO, ...args]);
+		return this;
+	}
 
-    /**
-     * log Warn message
-     *
-     * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF  (ALL = 0xff;OFF = 0x00;
-     *
-     * @param {*} arguments
-     * @returns {Logger}
-     * @since 1.5.0
-     */
-    logWarn(...args) {
-        if (typeof args !== "object" || args[0] === null) {
-            throw new Error("the first argument must be an object");
-        }
+	/**
+	 * log Warn message
+	 *
+	 * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF  (ALL = 0xff;OFF = 0x00;
+	 *
+	 * @param {*} arguments
+	 * @returns {Logger}
+	 * @since 1.5.0
+	 */
+	logWarn(...args) {
+		if (typeof args !== "object" || args[0] === null) {
+			throw new Error("the first argument must be an object");
+		}
 
-        triggerLog.apply(this, [WARN, ...args]);
-        return this;
-    }
+		triggerLog.apply(this, [WARN, ...args]);
+		return this;
+	}
 
-    /**
-     * log Error message
-     *
-     * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF  (ALL = 0xff;OFF = 0x00;
-     *
-     * @param {*} arguments
-     * @returns {Logger}
-     * @since 1.5.0
-     */
-    logError(...args) {
-        if (typeof args !== "object" || args[0] === null) {
-            throw new Error("the first argument must be an object");
-        }
+	/**
+	 * log Error message
+	 *
+	 * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF  (ALL = 0xff;OFF = 0x00;
+	 *
+	 * @param {*} arguments
+	 * @returns {Logger}
+	 * @since 1.5.0
+	 */
+	logError(...args) {
+		if (typeof args !== "object" || args[0] === null) {
+			throw new Error("the first argument must be an object");
+		}
 
-        triggerLog.apply(this, [ERROR, ...args]);
-        return this;
-    }
+		triggerLog.apply(this, [ERROR, ...args]);
+		return this;
+	}
 
-    /**
-     * log Fatal message
-     *
-     * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF  (ALL = 0xff;OFF = 0x00;
-     *
-     * @param {*} arguments
-     * @returns {Logger}
-     * @since 1.5.0
-     */
-    logFatal(...args) {
-        if (typeof args !== "object" || args[0] === null) {
-            throw new Error("the first argument must be an object");
-        }
+	/**
+	 * log Fatal message
+	 *
+	 * ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF  (ALL = 0xff;OFF = 0x00;
+	 *
+	 * @param {*} arguments
+	 * @returns {Logger}
+	 * @since 1.5.0
+	 */
+	logFatal(...args) {
+		if (typeof args !== "object" || args[0] === null) {
+			throw new Error("the first argument must be an object");
+		}
 
-        triggerLog.apply(this, [FATAL, ...args]);
-        return this;
-    }
+		triggerLog.apply(this, [FATAL, ...args]);
+		return this;
+	}
 
-    /**
-     * Labels
-     *
-     * @param {integer} level
-     * @returns {string}
-     */
-    getLabel(level) {
-        validateInteger(level);
+	/**
+	 * Labels
+	 *
+	 * @param {integer} level
+	 * @returns {string}
+	 */
+	getLabel(level) {
+		validateInteger(level);
 
-        if (level === ALL) return "ALL";
-        if (level === TRACE) return "TRACE";
-        if (level === DEBUG) return "DEBUG";
-        if (level === INFO) return "INFO";
-        if (level === WARN) return "WARN";
-        if (level === ERROR) return "ERROR";
-        if (level === FATAL) return "FATAL";
-        if (level === OFF) return "OFF";
+		if (level === ALL) return "ALL";
+		if (level === TRACE) return "TRACE";
+		if (level === DEBUG) return "DEBUG";
+		if (level === INFO) return "INFO";
+		if (level === WARN) return "WARN";
+		if (level === ERROR) return "ERROR";
+		if (level === FATAL) return "FATAL";
+		if (level === OFF) return "OFF";
 
-        return "unknown";
-    }
+		return "unknown";
+	}
 
-    /**
-     * Level
-     *
-     * @param {string} label
-     * @returns {integer}
-     */
-    getLevel(label) {
-        validateString(label);
+	/**
+	 * Level
+	 *
+	 * @param {string} label
+	 * @returns {integer}
+	 */
+	getLevel(label) {
+		validateString(label);
 
-        if (label === "ALL") return ALL;
-        if (label === "TRACE") return TRACE;
-        if (label === "DEBUG") return DEBUG;
-        if (label === "INFO") return INFO;
-        if (label === "WARN") return WARN;
-        if (label === "ERROR") return ERROR;
-        if (label === "FATAL") return FATAL;
-        if (label === "OFF") return OFF;
+		if (label === "ALL") return ALL;
+		if (label === "TRACE") return TRACE;
+		if (label === "DEBUG") return DEBUG;
+		if (label === "INFO") return INFO;
+		if (label === "WARN") return WARN;
+		if (label === "ERROR") return ERROR;
+		if (label === "FATAL") return FATAL;
+		if (label === "OFF") return OFF;
 
-        return 0;
-    }
+		return 0;
+	}
 }
 
 /**
@@ -272,11 +276,11 @@ class Logger extends Base {
  * @private
  */
 function triggerLog(loglevel, ...args) {
-    var logger = this;
+	var logger = this;
 
-    for (let handler of logger.handler) {
-        handler.log(new LogEntry(loglevel, args));
-    }
+	for (let handler of logger.handler) {
+		handler.log(new LogEntry(loglevel, args));
+	}
 
-    return logger;
+	return logger;
 }
diff --git a/source/math/random.mjs b/source/math/random.mjs
index 163712021027c8c0ad5cc9a41f94f6a8766b44d8..8b3cf0205bdd8603b4ad9669ab1f954b829ccdbc 100644
--- a/source/math/random.mjs
+++ b/source/math/random.mjs
@@ -25,18 +25,18 @@ export { random };
  * @copyright schukai GmbH
  */
 function random(min, max) {
-    if (min === undefined) {
-        min = 0;
-    }
-    if (max === undefined) {
-        max = MAX;
-    }
-
-    if (max < min) {
-        throw new Error("max must be greater than min");
-    }
-
-    return Math.round(create(min, max));
+	if (min === undefined) {
+		min = 0;
+	}
+	if (max === undefined) {
+		max = MAX;
+	}
+
+	if (max < min) {
+		throw new Error("max must be greater than min");
+	}
+
+	return Math.round(create(min, max));
 }
 
 /**
@@ -46,10 +46,10 @@ function random(min, max) {
 var MAX = 1000000000;
 
 Math.log2 =
-    Math.log2 ||
-    function (n) {
-        return Math.log(n) / Math.log(2);
-    };
+	Math.log2 ||
+	function (n) {
+		return Math.log(n) / Math.log(2);
+	};
 
 /**
  *
@@ -62,46 +62,50 @@ Math.log2 =
  * @throws {Error} the distance is too small to create a random number.
  */
 function create(min, max) {
-    let crypt;
-    let globalReference = getGlobal();
-
-    crypt = globalReference?.["crypto"] || globalReference?.["msCrypto"] || globalReference?.["crypto"] || undefined;
-
-    if (typeof crypt === "undefined") {
-        throw new Error("missing crypt");
-    }
-
-    let rval = 0;
-    const range = max - min;
-    if (range < 2) {
-        throw new Error("the distance is too small to create a random number.");
-    }
-
-    const bitsNeeded = Math.ceil(Math.log2(range));
-    if (bitsNeeded > 53) {
-        throw new Error("we cannot generate numbers larger than 53 bits.");
-    }
-    const bytesNeeded = Math.ceil(bitsNeeded / 8);
-    const mask = Math.pow(2, bitsNeeded) - 1;
-
-    const byteArray = new Uint8Array(bytesNeeded);
-    crypt.getRandomValues(byteArray);
-
-    let p = (bytesNeeded - 1) * 8;
-    for (var i = 0; i < bytesNeeded; i++) {
-        rval += byteArray[i] * Math.pow(2, p);
-        p -= 8;
-    }
-
-    rval = rval & mask;
-
-    if (rval >= range) {
-        return create(min, max);
-    }
-
-    if (rval < min) {
-        rval += min;
-    }
-
-    return rval;
+	let crypt;
+	let globalReference = getGlobal();
+
+	crypt =
+		globalReference?.["crypto"] ||
+		globalReference?.["msCrypto"] ||
+		globalReference?.["crypto"] ||
+		undefined;
+
+	if (typeof crypt === "undefined") {
+		throw new Error("missing crypt");
+	}
+
+	let rval = 0;
+	const range = max - min;
+	if (range < 2) {
+		throw new Error("the distance is too small to create a random number.");
+	}
+
+	const bitsNeeded = Math.ceil(Math.log2(range));
+	if (bitsNeeded > 53) {
+		throw new Error("we cannot generate numbers larger than 53 bits.");
+	}
+	const bytesNeeded = Math.ceil(bitsNeeded / 8);
+	const mask = Math.pow(2, bitsNeeded) - 1;
+
+	const byteArray = new Uint8Array(bytesNeeded);
+	crypt.getRandomValues(byteArray);
+
+	let p = (bytesNeeded - 1) * 8;
+	for (var i = 0; i < bytesNeeded; i++) {
+		rval += byteArray[i] * Math.pow(2, p);
+		p -= 8;
+	}
+
+	rval = rval & mask;
+
+	if (rval >= range) {
+		return create(min, max);
+	}
+
+	if (rval < min) {
+		rval += min;
+	}
+
+	return rval;
 }
diff --git a/source/monster.mjs b/source/monster.mjs
index 12e5ec8e30f2aafdaa93db30cede9910d73240fd..24cde159fc65d3a498b36999c9652ad2edde26a5 100644
--- a/source/monster.mjs
+++ b/source/monster.mjs
@@ -1,4 +1,3 @@
-
 /**
  * Copyright schukai GmbH and contributors 2023. All Rights Reserved.
  * Node module: @schukai/monster
@@ -16,107 +15,107 @@
  * @author schukai GmbH
  */
 
-export * from "./text/formatter.mjs"
-export * from "./text/generate-range-comparison-expression.mjs"
-export * from "./text/util.mjs"
-export * from "./text/bracketed-key-value-hash.mjs"
-export * from "./math/random.mjs"
-export * from "./util/trimspaces.mjs"
-export * from "./util/processing.mjs"
-export * from "./util/runtime.mjs"
-export * from "./util/deadmansswitch.mjs"
-export * from "./util/comparator.mjs"
-export * from "./util/freeze.mjs"
-export * from "./util/clone.mjs"
-export * from "./logging/handler/console.mjs"
-export * from "./logging/logger.mjs"
-export * from "./logging/handler.mjs"
-export * from "./logging/logentry.mjs"
-export * from "./net/webconnect.mjs"
-export * from "./net/webconnect/message.mjs"
-export * from "./constraints/invalid.mjs"
-export * from "./constraints/abstractoperator.mjs"
-export * from "./constraints/oroperator.mjs"
-export * from "./constraints/isobject.mjs"
-export * from "./constraints/andoperator.mjs"
-export * from "./constraints/isarray.mjs"
-export * from "./constraints/abstract.mjs"
-export * from "./constraints/valid.mjs"
-export * from "./dom/dimension.mjs"
-export * from "./dom/resource/link/stylesheet.mjs"
-export * from "./dom/resource/link.mjs"
-export * from "./dom/resource/script.mjs"
-export * from "./dom/resource/data.mjs"
-export * from "./dom/util/init-options-from-attributes.mjs"
-export * from "./dom/util/set-option-from-attribute.mjs"
-export * from "./dom/util/extract-keys.mjs"
-export * from "./dom/worker/factory.mjs"
-export * from "./dom/updater.mjs"
-export * from "./dom/locale.mjs"
-export * from "./dom/theme.mjs"
-export * from "./dom/customelement.mjs"
-export * from "./dom/slotted.mjs"
-export * from "./dom/focusmanager.mjs"
-export * from "./dom/ready.mjs"
-export * from "./dom/util.mjs"
-export * from "./dom/attributes.mjs"
-export * from "./dom/resource.mjs"
-export * from "./dom/resourcemanager.mjs"
-export * from "./dom/assembler.mjs"
-export * from "./dom/customcontrol.mjs"
-export * from "./dom/template.mjs"
-export * from "./dom/constants.mjs"
-export * from "./dom/events.mjs"
-export * from "./data/datasource/dom.mjs"
-export * from "./data/datasource/storage/localstorage.mjs"
-export * from "./data/datasource/storage/sessionstorage.mjs"
-export * from "./data/datasource/storage.mjs"
-export * from "./data/datasource/server.mjs"
-export * from "./data/datasource/server/restapi/data-fetch-error.mjs"
-export * from "./data/datasource/server/restapi/writeerror.mjs"
-export * from "./data/datasource/server/webconnect.mjs"
-export * from "./data/datasource/server/restapi.mjs"
-export * from "./data/datasource.mjs"
-export * from "./data/buildmap.mjs"
-export * from "./data/transformer.mjs"
-export * from "./data/diff.mjs"
-export * from "./data/buildtree.mjs"
-export * from "./data/pathfinder.mjs"
-export * from "./data/pipe.mjs"
-export * from "./data/extend.mjs"
-export * from "./types/nodelist.mjs"
-export * from "./types/base.mjs"
-export * from "./types/mediatype.mjs"
-export * from "./types/tokenlist.mjs"
-export * from "./types/proxyobserver.mjs"
-export * from "./types/version.mjs"
-export * from "./types/global.mjs"
-export * from "./types/observerlist.mjs"
-export * from "./types/internal.mjs"
-export * from "./types/observablequeue.mjs"
-export * from "./types/dataurl.mjs"
-export * from "./types/binary.mjs"
-export * from "./types/observer.mjs"
-export * from "./types/regex.mjs"
-export * from "./types/randomid.mjs"
-export * from "./types/id.mjs"
-export * from "./types/uuid.mjs"
-export * from "./types/is.mjs"
-export * from "./types/validate.mjs"
-export * from "./types/typeof.mjs"
-export * from "./types/uniquequeue.mjs"
-export * from "./types/stack.mjs"
-export * from "./types/basewithoptions.mjs"
-export * from "./types/node.mjs"
-export * from "./types/queue.mjs"
-export * from "./types/noderecursiveiterator.mjs"
-export * from "./i18n/formatter.mjs"
-export * from "./i18n/locale.mjs"
-export * from "./i18n/provider.mjs"
-export * from "./i18n/providers/fetch.mjs"
-export * from "./i18n/providers/embed.mjs"
-export * from "./i18n/translations.mjs"
-export * from "./constants.mjs"
+export * from "./text/formatter.mjs";
+export * from "./text/generate-range-comparison-expression.mjs";
+export * from "./text/util.mjs";
+export * from "./text/bracketed-key-value-hash.mjs";
+export * from "./math/random.mjs";
+export * from "./util/trimspaces.mjs";
+export * from "./util/processing.mjs";
+export * from "./util/runtime.mjs";
+export * from "./util/deadmansswitch.mjs";
+export * from "./util/comparator.mjs";
+export * from "./util/freeze.mjs";
+export * from "./util/clone.mjs";
+export * from "./logging/handler/console.mjs";
+export * from "./logging/logger.mjs";
+export * from "./logging/handler.mjs";
+export * from "./logging/logentry.mjs";
+export * from "./net/webconnect.mjs";
+export * from "./net/webconnect/message.mjs";
+export * from "./constraints/invalid.mjs";
+export * from "./constraints/abstractoperator.mjs";
+export * from "./constraints/oroperator.mjs";
+export * from "./constraints/isobject.mjs";
+export * from "./constraints/andoperator.mjs";
+export * from "./constraints/isarray.mjs";
+export * from "./constraints/abstract.mjs";
+export * from "./constraints/valid.mjs";
+export * from "./dom/dimension.mjs";
+export * from "./dom/resource/link/stylesheet.mjs";
+export * from "./dom/resource/link.mjs";
+export * from "./dom/resource/script.mjs";
+export * from "./dom/resource/data.mjs";
+export * from "./dom/util/init-options-from-attributes.mjs";
+export * from "./dom/util/set-option-from-attribute.mjs";
+export * from "./dom/util/extract-keys.mjs";
+export * from "./dom/worker/factory.mjs";
+export * from "./dom/updater.mjs";
+export * from "./dom/locale.mjs";
+export * from "./dom/theme.mjs";
+export * from "./dom/customelement.mjs";
+export * from "./dom/slotted.mjs";
+export * from "./dom/focusmanager.mjs";
+export * from "./dom/ready.mjs";
+export * from "./dom/util.mjs";
+export * from "./dom/attributes.mjs";
+export * from "./dom/resource.mjs";
+export * from "./dom/resourcemanager.mjs";
+export * from "./dom/assembler.mjs";
+export * from "./dom/customcontrol.mjs";
+export * from "./dom/template.mjs";
+export * from "./dom/constants.mjs";
+export * from "./dom/events.mjs";
+export * from "./data/datasource/dom.mjs";
+export * from "./data/datasource/storage/localstorage.mjs";
+export * from "./data/datasource/storage/sessionstorage.mjs";
+export * from "./data/datasource/storage.mjs";
+export * from "./data/datasource/server.mjs";
+export * from "./data/datasource/server/restapi/data-fetch-error.mjs";
+export * from "./data/datasource/server/restapi/writeerror.mjs";
+export * from "./data/datasource/server/webconnect.mjs";
+export * from "./data/datasource/server/restapi.mjs";
+export * from "./data/datasource.mjs";
+export * from "./data/buildmap.mjs";
+export * from "./data/transformer.mjs";
+export * from "./data/diff.mjs";
+export * from "./data/buildtree.mjs";
+export * from "./data/pathfinder.mjs";
+export * from "./data/pipe.mjs";
+export * from "./data/extend.mjs";
+export * from "./types/nodelist.mjs";
+export * from "./types/base.mjs";
+export * from "./types/mediatype.mjs";
+export * from "./types/tokenlist.mjs";
+export * from "./types/proxyobserver.mjs";
+export * from "./types/version.mjs";
+export * from "./types/global.mjs";
+export * from "./types/observerlist.mjs";
+export * from "./types/internal.mjs";
+export * from "./types/observablequeue.mjs";
+export * from "./types/dataurl.mjs";
+export * from "./types/binary.mjs";
+export * from "./types/observer.mjs";
+export * from "./types/regex.mjs";
+export * from "./types/randomid.mjs";
+export * from "./types/id.mjs";
+export * from "./types/uuid.mjs";
+export * from "./types/is.mjs";
+export * from "./types/validate.mjs";
+export * from "./types/typeof.mjs";
+export * from "./types/uniquequeue.mjs";
+export * from "./types/stack.mjs";
+export * from "./types/basewithoptions.mjs";
+export * from "./types/node.mjs";
+export * from "./types/queue.mjs";
+export * from "./types/noderecursiveiterator.mjs";
+export * from "./i18n/formatter.mjs";
+export * from "./i18n/locale.mjs";
+export * from "./i18n/provider.mjs";
+export * from "./i18n/providers/fetch.mjs";
+export * from "./i18n/providers/embed.mjs";
+export * from "./i18n/translations.mjs";
+export * from "./constants.mjs";
 
 export { Monster };
 
@@ -129,5 +128,3 @@ export { Monster };
  * @memberOf Monster
  */
 class Monster {}
-
-
diff --git a/source/net/webconnect.mjs b/source/net/webconnect.mjs
index 7eb7db338f1eea01d7fee9e25b1cdc549636d14d..299f88b50078949a7e304b85b64f2fc7990df050 100644
--- a/source/net/webconnect.mjs
+++ b/source/net/webconnect.mjs
@@ -44,19 +44,19 @@ const manualCloseSymbol = Symbol("manualClose");
  * @type {{"1000": string, "1011": string, "1010": string, "1008": string, "1007": string, "1006": string, "1005": string, "1004": string, "1015": string, "1003": string, "1002": string, "1001": string, "1009": string}}
  */
 const connectionStatusCode = {
-    1000: "Normal closure",
-    1001: "Going away",
-    1002: "Protocol error",
-    1003: "Unsupported data",
-    1004: "Reserved",
-    1005: "No status code",
-    1006: "Connection closed abnormally",
-    1007: "Invalid frame payload data",
-    1008: "Policy violation",
-    1009: "Message too big",
-    1010: "Mandatory extension",
-    1011: "Internal server error",
-    1015: "TLS handshake",
+	1000: "Normal closure",
+	1001: "Going away",
+	1002: "Protocol error",
+	1003: "Unsupported data",
+	1004: "Reserved",
+	1005: "No status code",
+	1006: "Connection closed abnormally",
+	1007: "Invalid frame payload data",
+	1008: "Policy violation",
+	1009: "Message too big",
+	1010: "Mandatory extension",
+	1011: "Internal server error",
+	1015: "TLS handshake",
 };
 
 /**
@@ -65,89 +65,100 @@ const connectionStatusCode = {
  * @throws {Error} No url defined for websocket datasource.
  */
 function connectServer(resolve, reject) {
-    const self = this;
-
-    const url = self.getOption("url");
-    if (!url) {
-        reject("No url defined for webconnect.");
-        return;
-    }
-
-    let promiseAllredyResolved = false;
-
-    let connectionTimeout = self.getOption("connection.timeout");
-    if (!isInteger(connectionTimeout) || connectionTimeout < 100) {
-        connectionTimeout = 5000;
-    }
-
-    setTimeout(() => {
-        if (promiseAllredyResolved) {
-            return;
-        }
-        reject(new Error("Connection timeout"));
-    }, connectionTimeout);
-
-    let reconnectTimeout = self.getOption("connection.reconnect.timeout");
-    if (!isInteger(reconnectTimeout) || reconnectTimeout < 1000) reconnectTimeout = 1000;
-    let reconnectAttempts = self.getOption("connection.reconnect.attempts");
-    if (!isInteger(reconnectAttempts) || reconnectAttempts < 1) reconnectAttempts = 1;
-    let reconnectEnabled = self.getOption("connection.reconnect.enabled");
-    if (reconnectEnabled !== true) reconnectEnabled = false;
-
-    self[manualCloseSymbol] = false;
-    self[connectionSymbol].reconnectCounter++;
-
-    if (self[connectionSymbol].socket && self[connectionSymbol].socket.readyState < 2) {
-        self[connectionSymbol].socket.close();
-    }
-    self[connectionSymbol].socket = null;
-    self[connectionSymbol].socket = new WebSocket(url);
-
-    self[connectionSymbol].socket.onmessage = function (event) {
-        if (event.data instanceof Blob) {
-            const reader = new FileReader();
-            reader.addEventListener("loadend", function () {
-                self[receiveQueueSymbol].add(new Message(reader.result));
-            });
-            reader.readAsText(new Message(event.data));
-        } else {
-            self[receiveQueueSymbol].add(Message.fromJSON(event.data));
-        }
-    };
-
-    self[connectionSymbol].socket.onopen = function () {
-        self[connectionSymbol].reconnectCounter = 0;
-        if (typeof resolve === "function" && !promiseAllredyResolved) {
-            promiseAllredyResolved = true;
-            resolve();
-        }
-    };
-
-    self[connectionSymbol].socket.close = function (event) {
-        if (self[manualCloseSymbol]) {
-            self[manualCloseSymbol] = false;
-            return;
-        }
-
-        if (reconnectEnabled && this[connectionSymbol].reconnectCounter < reconnectAttempts) {
-            setTimeout(() => {
-                self.connect();
-            }, reconnectTimeout * this[connectionSymbol].reconnectCounter);
-        }
-    };
-
-    self[connectionSymbol].socket.onerror = (error) => {
-        if (reconnectEnabled && self[connectionSymbol].reconnectCounter < reconnectAttempts) {
-            setTimeout(() => {
-                self.connect();
-            }, reconnectTimeout * this[connectionSymbol].reconnectCounter);
-        } else {
-            if (typeof reject === "function" && !promiseAllredyResolved) {
-                promiseAllredyResolved = true;
-                reject(error);
-            }
-        }
-    };
+	const self = this;
+
+	const url = self.getOption("url");
+	if (!url) {
+		reject("No url defined for webconnect.");
+		return;
+	}
+
+	let promiseAllredyResolved = false;
+
+	let connectionTimeout = self.getOption("connection.timeout");
+	if (!isInteger(connectionTimeout) || connectionTimeout < 100) {
+		connectionTimeout = 5000;
+	}
+
+	setTimeout(() => {
+		if (promiseAllredyResolved) {
+			return;
+		}
+		reject(new Error("Connection timeout"));
+	}, connectionTimeout);
+
+	let reconnectTimeout = self.getOption("connection.reconnect.timeout");
+	if (!isInteger(reconnectTimeout) || reconnectTimeout < 1000)
+		reconnectTimeout = 1000;
+	let reconnectAttempts = self.getOption("connection.reconnect.attempts");
+	if (!isInteger(reconnectAttempts) || reconnectAttempts < 1)
+		reconnectAttempts = 1;
+	let reconnectEnabled = self.getOption("connection.reconnect.enabled");
+	if (reconnectEnabled !== true) reconnectEnabled = false;
+
+	self[manualCloseSymbol] = false;
+	self[connectionSymbol].reconnectCounter++;
+
+	if (
+		self[connectionSymbol].socket &&
+		self[connectionSymbol].socket.readyState < 2
+	) {
+		self[connectionSymbol].socket.close();
+	}
+	self[connectionSymbol].socket = null;
+	self[connectionSymbol].socket = new WebSocket(url);
+
+	self[connectionSymbol].socket.onmessage = function (event) {
+		if (event.data instanceof Blob) {
+			const reader = new FileReader();
+			reader.addEventListener("loadend", function () {
+				self[receiveQueueSymbol].add(new Message(reader.result));
+			});
+			reader.readAsText(new Message(event.data));
+		} else {
+			self[receiveQueueSymbol].add(Message.fromJSON(event.data));
+		}
+	};
+
+	self[connectionSymbol].socket.onopen = function () {
+		self[connectionSymbol].reconnectCounter = 0;
+		if (typeof resolve === "function" && !promiseAllredyResolved) {
+			promiseAllredyResolved = true;
+			resolve();
+		}
+	};
+
+	self[connectionSymbol].socket.close = function (event) {
+		if (self[manualCloseSymbol]) {
+			self[manualCloseSymbol] = false;
+			return;
+		}
+
+		if (
+			reconnectEnabled &&
+			this[connectionSymbol].reconnectCounter < reconnectAttempts
+		) {
+			setTimeout(() => {
+				self.connect();
+			}, reconnectTimeout * this[connectionSymbol].reconnectCounter);
+		}
+	};
+
+	self[connectionSymbol].socket.onerror = (error) => {
+		if (
+			reconnectEnabled &&
+			self[connectionSymbol].reconnectCounter < reconnectAttempts
+		) {
+			setTimeout(() => {
+				self.connect();
+			}, reconnectTimeout * this[connectionSymbol].reconnectCounter);
+		} else {
+			if (typeof reject === "function" && !promiseAllredyResolved) {
+				promiseAllredyResolved = true;
+				reject(error);
+			}
+		}
+	};
 }
 
 /**
@@ -161,175 +172,175 @@ function connectServer(resolve, reject) {
  * @summary The LocalStorage class encapsulates the access to data objects.
  */
 class WebConnect extends BaseWithOptions {
-    /**
-     *
-     * @param {Object} [options] options contains definitions for the webconnect.
-     */
-    constructor(options) {
-        if (isString(options)) {
-            options = { url: options };
-        }
-
-        super(options);
-
-        this[receiveQueueSymbol] = new ObservableQueue();
-        this[sendQueueSymbol] = new ObservableQueue();
-
-        this[connectionSymbol] = {};
-        this[connectionSymbol].socket = null;
-        this[connectionSymbol].reconnectCounter = 0;
-        this[manualCloseSymbol] = false;
-    }
-
-    /**
-     *
-     * @returns {Promise}
-     */
-    connect() {
-        const self = this;
-
-        return new Promise((resolve, reject) => {
-            connectServer.call(this, resolve, reject);
-        });
-    }
-
-    /**
-     * @returns {boolean}
-     */
-    isConnected() {
-        return this[connectionSymbol]?.socket?.readyState === 1;
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/net/webconnect");
-    }
-
-    /**
-     * @property {string} url=undefined Defines the resource that you wish to fetch.
-     * @property {Object} connection
-     * @property {Object} connection.timeout=5000 Defines the timeout for the connection.
-     * @property {Number} connection.reconnect.timeout The timeout in milliseconds for the reconnect.
-     * @property {Number} connection.reconnect.attempts The maximum number of reconnects.
-     * @property {Bool} connection.reconnect.enabled If the reconnect is enabled.
-     */
-    get defaults() {
-        return Object.assign({}, super.defaults, {
-            url: undefined,
-            connection: {
-                timeout: 5000,
-                reconnect: {
-                    timeout: 1000,
-                    attempts: 1,
-                    enabled: false,
-                },
-            },
-        });
-    }
-
-    /**
-     * This method closes the connection.
-     *
-     * @param {Number} [code=1000] The close code.
-     * @param {String} [reason=""] The close reason.
-     * @returns {Promise}
-     * @see https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1
-     */
-    close(statusCode, reason) {
-        if (!isInteger(statusCode) || statusCode < 1000 || statusCode > 4999) {
-            statusCode = 1000;
-        }
-        if (!isString(reason)) {
-            reason = "";
-        }
-
-        return new Promise((resolve, reject) => {
-            try {
-                this[manualCloseSymbol] = true;
-                if (this[connectionSymbol].socket) {
-                    this[connectionSymbol].socket.close(statusCode, reason);
-                }
-            } catch (error) {
-                reject(error);
-            }
-            resolve();
-        });
-    }
-
-    /**
-     * Polls the receive queue for new messages.
-     *
-     * @returns {Message}
-     */
-    poll() {
-        return this[receiveQueueSymbol].poll();
-    }
-
-    /**
-     * Are there any messages in the receive queue?
-     *
-     * @returns {boolean}
-     */
-    dataReceived() {
-        return !this[receiveQueueSymbol].isEmpty();
-    }
-
-    /**
-     * Get Message from the receive queue, but do not remove it.
-     *
-     * @returns {Object}
-     */
-    peek() {
-        return this[receiveQueueSymbol].peek();
-    }
-
-    /**
-     * Attach a new observer
-     *
-     * @param {Observer} observer
-     * @returns {ProxyObserver}
-     */
-    attachObserver(observer) {
-        this[receiveQueueSymbol].attachObserver(observer);
-        return this;
-    }
-
-    /**
-     * Detach a observer
-     *
-     * @param {Observer} observer
-     * @returns {ProxyObserver}
-     */
-    detachObserver(observer) {
-        this[receiveQueueSymbol].detachObserver(observer);
-        return this;
-    }
-
-    /**
-     * @param {Observer} observer
-     * @returns {boolean}
-     */
-    containsObserver(observer) {
-        return this[receiveQueueSymbol].containsObserver(observer);
-    }
-
-    /**
-     * @param {Message|Object} message
-     * @return {Promise}
-     */
-    send(message) {
-        const self = this;
-
-        return new Promise((resolve, reject) => {
-            if (self[connectionSymbol].socket.readyState !== 1) {
-                reject("the socket is not ready");
-            }
-
-            self[connectionSymbol].socket.send(JSON.stringify(message));
-            resolve();
-        });
-    }
+	/**
+	 *
+	 * @param {Object} [options] options contains definitions for the webconnect.
+	 */
+	constructor(options) {
+		if (isString(options)) {
+			options = { url: options };
+		}
+
+		super(options);
+
+		this[receiveQueueSymbol] = new ObservableQueue();
+		this[sendQueueSymbol] = new ObservableQueue();
+
+		this[connectionSymbol] = {};
+		this[connectionSymbol].socket = null;
+		this[connectionSymbol].reconnectCounter = 0;
+		this[manualCloseSymbol] = false;
+	}
+
+	/**
+	 *
+	 * @returns {Promise}
+	 */
+	connect() {
+		const self = this;
+
+		return new Promise((resolve, reject) => {
+			connectServer.call(this, resolve, reject);
+		});
+	}
+
+	/**
+	 * @returns {boolean}
+	 */
+	isConnected() {
+		return this[connectionSymbol]?.socket?.readyState === 1;
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/net/webconnect");
+	}
+
+	/**
+	 * @property {string} url=undefined Defines the resource that you wish to fetch.
+	 * @property {Object} connection
+	 * @property {Object} connection.timeout=5000 Defines the timeout for the connection.
+	 * @property {Number} connection.reconnect.timeout The timeout in milliseconds for the reconnect.
+	 * @property {Number} connection.reconnect.attempts The maximum number of reconnects.
+	 * @property {Bool} connection.reconnect.enabled If the reconnect is enabled.
+	 */
+	get defaults() {
+		return Object.assign({}, super.defaults, {
+			url: undefined,
+			connection: {
+				timeout: 5000,
+				reconnect: {
+					timeout: 1000,
+					attempts: 1,
+					enabled: false,
+				},
+			},
+		});
+	}
+
+	/**
+	 * This method closes the connection.
+	 *
+	 * @param {Number} [code=1000] The close code.
+	 * @param {String} [reason=""] The close reason.
+	 * @returns {Promise}
+	 * @see https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1
+	 */
+	close(statusCode, reason) {
+		if (!isInteger(statusCode) || statusCode < 1000 || statusCode > 4999) {
+			statusCode = 1000;
+		}
+		if (!isString(reason)) {
+			reason = "";
+		}
+
+		return new Promise((resolve, reject) => {
+			try {
+				this[manualCloseSymbol] = true;
+				if (this[connectionSymbol].socket) {
+					this[connectionSymbol].socket.close(statusCode, reason);
+				}
+			} catch (error) {
+				reject(error);
+			}
+			resolve();
+		});
+	}
+
+	/**
+	 * Polls the receive queue for new messages.
+	 *
+	 * @returns {Message}
+	 */
+	poll() {
+		return this[receiveQueueSymbol].poll();
+	}
+
+	/**
+	 * Are there any messages in the receive queue?
+	 *
+	 * @returns {boolean}
+	 */
+	dataReceived() {
+		return !this[receiveQueueSymbol].isEmpty();
+	}
+
+	/**
+	 * Get Message from the receive queue, but do not remove it.
+	 *
+	 * @returns {Object}
+	 */
+	peek() {
+		return this[receiveQueueSymbol].peek();
+	}
+
+	/**
+	 * Attach a new observer
+	 *
+	 * @param {Observer} observer
+	 * @returns {ProxyObserver}
+	 */
+	attachObserver(observer) {
+		this[receiveQueueSymbol].attachObserver(observer);
+		return this;
+	}
+
+	/**
+	 * Detach a observer
+	 *
+	 * @param {Observer} observer
+	 * @returns {ProxyObserver}
+	 */
+	detachObserver(observer) {
+		this[receiveQueueSymbol].detachObserver(observer);
+		return this;
+	}
+
+	/**
+	 * @param {Observer} observer
+	 * @returns {boolean}
+	 */
+	containsObserver(observer) {
+		return this[receiveQueueSymbol].containsObserver(observer);
+	}
+
+	/**
+	 * @param {Message|Object} message
+	 * @return {Promise}
+	 */
+	send(message) {
+		const self = this;
+
+		return new Promise((resolve, reject) => {
+			if (self[connectionSymbol].socket.readyState !== 1) {
+				reject("the socket is not ready");
+			}
+
+			self[connectionSymbol].socket.send(JSON.stringify(message));
+			resolve();
+		});
+	}
 }
diff --git a/source/net/webconnect/message.mjs b/source/net/webconnect/message.mjs
index 09c42a9013ed10e557eb1b5d2e239c480d192db6..a8411bdfa999d858f7b144da0d756b181c40e668 100644
--- a/source/net/webconnect/message.mjs
+++ b/source/net/webconnect/message.mjs
@@ -22,38 +22,38 @@ const dataSymbol = Symbol("@@data");
  * @summary The Message class encapsulates a WebSocket message.
  */
 class Message extends Base {
-    /**
-     * @param {Object} data
-     * @throws {TypeError} value is not a object
-     */
-    constructor(data) {
-        super();
-        this[dataSymbol] = validateObject(data);
-    }
+	/**
+	 * @param {Object} data
+	 * @throws {TypeError} value is not a object
+	 */
+	constructor(data) {
+		super();
+		this[dataSymbol] = validateObject(data);
+	}
 
-    /**
-     * Returns the raw message.
-     *
-     * @returns {object}
-     */
-    getData() {
-        return this[dataSymbol];
-    }
+	/**
+	 * Returns the raw message.
+	 *
+	 * @returns {object}
+	 */
+	getData() {
+		return this[dataSymbol];
+	}
 
-    /**
-     * @returns {*}
-     */
-    toJSON() {
-        return this[dataSymbol];
-    }
+	/**
+	 * @returns {*}
+	 */
+	toJSON() {
+		return this[dataSymbol];
+	}
 
-    /**
-     * @param {string} json
-     * @returns {Message}
-     * @throws {TypeError} value is not a string
-     */
-    static fromJSON(json) {
-        validateString(json);
-        return new Message(JSON.parse(json));
-    }
+	/**
+	 * @param {string} json
+	 * @returns {Message}
+	 * @throws {TypeError} value is not a string
+	 */
+	static fromJSON(json) {
+		validateString(json);
+		return new Message(JSON.parse(json));
+	}
 }
diff --git a/source/text/bracketed-key-value-hash.mjs b/source/text/bracketed-key-value-hash.mjs
index 55831dcba442b88cc2727199eedf92c008bd4a24..4fe3e50d0215db998f575f0d68ad21433bfc22b2 100644
--- a/source/text/bracketed-key-value-hash.mjs
+++ b/source/text/bracketed-key-value-hash.mjs
@@ -44,152 +44,155 @@ export { parseBracketedKeyValueHash, createBracketedKeyValueHash };
  * @returns {Object} - An object representing the parsed result, with keys representing the selectors and values representing the key-value pairs associated with each selector.
  *                    - Returns an empty object if there was an error during parsing. */
 function parseBracketedKeyValueHash(hashString) {
-    const selectors = {};
-    //const selectorStack = [];
-    //const keyValueStack = [];
-
-    const trimmedHashString = hashString.trim();
-    const cleanedHashString = trimmedHashString.charAt(0) === "#" ? trimmedHashString.slice(1) : trimmedHashString;
-
-    //const selectors = (keyValueStack.length > 0) ? result[selectorStack[selectorStack.length - 1]] : result;
-    let currentSelector = "";
-
-    function addToResult(key, value) {
-        if (currentSelector && key) {
-            if (!selectors[currentSelector]) {
-                selectors[currentSelector] = {};
-            }
-
-            selectors[currentSelector][key] = value;
-        }
-    }
-
-    let currentKey = "";
-    let currentValue = "";
-    let inKey = true;
-    let inValue = false;
-    let inQuotedValue = false;
-    let inSelector = true;
-    let escaped = false;
-    let quotedValueStartChar = "";
-
-    for (let i = 0; i < cleanedHashString.length; i++) {
-        const c = cleanedHashString[i];
-        const nextChar = cleanedHashString?.[i + 1];
-
-        if (c === "\\" && !escaped) {
-            escaped = true;
-            continue;
-        }
-
-        if (escaped) {
-            if (inSelector) {
-                currentSelector += c;
-            } else if (inKey) {
-                currentKey += c;
-            } else if (inValue) {
-                currentValue += c;
-            }
-            escaped = false;
-            continue;
-        }
-
-        if (inQuotedValue && quotedValueStartChar !== c) {
-            if (inSelector) {
-                currentSelector += c;
-            } else if (inKey) {
-                currentKey += c;
-            } else if (inValue) {
-                currentValue += c;
-            }
-
-            continue;
-        }
-
-        if (c === ";" && inSelector) {
-            inSelector = true;
-            currentSelector = "";
-            continue;
-        }
-
-        if (inSelector === true && c !== "(") {
-            currentSelector += c;
-            continue;
-        }
-
-        if (c === "(" && inSelector) {
-            inSelector = false;
-            inKey = true;
-
-            currentKey = "";
-            continue;
-        }
-
-        if (inKey === true && c !== "=") {
-            currentKey += c;
-            continue;
-        }
-
-        if (c === "=" && inKey) {
-            inKey = false;
-            inValue = true;
-
-            if (nextChar === '"' || nextChar === "'") {
-                inQuotedValue = true;
-                quotedValueStartChar = nextChar;
-                i++;
-                continue;
-            }
-
-            currentValue = "";
-            continue;
-        }
-
-        if (inValue === true) {
-            if (inQuotedValue) {
-                if (c === quotedValueStartChar) {
-                    inQuotedValue = false;
-                    continue;
-                }
-
-                currentValue += c;
-                continue;
-            }
-
-            if (c === ",") {
-                inValue = false;
-                inKey = true;
-                const decodedCurrentValue = decodeURIComponent(currentValue);
-                addToResult(currentKey, decodedCurrentValue);
-                currentKey = "";
-                currentValue = "";
-                continue;
-            }
-
-            if (c === ")") {
-                inValue = false;
-                //inKey = true;
-                inSelector = true;
-
-                const decodedCurrentValue = decodeURIComponent(currentValue);
-                addToResult(currentKey, decodedCurrentValue);
-                currentKey = "";
-                currentValue = "";
-                currentSelector = "";
-                continue;
-            }
-
-            currentValue += c;
-
-            continue;
-        }
-    }
-
-    if (inSelector) {
-        return selectors;
-    }
-
-    return {};
+	const selectors = {};
+	//const selectorStack = [];
+	//const keyValueStack = [];
+
+	const trimmedHashString = hashString.trim();
+	const cleanedHashString =
+		trimmedHashString.charAt(0) === "#"
+			? trimmedHashString.slice(1)
+			: trimmedHashString;
+
+	//const selectors = (keyValueStack.length > 0) ? result[selectorStack[selectorStack.length - 1]] : result;
+	let currentSelector = "";
+
+	function addToResult(key, value) {
+		if (currentSelector && key) {
+			if (!selectors[currentSelector]) {
+				selectors[currentSelector] = {};
+			}
+
+			selectors[currentSelector][key] = value;
+		}
+	}
+
+	let currentKey = "";
+	let currentValue = "";
+	let inKey = true;
+	let inValue = false;
+	let inQuotedValue = false;
+	let inSelector = true;
+	let escaped = false;
+	let quotedValueStartChar = "";
+
+	for (let i = 0; i < cleanedHashString.length; i++) {
+		const c = cleanedHashString[i];
+		const nextChar = cleanedHashString?.[i + 1];
+
+		if (c === "\\" && !escaped) {
+			escaped = true;
+			continue;
+		}
+
+		if (escaped) {
+			if (inSelector) {
+				currentSelector += c;
+			} else if (inKey) {
+				currentKey += c;
+			} else if (inValue) {
+				currentValue += c;
+			}
+			escaped = false;
+			continue;
+		}
+
+		if (inQuotedValue && quotedValueStartChar !== c) {
+			if (inSelector) {
+				currentSelector += c;
+			} else if (inKey) {
+				currentKey += c;
+			} else if (inValue) {
+				currentValue += c;
+			}
+
+			continue;
+		}
+
+		if (c === ";" && inSelector) {
+			inSelector = true;
+			currentSelector = "";
+			continue;
+		}
+
+		if (inSelector === true && c !== "(") {
+			currentSelector += c;
+			continue;
+		}
+
+		if (c === "(" && inSelector) {
+			inSelector = false;
+			inKey = true;
+
+			currentKey = "";
+			continue;
+		}
+
+		if (inKey === true && c !== "=") {
+			currentKey += c;
+			continue;
+		}
+
+		if (c === "=" && inKey) {
+			inKey = false;
+			inValue = true;
+
+			if (nextChar === '"' || nextChar === "'") {
+				inQuotedValue = true;
+				quotedValueStartChar = nextChar;
+				i++;
+				continue;
+			}
+
+			currentValue = "";
+			continue;
+		}
+
+		if (inValue === true) {
+			if (inQuotedValue) {
+				if (c === quotedValueStartChar) {
+					inQuotedValue = false;
+					continue;
+				}
+
+				currentValue += c;
+				continue;
+			}
+
+			if (c === ",") {
+				inValue = false;
+				inKey = true;
+				const decodedCurrentValue = decodeURIComponent(currentValue);
+				addToResult(currentKey, decodedCurrentValue);
+				currentKey = "";
+				currentValue = "";
+				continue;
+			}
+
+			if (c === ")") {
+				inValue = false;
+				//inKey = true;
+				inSelector = true;
+
+				const decodedCurrentValue = decodeURIComponent(currentValue);
+				addToResult(currentKey, decodedCurrentValue);
+				currentKey = "";
+				currentValue = "";
+				currentSelector = "";
+				continue;
+			}
+
+			currentValue += c;
+
+			continue;
+		}
+	}
+
+	if (inSelector) {
+		return selectors;
+	}
+
+	return {};
 }
 
 /**
@@ -201,37 +204,37 @@ function parseBracketedKeyValueHash(hashString) {
  * @since 3.37.0
  */
 function createBracketedKeyValueHash(object, addHashPrefix = true) {
-    if (!object) {
-        return addHashPrefix ? "#" : "";
-    }
-
-    let hashString = "";
-
-    function encodeKeyValue(key, value) {
-        return encodeURIComponent(key) + "=" + encodeURIComponent(value);
-    }
-
-    for (const selector in object) {
-        if (object.hasOwnProperty(selector)) {
-            const keyValuePairs = object[selector];
-            let selectorString = selector;
-            let keyValueString = "";
-
-            for (const key in keyValuePairs) {
-                if (keyValuePairs.hasOwnProperty(key)) {
-                    const value = keyValuePairs[key];
-                    keyValueString += keyValueString.length === 0 ? "" : ",";
-                    keyValueString += encodeKeyValue(key, value);
-                }
-            }
-
-            if (keyValueString.length > 0) {
-                selectorString += "(" + keyValueString + ")";
-                hashString += hashString.length === 0 ? "" : ";";
-                hashString += selectorString;
-            }
-        }
-    }
-
-    return addHashPrefix ? "#" + hashString : hashString;
+	if (!object) {
+		return addHashPrefix ? "#" : "";
+	}
+
+	let hashString = "";
+
+	function encodeKeyValue(key, value) {
+		return encodeURIComponent(key) + "=" + encodeURIComponent(value);
+	}
+
+	for (const selector in object) {
+		if (object.hasOwnProperty(selector)) {
+			const keyValuePairs = object[selector];
+			let selectorString = selector;
+			let keyValueString = "";
+
+			for (const key in keyValuePairs) {
+				if (keyValuePairs.hasOwnProperty(key)) {
+					const value = keyValuePairs[key];
+					keyValueString += keyValueString.length === 0 ? "" : ",";
+					keyValueString += encodeKeyValue(key, value);
+				}
+			}
+
+			if (keyValueString.length > 0) {
+				selectorString += "(" + keyValueString + ")";
+				hashString += hashString.length === 0 ? "" : ";";
+				hashString += selectorString;
+			}
+		}
+	}
+
+	return addHashPrefix ? "#" + hashString : hashString;
 }
diff --git a/source/text/formatter.mjs b/source/text/formatter.mjs
index 79db10f9cbfde9d48f6f4b6c20017668571a5c48..b238eebb31d4f0ea9eadd891ae3e2afb04349587 100644
--- a/source/text/formatter.mjs
+++ b/source/text/formatter.mjs
@@ -109,115 +109,117 @@ const workingDataSymbol = Symbol("workingData");
  * @memberOf Monster.Text
  */
 class Formatter extends BaseWithOptions {
-    /**
-     * Default values for the markers are `${` and `}`
-     *
-     * @param {object} object
-     * @throws {TypeError} value is not a object
-     */
-    constructor(object, options) {
-        super(options);
-        this[internalObjectSymbol] = object || {};
-        this[markerOpenIndexSymbol] = 0;
-        this[markerCloseIndexSymbol] = 0;
-    }
-
-    /**
-     * @property {object} marker
-     * @property {array} marker.open=["${"]
-     * @property {array} marker.close=["${"]
-     * @property {object} parameter
-     * @property {string} parameter.delimiter="::"
-     * @property {string} parameter.assignment="="
-     * @property {object} callbacks={}
-     */
-    get defaults() {
-        return extend({}, super.defaults, {
-            marker: {
-                open: ["${"],
-                close: ["}"],
-            },
-            parameter: {
-                delimiter: "::",
-                assignment: "=",
-            },
-            callbacks: {},
-        });
-    }
-
-    /**
-     * Set new Parameter Character
-     *
-     * Default values for the chars are `::` and `=`
-     *
-     * ```
-     * formatter.setParameterChars('#');
-     * formatter.setParameterChars('[',']');
-     * formatter.setParameterChars('i18n{','}');
-     * ```
-     *
-     * @param {string} delimiter
-     * @param {string} assignment
-     * @return {Formatter}
-     * @since 1.24.0
-     * @throws {TypeError} value is not a string
-     */
-    setParameterChars(delimiter, assignment) {
-        if (delimiter !== undefined) {
-            this[internalSymbol]["parameter"]["delimiter"] = validateString(delimiter);
-        }
-
-        if (assignment !== undefined) {
-            this[internalSymbol]["parameter"]["assignment"] = validateString(assignment);
-        }
-
-        return this;
-    }
-
-    /**
-     * Set new Marker
-     *
-     * Default values for the markers are `${` and `}`
-     *
-     * ```
-     * formatter.setMarker('#'); // open and close are both #
-     * formatter.setMarker('[',']');
-     * formatter.setMarker('i18n{','}');
-     * ```
-     *
-     * @param {array|string} open
-     * @param {array|string|undefined} close
-     * @return {Formatter}
-     * @since 1.12.0
-     * @throws {TypeError} value is not a string
-     */
-    setMarker(open, close) {
-        if (close === undefined) {
-            close = open;
-        }
-
-        if (isString(open)) open = [open];
-        if (isString(close)) close = [close];
-
-        this[internalSymbol]["marker"]["open"] = validateArray(open);
-        this[internalSymbol]["marker"]["close"] = validateArray(close);
-        return this;
-    }
-
-    /**
-     *
-     * @param {string} text
-     * @return {string}
-     * @throws {TypeError} value is not a string
-     * @throws {Error} too deep nesting
-     */
-    format(text) {
-        this[watchdogSymbol] = 0;
-        this[markerOpenIndexSymbol] = 0;
-        this[markerCloseIndexSymbol] = 0;
-        this[workingDataSymbol] = {};
-        return format.call(this, text);
-    }
+	/**
+	 * Default values for the markers are `${` and `}`
+	 *
+	 * @param {object} object
+	 * @throws {TypeError} value is not a object
+	 */
+	constructor(object, options) {
+		super(options);
+		this[internalObjectSymbol] = object || {};
+		this[markerOpenIndexSymbol] = 0;
+		this[markerCloseIndexSymbol] = 0;
+	}
+
+	/**
+	 * @property {object} marker
+	 * @property {array} marker.open=["${"]
+	 * @property {array} marker.close=["${"]
+	 * @property {object} parameter
+	 * @property {string} parameter.delimiter="::"
+	 * @property {string} parameter.assignment="="
+	 * @property {object} callbacks={}
+	 */
+	get defaults() {
+		return extend({}, super.defaults, {
+			marker: {
+				open: ["${"],
+				close: ["}"],
+			},
+			parameter: {
+				delimiter: "::",
+				assignment: "=",
+			},
+			callbacks: {},
+		});
+	}
+
+	/**
+	 * Set new Parameter Character
+	 *
+	 * Default values for the chars are `::` and `=`
+	 *
+	 * ```
+	 * formatter.setParameterChars('#');
+	 * formatter.setParameterChars('[',']');
+	 * formatter.setParameterChars('i18n{','}');
+	 * ```
+	 *
+	 * @param {string} delimiter
+	 * @param {string} assignment
+	 * @return {Formatter}
+	 * @since 1.24.0
+	 * @throws {TypeError} value is not a string
+	 */
+	setParameterChars(delimiter, assignment) {
+		if (delimiter !== undefined) {
+			this[internalSymbol]["parameter"]["delimiter"] =
+				validateString(delimiter);
+		}
+
+		if (assignment !== undefined) {
+			this[internalSymbol]["parameter"]["assignment"] =
+				validateString(assignment);
+		}
+
+		return this;
+	}
+
+	/**
+	 * Set new Marker
+	 *
+	 * Default values for the markers are `${` and `}`
+	 *
+	 * ```
+	 * formatter.setMarker('#'); // open and close are both #
+	 * formatter.setMarker('[',']');
+	 * formatter.setMarker('i18n{','}');
+	 * ```
+	 *
+	 * @param {array|string} open
+	 * @param {array|string|undefined} close
+	 * @return {Formatter}
+	 * @since 1.12.0
+	 * @throws {TypeError} value is not a string
+	 */
+	setMarker(open, close) {
+		if (close === undefined) {
+			close = open;
+		}
+
+		if (isString(open)) open = [open];
+		if (isString(close)) close = [close];
+
+		this[internalSymbol]["marker"]["open"] = validateArray(open);
+		this[internalSymbol]["marker"]["close"] = validateArray(close);
+		return this;
+	}
+
+	/**
+	 *
+	 * @param {string} text
+	 * @return {string}
+	 * @throws {TypeError} value is not a string
+	 * @throws {Error} too deep nesting
+	 */
+	format(text) {
+		this[watchdogSymbol] = 0;
+		this[markerOpenIndexSymbol] = 0;
+		this[markerCloseIndexSymbol] = 0;
+		this[workingDataSymbol] = {};
+		return format.call(this, text);
+	}
 }
 
 /**
@@ -225,34 +227,45 @@ class Formatter extends BaseWithOptions {
  * @return {string}
  */
 function format(text) {
-    const self = this;
-
-    self[watchdogSymbol]++;
-    if (this[watchdogSymbol] > 20) {
-        throw new Error("too deep nesting");
-    }
-
-    let openMarker = self[internalSymbol]["marker"]["open"]?.[this[markerOpenIndexSymbol]];
-    let closeMarker = self[internalSymbol]["marker"]["close"]?.[this[markerCloseIndexSymbol]];
-
-    // contains no placeholders
-    if (text.indexOf(openMarker) === -1 || text.indexOf(closeMarker) === -1) {
-        return text;
-    }
-
-    let result = tokenize.call(this, validateString(text), openMarker, closeMarker);
-
-    if (self[internalSymbol]["marker"]["open"]?.[this[markerOpenIndexSymbol] + 1]) {
-        this[markerOpenIndexSymbol]++;
-    }
-
-    if (self[internalSymbol]["marker"]["close"]?.[this[markerCloseIndexSymbol] + 1]) {
-        this[markerCloseIndexSymbol]++;
-    }
-
-    result = format.call(self, result);
-
-    return result;
+	const self = this;
+
+	self[watchdogSymbol]++;
+	if (this[watchdogSymbol] > 20) {
+		throw new Error("too deep nesting");
+	}
+
+	let openMarker =
+		self[internalSymbol]["marker"]["open"]?.[this[markerOpenIndexSymbol]];
+	let closeMarker =
+		self[internalSymbol]["marker"]["close"]?.[this[markerCloseIndexSymbol]];
+
+	// contains no placeholders
+	if (text.indexOf(openMarker) === -1 || text.indexOf(closeMarker) === -1) {
+		return text;
+	}
+
+	let result = tokenize.call(
+		this,
+		validateString(text),
+		openMarker,
+		closeMarker,
+	);
+
+	if (
+		self[internalSymbol]["marker"]["open"]?.[this[markerOpenIndexSymbol] + 1]
+	) {
+		this[markerOpenIndexSymbol]++;
+	}
+
+	if (
+		self[internalSymbol]["marker"]["close"]?.[this[markerCloseIndexSymbol] + 1]
+	) {
+		this[markerCloseIndexSymbol]++;
+	}
+
+	result = format.call(self, result);
+
+	return result;
 }
 
 /**
@@ -263,77 +276,93 @@ function format(text) {
  * @return {string}
  */
 function tokenize(text, openMarker, closeMarker) {
-    const self = this;
-
-    let formatted = [];
-
-    const parameterAssignment = self[internalSymbol]["parameter"]["assignment"];
-    const parameterDelimiter = self[internalSymbol]["parameter"]["delimiter"];
-    const callbacks = self[internalSymbol]["callbacks"];
-
-    while (true) {
-        let startIndex = text.indexOf(openMarker);
-        // no marker
-        if (startIndex === -1) {
-            formatted.push(text);
-            break;
-        } else if (startIndex > 0) {
-            formatted.push(text.substring(0, startIndex));
-            text = text.substring(startIndex);
-        }
-
-        let endIndex = text.substring(openMarker.length).indexOf(closeMarker);
-        if (endIndex !== -1) endIndex += openMarker.length;
-        let insideStartIndex = text.substring(openMarker.length).indexOf(openMarker);
-        if (insideStartIndex !== -1) {
-            insideStartIndex += openMarker.length;
-            if (insideStartIndex < endIndex) {
-                let result = tokenize.call(self, text.substring(insideStartIndex), openMarker, closeMarker);
-                text = text.substring(0, insideStartIndex) + result;
-                endIndex = text.substring(openMarker.length).indexOf(closeMarker);
-                if (endIndex !== -1) endIndex += openMarker.length;
-            }
-        }
-
-        if (endIndex === -1) {
-            throw new Error("syntax error in formatter template");
-        }
-
-        let key = text.substring(openMarker.length, endIndex);
-        let parts = key.split(parameterDelimiter);
-        let currentPipe = parts.shift();
-
-        self[workingDataSymbol] = extend({}, self[internalObjectSymbol], self[workingDataSymbol]);
-
-        for (const kv of parts) {
-            const [k, v] = kv.split(parameterAssignment);
-            self[workingDataSymbol][k] = v;
-        }
-
-        const t1 = key.split("|").shift().trim(); // pipe symbol
-        const t2 = t1.split("::").shift().trim(); // key value delimiter
-        const t3 = t2.split(".").shift().trim(); // path delimiter
-        let prefix = self[workingDataSymbol]?.[t3] ? "path:" : "static:";
-
-        let command = "";
-        if (prefix && key.indexOf(prefix) !== 0 && key.indexOf("path:") !== 0 && key.indexOf("static:") !== 0) {
-            command = prefix;
-        }
-
-        command += currentPipe;
-
-        const pipe = new Pipe(command);
-
-        if (isObject(callbacks)) {
-            for (const [name, callback] of Object.entries(callbacks)) {
-                pipe.setCallback(name, callback);
-            }
-        }
-
-        formatted.push(validateString(pipe.run(self[workingDataSymbol])));
-
-        text = text.substring(endIndex + closeMarker.length);
-    }
-
-    return formatted.join("");
+	const self = this;
+
+	let formatted = [];
+
+	const parameterAssignment = self[internalSymbol]["parameter"]["assignment"];
+	const parameterDelimiter = self[internalSymbol]["parameter"]["delimiter"];
+	const callbacks = self[internalSymbol]["callbacks"];
+
+	while (true) {
+		let startIndex = text.indexOf(openMarker);
+		// no marker
+		if (startIndex === -1) {
+			formatted.push(text);
+			break;
+		} else if (startIndex > 0) {
+			formatted.push(text.substring(0, startIndex));
+			text = text.substring(startIndex);
+		}
+
+		let endIndex = text.substring(openMarker.length).indexOf(closeMarker);
+		if (endIndex !== -1) endIndex += openMarker.length;
+		let insideStartIndex = text
+			.substring(openMarker.length)
+			.indexOf(openMarker);
+		if (insideStartIndex !== -1) {
+			insideStartIndex += openMarker.length;
+			if (insideStartIndex < endIndex) {
+				let result = tokenize.call(
+					self,
+					text.substring(insideStartIndex),
+					openMarker,
+					closeMarker,
+				);
+				text = text.substring(0, insideStartIndex) + result;
+				endIndex = text.substring(openMarker.length).indexOf(closeMarker);
+				if (endIndex !== -1) endIndex += openMarker.length;
+			}
+		}
+
+		if (endIndex === -1) {
+			throw new Error("syntax error in formatter template");
+		}
+
+		let key = text.substring(openMarker.length, endIndex);
+		let parts = key.split(parameterDelimiter);
+		let currentPipe = parts.shift();
+
+		self[workingDataSymbol] = extend(
+			{},
+			self[internalObjectSymbol],
+			self[workingDataSymbol],
+		);
+
+		for (const kv of parts) {
+			const [k, v] = kv.split(parameterAssignment);
+			self[workingDataSymbol][k] = v;
+		}
+
+		const t1 = key.split("|").shift().trim(); // pipe symbol
+		const t2 = t1.split("::").shift().trim(); // key value delimiter
+		const t3 = t2.split(".").shift().trim(); // path delimiter
+		let prefix = self[workingDataSymbol]?.[t3] ? "path:" : "static:";
+
+		let command = "";
+		if (
+			prefix &&
+			key.indexOf(prefix) !== 0 &&
+			key.indexOf("path:") !== 0 &&
+			key.indexOf("static:") !== 0
+		) {
+			command = prefix;
+		}
+
+		command += currentPipe;
+
+		const pipe = new Pipe(command);
+
+		if (isObject(callbacks)) {
+			for (const [name, callback] of Object.entries(callbacks)) {
+				pipe.setCallback(name, callback);
+			}
+		}
+
+		formatted.push(validateString(pipe.run(self[workingDataSymbol])));
+
+		text = text.substring(endIndex + closeMarker.length);
+	}
+
+	return formatted.join("");
 }
diff --git a/source/text/generate-range-comparison-expression.mjs b/source/text/generate-range-comparison-expression.mjs
index 367516e3cd12f03cf874936d88a0731224a3b402..1d28445bd4ef63e91a4b6b5cad654ed73e7a4d76 100644
--- a/source/text/generate-range-comparison-expression.mjs
+++ b/source/text/generate-range-comparison-expression.mjs
@@ -56,38 +56,60 @@ export { generateRangeComparisonExpression };
  * @memberOf Monster.Text
  * @summary Generates a comparison expression based on a range of values.
  */
-function generateRangeComparisonExpression(expression, valueName, options = {}) {
-    const { urlEncode = false, andOp = "&&", orOp = "||", eqOp = "==", geOp = ">=", leOp = "<=" } = options;
-    const ranges = expression.split(",");
-    let comparison = "";
-    for (let i = 0; i < ranges.length; i++) {
-        const range = ranges[i].trim();
-        if (range === "") {
-            throw new Error(`Invalid range '${range}'`);
-        } else if (range.includes("-")) {
-            const [start, end] = range.split("-").map((s) => (s === "" ? null : parseFloat(s)));
-            if ((start !== null && isNaN(start)) || (end !== null && isNaN(end))) {
-                throw new Error(`Invalid value in range '${range}'`);
-            }
-            if (start !== null && end !== null && start > end) {
-                throw new Error(`Invalid range '${range}'`);
-            }
-            const compStart =
-                start !== null ? `${valueName}${urlEncode ? encodeURIComponent(geOp) : geOp}${start}` : "";
-            const compEnd = end !== null ? `${valueName}${urlEncode ? encodeURIComponent(leOp) : leOp}${end}` : "";
-            const compRange = `${compStart}${compStart && compEnd ? ` ${andOp} ` : ""}${compEnd}`;
-            comparison += ranges.length > 1 ? `(${compRange})` : compRange;
-        } else {
-            const value = parseFloat(range);
-            if (isNaN(value)) {
-                throw new Error(`Invalid value '${range}'`);
-            }
-            const compValue = `${valueName}${urlEncode ? encodeURIComponent(eqOp) : eqOp}${value}`;
-            comparison += ranges.length > 1 ? `(${compValue})` : compValue;
-        }
-        if (i < ranges.length - 1) {
-            comparison += ` ${orOp} `;
-        }
-    }
-    return comparison;
+function generateRangeComparisonExpression(
+	expression,
+	valueName,
+	options = {},
+) {
+	const {
+		urlEncode = false,
+		andOp = "&&",
+		orOp = "||",
+		eqOp = "==",
+		geOp = ">=",
+		leOp = "<=",
+	} = options;
+	const ranges = expression.split(",");
+	let comparison = "";
+	for (let i = 0; i < ranges.length; i++) {
+		const range = ranges[i].trim();
+		if (range === "") {
+			throw new Error(`Invalid range '${range}'`);
+		} else if (range.includes("-")) {
+			const [start, end] = range
+				.split("-")
+				.map((s) => (s === "" ? null : parseFloat(s)));
+			if ((start !== null && isNaN(start)) || (end !== null && isNaN(end))) {
+				throw new Error(`Invalid value in range '${range}'`);
+			}
+			if (start !== null && end !== null && start > end) {
+				throw new Error(`Invalid range '${range}'`);
+			}
+			const compStart =
+				start !== null
+					? `${valueName}${urlEncode ? encodeURIComponent(geOp) : geOp}${start}`
+					: "";
+			const compEnd =
+				end !== null
+					? `${valueName}${urlEncode ? encodeURIComponent(leOp) : leOp}${end}`
+					: "";
+			const compRange = `${compStart}${
+				compStart && compEnd ? ` ${andOp} ` : ""
+			}${compEnd}`;
+			comparison += ranges.length > 1 ? `(${compRange})` : compRange;
+		} else {
+			const value = parseFloat(range);
+			if (isNaN(value)) {
+				throw new Error(`Invalid value '${range}'`);
+			}
+			const compValue = `${valueName}${
+				urlEncode ? encodeURIComponent(eqOp) : eqOp
+			}${value}`;
+			comparison += ranges.length > 1 ? `(${compValue})` : compValue;
+		}
+		if (i < ranges.length - 1) {
+			comparison += ` ${orOp} `;
+		}
+	}
+	return comparison;
 }
diff --git a/source/types/base.mjs b/source/types/base.mjs
index 1e48be0780dd4b92b4f87171a4b1491a0bc00473..d7cd4ba7f54b5138401f5e4468f3291d7a82c3b2 100644
--- a/source/types/base.mjs
+++ b/source/types/base.mjs
@@ -36,50 +36,54 @@ export { Base };
  * @memberOf Monster.Types
  */
 class Base extends Object {
-    /**
-     *
-     * @returns {string}
-     */
-    toString() {
-        return JSON.stringify(this);
-    }
+	/**
+	 *
+	 * @returns {string}
+	 */
+	toString() {
+		return JSON.stringify(this);
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/types/base");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/types/base");
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @param that
-     * @returns {boolean}
-     * @since 2.1.0
-     */
-    static [Symbol.hasInstance](that) {
-        if (that === undefined || that === null || (typeof that !== "object" && typeof that !== "function")) {
-            return false;
-        }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @param that
+	 * @returns {boolean}
+	 * @since 2.1.0
+	 */
+	static [Symbol.hasInstance](that) {
+		if (
+			that === undefined ||
+			that === null ||
+			(typeof that !== "object" && typeof that !== "function")
+		) {
+			return false;
+		}
 
-        const thatClass = Object.getPrototypeOf(that);
-        if (
-            thatClass === undefined ||
-            thatClass === null ||
-            (typeof thatClass !== "object" && typeof thatClass !== "function")
-        ) {
-            return false;
-        }
+		const thatClass = Object.getPrototypeOf(that);
+		if (
+			thatClass === undefined ||
+			thatClass === null ||
+			(typeof thatClass !== "object" && typeof thatClass !== "function")
+		) {
+			return false;
+		}
 
-        if (checkInstanceSymbol.apply(this, [thatClass]) === true) {
-            return true;
-        }
+		if (checkInstanceSymbol.apply(this, [thatClass]) === true) {
+			return true;
+		}
 
-        // this call the static method of the super class, if there is one
-        return super[Symbol.hasInstance](that);
-    }
+		// this call the static method of the super class, if there is one
+		return super[Symbol.hasInstance](that);
+	}
 }
 
 /**
@@ -91,31 +95,35 @@ class Base extends Object {
  * @since 2.1.0
  */
 function checkInstanceSymbol(obj) {
-    if (this.hasOwnProperty(instanceSymbol) === false) {
-        return false;
-    }
+	if (this.hasOwnProperty(instanceSymbol) === false) {
+		return false;
+	}
 
-    const proto = obj?.constructor;
-    if (proto === undefined || proto === null || (typeof proto !== "object" && typeof proto !== "function")) {
-        return false;
-    }
+	const proto = obj?.constructor;
+	if (
+		proto === undefined ||
+		proto === null ||
+		(typeof proto !== "object" && typeof proto !== "function")
+	) {
+		return false;
+	}
 
-    if (proto.hasOwnProperty(instanceSymbol) !== true) {
-        return checkInstanceSymbol.apply(this, [obj.__proto__]);
-    }
+	if (proto.hasOwnProperty(instanceSymbol) !== true) {
+		return checkInstanceSymbol.apply(this, [obj.__proto__]);
+	}
 
-    const symbol = proto[instanceSymbol];
-    if (symbol === undefined) {
-        if (obj.__proto__) {
-            return checkInstanceSymbol(obj.__proto__);
-        } else {
-            return false;
-        }
-    }
+	const symbol = proto[instanceSymbol];
+	if (symbol === undefined) {
+		if (obj.__proto__) {
+			return checkInstanceSymbol(obj.__proto__);
+		} else {
+			return false;
+		}
+	}
 
-    if (symbol === this[instanceSymbol]) {
-        return true;
-    }
+	if (symbol === this[instanceSymbol]) {
+		return true;
+	}
 
-    return checkInstanceSymbol.apply(this, [obj.__proto__]);
+	return checkInstanceSymbol.apply(this, [obj.__proto__]);
 }
diff --git a/source/types/basewithoptions.mjs b/source/types/basewithoptions.mjs
index 9ad16e121d2e8e8a89eecda62115306b88008d81..793e33bac1ed7e384e216128562fbc7ab4e0ea9c 100644
--- a/source/types/basewithoptions.mjs
+++ b/source/types/basewithoptions.mjs
@@ -29,56 +29,56 @@ export { BaseWithOptions };
  * @deprecated since 3.15.0 use {@link Monster.Types.Base} with {@link Monster.Types.equipWithInternal} instead.
  */
 class BaseWithOptions extends Base {
-    /**
-     *
-     * @param {object} options
-     */
-    constructor(options) {
-        super();
+	/**
+	 *
+	 * @param {object} options
+	 */
+	constructor(options) {
+		super();
 
-        if (options === undefined) {
-            options = {};
-        }
+		if (options === undefined) {
+			options = {};
+		}
 
-        this[internalSymbol] = extend({}, this.defaults, validateObject(options));
-    }
+		this[internalSymbol] = extend({}, this.defaults, validateObject(options));
+	}
 
-    /**
-     * This getter provides the options. Derived classes overwrite
-     * this getter with their own values. It is good karma to always include
-     * the values from the parent class.
-     *
-     * ```javascript
-     * get defaults() {
-     *     return Object.assign({}, super.defaults, {
-     *         mykey: true
-     *     });
-     * }
-     *
-     * ```
-     *
-     * @return {object}
-     */
-    get defaults() {
-        return {};
-    }
+	/**
+	 * This getter provides the options. Derived classes overwrite
+	 * this getter with their own values. It is good karma to always include
+	 * the values from the parent class.
+	 *
+	 * ```javascript
+	 * get defaults() {
+	 *     return Object.assign({}, super.defaults, {
+	 *         mykey: true
+	 *     });
+	 * }
+	 *
+	 * ```
+	 *
+	 * @return {object}
+	 */
+	get defaults() {
+		return {};
+	}
 
-    /**
-     * nested options can be specified by path `a.b.c`
-     *
-     * @param {string} path
-     * @param {*} defaultValue
-     * @return {*}
-     * @since 1.10.0
-     */
-    getOption(path, defaultValue) {
-        let value;
+	/**
+	 * nested options can be specified by path `a.b.c`
+	 *
+	 * @param {string} path
+	 * @param {*} defaultValue
+	 * @return {*}
+	 * @since 1.10.0
+	 */
+	getOption(path, defaultValue) {
+		let value;
 
-        try {
-            value = new Pathfinder(this[internalSymbol]).getVia(path);
-        } catch (e) {}
+		try {
+			value = new Pathfinder(this[internalSymbol]).getVia(path);
+		} catch (e) {}
 
-        if (value === undefined) return defaultValue;
-        return value;
-    }
+		if (value === undefined) return defaultValue;
+		return value;
+	}
 }
diff --git a/source/types/binary.mjs b/source/types/binary.mjs
index 9231a59720e6afd4c6d1333e9ec7fb0c27510dc1..26835add6949868d9ac5715540f59fda7bbba4fb 100644
--- a/source/types/binary.mjs
+++ b/source/types/binary.mjs
@@ -20,19 +20,19 @@ export { toBinary, fromBinary };
  * @since 1.18.0
  */
 function toBinary(string) {
-    const codeUnits = new Uint16Array(validateString(string).length);
-    for (let i = 0; i < codeUnits.length; i++) {
-        codeUnits[i] = string.charCodeAt(i);
-    }
+	const codeUnits = new Uint16Array(validateString(string).length);
+	for (let i = 0; i < codeUnits.length; i++) {
+		codeUnits[i] = string.charCodeAt(i);
+	}
 
-    const charCodes = new Uint8Array(codeUnits.buffer);
-    let result = "";
+	const charCodes = new Uint8Array(codeUnits.buffer);
+	let result = "";
 
-    for (let i = 0; i < charCodes.byteLength; i++) {
-        result += String.fromCharCode(charCodes[i]);
-    }
+	for (let i = 0; i < charCodes.byteLength; i++) {
+		result += String.fromCharCode(charCodes[i]);
+	}
 
-    return result;
+	return result;
 }
 
 /**
@@ -46,14 +46,14 @@ function toBinary(string) {
  * @since 1.18.0
  */
 function fromBinary(binary) {
-    const bytes = new Uint8Array(validateString(binary).length);
-    for (let i = 0; i < bytes.length; i++) {
-        bytes[i] = binary.charCodeAt(i);
-    }
-    const charCodes = new Uint16Array(bytes.buffer);
-    let result = "";
-    for (let i = 0; i < charCodes.length; i++) {
-        result += String.fromCharCode(charCodes[i]);
-    }
-    return result;
+	const bytes = new Uint8Array(validateString(binary).length);
+	for (let i = 0; i < bytes.length; i++) {
+		bytes[i] = binary.charCodeAt(i);
+	}
+	const charCodes = new Uint16Array(bytes.buffer);
+	let result = "";
+	for (let i = 0; i < charCodes.length; i++) {
+		result += String.fromCharCode(charCodes[i]);
+	}
+	return result;
 }
diff --git a/source/types/dataurl.mjs b/source/types/dataurl.mjs
index b35d0eba9c5426187df38dea247d1b115411fae9..7d73d5057811118001e1878ae9f2a0cc90be8445 100644
--- a/source/types/dataurl.mjs
+++ b/source/types/dataurl.mjs
@@ -8,7 +8,11 @@
 import { Base } from "./base.mjs";
 import { isString } from "./is.mjs";
 import { MediaType, parseMediaType } from "./mediatype.mjs";
-import { validateBoolean, validateInstance, validateString } from "./validate.mjs";
+import {
+	validateBoolean,
+	validateInstance,
+	validateString,
+} from "./validate.mjs";
 import { instanceSymbol } from "../constants.mjs";
 export { DataUrl, parseDataURL };
 
@@ -29,59 +33,61 @@ const internal = Symbol("internal");
  * @see https://datatracker.ietf.org/doc/html/rfc2397
  */
 class DataUrl extends Base {
-    /**
-     *
-     * @param {String} content
-     * @param {String|Monster.Types.MediaType} mediatype
-     * @param {boolean} base64=true
-     */
-    constructor(content, mediatype, base64) {
-        super();
-
-        if (isString(mediatype)) {
-            mediatype = parseMediaType(mediatype);
-        }
-
-        this[internal] = {
-            content: validateString(content),
-            mediatype: validateInstance(mediatype, MediaType),
-            base64: validateBoolean(base64 === undefined ? true : base64),
-        };
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/types/data-url");
-    }
-
-    get content() {
-        return this[internal].base64 ? atob(this[internal].content) : this[internal].content;
-    }
-
-    get mediatype() {
-        return this[internal].mediatype;
-    }
-
-    /**
-     *
-     * @return {string}
-     * @see https://datatracker.ietf.org/doc/html/rfc2397
-     */
-    toString() {
-        let content = this[internal].content;
-
-        if (this[internal].base64 === true) {
-            content = `;base64,${content}`;
-        } else {
-            content = `,${encodeURIComponent(content)}`;
-        }
-
-        return `data:${this[internal].mediatype.toString()}${content}`;
-    }
+	/**
+	 *
+	 * @param {String} content
+	 * @param {String|Monster.Types.MediaType} mediatype
+	 * @param {boolean} base64=true
+	 */
+	constructor(content, mediatype, base64) {
+		super();
+
+		if (isString(mediatype)) {
+			mediatype = parseMediaType(mediatype);
+		}
+
+		this[internal] = {
+			content: validateString(content),
+			mediatype: validateInstance(mediatype, MediaType),
+			base64: validateBoolean(base64 === undefined ? true : base64),
+		};
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/types/data-url");
+	}
+
+	get content() {
+		return this[internal].base64
+			? atob(this[internal].content)
+			: this[internal].content;
+	}
+
+	get mediatype() {
+		return this[internal].mediatype;
+	}
+
+	/**
+	 *
+	 * @return {string}
+	 * @see https://datatracker.ietf.org/doc/html/rfc2397
+	 */
+	toString() {
+		let content = this[internal].content;
+
+		if (this[internal].base64 === true) {
+			content = `;base64,${content}`;
+		} else {
+			content = `,${encodeURIComponent(content)}`;
+		}
+
+		return `data:${this[internal].mediatype.toString()}${content}`;
+	}
 }
 
 /**
@@ -105,40 +111,40 @@ class DataUrl extends Base {
  * @memberOf Monster.Types
  */
 function parseDataURL(dataurl) {
-    validateString(dataurl);
-
-    dataurl = dataurl.trim();
-
-    if (dataurl.substring(0, 5) !== "data:") {
-        throw new TypeError("incorrect or missing data protocol");
-    }
-
-    dataurl = dataurl.substring(5);
-
-    let p = dataurl.indexOf(",");
-    if (p === -1) {
-        throw new TypeError("malformed data url");
-    }
-
-    let content = dataurl.substring(p + 1);
-    let mediatypeAndBase64 = dataurl.substring(0, p).trim();
-    let mediatype = "text/plain;charset=US-ASCII";
-    let base64Flag = false;
-
-    if (mediatypeAndBase64 !== "") {
-        mediatype = mediatypeAndBase64;
-        if (mediatypeAndBase64.endsWith("base64")) {
-            let i = mediatypeAndBase64.lastIndexOf(";");
-            mediatype = mediatypeAndBase64.substring(0, i);
-            base64Flag = true;
-        } else {
-            content = decodeURIComponent(content);
-        }
-
-        mediatype = parseMediaType(mediatype);
-    } else {
-        content = decodeURIComponent(content);
-    }
-
-    return new DataUrl(content, mediatype, base64Flag);
+	validateString(dataurl);
+
+	dataurl = dataurl.trim();
+
+	if (dataurl.substring(0, 5) !== "data:") {
+		throw new TypeError("incorrect or missing data protocol");
+	}
+
+	dataurl = dataurl.substring(5);
+
+	let p = dataurl.indexOf(",");
+	if (p === -1) {
+		throw new TypeError("malformed data url");
+	}
+
+	let content = dataurl.substring(p + 1);
+	let mediatypeAndBase64 = dataurl.substring(0, p).trim();
+	let mediatype = "text/plain;charset=US-ASCII";
+	let base64Flag = false;
+
+	if (mediatypeAndBase64 !== "") {
+		mediatype = mediatypeAndBase64;
+		if (mediatypeAndBase64.endsWith("base64")) {
+			let i = mediatypeAndBase64.lastIndexOf(";");
+			mediatype = mediatypeAndBase64.substring(0, i);
+			base64Flag = true;
+		} else {
+			content = decodeURIComponent(content);
+		}
+
+		mediatype = parseMediaType(mediatype);
+	} else {
+		content = decodeURIComponent(content);
+	}
+
+	return new DataUrl(content, mediatype, base64Flag);
 }
diff --git a/source/types/global.mjs b/source/types/global.mjs
index 7cf2e4beb548269571e1d1ebab488a7504ea0e99..7933dc7ea903442371dcf17edd2ff1624687aa5d 100644
--- a/source/types/global.mjs
+++ b/source/types/global.mjs
@@ -5,7 +5,11 @@
  * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
  */
 
-import { validateFunction, validateObject, validateString } from "./validate.mjs";
+import {
+	validateFunction,
+	validateObject,
+	validateString,
+} from "./validate.mjs";
 
 export { getGlobal, getGlobalObject, getGlobalFunction };
 
@@ -20,39 +24,39 @@ let globalReference;
  * @throws {Error} unsupported environment.
  */
 (function () {
-    if (typeof globalThis === "object") {
-        globalReference = globalThis;
-        return;
-    }
+	if (typeof globalThis === "object") {
+		globalReference = globalThis;
+		return;
+	}
 
-    if (typeof self !== "undefined") {
-        globalReference = self;
-        return;
-    } else if (typeof window !== "undefined") {
-        globalReference = window;
-        return;
-    }
+	if (typeof self !== "undefined") {
+		globalReference = self;
+		return;
+	} else if (typeof window !== "undefined") {
+		globalReference = window;
+		return;
+	}
 
-    Object.defineProperty(Object.prototype, "__monster__", {
-        get: function () {
-            return this;
-        },
-        configurable: true,
-    });
+	Object.defineProperty(Object.prototype, "__monster__", {
+		get: function () {
+			return this;
+		},
+		configurable: true,
+	});
 
-    if (typeof __monster__ === "object") {
-        __monster__.globalThis = __monster__;
-        delete Object.prototype.__monster__;
+	if (typeof __monster__ === "object") {
+		__monster__.globalThis = __monster__;
+		delete Object.prototype.__monster__;
 
-        globalReference = globalThis;
-        return;
-    }
+		globalReference = globalThis;
+		return;
+	}
 
-    try {
-        globalReference = Function("return this")();
-    } catch (e) {}
+	try {
+		globalReference = Function("return this")();
+	} catch (e) {}
 
-    throw new Error("unsupported environment.");
+	throw new Error("unsupported environment.");
 })();
 
 /**
@@ -66,7 +70,7 @@ let globalReference;
  * @returns {objec} globalThis
  */
 function getGlobal() {
-    return globalReference;
+	return globalReference;
 }
 
 /**
@@ -102,11 +106,12 @@ function getGlobal() {
  * @throws {TypeError} value is not a string
  */
 function getGlobalObject(name) {
-    validateString(name);
-    let o = globalReference?.[name];
-    if (typeof o === "undefined") throw new Error(`the object ${name} is not defined`);
-    validateObject(o);
-    return o;
+	validateString(name);
+	let o = globalReference?.[name];
+	if (typeof o === "undefined")
+		throw new Error(`the object ${name} is not defined`);
+	validateObject(o);
+	return o;
 }
 
 /**
@@ -140,9 +145,10 @@ function getGlobalObject(name) {
  * @throws {TypeError} value is not a string
  */
 function getGlobalFunction(name) {
-    validateString(name);
-    let f = globalReference?.[name];
-    if (typeof f === "undefined") throw new Error(`the function ${name} is not defined`);
-    validateFunction(f);
-    return f;
+	validateString(name);
+	let f = globalReference?.[name];
+	if (typeof f === "undefined")
+		throw new Error(`the function ${name} is not defined`);
+	validateFunction(f);
+	return f;
 }
diff --git a/source/types/id.mjs b/source/types/id.mjs
index aefedbaed6fab3dca04b89cae0dff38a2f6ff4ec..0d45221fac75a525819789db3817da4ec5033b51 100644
--- a/source/types/id.mjs
+++ b/source/types/id.mjs
@@ -32,34 +32,34 @@ let internalCounter = new Map();
  * @summary Automatic generation of ids
  */
 class ID extends Base {
-    /**
-     * create new id with prefix
-     *
-     * @param {string} prefix
-     */
-    constructor(prefix) {
-        super();
+	/**
+	 * create new id with prefix
+	 *
+	 * @param {string} prefix
+	 */
+	constructor(prefix) {
+		super();
 
-        if (prefix === undefined) {
-            prefix = "id";
-        }
+		if (prefix === undefined) {
+			prefix = "id";
+		}
 
-        validateString(prefix);
+		validateString(prefix);
 
-        if (!internalCounter.has(prefix)) {
-            internalCounter.set(prefix, 1);
-        }
+		if (!internalCounter.has(prefix)) {
+			internalCounter.set(prefix, 1);
+		}
 
-        let count = internalCounter.get(prefix);
-        this.id = prefix + count;
+		let count = internalCounter.get(prefix);
+		this.id = prefix + count;
 
-        internalCounter.set(prefix, ++count);
-    }
+		internalCounter.set(prefix, ++count);
+	}
 
-    /**
-     * @return {string}
-     */
-    toString() {
-        return this.id;
-    }
+	/**
+	 * @return {string}
+	 */
+	toString() {
+		return this.id;
+	}
 }
diff --git a/source/types/internal.mjs b/source/types/internal.mjs
index 323b4068e2764d5fcea9b30c22b060c8f704aa16..f8840d0691787986b21dfae985c2447363cc0377 100644
--- a/source/types/internal.mjs
+++ b/source/types/internal.mjs
@@ -38,97 +38,99 @@ const propertyName = "internalDefaults";
  * @memberOf Monster.Types
  */
 function equipWithInternal() {
-    const self = this;
-    validateObject(self);
-
-    if (!hasGetter(self, propertyName)) {
-        Object.defineProperty(self, propertyName, {
-            get: function () {
-                return {};
-            },
-        });
-    }
-
-    const defaults = extend({}, self[propertyName] || {});
-    self[internalSymbol] = new ProxyObserver(defaults);
-
-    /**
-     * Attach a new observer
-     *
-     * @param {Observer} observer
-     * @returns {ProxyObserver}
-     */
-    self["attachInternalObserver"] = (observer) => {
-        self[internalSymbol].attachObserver(observer);
-        return self;
-    };
-
-    /**
-     * Detach a observer
-     *
-     * @param {Observer} observer
-     * @returns {ProxyObserver}
-     */
-    self["detachInternalObserver"] = (observer) => {
-        self[internalSymbol].detachObserver(observer);
-        return self;
-    };
-
-    /**
-     * Check if a observer is attached
-     *
-     * @param {Observer} observer
-     * @returns {boolean}
-     */
-    self["containsInternalObserver"] = (observer) => {
-        return self[internalSymbol].containsObserver(observer);
-    };
-
-    /**
-     * Set an internal value, nested internals can be specified by path `a.b.c`
-     *
-     * @param {string} path
-     * @param {*} value
-     * @return {Datasource}
-     */
-    self["setInternal"] = (path, value) => {
-        new Pathfinder(self[internalSymbol].getSubject()).setVia(path, value);
-        return self;
-    };
-
-    /**
-     * set multiple internals at once
-     *
-     * @param {string|object} options
-     * @return {Datasource}
-     * @throws {Error} the options does not contain a valid json definition
-     */
-    self["setInternals"] = (options) => {
-        if (isString(options)) {
-            options = parseOptionsJSON(options);
-        }
-
-        extend(self[internalSymbol].getSubject(), defaults, options);
-        return self;
-    };
-
-    /**
-     * nested internals can be specified by path `a.b.c`
-     *
-     * @param {string} path
-     * @param {*} defaultValue
-     * @return {*}
-     */
-    self["getInternal"] = (path, defaultValue) => {
-        let value;
-
-        try {
-            value = new Pathfinder(self[internalSymbol].getRealSubject()).getVia(path);
-        } catch (e) {}
-
-        if (value === undefined) return defaultValue;
-        return value;
-    };
+	const self = this;
+	validateObject(self);
+
+	if (!hasGetter(self, propertyName)) {
+		Object.defineProperty(self, propertyName, {
+			get: function () {
+				return {};
+			},
+		});
+	}
+
+	const defaults = extend({}, self[propertyName] || {});
+	self[internalSymbol] = new ProxyObserver(defaults);
+
+	/**
+	 * Attach a new observer
+	 *
+	 * @param {Observer} observer
+	 * @returns {ProxyObserver}
+	 */
+	self["attachInternalObserver"] = (observer) => {
+		self[internalSymbol].attachObserver(observer);
+		return self;
+	};
+
+	/**
+	 * Detach a observer
+	 *
+	 * @param {Observer} observer
+	 * @returns {ProxyObserver}
+	 */
+	self["detachInternalObserver"] = (observer) => {
+		self[internalSymbol].detachObserver(observer);
+		return self;
+	};
+
+	/**
+	 * Check if a observer is attached
+	 *
+	 * @param {Observer} observer
+	 * @returns {boolean}
+	 */
+	self["containsInternalObserver"] = (observer) => {
+		return self[internalSymbol].containsObserver(observer);
+	};
+
+	/**
+	 * Set an internal value, nested internals can be specified by path `a.b.c`
+	 *
+	 * @param {string} path
+	 * @param {*} value
+	 * @return {Datasource}
+	 */
+	self["setInternal"] = (path, value) => {
+		new Pathfinder(self[internalSymbol].getSubject()).setVia(path, value);
+		return self;
+	};
+
+	/**
+	 * set multiple internals at once
+	 *
+	 * @param {string|object} options
+	 * @return {Datasource}
+	 * @throws {Error} the options does not contain a valid json definition
+	 */
+	self["setInternals"] = (options) => {
+		if (isString(options)) {
+			options = parseOptionsJSON(options);
+		}
+
+		extend(self[internalSymbol].getSubject(), defaults, options);
+		return self;
+	};
+
+	/**
+	 * nested internals can be specified by path `a.b.c`
+	 *
+	 * @param {string} path
+	 * @param {*} defaultValue
+	 * @return {*}
+	 */
+	self["getInternal"] = (path, defaultValue) => {
+		let value;
+
+		try {
+			value = new Pathfinder(self[internalSymbol].getRealSubject()).getVia(
+				path,
+			);
+		} catch (e) {}
+
+		if (value === undefined) return defaultValue;
+		return value;
+	};
 }
 
 /**
@@ -138,14 +140,14 @@ function equipWithInternal() {
  * @return {boolean}
  */
 function hasGetter(obj, prop) {
-    while (isObject(obj)) {
-        if (Object.getOwnPropertyDescriptor(obj, prop)?.["get"]) {
-            return true;
-        }
-        obj = Object.getPrototypeOf(obj);
-    }
-
-    return false;
+	while (isObject(obj)) {
+		if (Object.getOwnPropertyDescriptor(obj, prop)?.["get"]) {
+			return true;
+		}
+		obj = Object.getPrototypeOf(obj);
+	}
+
+	return false;
 }
 
 /**
@@ -154,23 +156,23 @@ function hasGetter(obj, prop) {
  * @return {Object}
  */
 function parseOptionsJSON(data) {
-    let obj = {};
+	let obj = {};
 
-    if (!isString(data)) {
-        return obj;
-    }
+	if (!isString(data)) {
+		return obj;
+	}
 
-    // the configuration can be specified as a data url.
-    try {
-        let dataUrl = parseDataURL(data);
-        data = dataUrl.content;
-    } catch (e) {}
+	// the configuration can be specified as a data url.
+	try {
+		let dataUrl = parseDataURL(data);
+		data = dataUrl.content;
+	} catch (e) {}
 
-    try {
-        obj = JSON.parse(data);
-    } catch (e) {
-        throw e;
-    }
+	try {
+		obj = JSON.parse(data);
+	} catch (e) {
+		throw e;
+	}
 
-    return validateObject(obj);
+	return validateObject(obj);
 }
diff --git a/source/types/is.mjs b/source/types/is.mjs
index 7a22e28e1e72a936e475818b151a8aa345d7057b..7e183130c62b65fab10c523c1c5bf08ab4639b89 100644
--- a/source/types/is.mjs
+++ b/source/types/is.mjs
@@ -5,7 +5,18 @@
  * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
  */
 
-export { isIterable, isPrimitive, isSymbol, isBoolean, isString, isObject, isInstance, isArray, isFunction, isInteger };
+export {
+	isIterable,
+	isPrimitive,
+	isSymbol,
+	isBoolean,
+	isString,
+	isObject,
+	isInstance,
+	isArray,
+	isFunction,
+	isInteger,
+};
 
 /**
  * With this function you can check if a value is iterable.
@@ -23,9 +34,9 @@ export { isIterable, isPrimitive, isSymbol, isBoolean, isString, isObject, isIns
  * @memberOf Monster.Types
  */
 function isIterable(value) {
-    if (value === undefined) return false;
-    if (value === null) return false;
-    return typeof value?.[Symbol.iterator] === "function";
+	if (value === undefined) return false;
+	if (value === null) return false;
+	return typeof value?.[Symbol.iterator] === "function";
 }
 
 /**
@@ -42,19 +53,24 @@ function isIterable(value) {
  * @memberOf Monster.Types
  */
 function isPrimitive(value) {
-    var type;
+	var type;
 
-    if (value === undefined || value === null) {
-        return true;
-    }
+	if (value === undefined || value === null) {
+		return true;
+	}
 
-    type = typeof value;
+	type = typeof value;
 
-    if (type === "string" || type === "number" || type === "boolean" || type === "symbol") {
-        return true;
-    }
+	if (
+		type === "string" ||
+		type === "number" ||
+		type === "boolean" ||
+		type === "symbol"
+	) {
+		return true;
+	}
 
-    return false;
+	return false;
 }
 
 /**
@@ -71,7 +87,7 @@ function isPrimitive(value) {
  * @memberOf Monster.Types
  */
 function isSymbol(value) {
-    return "symbol" === typeof value ? true : false;
+	return "symbol" === typeof value ? true : false;
 }
 
 /**
@@ -88,11 +104,11 @@ function isSymbol(value) {
  * @memberOf Monster.Types
  */
 function isBoolean(value) {
-    if (value === true || value === false) {
-        return true;
-    }
+	if (value === true || value === false) {
+		return true;
+	}
 
-    return false;
+	return false;
 }
 
 /**
@@ -109,10 +125,10 @@ function isBoolean(value) {
  * @memberOf Monster.Types
  */
 function isString(value) {
-    if (value === undefined || typeof value !== "string") {
-        return false;
-    }
-    return true;
+	if (value === undefined || typeof value !== "string") {
+		return false;
+	}
+	return true;
 }
 
 /**
@@ -129,14 +145,14 @@ function isString(value) {
  * @memberOf Monster.Types
  */
 function isObject(value) {
-    if (isArray(value)) return false;
-    if (isPrimitive(value)) return false;
+	if (isArray(value)) return false;
+	if (isPrimitive(value)) return false;
 
-    if (typeof value === "object") {
-        return true;
-    }
+	if (typeof value === "object") {
+		return true;
+	}
 
-    return false;
+	return false;
 }
 
 /**
@@ -154,10 +170,10 @@ function isObject(value) {
  * @memberOf Monster.Types
  */
 function isInstance(value, instance) {
-    if (!isObject(value)) return false;
-    if (!isFunction(instance)) return false;
-    if (!instance.hasOwnProperty("prototype")) return false;
-    return value instanceof instance ? true : false;
+	if (!isObject(value)) return false;
+	if (!isFunction(instance)) return false;
+	if (!instance.hasOwnProperty("prototype")) return false;
+	return value instanceof instance ? true : false;
 }
 
 /**
@@ -175,7 +191,7 @@ function isInstance(value, instance) {
  * @see https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
  */
 function isArray(value) {
-    return Array.isArray(value);
+	return Array.isArray(value);
 }
 
 /**
@@ -192,14 +208,14 @@ function isArray(value) {
  * @memberOf Monster.Types
  */
 function isFunction(value) {
-    if (isArray(value)) return false;
-    if (isPrimitive(value)) return false;
+	if (isArray(value)) return false;
+	if (isPrimitive(value)) return false;
 
-    if (typeof value === "function") {
-        return true;
-    }
+	if (typeof value === "function") {
+		return true;
+	}
 
-    return false;
+	return false;
 }
 
 /**
@@ -216,5 +232,5 @@ function isFunction(value) {
  * @memberOf Monster.Types
  */
 function isInteger(value) {
-    return Number.isInteger(value);
+	return Number.isInteger(value);
 }
diff --git a/source/types/mediatype.mjs b/source/types/mediatype.mjs
index efde823e279a76eba4d649c533f4c0e3eb8c49a6..e4f855454b5f5a9e5002032be23a3b83c7a25909 100644
--- a/source/types/mediatype.mjs
+++ b/source/types/mediatype.mjs
@@ -33,92 +33,92 @@ const internal = Symbol("internal");
  * @memberOf Monster.Types
  */
 class MediaType extends Base {
-    /**
-     *
-     * @param {String} type
-     * @param {String} subtype
-     * @param {Monster.Types.Parameter[]} parameter
-     */
-    constructor(type, subtype, parameter) {
-        super();
-
-        this[internal] = {
-            type: validateString(type).toLowerCase(),
-            subtype: validateString(subtype).toLowerCase(),
-            parameter: [],
-        };
-
-        if (parameter !== undefined) {
-            this[internal]["parameter"] = validateArray(parameter);
-        }
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/types/media-type");
-    }
-
-    /**
-     * @return {String}
-     */
-    get type() {
-        return this[internal].type;
-    }
-
-    /**
-     * @return {String}
-     */
-    get subtype() {
-        return this[internal].subtype;
-    }
-
-    /**
-     * @return {Monster.Types.Parameter[]}
-     */
-    get parameter() {
-        return this[internal].parameter;
-    }
-
-    /**
-     *
-     *
-     * @return {Map}
-     */
-    get parameter() {
-        const result = new Map();
-
-        this[internal]["parameter"].forEach((p) => {
-            let value = p.value;
-
-            // internally special values are partly stored with quotes, this function removes them.
-            if (value.startsWith('"') && value.endsWith('"')) {
-                value = value.substring(1, value.length - 1);
-            }
-
-            result.set(p.key, value);
-        });
-
-        return result;
-    }
-
-    /**
-     *
-     * @return {string}
-     */
-    toString() {
-        let parameter = [];
-        for (let a of this[internal].parameter) {
-            parameter.push(`${a.key}=${a.value}`);
-        }
-
-        return `${this[internal].type}/${this[internal].subtype}${
-            parameter.length > 0 ? `;${parameter.join(";")}` : ""
-        }`;
-    }
+	/**
+	 *
+	 * @param {String} type
+	 * @param {String} subtype
+	 * @param {Monster.Types.Parameter[]} parameter
+	 */
+	constructor(type, subtype, parameter) {
+		super();
+
+		this[internal] = {
+			type: validateString(type).toLowerCase(),
+			subtype: validateString(subtype).toLowerCase(),
+			parameter: [],
+		};
+
+		if (parameter !== undefined) {
+			this[internal]["parameter"] = validateArray(parameter);
+		}
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/types/media-type");
+	}
+
+	/**
+	 * @return {String}
+	 */
+	get type() {
+		return this[internal].type;
+	}
+
+	/**
+	 * @return {String}
+	 */
+	get subtype() {
+		return this[internal].subtype;
+	}
+
+	/**
+	 * @return {Monster.Types.Parameter[]}
+	 */
+	get parameter() {
+		return this[internal].parameter;
+	}
+
+	/**
+	 *
+	 *
+	 * @return {Map}
+	 */
+	get parameter() {
+		const result = new Map();
+
+		this[internal]["parameter"].forEach((p) => {
+			let value = p.value;
+
+			// internally special values are partly stored with quotes, this function removes them.
+			if (value.startsWith('"') && value.endsWith('"')) {
+				value = value.substring(1, value.length - 1);
+			}
+
+			result.set(p.key, value);
+		});
+
+		return result;
+	}
+
+	/**
+	 *
+	 * @return {string}
+	 */
+	toString() {
+		let parameter = [];
+		for (let a of this[internal].parameter) {
+			parameter.push(`${a.key}=${a.value}`);
+		}
+
+		return `${this[internal].type}/${this[internal].subtype}${
+			parameter.length > 0 ? `;${parameter.join(";")}` : ""
+		}`;
+	}
 }
 
 /**
@@ -158,24 +158,24 @@ class MediaType extends Base {
  * @memberOf Monster.Types
  */
 function parseMediaType(mediatype) {
-    const regex =
-        /(?<type>[A-Za-z]+|\*)\/(?<subtype>([a-zA-Z0-9.\+_\-]+)|\*|)(?<parameter>\s*;\s*([a-zA-Z0-9]+)\s*(=\s*("?[A-Za-z0-9_\-]+"?))?)*/g;
-    const result = regex.exec(validateString(mediatype));
+	const regex =
+		/(?<type>[A-Za-z]+|\*)\/(?<subtype>([a-zA-Z0-9.\+_\-]+)|\*|)(?<parameter>\s*;\s*([a-zA-Z0-9]+)\s*(=\s*("?[A-Za-z0-9_\-]+"?))?)*/g;
+	const result = regex.exec(validateString(mediatype));
 
-    const groups = result?.["groups"];
-    if (groups === undefined) {
-        throw new TypeError("the mimetype can not be parsed");
-    }
+	const groups = result?.["groups"];
+	if (groups === undefined) {
+		throw new TypeError("the mimetype can not be parsed");
+	}
 
-    const type = groups?.["type"];
-    const subtype = groups?.["subtype"];
-    const parameter = groups?.["parameter"];
+	const type = groups?.["type"];
+	const subtype = groups?.["subtype"];
+	const parameter = groups?.["parameter"];
 
-    if (subtype === "" || type === "") {
-        throw new TypeError("blank value is not allowed");
-    }
+	if (subtype === "" || type === "") {
+		throw new TypeError("blank value is not allowed");
+	}
 
-    return new MediaType(type, subtype, parseParameter(parameter));
+	return new MediaType(type, subtype, parseParameter(parameter));
 }
 
 /**
@@ -187,29 +187,29 @@ function parseMediaType(mediatype) {
  * @memberOf Monster.Types
  */
 function parseParameter(parameter) {
-    if (!isString(parameter)) {
-        return undefined;
-    }
+	if (!isString(parameter)) {
+		return undefined;
+	}
 
-    let result = [];
+	let result = [];
 
-    parameter.split(";").forEach((entry) => {
-        entry = entry.trim();
-        if (entry === "") {
-            return;
-        }
+	parameter.split(";").forEach((entry) => {
+		entry = entry.trim();
+		if (entry === "") {
+			return;
+		}
 
-        const kv = entry.split("=");
+		const kv = entry.split("=");
 
-        let key = validateString(kv?.[0]).trim();
-        let value = validateString(kv?.[1]).trim();
+		let key = validateString(kv?.[0]).trim();
+		let value = validateString(kv?.[1]).trim();
 
-        // if values are quoted, they remain so internally
-        result.push({
-            key: key,
-            value: value,
-        });
-    });
+		// if values are quoted, they remain so internally
+		result.push({
+			key: key,
+			value: value,
+		});
+	});
 
-    return result;
+	return result;
 }
diff --git a/source/types/node.mjs b/source/types/node.mjs
index 7a90e892f63fae049e228825d38f1c0a60d2be80..ebc2be2b29fe7b1b0ab8d031a82b833b513ca8c9 100644
--- a/source/types/node.mjs
+++ b/source/types/node.mjs
@@ -36,144 +36,153 @@ const treeStructureSymbol = Symbol("treeStructure");
  * @see https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Iteration_protocols
  */
 class Node extends Base {
-    /**
-     * @param {*} [value]
-     */
-    constructor(value) {
-        super();
-        this[internalValueSymbol] = value;
-
-        this[treeStructureSymbol] = {
-            parent: null,
-            childNodes: new NodeList(),
-            level: 0,
-        };
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/types/node");
-    }
-
-    /**
-     * @property {*}
-     */
-    get value() {
-        return this[internalValueSymbol];
-    }
-
-    /**
-     * @property {*}
-     */
-    set value(value) {
-        this[internalValueSymbol] = value;
-    }
-
-    /**
-     * @property {Monster.Types.Node|null}
-     */
-    get parent() {
-        return this[treeStructureSymbol].parent;
-    }
-
-    /**
-     * @property {integer}
-     */
-    get level() {
-        return this[treeStructureSymbol].level;
-    }
-
-    /**
-     *
-     * @property {NodeList}
-     */
-    get childNodes() {
-        return this[treeStructureSymbol].childNodes;
-    }
-
-    /**
-     *
-     * @property {NodeList}
-     */
-    set childNodes(childNodes) {
-        this[treeStructureSymbol].childNodes = validateInstance(childNodes, NodeList);
-        setChildLevelAndParent.call(this, this, 1);
-    }
-
-    /**
-     * @return {Monster.Types.Node}
-     * @param {Node} node
-     */
-    appendChild(node) {
-        this[treeStructureSymbol].childNodes.add(validateInstance(node, Node));
-        node[treeStructureSymbol].parent = this;
-
-        node[treeStructureSymbol].level = this.level + 1;
-        setChildLevelAndParent.call(this, node, 1);
-        return this;
-    }
-
-    /**
-     * @return {Monster.Types.Node}
-     * @param {Node} node
-     */
-    removeChild(node) {
-        this[treeStructureSymbol].childNodes.remove(validateInstance(node, Node));
-        node[treeStructureSymbol].parent = null;
-
-        node[treeStructureSymbol].level = 0;
-        setChildLevelAndParent.call(this, node, -1);
-        return this;
-    }
-
-    /**
-     *
-     * @return {boolean}
-     */
-    hasChildNodes() {
-        return this[treeStructureSymbol].childNodes.length > 0;
-    }
-
-    /**
-     * @return {Monster.Types.Node}
-     * @param {Node} node
-     */
-    hasChild(node) {
-        return this[treeStructureSymbol].childNodes.has(validateInstance(node, Node));
-    }
-
-    /**
-     * @since 1.28.0
-     * @return {string}
-     */
-    toString() {
-        let parts = [];
-        if (this[internalValueSymbol]) {
-            let label = this[internalValueSymbol];
-            if (!isPrimitive(label)) label = JSON.stringify(this[internalValueSymbol]);
-
-            parts.push(label);
-        }
-
-        if (!this.hasChildNodes()) {
-            return parts.join("\n");
-        }
-
-        let count = this.childNodes.length;
-        let counter = 0;
-
-        for (const node of this.childNodes) {
-            counter++;
-            const prefix = (count === counter ? "└" : "├").padStart(2 * node.level, " |");
-            parts.push(prefix + node.toString());
-        }
-
-        return parts.join("\n");
-    }
+	/**
+	 * @param {*} [value]
+	 */
+	constructor(value) {
+		super();
+		this[internalValueSymbol] = value;
+
+		this[treeStructureSymbol] = {
+			parent: null,
+			childNodes: new NodeList(),
+			level: 0,
+		};
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/types/node");
+	}
+
+	/**
+	 * @property {*}
+	 */
+	get value() {
+		return this[internalValueSymbol];
+	}
+
+	/**
+	 * @property {*}
+	 */
+	set value(value) {
+		this[internalValueSymbol] = value;
+	}
+
+	/**
+	 * @property {Monster.Types.Node|null}
+	 */
+	get parent() {
+		return this[treeStructureSymbol].parent;
+	}
+
+	/**
+	 * @property {integer}
+	 */
+	get level() {
+		return this[treeStructureSymbol].level;
+	}
+
+	/**
+	 *
+	 * @property {NodeList}
+	 */
+	get childNodes() {
+		return this[treeStructureSymbol].childNodes;
+	}
+
+	/**
+	 *
+	 * @property {NodeList}
+	 */
+	set childNodes(childNodes) {
+		this[treeStructureSymbol].childNodes = validateInstance(
+			childNodes,
+			NodeList,
+		);
+		setChildLevelAndParent.call(this, this, 1);
+	}
+
+	/**
+	 * @return {Monster.Types.Node}
+	 * @param {Node} node
+	 */
+	appendChild(node) {
+		this[treeStructureSymbol].childNodes.add(validateInstance(node, Node));
+		node[treeStructureSymbol].parent = this;
+
+		node[treeStructureSymbol].level = this.level + 1;
+		setChildLevelAndParent.call(this, node, 1);
+		return this;
+	}
+
+	/**
+	 * @return {Monster.Types.Node}
+	 * @param {Node} node
+	 */
+	removeChild(node) {
+		this[treeStructureSymbol].childNodes.remove(validateInstance(node, Node));
+		node[treeStructureSymbol].parent = null;
+
+		node[treeStructureSymbol].level = 0;
+		setChildLevelAndParent.call(this, node, -1);
+		return this;
+	}
+
+	/**
+	 *
+	 * @return {boolean}
+	 */
+	hasChildNodes() {
+		return this[treeStructureSymbol].childNodes.length > 0;
+	}
+
+	/**
+	 * @return {Monster.Types.Node}
+	 * @param {Node} node
+	 */
+	hasChild(node) {
+		return this[treeStructureSymbol].childNodes.has(
+			validateInstance(node, Node),
+		);
+	}
+
+	/**
+	 * @since 1.28.0
+	 * @return {string}
+	 */
+	toString() {
+		let parts = [];
+		if (this[internalValueSymbol]) {
+			let label = this[internalValueSymbol];
+			if (!isPrimitive(label))
+				label = JSON.stringify(this[internalValueSymbol]);
+
+			parts.push(label);
+		}
+
+		if (!this.hasChildNodes()) {
+			return parts.join("\n");
+		}
+
+		let count = this.childNodes.length;
+		let counter = 0;
+
+		for (const node of this.childNodes) {
+			counter++;
+			const prefix = (count === counter ? "└" : "├").padStart(
+				2 * node.level,
+				" |",
+			);
+			parts.push(prefix + node.toString());
+		}
+
+		return parts.join("\n");
+	}
 }
 
 /**
@@ -183,16 +192,17 @@ class Node extends Base {
  * @return {setChildLevelAndParent}
  */
 function setChildLevelAndParent(node, operand) {
-    const self = this;
-
-    if (node !== this) {
-        node[treeStructureSymbol].parent = this;
-    }
-
-    node[treeStructureSymbol].childNodes.forEach(function (child) {
-        child[treeStructureSymbol].parent = node;
-        child[treeStructureSymbol].level = node[treeStructureSymbol].level + operand;
-        setChildLevelAndParent.call(self, child, operand);
-    });
-    return this;
+	const self = this;
+
+	if (node !== this) {
+		node[treeStructureSymbol].parent = this;
+	}
+
+	node[treeStructureSymbol].childNodes.forEach(function (child) {
+		child[treeStructureSymbol].parent = node;
+		child[treeStructureSymbol].level =
+			node[treeStructureSymbol].level + operand;
+		setChildLevelAndParent.call(self, child, operand);
+	});
+	return this;
 }
diff --git a/source/types/nodelist.mjs b/source/types/nodelist.mjs
index 131ee5620c3770663e734d506617a60e43ffd2b6..5d7a8635cfa0691008297c49d079fe21aaf9d8b5 100644
--- a/source/types/nodelist.mjs
+++ b/source/types/nodelist.mjs
@@ -21,100 +21,100 @@ export { NodeList };
  * @summary A NodeList class
  */
 class NodeList extends Set {
-    /**
-     * @throws {Error} invalid value type
-     * @param {NodeList|Node|Array<Node>}values
-     */
-    constructor(values) {
-        super();
-
-        const self = this;
-
-        if (values === undefined) return;
-
-        if (isArray(values)) {
-            values.forEach((value) => self.add(value));
-        } else if (isInstance(values, NodeList)) {
-            values.forEach((value) => self.add(value));
-        } else if (isInstance(values, Node)) {
-            self.add(values);
-        } else {
-            throw new Error("invalid value type");
-        }
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/types/node-list");
-    }
-
-    /**
-     *
-     * @param {Node} node
-     * @return {Monster.Types.NodeList}
-     */
-    add(node) {
-        super.add(validateInstance(node, Node));
-        return this;
-    }
-
-    /**
-     * @param {Node} node
-     * @returns {NodeList}
-     */
-    remove(node) {
-        super.delete(validateInstance(node, Node));
-        return this;
-    }
-
-    /**
-     * @param {Node} node
-     * @returns {boolean}
-     */
-    has(node) {
-        return super.has(validateInstance(node, Node));
-    }
-
-    /**
-     * @returns {NodeList}
-     */
-    clear() {
-        super.clear();
-        return this;
-    }
-
-    /**
-     * @returns {NodeList}
-     */
-    toArray() {
-        return Array.from(this);
-    }
-
-    /**
-     * @returns {NodeList}
-     */
-    toJSON() {
-        return this.toArray();
-    }
-
-    /**
-     * @returns {NodeList}
-     */
-    toString() {
-        let parts = [];
-
-        for (const node of this.toArray()) {
-            parts.push(node.toString());
-        }
-
-        return parts.join("\n");
-    }
-
-    get length() {
-        return super.size;
-    }
+	/**
+	 * @throws {Error} invalid value type
+	 * @param {NodeList|Node|Array<Node>}values
+	 */
+	constructor(values) {
+		super();
+
+		const self = this;
+
+		if (values === undefined) return;
+
+		if (isArray(values)) {
+			values.forEach((value) => self.add(value));
+		} else if (isInstance(values, NodeList)) {
+			values.forEach((value) => self.add(value));
+		} else if (isInstance(values, Node)) {
+			self.add(values);
+		} else {
+			throw new Error("invalid value type");
+		}
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/types/node-list");
+	}
+
+	/**
+	 *
+	 * @param {Node} node
+	 * @return {Monster.Types.NodeList}
+	 */
+	add(node) {
+		super.add(validateInstance(node, Node));
+		return this;
+	}
+
+	/**
+	 * @param {Node} node
+	 * @returns {NodeList}
+	 */
+	remove(node) {
+		super.delete(validateInstance(node, Node));
+		return this;
+	}
+
+	/**
+	 * @param {Node} node
+	 * @returns {boolean}
+	 */
+	has(node) {
+		return super.has(validateInstance(node, Node));
+	}
+
+	/**
+	 * @returns {NodeList}
+	 */
+	clear() {
+		super.clear();
+		return this;
+	}
+
+	/**
+	 * @returns {NodeList}
+	 */
+	toArray() {
+		return Array.from(this);
+	}
+
+	/**
+	 * @returns {NodeList}
+	 */
+	toJSON() {
+		return this.toArray();
+	}
+
+	/**
+	 * @returns {NodeList}
+	 */
+	toString() {
+		let parts = [];
+
+		for (const node of this.toArray()) {
+			parts.push(node.toString());
+		}
+
+		return parts.join("\n");
+	}
+
+	get length() {
+		return super.size;
+	}
 }
diff --git a/source/types/noderecursiveiterator.mjs b/source/types/noderecursiveiterator.mjs
index 900f01e49660b4bd3f1d81831ab5f75312645c60..f1673f30f33f7fb446b8ce28dcff2e0dae053915 100644
--- a/source/types/noderecursiveiterator.mjs
+++ b/source/types/noderecursiveiterator.mjs
@@ -32,63 +32,63 @@ const isNodeListSymbol = Symbol("isNodeList");
  * @summary An iterator to run recursively through a tree of nodes
  */
 class NodeRecursiveIterator extends Base {
-    /**
-     * @param {Node} [data]
-     */
-    constructor(node) {
-        super();
+	/**
+	 * @param {Node} [data]
+	 */
+	constructor(node) {
+		super();
 
-        this[isNodeListSymbol] = false;
+		this[isNodeListSymbol] = false;
 
-        // iterator is a nodelist
-        if (isInstance(node, NodeList)) {
-            let children = node;
-            node = new Node();
-            node.childNodes = children;
-            this[isNodeListSymbol] = true;
-        }
+		// iterator is a nodelist
+		if (isInstance(node, NodeList)) {
+			let children = node;
+			node = new Node();
+			node.childNodes = children;
+			this[isNodeListSymbol] = true;
+		}
 
-        this[internalSymbol] = validateInstance(node, Node);
-    }
+		this[internalSymbol] = validateInstance(node, Node);
+	}
 
-    /**
-     * @private
-     * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield
-     */
-    [Symbol.iterator] = function* () {
-        /**
-         * The end of the generator function is reached. In this case, execution of the generator
-         * ends and an IteratorResult is returned to the caller in which the value is undefined and done is true.
-         * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield
-         */
-        if (this[internalSymbol] === undefined) {
-            return;
-        }
+	/**
+	 * @private
+	 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield
+	 */
+	[Symbol.iterator] = function* () {
+		/**
+		 * The end of the generator function is reached. In this case, execution of the generator
+		 * ends and an IteratorResult is returned to the caller in which the value is undefined and done is true.
+		 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield
+		 */
+		if (this[internalSymbol] === undefined) {
+			return;
+		}
 
-        // iterator is a nodelist and the main node is only a placeholder
-        if (this[isNodeListSymbol] !== true) {
-            yield this[internalSymbol];
-        }
+		// iterator is a nodelist and the main node is only a placeholder
+		if (this[isNodeListSymbol] !== true) {
+			yield this[internalSymbol];
+		}
 
-        if (this[internalSymbol].hasChildNodes()) {
-            let childNodes = this[internalSymbol].childNodes;
+		if (this[internalSymbol].hasChildNodes()) {
+			let childNodes = this[internalSymbol].childNodes;
 
-            for (let node of childNodes) {
-                yield* new NodeRecursiveIterator(node);
-            }
-        }
+			for (let node of childNodes) {
+				yield* new NodeRecursiveIterator(node);
+			}
+		}
 
-        return;
-    };
+		return;
+	};
 
-    /**
-     * @param {function} callback
-     * @return {Monster.Types.NodeRecursiveIterator}
-     */
-    forEach(callback) {
-        for (const node of this) {
-            callback(node);
-        }
-        return this;
-    }
+	/**
+	 * @param {function} callback
+	 * @return {Monster.Types.NodeRecursiveIterator}
+	 */
+	forEach(callback) {
+		for (const node of this) {
+			callback(node);
+		}
+		return this;
+	}
 }
diff --git a/source/types/observablequeue.mjs b/source/types/observablequeue.mjs
index 19b2d99a9da6579a03a991842f2276ae3c3d95bf..93e2151d92d7f95c37a9bbc310edf72d87a168eb 100644
--- a/source/types/observablequeue.mjs
+++ b/source/types/observablequeue.mjs
@@ -24,84 +24,84 @@ export { ObservableQueue };
  * @summary An observable Queue (Fifo)
  */
 class ObservableQueue extends Queue {
-    /**
-     *
-     */
-    constructor() {
-        super();
-        this[internalSymbol] = {
-            observers: new ObserverList(),
-        };
-    }
+	/**
+	 *
+	 */
+	constructor() {
+		super();
+		this[internalSymbol] = {
+			observers: new ObserverList(),
+		};
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/types/observablequeue");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/types/observablequeue");
+	}
 
-    /**
-     * Add a new element to the end of the queue.
-     *
-     * @param {*} value
-     * @returns {Queue}
-     */
-    add(value) {
-        super.add(value);
-        this.notifyObservers();
-        return this;
-    }
+	/**
+	 * Add a new element to the end of the queue.
+	 *
+	 * @param {*} value
+	 * @returns {Queue}
+	 */
+	add(value) {
+		super.add(value);
+		this.notifyObservers();
+		return this;
+	}
 
-    /**
-     * remove all entries
-     *
-     * @returns {Queue}
-     */
-    clear() {
-        super.clear();
-        this.notifyObservers();
-        return this;
-    }
+	/**
+	 * remove all entries
+	 *
+	 * @returns {Queue}
+	 */
+	clear() {
+		super.clear();
+		this.notifyObservers();
+		return this;
+	}
 
-    /**
-     * Attach a new observer
-     *
-     * @param {Observer} observer
-     * @returns {ProxyObserver}
-     */
-    attachObserver(observer) {
-        this[internalSymbol].observers.attach(observer);
-        return this;
-    }
+	/**
+	 * Attach a new observer
+	 *
+	 * @param {Observer} observer
+	 * @returns {ProxyObserver}
+	 */
+	attachObserver(observer) {
+		this[internalSymbol].observers.attach(observer);
+		return this;
+	}
 
-    /**
-     * Detach a observer
-     *
-     * @param {Observer} observer
-     * @returns {ProxyObserver}
-     */
-    detachObserver(observer) {
-        this[internalSymbol].observers.detach(observer);
-        return this;
-    }
+	/**
+	 * Detach a observer
+	 *
+	 * @param {Observer} observer
+	 * @returns {ProxyObserver}
+	 */
+	detachObserver(observer) {
+		this[internalSymbol].observers.detach(observer);
+		return this;
+	}
 
-    /**
-     * Notify all observer
-     *
-     * @returns {Promise}
-     */
-    notifyObservers() {
-        return this[internalSymbol].observers.notify(this);
-    }
+	/**
+	 * Notify all observer
+	 *
+	 * @returns {Promise}
+	 */
+	notifyObservers() {
+		return this[internalSymbol].observers.notify(this);
+	}
 
-    /**
-     * @param {Observer} observer
-     * @returns {boolean}
-     */
-    containsObserver(observer) {
-        return this[internalSymbol].observers.contains(observer);
-    }
+	/**
+	 * @param {Observer} observer
+	 * @returns {boolean}
+	 */
+	containsObserver(observer) {
+		return this[internalSymbol].observers.contains(observer);
+	}
 }
diff --git a/source/types/observer.mjs b/source/types/observer.mjs
index 6c9cd78c8b66658c2b5e0659dd4be96602bb94b4..ab1ccee084e72ebae70f74e735f1cf45b7c3fe26 100644
--- a/source/types/observer.mjs
+++ b/source/types/observer.mjs
@@ -45,108 +45,108 @@ export { Observer };
  * @memberOf Monster.Types
  */
 class Observer extends Base {
-    /**
-     *
-     * @param {function} callback
-     * @param {*} args
-     */
-    constructor(callback, ...args) {
-        super();
-
-        if (typeof callback !== "function") {
-            throw new Error("observer callback must be a function");
-        }
-
-        this.callback = callback;
-        this.arguments = args;
-        this.tags = new TokenList();
-        this.queue = new UniqueQueue();
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/types/observer");
-    }
-
-    /**
-     *
-     * @param {string} tag
-     * @returns {Observer}
-     */
-    addTag(tag) {
-        this.tags.add(tag);
-        return this;
-    }
-
-    /**
-     *
-     * @param {string} tag
-     * @returns {Observer}
-     */
-    removeTag(tag) {
-        this.tags.remove(tag);
-        return this;
-    }
-
-    /**
-     *
-     * @returns {Array}
-     */
-    getTags() {
-        return this.tags.entries();
-    }
-
-    /**
-     *
-     * @param {string} tag
-     * @returns {boolean}
-     */
-    hasTag(tag) {
-        return this.tags.contains(tag);
-    }
-
-    /**
-     *
-     * @param {object} subject
-     * @returns {Promise}
-     */
-    update(subject) {
-        let self = this;
-
-        return new Promise(function (resolve, reject) {
-            if (!isObject(subject)) {
-                reject("subject must be an object");
-                return;
-            }
-
-            self.queue.add(subject);
-
-            setTimeout(() => {
-                try {
-                    // the queue and the settimeout ensure that an object is not
-                    // informed of the same change more than once.
-                    if (self.queue.isEmpty()) {
-                        resolve();
-                        return;
-                    }
-
-                    let s = self.queue.poll();
-                    let result = self.callback.apply(s, self.arguments);
-
-                    if (isObject(result) && result instanceof Promise) {
-                        result.then(resolve).catch(reject);
-                        return;
-                    }
-
-                    resolve(result);
-                } catch (e) {
-                    reject(e);
-                }
-            }, 0);
-        });
-    }
+	/**
+	 *
+	 * @param {function} callback
+	 * @param {*} args
+	 */
+	constructor(callback, ...args) {
+		super();
+
+		if (typeof callback !== "function") {
+			throw new Error("observer callback must be a function");
+		}
+
+		this.callback = callback;
+		this.arguments = args;
+		this.tags = new TokenList();
+		this.queue = new UniqueQueue();
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/types/observer");
+	}
+
+	/**
+	 *
+	 * @param {string} tag
+	 * @returns {Observer}
+	 */
+	addTag(tag) {
+		this.tags.add(tag);
+		return this;
+	}
+
+	/**
+	 *
+	 * @param {string} tag
+	 * @returns {Observer}
+	 */
+	removeTag(tag) {
+		this.tags.remove(tag);
+		return this;
+	}
+
+	/**
+	 *
+	 * @returns {Array}
+	 */
+	getTags() {
+		return this.tags.entries();
+	}
+
+	/**
+	 *
+	 * @param {string} tag
+	 * @returns {boolean}
+	 */
+	hasTag(tag) {
+		return this.tags.contains(tag);
+	}
+
+	/**
+	 *
+	 * @param {object} subject
+	 * @returns {Promise}
+	 */
+	update(subject) {
+		let self = this;
+
+		return new Promise(function (resolve, reject) {
+			if (!isObject(subject)) {
+				reject("subject must be an object");
+				return;
+			}
+
+			self.queue.add(subject);
+
+			setTimeout(() => {
+				try {
+					// the queue and the settimeout ensure that an object is not
+					// informed of the same change more than once.
+					if (self.queue.isEmpty()) {
+						resolve();
+						return;
+					}
+
+					let s = self.queue.poll();
+					let result = self.callback.apply(s, self.arguments);
+
+					if (isObject(result) && result instanceof Promise) {
+						result.then(resolve).catch(reject);
+						return;
+					}
+
+					resolve(result);
+				} catch (e) {
+					reject(e);
+				}
+			}, 0);
+		});
+	}
 }
diff --git a/source/types/observerlist.mjs b/source/types/observerlist.mjs
index 92befe4ee28f6a3c5c538bcaa687660029af69bb..bcc4a489007fe48cc9ba14ec9a5f6e31819599fd 100644
--- a/source/types/observerlist.mjs
+++ b/source/types/observerlist.mjs
@@ -20,79 +20,79 @@ export { ObserverList };
  * @memberOf Monster.Types
  */
 class ObserverList extends Base {
-    /**
-     *
-     */
-    constructor() {
-        super();
-        this.observers = [];
-    }
+	/**
+	 *
+	 */
+	constructor() {
+		super();
+		this.observers = [];
+	}
 
-    /**
-     *
-     * @param {Observer} observer
-     * @return {ObserverList}
-     * @throws {TypeError} value is not an instance of Observer
-     */
-    attach(observer) {
-        validateInstance(observer, Observer);
+	/**
+	 *
+	 * @param {Observer} observer
+	 * @return {ObserverList}
+	 * @throws {TypeError} value is not an instance of Observer
+	 */
+	attach(observer) {
+		validateInstance(observer, Observer);
 
-        this.observers.push(observer);
-        return this;
-    }
+		this.observers.push(observer);
+		return this;
+	}
 
-    /**
-     *
-     * @param {Observer} observer
-     * @return {ObserverList}
-     * @throws {TypeError} value is not an instance of Observer
-     */
-    detach(observer) {
-        validateInstance(observer, Observer);
+	/**
+	 *
+	 * @param {Observer} observer
+	 * @return {ObserverList}
+	 * @throws {TypeError} value is not an instance of Observer
+	 */
+	detach(observer) {
+		validateInstance(observer, Observer);
 
-        var i = 0;
-        var l = this.observers.length;
-        for (; i < l; i++) {
-            if (this.observers[i] === observer) {
-                this.observers.splice(i, 1);
-            }
-        }
+		var i = 0;
+		var l = this.observers.length;
+		for (; i < l; i++) {
+			if (this.observers[i] === observer) {
+				this.observers.splice(i, 1);
+			}
+		}
 
-        return this;
-    }
+		return this;
+	}
 
-    /**
-     *
-     * @param {Observer} observer
-     * @return {boolean}
-     * @throws {TypeError} value is not an instance of Observer
-     */
-    contains(observer) {
-        validateInstance(observer, Observer);
-        var i = 0;
-        var l = this.observers.length;
-        for (; i < l; i++) {
-            if (this.observers[i] === observer) {
-                return true;
-            }
-        }
-        return false;
-    }
+	/**
+	 *
+	 * @param {Observer} observer
+	 * @return {boolean}
+	 * @throws {TypeError} value is not an instance of Observer
+	 */
+	contains(observer) {
+		validateInstance(observer, Observer);
+		var i = 0;
+		var l = this.observers.length;
+		for (; i < l; i++) {
+			if (this.observers[i] === observer) {
+				return true;
+			}
+		}
+		return false;
+	}
 
-    /**
-     *
-     * @param subject
-     * @return {Promise}
-     */
-    notify(subject) {
-        let pomises = [];
+	/**
+	 *
+	 * @param subject
+	 * @return {Promise}
+	 */
+	notify(subject) {
+		let pomises = [];
 
-        let i = 0;
-        let l = this.observers.length;
-        for (; i < l; i++) {
-            pomises.push(this.observers[i].update(subject));
-        }
+		let i = 0;
+		let l = this.observers.length;
+		for (; i < l; i++) {
+			pomises.push(this.observers[i].update(subject));
+		}
 
-        return Promise.all(pomises);
-    }
+		return Promise.all(pomises);
+	}
 }
diff --git a/source/types/proxyobserver.mjs b/source/types/proxyobserver.mjs
index 8043db6a862f324c2d0354152f81fb91c59cf539..42c19d9e8a90d079e0534e346301fa1bb04be55e 100644
--- a/source/types/proxyobserver.mjs
+++ b/source/types/proxyobserver.mjs
@@ -29,107 +29,107 @@ export { ProxyObserver };
  * @memberOf Monster.Types
  */
 class ProxyObserver extends Base {
-    /**
-     *
-     * @param {object} object
-     * @throws {TypeError} value is not a object
-     */
-    constructor(object) {
-        super();
-
-        this.realSubject = validateObject(object);
-        this.subject = new Proxy(object, getHandler.call(this));
-
-        this.objectMap = new WeakMap();
-        this.objectMap.set(this.realSubject, this.subject);
-
-        this.proxyMap = new WeakMap();
-        this.proxyMap.set(this.subject, this.realSubject);
-
-        this.observers = new ObserverList();
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/types/proxy-observer");
-    }
-
-    /**
-     * @returns {object}
-     */
-    getSubject() {
-        return this.subject;
-    }
-
-    /**
-     * @since 1.24.0
-     * @param {Object} obj
-     * @return {Monster.Types.ProxyObserver}
-     */
-    setSubject(obj) {
-        let i;
-        let k = Object.keys(this.subject);
-        for (i = 0; i < k.length; i++) {
-            delete this.subject[k[i]];
-        }
-
-        this.subject = extend(this.subject, obj);
-        return this;
-    }
-
-    /**
-     * Get the real object
-     *
-     * Changes to this object are not noticed by the observers, so you can make a large number of changes and inform the observers later.
-     * 
-     * @returns {object}
-     */
-    getRealSubject() {
-        return this.realSubject;
-    }
-
-    /**
-     * attach a new observer
-     *
-     * @param {Observer} observer
-     * @returns {ProxyObserver}
-     */
-    attachObserver(observer) {
-        this.observers.attach(observer);
-        return this;
-    }
-
-    /**
-     * detach a observer
-     *
-     * @param {Observer} observer
-     * @returns {ProxyObserver}
-     */
-    detachObserver(observer) {
-        this.observers.detach(observer);
-        return this;
-    }
-
-    /**
-     * notify all observer
-     *
-     * @returns {Promise}
-     */
-    notifyObservers() {
-        return this.observers.notify(this);
-    }
-
-    /**
-     * @param {Observer} observer
-     * @returns {boolean}
-     */
-    containsObserver(observer) {
-        return this.observers.contains(observer);
-    }
+	/**
+	 *
+	 * @param {object} object
+	 * @throws {TypeError} value is not a object
+	 */
+	constructor(object) {
+		super();
+
+		this.realSubject = validateObject(object);
+		this.subject = new Proxy(object, getHandler.call(this));
+
+		this.objectMap = new WeakMap();
+		this.objectMap.set(this.realSubject, this.subject);
+
+		this.proxyMap = new WeakMap();
+		this.proxyMap.set(this.subject, this.realSubject);
+
+		this.observers = new ObserverList();
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/types/proxy-observer");
+	}
+
+	/**
+	 * @returns {object}
+	 */
+	getSubject() {
+		return this.subject;
+	}
+
+	/**
+	 * @since 1.24.0
+	 * @param {Object} obj
+	 * @return {Monster.Types.ProxyObserver}
+	 */
+	setSubject(obj) {
+		let i;
+		let k = Object.keys(this.subject);
+		for (i = 0; i < k.length; i++) {
+			delete this.subject[k[i]];
+		}
+
+		this.subject = extend(this.subject, obj);
+		return this;
+	}
+
+	/**
+	 * Get the real object
+	 *
+	 * Changes to this object are not noticed by the observers, so you can make a large number of changes and inform the observers later.
+	 *
+	 * @returns {object}
+	 */
+	getRealSubject() {
+		return this.realSubject;
+	}
+
+	/**
+	 * attach a new observer
+	 *
+	 * @param {Observer} observer
+	 * @returns {ProxyObserver}
+	 */
+	attachObserver(observer) {
+		this.observers.attach(observer);
+		return this;
+	}
+
+	/**
+	 * detach a observer
+	 *
+	 * @param {Observer} observer
+	 * @returns {ProxyObserver}
+	 */
+	detachObserver(observer) {
+		this.observers.detach(observer);
+		return this;
+	}
+
+	/**
+	 * notify all observer
+	 *
+	 * @returns {Promise}
+	 */
+	notifyObservers() {
+		return this.observers.notify(this);
+	}
+
+	/**
+	 * @param {Observer} observer
+	 * @returns {boolean}
+	 */
+	containsObserver(observer) {
+		return this.observers.contains(observer);
+	}
 }
 
 /**
@@ -139,113 +139,113 @@ class ProxyObserver extends Base {
  * @see {@link https://gitlab.schukai.com/-/snippets/49}
  */
 function getHandler() {
-    const proxy = this;
-
-    // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots
-    const handler = {
-        // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver
-        get: function (target, key, receiver) {
-            const value = Reflect.get(target, key, receiver);
-
-            if (typeof key === "symbol") {
-                return value;
-            }
-
-            if (isPrimitive(value)) {
-                return value;
-            }
-
-            // set value as proxy if object or array
-            if (isArray(value) || isObject(value)) {
-                if (proxy.objectMap.has(value)) {
-                    return proxy.objectMap.get(value);
-                } else if (proxy.proxyMap.has(value)) {
-                    return value;
-                } else {
-                    let p = new Proxy(value, handler);
-                    proxy.objectMap.set(value, p);
-                    proxy.proxyMap.set(p, value);
-                    return p;
-                }
-            }
-
-            return value;
-        },
-
-        // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver
-        set: function (target, key, value, receiver) {
-            if (proxy.proxyMap.has(value)) {
-                value = proxy.proxyMap.get(value);
-            }
-
-            if (proxy.proxyMap.has(target)) {
-                target = proxy.proxyMap.get(target);
-            }
-
-            let current = Reflect.get(target, key, receiver);
-            if (proxy.proxyMap.has(current)) {
-                current = proxy.proxyMap.get(current);
-            }
-
-            if (current === value) {
-                return true;
-            }
-
-            let result;
-            let descriptor = Reflect.getOwnPropertyDescriptor(target, key);
-
-            if (descriptor === undefined) {
-                descriptor = {
-                    writable: true,
-                    enumerable: true,
-                    configurable: true,
-                };
-            }
-
-            descriptor["value"] = value;
-            result = Reflect.defineProperty(target, key, descriptor);
-
-            if (typeof key !== "symbol") {
-                proxy.observers.notify(proxy);
-            }
-
-            return result;
-        },
-
-        // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-delete-p
-        deleteProperty: function (target, key) {
-            if (key in target) {
-                delete target[key];
-
-                if (typeof key !== "symbol") {
-                    proxy.observers.notify(proxy);
-                }
-
-                return true;
-            }
-            return false;
-        },
-
-        // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc
-        defineProperty: function (target, key, descriptor) {
-            let result = Reflect.defineProperty(target, key, descriptor);
-            if (typeof key !== "symbol") {
-                proxy.observers.notify(proxy);
-            }
-            return result;
-        },
-
-        // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v
-        setPrototypeOf: function (target, key) {
-            let result = Reflect.setPrototypeOf(object1, key);
-
-            if (typeof key !== "symbol") {
-                proxy.observers.notify(proxy);
-            }
-
-            return result;
-        },
-    };
-
-    return handler;
+	const proxy = this;
+
+	// https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots
+	const handler = {
+		// https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver
+		get: function (target, key, receiver) {
+			const value = Reflect.get(target, key, receiver);
+
+			if (typeof key === "symbol") {
+				return value;
+			}
+
+			if (isPrimitive(value)) {
+				return value;
+			}
+
+			// set value as proxy if object or array
+			if (isArray(value) || isObject(value)) {
+				if (proxy.objectMap.has(value)) {
+					return proxy.objectMap.get(value);
+				} else if (proxy.proxyMap.has(value)) {
+					return value;
+				} else {
+					let p = new Proxy(value, handler);
+					proxy.objectMap.set(value, p);
+					proxy.proxyMap.set(p, value);
+					return p;
+				}
+			}
+
+			return value;
+		},
+
+		// https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver
+		set: function (target, key, value, receiver) {
+			if (proxy.proxyMap.has(value)) {
+				value = proxy.proxyMap.get(value);
+			}
+
+			if (proxy.proxyMap.has(target)) {
+				target = proxy.proxyMap.get(target);
+			}
+
+			let current = Reflect.get(target, key, receiver);
+			if (proxy.proxyMap.has(current)) {
+				current = proxy.proxyMap.get(current);
+			}
+
+			if (current === value) {
+				return true;
+			}
+
+			let result;
+			let descriptor = Reflect.getOwnPropertyDescriptor(target, key);
+
+			if (descriptor === undefined) {
+				descriptor = {
+					writable: true,
+					enumerable: true,
+					configurable: true,
+				};
+			}
+
+			descriptor["value"] = value;
+			result = Reflect.defineProperty(target, key, descriptor);
+
+			if (typeof key !== "symbol") {
+				proxy.observers.notify(proxy);
+			}
+
+			return result;
+		},
+
+		// https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-delete-p
+		deleteProperty: function (target, key) {
+			if (key in target) {
+				delete target[key];
+
+				if (typeof key !== "symbol") {
+					proxy.observers.notify(proxy);
+				}
+
+				return true;
+			}
+			return false;
+		},
+
+		// https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc
+		defineProperty: function (target, key, descriptor) {
+			let result = Reflect.defineProperty(target, key, descriptor);
+			if (typeof key !== "symbol") {
+				proxy.observers.notify(proxy);
+			}
+			return result;
+		},
+
+		// https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v
+		setPrototypeOf: function (target, key) {
+			let result = Reflect.setPrototypeOf(object1, key);
+
+			if (typeof key !== "symbol") {
+				proxy.observers.notify(proxy);
+			}
+
+			return result;
+		},
+	};
+
+	return handler;
 }
diff --git a/source/types/queue.mjs b/source/types/queue.mjs
index 259122768d6e527c809fe9570af7aa5aa5eeb1f6..ffdeaf0b6401adc08336aa7ceef88226a4c00fcc 100644
--- a/source/types/queue.mjs
+++ b/source/types/queue.mjs
@@ -27,74 +27,74 @@ export { Queue };
  * @summary A Queue (Fifo)
  */
 class Queue extends Base {
-    /**
-     *
-     */
-    constructor() {
-        super();
-        this.data = [];
-    }
+	/**
+	 *
+	 */
+	constructor() {
+		super();
+		this.data = [];
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/types/queue");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/types/queue");
+	}
 
-    /**
-     * @return {boolean}
-     */
-    isEmpty() {
-        return this.data.length === 0;
-    }
+	/**
+	 * @return {boolean}
+	 */
+	isEmpty() {
+		return this.data.length === 0;
+	}
 
-    /**
-     * Read the element at the front of the queue without removing it.
-     *
-     * @return {*}
-     */
-    peek() {
-        if (this.isEmpty()) {
-            return undefined;
-        }
+	/**
+	 * Read the element at the front of the queue without removing it.
+	 *
+	 * @return {*}
+	 */
+	peek() {
+		if (this.isEmpty()) {
+			return undefined;
+		}
 
-        return this.data[0];
-    }
+		return this.data[0];
+	}
 
-    /**
-     * Add a new element to the end of the queue.
-     *
-     * @param {*} value
-     * @returns {Queue}
-     */
-    add(value) {
-        this.data.push(value);
-        return this;
-    }
+	/**
+	 * Add a new element to the end of the queue.
+	 *
+	 * @param {*} value
+	 * @returns {Queue}
+	 */
+	add(value) {
+		this.data.push(value);
+		return this;
+	}
 
-    /**
-     * remove all entries
-     *
-     * @returns {Queue}
-     */
-    clear() {
-        this.data = [];
-        return this;
-    }
+	/**
+	 * remove all entries
+	 *
+	 * @returns {Queue}
+	 */
+	clear() {
+		this.data = [];
+		return this;
+	}
 
-    /**
-     * Remove the element at the front of the queue
-     * If the queue is empty, return undefined.
-     *
-     * @return {*}
-     */
-    poll() {
-        if (this.isEmpty()) {
-            return undefined;
-        }
-        return this.data.shift();
-    }
+	/**
+	 * Remove the element at the front of the queue
+	 * If the queue is empty, return undefined.
+	 *
+	 * @return {*}
+	 */
+	poll() {
+		if (this.isEmpty()) {
+			return undefined;
+		}
+		return this.data.shift();
+	}
 }
diff --git a/source/types/randomid.mjs b/source/types/randomid.mjs
index 075f1ad6bb62839a47da4940b219de31a82df5a9..b033f12aaace555abcfffbfecbc31de05ca8db34 100644
--- a/source/types/randomid.mjs
+++ b/source/types/randomid.mjs
@@ -27,19 +27,19 @@ let internalCounter = 0;
  * @summary class to generate random numbers
  */
 class RandomID extends ID {
-    /**
-     * create new object
-     */
-    constructor() {
-        super();
+	/**
+	 * create new object
+	 */
+	constructor() {
+		super();
 
-        internalCounter += 1;
+		internalCounter += 1;
 
-        this.id =
-            getGlobal()
-                .btoa(random(1, 10000))
-                .replace(/=/g, "")
-                /** No numbers at the beginning of the ID, because of possible problems with DOM */
-                .replace(/^[0-9]+/, "X") + internalCounter;
-    }
+		this.id =
+			getGlobal()
+				.btoa(random(1, 10000))
+				.replace(/=/g, "")
+				/** No numbers at the beginning of the ID, because of possible problems with DOM */
+				.replace(/^[0-9]+/, "X") + internalCounter;
+	}
 }
diff --git a/source/types/regex.mjs b/source/types/regex.mjs
index ea10692f5ba477347595a130451ec348dc9451e5..90d4b74c1cd2ba57c2e4bc6539daf49c8522be00 100644
--- a/source/types/regex.mjs
+++ b/source/types/regex.mjs
@@ -21,5 +21,7 @@ export { escapeString };
  * @throws {TypeError} value is not a string
  */
 function escapeString(value) {
-    return validateString(value).replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
+	return validateString(value)
+		.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&")
+		.replace(/-/g, "\\x2d");
 }
diff --git a/source/types/stack.mjs b/source/types/stack.mjs
index 6d5a7179c16da99f6cd23341cd5f99ccc2493d26..8958f433a8861aeaefbb8504968b84e93386a11d 100644
--- a/source/types/stack.mjs
+++ b/source/types/stack.mjs
@@ -18,75 +18,75 @@ export { Stack };
  * @memberOf Monster.Types
  */
 class Stack extends Base {
-    /**
-     *
-     */
-    constructor() {
-        super();
-        this.data = [];
-    }
+	/**
+	 *
+	 */
+	constructor() {
+		super();
+		this.data = [];
+	}
 
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/types/stack");
-    }
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/types/stack");
+	}
 
-    /**
-     * @return {boolean}
-     */
-    isEmpty() {
-        return this.data.length === 0;
-    }
+	/**
+	 * @return {boolean}
+	 */
+	isEmpty() {
+		return this.data.length === 0;
+	}
 
-    /**
-     * looks at the object at the top of this stack without removing it from the stack.
-     *
-     * @return {*}
-     */
-    peek() {
-        if (this.isEmpty()) {
-            return undefined;
-        }
+	/**
+	 * looks at the object at the top of this stack without removing it from the stack.
+	 *
+	 * @return {*}
+	 */
+	peek() {
+		if (this.isEmpty()) {
+			return undefined;
+		}
 
-        return this.data?.[this.data.length - 1];
-    }
+		return this.data?.[this.data.length - 1];
+	}
 
-    /**
-     * pushes an item onto the top of this stack.
-     *
-     * @param {*} value
-     * @returns {Queue}
-     */
-    push(value) {
-        this.data.push(value);
-        return this;
-    }
+	/**
+	 * pushes an item onto the top of this stack.
+	 *
+	 * @param {*} value
+	 * @returns {Queue}
+	 */
+	push(value) {
+		this.data.push(value);
+		return this;
+	}
 
-    /**
-     * remove all entries
-     *
-     * @returns {Queue}
-     */
-    clear() {
-        this.data = [];
-        return this;
-    }
+	/**
+	 * remove all entries
+	 *
+	 * @returns {Queue}
+	 */
+	clear() {
+		this.data = [];
+		return this;
+	}
 
-    /**
-     * removes the object at the top of this stack and returns
-     * that object as the value of this function. is the stack empty
-     * the return value is undefined.
-     *
-     * @return {*}
-     */
-    pop() {
-        if (this.isEmpty()) {
-            return undefined;
-        }
-        return this.data.pop();
-    }
+	/**
+	 * removes the object at the top of this stack and returns
+	 * that object as the value of this function. is the stack empty
+	 * the return value is undefined.
+	 *
+	 * @return {*}
+	 */
+	pop() {
+		if (this.isEmpty()) {
+			return undefined;
+		}
+		return this.data.pop();
+	}
 }
diff --git a/source/types/tokenlist.mjs b/source/types/tokenlist.mjs
index b93c25cfca64b4b7efa107d22066fc636b949b2f..0e6a7f1942a250184dc442f2dde4ee5f8cf7f3c6 100644
--- a/source/types/tokenlist.mjs
+++ b/source/types/tokenlist.mjs
@@ -25,223 +25,223 @@ export { TokenList };
  * @memberOf Monster.Types
  */
 class TokenList extends Base {
-    /**
-     *
-     * @param {array|string|iteratable} init
-     */
-    constructor(init) {
-        super();
-        this.tokens = new Set();
+	/**
+	 *
+	 * @param {array|string|iteratable} init
+	 */
+	constructor(init) {
+		super();
+		this.tokens = new Set();
 
-        if (typeof init !== "undefined") {
-            this.add(init);
-        }
-    }
+		if (typeof init !== "undefined") {
+			this.add(init);
+		}
+	}
 
-    /**
-     * Iterator protocol
-     *
-     * @returns {Symbol.iterator}
-     */
-    getIterator() {
-        return this[Symbol.iterator]();
-    }
+	/**
+	 * Iterator protocol
+	 *
+	 * @returns {Symbol.iterator}
+	 */
+	getIterator() {
+		return this[Symbol.iterator]();
+	}
 
-    /**
-     * Iterator
-     *
-     * @returns {{next: ((function(): ({value: *, done: boolean}))|*)}}
-     */
-    [Symbol.iterator]() {
-        // Use a new index for each iterator. This makes multiple
-        // iterations over the iterable safe for non-trivial cases,
-        // such as use of break or nested looping over the same iterable.
-        let index = 0;
-        let entries = this.entries();
+	/**
+	 * Iterator
+	 *
+	 * @returns {{next: ((function(): ({value: *, done: boolean}))|*)}}
+	 */
+	[Symbol.iterator]() {
+		// Use a new index for each iterator. This makes multiple
+		// iterations over the iterable safe for non-trivial cases,
+		// such as use of break or nested looping over the same iterable.
+		let index = 0;
+		let entries = this.entries();
 
-        return {
-            next: () => {
-                if (index < entries.length) {
-                    return { value: entries?.[index++], done: false };
-                } else {
-                    return { done: true };
-                }
-            },
-        };
-    }
+		return {
+			next: () => {
+				if (index < entries.length) {
+					return { value: entries?.[index++], done: false };
+				} else {
+					return { done: true };
+				}
+			},
+		};
+	}
 
-    /**
-     * Returns true if it contains token, otherwise false
-     *
-     * @externalExample ../../example/types/tokenlist-2.mjs
-     * @param {array|string|iteratable} value
-     * @returns {boolean}
-     */
-    contains(value) {
-        if (isString(value)) {
-            value = value.trim();
-            let counter = 0;
-            value.split(" ").forEach((token) => {
-                if (this.tokens.has(token.trim()) === false) return false;
-                counter++;
-            });
-            return counter > 0 ? true : false;
-        }
+	/**
+	 * Returns true if it contains token, otherwise false
+	 *
+	 * @externalExample ../../example/types/tokenlist-2.mjs
+	 * @param {array|string|iteratable} value
+	 * @returns {boolean}
+	 */
+	contains(value) {
+		if (isString(value)) {
+			value = value.trim();
+			let counter = 0;
+			value.split(" ").forEach((token) => {
+				if (this.tokens.has(token.trim()) === false) return false;
+				counter++;
+			});
+			return counter > 0 ? true : false;
+		}
 
-        if (isIterable(value)) {
-            let counter = 0;
-            for (let token of value) {
-                validateString(token);
-                if (this.tokens.has(token.trim()) === false) return false;
-                counter++;
-            }
-            return counter > 0 ? true : false;
-        }
+		if (isIterable(value)) {
+			let counter = 0;
+			for (let token of value) {
+				validateString(token);
+				if (this.tokens.has(token.trim()) === false) return false;
+				counter++;
+			}
+			return counter > 0 ? true : false;
+		}
 
-        return false;
-    }
+		return false;
+	}
 
-    /**
-     * Add tokens
-     *
-     * @externalExample ../../example/types/tokenlist-3.mjs
-     * @param {array|string|iteratable} value
-     * @returns {TokenList}
-     * @throws {TypeError} unsupported value
-     */
-    add(value) {
-        if (isString(value)) {
-            value.split(" ").forEach((token) => {
-                this.tokens.add(token.trim());
-            });
-        } else if (isIterable(value)) {
-            for (let token of value) {
-                validateString(token);
-                this.tokens.add(token.trim());
-            }
-        } else if (typeof value !== "undefined") {
-            throw new TypeError("unsupported value");
-        }
+	/**
+	 * Add tokens
+	 *
+	 * @externalExample ../../example/types/tokenlist-3.mjs
+	 * @param {array|string|iteratable} value
+	 * @returns {TokenList}
+	 * @throws {TypeError} unsupported value
+	 */
+	add(value) {
+		if (isString(value)) {
+			value.split(" ").forEach((token) => {
+				this.tokens.add(token.trim());
+			});
+		} else if (isIterable(value)) {
+			for (let token of value) {
+				validateString(token);
+				this.tokens.add(token.trim());
+			}
+		} else if (typeof value !== "undefined") {
+			throw new TypeError("unsupported value");
+		}
 
-        return this;
-    }
+		return this;
+	}
 
-    /**
-     * remove all tokens
-     *
-     * @returns {TokenList}
-     */
-    clear() {
-        this.tokens.clear();
-        return this;
-    }
+	/**
+	 * remove all tokens
+	 *
+	 * @returns {TokenList}
+	 */
+	clear() {
+		this.tokens.clear();
+		return this;
+	}
 
-    /**
-     * Removes token
-     *
-     * @externalExample ../../example/types/tokenlist-4.mjs
-     * @param {array|string|iteratable} value
-     * @returns {TokenList}
-     * @throws {TypeError} unsupported value
-     */
-    remove(value) {
-        if (isString(value)) {
-            value.split(" ").forEach((token) => {
-                this.tokens.delete(token.trim());
-            });
-        } else if (isIterable(value)) {
-            for (let token of value) {
-                validateString(token);
-                this.tokens.delete(token.trim());
-            }
-        } else if (typeof value !== "undefined") {
-            throw new TypeError("unsupported value", "types/tokenlist.mjs");
-        }
+	/**
+	 * Removes token
+	 *
+	 * @externalExample ../../example/types/tokenlist-4.mjs
+	 * @param {array|string|iteratable} value
+	 * @returns {TokenList}
+	 * @throws {TypeError} unsupported value
+	 */
+	remove(value) {
+		if (isString(value)) {
+			value.split(" ").forEach((token) => {
+				this.tokens.delete(token.trim());
+			});
+		} else if (isIterable(value)) {
+			for (let token of value) {
+				validateString(token);
+				this.tokens.delete(token.trim());
+			}
+		} else if (typeof value !== "undefined") {
+			throw new TypeError("unsupported value", "types/tokenlist.mjs");
+		}
 
-        return this;
-    }
+		return this;
+	}
 
-    /**
-     * this method replaces a token with a new token.
-     *
-     * if the passed token exists, it is replaced with newToken and TokenList is returned.
-     * if the token does not exist, newToken is not set and TokenList is returned.
-     *
-     * @param {string} token
-     * @param {string} newToken
-     * @returns {TokenList}
-     */
-    replace(token, newToken) {
-        validateString(token);
-        validateString(newToken);
-        if (!this.contains(token)) {
-            return this;
-        }
+	/**
+	 * this method replaces a token with a new token.
+	 *
+	 * if the passed token exists, it is replaced with newToken and TokenList is returned.
+	 * if the token does not exist, newToken is not set and TokenList is returned.
+	 *
+	 * @param {string} token
+	 * @param {string} newToken
+	 * @returns {TokenList}
+	 */
+	replace(token, newToken) {
+		validateString(token);
+		validateString(newToken);
+		if (!this.contains(token)) {
+			return this;
+		}
 
-        let a = Array.from(this.tokens);
-        let i = a.indexOf(token);
-        if (i === -1) return this;
+		let a = Array.from(this.tokens);
+		let i = a.indexOf(token);
+		if (i === -1) return this;
 
-        a.splice(i, 1, newToken);
-        this.tokens = new Set();
-        this.add(a);
+		a.splice(i, 1, newToken);
+		this.tokens = new Set();
+		this.add(a);
 
-        return this;
-    }
+		return this;
+	}
 
-    /**
-     * Removes token from string. If token doesn't exist it's added.
-     *
-     * @externalExample ../../example/types/tokenlist-5.mjs
-     * @param {array|string|iteratable} value
-     * @returns {boolean}
-     * @throws {TypeError} unsupported value
-     */
-    toggle(value) {
-        if (isString(value)) {
-            value.split(" ").forEach((token) => {
-                toggleValue.call(this, token);
-            });
-        } else if (isIterable(value)) {
-            for (let token of value) {
-                toggleValue.call(this, token);
-            }
-        } else if (typeof value !== "undefined") {
-            throw new TypeError("unsupported value", "types/tokenlist.mjs");
-        }
+	/**
+	 * Removes token from string. If token doesn't exist it's added.
+	 *
+	 * @externalExample ../../example/types/tokenlist-5.mjs
+	 * @param {array|string|iteratable} value
+	 * @returns {boolean}
+	 * @throws {TypeError} unsupported value
+	 */
+	toggle(value) {
+		if (isString(value)) {
+			value.split(" ").forEach((token) => {
+				toggleValue.call(this, token);
+			});
+		} else if (isIterable(value)) {
+			for (let token of value) {
+				toggleValue.call(this, token);
+			}
+		} else if (typeof value !== "undefined") {
+			throw new TypeError("unsupported value", "types/tokenlist.mjs");
+		}
 
-        return this;
-    }
+		return this;
+	}
 
-    /**
-     * returns an array with all tokens
-     *
-     * @returns {array}
-     */
-    entries() {
-        return Array.from(this.tokens);
-    }
+	/**
+	 * returns an array with all tokens
+	 *
+	 * @returns {array}
+	 */
+	entries() {
+		return Array.from(this.tokens);
+	}
 
-    /**
-     * executes the provided function with each value of the set
-     *
-     * @param {function} callback
-     * @returns {TokenList}
-     */
-    forEach(callback) {
-        validateFunction(callback);
-        this.tokens.forEach(callback);
-        return this;
-    }
+	/**
+	 * executes the provided function with each value of the set
+	 *
+	 * @param {function} callback
+	 * @returns {TokenList}
+	 */
+	forEach(callback) {
+		validateFunction(callback);
+		this.tokens.forEach(callback);
+		return this;
+	}
 
-    /**
-     * returns the individual tokens separated by a blank character
-     *
-     * @returns {string}
-     */
-    toString() {
-        return this.entries().join(" ");
-    }
+	/**
+	 * returns the individual tokens separated by a blank character
+	 *
+	 * @returns {string}
+	 */
+	toString() {
+		return this.entries().join(" ");
+	}
 }
 
 /**
@@ -251,13 +251,14 @@ class TokenList extends Base {
  * @throws {Error} must be called with TokenList.call
  */
 function toggleValue(token) {
-    if (!(this instanceof TokenList)) throw Error("must be called with TokenList.call");
-    validateString(token);
-    token = token.trim();
-    if (this.contains(token)) {
-        this.remove(token);
-        return this;
-    }
-    this.add(token);
-    return this;
+	if (!(this instanceof TokenList))
+		throw Error("must be called with TokenList.call");
+	validateString(token);
+	token = token.trim();
+	if (this.contains(token)) {
+		this.remove(token);
+		return this;
+	}
+	this.add(token);
+	return this;
 }
diff --git a/source/types/typeof.mjs b/source/types/typeof.mjs
index 0ec8d1c94a2eb4eb3202955c6437d4224aef570c..651c17c6e42ab8d1aa69dc892b4fd429f4467997 100644
--- a/source/types/typeof.mjs
+++ b/source/types/typeof.mjs
@@ -20,16 +20,18 @@ export { typeOf };
  * @throws {TypeError} value is not a primitive
  */
 function typeOf(value) {
-    let type = {}.toString.call(value).match(/\s([a-zA-Z]+)/)[1];
-    if ("Object" === type) {
-        const name = value.constructor.name;
-        if (name) {
-            return name.toLowerCase();
-        }
+	let type = {}.toString.call(value).match(/\s([a-zA-Z]+)/)[1];
+	if ("Object" === type) {
+		const name = value.constructor.name;
+		if (name) {
+			return name.toLowerCase();
+		}
 
-        const results = /^(class|function)\s+(\w+)/.exec(value.constructor.toString());
-        type = results && results.length > 2 ? results[2] : "";
-    }
+		const results = /^(class|function)\s+(\w+)/.exec(
+			value.constructor.toString(),
+		);
+		type = results && results.length > 2 ? results[2] : "";
+	}
 
-    return type.toLowerCase();
+	return type.toLowerCase();
 }
diff --git a/source/types/uniquequeue.mjs b/source/types/uniquequeue.mjs
index ccad0b9747d71dae83b2d1e860df581b8755829b..856920c2b0a1a8d7c6de53f59aa5ee078111d687 100644
--- a/source/types/uniquequeue.mjs
+++ b/source/types/uniquequeue.mjs
@@ -21,57 +21,57 @@ export { UniqueQueue };
  * @summary A queue for unique values
  */
 class UniqueQueue extends Queue {
-    /**
-     *
-     */
-    constructor() {
-        super();
-        this[internalSymbol] = {
-            unique: new WeakSet(),
-        };
-    }
+	/**
+	 *
+	 */
+	constructor() {
+		super();
+		this[internalSymbol] = {
+			unique: new WeakSet(),
+		};
+	}
 
-    /**
-     * Add a new element to the end of the queue.
-     *
-     * @param {object} value
-     * @returns {Queue}
-     * @throws {TypeError} value is not a object
-     */
-    add(value) {
-        validateObject(value);
+	/**
+	 * Add a new element to the end of the queue.
+	 *
+	 * @param {object} value
+	 * @returns {Queue}
+	 * @throws {TypeError} value is not a object
+	 */
+	add(value) {
+		validateObject(value);
 
-        if (!this[internalSymbol].unique.has(value)) {
-            this[internalSymbol].unique.add(value);
-            super.add(value);
-        }
+		if (!this[internalSymbol].unique.has(value)) {
+			this[internalSymbol].unique.add(value);
+			super.add(value);
+		}
 
-        return this;
-    }
+		return this;
+	}
 
-    /**
-     * remove all entries
-     *
-     * @returns {Queue}
-     */
-    clear() {
-        super.clear();
-        this[internalSymbol].unique = new WeakSet();
-        return this;
-    }
+	/**
+	 * remove all entries
+	 *
+	 * @returns {Queue}
+	 */
+	clear() {
+		super.clear();
+		this[internalSymbol].unique = new WeakSet();
+		return this;
+	}
 
-    /**
-     * Remove the element at the front of the queue
-     * If the queue is empty, return undefined.
-     *
-     * @return {object}
-     */
-    poll() {
-        if (this.isEmpty()) {
-            return undefined;
-        }
-        let value = this.data.shift();
-        this[internalSymbol].unique.delete(value);
-        return value;
-    }
+	/**
+	 * Remove the element at the front of the queue
+	 * If the queue is empty, return undefined.
+	 *
+	 * @return {object}
+	 */
+	poll() {
+		if (this.isEmpty()) {
+			return undefined;
+		}
+		let value = this.data.shift();
+		this[internalSymbol].unique.delete(value);
+		return value;
+	}
 }
diff --git a/source/types/uuid.mjs b/source/types/uuid.mjs
index bc832eb782fb32589e09d86b292c92a78fbe4a20..e7994368b7ad6b5f6b0a21ebe27aead969ead747 100644
--- a/source/types/uuid.mjs
+++ b/source/types/uuid.mjs
@@ -23,34 +23,34 @@ export { UUID };
  * @throws {Error} unsupported
  */
 class UUID extends Base {
-    /**
-     *
-     */
-    constructor() {
-        super();
+	/**
+	 *
+	 */
+	constructor() {
+		super();
 
-        let uuid = createWithCrypto();
+		let uuid = createWithCrypto();
 
-        if (uuid === undefined) {
-            uuid = createWithRandom();
-        }
+		if (uuid === undefined) {
+			uuid = createWithRandom();
+		}
 
-        if (uuid === undefined) {
-            throw new Error("unsupported");
-        }
+		if (uuid === undefined) {
+			throw new Error("unsupported");
+		}
 
-        this[internalSymbol] = {
-            value: uuid,
-        };
-    }
+		this[internalSymbol] = {
+			value: uuid,
+		};
+	}
 
-    /**
-     *
-     * @return {string}
-     */
-    toString() {
-        return this[internalSymbol]["value"];
-    }
+	/**
+	 *
+	 * @return {string}
+	 */
+	toString() {
+		return this[internalSymbol]["value"];
+	}
 }
 
 /**
@@ -58,11 +58,11 @@ class UUID extends Base {
  * @return {string|undefined}
  */
 function createWithRandom() {
-    return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
-        const r = (random(0, 65000) * 16) | 0;
-        const v = c === "x" ? r : (r & 0x3) | 0x8;
-        return v.toString(16)[0];
-    });
+	return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
+		const r = (random(0, 65000) * 16) | 0;
+		const v = c === "x" ? r : (r & 0x3) | 0x8;
+		return v.toString(16)[0];
+	});
 }
 
 /**
@@ -70,8 +70,8 @@ function createWithRandom() {
  * @return {string|undefined}
  */
 function createWithCrypto() {
-    const crypt = getGlobalObject("crypto");
-    if (!isObject(crypt)) return;
-    if (typeof crypt?.["randomUUID"]) return;
-    return crypt.randomUUID();
+	const crypt = getGlobalObject("crypto");
+	if (!isObject(crypt)) return;
+	if (typeof crypt?.["randomUUID"]) return;
+	return crypt.randomUUID();
 }
diff --git a/source/types/validate.mjs b/source/types/validate.mjs
index e97c4c6ff5410e4580b51e765da6947309338a54..f7aa7f5f2f7944815006f21bf7579aa038c8c16f 100644
--- a/source/types/validate.mjs
+++ b/source/types/validate.mjs
@@ -6,29 +6,29 @@
  */
 
 import {
-    isArray,
-    isBoolean,
-    isFunction,
-    isInstance,
-    isInteger,
-    isIterable,
-    isObject,
-    isPrimitive,
-    isString,
-    isSymbol,
+	isArray,
+	isBoolean,
+	isFunction,
+	isInstance,
+	isInteger,
+	isIterable,
+	isObject,
+	isPrimitive,
+	isString,
+	isSymbol,
 } from "./is.mjs";
 
 export {
-    validateIterable,
-    validatePrimitive,
-    validateBoolean,
-    validateString,
-    validateObject,
-    validateInstance,
-    validateArray,
-    validateSymbol,
-    validateFunction,
-    validateInteger,
+	validateIterable,
+	validatePrimitive,
+	validateBoolean,
+	validateString,
+	validateObject,
+	validateInstance,
+	validateArray,
+	validateSymbol,
+	validateFunction,
+	validateInteger,
 };
 
 /**
@@ -54,10 +54,10 @@ export {
  * @see {@link Monster.Types#isPrimitive}
  */
 function validateIterable(value) {
-    if (!isIterable(value)) {
-        throw new TypeError("value is not iterable");
-    }
-    return value;
+	if (!isIterable(value)) {
+		throw new TypeError("value is not iterable");
+	}
+	return value;
 }
 
 /**
@@ -83,10 +83,10 @@ function validateIterable(value) {
  * @see {@link Monster.Types#isPrimitive}
  */
 function validatePrimitive(value) {
-    if (!isPrimitive(value)) {
-        throw new TypeError("value is not a primitive");
-    }
-    return value;
+	if (!isPrimitive(value)) {
+		throw new TypeError("value is not a primitive");
+	}
+	return value;
 }
 
 /**
@@ -111,10 +111,10 @@ function validatePrimitive(value) {
  * @throws {TypeError}  value is not primitive
  */
 function validateBoolean(value) {
-    if (!isBoolean(value)) {
-        throw new TypeError("value is not a boolean");
-    }
-    return value;
+	if (!isBoolean(value)) {
+		throw new TypeError("value is not a boolean");
+	}
+	return value;
 }
 
 /**
@@ -137,10 +137,10 @@ function validateBoolean(value) {
  * @throws {TypeError} value is not a string
  */
 function validateString(value) {
-    if (!isString(value)) {
-        throw new TypeError("value is not a string");
-    }
-    return value;
+	if (!isString(value)) {
+		throw new TypeError("value is not a string");
+	}
+	return value;
 }
 
 /**
@@ -164,10 +164,10 @@ function validateString(value) {
  * @throws {TypeError} value is not a object
  */
 function validateObject(value) {
-    if (!isObject(value)) {
-        throw new TypeError("value is not a object");
-    }
-    return value;
+	if (!isObject(value)) {
+		throw new TypeError("value is not a object");
+	}
+	return value;
 }
 
 /**
@@ -191,19 +191,19 @@ function validateObject(value) {
  * @throws {TypeError} value is not an instance of
  */
 function validateInstance(value, instance) {
-    if (!isInstance(value, instance)) {
-        let n = "";
-        if (isObject(instance) || isFunction(instance)) {
-            n = instance?.["name"];
-        }
+	if (!isInstance(value, instance)) {
+		let n = "";
+		if (isObject(instance) || isFunction(instance)) {
+			n = instance?.["name"];
+		}
 
-        if (n) {
-            n = ` ${n}`;
-        }
+		if (n) {
+			n = ` ${n}`;
+		}
 
-        throw new TypeError(`value is not an instance of${n}`);
-    }
-    return value;
+		throw new TypeError(`value is not an instance of${n}`);
+	}
+	return value;
 }
 
 /**
@@ -226,10 +226,10 @@ function validateInstance(value, instance) {
  * @throws {TypeError} value is not an array
  */
 function validateArray(value) {
-    if (!isArray(value)) {
-        throw new TypeError("value is not an array");
-    }
-    return value;
+	if (!isArray(value)) {
+		throw new TypeError("value is not an array");
+	}
+	return value;
 }
 
 /**
@@ -252,10 +252,10 @@ function validateArray(value) {
  * @throws {TypeError} value is not an symbol
  */
 function validateSymbol(value) {
-    if (!isSymbol(value)) {
-        throw new TypeError("value is not an symbol");
-    }
-    return value;
+	if (!isSymbol(value)) {
+		throw new TypeError("value is not an symbol");
+	}
+	return value;
 }
 
 /**
@@ -279,10 +279,10 @@ function validateSymbol(value) {
  * @throws {TypeError} value is not a function
  */
 function validateFunction(value) {
-    if (!isFunction(value)) {
-        throw new TypeError("value is not a function");
-    }
-    return value;
+	if (!isFunction(value)) {
+		throw new TypeError("value is not a function");
+	}
+	return value;
 }
 
 /**
@@ -306,8 +306,8 @@ function validateFunction(value) {
  * @throws {TypeError} value is not an integer
  */
 function validateInteger(value) {
-    if (!isInteger(value)) {
-        throw new TypeError("value is not an integer");
-    }
-    return value;
+	if (!isInteger(value)) {
+		throw new TypeError("value is not an integer");
+	}
+	return value;
 }
diff --git a/source/types/version.mjs b/source/types/version.mjs
index 16d05410838c6ff0cefdb686a5add410ec754387..6d12667dfa18c7b09bdab9ce33e9648dc1b6c9ed 100644
--- a/source/types/version.mjs
+++ b/source/types/version.mjs
@@ -22,105 +22,115 @@ export { Version, getMonsterVersion };
  * @summary The version object contains a sematic version number
  */
 class Version extends Base {
-    /**
-     *
-     * @param major
-     * @param minor
-     * @param patch
-     * @throws {Error} major is not a number
-     * @throws {Error} minor is not a number
-     * @throws {Error} patch is not a number
-     */
-    constructor(major, minor, patch) {
-        super();
-
-        if (typeof major === "string" && minor === undefined && patch === undefined) {
-            let parts = major.toString().split(".");
-            major = parseInt(parts[0] || 0);
-            minor = parseInt(parts[1] || 0);
-            patch = parseInt(parts[2] || 0);
-        }
-
-        if (major === undefined) {
-            throw new Error("major version is undefined");
-        }
-
-        if (minor === undefined) {
-            minor = 0;
-        }
-
-        if (patch === undefined) {
-            patch = 0;
-        }
-
-        this.major = parseInt(major);
-        this.minor = parseInt(minor);
-        this.patch = parseInt(patch);
-
-        if (isNaN(this.major)) {
-            throw new Error("major is not a number");
-        }
-
-        if (isNaN(this.minor)) {
-            throw new Error("minor is not a number");
-        }
-
-        if (isNaN(this.patch)) {
-            throw new Error("patch is not a number");
-        }
-    }
-
-    /**
-     * This method is called by the `instanceof` operator.
-     * @returns {symbol}
-     * @since 2.1.0
-     */
-    static get [instanceSymbol]() {
-        return Symbol.for("@schukai/monster/types/version");
-    }
-
-    /**
-     *
-     * @returns {string}
-     */
-    toString() {
-        return `${this.major}.${this.minor}.${this.patch}`;
-    }
-
-    /**
-     * returns 0 if equal, -1 if the object version is less and 1 if greater
-     * than the compared version
-     *
-     * @param {string|Version} version Version to compare
-     * @returns {number}
-     */
-    compareTo(version) {
-        if (version instanceof Version) {
-            version = version.toString();
-        }
-
-        if (typeof version !== "string") {
-            throw new Error("type exception");
-        }
-
-        if (version === this.toString()) {
-            return 0;
-        }
-
-        let a = [this.major, this.minor, this.patch];
-        let b = version.split(".");
-        let len = Math.max(a.length, b.length);
-
-        for (let i = 0; i < len; i += 1) {
-            if ((a[i] && !b[i] && parseInt(a[i]) > 0) || parseInt(a[i]) > parseInt(b[i])) {
-                return 1;
-            } else if ((b[i] && !a[i] && parseInt(b[i]) > 0) || parseInt(a[i]) < parseInt(b[i])) {
-                return -1;
-            }
-        }
-
-        return 0;
-    }
+	/**
+	 *
+	 * @param major
+	 * @param minor
+	 * @param patch
+	 * @throws {Error} major is not a number
+	 * @throws {Error} minor is not a number
+	 * @throws {Error} patch is not a number
+	 */
+	constructor(major, minor, patch) {
+		super();
+
+		if (
+			typeof major === "string" &&
+			minor === undefined &&
+			patch === undefined
+		) {
+			let parts = major.toString().split(".");
+			major = parseInt(parts[0] || 0);
+			minor = parseInt(parts[1] || 0);
+			patch = parseInt(parts[2] || 0);
+		}
+
+		if (major === undefined) {
+			throw new Error("major version is undefined");
+		}
+
+		if (minor === undefined) {
+			minor = 0;
+		}
+
+		if (patch === undefined) {
+			patch = 0;
+		}
+
+		this.major = parseInt(major);
+		this.minor = parseInt(minor);
+		this.patch = parseInt(patch);
+
+		if (isNaN(this.major)) {
+			throw new Error("major is not a number");
+		}
+
+		if (isNaN(this.minor)) {
+			throw new Error("minor is not a number");
+		}
+
+		if (isNaN(this.patch)) {
+			throw new Error("patch is not a number");
+		}
+	}
+
+	/**
+	 * This method is called by the `instanceof` operator.
+	 * @returns {symbol}
+	 * @since 2.1.0
+	 */
+	static get [instanceSymbol]() {
+		return Symbol.for("@schukai/monster/types/version");
+	}
+
+	/**
+	 *
+	 * @returns {string}
+	 */
+	toString() {
+		return `${this.major}.${this.minor}.${this.patch}`;
+	}
+
+	/**
+	 * returns 0 if equal, -1 if the object version is less and 1 if greater
+	 * than the compared version
+	 *
+	 * @param {string|Version} version Version to compare
+	 * @returns {number}
+	 */
+	compareTo(version) {
+		if (version instanceof Version) {
+			version = version.toString();
+		}
+
+		if (typeof version !== "string") {
+			throw new Error("type exception");
+		}
+
+		if (version === this.toString()) {
+			return 0;
+		}
+
+		let a = [this.major, this.minor, this.patch];
+		let b = version.split(".");
+		let len = Math.max(a.length, b.length);
+
+		for (let i = 0; i < len; i += 1) {
+			if (
+				(a[i] && !b[i] && parseInt(a[i]) > 0) ||
+				parseInt(a[i]) > parseInt(b[i])
+			) {
+				return 1;
+			} else if (
+				(b[i] && !a[i] && parseInt(b[i]) > 0) ||
+				parseInt(a[i]) < parseInt(b[i])
+			) {
+				return -1;
+			}
+		}
+
+		return 0;
+	}
 }
 
 let monsterVersion;
@@ -137,12 +147,12 @@ let monsterVersion;
  * @memberOf Monster
  */
 function getMonsterVersion() {
-    if (monsterVersion instanceof Version) {
-        return monsterVersion;
-    }
+	if (monsterVersion instanceof Version) {
+		return monsterVersion;
+	}
 
-    /** don't touch, replaced by make with package.json version */
-    monsterVersion = new Version("3.51.5");
+	/** don't touch, replaced by make with package.json version */
+	monsterVersion = new Version("3.51.5");
 
-    return monsterVersion;
+	return monsterVersion;
 }
diff --git a/source/util/clone.mjs b/source/util/clone.mjs
index 5df58a329afc5fd874d545d7560abd715f223771..3482a1dfb096bc3786a296991824fe68b0ed5612 100644
--- a/source/util/clone.mjs
+++ b/source/util/clone.mjs
@@ -30,64 +30,70 @@ export { clone };
  * @throws {Error} unable to clone obj! its type isn't supported.
  */
 function clone(obj) {
-    // typeof null results in 'object'.  https://2ality.com/2013/10/typeof-null.html
-    if (null === obj) {
-        return obj;
-    }
-
-    // Handle the two simple types, null and undefined
-    if (isPrimitive(obj)) {
-        return obj;
-    }
-
-    // Handle the two simple types, null and undefined
-    if (isFunction(obj)) {
-        return obj;
-    }
-
-    // Handle Array
-    if (isArray(obj)) {
-        let copy = [];
-        for (var i = 0, len = obj.length; i < len; i++) {
-            copy[i] = clone(obj[i]);
-        }
-
-        return copy;
-    }
-
-    if (isObject(obj)) {
-        // Handle Date
-        if (obj instanceof Date) {
-            let copy = new Date();
-            copy.setTime(obj.getTime());
-            return copy;
-        }
-
-        /** Do not clone DOM nodes */
-        if (typeof Element !== "undefined" && obj instanceof Element) return obj;
-        if (typeof HTMLDocument !== "undefined" && obj instanceof HTMLDocument) return obj;
-        if (typeof DocumentFragment !== "undefined" && obj instanceof DocumentFragment) return obj;
-
-        /** Do not clone global objects */
-        if (obj === getGlobal()) return obj;
-        if (typeof globalContext !== "undefined" && obj === globalContext) return obj;
-        if (typeof window !== "undefined" && obj === window) return obj;
-        if (typeof document !== "undefined" && obj === document) return obj;
-        if (typeof navigator !== "undefined" && obj === navigator) return obj;
-        if (typeof JSON !== "undefined" && obj === JSON) return obj;
-
-        // Handle Proxy-Object
-        try {
-            // try/catch because possible: TypeError: Function has non-object prototype 'undefined' in instanceof check
-            if (obj instanceof Proxy) {
-                return obj;
-            }
-        } catch (e) {}
-
-        return cloneObject(obj);
-    }
-
-    throw new Error("unable to clone obj! its type isn't supported.");
+	// typeof null results in 'object'.  https://2ality.com/2013/10/typeof-null.html
+	if (null === obj) {
+		return obj;
+	}
+
+	// Handle the two simple types, null and undefined
+	if (isPrimitive(obj)) {
+		return obj;
+	}
+
+	// Handle the two simple types, null and undefined
+	if (isFunction(obj)) {
+		return obj;
+	}
+
+	// Handle Array
+	if (isArray(obj)) {
+		let copy = [];
+		for (var i = 0, len = obj.length; i < len; i++) {
+			copy[i] = clone(obj[i]);
+		}
+
+		return copy;
+	}
+
+	if (isObject(obj)) {
+		// Handle Date
+		if (obj instanceof Date) {
+			let copy = new Date();
+			copy.setTime(obj.getTime());
+			return copy;
+		}
+
+		/** Do not clone DOM nodes */
+		if (typeof Element !== "undefined" && obj instanceof Element) return obj;
+		if (typeof HTMLDocument !== "undefined" && obj instanceof HTMLDocument)
+			return obj;
+		if (
+			typeof DocumentFragment !== "undefined" &&
+			obj instanceof DocumentFragment
+		)
+			return obj;
+
+		/** Do not clone global objects */
+		if (obj === getGlobal()) return obj;
+		if (typeof globalContext !== "undefined" && obj === globalContext)
+			return obj;
+		if (typeof window !== "undefined" && obj === window) return obj;
+		if (typeof document !== "undefined" && obj === document) return obj;
+		if (typeof navigator !== "undefined" && obj === navigator) return obj;
+		if (typeof JSON !== "undefined" && obj === JSON) return obj;
+
+		// Handle Proxy-Object
+		try {
+			// try/catch because possible: TypeError: Function has non-object prototype 'undefined' in instanceof check
+			if (obj instanceof Proxy) {
+				return obj;
+			}
+		} catch (e) {}
+
+		return cloneObject(obj);
+	}
+
+	throw new Error("unable to clone obj! its type isn't supported.");
 }
 
 /**
@@ -97,37 +103,43 @@ function clone(obj) {
  * @private
  */
 function cloneObject(obj) {
-    validateObject(obj);
-
-    const fkt = obj?.["constructor"];
-
-    /** Object has clone method */
-    if (typeOf(fkt) === "function") {
-        const prototype = fkt?.prototype;
-        if (typeof prototype === "object") {
-            if (prototype.hasOwnProperty("getClone") && typeOf(obj.getClone) === "function") {
-                return obj.getClone();
-            }
-        }
-    }
-
-    let copy = {};
-    if (typeof obj.constructor === "function" && typeof obj.constructor.call === "function") {
-        copy = new obj.constructor();
-    }
-
-    for (let key in obj) {
-        if (!obj.hasOwnProperty(key)) {
-            continue;
-        }
-
-        if (isPrimitive(obj[key])) {
-            copy[key] = obj[key];
-            continue;
-        }
-
-        copy[key] = clone(obj[key]);
-    }
-
-    return copy;
+	validateObject(obj);
+
+	const fkt = obj?.["constructor"];
+
+	/** Object has clone method */
+	if (typeOf(fkt) === "function") {
+		const prototype = fkt?.prototype;
+		if (typeof prototype === "object") {
+			if (
+				prototype.hasOwnProperty("getClone") &&
+				typeOf(obj.getClone) === "function"
+			) {
+				return obj.getClone();
+			}
+		}
+	}
+
+	let copy = {};
+	if (
+		typeof obj.constructor === "function" &&
+		typeof obj.constructor.call === "function"
+	) {
+		copy = new obj.constructor();
+	}
+
+	for (let key in obj) {
+		if (!obj.hasOwnProperty(key)) {
+			continue;
+		}
+
+		if (isPrimitive(obj[key])) {
+			copy[key] = obj[key];
+			continue;
+		}
+
+		copy[key] = clone(obj[key]);
+	}
+
+	return copy;
 }
diff --git a/source/util/comparator.mjs b/source/util/comparator.mjs
index b681f7f1ea1eb76d796eb739fc584eb822bfb0d4..89342da7b8a3b444f9a79d356c828890a19d220a 100644
--- a/source/util/comparator.mjs
+++ b/source/util/comparator.mjs
@@ -37,112 +37,112 @@ export { Comparator };
  * @memberOf Monster.Util
  */
 class Comparator extends Base {
-    /**
-     * create new comparator
-     *
-     * @param {Monster.Util~exampleCallback} [callback] Comparator callback
-     * @throw {TypeError} unsupported type
-     * @throw {TypeError} impractical comparison
-     */
-    constructor(callback) {
-        super();
+	/**
+	 * create new comparator
+	 *
+	 * @param {Monster.Util~exampleCallback} [callback] Comparator callback
+	 * @throw {TypeError} unsupported type
+	 * @throw {TypeError} impractical comparison
+	 */
+	constructor(callback) {
+		super();
 
-        if (isFunction(callback)) {
-            this.compare = callback;
-        } else if (callback !== undefined) {
-            throw new TypeError("unsupported type");
-        } else {
-            // default compare function
+		if (isFunction(callback)) {
+			this.compare = callback;
+		} else if (callback !== undefined) {
+			throw new TypeError("unsupported type");
+		} else {
+			// default compare function
 
-            /**
-             *
-             * @param {*} a
-             * @param {*} b
-             * @return {integer} -1, 0 or 1
-             */
-            this.compare = function (a, b) {
-                if (typeof a !== typeof b) {
-                    throw new TypeError("impractical comparison", "types/comparator.mjs");
-                }
+			/**
+			 *
+			 * @param {*} a
+			 * @param {*} b
+			 * @return {integer} -1, 0 or 1
+			 */
+			this.compare = function (a, b) {
+				if (typeof a !== typeof b) {
+					throw new TypeError("impractical comparison", "types/comparator.mjs");
+				}
 
-                if (a === b) {
-                    return 0;
-                }
-                return a < b ? -1 : 1;
-            };
-        }
-    }
+				if (a === b) {
+					return 0;
+				}
+				return a < b ? -1 : 1;
+			};
+		}
+	}
 
-    /**
-     * changes the order of the operators
-     *
-     * @return {Comparator}
-     */
-    reverse() {
-        const original = this.compare;
-        this.compare = (a, b) => original(b, a);
-        return this;
-    }
+	/**
+	 * changes the order of the operators
+	 *
+	 * @return {Comparator}
+	 */
+	reverse() {
+		const original = this.compare;
+		this.compare = (a, b) => original(b, a);
+		return this;
+	}
 
-    /**
-     * Checks if two variables are equal.
-     *
-     * @param {*} a
-     * @param {*} b
-     *
-     * @return {boolean}
-     */
-    equal(a, b) {
-        return this.compare(a, b) === 0;
-    }
+	/**
+	 * Checks if two variables are equal.
+	 *
+	 * @param {*} a
+	 * @param {*} b
+	 *
+	 * @return {boolean}
+	 */
+	equal(a, b) {
+		return this.compare(a, b) === 0;
+	}
 
-    /**
-     * Checks if variable `a` is greater than `b`
-     *
-     * @param {*} a
-     * @param {*} b
-     *
-     * @return {boolean}
-     */
-    greaterThan(a, b) {
-        return this.compare(a, b) > 0;
-    }
+	/**
+	 * Checks if variable `a` is greater than `b`
+	 *
+	 * @param {*} a
+	 * @param {*} b
+	 *
+	 * @return {boolean}
+	 */
+	greaterThan(a, b) {
+		return this.compare(a, b) > 0;
+	}
 
-    /**
-     * Checks if variable `a` is greater than or equal to `b`
-     *
-     * @param {*} a
-     * @param {*} b
-     *
-     * @return {boolean}
-     */
-    greaterThanOrEqual(a, b) {
-        return this.greaterThan(a, b) || this.equal(a, b);
-    }
+	/**
+	 * Checks if variable `a` is greater than or equal to `b`
+	 *
+	 * @param {*} a
+	 * @param {*} b
+	 *
+	 * @return {boolean}
+	 */
+	greaterThanOrEqual(a, b) {
+		return this.greaterThan(a, b) || this.equal(a, b);
+	}
 
-    /**
-     * Checks if variable `a` is less than or equal to `b`
-     *
-     * @param {*} a
-     * @param {*} b
-     *
-     * @return {boolean}
-     */
-    lessThanOrEqual(a, b) {
-        return this.lessThan(a, b) || this.equal(a, b);
-    }
+	/**
+	 * Checks if variable `a` is less than or equal to `b`
+	 *
+	 * @param {*} a
+	 * @param {*} b
+	 *
+	 * @return {boolean}
+	 */
+	lessThanOrEqual(a, b) {
+		return this.lessThan(a, b) || this.equal(a, b);
+	}
 
-    /**
-     * Checks if variable a is less than b
-     *
-     * @param {*} a
-     * @param {*} b
-     *
-     * @return {boolean}
-     */
-    lessThan(a, b) {
-        return this.compare(a, b) < 0;
-    }
+	/**
+	 * Checks if variable a is less than b
+	 *
+	 * @param {*} a
+	 * @param {*} b
+	 *
+	 * @return {boolean}
+	 */
+	lessThan(a, b) {
+		return this.compare(a, b) < 0;
+	}
 }
 
 /**
diff --git a/source/util/deadmansswitch.mjs b/source/util/deadmansswitch.mjs
index 32fe83afbe5107ecb850d4006f92b781c4576ea8..04b0280949d04fcb48d2964ca402314eea820d04 100644
--- a/source/util/deadmansswitch.mjs
+++ b/source/util/deadmansswitch.mjs
@@ -24,53 +24,53 @@ export { DeadMansSwitch };
  * @summary Class to be able to execute function chains
  */
 class DeadMansSwitch extends Base {
-    /**
-     * Create new dead man's switch
-     *
-     * @param {Integer} delay
-     * @param {function} callback
-     * @throw {TypeError} the arguments must be either integer or functions
-     * @throws {TypeError} value is not an integer
-     */
-    constructor(delay, callback) {
-        super();
+	/**
+	 * Create new dead man's switch
+	 *
+	 * @param {Integer} delay
+	 * @param {function} callback
+	 * @throw {TypeError} the arguments must be either integer or functions
+	 * @throws {TypeError} value is not an integer
+	 */
+	constructor(delay, callback) {
+		super();
 
-        init.call(this, validateInteger(delay), validateFunction(callback));
-    }
+		init.call(this, validateInteger(delay), validateFunction(callback));
+	}
 
-    /**
-     *
-     * @param {Integer|undefined} [delay]
-     */
-    touch(delay) {
-        if (this[internalSymbol]["isAlreadyRun"] === true) {
-            throw new Error("has already run");
-        }
+	/**
+	 *
+	 * @param {Integer|undefined} [delay]
+	 */
+	touch(delay) {
+		if (this[internalSymbol]["isAlreadyRun"] === true) {
+			throw new Error("has already run");
+		}
 
-        if (isInteger(delay)) {
-            this[internalSymbol]["delay"] = delay;
-        } else if (delay !== undefined) {
-            throw new Error("unsupported argument");
-        }
+		if (isInteger(delay)) {
+			this[internalSymbol]["delay"] = delay;
+		} else if (delay !== undefined) {
+			throw new Error("unsupported argument");
+		}
 
-        clearTimeout(this[internalSymbol]["timer"]);
+		clearTimeout(this[internalSymbol]["timer"]);
 
-        initCallback.call(this);
+		initCallback.call(this);
 
-        return this;
-    }
+		return this;
+	}
 }
 
 /**
  * @private
  */
 function initCallback() {
-    const self = this;
+	const self = this;
 
-    self[internalSymbol]["timer"] = setTimeout(() => {
-        self[internalSymbol]["isAlreadyRun"] = true;
-        self[internalSymbol]["callback"]();
-    }, self[internalSymbol]["delay"]);
+	self[internalSymbol]["timer"] = setTimeout(() => {
+		self[internalSymbol]["isAlreadyRun"] = true;
+		self[internalSymbol]["callback"]();
+	}, self[internalSymbol]["delay"]);
 }
 
 /**
@@ -79,14 +79,14 @@ function initCallback() {
  * @param {function} callback
  */
 function init(delay, callback) {
-    const self = this;
+	const self = this;
 
-    self[internalSymbol] = {
-        callback,
-        delay,
-        isAlreadyRun: false,
-        timer: undefined,
-    };
+	self[internalSymbol] = {
+		callback,
+		delay,
+		isAlreadyRun: false,
+		timer: undefined,
+	};
 
-    initCallback.call(self);
+	initCallback.call(self);
 }
diff --git a/source/util/freeze.mjs b/source/util/freeze.mjs
index b17e54848c2f51624c95c2c1705bbfc1d88ab471..fbb20e5f8e7df311421419c4e2adcf151c3ad111 100644
--- a/source/util/freeze.mjs
+++ b/source/util/freeze.mjs
@@ -21,17 +21,18 @@ export { deepFreeze };
  * @throws {TypeError} value is not a object
  */
 function deepFreeze(object) {
-    validateObject(object);
+	validateObject(object);
 
-    // Retrieve the defined property names of the object
-    var propNames = Object.getOwnPropertyNames(object);
+	// Retrieve the defined property names of the object
+	var propNames = Object.getOwnPropertyNames(object);
 
-    // Freeze properties before freezing yourself
-    for (let name of propNames) {
-        let value = object[name];
+	// Freeze properties before freezing yourself
+	for (let name of propNames) {
+		let value = object[name];
 
-        object[name] = value && typeof value === "object" ? deepFreeze(value) : value;
-    }
+		object[name] =
+			value && typeof value === "object" ? deepFreeze(value) : value;
+	}
 
-    return Object.freeze(object);
+	return Object.freeze(object);
 }
diff --git a/source/util/processing.mjs b/source/util/processing.mjs
index 2f9ece33ba7006c63443c70dd928e9fe1ba1bfe2..b0b1ef1f68f84b18b44e3ae274205164ef677c55 100644
--- a/source/util/processing.mjs
+++ b/source/util/processing.mjs
@@ -5,51 +5,51 @@
  * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
  */
 
-import {internalSymbol} from "../constants.mjs";
-import {Base} from "../types/base.mjs";
-import {getGlobalFunction} from "../types/global.mjs";
-import {isFunction, isInteger} from "../types/is.mjs";
-import {Queue} from "../types/queue.mjs";
-import {validateFunction, validateInteger} from "../types/validate.mjs";
+import { internalSymbol } from "../constants.mjs";
+import { Base } from "../types/base.mjs";
+import { getGlobalFunction } from "../types/global.mjs";
+import { isFunction, isInteger } from "../types/is.mjs";
+import { Queue } from "../types/queue.mjs";
+import { validateFunction, validateInteger } from "../types/validate.mjs";
 
-export {Processing};
+export { Processing };
 
 /**
  * @private
  */
 class Callback {
-    /**
-     *
-     * @param {function} callback
-     * @param {int|undefined} time
-     * @throws {TypeError} value is not a function
-     * @throws {TypeError} value is not an integer
-     * @private
-     */
-    constructor(callback, time) {
-        this[internalSymbol] = {
-            callback: validateFunction(callback),
-            time: validateInteger(time ?? 0),
-        };
-    }
+	/**
+	 *
+	 * @param {function} callback
+	 * @param {int|undefined} time
+	 * @throws {TypeError} value is not a function
+	 * @throws {TypeError} value is not an integer
+	 * @private
+	 */
+	constructor(callback, time) {
+		this[internalSymbol] = {
+			callback: validateFunction(callback),
+			time: validateInteger(time ?? 0),
+		};
+	}
 
-    /**
-     * @private
-     * @param  {*} data
-     * @return {Promise}
-     */
-    run(data) {
-        const self = this;
-        return new Promise((resolve, reject) => {
-            getGlobalFunction("setTimeout")(() => {
-                try {
-                    resolve(self[internalSymbol].callback(data));
-                } catch (e) {
-                    reject(e);
-                }
-            }, self[internalSymbol].time);
-        });
-    }
+	/**
+	 * @private
+	 * @param  {*} data
+	 * @return {Promise}
+	 */
+	run(data) {
+		const self = this;
+		return new Promise((resolve, reject) => {
+			getGlobalFunction("setTimeout")(() => {
+				try {
+					resolve(self[internalSymbol].callback(data));
+				} catch (e) {
+					reject(e);
+				}
+			}, self[internalSymbol].time);
+		});
+	}
 }
 
 /**
@@ -74,80 +74,81 @@ class Callback {
  * @summary Class to be able to execute function chains
  */
 class Processing extends Base {
-    /**
-     * Create new Processing
-     *
-     * Functions and timeouts can be passed. If a timeout is passed, it applies to all further functions.
-     * In the example
-     *
-     * `timeout1, function1, function2, function3, timeout2, function4`
-     *
-     * the timeout1 is valid for the functions 1, 2 and 3 and the timeout2 for the function4.
-     *
-     * So the execution time is timeout1+timeout1+timeout1+timeout2
-     *
-     * @throw {TypeError} the arguments must be either integer or functions
-     * @param {...(int|function)} args
-     */
-    constructor(...args) {
-        super();
+	/**
+	 * Create new Processing
+	 *
+	 * Functions and timeouts can be passed. If a timeout is passed, it applies to all further functions.
+	 * In the example
+	 *
+	 * `timeout1, function1, function2, function3, timeout2, function4`
+	 *
+	 * the timeout1 is valid for the functions 1, 2 and 3 and the timeout2 for the function4.
+	 *
+	 * So the execution time is timeout1+timeout1+timeout1+timeout2
+	 *
+	 * @throw {TypeError} the arguments must be either integer or functions
+	 * @param {...(int|function)} args
+	 */
+	constructor(...args) {
+		super();
 
-        this[internalSymbol] = {
-            queue: new Queue(),
-        };
+		this[internalSymbol] = {
+			queue: new Queue(),
+		};
 
-        let time = 0;
+		let time = 0;
 
-        if (typeof args !== "object" || args[0] === null) {
-            throw new TypeError("the arguments must be either integer or functions");
-        }
+		if (typeof args !== "object" || args[0] === null) {
+			throw new TypeError("the arguments must be either integer or functions");
+		}
 
-        for (const [, arg] of Object.entries(args)) {
-            if (isInteger(arg) && arg >= 0) {
-                time = arg;
-            } else if (isFunction(arg)) {
-                this[internalSymbol].queue.add(new Callback(arg, time));
-            } else {
-                throw new TypeError("the arguments must be either integer or functions");
-            }
-        }
-    }
+		for (const [, arg] of Object.entries(args)) {
+			if (isInteger(arg) && arg >= 0) {
+				time = arg;
+			} else if (isFunction(arg)) {
+				this[internalSymbol].queue.add(new Callback(arg, time));
+			} else {
+				throw new TypeError(
+					"the arguments must be either integer or functions",
+				);
+			}
+		}
+	}
 
-    /**
-     * Adds a function with the desired timeout
-     * If no timeout is specified, the timeout of the previous function is used.
-     *
-     * @param {function} callback
-     * @param {int|undefined} time
-     * @throws {TypeError} value is not a function
-     * @throws {TypeError} value is not an integer
-     */
-    add(callback, time) {
-        this[internalSymbol].queue.add(new Callback(callback, time));
-        return this;
-    }
+	/**
+	 * Adds a function with the desired timeout
+	 * If no timeout is specified, the timeout of the previous function is used.
+	 *
+	 * @param {function} callback
+	 * @param {int|undefined} time
+	 * @throws {TypeError} value is not a function
+	 * @throws {TypeError} value is not an integer
+	 */
+	add(callback, time) {
+		this[internalSymbol].queue.add(new Callback(callback, time));
+		return this;
+	}
 
-    /**
-     * Executes the defined functions in order.
-     *
-     * @param {*} data
-     * @return {Promise}
-     */
-    run(data) {
-        const self = this;
-        if (self[internalSymbol].queue.isEmpty()) {
-            return Promise.resolve(data);
-        }
+	/**
+	 * Executes the defined functions in order.
+	 *
+	 * @param {*} data
+	 * @return {Promise}
+	 */
+	run(data) {
+		const self = this;
+		if (self[internalSymbol].queue.isEmpty()) {
+			return Promise.resolve(data);
+		}
 
-        const callback = self[internalSymbol].queue.poll();
+		const callback = self[internalSymbol].queue.poll();
 
-        if (callback === null || callback === undefined) {
-            return Promise.resolve(data);
-        }
+		if (callback === null || callback === undefined) {
+			return Promise.resolve(data);
+		}
 
-        return callback.run(data)
-            .then((result) => {
-                return self.run(result);
-            });
-    }
+		return callback.run(data).then((result) => {
+			return self.run(result);
+		});
+	}
 }
diff --git a/source/util/runtime.mjs b/source/util/runtime.mjs
index 41803e3a1aba5a180be49daf3e51c4d0ae5c77b3..1c0803e9ea2eb989cc010858d04b14a122982c5e 100644
--- a/source/util/runtime.mjs
+++ b/source/util/runtime.mjs
@@ -64,56 +64,68 @@ const ENV_UNKNOWN = "unknown";
  * @returns {string} The detected runtime environment. Possible values are:
  */
 function detectRuntimeEnvironment() {
-    // AWS Lambda environment
-    if (typeof process !== "undefined" && process.env != null && process.env.AWS_LAMBDA_FUNCTION_NAME) {
-        return ENV_AWS_LAMBDA;
-    }
+	// AWS Lambda environment
+	if (
+		typeof process !== "undefined" &&
+		process.env != null &&
+		process.env.AWS_LAMBDA_FUNCTION_NAME
+	) {
+		return ENV_AWS_LAMBDA;
+	}
 
-    // Google Cloud Functions environment
-    if (typeof process !== "undefined" && process.env != null && process.env.FUNCTION_NAME) {
-        return ENV_GOOGLE_FUNCTIONS;
-    }
+	// Google Cloud Functions environment
+	if (
+		typeof process !== "undefined" &&
+		process.env != null &&
+		process.env.FUNCTION_NAME
+	) {
+		return ENV_GOOGLE_FUNCTIONS;
+	}
 
-    // Node.js environment
-    if (typeof process !== "undefined" && process.versions != null && process.versions.node != null) {
-        // Electron environment
-        if (process.versions.electron != null) {
-            return ENV_ELECTRON;
-        }
-        return ENV_NODE;
-    }
+	// Node.js environment
+	if (
+		typeof process !== "undefined" &&
+		process.versions != null &&
+		process.versions.node != null
+	) {
+		// Electron environment
+		if (process.versions.electron != null) {
+			return ENV_ELECTRON;
+		}
+		return ENV_NODE;
+	}
 
-    // Browser environment
-    if (
-        typeof window !== "undefined" &&
-        typeof window.document !== "undefined" &&
-        typeof navigator !== "undefined" &&
-        typeof navigator.userAgent === "string"
-    ) {
-        // Web Worker environment
-        if (typeof self === "object" && typeof importScripts === "function") {
-            return ENV_WEB_WORKER;
-        }
-        return ENV_BROWSER;
-    }
+	// Browser environment
+	if (
+		typeof window !== "undefined" &&
+		typeof window.document !== "undefined" &&
+		typeof navigator !== "undefined" &&
+		typeof navigator.userAgent === "string"
+	) {
+		// Web Worker environment
+		if (typeof self === "object" && typeof importScripts === "function") {
+			return ENV_WEB_WORKER;
+		}
+		return ENV_BROWSER;
+	}
 
-    // Deno environment
-    if (typeof Deno !== "undefined") {
-        return ENV_DENO;
-    }
+	// Deno environment
+	if (typeof Deno !== "undefined") {
+		return ENV_DENO;
+	}
 
-    // Unknown environment
-    return ENV_UNKNOWN;
+	// Unknown environment
+	return ENV_UNKNOWN;
 }
 
 export {
-    ENV_AWS_LAMBDA,
-    ENV_GOOGLE_FUNCTIONS,
-    ENV_ELECTRON,
-    ENV_NODE,
-    ENV_BROWSER,
-    ENV_WEB_WORKER,
-    ENV_DENO,
-    ENV_UNKNOWN,
-    detectRuntimeEnvironment,
+	ENV_AWS_LAMBDA,
+	ENV_GOOGLE_FUNCTIONS,
+	ENV_ELECTRON,
+	ENV_NODE,
+	ENV_BROWSER,
+	ENV_WEB_WORKER,
+	ENV_DENO,
+	ENV_UNKNOWN,
+	detectRuntimeEnvironment,
 };
diff --git a/source/util/trimspaces.mjs b/source/util/trimspaces.mjs
index 9967daa4704baf0bcf619fca774976b76b5692b8..9bfadc0171506279e255aea405c55a9d03d6fa68 100644
--- a/source/util/trimspaces.mjs
+++ b/source/util/trimspaces.mjs
@@ -37,35 +37,35 @@ export { trimSpaces };
  * @throws {TypeError} value is not a string
  */
 function trimSpaces(value) {
-    validateString(value);
+	validateString(value);
 
-    let placeholder = new Map();
-    const regex = /((?<pattern>\\(?<char>.)){1})/gim;
+	let placeholder = new Map();
+	const regex = /((?<pattern>\\(?<char>.)){1})/gim;
 
-    // The separator for args must be escaped
-    // undefined string which should not occur normally and is also not a regex
-    let result = value.matchAll(regex);
+	// The separator for args must be escaped
+	// undefined string which should not occur normally and is also not a regex
+	let result = value.matchAll(regex);
 
-    for (let m of result) {
-        let g = m?.["groups"];
-        if (!isObject(g)) {
-            continue;
-        }
+	for (let m of result) {
+		let g = m?.["groups"];
+		if (!isObject(g)) {
+			continue;
+		}
 
-        let p = g?.["pattern"];
-        let c = g?.["char"];
+		let p = g?.["pattern"];
+		let c = g?.["char"];
 
-        if (p && c) {
-            let r = `__${new ID().toString()}__`;
-            placeholder.set(r, c);
-            value = value.replace(p, r);
-        }
-    }
+		if (p && c) {
+			let r = `__${new ID().toString()}__`;
+			placeholder.set(r, c);
+			value = value.replace(p, r);
+		}
+	}
 
-    value = value.trim();
-    placeholder.forEach((v, k) => {
-        value = value.replace(k, `\\${v}`);
-    });
+	value = value.trim();
+	placeholder.forEach((v, k) => {
+		value = value.replace(k, `\\${v}`);
+	});
 
-    return value;
+	return value;
 }