diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
index d66d746..dd48733 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PageRenderer.java
@@ -74,7 +74,7 @@
 import java.util.Locale;
 import java.util.Map;
 
-// currently using tobago-myfaces.js instead
+// using jsf.js from a specific MyFaces version instead, to avoid old bugs
 //@ResourceDependency(name="jsf.js", library="javax.faces", target="head")
 public class PageRenderer extends RendererBase {
 
@@ -391,7 +391,7 @@
             if ("javax.faces".equals(attributes.get("library"))
                 && "jsf.js".equals(attributes.get("name"))) {
               // workaround for WebSphere
-              // We don't need jsf.js from the JSF impl, because Tobago comes with its own tobago-myfaces.js
+              // We don't need jsf.js from the JSF impl, because Tobago comes with its own jsf.js
               if (LOG.isDebugEnabled()) {
                 LOG.debug("Skip rendering resource jsf.js");
               }
diff --git a/tobago-theme/pom.xml b/tobago-theme/pom.xml
index bf1b449..ac6ee95 100644
--- a/tobago-theme/pom.xml
+++ b/tobago-theme/pom.xml
@@ -152,6 +152,8 @@
                     <include>ts/ext*.ts</include>
                     <include>js/tobago*.js</include>
                     <include>js/tobago*.js.map</include>
+                    <include>js/jsf*.js</include>
+                    <include>js/jsf*.js.map</include>
                     <include>ts/tobago*.ts</include>
                     <include>ts/test.ts</include>
                     <!-- todo: check a better way for polyfill -->
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/js/jsf-development.js b/tobago-theme/tobago-theme-standard/src/main/npm/js/jsf-development.js
new file mode 100644
index 0000000..6f021f8
--- /dev/null
+++ b/tobago-theme/tobago-theme-standard/src/main/npm/js/jsf-development.js
@@ -0,0 +1,6521 @@
+(function(e, a) { for(var i in a) e[i] = a[i]; }(window, /******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId]) {
+/******/ 			return installedModules[moduleId].exports;
+/******/ 		}
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			i: moduleId,
+/******/ 			l: false,
+/******/ 			exports: {}
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.l = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+/******/
+/******/ 	// define getter function for harmony exports
+/******/ 	__webpack_require__.d = function(exports, name, getter) {
+/******/ 		if(!__webpack_require__.o(exports, name)) {
+/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
+/******/ 		}
+/******/ 	};
+/******/
+/******/ 	// define __esModule on exports
+/******/ 	__webpack_require__.r = function(exports) {
+/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
+/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+/******/ 		}
+/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
+/******/ 	};
+/******/
+/******/ 	// create a fake namespace object
+/******/ 	// mode & 1: value is a module id, require it
+/******/ 	// mode & 2: merge all properties of value into the ns
+/******/ 	// mode & 4: return value when already ns object
+/******/ 	// mode & 8|1: behave like require
+/******/ 	__webpack_require__.t = function(value, mode) {
+/******/ 		if(mode & 1) value = __webpack_require__(value);
+/******/ 		if(mode & 8) return value;
+/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
+/******/ 		var ns = Object.create(null);
+/******/ 		__webpack_require__.r(ns);
+/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
+/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
+/******/ 		return ns;
+/******/ 	};
+/******/
+/******/ 	// getDefaultExport function for compatibility with non-harmony modules
+/******/ 	__webpack_require__.n = function(module) {
+/******/ 		var getter = module && module.__esModule ?
+/******/ 			function getDefault() { return module['default']; } :
+/******/ 			function getModuleExports() { return module; };
+/******/ 		__webpack_require__.d(getter, 'a', getter);
+/******/ 		return getter;
+/******/ 	};
+/******/
+/******/ 	// Object.prototype.hasOwnProperty.call
+/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+/******/
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(__webpack_require__.s = "./src/main/typescript/api/Jsf.ts");
+/******/ })
+/************************************************************************/
+/******/ ({
+
+/***/ "./src/main/typescript/api/Jsf.ts":
+/*!****************************************!*\
+  !*** ./src/main/typescript/api/Jsf.ts ***!
+  \****************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var __spreadArrays = (this && this.__spreadArrays) || function () {
+    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
+    for (var r = Array(s), k = 0, i = 0; i < il; i++)
+        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
+            r[k] = a[j];
+    return r;
+};
+var _a, _b, _c;
+Object.defineProperty(exports, "__esModule", { value: true });
+///<reference path='./ApiInterfaces.ts'/>
+///<reference types='../../types/typedefs'/>
+var AjaxImpl_1 = __webpack_require__(/*! ../impl/AjaxImpl */ "./src/main/typescript/impl/AjaxImpl.ts");
+var PushImpl_1 = __webpack_require__(/*! ../impl/PushImpl */ "./src/main/typescript/impl/PushImpl.ts");
+var mf_impl = (_c = (_b = (_a = window) === null || _a === void 0 ? void 0 : _a.myfaces) === null || _b === void 0 ? void 0 : _b._impl, (_c !== null && _c !== void 0 ? _c : {}));
+var jsf;
+(function (jsf) {
+    "use strict";
+    /*
+     * Version of the implementation for the jsf.js.
+     * <p />
+     * as specified within the jsf specifications jsf.html:
+     * <ul>
+     * <li>left two digits major release number</li>
+     * <li>middle two digits minor spec release number</li>
+     * <li>right two digits bug release number</li>
+     * </ul>
+     * @constant
+     */
+    jsf.specversion = 220000;
+    /**
+     * Implementation version as specified within the jsf specification.
+     * <p />
+     * A number increased with every implementation version
+     * and reset by moving to a new spec release number
+     *
+     * @constant
+     */
+    jsf.implversion = 0;
+    /**
+     * SeparatorChar as defined by UINamingContainer.getNamingContainerSeparatorChar()
+     * @type {Char}
+     */
+    jsf.separatorchar = getSeparatorChar();
+    /**
+     * This method is responsible for the return of a given project stage as defined
+     * by the jsf specification.
+     * <p/>
+     * Valid return values are:
+     * <ul>
+     *     <li>&quot;Production&quot;</li>
+     *     <li>&quot;Development&quot;</li>
+     *     <li>&quot;SystemTest&quot;</li>
+     *     <li>&quot;UnitTest&quot;</li>
+     * </li>
+     *
+     * @return {String} the current project state emitted by the server side method:
+     * <i>javax.faces.application.Application.getProjectStage()</i>
+     */
+    function getProjectStage() {
+        return AjaxImpl_1.Implementation.getProjectStage();
+    }
+    jsf.getProjectStage = getProjectStage;
+    /**
+     * collect and encode data for a given form element (must be of type form)
+     * find the javax.faces.ViewState element and encode its value as well!
+     * return a concatenated string of the encoded values!
+     *
+     * @throws an exception in case of the given element not being of type form!
+     * https://issues.apache.org/jira/browse/MYFACES-2110
+     */
+    function getViewState(formElement) {
+        return AjaxImpl_1.Implementation.getViewState(formElement);
+    }
+    jsf.getViewState = getViewState;
+    /**
+     * returns the window identifier for the given node / window
+     * @param {optional String | DomNode}  the node for which the client identifier has to be determined
+     * @return the window identifier or null if none is found
+     */
+    function getClientWindow(rootNode) {
+        return AjaxImpl_1.Implementation.getClientWindow(rootNode);
+    }
+    jsf.getClientWindow = getClientWindow;
+    //private helper functions
+    function getSeparatorChar() {
+        return AjaxImpl_1.Implementation.getSeparatorChar();
+    }
+    var ajax;
+    (function (ajax) {
+        "use strict";
+        /**
+         * this function has to send the ajax requests
+         *
+         * following requestInternal conditions must be met:
+         * <ul>
+         *  <li> the requestInternal must be sent asynchronously! </li>
+         *  <li> the requestInternal must be a POST!!! requestInternal </li>
+         *  <li> the requestInternal url must be the form action attribute </li>
+         *  <li> all requests must be queued with a client side requestInternal queue to ensure the requestInternal ordering!</li>
+         * </ul>
+         *
+         * @param {String|Node} element: any dom element no matter being it html or jsf, from which the event is emitted
+         * @param {EVENT} event: any javascript event supported by that object
+         * @param {Map} options : map of options being pushed into the ajax cycle
+         */
+        function request(element, event, options) {
+            AjaxImpl_1.Implementation.request(element, event, options);
+            //Implementation.getInstance().requestInternal(element, event, options);
+        }
+        ajax.request = request;
+        /**
+         * response handler
+         * @param request the request object having triggered this response
+         * @param context the request context
+         *
+         * TODO add info on what can be in the context
+         */
+        function response(request, context) {
+            AjaxImpl_1.Implementation.response(request, context);
+        }
+        ajax.response = response;
+        /**
+         * Adds an error handler to our global error queue.
+         * the error handler must be of the format <i>function errorListener(&lt;errorData&gt;)</i>
+         * with errorData being of following format:
+         * <ul>
+         *     <li> errorData.type : &quot;error&quot;</li>
+         *     <li> errorData.status : the error status message</li>
+         *     <li> errorData.serverErrorName : the server error name in case of a server error</li>
+         *     <li> errorData.serverErrorMessage : the server error message in case of a server error</li>
+         *     <li> errorData.source  : the issuing source element which triggered the requestInternal </li>
+         *     <li> eventData.responseCode: the response code (aka http requestInternal response code, 401 etc...) </li>
+         *     <li> eventData.responseText: the requestInternal response text </li>
+         *     <li> eventData.responseXML: the requestInternal response xml </li>
+         * </ul>
+         *
+         * @param {function} errorListener error handler must be of the format <i>function errorListener(&lt;errorData&gt;)</i>
+         */
+        function addOnError(errorFunc) {
+            AjaxImpl_1.Implementation.addOnError(errorFunc);
+        }
+        ajax.addOnError = addOnError;
+        /**
+         * Adds a global event listener to the ajax event queue. The event listener must be a function
+         * of following format: <i>function eventListener(&lt;eventData&gt;)</i>
+         *
+         * @param {function} eventListener event must be of the format <i>function eventListener(&lt;eventData&gt;)</i>
+         */
+        function addOnEvent(eventFunc) {
+            AjaxImpl_1.Implementation.addOnEvent(eventFunc);
+        }
+        ajax.addOnEvent = addOnEvent;
+    })(ajax = jsf.ajax || (jsf.ajax = {}));
+    var util;
+    (function (util) {
+        /**
+         * varargs function which executes a chain of code (functions or any other code)
+         *
+         * if any of the code returns false, the execution
+         * is terminated prematurely skipping the rest of the code!
+         *
+         * @param {DomNode} source, the callee object
+         * @param {Event} event, the event object of the callee event triggering this function
+         * @param funcs ... arbitrary array of functions or strings
+         * @returns true if the chain has succeeded false otherwise
+         */
+        function chain(source, event) {
+            var funcs = [];
+            for (var _i = 2; _i < arguments.length; _i++) {
+                funcs[_i - 2] = arguments[_i];
+            }
+            return AjaxImpl_1.Implementation.chain.apply(AjaxImpl_1.Implementation, __spreadArrays([source, event], funcs));
+        }
+        util.chain = chain;
+    })(util = jsf.util || (jsf.util = {}));
+    var push;
+    (function (push) {
+        /**
+         * @param {function} onopen The function to be invoked when the web socket is opened.
+         * @param {function} onmessage The function to be invoked when a message is received.
+         * @param {function} onclose The function to be invoked when the web socket is closed.
+         * @param {boolean} autoconnect Whether or not to immediately open the socket. Defaults to <code>false</code>.
+         */
+        function init(socketClientId, uri, channel, onopen, onmessage, onclose, behaviorScripts, autoconnect) {
+            PushImpl_1.PushImpl.init(socketClientId, uri, channel, onopen, onmessage, onclose, behaviorScripts, autoconnect);
+        }
+        push.init = init;
+        /**
+         * Open the web socket on the given channel.
+         * @param {string} channel The name of the web socket channel.
+         * @throws {Error} When channel is unknown.
+         */
+        function open(socketClientId) {
+            PushImpl_1.PushImpl.open(socketClientId);
+        }
+        push.open = open;
+        /**
+         * Close the web socket on the given channel.
+         * @param {string} channel The name of the web socket channel.
+         * @throws {Error} When channel is unknown.
+         */
+        function close(socketClientId) {
+            PushImpl_1.PushImpl.close(socketClientId);
+        }
+        push.close = close;
+    })(push = jsf.push || (jsf.push = {}));
+    //We hook the old namespace system into our npm system
+    //if ("undefined" == window.jsf) {
+    //    window.jsf = jsf;
+    //}
+})(jsf = exports.jsf || (exports.jsf = {}));
+//fullfill the window contract
+var myfaces;
+(function (myfaces) {
+    var _a, _b, _c;
+    //legacy compatibility
+    myfaces._impl = mf_impl;
+    /**
+     * AB function similar to mojarra and Primefaces
+     * not part of the spec but a convenience accessor method
+     * Code provided by Thomas Andraschko
+     *
+     * @param source the event source
+     * @param event the event
+     * @param eventName event name for java.javax.faces.behavior.evemnt
+     * @param execute execute list as passed down in jsf.ajax.request
+     * @param render
+     * @param options
+     */
+    function ab(source, event, eventName, execute, render, options) {
+        if (options === void 0) { options = {}; }
+        if (eventName) {
+            options["javax.faces.behavior.event"] = eventName;
+        }
+        if (execute) {
+            options["execute"] = execute;
+        }
+        if (render) {
+            options["render"] = render;
+        }
+        jsf.ajax.request(source, event, options);
+    }
+    myfaces.ab = ab;
+    //We hook the old namespace system into our npm system
+    if ("undefined" == ((_b = (_a = window) === null || _a === void 0 ? void 0 : _a.myfaces) === null || _b === void 0 ? void 0 : _b.ab)) {
+        window["myfaces"] = (_c = window.myfaces, (_c !== null && _c !== void 0 ? _c : {}));
+        window.myfaces["ab"] = ab;
+    }
+})(myfaces = exports.myfaces || (exports.myfaces = {}));
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/api/Myfaces.ts":
+/*!********************************************!*\
+  !*** ./src/main/typescript/api/Myfaces.ts ***!
+  \********************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+var myfaces;
+(function (myfaces) {
+    var ConfigHolder = /** @class */ (function () {
+        function ConfigHolder() {
+            this.projectStage = null;
+            this.separator = null;
+        }
+        return ConfigHolder;
+    }());
+    myfaces.ConfigHolder = ConfigHolder;
+    myfaces.config = new ConfigHolder();
+    //if (window && "undefined" == typeof window.myfaces) {
+    //    window.myfaces = myfaces;
+    //}
+})(myfaces = exports.myfaces || (exports.myfaces = {}));
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/ext/monadish/DomQuery.ts":
+/*!******************************************************!*\
+  !*** ./src/main/typescript/ext/monadish/DomQuery.ts ***!
+  \******************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+var __spreadArrays = (this && this.__spreadArrays) || function () {
+    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
+    for (var r = Array(s), k = 0, i = 0; i < il; i++)
+        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
+            r[k] = a[j];
+    return r;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var Monad_1 = __webpack_require__(/*! ./Monad */ "./src/main/typescript/ext/monadish/Monad.ts");
+var Stream_1 = __webpack_require__(/*! ./Stream */ "./src/main/typescript/ext/monadish/Stream.ts");
+var Lang_1 = __webpack_require__(/*! ./Lang */ "./src/main/typescript/ext/monadish/Lang.ts");
+var trim = Lang_1.Lang.trim;
+var objToArray = Lang_1.Lang.objToArray;
+var isString = Lang_1.Lang.isString;
+var equalsIgnoreCase = Lang_1.Lang.equalsIgnoreCase;
+// @ts-ignore supression needed here due to fromnullable
+var ElementAttribute = /** @class */ (function (_super) {
+    __extends(ElementAttribute, _super);
+    function ElementAttribute(element, name, defaultVal) {
+        if (defaultVal === void 0) { defaultVal = null; }
+        var _this = _super.call(this, element, name) || this;
+        _this.element = element;
+        _this.name = name;
+        _this.defaultVal = defaultVal;
+        return _this;
+    }
+    Object.defineProperty(ElementAttribute.prototype, "value", {
+        get: function () {
+            var _a;
+            var val = (_a = this.element.get(0)).orElse.apply(_a, []).values;
+            if (!val.length) {
+                return this.defaultVal;
+            }
+            return val[0].getAttribute(this.name);
+        },
+        set: function (value) {
+            var _a;
+            var val = (_a = this.element.get(0)).orElse.apply(_a, []).values;
+            for (var cnt = 0; cnt < val.length; cnt++) {
+                val[cnt].setAttribute(this.name, value);
+            }
+            val[0].setAttribute(this.name, value);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    ElementAttribute.prototype.getClass = function () {
+        return ElementAttribute;
+    };
+    ElementAttribute.fromNullable = function (value, valueKey) {
+        if (valueKey === void 0) { valueKey = "value"; }
+        return new ElementAttribute(value, valueKey);
+    };
+    return ElementAttribute;
+}(Monad_1.ValueEmbedder));
+exports.ElementAttribute = ElementAttribute;
+/**
+ * small helper for the specialized jsf case
+ * @param src
+ * @constructor
+ */
+var DEFAULT_JSF_WHITELIST = function (src) {
+    return (src.indexOf("ln=scripts") == -1 &&
+        src.indexOf("ln=javax.faces") == -1) ||
+        (src.indexOf("/jsf.js") == -1 &&
+            src.indexOf("/jsf-uncompressed.js") == -1);
+};
+/**
+ * Monadic DomNode representation, ala jquery
+ * This is a thin wrapper over querySelectorAll
+ * to get slim monadic support
+ * to reduce implementation code on the users side.
+ * This is vital for frameworks which want to rely on
+ * plain dom but still do not want to lose
+ * the reduced code footprint of querying dom trees and traversing
+ * by using functional patterns.
+ *
+ * Also a few convenience methods are added to reduce
+ * the code footprint of standard dom processing
+ * operations like eval
+ *
+ * TODO add jquery fallback support, since it is supported
+ * in most older systems
+ * Note parts of this code still stem from the Dom.js I have written 10 years
+ * ago, those parts look a little bit ancient and will be replaced over time.
+ *
+ */
+var DomQuery = /** @class */ (function () {
+    function DomQuery() {
+        var _a;
+        var rootNode = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            rootNode[_i] = arguments[_i];
+        }
+        this.rootNode = [];
+        this.pos = -1;
+        this._limits = -1;
+        if (Monad_1.Optional.fromNullable(rootNode).isAbsent() || !rootNode.length) {
+            return;
+        }
+        else {
+            //we need to flatten out the arrays
+            for (var cnt = 0; cnt < rootNode.length; cnt++) {
+                if (isString(rootNode[cnt])) {
+                    var foundElement = DomQuery.querySelectorAll(rootNode[cnt]);
+                    if (!foundElement.isAbsent()) {
+                        rootNode.push.apply(rootNode, foundElement.values);
+                    }
+                }
+                else if (rootNode[cnt] instanceof DomQuery) {
+                    (_a = this.rootNode).push.apply(_a, rootNode[cnt].values);
+                }
+                else {
+                    this.rootNode.push(rootNode[cnt]);
+                }
+            }
+        }
+    }
+    Object.defineProperty(DomQuery.prototype, "value", {
+        /**
+         * returns the first element
+         */
+        get: function () {
+            return this.getAsElem(0);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(DomQuery.prototype, "values", {
+        get: function () {
+            return this.allElems();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(DomQuery.prototype, "id", {
+        /**
+         * returns the id of the first element
+         */
+        get: function () {
+            return new ElementAttribute(this.get(0), "id");
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(DomQuery.prototype, "length", {
+        /**
+         * length of the entire query set
+         */
+        get: function () {
+            return this.rootNode.length;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(DomQuery.prototype, "tagName", {
+        /**
+         * convenience method for tagName
+         */
+        get: function () {
+            return this.getAsElem(0).getIf("tagName");
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(DomQuery.prototype, "nodeName", {
+        /**
+         * convenience method for nodeName
+         */
+        get: function () {
+            return this.getAsElem(0).getIf("nodeName");
+        },
+        enumerable: true,
+        configurable: true
+    });
+    DomQuery.prototype.isTag = function (tagName) {
+        return !this.isAbsent()
+            && (this.nodeName.orElse("__none___")
+                .value.toLowerCase() == tagName.toLowerCase()
+                || this.tagName.orElse("__none___")
+                    .value.toLowerCase() == tagName.toLowerCase());
+    };
+    Object.defineProperty(DomQuery.prototype, "type", {
+        /**
+         * convenience property for type
+         *
+         * returns null in case of no type existing otherwise
+         * the type of the first element
+         */
+        get: function () {
+            return this.getAsElem(0).getIf("type");
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(DomQuery.prototype, "name", {
+        /**
+         * convenience property for name
+         *
+         * returns null in case of no type existing otherwise
+         * the name of the first element
+         */
+        get: function () {
+            return new Monad_1.ValueEmbedder(this.getAsElem(0).value, "name");
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(DomQuery.prototype, "inputValue", {
+        /**
+         * convenience property for value
+         *
+         * returns null in case of no type existing otherwise
+         * the value of the first element
+         */
+        get: function () {
+            if (this.getAsElem(0).getIf("value").isPresent()) {
+                return new Monad_1.ValueEmbedder(this.getAsElem(0).value);
+            }
+            else {
+                return Monad_1.ValueEmbedder.absent;
+            }
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(DomQuery.prototype, "checked", {
+        get: function () {
+            return Stream_1.Stream.of.apply(Stream_1.Stream, this.values).allMatch(function (el) { return !!el.checked; });
+        },
+        set: function (newChecked) {
+            this.eachElem(function (el) { return el.checked = newChecked; });
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(DomQuery.prototype, "elements", {
+        get: function () {
+            var _this = this;
+            var elements = this.stream.flatMap(function (item) {
+                var formElement = item.value.value;
+                return new Stream_1.Stream(formElement.elements ? objToArray(formElement.elements) : []);
+            }).filter(function (item) { return !!item; }).collect(new DomQueryCollector());
+            return elements
+                .orElseLazy(function () { return _this.querySelectorAll("input, select, textarea, fieldset"); });
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(DomQuery.prototype, "disabled", {
+        /**
+         * todo align this api with the rest of the apis
+         */
+        get: function () {
+            return this.attr("disabled").isPresent();
+        },
+        set: function (disabled) {
+            // this.attr("disabled").value = disabled + "";
+            if (!disabled) {
+                this.removeAttribute("disabled");
+            }
+            else {
+                this.attr("disabled").value = "disabled";
+            }
+        },
+        enumerable: true,
+        configurable: true
+    });
+    DomQuery.prototype.removeAttribute = function (name) {
+        this.eachElem(function (item) { return item.removeAttribute(name); });
+    };
+    Object.defineProperty(DomQuery.prototype, "childNodes", {
+        get: function () {
+            var childNodeArr = [];
+            this.eachElem(function (item) {
+                childNodeArr = childNodeArr.concat(objToArray(item.childNodes));
+            });
+            return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], childNodeArr)))();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(DomQuery.prototype, "stream", {
+        /**
+         * binding into stream
+         */
+        get: function () {
+            return new (Stream_1.Stream.bind.apply(Stream_1.Stream, __spreadArrays([void 0], this.asArray)))();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(DomQuery.prototype, "lazyStream", {
+        /**
+         * fetches a lazy stream representation
+         * lazy should be applied if you have some filters etc
+         * in between, this can reduce the number of post filter operations
+         * and ram usage
+         * significantly because the operations are done lazily and stop
+         * once they hit a dead end.
+         */
+        get: function () {
+            return Stream_1.LazyStream.ofStreamDataSource(this);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(DomQuery.prototype, "asArray", {
+        get: function () {
+            var ret = [];
+            this.each(function (item) {
+                ret.push(item);
+            });
+            return ret;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    /**
+     * easy query selector all producer
+     *
+     * @param selector the selector
+     * @returns a results dom query object
+     */
+    DomQuery.querySelectorAll = function (selector) {
+        return new DomQuery(document).querySelectorAll(selector);
+    };
+    /**
+     * byId producer
+     *
+     * @param selector id
+     * @return a DomQuery containing the found elements
+     */
+    DomQuery.byId = function (selector) {
+        if (isString(selector)) {
+            return new DomQuery(document).byId(selector);
+        }
+        else {
+            return new DomQuery(selector);
+        }
+    };
+    /**
+     * byTagName producer
+     *
+     * @param selector name
+     * @return a DomQuery containing the found elements
+     */
+    DomQuery.byTagName = function (selector) {
+        if (isString(selector)) {
+            return new DomQuery(document).byTagName(selector);
+        }
+        else {
+            return new DomQuery(selector);
+        }
+    };
+    DomQuery.globalEval = function (code, nonce) {
+        return new DomQuery(document).globalEval(code, nonce);
+    };
+    /**
+     * builds the ie nodes properly in a placeholder
+     * and bypasses a non script insert bug that way
+     * @param markup the marku code
+     */
+    DomQuery.fromMarkup = function (markup) {
+        //https://developer.mozilla.org/de/docs/Web/API/DOMParser license creative commons
+        var doc = document.implementation.createHTMLDocument("");
+        markup = trim(markup);
+        var lowerMarkup = markup.toLowerCase();
+        if (lowerMarkup.indexOf('<!doctype') != -1 ||
+            lowerMarkup.indexOf('<html') != -1 ||
+            lowerMarkup.indexOf('<head') != -1 || //TODO proper regexps here to avoid embedded tags with same element names to be triggered
+            lowerMarkup.indexOf('<body') != -1) {
+            doc.documentElement.innerHTML = markup;
+            return new DomQuery(doc.documentElement);
+        }
+        else {
+            var startsWithTag = function (str, tagName) {
+                var tag1 = ["<", tagName, ">"].join("");
+                var tag2 = ["<", tagName, " "].join("");
+                return (str.indexOf(tag1) == 0) || (str.indexOf(tag2) == 0);
+            };
+            var dummyPlaceHolder = new DomQuery(document.createElement("div"));
+            //table needs special treatment due to the browsers auto creation
+            if (startsWithTag(lowerMarkup, "thead") || startsWithTag(lowerMarkup, "tbody")) {
+                dummyPlaceHolder.html("<table>" + markup + "</table>");
+                return dummyPlaceHolder.querySelectorAll("table").get(0).childNodes.detach();
+            }
+            else if (startsWithTag(lowerMarkup, "tfoot")) {
+                dummyPlaceHolder.html("<table><thead></thead><tbody><tbody" + markup + "</table>");
+                return dummyPlaceHolder.querySelectorAll("table").get(2).childNodes.detach();
+            }
+            else if (startsWithTag(lowerMarkup, "tr")) {
+                dummyPlaceHolder.html("<table><tbody>" + markup + "</tbody></table>");
+                return dummyPlaceHolder.querySelectorAll("tbody").get(0).childNodes.detach();
+            }
+            else if (startsWithTag(lowerMarkup, "td")) {
+                dummyPlaceHolder.html("<table><tbody><tr>" + markup + "</tr></tbody></table>");
+                return dummyPlaceHolder.querySelectorAll("tr").get(0).childNodes.detach();
+            }
+            dummyPlaceHolder.html(markup);
+            return dummyPlaceHolder.childNodes.detach();
+        }
+    };
+    /**
+     * returns the nth element as domquery
+     * from the internal elements
+     * note if you try to reach a non existing element position
+     * you will get back an absent entry
+     *
+     * @param index the nth index
+     */
+    DomQuery.prototype.get = function (index) {
+        return (index < this.rootNode.length) ? new DomQuery(this.rootNode[index]) : DomQuery.absent;
+    };
+    /**
+     * returns the nth element as optional of an Element object
+     * @param index the number from the index
+     * @param defaults the default value if the index is overrun default Optional.absent
+     */
+    DomQuery.prototype.getAsElem = function (index, defaults) {
+        if (defaults === void 0) { defaults = Monad_1.Optional.absent; }
+        return (index < this.rootNode.length) ? Monad_1.Optional.fromNullable(this.rootNode[index]) : defaults;
+    };
+    /**
+     * returns the value array< of all elements
+     */
+    DomQuery.prototype.allElems = function () {
+        return this.rootNode;
+    };
+    /**
+     * absent no values reached?
+     */
+    DomQuery.prototype.isAbsent = function () {
+        return this.length == 0;
+    };
+    /**
+     * should make the code clearer
+     * note if you pass a function
+     * this refers to the active dopmquery object
+     */
+    DomQuery.prototype.isPresent = function (presentRunnable) {
+        var absent = this.isAbsent();
+        if (!absent && presentRunnable) {
+            presentRunnable.call(this, this);
+        }
+        return !absent;
+    };
+    /**
+     * should make the code clearer
+     * note if you pass a function
+     * this refers to the active dopmquery object
+     *
+     *
+     * @param presentRunnable
+     */
+    DomQuery.prototype.ifPresentLazy = function (presentRunnable) {
+        if (presentRunnable === void 0) { presentRunnable = function () {
+        }; }
+        this.isPresent.call(this, presentRunnable);
+        return this;
+    };
+    /**
+     * remove all affected nodes from this query object from the dom tree
+     */
+    DomQuery.prototype.delete = function () {
+        this.eachElem(function (node) {
+            if (node.parentNode) {
+                node.parentNode.removeChild(node);
+            }
+        });
+    };
+    /**
+     * query selector all on the existing dom query object
+     *
+     * @param selector the standard selector
+     * @return a DomQuery with the results
+     */
+    DomQuery.prototype.querySelectorAll = function (selector) {
+        var _a, _b, _c;
+        if (!((_b = (_a = this) === null || _a === void 0 ? void 0 : _a.rootNode) === null || _b === void 0 ? void 0 : _b.length)) {
+            return this;
+        }
+        var nodes = [];
+        for (var cnt = 0; cnt < this.rootNode.length; cnt++) {
+            if (!((_c = this.rootNode[cnt]) === null || _c === void 0 ? void 0 : _c.querySelectorAll)) {
+                continue;
+            }
+            var res = this.rootNode[cnt].querySelectorAll(selector);
+            nodes = nodes.concat(objToArray(res));
+        }
+        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], nodes)))();
+    };
+    /**
+     * core byId method
+     * @param id the id to search for
+     * @param includeRoot also match the root element?
+     */
+    DomQuery.prototype.byId = function (id, includeRoot) {
+        var _a;
+        var res = [];
+        for (var cnt = 0; includeRoot && cnt < this.rootNode.length; cnt++) {
+            if (((_a = this.rootNode[cnt]) === null || _a === void 0 ? void 0 : _a.id) == id) {
+                res.push(new DomQuery(this.rootNode[cnt]));
+            }
+        }
+        //for some strange kind of reason the # selector fails
+        //on hidden elements we use the attributes match selector
+        //that works
+        res = res.concat(this.querySelectorAll("[id=\"" + id + "\"]"));
+        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], res)))();
+    };
+    /**
+     * same as byId just for the tag name
+     * @param tagName
+     * @param includeRoot
+     */
+    DomQuery.prototype.byTagName = function (tagName, includeRoot) {
+        var _a;
+        var res = [];
+        for (var cnt = 0; includeRoot && cnt < this.rootNode.length; cnt++) {
+            if (((_a = this.rootNode[cnt]) === null || _a === void 0 ? void 0 : _a.tagName) == tagName) {
+                res.push(new DomQuery(this.rootNode[cnt]));
+            }
+        }
+        res = res.concat(this.querySelectorAll(tagName));
+        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], res)))();
+    };
+    /**
+     * attr accessor, usage myQuery.attr("class").value = "bla"
+     * or let value myQuery.attr("class").value
+     * @param attr the attribute to set
+     * @param defaultValue the default value in case nothing is presented (defaults to null)
+     */
+    DomQuery.prototype.attr = function (attr, defaultValue) {
+        if (defaultValue === void 0) { defaultValue = null; }
+        return new ElementAttribute(this, attr, defaultValue);
+    };
+    /**
+     * hasclass, checks for an existing class in the class attributes
+     *
+     * @param clazz the class to search for
+     */
+    DomQuery.prototype.hasClass = function (clazz) {
+        var hasIt = false;
+        this.each(function (item) {
+            var oldClass = item.attr("class").value || "";
+            if (oldClass.toLowerCase().indexOf(clazz.toLowerCase()) == -1) {
+                return;
+            }
+            else {
+                var oldClasses = oldClass.split(/\s+/gi);
+                var found = false;
+                for (var cnt = 0; cnt < oldClasses.length && !found; cnt++) {
+                    found = oldClasses[cnt].toLowerCase() == clazz.toLowerCase();
+                }
+                hasIt = hasIt || found;
+                if (hasIt) {
+                    return false;
+                }
+            }
+        });
+        return hasIt;
+    };
+    /**
+     * appends a class string if not already in the element(s)
+     *
+     * @param clazz the style class to append
+     */
+    DomQuery.prototype.addClass = function (clazz) {
+        var _this = this;
+        this.each(function (item) {
+            var oldClass = item.attr("class").value || "";
+            if (!_this.hasClass(clazz)) {
+                item.attr("class").value = trim(oldClass + " " + clazz);
+                return;
+            }
+        });
+        return this;
+    };
+    /**
+     * remove the style class if in the class definitions
+     *
+     * @param clazz
+     */
+    DomQuery.prototype.removeClass = function (clazz) {
+        var _this = this;
+        this.each(function (item) {
+            if (_this.hasClass(clazz)) {
+                var oldClass = item.attr("class").value || "";
+                var newClasses = [];
+                var oldClasses = oldClass.split(/\s+/gi);
+                for (var cnt = 0; cnt < oldClasses.length; cnt++) {
+                    if (oldClasses[cnt].toLowerCase() != clazz.toLowerCase()) {
+                        newClasses.push(oldClasses[cnt]);
+                    }
+                }
+                item.attr("class").value = newClasses.join(" ");
+            }
+        });
+        return this;
+    };
+    /**
+     * checks whether we have a multipart element in our children
+     */
+    DomQuery.prototype.isMultipartCandidate = function () {
+        return this.querySelectorAll("input[type='file']").firstElem().isPresent();
+    };
+    /**
+     * innerHtml equivalkent
+     * equivalent to jqueries html
+     * as setter the html is set and the
+     * DomQuery is given back
+     * as getter the html string is returned
+     *
+     * @param inval
+     */
+    DomQuery.prototype.html = function (inval) {
+        if (Monad_1.Optional.fromNullable(inval).isAbsent()) {
+            return this.isPresent() ? Monad_1.Optional.fromNullable(this.innerHtml) : Monad_1.Optional.absent;
+        }
+        this.innerHtml = inval;
+        return this;
+    };
+    Object.defineProperty(DomQuery.prototype, "innerHtml", {
+        get: function () {
+            var retArr = [];
+            this.eachElem(function (elem) { return retArr.push(elem.innerHTML); });
+            return retArr.join("");
+        },
+        set: function (inVal) {
+            this.eachElem(function (elem) { return elem.innerHTML = inVal; });
+        },
+        enumerable: true,
+        configurable: true
+    });
+    //source: https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
+    //code snippet license: https://creativecommons.org/licenses/by-sa/2.5/
+    DomQuery.prototype._mozMatchesSelector = function (toMatch, selector) {
+        var prot = toMatch;
+        var matchesSelector = prot.matchesSelector ||
+            prot.mozMatchesSelector ||
+            prot.msMatchesSelector ||
+            prot.oMatchesSelector ||
+            prot.webkitMatchesSelector ||
+            function (s) {
+                var matches = (document || window.ownerDocument).querySelectorAll(s), i = matches.length;
+                while (--i >= 0 && matches.item(i) !== toMatch) {
+                }
+                return i > -1;
+            };
+        return matchesSelector.call(toMatch, selector);
+    };
+    /**
+     * filters the current dom query elements
+     * upon a given selector
+     *
+     * @param selector
+     */
+    DomQuery.prototype.filterSelector = function (selector) {
+        var _this = this;
+        var matched = [];
+        this.eachElem(function (item) {
+            if (_this._mozMatchesSelector(item, selector)) {
+                matched.push(item);
+            }
+        });
+        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], matched)))();
+    };
+    DomQuery.prototype.matchesSelector = function (selector) {
+        var _this = this;
+        this.eachElem(function (item) {
+            if (!_this._mozMatchesSelector(item, selector)) {
+                return false;
+            }
+        });
+        return true;
+    };
+    /**
+     * easy node traversal, you can pass
+     * a set of node selectors which are joined as direct childs
+     *
+     * not the rootnodes are not in the getIf, those are always the child nodes
+     *
+     * @param nodeSelector
+     */
+    DomQuery.prototype.getIf = function () {
+        var nodeSelector = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            nodeSelector[_i] = arguments[_i];
+        }
+        var selectorStage = this.childNodes;
+        for (var cnt = 0; cnt < nodeSelector.length; cnt++) {
+            selectorStage = selectorStage.filterSelector(nodeSelector[cnt]);
+            if (selectorStage.isAbsent()) {
+                return selectorStage;
+            }
+        }
+        return selectorStage;
+    };
+    DomQuery.prototype.eachElem = function (func) {
+        for (var cnt = 0, len = this.rootNode.length; cnt < len; cnt++) {
+            if (func(this.rootNode[cnt], cnt) === false) {
+                break;
+            }
+        }
+        return this;
+    };
+    DomQuery.prototype.firstElem = function (func) {
+        if (func === void 0) { func = function (item) { return item; }; }
+        if (this.rootNode.length > 1) {
+            func(this.rootNode[0], 0);
+        }
+        return this;
+    };
+    DomQuery.prototype.each = function (func) {
+        Stream_1.Stream.of.apply(Stream_1.Stream, this.rootNode).each(function (item, cnt) {
+            //we could use a filter, but for the best performance we dont
+            if (item == null) {
+                return;
+            }
+            return func(DomQuery.byId(item), cnt);
+        });
+        return this;
+    };
+    /**
+     * returns a new dom query containing only the first element max
+     *
+     * @param func a an optional callback function to perform an operation on the first element
+     */
+    DomQuery.prototype.first = function (func) {
+        if (func === void 0) { func = function (item) { return item; }; }
+        if (this.rootNode.length >= 1) {
+            func(this.get(0), 0);
+            return this.get(0);
+        }
+        return this;
+    };
+    /**
+     * filter function which filters a subset
+     *
+     * @param func
+     */
+    DomQuery.prototype.filter = function (func) {
+        var reArr = [];
+        this.each(function (item) {
+            func(item) ? reArr.push(item) : null;
+        });
+        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], reArr)))();
+    };
+    //TODO append prepend
+    /**
+     * global eval head appendix method
+     * no other methods are supported anymore
+     * @param code the code to be evaled
+     * @param  nonce optional  nonce key for higher security
+     */
+    DomQuery.prototype.globalEval = function (code, nonce) {
+        var head = document.getElementsByTagName("head")[0] || document.documentElement;
+        var script = document.createElement("script");
+        if (nonce) {
+            script.setAttribute("nonce", nonce);
+        }
+        script.type = "text/javascript";
+        script.innerHTML = code;
+        var newScriptElement = head.appendChild(script);
+        head.removeChild(newScriptElement);
+        return this;
+    };
+    /**
+     * detaches a set of nodes from their parent elements
+     * in a browser independend manner
+     * @param {Object} items the items which need to be detached
+     * @return {Array} an array of nodes with the detached dom nodes
+     */
+    DomQuery.prototype.detach = function () {
+        this.eachElem(function (item) {
+            item.parentNode.removeChild(item);
+        });
+        return this;
+    };
+    /**
+     * appends the current set of elements
+     * to the element or first element passed via elem
+     * @param elem
+     */
+    DomQuery.prototype.appendTo = function (elem) {
+        this.eachElem(function (item) {
+            var value1 = elem.getAsElem(0).orElseLazy(function () {
+                return {
+                    appendChild: function (theItem) {
+                    }
+                };
+            }).value;
+            value1.appendChild(item);
+        });
+    };
+    /**
+     * loads and evals a script from a source uri
+     *
+     * @param src the source to be loaded and evaled
+     * @param defer in miliseconds execution default (0 == no defer)
+     * @param charSet
+     */
+    DomQuery.prototype.loadScriptEval = function (src, defer, charSet) {
+        var _this = this;
+        if (defer === void 0) { defer = 0; }
+        if (charSet === void 0) { charSet = "utf-8"; }
+        var xhr = new XMLHttpRequest();
+        xhr.open("GET", src, false);
+        if (charSet) {
+            xhr.setRequestHeader("Content-Type", "application/x-javascript; charset:" + charSet);
+        }
+        xhr.send(null);
+        xhr.onload = function (responseData) {
+            //defer also means we have to process after the ajax response
+            //has been processed
+            //we can achieve that with a small timeout, the timeout
+            //triggers after the processing is done!
+            if (!defer) {
+                _this.globalEval(xhr.responseText.replace("\n", "\r\n") + "\r\n//@ sourceURL=" + src);
+            }
+            else {
+                //TODO not ideal we maybe ought to move to something else here
+                //but since it is not in use yet, it is ok
+                setTimeout(function () {
+                    _this.globalEval(xhr.responseText + "\r\n//@ sourceURL=" + src);
+                }, defer);
+            }
+        };
+        xhr.onerror = function (data) {
+            throw Error(data);
+        };
+        //since we are synchronous we do it after not with onReadyStateChange
+        return this;
+    };
+    DomQuery.prototype.insertAfter = function () {
+        var toInsertParams = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            toInsertParams[_i] = arguments[_i];
+        }
+        this.each(function (existingItem) {
+            var existingElement = existingItem.getAsElem(0).value;
+            var rootNode = existingElement.parentNode;
+            var _loop_1 = function (cnt) {
+                var nextSibling = existingElement.nextSibling;
+                toInsertParams[cnt].eachElem(function (insertElem) {
+                    if (nextSibling) {
+                        rootNode.insertBefore(insertElem, nextSibling);
+                        existingElement = nextSibling;
+                    }
+                    else {
+                        rootNode.appendChild(insertElem);
+                    }
+                });
+            };
+            for (var cnt = 0; cnt < toInsertParams.length; cnt++) {
+                _loop_1(cnt);
+            }
+        });
+        var res = [];
+        res.push(this);
+        res = res.concat(toInsertParams);
+        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], res)))();
+    };
+    DomQuery.prototype.insertBefore = function () {
+        var toInsertParams = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            toInsertParams[_i] = arguments[_i];
+        }
+        this.each(function (existingItem) {
+            var existingElement = existingItem.getAsElem(0).value;
+            var rootNode = existingElement.parentNode;
+            for (var cnt = 0; cnt < toInsertParams.length; cnt++) {
+                toInsertParams[cnt].eachElem(function (insertElem) {
+                    rootNode.insertBefore(insertElem, existingElement);
+                });
+            }
+        });
+        var res = [];
+        res.push(this);
+        res = res.concat(toInsertParams);
+        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], res)))();
+    };
+    DomQuery.prototype.orElse = function () {
+        var elseValue = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            elseValue[_i] = arguments[_i];
+        }
+        if (this.isPresent()) {
+            return this;
+        }
+        else {
+            return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], elseValue)))();
+        }
+    };
+    DomQuery.prototype.orElseLazy = function (func) {
+        if (this.isPresent()) {
+            return this;
+        }
+        else {
+            return new DomQuery(func());
+        }
+    };
+    DomQuery.prototype.parents = function (tagName) {
+        var retSet = new Set();
+        var retArr = [];
+        var lowerTagName = tagName.toLowerCase();
+        var resolveItem = function (item) {
+            if ((item.tagName || "").toLowerCase() == lowerTagName && !retSet.has(item)) {
+                retSet.add(item);
+                retArr.push(item);
+            }
+        };
+        this.eachElem(function (item) {
+            while (item.parentNode) {
+                item = item.parentNode;
+                resolveItem(item);
+                //nested forms not possible, performance shortcut
+                if (tagName == "form" && retArr.length) {
+                    return false;
+                }
+            }
+        });
+        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], retArr)))();
+    };
+    DomQuery.prototype.copyAttrs = function (sourceItem) {
+        var _this = this;
+        sourceItem.eachElem(function (sourceNode) {
+            var attrs = objToArray(sourceNode.attributes);
+            for (var _i = 0, attrs_1 = attrs; _i < attrs_1.length; _i++) {
+                var item = attrs_1[_i];
+                var value = item.value;
+                var name_1 = item.name;
+                switch (name_1) {
+                    case "id":
+                        _this.id.value = value;
+                        break;
+                    case "disabled":
+                        _this.resolveAttributeHolder("disabled").disabled = value;
+                        break;
+                    case "checked":
+                        _this.resolveAttributeHolder("checked").checked = value;
+                        break;
+                    default:
+                        _this.attr(name_1).value = value;
+                }
+            }
+        });
+        return this;
+    };
+    /**
+     * resolves an attribute holder compared
+     * @param attrName the attribute name
+     */
+    DomQuery.prototype.resolveAttributeHolder = function (attrName) {
+        if (attrName === void 0) { attrName = "value"; }
+        var ret = [];
+        ret[attrName] = null;
+        return (attrName in this.getAsElem(0).value) ?
+            this.getAsElem(0).value :
+            ret;
+    };
+    /**
+     * outerhtml convenience method
+     * browsers only support innerHTML but
+     * for instance for your jsf.js we have a full
+     * replace pattern which needs outerHTML processing
+     *
+     * @param markup
+     * @param runEmbeddedScripts
+     * @param runEmbeddedCss
+     */
+    DomQuery.prototype.outerHTML = function (markup, runEmbeddedScripts, runEmbeddedCss) {
+        var _a, _b;
+        if (this.isAbsent()) {
+            return;
+        }
+        var focusElementId = (_b = (_a = document) === null || _a === void 0 ? void 0 : _a.activeElement) === null || _b === void 0 ? void 0 : _b.id;
+        var caretPosition = (focusElementId) ? DomQuery.getCaretPosition(document.activeElement) : null;
+        var nodes = DomQuery.fromMarkup(markup);
+        var res = [];
+        var toReplace = this.getAsElem(0).value;
+        var firstInsert = nodes.get(0);
+        var parentNode = toReplace.parentNode;
+        var replaced = firstInsert.getAsElem(0).value;
+        parentNode.replaceChild(replaced, toReplace);
+        res.push(new DomQuery(replaced));
+        //no replacement possible
+        if (this.isAbsent()) {
+            return this;
+        }
+        var insertAdditionalItems = [];
+        if (nodes.length > 1) {
+            insertAdditionalItems = insertAdditionalItems.concat.apply(insertAdditionalItems, nodes.values.slice(1));
+            res.push(DomQuery.byId(replaced).insertAfter(new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], insertAdditionalItems)))()));
+        }
+        if (runEmbeddedScripts) {
+            this.runScripts();
+        }
+        if (runEmbeddedCss) {
+            this.runCss();
+        }
+        var focusElement = DomQuery.byId(focusElementId);
+        if (focusElementId && focusElement.isPresent() &&
+            caretPosition != null && "undefined" != typeof caretPosition) {
+            focusElement.eachElem(function (item) { return DomQuery.setCaretPosition(item, caretPosition); });
+        }
+        return nodes;
+    };
+    /**
+     * Run through the given nodes in the DomQuery execute the inline scripts
+     * @param whilteListed: optional whitelist function which can filter out script tags which are not processed
+     * defaults to the standard jsf.js exclusion (we use this code for myfaces)
+     */
+    DomQuery.prototype.runScripts = function (whilteListed) {
+        var _this = this;
+        if (whilteListed === void 0) { whilteListed = DEFAULT_JSF_WHITELIST; }
+        var finalScripts = [], equi = equalsIgnoreCase, execScrpt = function (item) {
+            var tagName = item.tagName;
+            var itemType = item.type || "";
+            if (tagName && equi(tagName, "script") &&
+                (itemType === "" || equi(itemType, "text/javascript") ||
+                    equi(itemType, "javascript") ||
+                    equi(itemType, "text/ecmascript") ||
+                    equi(itemType, "ecmascript"))) {
+                var src = item.getAttribute('src');
+                if ('undefined' != typeof src
+                    && null != src
+                    && src.length > 0) {
+                    //we have to move this into an inner if because chrome otherwise chokes
+                    //due to changing the and order instead of relying on left to right
+                    //if jsf.js is already registered we do not replace it anymore
+                    if (whilteListed(src)) {
+                        if (finalScripts.length) {
+                            //script source means we have to eval the existing
+                            //scripts before running the include
+                            _this.globalEval(finalScripts.join("\n"));
+                            finalScripts = [];
+                        }
+                        _this.loadScriptEval(src, 0, "UTF-8");
+                    }
+                }
+                else {
+                    // embedded script auto eval
+                    //TODO this probably needs to be changed due to our new parsing structures
+                    //probably not needed anymore
+                    var evalText = trim(item.text || item.innerText || item.innerHTML);
+                    var go = true;
+                    while (go) {
+                        go = false;
+                        if (evalText.substring(0, 4) == "<!--") {
+                            evalText = evalText.substring(4);
+                            go = true;
+                        }
+                        if (evalText.substring(0, 4) == "//<!--") {
+                            evalText = evalText.substring(6);
+                            go = true;
+                        }
+                        if (evalText.substring(0, 11) == "//<![CDATA[") {
+                            evalText = evalText.substring(11);
+                            go = true;
+                        }
+                    }
+                    // we have to run the script under a global context
+                    //we store the script for less calls to eval
+                    finalScripts.push(evalText);
+                }
+            }
+        };
+        try {
+            var scriptElements = new DomQuery(this.filterSelector("script"), this.querySelectorAll("script"));
+            //script execution order by relative pos in their dom tree
+            scriptElements.stream
+                .flatMap(function (item) {
+                return Stream_1.Stream.of(item.values);
+            })
+                .sort(function (node1, node2) {
+                return node1.compareDocumentPosition(node2) - 3; //preceding 2, following == 4
+            })
+                .each(function (item) { return execScrpt(item); });
+            if (finalScripts.length) {
+                this.globalEval(finalScripts.join("\n"));
+            }
+        }
+        catch (e) {
+            if (window.console && window.console.error) {
+                //not sure if we
+                //should use our standard
+                //error mechanisms here
+                //because in the head appendix
+                //method only a console
+                //error would be raised as well
+                console.error(e.message || e.description);
+            }
+        }
+        finally {
+            //the usual ie6 fix code
+            //the IE6 garbage collector is broken
+            //nulling closures helps somewhat to reduce
+            //mem leaks, which are impossible to avoid
+            //at this browser
+            execScrpt = null;
+        }
+        return this;
+    };
+    DomQuery.prototype.runCss = function () {
+        var applyStyle = function (item, style) {
+            var _a, _b, _c, _d, _e;
+            var newSS = document.createElement("style");
+            document.getElementsByTagName("head")[0].appendChild(newSS);
+            var styleSheet = (_a = newSS.sheet, (_a !== null && _a !== void 0 ? _a : newSS.styleSheet));
+            newSS.setAttribute("rel", (_b = item.getAttribute("rel"), (_b !== null && _b !== void 0 ? _b : "stylesheet")));
+            newSS.setAttribute("type", (_c = item.getAttribute("type"), (_c !== null && _c !== void 0 ? _c : "text/css")));
+            if (_e = (_d = styleSheet) === null || _d === void 0 ? void 0 : _d.cssText, (_e !== null && _e !== void 0 ? _e : false)) {
+                styleSheet.cssText = style;
+            }
+            else {
+                newSS.appendChild(document.createTextNode(style));
+            }
+        }, execCss = function (item) {
+            var tagName = item.tagName;
+            if (tagName && equalsIgnoreCase(tagName, "link") && equalsIgnoreCase(item.getAttribute("type"), "text/css")) {
+                applyStyle(item, "@import url('" + item.getAttribute("href") + "');");
+            }
+            else if (tagName && equalsIgnoreCase(tagName, "style") && equalsIgnoreCase(item.getAttribute("type"), "text/css")) {
+                var innerText = [];
+                //compliant browsers know child nodes
+                var childNodes = item.childNodes;
+                if (childNodes) {
+                    var len = childNodes.length;
+                    for (var cnt = 0; cnt < len; cnt++) {
+                        innerText.push(childNodes[cnt].innerHTML || childNodes[cnt].data);
+                    }
+                    //non compliant ones innerHTML
+                }
+                else if (item.innerHTML) {
+                    innerText.push(item.innerHTML);
+                }
+                applyStyle(item, innerText.join(""));
+            }
+        };
+        var scriptElements = new DomQuery(this.filterSelector("link, style"), this.querySelectorAll("link, style"));
+        scriptElements.stream
+            .flatMap(function (item) {
+            return Stream_1.Stream.of(item.values);
+        })
+            .sort(function (node1, node2) {
+            return node1.compareDocumentPosition(node2) - 3; //preceding 2, following == 4
+        })
+            .each(function (item) { return execCss(item); });
+        return this;
+    };
+    /**
+     * fires a click event on the underlying dom elements
+     */
+    DomQuery.prototype.click = function () {
+        this.fireEvent("click");
+        return this;
+    };
+    DomQuery.prototype.addEventListener = function (type, listener, options) {
+        this.eachElem(function (node) {
+            node.addEventListener(type, listener, options);
+        });
+        return this;
+    };
+    DomQuery.prototype.removeEventListener = function (type, listener, options) {
+        this.eachElem(function (node) {
+            node.removeEventListener(type, listener, options);
+        });
+        return this;
+    };
+    /**
+     * fires an event
+     */
+    DomQuery.prototype.fireEvent = function (eventName) {
+        this.eachElem(function (node) {
+            var doc;
+            if (node.ownerDocument) {
+                doc = node.ownerDocument;
+            }
+            else if (node.nodeType == 9) {
+                // the node may be the document itself, nodeType 9 = DOCUMENT_NODE
+                doc = node;
+            }
+            else {
+                throw new Error("Invalid node passed to fireEvent: " + node.id);
+            }
+            if (node.dispatchEvent) {
+                // Gecko-style approach (now the standard) takes more work
+                var eventClass = "";
+                // Different events have different event classes.
+                // If this switch statement can't map an eventName to an eventClass,
+                // the event firing is going to fail.
+                switch (eventName) {
+                    case "click": // Dispatching of 'click' appears to not work correctly in Safari. Use 'mousedown' or 'mouseup' instead.
+                    case "mousedown":
+                    case "mouseup":
+                        eventClass = "MouseEvents";
+                        break;
+                    case "focus":
+                    case "change":
+                    case "blur":
+                    case "select":
+                        eventClass = "HTMLEvents";
+                        break;
+                    default:
+                        throw "fireEvent: Couldn't find an event class for event '" + eventName + "'.";
+                        break;
+                }
+                var event_1 = doc.createEvent(eventClass);
+                event_1.initEvent(eventName, true, true); // All events created as bubbling and cancelable.
+                event_1.synthetic = true; // allow detection of synthetic events
+                // The second parameter says go ahead with the default action
+                node.dispatchEvent(event_1);
+            }
+            else if (node.fireEvent) {
+                // IE-old school style, you can drop this if you don't need to support IE8 and lower
+                var event_2 = doc.createEventObject();
+                event_2.synthetic = true; // allow detection of synthetic events
+                node.fireEvent("on" + eventName, event_2);
+            }
+        });
+    };
+    DomQuery.prototype.textContent = function (joinstr) {
+        if (joinstr === void 0) { joinstr = ""; }
+        return this.stream
+            .map(function (value) {
+            var item = value.getAsElem(0).orElseLazy(function () {
+                return {
+                    textContent: ""
+                };
+            }).value;
+            return item.textContent || "";
+        })
+            .reduce(function (text1, text2) { return text1 + joinstr + text2; }, "").value;
+    };
+    DomQuery.prototype.innerText = function (joinstr) {
+        if (joinstr === void 0) { joinstr = ""; }
+        return this.stream
+            .map(function (value) {
+            var item = value.getAsElem(0).orElseLazy(function () {
+                return {
+                    innerText: ""
+                };
+            }).value;
+            return item.innerText || "";
+        })
+            .reduce(function (text1, text2) { return [text1, text2].join(joinstr); }, "").value;
+    };
+    /**
+     * encodes all input elements properly into respective
+     * config entries, this can be used
+     * for legacy systems, for newer usecases, use the
+     * HTML5 Form class which all newer browsers provide
+     *
+     * @param toMerge optional config which can be merged in
+     * @return a copy pf
+     */
+    DomQuery.prototype.encodeFormElement = function (toMerge) {
+        if (toMerge === void 0) { toMerge = new Monad_1.Config({}); }
+        //browser behavior no element name no encoding (normal submit fails in that case)
+        //https://issues.apache.org/jira/browse/MYFACES-2847
+        if (this.name.isAbsent()) {
+            return;
+        }
+        //lets keep it sideffects free
+        var target = toMerge.shallowCopy;
+        this.each(function (element) {
+            if (element.name.isAbsent()) { //no name, no encoding
+                return;
+            }
+            var name = element.name.value;
+            var tagName = element.tagName.orElse("__none__").value.toLowerCase();
+            var elemType = element.type.orElse("__none__").value.toLowerCase();
+            elemType = elemType.toLowerCase();
+            // routine for all elements
+            // rules:
+            // - process only inputs, textareas and selects
+            // - elements muest have attribute "name"
+            // - elements must not be disabled
+            if (((tagName == "input" || tagName == "textarea" || tagName == "select") &&
+                (name != null && name != "")) && !element.disabled) {
+                // routine for select elements
+                // rules:
+                // - if select-one and value-Attribute exist => "name=value"
+                // (also if value empty => "name=")
+                // - if select-one and value-Attribute don't exist =>
+                // "name=DisplayValue"
+                // - if select multi and multple selected => "name=value1&name=value2"
+                // - if select and selectedIndex=-1 don't submit
+                if (tagName == "select") {
+                    // selectedIndex must be >= 0 sein to be submittet
+                    var selectElem = element.getAsElem(0).value;
+                    if (selectElem.selectedIndex >= 0) {
+                        var uLen = selectElem.options.length;
+                        for (var u = 0; u < uLen; u++) {
+                            // find all selected options
+                            //let subBuf = [];
+                            if (selectElem.options[u].selected) {
+                                var elementOption = selectElem.options[u];
+                                target.assign(name).value = (elementOption.getAttribute("value") != null) ?
+                                    elementOption.value : elementOption.text;
+                            }
+                        }
+                    }
+                }
+                // routine for remaining elements
+                // rules:
+                // - don't submit no selects (processed above), buttons, reset buttons, submit buttons,
+                // - submit checkboxes and radio inputs only if checked
+                if ((tagName != "select" && elemType != "button"
+                    && elemType != "reset" && elemType != "submit" && elemType != "image")
+                    && ((elemType != "checkbox" && elemType != "radio") || element.checked)) {
+                    var files = element.value.files;
+                    if (files && files.length) {
+                        //xhr level2
+                        target.assign(name).value = files[0];
+                    }
+                    else {
+                        target.assign(name).value = element.inputValue.value;
+                    }
+                }
+            }
+        });
+        return target;
+    };
+    Object.defineProperty(DomQuery.prototype, "cDATAAsString", {
+        get: function () {
+            var cDataBlock = [];
+            var TYPE_CDATA_BLOCK = 4;
+            // response may contain several blocks
+            return this.stream
+                .flatMap(function (item) { return item.childNodes.stream; }).reduce(function (reduced, item) {
+                var _a, _b, _c, _d, _e, _f, _g;
+                if (((_c = (_b = (_a = item) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.value) === null || _c === void 0 ? void 0 : _c.nodeType) == TYPE_CDATA_BLOCK) {
+                    reduced.push((_g = (_f = (_e = (_d = item) === null || _d === void 0 ? void 0 : _d.value) === null || _e === void 0 ? void 0 : _e.value) === null || _f === void 0 ? void 0 : _f.data, (_g !== null && _g !== void 0 ? _g : "")));
+                }
+                return reduced;
+            }, []).value.join("");
+        },
+        enumerable: true,
+        configurable: true
+    });
+    DomQuery.prototype.subNodes = function (from, to) {
+        if (Monad_1.Optional.fromNullable(to).isAbsent()) {
+            to = this.length;
+        }
+        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], this.rootNode.slice(from, Math.min(to, this.length)))))();
+    };
+    DomQuery.prototype.limits = function (end) {
+        this._limits = end;
+        return this;
+    };
+    //-- internally exposed methods needed for the interconnectivity
+    DomQuery.prototype.hasNext = function () {
+        var isLimitsReached = this._limits != -1 && this.pos >= this._limits - 1;
+        var isEndOfArray = this.pos >= this.values.length - 1;
+        return !(isLimitsReached ||
+            isEndOfArray);
+    };
+    DomQuery.prototype.next = function () {
+        if (!this.hasNext()) {
+            return null;
+        }
+        this.pos++;
+        return new DomQuery(this.values[this.pos]);
+    };
+    DomQuery.prototype.reset = function () {
+        this.pos = -1;
+    };
+    //from
+    // http://blog.vishalon.net/index.php/javascript-getting-and-setting-caret-position-in-textarea/
+    DomQuery.getCaretPosition = function (ctrl) {
+        var _a;
+        var caretPos = 0;
+        try {
+            if ((_a = document) === null || _a === void 0 ? void 0 : _a.selection) {
+                ctrl.focus();
+                var selection = document.selection.createRange();
+                //the selection now is start zero
+                selection.moveStart('character', -ctrl.value.length);
+                //the caretposition is the selection start
+                caretPos = selection.text.length;
+            }
+        }
+        catch (e) {
+            //now this is ugly, but not supported input types throw errors for selectionStart
+            //just in case someone dumps this code onto unsupported browsers
+        }
+        return caretPos;
+    };
+    DomQuery.setCaretPosition = function (ctrl, pos) {
+        ctrl.focus();
+        //the selection range is our caret position
+        ctrl.setSelectionRange(pos, pos);
+    };
+    DomQuery.absent = new DomQuery();
+    return DomQuery;
+}());
+exports.DomQuery = DomQuery;
+/**
+ * Various collectors
+ * which can be used in conjunction with Streams
+ */
+/**
+ * A collector which bundles a full dom query stream into a single dom query element
+ *
+ * This connects basically our stream back into DomQuery
+ */
+var DomQueryCollector = /** @class */ (function () {
+    function DomQueryCollector() {
+        this.data = [];
+    }
+    DomQueryCollector.prototype.collect = function (element) {
+        this.data.push(element);
+    };
+    Object.defineProperty(DomQueryCollector.prototype, "finalValue", {
+        get: function () {
+            return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], this.data)))();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    return DomQueryCollector;
+}());
+exports.DomQueryCollector = DomQueryCollector;
+/**
+ * abbreviation for DomQuery
+ */
+exports.DQ = DomQuery;
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/ext/monadish/Lang.ts":
+/*!**************************************************!*\
+  !*** ./src/main/typescript/ext/monadish/Lang.ts ***!
+  \**************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+var Monad_1 = __webpack_require__(/*! ./Monad */ "./src/main/typescript/ext/monadish/Monad.ts");
+/**
+ * Lang helpers crossported from the apache myfaces project
+ */
+var Lang;
+(function (Lang) {
+    //should be in lang, but for now here to avoid recursive imports, not sure if typescript still has a problem with those
+    /**
+     * helper function to savely resolve anything
+     * this is not an elvis operator, it resolves
+     * a value without exception in a tree and if
+     * it is not resolvable then an optional of
+     * a default value is restored or Optional.empty
+     * if none is given
+     *
+     * usage
+     * <code>
+     *     let var: Optiona<string> = saveResolve(() => a.b.c.d.e, "foobaz")
+     * </code>
+     *
+     * @param resolverProducer a lambda which can produce the value
+     * @param defaultValue an optional default value if the producer failes to produce anything
+     * @returns an Optional of the produced value
+     */
+    function saveResolve(resolverProducer, defaultValue) {
+        if (defaultValue === void 0) { defaultValue = null; }
+        try {
+            var result = resolverProducer();
+            return Monad_1.Optional.fromNullable((result !== null && result !== void 0 ? result : defaultValue));
+        }
+        catch (e) {
+            return Monad_1.Optional.absent;
+        }
+    }
+    Lang.saveResolve = saveResolve;
+    function saveResolveLazy(resolverProducer, defaultValue) {
+        if (defaultValue === void 0) { defaultValue = null; }
+        try {
+            var result = resolverProducer();
+            return Monad_1.Optional.fromNullable((result !== null && result !== void 0 ? result : defaultValue()));
+        }
+        catch (e) {
+            return Monad_1.Optional.absent;
+        }
+    }
+    Lang.saveResolveLazy = saveResolveLazy;
+    /**
+     * String to array function performs a string to array transformation
+     * @param {String} it the string which has to be changed into an array
+     * @param {RegExp} splitter our splitter reglar expression
+     * @return a trimmed array of the splitted string
+     */
+    function strToArray(it, splitter) {
+        if (splitter === void 0) { splitter = /\./gi; }
+        var ret = [];
+        it.split(splitter).forEach((function (element) {
+            ret.push(trim(element));
+        }));
+        return ret;
+    }
+    Lang.strToArray = strToArray;
+    /**
+     * hyperfast trim
+     * http://blog.stevenlevithan.com/archives/faster-trim-javascript
+     * crossported from dojo
+     */
+    function trim(str) {
+        str = str.replace(/^\s\s*/, '');
+        var ws = /\s/, i = str.length;
+        while (ws.test(str.charAt(--i))) {
+            //do nothing
+        }
+        return str.slice(0, i + 1);
+    }
+    Lang.trim = trim;
+    /**
+     * generic object arrays like dom definitions to array conversion method which
+     * transforms any object to something array like
+     * @param obj
+     * @param offset
+     * @param pack
+     * @returns an array converted from the object
+     */
+    function objToArray(obj, offset, pack) {
+        if (offset === void 0) { offset = 0; }
+        if (pack === void 0) { pack = []; }
+        if (((obj !== null && obj !== void 0 ? obj : "__undefined__")) == "__undefined__") {
+            return (pack !== null && pack !== void 0 ? pack : null);
+        }
+        //since offset is numeric we cannot use the shortcut due to 0 being false
+        //special condition array delivered no offset no pack
+        if (obj instanceof Array && !offset && !pack)
+            return obj;
+        return pack.concat(Array.prototype.slice.call(obj, offset));
+    }
+    Lang.objToArray = objToArray;
+    /**
+     * equalsIgnoreCase, case insensitive comparison of two strings
+     *
+     * @param source
+     * @param destination
+     */
+    function equalsIgnoreCase(source, destination) {
+        var finalSource = (source !== null && source !== void 0 ? source : "___no_value__");
+        var finalDest = (destination !== null && destination !== void 0 ? destination : "___no_value__");
+        //in any other case we do a strong string comparison
+        return finalSource.toLowerCase() === finalDest.toLowerCase();
+    }
+    Lang.equalsIgnoreCase = equalsIgnoreCase;
+    /**
+     * runtime type assertion
+     *
+     * @param probe the probe to be tested for a type
+     * @param theType the type to be tested for
+     */
+    function assertType(probe, theType) {
+        return isString(theType) ? typeof probe == theType : probe instanceof theType;
+    }
+    Lang.assertType = assertType;
+    /**
+     * Backported from dojo
+     * a failsafe string determination method
+     * (since in javascript String != "" typeof alone fails!)
+     * @param it {|Object|} the object to be checked for being a string
+     * @return true in case of being a string false otherwise
+     */
+    function isString(it) {
+        //	summary:
+        //		Return true if it is a String
+        return !!arguments.length && it != null && (typeof it == "string" || it instanceof String); // Boolean
+    }
+    Lang.isString = isString;
+    function isFunc(it) {
+        return it instanceof Function || typeof it === "function";
+    }
+    Lang.isFunc = isFunc;
+    // code from https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
+    // license https://creativecommons.org/licenses/by-sa/2.5/
+    function objAssign(target) {
+        var theArgs = [];
+        for (var _i = 1; _i < arguments.length; _i++) {
+            theArgs[_i - 1] = arguments[_i];
+        }
+        if (target == null) { // TypeError if undefined or null
+            throw new TypeError('Cannot convert undefined or null to object');
+        }
+        var to = Object(target);
+        if (Object.assign) {
+            theArgs.forEach(function (item) { return Object.assign(to, item); });
+            return to;
+        }
+        theArgs.forEach(function (item) {
+            var nextSource = item;
+            if (nextSource != null) { // Skip over if undefined or null
+                for (var nextKey in nextSource) {
+                    // Avoid bugs when hasOwnProperty is shadowed
+                    if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
+                        to[nextKey] = nextSource[nextKey];
+                    }
+                }
+            }
+        });
+        return to;
+    }
+    Lang.objAssign = objAssign;
+})(Lang = exports.Lang || (exports.Lang = {}));
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/ext/monadish/Monad.ts":
+/*!***************************************************!*\
+  !*** ./src/main/typescript/ext/monadish/Monad.ts ***!
+  \***************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+/**
+ * A module which keeps  basic monadish like definitions in place without any sidedependencies to other modules.
+ * Useful if you need the functions in another library to keep its dependencies down
+ */
+/*IMonad definitions*/
+var Lang_1 = __webpack_require__(/*! ./Lang */ "./src/main/typescript/ext/monadish/Lang.ts");
+var SourcesCollectors_1 = __webpack_require__(/*! ./SourcesCollectors */ "./src/main/typescript/ext/monadish/SourcesCollectors.ts");
+var Stream_1 = __webpack_require__(/*! ./Stream */ "./src/main/typescript/ext/monadish/Stream.ts");
+var objAssign = Lang_1.Lang.objAssign;
+/**
+ * Implementation of a monad
+ * (Sideffect free), no write allowed directly on the monads
+ * value state
+ */
+var Monad = /** @class */ (function () {
+    function Monad(value) {
+        this._value = value;
+    }
+    Object.defineProperty(Monad.prototype, "value", {
+        get: function () {
+            return this._value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Monad.prototype.map = function (fn) {
+        if (!fn) {
+            fn = function (inval) { return inval; };
+        }
+        var result = fn(this.value);
+        return new Monad(result);
+    };
+    Monad.prototype.flatMap = function (fn) {
+        var _a;
+        var mapped = this.map(fn);
+        while (((_a = mapped) === null || _a === void 0 ? void 0 : _a.value) instanceof Monad) {
+            mapped = mapped.value;
+        }
+        return mapped;
+    };
+    return Monad;
+}());
+exports.Monad = Monad;
+/**
+ * optional implementation, an optional is basically an implementation of a Monad with additional syntactic
+ * sugar on top
+ * (Sideeffect free, since value assignment is not allowed)
+ * */
+var Optional = /** @class */ (function (_super) {
+    __extends(Optional, _super);
+    function Optional(value) {
+        return _super.call(this, value) || this;
+    }
+    Object.defineProperty(Optional.prototype, "value", {
+        get: function () {
+            if (this._value instanceof Monad) {
+                return this._value.flatMap().value;
+            }
+            return this._value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Optional.fromNullable = function (value) {
+        return new Optional(value);
+    };
+    /*syntactic sugar for absent and present checks*/
+    Optional.prototype.isAbsent = function () {
+        return "undefined" == typeof this.value || null == this.value;
+    };
+    /**
+     * any value present
+     */
+    Optional.prototype.isPresent = function (presentRunnable) {
+        var absent = this.isAbsent();
+        if (!absent && presentRunnable) {
+            presentRunnable.call(this, this);
+        }
+        return !absent;
+    };
+    Optional.prototype.ifPresentLazy = function (presentRunnable) {
+        if (presentRunnable === void 0) { presentRunnable = function () {
+        }; }
+        this.isPresent.call(this, presentRunnable);
+        return this;
+    };
+    Optional.prototype.orElse = function (elseValue) {
+        if (this.isPresent()) {
+            return this;
+        }
+        else {
+            //shortcut
+            if (elseValue == null) {
+                return Optional.absent;
+            }
+            return this.flatMap(function () { return elseValue; });
+        }
+    };
+    /**
+     * lazy, passes a function which then is lazily evaluated
+     * instead of a direct value
+     * @param func
+     */
+    Optional.prototype.orElseLazy = function (func) {
+        if (this.isPresent()) {
+            return this;
+        }
+        else {
+            return this.flatMap(func);
+        }
+    };
+    /*
+     * we need to implement it to fullfill the contract, although it is used only internally
+     * all values are flattened when accessed anyway, so there is no need to call this methiod
+     */
+    Optional.prototype.flatMap = function (fn) {
+        var val = _super.prototype.flatMap.call(this, fn);
+        if (!(val instanceof Optional)) {
+            return Optional.fromNullable(val.value);
+        }
+        return val.flatMap();
+    };
+    /*
+     * elvis operation, take care, if you use this you lose typesafety and refactoring
+     * capabilites, unfortunately typesceript does not allow to have its own elvis operator
+     * this is some syntactic sugar however which is quite useful*/
+    Optional.prototype.getIf = function () {
+        var key = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            key[_i] = arguments[_i];
+        }
+        var currentPos = this;
+        for (var cnt = 0; cnt < key.length; cnt++) {
+            var currKey = this.keyVal(key[cnt]);
+            var arrPos = this.arrayIndex(key[cnt]);
+            if (currKey === "" && arrPos >= 0) {
+                currentPos = this.getClass().fromNullable(!(currentPos.value instanceof Array) ? null : (currentPos.value.length < arrPos ? null : currentPos.value[arrPos]));
+                if (currentPos.isAbsent()) {
+                    return currentPos;
+                }
+                continue;
+            }
+            else if (currKey && arrPos >= 0) {
+                if (currentPos.getIfPresent(currKey).isAbsent()) {
+                    return currentPos;
+                }
+                currentPos = (currentPos.getIfPresent(currKey).value instanceof Array) ? this.getClass().fromNullable(currentPos.getIfPresent(currKey).value[arrPos]) : this.getClass().absent;
+                if (currentPos.isAbsent()) {
+                    return currentPos;
+                }
+                continue;
+            }
+            else {
+                currentPos = currentPos.getIfPresent(currKey);
+            }
+            if (currentPos.isAbsent()) {
+                return currentPos;
+            }
+            else if (arrPos > -1) {
+                currentPos = this.getClass().fromNullable(currentPos.value[arrPos]);
+            }
+        }
+        var retVal = currentPos;
+        return retVal;
+    };
+    /**
+     * simple match, if the first order function call returns
+     * true then there is a match, if the value is not present
+     * it never matches
+     *
+     * @param fn the first order function performing the match
+     */
+    Optional.prototype.match = function (fn) {
+        if (this.isAbsent()) {
+            return false;
+        }
+        return fn(this.value);
+    };
+    /**
+     * convenience function to flatmap the internal value
+     * and replace it with a default in case of being absent
+     *
+     * @param defaultVal
+     * @returns {Optional<any>}
+     */
+    Optional.prototype.get = function (defaultVal) {
+        if (defaultVal === void 0) { defaultVal = Optional.absent; }
+        if (this.isAbsent()) {
+            return this.getClass().fromNullable(defaultVal).flatMap();
+        }
+        return this.getClass().fromNullable(this.value).flatMap();
+    };
+    Optional.prototype.toJson = function () {
+        return JSON.stringify(this.value);
+    };
+    /**
+     * helper to override several implementations in a more fluent way
+     * by having a getClass operation we can avoid direct calls into the constructor or
+     * static methods and do not have to implement several methods which rely on the type
+     * of "this"
+     * @returns {Monadish.Optional}
+     */
+    Optional.prototype.getClass = function () {
+        return Optional;
+    };
+    /*helper method for getIf with array access aka <name>[<indexPos>]*/
+    Optional.prototype.arrayIndex = function (key) {
+        var start = key.indexOf("[");
+        var end = key.indexOf("]");
+        if (start >= 0 && end > 0 && start < end) {
+            return parseInt(key.substring(start + 1, end));
+        }
+        else {
+            return -1;
+        }
+    };
+    /*helper method for getIf with array access aka <name>[<indexPos>]*/
+    Optional.prototype.keyVal = function (key) {
+        var start = key.indexOf("[");
+        if (start >= 0) {
+            return key.substring(0, start);
+        }
+        else {
+            return key;
+        }
+    };
+    /**
+     * additional syntactic sugar which is not part of the usual optional implementation
+     * but makes life easier, if you want to sacrifice typesafety and refactoring
+     * capabilities in typescript
+     */
+    Optional.prototype.getIfPresent = function (key) {
+        if (this.isAbsent()) {
+            return this.getClass().absent;
+        }
+        return this.getClass().fromNullable(this.value[key]).flatMap();
+    };
+    /**
+     * elvis like typesafe functional save resolver
+     * a typesafe option for getIfPresent
+     *
+     * usage myOptional.resolve(value => value.subAttr.subAttr2).orElseLazy(....)
+     * if this is resolvable without any errors an Optional with the value is returned
+     * if not, then an Optional absent is returned, also if you return Optional absent
+     * it is flatmapped into absent
+     *
+     * @param resolver the resolver function, can throw any arbitrary errors, int  the error case
+     * the resolution goes towards absent
+     */
+    Optional.prototype.resolve = function (resolver) {
+        if (this.isAbsent()) {
+            return Optional.absent;
+        }
+        try {
+            return Optional.fromNullable(resolver(this.value));
+        }
+        catch (e) {
+            return Optional.absent;
+        }
+    };
+    /*default value for absent*/
+    Optional.absent = Optional.fromNullable(null);
+    return Optional;
+}(Monad));
+exports.Optional = Optional;
+// --------------------- From here onwards we break out the sideffects free limits ------------
+/**
+ * ValueEmbedder is the writeable version
+ * of optional, it basically is a wrappber
+ * around a construct which has a state
+ * and can be written to.
+ *
+ * For the readonly version see Optional
+ */
+var ValueEmbedder = /** @class */ (function (_super) {
+    __extends(ValueEmbedder, _super);
+    function ValueEmbedder(rootElem, valueKey) {
+        if (valueKey === void 0) { valueKey = "value"; }
+        var _this = _super.call(this, rootElem) || this;
+        _this.key = valueKey;
+        return _this;
+    }
+    Object.defineProperty(ValueEmbedder.prototype, "value", {
+        get: function () {
+            return this._value ? this._value[this.key] : null;
+        },
+        set: function (newVal) {
+            if (!this._value) {
+                return;
+            }
+            this._value[this.key] = newVal;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    ValueEmbedder.prototype.orElse = function (elseValue) {
+        var alternative = {};
+        alternative[this.key] = elseValue;
+        return this.isPresent() ? this : new ValueEmbedder(alternative, this.key);
+    };
+    ValueEmbedder.prototype.orElseLazy = function (func) {
+        if (this.isPresent()) {
+            return this;
+        }
+        else {
+            var alternative = {};
+            alternative[this.key] = func();
+            return new ValueEmbedder(alternative, this.key);
+        }
+    };
+    /**
+     * helper to override several implementations in a more fluent way
+     * by having a getClass operation we can avoid direct calls into the constructor or
+     * static methods and do not have to implement several methods which rely on the type
+     * of "this"
+     * @returns {Monadish.Optional}
+     */
+    ValueEmbedder.prototype.getClass = function () {
+        return ValueEmbedder;
+    };
+    ValueEmbedder.fromNullable = function (value, valueKey) {
+        if (valueKey === void 0) { valueKey = "value"; }
+        return new ValueEmbedder(value, valueKey);
+    };
+    /*default value for absent*/
+    ValueEmbedder.absent = ValueEmbedder.fromNullable(null);
+    return ValueEmbedder;
+}(Optional));
+exports.ValueEmbedder = ValueEmbedder;
+/**
+ * specialized value embedder
+ * for our Configuration
+ */
+var ConfigEntry = /** @class */ (function (_super) {
+    __extends(ConfigEntry, _super);
+    function ConfigEntry(rootElem, key, arrPos) {
+        var _this = _super.call(this, rootElem, key) || this;
+        _this.arrPos = (arrPos !== null && arrPos !== void 0 ? arrPos : -1);
+        return _this;
+    }
+    Object.defineProperty(ConfigEntry.prototype, "value", {
+        get: function () {
+            if (this.key == "" && this.arrPos >= 0) {
+                return this._value[this.arrPos];
+            }
+            else if (this.key && this.arrPos >= 0) {
+                return this._value[this.key][this.arrPos];
+            }
+            return this._value[this.key];
+        },
+        set: function (val) {
+            if (this.key == "" && this.arrPos >= 0) {
+                this._value[this.arrPos] = val;
+                return;
+            }
+            else if (this.key && this.arrPos >= 0) {
+                this._value[this.key][this.arrPos] = val;
+                return;
+            }
+            this._value[this.key] = val;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    /*default value for absent*/
+    ConfigEntry.absent = ConfigEntry.fromNullable(null);
+    return ConfigEntry;
+}(ValueEmbedder));
+/**
+ * Config, basically an optional wrapper for a json structure
+ * (not sideeffect free, since we can alter the internal config state
+ * without generating a new config), not sure if we should make it sideffect free
+ * since this would swallow a lot of performane and ram
+ */
+var Config = /** @class */ (function (_super) {
+    __extends(Config, _super);
+    function Config(root) {
+        return _super.call(this, root) || this;
+    }
+    Object.defineProperty(Config.prototype, "shallowCopy", {
+        get: function () {
+            return new Config(Stream_1.Stream.ofAssoc(this.value).collect(new SourcesCollectors_1.AssocArrayCollector()));
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Config.prototype, "deepCopy", {
+        get: function () {
+            return new Config(objAssign({}, this.value));
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Config.fromNullable = function (value) {
+        return new Config(value);
+    };
+    /**
+     * simple merge for the root configs
+     */
+    Config.prototype.shallowMerge = function (other, overwrite) {
+        if (overwrite === void 0) { overwrite = true; }
+        for (var key in other.value) {
+            if (overwrite || !(key in this.value)) {
+                this.assign(key).value = other.getIf(key).value;
+            }
+        }
+    };
+    Config.prototype.assign = function () {
+        var keys = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            keys[_i] = arguments[_i];
+        }
+        if (keys.length < 1) {
+            return;
+        }
+        this.buildPath(keys);
+        var currKey = this.keyVal(keys[keys.length - 1]);
+        var arrPos = this.arrayIndex(keys[keys.length - 1]);
+        var retVal = new ConfigEntry(keys.length == 1 ? this.value : this.getIf.apply(this, keys.slice(0, keys.length - 1)).value, currKey, arrPos);
+        return retVal;
+    };
+    Config.prototype.assignIf = function (condition) {
+        var keys = [];
+        for (var _i = 1; _i < arguments.length; _i++) {
+            keys[_i - 1] = arguments[_i];
+        }
+        return condition ? this.assign.apply(this, keys) : { value: null };
+    };
+    Config.prototype.getIf = function () {
+        var keys = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            keys[_i] = arguments[_i];
+        }
+        return this.getClass().fromNullable(_super.prototype.getIf.apply(this, keys).value);
+    };
+    Config.prototype.get = function (defaultVal) {
+        return this.getClass().fromNullable(_super.prototype.get.call(this, defaultVal).value);
+    };
+    //empties the current config entry
+    Config.prototype.delete = function (key) {
+        if (key in this.value) {
+            delete this.value[key];
+        }
+        return this;
+    };
+    Config.prototype.toJson = function () {
+        return JSON.stringify(this.value);
+    };
+    Config.prototype.getClass = function () {
+        return Config;
+    };
+    Config.prototype.setVal = function (val) {
+        this._value = val;
+    };
+    Config.prototype.buildPath = function (keys) {
+        var val = this;
+        var parentVal = this.getClass().fromNullable(null);
+        var parentPos = -1;
+        var alloc = function (arr, length) {
+            var length1 = arr.length;
+            var length2 = length1 + length;
+            for (var cnt = length1; cnt < length2; cnt++) {
+                arr.push({});
+            }
+        };
+        for (var cnt = 0; cnt < keys.length; cnt++) {
+            var currKey = this.keyVal(keys[cnt]);
+            var arrPos = this.arrayIndex(keys[cnt]);
+            if (currKey === "" && arrPos >= 0) {
+                val.setVal((val.value instanceof Array) ? val.value : []);
+                alloc(val.value, arrPos + 1);
+                if (parentPos >= 0) {
+                    parentVal.value[parentPos] = val.value;
+                }
+                parentVal = val;
+                parentPos = arrPos;
+                val = this.getClass().fromNullable(val.value[arrPos]);
+                continue;
+            }
+            var tempVal = val.getIf(currKey);
+            if (arrPos == -1) {
+                if (tempVal.isAbsent()) {
+                    tempVal = this.getClass().fromNullable(val.value[currKey] = {});
+                }
+                else {
+                    val = tempVal;
+                }
+            }
+            else {
+                var arr = (tempVal.value instanceof Array) ? tempVal.value : [];
+                alloc(arr, arrPos + 1);
+                val.value[currKey] = arr;
+                tempVal = this.getClass().fromNullable(arr[arrPos]);
+            }
+            parentVal = val;
+            parentPos = arrPos;
+            val = tempVal;
+        }
+        return this;
+    };
+    return Config;
+}(Optional));
+exports.Config = Config;
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/ext/monadish/SourcesCollectors.ts":
+/*!***************************************************************!*\
+  !*** ./src/main/typescript/ext/monadish/SourcesCollectors.ts ***!
+  \***************************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var __spreadArrays = (this && this.__spreadArrays) || function () {
+    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
+    for (var r = Array(s), k = 0, i = 0; i < il; i++)
+        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
+            r[k] = a[j];
+    return r;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var Stream_1 = __webpack_require__(/*! ./Stream */ "./src/main/typescript/ext/monadish/Stream.ts");
+/**
+ * implementation of iteratable on top of array
+ */
+var ArrayStreamDataSource = /** @class */ (function () {
+    function ArrayStreamDataSource() {
+        var value = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            value[_i] = arguments[_i];
+        }
+        this.dataPos = -1;
+        this.value = value;
+    }
+    ArrayStreamDataSource.prototype.hasNext = function () {
+        return this.value.length - 1 > this.dataPos;
+    };
+    ArrayStreamDataSource.prototype.next = function () {
+        this.dataPos++;
+        return this.value[this.dataPos];
+    };
+    ArrayStreamDataSource.prototype.reset = function () {
+        this.dataPos = -1;
+    };
+    return ArrayStreamDataSource;
+}());
+exports.ArrayStreamDataSource = ArrayStreamDataSource;
+/**
+ * an intermediate data source wich prefilters
+ * incoming stream data
+ * and lets only the data out which
+ * passes the filter function check
+ */
+var FilteredStreamDatasource = /** @class */ (function () {
+    function FilteredStreamDatasource(filterFunc, parent) {
+        this.filteredNext = null;
+        this.filterFunc = filterFunc;
+        this.inputDataSource = parent;
+    }
+    /**
+     * in order to filter we have to make a look ahead until the
+     * first next allowed element
+     * hence we prefetch the element and then
+     * serve it via next
+     */
+    FilteredStreamDatasource.prototype.hasNext = function () {
+        while (this.filteredNext == null && this.inputDataSource.hasNext()) {
+            var next = this.inputDataSource.next();
+            if (this.filterFunc(next)) {
+                this.filteredNext = next;
+                return true;
+            }
+            else {
+                this.filteredNext = null;
+            }
+        }
+        return this.filteredNext != null;
+    };
+    /**
+     * serve the next element
+     */
+    FilteredStreamDatasource.prototype.next = function () {
+        var ret = this.filteredNext;
+        this.filteredNext = null;
+        //We have to call hasNext, to roll another
+        //prefetch in case someone runs next
+        //sequentially without calling hasNext
+        this.hasNext();
+        return ret;
+    };
+    FilteredStreamDatasource.prototype.reset = function () {
+        this.filteredNext = null;
+        this.inputDataSource.reset();
+    };
+    return FilteredStreamDatasource;
+}());
+exports.FilteredStreamDatasource = FilteredStreamDatasource;
+/**
+ * an intermediate datasource which maps the items from
+ * one into another
+ */
+var MappedStreamDataSource = /** @class */ (function () {
+    function MappedStreamDataSource(mapFunc, parent) {
+        this.mapFunc = mapFunc;
+        this.inputDataSource = parent;
+    }
+    MappedStreamDataSource.prototype.hasNext = function () {
+        return this.inputDataSource.hasNext();
+    };
+    MappedStreamDataSource.prototype.next = function () {
+        return this.mapFunc(this.inputDataSource.next());
+    };
+    MappedStreamDataSource.prototype.reset = function () {
+        this.inputDataSource.reset();
+    };
+    return MappedStreamDataSource;
+}());
+exports.MappedStreamDataSource = MappedStreamDataSource;
+/**
+ * Same for flatmap to deal with element -> stream mappings
+ */
+var FlatMapStreamDataSource = /** @class */ (function () {
+    function FlatMapStreamDataSource(func, parent) {
+        this.mapFunc = func;
+        this.inputDataSource = parent;
+    }
+    FlatMapStreamDataSource.prototype.hasNext = function () {
+        return this.resolveCurrentNext() || this.resolveNextNext();
+    };
+    FlatMapStreamDataSource.prototype.resolveCurrentNext = function () {
+        var next = false;
+        if (this.activeDataSource) {
+            next = this.activeDataSource.hasNext();
+        }
+        return next;
+    };
+    FlatMapStreamDataSource.prototype.resolveNextNext = function () {
+        var next = false;
+        while (!next && this.inputDataSource.hasNext()) {
+            var mapped = this.mapFunc(this.inputDataSource.next());
+            if (Array.isArray(mapped)) {
+                this.activeDataSource = new (ArrayStreamDataSource.bind.apply(ArrayStreamDataSource, __spreadArrays([void 0], mapped)))();
+            }
+            else {
+                this.activeDataSource = mapped;
+            }
+            next = this.activeDataSource.hasNext();
+        }
+        return next;
+    };
+    FlatMapStreamDataSource.prototype.next = function () {
+        return this.activeDataSource.next();
+    };
+    FlatMapStreamDataSource.prototype.reset = function () {
+        this.inputDataSource.reset();
+    };
+    return FlatMapStreamDataSource;
+}());
+exports.FlatMapStreamDataSource = FlatMapStreamDataSource;
+/**
+ * For the time being we only need one collector
+ * a collector which collects a stream back into arrays
+ */
+var ArrayCollector = /** @class */ (function () {
+    function ArrayCollector() {
+        this.data = [];
+    }
+    ArrayCollector.prototype.collect = function (element) {
+        this.data.push(element);
+    };
+    Object.defineProperty(ArrayCollector.prototype, "finalValue", {
+        get: function () {
+            return this.data;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    return ArrayCollector;
+}());
+exports.ArrayCollector = ArrayCollector;
+/**
+ * collects an assoc stream back to an assoc array
+ */
+var AssocArrayCollector = /** @class */ (function () {
+    function AssocArrayCollector() {
+        this.finalValue = {};
+    }
+    AssocArrayCollector.prototype.collect = function (element) {
+        var _a, _b;
+        this.finalValue[_a = element[0], (_a !== null && _a !== void 0 ? _a : element)] = (_b = element[1], (_b !== null && _b !== void 0 ? _b : true));
+    };
+    return AssocArrayCollector;
+}());
+exports.AssocArrayCollector = AssocArrayCollector;
+/**
+ * Form data collector for key value pair streams
+ */
+var FormDataCollector = /** @class */ (function () {
+    function FormDataCollector() {
+        this.finalValue = new FormData();
+    }
+    FormDataCollector.prototype.collect = function (element) {
+        this.finalValue.append(element.key, element.value);
+    };
+    return FormDataCollector;
+}());
+exports.FormDataCollector = FormDataCollector;
+/**
+ * Form data collector for DomQuery streams
+ */
+var QueryFormDataCollector = /** @class */ (function () {
+    function QueryFormDataCollector() {
+        this.finalValue = new FormData();
+    }
+    QueryFormDataCollector.prototype.collect = function (element) {
+        var toMerge = element.encodeFormElement();
+        if (toMerge.isPresent()) {
+            this.finalValue.append(element.name.value, toMerge.get(element.name).value);
+        }
+    };
+    return QueryFormDataCollector;
+}());
+exports.QueryFormDataCollector = QueryFormDataCollector;
+/**
+ * Encoded String collector from dom query streams
+ */
+var QueryFormStringCollector = /** @class */ (function () {
+    function QueryFormStringCollector() {
+        this.formData = [];
+    }
+    QueryFormStringCollector.prototype.collect = function (element) {
+        var toMerge = element.encodeFormElement();
+        if (toMerge.isPresent()) {
+            this.formData.push([element.name.value, toMerge.get(element.name).value]);
+        }
+    };
+    Object.defineProperty(QueryFormStringCollector.prototype, "finalValue", {
+        get: function () {
+            return Stream_1.Stream.of.apply(Stream_1.Stream, this.formData).map(function (keyVal) { return keyVal.join("="); })
+                .reduce(function (item1, item2) { return [item1, item2].join("&"); })
+                .orElse("").value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    return QueryFormStringCollector;
+}());
+exports.QueryFormStringCollector = QueryFormStringCollector;
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/ext/monadish/Stream.ts":
+/*!****************************************************!*\
+  !*** ./src/main/typescript/ext/monadish/Stream.ts ***!
+  \****************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var __spreadArrays = (this && this.__spreadArrays) || function () {
+    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
+    for (var r = Array(s), k = 0, i = 0; i < il; i++)
+        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
+            r[k] = a[j];
+    return r;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+/*
+ * A small stream implementation
+ */
+var Monad_1 = __webpack_require__(/*! ./Monad */ "./src/main/typescript/ext/monadish/Monad.ts");
+var SourcesCollectors_1 = __webpack_require__(/*! ./SourcesCollectors */ "./src/main/typescript/ext/monadish/SourcesCollectors.ts");
+/**
+ * A simple typescript based reimplementation of streams
+ *
+ * This is the early eval version
+ * for a lazy eval version check, LazyStream, which is api compatible
+ * to this implementation, however with the benefit of being able
+ * to provide infinite data sources and generic data providers, the downside
+ * is, it might be a tad slower in some situations
+ */
+var Stream = /** @class */ (function () {
+    function Stream() {
+        var value = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            value[_i] = arguments[_i];
+        }
+        this._limits = -1;
+        this.pos = -1;
+        this.value = value;
+    }
+    Stream.of = function () {
+        var data = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            data[_i] = arguments[_i];
+        }
+        return new (Stream.bind.apply(Stream, __spreadArrays([void 0], data)))();
+    };
+    Stream.ofAssoc = function (data) {
+        return this.of.apply(this, Object.keys(data)).map(function (key) { return [key, data[key]]; });
+    };
+    Stream.ofDataSource = function (dataSource) {
+        var value = [];
+        while (dataSource.hasNext()) {
+            value.push(dataSource.next());
+        }
+        return new (Stream.bind.apply(Stream, __spreadArrays([void 0], value)))();
+    };
+    Stream.prototype.limits = function (end) {
+        this._limits = end;
+        return this;
+    };
+    Stream.prototype.onElem = function (fn) {
+        for (var cnt = 0; cnt < this.value.length && (this._limits == -1 || cnt < this._limits); cnt++) {
+            if (fn(this.value[cnt], cnt) === false) {
+                break;
+            }
+        }
+        return this;
+    };
+    Stream.prototype.each = function (fn) {
+        this.onElem(fn);
+    };
+    Stream.prototype.map = function (fn) {
+        if (!fn) {
+            fn = function (inval) { return inval; };
+        }
+        var res = [];
+        this.each(function (item, cnt) {
+            res.push(fn(item));
+        });
+        return new (Stream.bind.apply(Stream, __spreadArrays([void 0], res)))();
+    };
+    /*
+     * we need to implement it to fullfill the contract, although it is used only internally
+     * all values are flattened when accessed anyway, so there is no need to call this methiod
+     */
+    Stream.prototype.flatMap = function (fn) {
+        var ret = [];
+        this.each(function (item) {
+            var strmR = fn(item);
+            ret = Array.isArray(strmR) ? ret.concat(strmR) : ret.concat.apply(ret, strmR.value);
+        });
+        return Stream.of.apply(Stream, ret);
+    };
+    Stream.prototype.filter = function (fn) {
+        var res = [];
+        this.each(function (data) {
+            if (fn(data)) {
+                res.push(data);
+            }
+        });
+        return new (Stream.bind.apply(Stream, __spreadArrays([void 0], res)))();
+    };
+    Stream.prototype.reduce = function (fn, startVal) {
+        if (startVal === void 0) { startVal = null; }
+        var offset = startVal != null ? 0 : 1;
+        var val1 = startVal != null ? startVal : this.value.length ? this.value[0] : null;
+        for (var cnt = offset; cnt < this.value.length && (this._limits == -1 || cnt < this._limits); cnt++) {
+            val1 = fn(val1, this.value[cnt]);
+        }
+        return Monad_1.Optional.fromNullable(val1);
+    };
+    Stream.prototype.first = function () {
+        return this.value && this.value.length ? Monad_1.Optional.fromNullable(this.value[0]) : Monad_1.Optional.absent;
+    };
+    Stream.prototype.last = function () {
+        //could be done via reduce, but is faster this way
+        var length = this._limits > 0 ? Math.min(this._limits, this.value.length) : this.value.length;
+        return Monad_1.Optional.fromNullable(length ? this.value[length - 1] : null);
+    };
+    Stream.prototype.anyMatch = function (fn) {
+        for (var cnt = 0; cnt < this.value.length && (this._limits == -1 || cnt < this._limits); cnt++) {
+            if (fn(this.value[cnt])) {
+                return true;
+            }
+        }
+        return false;
+    };
+    Stream.prototype.allMatch = function (fn) {
+        if (!this.value.length) {
+            return false;
+        }
+        var matches = 0;
+        for (var cnt = 0; cnt < this.value.length; cnt++) {
+            if (fn(this.value[cnt])) {
+                matches++;
+            }
+        }
+        return matches == this.value.length;
+    };
+    Stream.prototype.noneMatch = function (fn) {
+        var matches = 0;
+        for (var cnt = 0; cnt < this.value.length; cnt++) {
+            if (!fn(this.value[cnt])) {
+                matches++;
+            }
+        }
+        return matches == this.value.length;
+    };
+    Stream.prototype.sort = function (comparator) {
+        var newArr = this.value.slice().sort(comparator);
+        return Stream.of.apply(Stream, newArr);
+    };
+    Stream.prototype.collect = function (collector) {
+        this.each(function (data) { return collector.collect(data); });
+        return collector.finalValue;
+    };
+    //-- internally exposed methods needed for the interconnectivity
+    Stream.prototype.hasNext = function () {
+        var isLimitsReached = this._limits != -1 && this.pos >= this._limits - 1;
+        var isEndOfArray = this.pos >= this.value.length - 1;
+        return !(isLimitsReached || isEndOfArray);
+    };
+    Stream.prototype.next = function () {
+        if (!this.hasNext()) {
+            return null;
+        }
+        this.pos++;
+        return this.value[this.pos];
+    };
+    Stream.prototype.reset = function () {
+        this.pos = -1;
+    };
+    return Stream;
+}());
+exports.Stream = Stream;
+/**
+ * Lazy implementation of a Stream
+ * The idea is to connect the intermediate
+ * streams as datasources like a linked list
+ * with reverse referencing and for special
+ * operations like filtering flatmapping
+ * have intermediate datasources in the list
+ * with specialized functions.
+ *
+ * Sort of a modified pipe valve pattern
+ * the streams are the pipes the intermediate
+ * data sources are the valves
+ *
+ * We then can use passed in functions to control
+ * the flow in the valves
+ *
+ * That way we can have a lazy evaluating stream
+ *
+ * So if an endpoint requests data
+ * a callback trace goes back the stream list
+ * which triggers an operation upwards
+ * which sends data down the drain which then is processed
+ * and filtered until one element hits the endpoint.
+ *
+ * That is repeated, until all elements are processed
+ * or an internal limit is hit.
+ *
+ */
+var LazyStream = /** @class */ (function () {
+    function LazyStream(parent) {
+        this._limits = -1;
+        /*
+         * needed to have the limits check working
+         * we need to keep track of the current position
+         * in the stream
+         */
+        this.pos = -1;
+        this.dataSource = parent;
+    }
+    LazyStream.of = function () {
+        var values = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            values[_i] = arguments[_i];
+        }
+        return new LazyStream(new (SourcesCollectors_1.ArrayStreamDataSource.bind.apply(SourcesCollectors_1.ArrayStreamDataSource, __spreadArrays([void 0], values)))());
+    };
+    LazyStream.ofAssoc = function (data) {
+        return this.of.apply(this, Object.keys(data)).map(function (key) { return [key, data[key]]; });
+    };
+    LazyStream.ofStreamDataSource = function (value) {
+        return new LazyStream(value);
+    };
+    LazyStream.prototype.hasNext = function () {
+        if (this.isOverLimits()) {
+            return false;
+        }
+        return this.dataSource.hasNext();
+    };
+    LazyStream.prototype.next = function () {
+        var next = this.dataSource.next();
+        // @ts-ignore
+        this.pos++;
+        return next;
+    };
+    LazyStream.prototype.reset = function () {
+        this.dataSource.reset();
+        this.pos = 0;
+        this._limits = -1;
+    };
+    LazyStream.prototype.nextFilter = function (fn) {
+        if (this.hasNext()) {
+            var newVal = this.next();
+            if (!fn(newVal)) {
+                return this.nextFilter(fn);
+            }
+            return newVal;
+        }
+        return null;
+    };
+    LazyStream.prototype.limits = function (max) {
+        this._limits = max;
+        return this;
+    };
+    //main stream methods
+    LazyStream.prototype.collect = function (collector) {
+        while (this.hasNext()) {
+            var t = this.next();
+            collector.collect(t);
+        }
+        return collector.finalValue;
+    };
+    LazyStream.prototype.onElem = function (fn) {
+        var _this = this;
+        return new LazyStream(new SourcesCollectors_1.MappedStreamDataSource(function (el) {
+            if (fn(el, _this.pos) === false) {
+                _this.stop();
+            }
+            return el;
+        }, this));
+    };
+    LazyStream.prototype.filter = function (fn) {
+        return new LazyStream(new SourcesCollectors_1.FilteredStreamDatasource(fn, this));
+    };
+    LazyStream.prototype.map = function (fn) {
+        return new LazyStream(new SourcesCollectors_1.MappedStreamDataSource(fn, this));
+    };
+    LazyStream.prototype.flatMap = function (fn) {
+        return new LazyStream(new SourcesCollectors_1.FlatMapStreamDataSource(fn, this));
+    };
+    //endpoint
+    LazyStream.prototype.each = function (fn) {
+        while (this.hasNext()) {
+            if (fn(this.next()) === false) {
+                this.stop();
+            }
+        }
+    };
+    LazyStream.prototype.reduce = function (fn, startVal) {
+        if (startVal === void 0) { startVal = null; }
+        if (!this.hasNext()) {
+            return Monad_1.Optional.absent;
+        }
+        var value1 = null;
+        var value2 = null;
+        if (startVal != null) {
+            value1 = startVal;
+            value2 = this.next();
+        }
+        else {
+            value1 = this.next();
+            if (!this.hasNext()) {
+                return Monad_1.Optional.fromNullable(value1);
+            }
+            value2 = this.next();
+        }
+        value1 = fn(value1, value2);
+        while (this.hasNext()) {
+            value2 = this.next();
+            value1 = fn(value1, value2);
+        }
+        return Monad_1.Optional.fromNullable(value1);
+    };
+    LazyStream.prototype.last = function () {
+        if (!this.hasNext()) {
+            return Monad_1.Optional.absent;
+        }
+        return this.reduce(function (el1, el2) { return el2; });
+    };
+    LazyStream.prototype.first = function () {
+        this.reset();
+        if (!this.hasNext()) {
+            return Monad_1.Optional.absent;
+        }
+        return Monad_1.Optional.fromNullable(this.next());
+    };
+    LazyStream.prototype.anyMatch = function (fn) {
+        while (this.hasNext()) {
+            if (fn(this.next())) {
+                return true;
+            }
+        }
+        return false;
+    };
+    LazyStream.prototype.allMatch = function (fn) {
+        while (this.hasNext()) {
+            if (!fn(this.next())) {
+                return false;
+            }
+        }
+        return true;
+    };
+    LazyStream.prototype.noneMatch = function (fn) {
+        while (this.hasNext()) {
+            if (fn(this.next())) {
+                return false;
+            }
+        }
+        return true;
+    };
+    LazyStream.prototype.sort = function (comparator) {
+        var arr = this.collect(new SourcesCollectors_1.ArrayCollector());
+        arr = arr.sort(comparator);
+        return LazyStream.of.apply(LazyStream, arr);
+    };
+    Object.defineProperty(LazyStream.prototype, "value", {
+        get: function () {
+            return this.collect(new SourcesCollectors_1.ArrayCollector());
+        },
+        enumerable: true,
+        configurable: true
+    });
+    LazyStream.prototype.stop = function () {
+        this.pos = this._limits + 1000000000;
+    };
+    LazyStream.prototype.isOverLimits = function () {
+        return this._limits != -1 && this.pos >= this._limits - 1;
+    };
+    return LazyStream;
+}());
+exports.LazyStream = LazyStream;
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/ext/monadish/XmlQuery.ts":
+/*!******************************************************!*\
+  !*** ./src/main/typescript/ext/monadish/XmlQuery.ts ***!
+  \******************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Lang_1 = __webpack_require__(/*! ./Lang */ "./src/main/typescript/ext/monadish/Lang.ts");
+var DomQuery_1 = __webpack_require__(/*! ./DomQuery */ "./src/main/typescript/ext/monadish/DomQuery.ts");
+var isString = Lang_1.Lang.isString;
+/**
+ * xml query as specialized case for DomQuery
+ */
+var XMLQuery = /** @class */ (function (_super) {
+    __extends(XMLQuery, _super);
+    function XMLQuery(rootNode, docType) {
+        if (docType === void 0) { docType = "text/xml"; }
+        var _this = this;
+        var createIe11DomQueryShim = function () {
+            //at the time if wroting ie11 is the only relevant browser
+            //left withut any DomQuery support
+            var parser = new ActiveXObject("Microsoft.XMLDOM");
+            parser.async = false;
+            //we shim th dom parser from ie in
+            return {
+                parseFromString: function (text, contentType) {
+                    return parser.loadXML(text);
+                }
+            };
+        };
+        var parseXML = function (xml) {
+            if (xml == null) {
+                return null;
+            }
+            var domParser = Lang_1.Lang.saveResolveLazy(function () { return new window.DOMParser(); }, function () { return createIe11DomQueryShim(); }).value;
+            return domParser.parseFromString(xml, docType);
+        };
+        if (isString(rootNode)) {
+            _this = _super.call(this, parseXML(rootNode)) || this;
+        }
+        else {
+            _this = _super.call(this, rootNode) || this;
+        }
+        return _this;
+    }
+    XMLQuery.prototype.isXMLParserError = function () {
+        return this.querySelectorAll("parsererror").isPresent();
+    };
+    XMLQuery.prototype.toString = function () {
+        var ret = [];
+        this.eachElem(function (node) {
+            var _a, _b, _c, _d, _e;
+            var serialized = (_d = (_c = (_b = (_a = window) === null || _a === void 0 ? void 0 : _a.XMLSerializer) === null || _b === void 0 ? void 0 : _b.constructor()) === null || _c === void 0 ? void 0 : _c.serializeToString(node), (_d !== null && _d !== void 0 ? _d : (_e = node) === null || _e === void 0 ? void 0 : _e.xml));
+            if (!!serialized) {
+                ret.push(serialized);
+            }
+        });
+        return ret.join("");
+    };
+    XMLQuery.prototype.parserErrorText = function (joinstr) {
+        return this.querySelectorAll("parsererror").textContent(joinstr);
+    };
+    XMLQuery.parseXML = function (txt) {
+        return new XMLQuery(txt);
+    };
+    XMLQuery.parseHTML = function (txt) {
+        return new XMLQuery(txt, "text/html");
+    };
+    XMLQuery.fromString = function (txt, parseType) {
+        if (parseType === void 0) { parseType = "text/xml"; }
+        return new XMLQuery(txt, parseType);
+    };
+    return XMLQuery;
+}(DomQuery_1.DomQuery));
+exports.XMLQuery = XMLQuery;
+exports.XQ = XMLQuery;
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/ext/monadish/index.ts":
+/*!***************************************************!*\
+  !*** ./src/main/typescript/ext/monadish/index.ts ***!
+  \***************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", { value: true });
+var DomQuery_1 = __webpack_require__(/*! ./DomQuery */ "./src/main/typescript/ext/monadish/DomQuery.ts");
+exports.DomQuery = DomQuery_1.DomQuery;
+exports.ElementAttribute = DomQuery_1.ElementAttribute;
+exports.DomQueryCollector = DomQuery_1.DomQueryCollector;
+exports.DQ = DomQuery_1.DQ;
+var Lang_1 = __webpack_require__(/*! ./Lang */ "./src/main/typescript/ext/monadish/Lang.ts");
+exports.Lang = Lang_1.Lang;
+var Monad_1 = __webpack_require__(/*! ./Monad */ "./src/main/typescript/ext/monadish/Monad.ts");
+exports.Config = Monad_1.Config;
+exports.Monad = Monad_1.Monad;
+exports.Optional = Monad_1.Optional;
+exports.ValueEmbedder = Monad_1.ValueEmbedder;
+var XmlQuery_1 = __webpack_require__(/*! ./XmlQuery */ "./src/main/typescript/ext/monadish/XmlQuery.ts");
+exports.XMLQuery = XmlQuery_1.XMLQuery;
+exports.XQ = XmlQuery_1.XQ;
+var Stream_1 = __webpack_require__(/*! ./Stream */ "./src/main/typescript/ext/monadish/Stream.ts");
+exports.Stream = Stream_1.Stream;
+exports.LazyStream = Stream_1.LazyStream;
+var SourcesCollectors_1 = __webpack_require__(/*! ./SourcesCollectors */ "./src/main/typescript/ext/monadish/SourcesCollectors.ts");
+exports.ArrayStreamDataSource = SourcesCollectors_1.ArrayStreamDataSource;
+exports.MappedStreamDataSource = SourcesCollectors_1.MappedStreamDataSource;
+exports.FilteredStreamDatasource = SourcesCollectors_1.FilteredStreamDatasource;
+exports.FlatMapStreamDataSource = SourcesCollectors_1.FlatMapStreamDataSource;
+exports.QueryFormStringCollector = SourcesCollectors_1.QueryFormStringCollector;
+exports.ArrayCollector = SourcesCollectors_1.ArrayCollector;
+exports.AssocArrayCollector = SourcesCollectors_1.AssocArrayCollector;
+exports.FormDataCollector = SourcesCollectors_1.FormDataCollector;
+exports.QueryFormDataCollector = SourcesCollectors_1.QueryFormDataCollector;
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/AjaxImpl.ts":
+/*!**********************************************!*\
+  !*** ./src/main/typescript/impl/AjaxImpl.ts ***!
+  \**********************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+var myfacesConfig = __webpack_require__(/*! ../api/Myfaces */ "./src/main/typescript/api/Myfaces.ts");
+var Response_1 = __webpack_require__(/*! ./xhrCore/Response */ "./src/main/typescript/impl/xhrCore/Response.ts");
+var XhrRequest_1 = __webpack_require__(/*! ./xhrCore/XhrRequest */ "./src/main/typescript/impl/xhrCore/XhrRequest.ts");
+var AsyncQueue_1 = __webpack_require__(/*! ./util/AsyncQueue */ "./src/main/typescript/impl/util/AsyncQueue.ts");
+var monadish_1 = __webpack_require__(/*! ../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
+var Assertions_1 = __webpack_require__(/*! ./util/Assertions */ "./src/main/typescript/impl/util/Assertions.ts");
+var XhrFormData_1 = __webpack_require__(/*! ./xhrCore/XhrFormData */ "./src/main/typescript/impl/xhrCore/XhrFormData.ts");
+var ExtDomQuery_1 = __webpack_require__(/*! ./util/ExtDomQuery */ "./src/main/typescript/impl/util/ExtDomQuery.ts");
+var ErrorData_1 = __webpack_require__(/*! ./xhrCore/ErrorData */ "./src/main/typescript/impl/xhrCore/ErrorData.ts");
+var Lang_1 = __webpack_require__(/*! ./util/Lang */ "./src/main/typescript/impl/util/Lang.ts");
+var Const_1 = __webpack_require__(/*! ./core/Const */ "./src/main/typescript/impl/core/Const.ts");
+var RequestDataResolver_1 = __webpack_require__(/*! ./xhrCore/RequestDataResolver */ "./src/main/typescript/impl/xhrCore/RequestDataResolver.ts");
+/*
+ * allowed project stages
+ */
+var ProjectStages;
+(function (ProjectStages) {
+    ProjectStages["Production"] = "Production";
+    ProjectStages["Development"] = "Development";
+    ProjectStages["SystemTest"] = "SystemTest";
+    ProjectStages["UnitTest"] = "UnitTest";
+})(ProjectStages || (ProjectStages = {}));
+/*
+ *   blockfilter for the passthrough filtering; the attributes given here
+ *   will not be transmitted from the options into the passthrough
+ */
+var BlockFilter;
+(function (BlockFilter) {
+    BlockFilter["onerror"] = "onerror";
+    BlockFilter["onevent"] = "onevent";
+    BlockFilter["render"] = "render";
+    BlockFilter["execute"] = "execute";
+    BlockFilter["myfaces"] = "myfaces";
+    BlockFilter["delay"] = "delay";
+    BlockFilter["timeout"] = "timeout";
+    BlockFilter["windowId"] = "windowId";
+})(BlockFilter || (BlockFilter = {}));
+/**
+ * Core Implementation
+ * to distinct between api and impl
+ *
+ * The original idea was to make the implementation pluggable
+ * but this is pointless, you always can overwrite the thin api layer
+ * however a dedicated api makes sense for readability reasons
+ */
+var Implementation;
+(function (Implementation) {
+    var trim = monadish_1.Lang.trim;
+    var getMessage = Lang_1.ExtLang.getMessage;
+    var getGlobalConfig = Lang_1.ExtLang.getGlobalConfig;
+    var assert = Assertions_1.Assertions.assert;
+    var globalConfig = myfacesConfig.myfaces.config;
+    var projectStage = null;
+    var separator = null;
+    var eventQueue = [];
+    var errorQueue = [];
+    Implementation.requestQueue = null;
+    /*error reporting threshold*/
+    var threshold = "ERROR";
+    /**
+     * fetches the separator char from the given script tags
+     *
+     * @return {char} the separator char for the given script tags
+     */
+    function getSeparatorChar() {
+        var _a, _b, _c, _d, _e;
+        return _e = (_c = (_b = (_a = this) === null || _a === void 0 ? void 0 : _a.globalConfig) === null || _b === void 0 ? void 0 : _b.separator, (_c !== null && _c !== void 0 ? _c : (_d = this) === null || _d === void 0 ? void 0 : _d.separator)), (_e !== null && _e !== void 0 ? _e : (separator = ExtDomQuery_1.ExtDomquery.searchJsfJsFor(/separator=([^&;]*)/).orElse(":").value));
+    }
+    Implementation.getSeparatorChar = getSeparatorChar;
+    /**
+     * this is for testing purposes only, since AjaxImpl is a module
+     * we need to reset for every unit test its internal states
+     */
+    function reset() {
+        globalConfig = myfacesConfig.myfaces.config;
+        projectStage = null;
+        separator = null;
+        eventQueue = [];
+        errorQueue = [];
+        Implementation.requestQueue = null;
+    }
+    Implementation.reset = reset;
+    /**
+     * @return the project stage also emitted by the server:
+     * it cannot be cached and must be delivered over the server
+     * The value for it comes from the requestInternal parameter of the jsf.js script called "stage".
+     */
+    function getProjectStage() {
+        var _a, _b, _c, _d, _e;
+        return _e = (_c = (_b = (_a = this) === null || _a === void 0 ? void 0 : _a.globalConfig) === null || _b === void 0 ? void 0 : _b.projectStage, (_c !== null && _c !== void 0 ? _c : (_d = this) === null || _d === void 0 ? void 0 : _d.projectStage)), (_e !== null && _e !== void 0 ? _e : (projectStage = resolveProjectStateFromURL()));
+    }
+    Implementation.getProjectStage = getProjectStage;
+    /**
+     * resolves the project stage as url parameter
+     * @return the project stage or null
+     */
+    function resolveProjectStateFromURL() {
+        /* run through all script tags and try to find the one that includes jsf.js */
+        var foundStage = ExtDomQuery_1.ExtDomquery.searchJsfJsFor(/stage=([^&;]*)/).value;
+        return (foundStage in ProjectStages) ? foundStage : null;
+    }
+    Implementation.resolveProjectStateFromURL = resolveProjectStateFromURL;
+    /**
+     * implementation of the jsf.util.chain functionality
+     *
+     * @param source
+     * @param event
+     * @param funcs
+     */
+    function chain(source, event) {
+        var funcs = [];
+        for (var _i = 2; _i < arguments.length; _i++) {
+            funcs[_i - 2] = arguments[_i];
+        }
+        var ret = true;
+        var resolveAndExecute = function (func) {
+            if ("string" != typeof func) {
+                //function is passed down as chain parameter, can be executed as is
+                return (ret = ret && (func.call(source, event) !== false));
+            }
+            else {
+                //either a function or a string can be passed in case of a string we have to wrap it into another function
+                //it it is not a plain executable code but a definition
+                var sourceCode = trim(func);
+                if (sourceCode.indexOf("function ") == 0) {
+                    sourceCode = "return " + sourceCode + " (event)";
+                }
+                return (ret = ret && (new Function("event", sourceCode).call(source, event) !== false));
+            }
+        };
+        //we can use our stream each functionality to run our chain here..
+        //the no return value == false stop stream functionality is handled by our resolveAndExecute
+        monadish_1.Stream.of.apply(monadish_1.Stream, funcs).each(function (func) { return resolveAndExecute(func); });
+        return ret;
+    }
+    Implementation.chain = chain;
+    /**
+     * this function has to send the ajax requests
+     *
+     * following request conditions must be met:
+     * <ul>
+     *  <li> the request must be sent asynchronously! </li>
+     *  <li> the request must be a POST!!! request </li>
+     *  <li> the request url must be the form action attribute </li>
+     *  <li> all requests must be queued with a client side request queue to ensure the request ordering!</li>
+     * </ul>
+     *
+     * @param el any dom element no matter being it html or jsf, from which the event is emitted
+     * @param event any javascript event supported by that object
+     * @param opts  map of options being pushed into the ajax cycle
+     *
+     * a) transformArguments out of the function
+     * b) passThrough handling with a map copy with a filter map block map
+     */
+    function request(el, event, opts) {
+        var _a, _b, _c, _d;
+        var _e = RequestDataResolver_1.resolveDefaults(event, opts, el), resolvedEvent = _e.resolvedEvent, options = _e.options, elem = _e.elem, elementId = _e.elementId, requestCtx = _e.requestCtx, internalCtx = _e.internalCtx, windowId = _e.windowId, isResetValues = _e.isResetValues;
+        Assertions_1.Assertions.assertRequestIntegrity(options, elem);
+        requestCtx.assignIf(!!windowId, Const_1.P_WINDOW_ID).value = windowId;
+        requestCtx.assign(Const_1.CTX_PARAM_PASS_THR).value = filterPassthroughValues(options.value);
+        requestCtx.assignIf(!!resolvedEvent, Const_1.CTX_PARAM_PASS_THR, Const_1.P_EVT).value = (_a = resolvedEvent) === null || _a === void 0 ? void 0 : _a.type;
+        /**
+         * ajax pass through context with the source
+         * onresolvedEvent and onerror
+         */
+        requestCtx.assign(Const_1.SOURCE).value = elementId.value;
+        /**
+         * on resolvedEvent and onError...
+         * those values will be traversed later on
+         * also into the response context
+         */
+        requestCtx.assign(Const_1.ON_EVENT).value = (_b = options.value) === null || _b === void 0 ? void 0 : _b.onevent;
+        requestCtx.assign(Const_1.ON_ERROR).value = (_c = options.value) === null || _c === void 0 ? void 0 : _c.onerror;
+        /**
+         * lets drag the myfaces config params also in
+         */
+        requestCtx.assign(Const_1.MYFACES).value = (_d = options.value) === null || _d === void 0 ? void 0 : _d.myfaces;
+        /**
+         * fetch the parent form
+         *
+         * note we also add an override possibility here
+         * so that people can use dummy forms and work
+         * with detached objects
+         */
+        var form = RequestDataResolver_1.resolveForm(requestCtx, elem, resolvedEvent);
+        /**
+         * binding contract the javax.faces.source must be set
+         */
+        requestCtx.assign(Const_1.CTX_PARAM_PASS_THR, Const_1.P_PARTIAL_SOURCE).value = elementId.value;
+        /**
+         * javax.faces.partial.ajax must be set to true
+         */
+        requestCtx.assign(Const_1.CTX_PARAM_PASS_THR, Const_1.P_AJAX).value = true;
+        /**
+         * binding contract the javax.faces.source must be set
+         */
+        requestCtx.assign(Const_1.CTX_PARAM_PASS_THR, Const_1.P_PARTIAL_SOURCE).value = elementId.value;
+        /**
+         * if resetValues is set to true
+         * then we have to set javax.faces.resetValues as well
+         * as pass through parameter
+         * the value has to be explicitly true, according to
+         * the specs jsdoc
+         */
+        requestCtx.assignIf(isResetValues, Const_1.CTX_PARAM_PASS_THR, Const_1.P_RESET_VALUES).value = true;
+        //additional meta information to speed things up, note internal non jsf
+        //pass through options are stored under _mfInternal in the context
+        internalCtx.assign(Const_1.CTX_PARAM_SRC_FRM_ID).value = form.id.value;
+        internalCtx.assign(Const_1.CTX_PARAM_SRC_CTL_ID).value = elementId.value;
+        internalCtx.assign(Const_1.CTX_PARAM_TR_TYPE).value = Const_1.REQ_TYPE_POST;
+        //mojarra compatibility, mojarra is sending the form id as well
+        //this is not documented behavior but can be determined by running
+        //mojarra under blackbox conditions
+        //i assume it does the same as our formId_submit=1 so leaving it out
+        //wont hurt but for the sake of compatibility we are going to add it
+        requestCtx.assign(Const_1.CTX_PARAM_PASS_THR, form.id.value).value = form.id.value;
+        assignClientWindowId(form, requestCtx);
+        assignExecute(options, requestCtx, form, elementId.value);
+        assignRender(options, requestCtx, form, elementId.value);
+        var delay = RequestDataResolver_1.resolveDelay(options);
+        var timeout = RequestDataResolver_1.resolveTimeout(options);
+        //now we enqueue the request as asynchronous runnable into our request
+        //queue and let the queue take over the rest
+        Implementation.queueHandler.addRequestToQueue(elem, form, requestCtx, internalCtx, delay, timeout);
+    }
+    Implementation.request = request;
+    /**
+     * Spec. 13.3.3
+     * Examining the response markup and updating the DOM tree
+     * @param {XMLHttpRequest} request - the ajax request
+     * @param {Object} context - the ajax context
+     */
+    function response(request, context) {
+        Response_1.Response.processResponse(request, context);
+    }
+    Implementation.response = response;
+    /**
+     * adds an error handler to the error queue
+     *
+     * @param errorListener the error listener handler
+     */
+    function addOnError(errorListener) {
+        /*error handling already done in the assert of the queue*/
+        errorQueue.push(errorListener);
+    }
+    Implementation.addOnError = addOnError;
+    /**
+     * adds an event handler to the event queue
+     *
+     * @param eventListener the event listener handler
+     */
+    function addOnEvent(eventListener) {
+        /*error handling already done in the assert of the queue*/
+        eventQueue.push(eventListener);
+    }
+    Implementation.addOnEvent = addOnEvent;
+    // noinspection JSUnusedLocalSymbols
+    /**
+     * sends an event to the event handlers
+     *
+     * @param data the event data object hosting the event data according to the spec @see EventData for what is reachable
+     * @param localHandler an optional event handler, which is processed before the event handler chain
+     */
+    function sendEvent(data, localHandler) {
+        if (localHandler === void 0) { localHandler = function (data) {
+        }; }
+        /*now we serve the queue as well*/
+        localHandler(data);
+        eventQueue.forEach(function (fn) { return fn(data); });
+    }
+    Implementation.sendEvent = sendEvent;
+    /**
+     * error handler behavior called internally
+     * and only into the impl it takes care of the
+     * internal message transformation to a myfaces internal error
+     * and then uses the standard send error mechanisms
+     * also a double error logging prevention is done as well
+     *
+     * @param request the request currently being processed
+     * @param context the context affected by this error
+     * @param exception the exception being thrown
+     * @param clearRequestQueue if set to true, clears the request queue of all pending requests
+     */
+    function stdErrorHandler(request, context, exception, clearRequestQueue) {
+        if (clearRequestQueue === void 0) { clearRequestQueue = false; }
+        //newer browsers do not allow to hold additional values on native objects like exceptions
+        //we hence capsule it into the request, which is gced automatically
+        //on ie as well, since the stdErrorHandler usually is called between requests
+        //this is a valid approach
+        try {
+            if (threshold == "ERROR") {
+                var errorData = ErrorData_1.ErrorData.fromClient(exception);
+                sendError(errorData);
+            }
+        }
+        finally {
+            if (clearRequestQueue) {
+                Implementation.requestQueue.cleanup();
+            }
+        }
+    }
+    Implementation.stdErrorHandler = stdErrorHandler;
+    // noinspection JSUnusedLocalSymbols
+    /**
+     * implementation triggering the error chain
+     *
+     *
+     *
+     *  handles the errors, in case of an onError exists within the context the onError is called as local error handler
+     *  the registered error handlers in the queue receiv an error message to be dealt with
+     *  and if the projectStage is at development an alert box is displayed
+     *
+     *  note: we have additional functionality here, via the global config myfaces.config.defaultErrorOutput a function can be provided
+     *  which changes the default output behavior from alert to something else
+     *
+     * @param errorData the error data to be displayed
+     * @param localHandler an optional local error handler which has to be processed before the error handler queue
+     */
+    function sendError(errorData, localHandler) {
+        if (localHandler === void 0) { localHandler = function (data) {
+        }; }
+        localHandler(errorData);
+        errorQueue.forEach(function (errorCallback) {
+            errorCallback(errorData);
+        });
+        var displayError = getGlobalConfig("defaultErrorOutput", (console ? console.error : alert));
+        displayError(errorData);
+    }
+    Implementation.sendError = sendError;
+    /**
+     * @node optional element or id defining a rootnode where an element with the id "javax.faces.windowId" is hosted
+     * @return the client window id of the current window, if one is given if none is found, null is returned
+     */
+    function getClientWindow(node) {
+        var _a;
+        var ALTERED = "___mf_id_altered__";
+        var INIT = "___init____";
+        /**
+         * the search root for the dom element search
+         */
+        var searchRoot = new monadish_1.DQ(node || document.body);
+        /**
+         * lazy helper to fetch the window id from the window url
+         */
+        var fetchWindowIdFromUrl = function () { return ExtDomQuery_1.ExtDomquery.searchJsfJsFor(/jfwid=([^&;]*)/).orElse(null).value; };
+        /**
+         * functional double check based on stream reduction
+         * the values should be identical or on INIT value which is a premise to
+         * skip the first check
+         *
+         * @param value1
+         * @param value2
+         */
+        var doubleCheck = function (value1, value2) {
+            if (value1 == ALTERED) {
+                return value1;
+            }
+            else if (value1 == INIT) {
+                return value2;
+            }
+            else if (value1 != value2) {
+                return ALTERED;
+            }
+            return value2;
+        };
+        /**
+         * helper for cleaner code, maps the value from an item
+         *
+         * @param item
+         */
+        var getValue = function (item) { return item.attr("value").value; };
+        /**
+         * fetch the window id from the forms
+         * window ids must be present in all forms
+         * or non existent. If they exist all of them must be the same
+         */
+        var formWindowId = searchRoot.stream.map(getValue).reduce(doubleCheck, INIT);
+        //if the resulting window id is set on altered then we have an unresolvable problem
+        assert(formWindowId.value != ALTERED, "Multiple different windowIds found in document");
+        /**
+         * return the window id or null
+         * prio, forms under node/document and if not given then from the url
+         */
+        return _a = formWindowId.value, (_a !== null && _a !== void 0 ? _a : fetchWindowIdFromUrl());
+    }
+    Implementation.getClientWindow = getClientWindow;
+    /**
+     * collect and encode data for a given form element (must be of type form)
+     * find the javax.faces.ViewState element and encode its value as well!
+     * @return a concatenated string of the encoded values!
+     *
+     * @throws Error in case of the given element not being of type form!
+     * https://issues.apache.org/jira/browse/MYFACES-2110
+     */
+    function getViewState(form) {
+        /**
+         *  typecheck assert!, we opt for strong typing here
+         *  because it makes it easier to detect bugs
+         */
+        var element = monadish_1.DQ.byId(form);
+        if (!element.isTag(Const_1.TAG_FORM)) {
+            throw new Error(getMessage("ERR_VIEWSTATE"));
+        }
+        var formData = new XhrFormData_1.XhrFormData(element);
+        return formData.toString();
+    }
+    Implementation.getViewState = getViewState;
+    /**
+     * this at the first sight looks like a weird construct, but we need to do it this way
+     * for testing, we cannot proxy addRequestToQueue from the testing frameworks directly
+     * but we need to keep it under unit tests.
+     */
+    Implementation.queueHandler = {
+        /**
+         * public to make it shimmable for tests
+         *
+         * adds a new request to our queue for further processing
+         */
+        addRequestToQueue: function (elem, form, reqCtx, respPassThr, delay, timeout) {
+            if (delay === void 0) { delay = 0; }
+            if (timeout === void 0) { timeout = 0; }
+            Implementation.requestQueue = (Implementation.requestQueue !== null && Implementation.requestQueue !== void 0 ? Implementation.requestQueue : new AsyncQueue_1.AsynchronouseQueue());
+            Implementation.requestQueue.enqueue(new XhrRequest_1.XhrRequest(elem, form, reqCtx, respPassThr, [], timeout), delay);
+        }
+    };
+    //----------------------------------------------- Methods ---------------------------------------------------------------------
+    /**
+     * the idea is to replace some placeholder parameters with their respective values
+     * placeholder params like  @all, @none, @form, @this need to be replaced by
+     * the values defined by the specification
+     *
+     * This function does it for the render parameters
+     *
+     * @param requestOptions the source options coming in as options object from jsf.ajax.request (options parameter)
+     * @param targetContext the receiving target context
+     * @param issuingForm the issuing form
+     * @param sourceElementId the executing element triggering the jsf.ajax.request (id of it)
+     */
+    function assignRender(requestOptions, targetContext, issuingForm, sourceElementId) {
+        if (requestOptions.getIf(Const_1.RENDER).isPresent()) {
+            remapDefaultConstants(targetContext.getIf(Const_1.CTX_PARAM_PASS_THR).get({}), Const_1.P_RENDER, requestOptions.getIf(Const_1.RENDER).value, issuingForm, sourceElementId);
+        }
+    }
+    /**
+     * the idea is to replace some placeholder parameters with their respective values
+     * placeholder params like  @all, @none, @form, @this need to be replaced by
+     * the values defined by the specification
+     *
+     * This function does it for the execute parameters
+     *
+     * @param requestOptions the source options coming in as options object from jsf.ajax.request (options parameter)
+     * @param targetContext the receiving target context
+     * @param issuingForm the issuing form
+     * @param sourceElementId the executing element triggering the jsf.ajax.request (id of it)
+     */
+    function assignExecute(requestOptions, targetContext, issuingForm, sourceElementId) {
+        if (requestOptions.getIf(Const_1.CTX_PARAM_EXECUTE).isPresent()) {
+            /*the options must be a blank delimited list of strings*/
+            /*compliance with Mojarra which automatically adds @this to an execute
+             * the spec rev 2.0a however states, if none is issued nothing at all should be sent down
+             */
+            requestOptions.assign(Const_1.CTX_PARAM_EXECUTE).value = [requestOptions.getIf(Const_1.CTX_PARAM_EXECUTE).value, Const_1.IDENT_THIS].join(" ");
+            remapDefaultConstants(targetContext.getIf(Const_1.CTX_PARAM_PASS_THR).get({}), Const_1.P_EXECUTE, requestOptions.getIf(Const_1.CTX_PARAM_EXECUTE).value, issuingForm, sourceElementId);
+        }
+        else {
+            targetContext.assign(Const_1.CTX_PARAM_PASS_THR, Const_1.P_EXECUTE).value = sourceElementId;
+        }
+    }
+    /**
+     * apply the browser tab where the request was originating from
+     *
+     * @param form the form hosting the client window id
+     * @param targetContext the target context receiving the value
+     */
+    function assignClientWindowId(form, targetContext) {
+        var clientWindow = jsf.getClientWindow(form.getAsElem(0).value);
+        if (clientWindow) {
+            targetContext.assign(Const_1.CTX_PARAM_PASS_THR, Const_1.P_CLIENT_WINDOW).value = clientWindow;
+        }
+    }
+    /**
+     * transforms the user values to the expected one
+     * with the proper none all form and this handling
+     * (note we also could use a simple string replace but then
+     * we would have had double entries under some circumstances)
+     *
+     * there are several standardized constants which need a special treatment
+     * like @all, @none, @form, @this
+     *
+     * @param targetConfig the target configuration receiving the final values
+     * @param targetKey the target key
+     * @param userValues the passed user values (aka input string which needs to be transformed)
+     * @param issuingForm the form where the issuing element originates
+     * @param issuingElementId the issuing element
+     */
+    function remapDefaultConstants(targetConfig, targetKey, userValues, issuingForm, issuingElementId) {
+        //a cleaner implementation of the transform list method
+        var iterValues = (userValues) ? trim(userValues).split(/\s+/gi) : [];
+        var ret = [];
+        var processed = {};
+        //the idea is simply to loop over all values and then replace
+        //their generic values and filter out doubles
+        //this is more readable than the old indexed based solution
+        //and not really slower because we had to build up the index in our old solution
+        //anyway
+        for (var cnt = 0; cnt < iterValues.length; cnt++) {
+            //avoid doubles
+            if (iterValues[cnt] in processed) {
+                continue;
+            }
+            switch (iterValues[cnt]) {
+                //@none no values should be sent
+                case Const_1.IDENT_NONE:
+                    return targetConfig.delete(targetKey);
+                //@all is a pass through case according to the spec
+                case Const_1.IDENT_ALL:
+                    targetConfig.assign(targetKey).value = Const_1.IDENT_ALL;
+                    return targetConfig;
+                //@form pushes the issuing form id into our list
+                case Const_1.IDENT_FORM:
+                    ret.push(issuingForm.id.value);
+                    processed[issuingForm.id.value] = true;
+                    break;
+                //@this is replaced with the current issuing element id
+                case Const_1.IDENT_THIS:
+                    if (!(issuingElementId in processed)) {
+                        ret.push(issuingElementId);
+                        processed[issuingElementId] = true;
+                    }
+                    break;
+                default:
+                    ret.push(iterValues[cnt]);
+                    processed[iterValues[cnt]] = true;
+            }
+        }
+        //We now add the target as joined list
+        targetConfig.assign(targetKey).value = ret.join(" ");
+        return targetConfig;
+    }
+    /**
+     * filter the options tiven with a blacklist so that only
+     * the values required for passthough land in the ajax request
+     *
+     * @param mappedOpts the options to be filtered
+     */
+    function filterPassthroughValues(mappedOpts) {
+        //we now can use the full code reduction given by our stream api
+        //to filter
+        return monadish_1.Stream.ofAssoc(mappedOpts)
+            .filter(function (item) { return !(item[0] in BlockFilter); })
+            .collect(new monadish_1.AssocArrayCollector());
+    }
+})(Implementation = exports.Implementation || (exports.Implementation = {}));
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/PushImpl.ts":
+/*!**********************************************!*\
+  !*** ./src/main/typescript/impl/PushImpl.ts ***!
+  \**********************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/**
+ * Typescript port of the jsf.push part in the myfaces implementation
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+//TODO still work in progress
+//this is a 1:1 port for the time being
+var Jsf_1 = __webpack_require__(/*! ../api/Jsf */ "./src/main/typescript/api/Jsf.ts");
+var Const_1 = __webpack_require__(/*! ./core/Const */ "./src/main/typescript/impl/core/Const.ts");
+/**
+ * Implementation class for the push functionality
+ */
+var PushImpl;
+(function (PushImpl) {
+    var URL_PROTOCOL = window.location.protocol.replace("http", "ws") + "//";
+    //we expose the member variables for testing purposes
+    //they are not directly touched outside of tests
+    /* socket map by token */
+    PushImpl.sockets = {};
+    /* component attributes by clientId */
+    PushImpl.components = {};
+    /* client ids by token (share websocket connection) */
+    PushImpl.clientIdsByTokens = {};
+    //needed for testing
+    function reset() {
+        PushImpl.sockets = {};
+        PushImpl.components = {};
+        PushImpl.clientIdsByTokens = {};
+    }
+    PushImpl.reset = reset;
+    /*
+     * Api implementations, exposed functions
+     */
+    /**
+     *
+     * @param {function} onopen The function to be invoked when the web socket is opened.
+     * @param {function} onmessage The function to be invoked when a message is received.
+     * @param {function} onclose The function to be invoked when the web socket is closed.
+     * @param {boolean} autoconnect Whether or not to immediately open the socket. Defaults to <code>false</code>.
+     */
+    function init(socketClientId, uri, channel, onopen, onmessage, onclose, behaviorScripts, autoconnect) {
+        onclose = resolveFunction(onclose);
+        if (!window.WebSocket) { // IE6-9.
+            onclose(-1, channel);
+            return;
+        }
+        var channelToken = uri.substr(uri.indexOf('?') + 1);
+        if (!PushImpl.components[socketClientId]) {
+            PushImpl.components[socketClientId] = {
+                'channelToken': channelToken,
+                'onopen': resolveFunction(onopen),
+                'onmessage': resolveFunction(onmessage),
+                'onclose': onclose,
+                'behaviors': behaviorScripts,
+                'autoconnect': autoconnect
+            };
+            if (!PushImpl.clientIdsByTokens[channelToken]) {
+                PushImpl.clientIdsByTokens[channelToken] = [];
+            }
+            PushImpl.clientIdsByTokens[channelToken].push(socketClientId);
+            if (!PushImpl.sockets[channelToken]) {
+                PushImpl.sockets[channelToken] = new Socket(channelToken, getBaseURL(uri), channel);
+            }
+        }
+        if (autoconnect) {
+            Jsf_1.jsf.push.open(socketClientId);
+        }
+    }
+    PushImpl.init = init;
+    function open(socketClientId) {
+        var _a, _b;
+        getSocket((_b = (_a = PushImpl.components) === null || _a === void 0 ? void 0 : _a[socketClientId]) === null || _b === void 0 ? void 0 : _b.channelToken).open();
+    }
+    PushImpl.open = open;
+    function close(socketClientId) {
+        var _a;
+        getSocket((_a = PushImpl.components) === null || _a === void 0 ? void 0 : _a[socketClientId].channelToken).close();
+    }
+    PushImpl.close = close;
+    // Private helper classes
+    // Private classes functions ----------------------------------------------------------------------------------
+    /**
+     * Creates a reconnecting web socket. When the web socket successfully connects on first attempt, then it will
+     * automatically reconnect on timeout with cumulative intervals of 500ms with a maximum of 25 attempts (~3 minutes).
+     * The <code>onclose</code> function will be called with the error code of the last attempt.
+     * @constructor
+     * @param {string} channelToken the channel token associated with this websocket connection
+     * @param {string} url The URL of the web socket
+     * @param {string} channel The name of the web socket channel.
+     */
+    var Socket = /** @class */ (function () {
+        function Socket(channelToken, url, channel) {
+            this.channelToken = channelToken;
+            this.url = url;
+            this.channel = channel;
+            this.reconnectAttempts = 0;
+        }
+        Socket.prototype.open = function () {
+            if (this.socket && this.socket.readyState == 1) {
+                return;
+            }
+            this.socket = new WebSocket(this.url);
+            this.bindCallbacks();
+        };
+        Socket.prototype.onopen = function (event) {
+            if (!this.reconnectAttempts) {
+                var clientIds = PushImpl.clientIdsByTokens[this.channelToken];
+                for (var i = clientIds.length - 1; i >= 0; i--) {
+                    var socketClientId = clientIds[i];
+                    PushImpl.components[socketClientId]['onopen'](this.channel);
+                }
+            }
+            this.reconnectAttempts = 0;
+        };
+        Socket.prototype.onmmessage = function (event) {
+            var message = JSON.parse(event.data);
+            for (var i = PushImpl.clientIdsByTokens[this.channelToken].length - 1; i >= 0; i--) {
+                var socketClientId = PushImpl.clientIdsByTokens[this.channelToken][i];
+                if (document.getElementById(socketClientId)) {
+                    try {
+                        PushImpl.components[socketClientId]['onmessage'](message, this.channel, event);
+                    }
+                    catch (e) {
+                        //Ignore
+                    }
+                    var behaviors = PushImpl.components[socketClientId]['behaviors'];
+                    var functions = behaviors[message];
+                    if (functions && functions.length) {
+                        for (var j = 0; j < functions.length; j++) {
+                            try {
+                                functions[j](null);
+                            }
+                            catch (e) {
+                                //Ignore
+                            }
+                        }
+                    }
+                }
+                else {
+                    PushImpl.clientIdsByTokens[this.channelToken].splice(i, 1);
+                }
+            }
+            if (PushImpl.clientIdsByTokens[this.channelToken].length == 0) {
+                //tag dissapeared
+                this.close();
+            }
+        };
+        Socket.prototype.onclose = function (event) {
+            var _a, _b;
+            if (!this.socket
+                || (event.code == 1000 && event.reason == Const_1.REASON_EXPIRED)
+                || (event.code == 1008)
+                || (!this.reconnectAttempts)
+                || (this.reconnectAttempts >= Const_1.MAX_RECONNECT_ATTEMPTS)) {
+                var clientIds = PushImpl.clientIdsByTokens[this.channelToken];
+                for (var i = clientIds.length - 1; i >= 0; i--) {
+                    var socketClientId = clientIds[i];
+                    PushImpl.components[socketClientId]['onclose']((_a = event) === null || _a === void 0 ? void 0 : _a.code, (_b = this) === null || _b === void 0 ? void 0 : _b.channel, event);
+                }
+            }
+            else {
+                setTimeout(this.open, Const_1.RECONNECT_INTERVAL * this.reconnectAttempts++);
+            }
+        };
+        ;
+        Socket.prototype.close = function () {
+            if (this.socket) {
+                var s = this.socket;
+                this.socket = null;
+                s.close();
+            }
+        };
+        /**
+         * bind the callbacks to the socket callbacks
+         */
+        Socket.prototype.bindCallbacks = function () {
+            var _this = this;
+            this.socket.onopen = function (event) { return _this.onopen(event); };
+            this.socket.onmessage = function (event) { return _this.onmmessage(event); };
+            this.socket.onclose = function (event) { return _this.onclose(event); };
+        };
+        return Socket;
+    }());
+    // Private static functions ---------------------------------------------------------------------------------------
+    function getBaseURL(url) {
+        if (url.indexOf("://") < 0) {
+            var base = window.location.hostname + ":" + window.location.port;
+            return URL_PROTOCOL + base + url;
+        }
+        else {
+            return url;
+        }
+    }
+    /**
+     * Get socket associated with given channelToken.
+     * @param {string} channelToken The name of the web socket channelToken.
+     * @return {Socket} Socket associated with given channelToken.
+     * @throws {Error} When channelToken is unknown, you may need to initialize
+     *                 it first via <code>init()</code> function.
+     */
+    function getSocket(channelToken) {
+        var socket = PushImpl.sockets[channelToken];
+        if (socket) {
+            return socket;
+        }
+        else {
+            throw new Error("Unknown channelToken: " + channelToken);
+        }
+    }
+    function resolveFunction(fn) {
+        if (fn === void 0) { fn = function () {
+        }; }
+        return ((typeof fn !== "function") && (fn = window[fn]), fn);
+    }
+})(PushImpl = exports.PushImpl || (exports.PushImpl = {}));
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/core/Const.ts":
+/*!************************************************!*\
+  !*** ./src/main/typescript/impl/core/Const.ts ***!
+  \************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+/*
+ * [export const] constants
+ */
+exports.P_PARTIAL_SOURCE = "javax.faces.source";
+exports.PARTIAL_ID = "partialId";
+exports.P_VIEWSTATE = "javax.faces.ViewState";
+exports.P_VIEWROOT = "javax.faces.ViewRoot";
+exports.P_VIEWHEAD = "javax.faces.ViewHead";
+exports.P_VIEWBODY = "javax.faces.ViewBody";
+/*some useful definitions*/
+exports.EMPTY_FUNC = Object.freeze(function () {
+});
+exports.EMPTY_STR = "";
+exports.EMPTY_MAP = Object.freeze({});
+exports.HTML_VIEWSTATE = ["<input type='hidden'", "id='", exports.P_VIEWSTATE, "' name='", exports.P_VIEWSTATE, "' value='' />"].join(exports.EMPTY_STR);
+/*internal identifiers for options*/
+exports.IDENT_ALL = "@all";
+exports.IDENT_NONE = "@none";
+exports.IDENT_THIS = "@this";
+exports.IDENT_FORM = "@form";
+exports.P_AJAX = "javax.faces.partial.ajax";
+exports.P_EXECUTE = "javax.faces.partial.execute";
+exports.P_RENDER = "javax.faces.partial.render";
+exports.P_EVT = "javax.faces.partial.event";
+exports.P_CLIENT_WINDOW = "javax.faces.ClientWindow";
+exports.P_RESET_VALUES = "javax.faces.partial.resetValues";
+exports.P_WINDOW_ID = "javax.faces.windowId";
+exports.RENDER = "render";
+exports.WINDOW_ID = "windowId";
+/* message types */
+exports.ERROR = "error";
+exports.EVENT = "event";
+exports.ON_ERROR = "onerror";
+exports.ON_EVENT = "onevent";
+/* event emitting stages */
+exports.BEGIN = "begin";
+exports.COMPLETE = "complete";
+exports.SUCCESS = "success";
+exports.SOURCE = "source";
+exports.STATUS = "status";
+exports.ERROR_NAME = "error-name";
+exports.ERROR_MESSAGE = "error-message";
+exports.RESPONSE_TEXT = "responseText";
+exports.RESPONSE_XML = "responseXML";
+/*ajax errors spec 14.4.2*/
+exports.HTTPERROR = "httpError";
+exports.EMPTY_RESPONSE = "emptyResponse";
+exports.MALFORMEDXML = "malformedXML";
+exports.SERVER_ERROR = "serverError";
+exports.CLIENT_ERROR = "clientError";
+exports.TIMEOUT_EVENT = "timeout";
+exports.CTX_PARAM_MF_INTERNAL = "_mfInternal";
+exports.CTX_PARAM_SRC_FRM_ID = "_mfSourceFormId";
+exports.CTX_PARAM_SRC_CTL_ID = "_mfSourceControlId";
+exports.CTX_PARAM_TR_TYPE = "_mfTransportType";
+exports.CTX_PARAM_PASS_THR = "passThrgh";
+exports.CTX_PARAM_DELAY = "delay";
+exports.CTX_PARAM_TIMEOUT = "timeout";
+exports.CTX_PARAM_RST = "resetValues";
+exports.CTX_PARAM_EXECUTE = "execute";
+exports.STAGE_DEVELOPMENT = "Development";
+exports.CONTENT_TYPE = "Content-Type";
+exports.HEAD_FACES_REQ = "Faces-Request";
+exports.REQ_ACCEPT = "Accept";
+exports.VAL_AJAX = "partial/ajax";
+exports.ENCODED_URL = "javax.faces.encodedURL";
+exports.REQ_TYPE_GET = "GET";
+exports.REQ_TYPE_POST = "POST";
+exports.STATE_EVT_BEGIN = "begin"; //TODO remove this
+exports.STATE_EVT_TIMEOUT = "TIMEOUT_EVENT";
+exports.STATE_EVT_COMPLETE = "complete"; //TODO remove this
+exports.URL_ENCODED = "application/x-www-form-urlencoded";
+exports.MULTIPART = "multipart/form-data";
+exports.NO_TIMEOUT = 0;
+exports.STD_ACCEPT = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
+exports.TAG_HEAD = "head";
+exports.TAG_FORM = "form";
+exports.TAG_BODY = "body";
+exports.TAG_BEFORE = "before";
+exports.TAG_AFTER = "after";
+exports.TAG_ATTR = "attribute";
+exports.SEL_VIEWSTATE_ELEM = "[name='" + exports.P_VIEWSTATE + "']";
+exports.SEL_RESPONSE_XML = "responseXML";
+exports.PHASE_PROCESS_RESPONSE = "processResponse";
+exports.ERR_NO_PARTIAL_RESPONSE = "Partial response not set";
+exports.ATTR_URL = "url";
+exports.ATTR_NAME = "name";
+exports.ATTR_VALUE = "value";
+exports.ATTR_ID = "id";
+/*partial response types*/
+exports.RESP_PARTIAL = "partial-response";
+/*partial commands*/
+exports.CMD_CHANGES = "changes";
+exports.CMD_UPDATE = "update";
+exports.CMD_DELETE = "delete";
+exports.CMD_INSERT = "insert";
+exports.CMD_EVAL = "eval";
+exports.CMD_ERROR = "error";
+exports.CMD_ATTRIBUTES = "attributes";
+exports.CMD_EXTENSION = "extension";
+exports.CMD_REDIRECT = "redirect";
+/*other constants*/
+exports.UPDATE_FORMS = "_updateForms";
+exports.UPDATE_ELEMS = "_updateElems";
+exports.MYFACES = "myfaces";
+exports.SEL_SCRIPTS_STYLES = "script, style, link";
+exports.MF_NONE = "__mf_none__";
+exports.REASON_EXPIRED = "Expired";
+exports.APPLIED_VST = "appliedViewState";
+exports.RECONNECT_INTERVAL = 500;
+exports.MAX_RECONNECT_ATTEMPTS = 25;
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/core/ImplTypes.ts":
+/*!****************************************************!*\
+  !*** ./src/main/typescript/impl/core/ImplTypes.ts ***!
+  \****************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+var Const_1 = __webpack_require__(/*! ./Const */ "./src/main/typescript/impl/core/Const.ts");
+/**
+ * a helper class to isolate the
+ * view state data processing
+ */
+var ViewState = /** @class */ (function () {
+    function ViewState(id, value) {
+        this.id = id;
+        this.value = value;
+        var viewStatePos = id.indexOf(Const_1.P_VIEWSTATE);
+        this.nameSpace = viewStatePos > 0 ? id.substr(0, viewStatePos - 1) : Const_1.EMPTY_STR;
+    }
+    Object.defineProperty(ViewState.prototype, "hasNameSpace", {
+        get: function () {
+            var _a, _b;
+            return !!(_b = (_a = this) === null || _a === void 0 ? void 0 : _a.nameSpace, (_b !== null && _b !== void 0 ? _b : Const_1.EMPTY_STR)).length;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    return ViewState;
+}());
+exports.ViewState = ViewState;
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/i18n/Messages.ts":
+/*!***************************************************!*\
+  !*** ./src/main/typescript/impl/i18n/Messages.ts ***!
+  \***************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+var Messages = /** @class */ (function () {
+    function Messages() {
+        this.MSG_TEST = "Testmessage";
+        /*Messages*/
+        /** @constant */
+        this.MSG_DEV_MODE = "Note, this message is only sent, because project stage is development and no " +
+            "other error listeners are registered.";
+        /** @constant */
+        this.MSG_AFFECTED_CLASS = "Affected Class=";
+        /** @constant */
+        this.MSG_AFFECTED_METHOD = "Affected Method=";
+        /** @constant */
+        this.MSG_ERROR_NAME = "Error Name=";
+        /** @constant */
+        this.MSG_ERROR_MESSAGE = "Error Message=";
+        /** @constant */
+        this.MSG_SERVER_ERROR_NAME = "Server Error Name=";
+        /** @constant */
+        this.MSG_ERROR_DESC = "Error Description=";
+        /** @constant */
+        this.MSG_ERROR_NO = "Error Number=";
+        /** @constant */
+        this.MSG_ERROR_LINENO = "Error Line Number=";
+        /*Errors and messages*/
+        /** @constant */
+        this.ERR_FORM = "Sourceform could not be determined, either because element is not attached to a form or we have multiple forms with named elements of the same identifier or name, stopping the ajax processing";
+        /** @constant */
+        this.ERR_VIEWSTATE = "jsf.viewState= param value not of type form!";
+        /** @constant */
+        this.ERR_TRANSPORT = "Transport type {0} does not exist";
+        /** @constant */
+        this.ERR_EVT_PASS = "an event must be passed down (either a an event object null or undefined) ";
+        /** @constant */
+        this.ERR_CONSTRUCT = "Parts of the response couldn't be retrieved when constructing the event data= {0} ";
+        /** @constant */
+        this.ERR_MALFORMEDXML = "The server response could not be parsed, the server has returned with a response which is not xml !";
+        /** @constant */
+        this.ERR_SOURCE_FUNC = "source cannot be a function (probably source and event were not defined or set to null";
+        /** @constant */
+        this.ERR_EV_OR_UNKNOWN = "An event object or unknown must be passed as second parameter";
+        /** @constant */
+        this.ERR_SOURCE_NOSTR = "source cannot be a string";
+        /** @constant */
+        this.ERR_SOURCE_DEF_NULL = "source must be defined or null";
+        //_Lang.js
+        /** @constant */
+        this.ERR_MUST_STRING = "{0}: {1} namespace must be of type String";
+        /** @constant */
+        this.ERR_REF_OR_ID = "{0}: {1} a reference node or identifier must be provided";
+        /** @constant */
+        this.ERR_PARAM_GENERIC = "{0}: parameter {1} must be of type {2}";
+        /** @constant */
+        this.ERR_PARAM_STR = "{0}: {1} param must be of type string";
+        /** @constant */
+        this.ERR_PARAM_STR_RE = "{0}: {1} param must be of type string or a regular expression";
+        /** @constant */
+        this.ERR_PARAM_MIXMAPS = "{0}: both a source as well as a destination map must be provided";
+        /** @constant */
+        this.ERR_MUST_BE_PROVIDED = "{0}: an {1} and a {2} must be provided";
+        /** @constant */
+        this.ERR_MUST_BE_PROVIDED1 = "{0}: {1} must be set";
+        /** @constant */
+        this.ERR_REPLACE_EL = "replaceElements called while evalNodes is not an array";
+        /** @constant */
+        this.ERR_EMPTY_RESPONSE = "{0}: The response cannot be null or empty!";
+        /** @constant */
+        this.ERR_ITEM_ID_NOTFOUND = "{0}: item with identifier {1} could not be found";
+        /** @constant */
+        this.ERR_PPR_IDREQ = "{0}: Error in PPR Insert, id must be present";
+        /** @constant */
+        this.ERR_PPR_INSERTBEFID = "{0}: Error in PPR Insert, before id or after id must be present";
+        /** @constant */
+        this.ERR_PPR_INSERTBEFID_1 = "{0}: Error in PPR Insert, before  node of id {1} does not exist in document";
+        /** @constant */
+        this.ERR_PPR_INSERTBEFID_2 = "{0}: Error in PPR Insert, after  node of id {1} does not exist in document";
+        /** @constant */
+        this.ERR_PPR_DELID = "{0}: Error in delete, id not in xml markup";
+        /** @constant */
+        this.ERR_PPR_UNKNOWNCID = "{0}:  Unknown Html-Component-ID= {1}";
+        /** @constant */
+        this.ERR_NO_VIEWROOTATTR = "{0}: Changing of ViewRoot attributes is not supported";
+        /** @constant */
+        this.ERR_NO_HEADATTR = "{0}: Changing of Head attributes is not supported";
+        /** @constant */
+        this.ERR_RED_URL = "{0}: Redirect without url";
+        /** @constant */
+        this.ERR_REQ_FAILED_UNKNOWN = "Request failed with unknown status";
+        /** @constant */
+        this.ERR_REQU_FAILED = "Request failed with status {0} and reason {1}";
+        /** @constant */
+        this.UNKNOWN = "UNKNOWN";
+    }
+    return Messages;
+}());
+exports.Messages = Messages;
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/util/Assertions.ts":
+/*!*****************************************************!*\
+  !*** ./src/main/typescript/impl/util/Assertions.ts ***!
+  \*****************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", { value: true });
+var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
+var Lang_1 = __webpack_require__(/*! ./Lang */ "./src/main/typescript/impl/util/Lang.ts");
+var getMessage = Lang_1.ExtLang.getMessage;
+var makeException = Lang_1.ExtLang.makeException;
+var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
+/**
+ * a set of internal code assertions
+ * which raise an error
+ *
+ */
+var Assertions;
+(function (Assertions) {
+    function assertRequestIntegrity(options, elem) {
+        /*assert if the onerror is set and once if it is set it must be of type function*/
+        assertFunction(options.getIf(Const_1.ON_ERROR).value);
+        /*assert if the onevent is set and once if it is set it must be of type function*/
+        assertFunction(options.getIf(Const_1.ON_EVENT).value);
+        //improve the error messages if an empty elem is passed
+        //Assertions.assertElementExists(elem);
+        assert(elem.isPresent(), getMessage("ERR_MUST_BE_PROVIDED1", "{0}: source  must be provided or exist", "source element id"), "jsf.ajax.request", "ArgNotSet");
+    }
+    Assertions.assertRequestIntegrity = assertRequestIntegrity;
+    function assertUrlExists(node) {
+        if (node.attr(Const_1.ATTR_URL).isAbsent()) {
+            throw Assertions.raiseError(new Error(), getMessage("ERR_RED_URL", null, "_Ajaxthis.processRedirect"), "processRedirect");
+        }
+    }
+    Assertions.assertUrlExists = assertUrlExists;
+    /**
+     * checks the xml for various issues which can occur
+     * and prevent a proper processing
+     */
+    function assertValidXMLResponse(responseXML) {
+        assert(!responseXML.isAbsent(), Const_1.EMPTY_RESPONSE, Const_1.PHASE_PROCESS_RESPONSE);
+        assert(!responseXML.isXMLParserError(), responseXML.parserErrorText(Const_1.EMPTY_STR), Const_1.PHASE_PROCESS_RESPONSE);
+        assert(responseXML.querySelectorAll(Const_1.RESP_PARTIAL).isPresent(), Const_1.ERR_NO_PARTIAL_RESPONSE, Const_1.PHASE_PROCESS_RESPONSE);
+    }
+    Assertions.assertValidXMLResponse = assertValidXMLResponse;
+    /**
+     * internal helper which raises an error in the
+     * format we need for further processing
+     *
+     * @param message the message
+     * @param title the title of the error (optional)
+     * @param name the name of the error (optional)
+     */
+    function raiseError(error, message, caller, title, name) {
+        var finalTitle = (title !== null && title !== void 0 ? title : Const_1.MALFORMEDXML);
+        var finalName = (name !== null && name !== void 0 ? name : Const_1.MALFORMEDXML);
+        var finalMessage = (message !== null && message !== void 0 ? message : Const_1.EMPTY_STR);
+        //TODO clean up the messy makeException, this is a perfect case for encapsulation and sane defaults
+        return makeException(error, finalTitle, finalName, "Response", caller || ((arguments.caller) ? arguments.caller.toString() : "_raiseError"), finalMessage);
+    }
+    Assertions.raiseError = raiseError;
+    /*
+     * using the new typescript 3.7 compiler assertion functionality to improve compiler hinting
+     * we are not fully there yet, but soon
+     */
+    function assert(value, msg, caller, title) {
+        if (msg === void 0) { msg = Const_1.EMPTY_STR; }
+        if (caller === void 0) { caller = Const_1.EMPTY_STR; }
+        if (title === void 0) { title = "Assertion Error"; }
+        if (!value) {
+            throw Assertions.raiseError(new Error(), msg, caller, title);
+        }
+    }
+    Assertions.assert = assert;
+    function assertType(value, theType, msg, caller, title) {
+        if (msg === void 0) { msg = Const_1.EMPTY_STR; }
+        if (caller === void 0) { caller = Const_1.EMPTY_STR; }
+        if (title === void 0) { title = "Type Assertion Error"; }
+        if ((!!value) && !monadish_1.Lang.assertType(value, theType)) {
+            throw Assertions.raiseError(new Error(), msg, caller, title);
+        }
+    }
+    Assertions.assertType = assertType;
+    function assertFunction(value, msg, caller, title) {
+        if (msg === void 0) { msg = Const_1.EMPTY_STR; }
+        if (caller === void 0) { caller = Const_1.EMPTY_STR; }
+        if (title === void 0) { title = "Assertion Error"; }
+        assertType(value, "function", msg, caller, title);
+    }
+    Assertions.assertFunction = assertFunction;
+})(Assertions = exports.Assertions || (exports.Assertions = {}));
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/util/AsyncQueue.ts":
+/*!*****************************************************!*\
+  !*** ./src/main/typescript/impl/util/AsyncQueue.ts ***!
+  \*****************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", { value: true });
+/**
+ * Asynchronous queue which starts to work
+ * through the callbacks until the queue is empty
+ *
+ * Every callback must be of async runnable
+ * which is sort of an extended promise which has
+ * added a decicated cancel and start point
+ *
+ * This interface can be used as wrapper contract
+ * for normal promises if needed.
+ */
+var AsynchronouseQueue = /** @class */ (function () {
+    function AsynchronouseQueue() {
+        this.runnableQueue = [];
+    }
+    Object.defineProperty(AsynchronouseQueue.prototype, "isEmpty", {
+        get: function () {
+            return !this.runnableQueue.length;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    /**
+     * enequeues an element and starts the
+     * asynchronous work loop if not already running
+     *
+     * @param element the element to be queued and processed
+     * @param delay possible delay after our usual process or drop if something newer is incoming algorithm
+     */
+    AsynchronouseQueue.prototype.enqueue = function (element, delay) {
+        var _this = this;
+        if (delay === void 0) { delay = 0; }
+        if (this.delayTimeout) {
+            clearTimeout(this.delayTimeout);
+            this.delayTimeout = null;
+        }
+        if (delay) {
+            this.delayTimeout = setTimeout(function () {
+                _this.appendElement(element);
+            });
+        }
+        else {
+            this.appendElement(element);
+        }
+    };
+    AsynchronouseQueue.prototype.dequeue = function () {
+        return this.runnableQueue.shift();
+    };
+    AsynchronouseQueue.prototype.cleanup = function () {
+        this.currentlyRunning = null;
+        this.runnableQueue.length = 0;
+    };
+    AsynchronouseQueue.prototype.appendElement = function (element) {
+        //only if the first element is added we start with a trigger
+        //otherwise a process already is running and not finished yet at that
+        //time
+        this.runnableQueue.push(element);
+        if (!this.currentlyRunning) {
+            this.runEntry();
+        }
+    };
+    AsynchronouseQueue.prototype.runEntry = function () {
+        var _this = this;
+        if (this.isEmpty) {
+            this.currentlyRunning = null;
+            return;
+        }
+        this.currentlyRunning = this.dequeue();
+        this.currentlyRunning
+            .catch(function (e) {
+            //in case of an error we always clean up the remaining calls
+            //to allow a clean recovery of the application
+            _this.cleanup();
+            throw e;
+        })
+            .then(
+        //the idea is to trigger the next over an event to reduce
+        //the number of recursive calls (stacks might be limited
+        //compared to ram)
+        //naturally give we have a DOM, the DOM is the natural event dispatch system
+        //which we can use, to decouple the calls from a recursive stack call
+        //(the browser engine will take care of that)
+        function () { return _this.callForNextElementToProcess(); }).start();
+    };
+    AsynchronouseQueue.prototype.cancel = function () {
+        try {
+            if (this.currentlyRunning) {
+                this.currentlyRunning.cancel();
+            }
+        }
+        finally {
+            this.cleanup();
+        }
+    };
+    AsynchronouseQueue.prototype.callForNextElementToProcess = function () {
+        this.runEntry();
+    };
+    AsynchronouseQueue.prototype.processNextElement = function () {
+        this.currentlyRunning = null;
+        if (!this.isEmpty) {
+            this.runEntry();
+        }
+    };
+    AsynchronouseQueue.EVT_NEXT = "__mf_queue_next__";
+    return AsynchronouseQueue;
+}());
+exports.AsynchronouseQueue = AsynchronouseQueue;
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/util/ExtDomQuery.ts":
+/*!******************************************************!*\
+  !*** ./src/main/typescript/impl/util/ExtDomQuery.ts ***!
+  \******************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Monad_1 = __webpack_require__(/*! ../../ext/monadish/Monad */ "./src/main/typescript/ext/monadish/Monad.ts");
+var DomQuery_1 = __webpack_require__(/*! ../../ext/monadish/DomQuery */ "./src/main/typescript/ext/monadish/DomQuery.ts");
+var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
+/**
+ * Extension which adds implementation specific
+ * meta data to our dom qury
+ *
+ * Usage
+ * el = new ExtDQ(oldReference)
+ * nonce = el.nonce
+ * windowId = el.getWindowId
+ */
+var ExtDomquery = /** @class */ (function (_super) {
+    __extends(ExtDomquery, _super);
+    function ExtDomquery() {
+        return _super !== null && _super.apply(this, arguments) || this;
+    }
+    Object.defineProperty(ExtDomquery, "windowId", {
+        get: function () {
+            return new ExtDomquery(document.body).windowId;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(ExtDomquery, "nonce", {
+        get: function () {
+            return new ExtDomquery(document.body).nonce;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(ExtDomquery.prototype, "windowId", {
+        get: function () {
+            var fetchWindowIdFromURL = function () {
+                var href = window.location.href;
+                var windowId = "windowId";
+                var regex = new RegExp("[\\?&]" + windowId + "=([^&#\\;]*)");
+                var results = regex.exec(href);
+                //initial trial over the url and a regexp
+                if (results != null)
+                    return results[1];
+                return null;
+            };
+            //byId ($)
+            if (this.value.isPresent()) {
+                var result = this.querySelectorAll("form input[name='" + Const_1.P_WINDOW_ID + "']");
+                if (result.length > 0) {
+                    throw Error("Multiple different windowIds found in document");
+                }
+                return (result.isPresent()) ? result.getAsElem(0).value.value : fetchWindowIdFromURL();
+            }
+            else {
+                return fetchWindowIdFromURL();
+            }
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(ExtDomquery.prototype, "nonce", {
+        /*
+        determines the jsfjs nonce and adds them to the namespace
+        * this is done once and only lazily
+        */
+        get: function () {
+            //already processed
+            var myfacesConfig = new Monad_1.Config(window.myfaces);
+            var nonce = myfacesConfig.assign("config", "cspMeta", "nonce");
+            if (nonce.value) {
+                return nonce.value;
+            }
+            var curScript = new DomQuery_1.DQ(document.currentScript);
+            //since our baseline atm is ie11 we cannot use document.currentScript globally
+            if (curScript.attr("nonce").value != null) {
+                //fastpath for modern browsers
+                return curScript.attr("nonce").value;
+            }
+            var nonceScript = DomQuery_1.DQ.querySelectorAll("script[src], link[src]").lazyStream
+                .filter(function (item) { return item.attr("nonce").value != null && item.attr("src") != null; })
+                .map((function (item) { return !item.attr("src").value.match(/jsf\.js\?ln\=javax\.faces/gi); }))
+                .first();
+            if (nonceScript.isPresent()) {
+                nonce.value = DomQuery_1.DomQuery.byId(nonceScript.value).attr("nonce").value;
+            }
+            return nonce.value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    ExtDomquery.searchJsfJsFor = function (item) {
+        return new ExtDomquery(document).searchJsfJsFor(item);
+    };
+    ExtDomquery.prototype.searchJsfJsFor = function (rexp) {
+        //perfect application for lazy stream
+        return DomQuery_1.DQ.querySelectorAll("script").lazyStream
+            .filter(function (item) {
+            var _a;
+            return (_a = item.attr("src").value, (_a !== null && _a !== void 0 ? _a : Const_1.EMPTY_STR)).search(/\/javax\.faces\.resource.*\/jsf\.js.*separator/) != -1;
+        }).map(function (item) {
+            var result = item.attr("src").value.match(rexp);
+            return decodeURIComponent(result[1]);
+        }).first();
+    };
+    ExtDomquery.prototype.globalEval = function (code, nonce) {
+        return _super.prototype.globalEval.call(this, code, (nonce !== null && nonce !== void 0 ? nonce : this.nonce));
+    };
+    return ExtDomquery;
+}(DomQuery_1.DQ));
+exports.ExtDomquery = ExtDomquery;
+exports.ExtDQ = DomQuery_1.DQ;
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/util/Lang.ts":
+/*!***********************************************!*\
+  !*** ./src/main/typescript/impl/util/Lang.ts ***!
+  \***********************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * todo replace singleton with module definition
+ *
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+var Lang_1 = __webpack_require__(/*! ../../ext/monadish/Lang */ "./src/main/typescript/ext/monadish/Lang.ts");
+var Messages_1 = __webpack_require__(/*! ../i18n/Messages */ "./src/main/typescript/impl/i18n/Messages.ts");
+var DomQuery_1 = __webpack_require__(/*! ../../ext/monadish/DomQuery */ "./src/main/typescript/ext/monadish/DomQuery.ts");
+var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
+var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
+var RequestDataResolver_1 = __webpack_require__(/*! ../xhrCore/RequestDataResolver */ "./src/main/typescript/impl/xhrCore/RequestDataResolver.ts");
+var ExtLang;
+(function (ExtLang) {
+    var installedLocale;
+    var nameSpace = "impl/util/Lang/";
+    function getLanguage() {
+        //TODO global config override
+        var _a, _b, _c;
+        var language = (_b = (_a = navigator.languages) === null || _a === void 0 ? void 0 : _a[0], (_b !== null && _b !== void 0 ? _b : (_c = navigator) === null || _c === void 0 ? void 0 : _c.language));
+        language = language.split("-")[0];
+        return language;
+    }
+    ExtLang.getLanguage = getLanguage;
+    //should be in lang, but for now here to avoid recursive imports, not sure if typescript still has a problem with those
+    /**
+     * helper function to savely resolve anything
+     * this is not an elvis operator, it resolves
+     * a value without exception in a tree and if
+     * it is not resolvable then an optional of
+     * a default value is restored or Optional.empty
+     * if none is given
+     *
+     * usage
+     * <code>
+     *     let var: Optional<string> = saveResolve(() => a.b.c.d.e, "foobaz")
+     * </code>
+     *
+     * @param resolverProducer a lambda which can produce the value
+     * @param defaultValue an optional default value if the producer failes to produce anything
+     * @returns an Optional of the produced value
+     */
+    function failSaveResolve(resolverProducer, defaultValue) {
+        if (defaultValue === void 0) { defaultValue = null; }
+        return Lang_1.Lang.saveResolve(resolverProducer, defaultValue);
+    }
+    ExtLang.failSaveResolve = failSaveResolve;
+    /**
+     * under some conditions it makes sense to swallow errors and return a default value in the error case
+     * classical example the optional resolution of values in a chain (thankfully now covered by Typescript itself)
+     * another example which we have in our system is that some operations fail only under test due to test framework
+     * limitations while they cannot fail in the real world.
+     *
+     * @param resolverProducer a producer function which produces a value in the non error case
+     * @param defaultValue the default value in case of a fail of the function
+     */
+    function failSaveExecute(resolverProducer, defaultValue) {
+        if (defaultValue === void 0) { defaultValue = null; }
+        Lang_1.Lang.saveResolve(resolverProducer, defaultValue);
+    }
+    ExtLang.failSaveExecute = failSaveExecute;
+    /**
+     * returns a given localized message upon a given key
+     * basic java log like templating functionality is included
+     *
+     * @param {String} key the key for the message
+     * @param {String} defaultMessage optional default message if none was found
+     *
+     * Additionally you can pass additional arguments, which are used
+     * in the same way java log templates use the params
+     *
+     * @param templateParams the param list to be filled in
+     */
+    function getMessage(key, defaultMessage) {
+        var templateParams = [];
+        for (var _i = 2; _i < arguments.length; _i++) {
+            templateParams[_i - 2] = arguments[_i];
+        }
+        var _a, _b;
+        installedLocale = (installedLocale !== null && installedLocale !== void 0 ? installedLocale : new Messages_1.Messages());
+        var msg = (_b = (_a = installedLocale[key], (_a !== null && _a !== void 0 ? _a : defaultMessage)), (_b !== null && _b !== void 0 ? _b : key + " - undefined message"));
+        monadish_1.Stream.of.apply(monadish_1.Stream, templateParams).each(function (param, cnt) {
+            msg = msg.replace(new RegExp(["\\{", cnt, "\\}"].join(Const_1.EMPTY_STR), "g"), param);
+        });
+        return msg;
+    }
+    ExtLang.getMessage = getMessage;
+    /**
+     * transforms a key value pair into a string
+     * @param key the key
+     * @param val the value
+     * @param delimiter the delimiter
+     */
+    function keyValToStr(key, val, delimiter) {
+        if (delimiter === void 0) { delimiter = "\n"; }
+        return [key, val].join(delimiter);
+    }
+    ExtLang.keyValToStr = keyValToStr;
+    /**
+     * creates an exeption with additional internal parameters
+     * for extra information
+     *
+     * @param {String} title the exception title
+     * @param {String} name  the exception name
+     * @param {String} callerCls the caller class
+     * @param {String} callFunc the caller function
+     * @param {String} message the message for the exception
+     */
+    function makeException(error, title, name, callerCls, callFunc, message) {
+        var _a;
+        return new Error((_a = message + ((callerCls !== null && callerCls !== void 0 ? callerCls : nameSpace)) + callFunc, (_a !== null && _a !== void 0 ? _a : (Const_1.EMPTY_STR + arguments.caller.toString()))));
+    }
+    ExtLang.makeException = makeException;
+    /**
+     * fetches a global config entry
+     * @param {String} configName the name of the configuration entry
+     * @param {Object} defaultValue
+     *
+     * @return either the config entry or if none is given the default value
+     */
+    function getGlobalConfig(configName, defaultValue) {
+        var _a, _b, _c, _d;
+        /**
+         * note we could use exists but this is an heavy operation, since the config name usually
+         * given this function here is called very often
+         * is a single entry without . in between we can do the lighter shortcut
+         */
+        return _d = (_c = (_b = (_a = window) === null || _a === void 0 ? void 0 : _a.myfaces) === null || _b === void 0 ? void 0 : _b.config) === null || _c === void 0 ? void 0 : _c[configName], (_d !== null && _d !== void 0 ? _d : defaultValue);
+    }
+    ExtLang.getGlobalConfig = getGlobalConfig;
+    /**
+     * fetches the form in an unprecise manner depending
+     * on an element or event target.
+     *
+     * The idea is that according to the jsf spec
+     * the enclosing form of the issuing element needs to be fetched.
+     *
+     * This is fine, but since then html5 came into the picture with the form attribute the element
+     * can be anywhere referencing its parent form.
+     *
+     * Also theoretically you can have the case of an issuing element enclosing a set of forms
+     * (not really often used, but theoretically it could be input button allows to embed html for instance)
+     *
+     * So the idea is not to limit the issuing form determination to the spec case
+     * but also cover the theoretical and html5 corner case.
+     *
+     * @param elem
+     * @param event
+     */
+    function getForm(elem, event) {
+        var FORM = "form";
+        var queryElem = new DomQuery_1.DQ(elem);
+        var eventTarget = new DomQuery_1.DQ(RequestDataResolver_1.getEventTarget(event));
+        if (queryElem.isTag(FORM)) {
+            return queryElem;
+        }
+        //html 5 for handling
+        if (queryElem.attr(FORM).isPresent()) {
+            var formId = queryElem.attr(FORM).value;
+            var foundForm = DomQuery_1.DQ.byId(formId);
+            if (foundForm.isPresent()) {
+                return foundForm;
+            }
+        }
+        var form = queryElem.parents(FORM)
+            .orElseLazy(function () { return queryElem.byTagName(FORM, true); })
+            .orElseLazy(function () { return eventTarget.parents(FORM); })
+            .orElseLazy(function () { return eventTarget.byTagName(FORM); })
+            .first();
+        assertFormExists(form);
+        return form;
+    }
+    ExtLang.getForm = getForm;
+    /**
+     * gets the local or global options with local ones having higher priority
+     * if no local or global one was found then the default value is given back
+     *
+     * @param {String} configName the name of the configuration entry
+     * @param {String} localOptions the local options root for the configuration myfaces as default marker is added implicitely
+     *
+     * @param {Object} defaultValue
+     *
+     * @return either the config entry or if none is given the default value
+     */
+    function getLocalOrGlobalConfig(localOptions, configName, defaultValue) {
+        var _a, _b, _c, _d, _e, _f, _g, _h;
+        return _h = (_d = (_c = (_b = (_a = localOptions.value) === null || _a === void 0 ? void 0 : _a.myfaces) === null || _b === void 0 ? void 0 : _b.config) === null || _c === void 0 ? void 0 : _c[configName], (_d !== null && _d !== void 0 ? _d : (_g = (_f = (_e = window) === null || _e === void 0 ? void 0 : _e.myfaces) === null || _f === void 0 ? void 0 : _f.config) === null || _g === void 0 ? void 0 : _g[configName])), (_h !== null && _h !== void 0 ? _h : defaultValue);
+    }
+    ExtLang.getLocalOrGlobalConfig = getLocalOrGlobalConfig;
+    /**
+     * assert that the form exists and throw an exception in the case it does not
+     * (TODO move this into the assertions)
+     *
+     * @param form the form to check for
+     */
+    function assertFormExists(form) {
+        if (form.isAbsent()) {
+            throw makeException(new Error(), null, null, "Impl", "getForm", getMessage("ERR_FORM"));
+        }
+    }
+})(ExtLang = exports.ExtLang || (exports.ExtLang = {}));
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/xhrCore/ErrorData.ts":
+/*!*******************************************************!*\
+  !*** ./src/main/typescript/impl/xhrCore/ErrorData.ts ***!
+  \*******************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
+var EventData_1 = __webpack_require__(/*! ./EventData */ "./src/main/typescript/impl/xhrCore/EventData.ts");
+var Lang_1 = __webpack_require__(/*! ../util/Lang */ "./src/main/typescript/impl/util/Lang.ts");
+var getMessage = Lang_1.ExtLang.getMessage;
+var ErrorType;
+(function (ErrorType) {
+    ErrorType["SERVER_ERROR"] = "serverError";
+    ErrorType["HTTP_ERROR"] = "httpError";
+    ErrorType["CLIENT_ERROR"] = "clientErrror";
+    ErrorType["TIMEOUT"] = "timeout";
+})(ErrorType = exports.ErrorType || (exports.ErrorType = {}));
+/**
+ * the spec has a problem of having the error
+ * object somewhat underspecified, there is no clear
+ * description of the required contents.
+ * I want to streamline it with mojarra here
+ * hence we are going to move
+ * everything into the same attributes,
+ * I will add deprecated myfaces backwards compatibility attributes as well
+ */
+var ErrorData = /** @class */ (function (_super) {
+    __extends(ErrorData, _super);
+    function ErrorData(source, errorName, errorMessage, responseText, responseXML, responseCode, status, type) {
+        if (responseText === void 0) { responseText = null; }
+        if (responseXML === void 0) { responseXML = null; }
+        if (responseCode === void 0) { responseCode = "200"; }
+        if (status === void 0) { status = "UNKNOWN"; }
+        if (type === void 0) { type = ErrorType.CLIENT_ERROR; }
+        var _this = _super.call(this) || this;
+        _this.type = "error";
+        _this.source = source;
+        _this.type = "error";
+        _this.errorName = errorName;
+        _this.message = _this.errorMessage = errorMessage;
+        _this.responseCode = responseCode;
+        _this.responseText = responseText;
+        _this.status = status;
+        _this.typeDetails = type;
+        if (type == ErrorType.SERVER_ERROR) {
+            _this.serverErrorName = _this.errorName;
+            _this.serverErrorMessage = _this.errorMessage;
+        }
+        return _this;
+    }
+    ErrorData.fromClient = function (e) {
+        return new ErrorData("client", e.name, e.message, e.stack);
+    };
+    ErrorData.fromHttpConnection = function (source, name, message, responseText, responseCode) {
+        return new ErrorData(source, name, message, responseText, responseCode, null, "UNKNOWN", ErrorType.HTTP_ERROR);
+    };
+    ErrorData.fromGeneric = function (context, errorCode, errorType) {
+        if (errorType === void 0) { errorType = ErrorType.SERVER_ERROR; }
+        var UNKNOWN = "UNKNOWN";
+        var getMsg = this.getMsg;
+        var source = getMsg(context, Const_1.SOURCE);
+        var errorName = getMsg(context, Const_1.ERROR_NAME);
+        var errorMessage = getMsg(context, Const_1.ERROR_MESSAGE);
+        var status = getMsg(context, Const_1.STATUS);
+        var responseText = getMsg(context, Const_1.RESPONSE_TEXT);
+        var responseXML = getMsg(context, Const_1.RESPONSE_XML);
+        return new ErrorData(source, name, errorMessage, responseText, responseXML, errorCode + Const_1.EMPTY_STR, status, errorType);
+    };
+    ErrorData.getMsg = function (context, param) {
+        var UNKNOWN = "UNKNOWN";
+        return getMessage(context.getIf(param).orElse(UNKNOWN).value);
+    };
+    ErrorData.fromServerError = function (context) {
+        return this.fromGeneric(context, -1);
+    };
+    return ErrorData;
+}(EventData_1.EventData));
+exports.ErrorData = ErrorData;
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/xhrCore/EventData.ts":
+/*!*******************************************************!*\
+  !*** ./src/main/typescript/impl/xhrCore/EventData.ts ***!
+  \*******************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", { value: true });
+var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
+var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
+var EventData = /** @class */ (function () {
+    function EventData() {
+    }
+    EventData.createFromRequest = function (request, context, /*event name*/ name) {
+        var _a, _b, _c, _d;
+        var eventData = new EventData();
+        eventData.type = Const_1.EVENT;
+        eventData.status = name;
+        var sourceId = context.getIf(Const_1.SOURCE)
+            .orElse(context.getIf(Const_1.P_PARTIAL_SOURCE).value)
+            .orElse(context.getIf(Const_1.CTX_PARAM_PASS_THR, Const_1.P_PARTIAL_SOURCE).value).value;
+        if (sourceId) {
+            eventData.source = monadish_1.DQ.byId(sourceId).first().value.value;
+        }
+        if (name !== Const_1.BEGIN) {
+            eventData.responseCode = (_b = (_a = request) === null || _a === void 0 ? void 0 : _a.status) === null || _b === void 0 ? void 0 : _b.toString();
+            eventData.responseText = (_c = request) === null || _c === void 0 ? void 0 : _c.responseText;
+            eventData.responseXML = (_d = request) === null || _d === void 0 ? void 0 : _d.responseXML;
+        }
+        return eventData;
+    };
+    return EventData;
+}());
+exports.EventData = EventData;
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/xhrCore/RequestDataResolver.ts":
+/*!*****************************************************************!*\
+  !*** ./src/main/typescript/impl/xhrCore/RequestDataResolver.ts ***!
+  \*****************************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
+var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
+var Lang_1 = __webpack_require__(/*! ../util/Lang */ "./src/main/typescript/impl/util/Lang.ts");
+var ExtDomQuery_1 = __webpack_require__(/*! ../util/ExtDomQuery */ "./src/main/typescript/impl/util/ExtDomQuery.ts");
+/**
+ * Resolver functions for various aspects of the request data
+ *
+ * stateless because it might be called from various
+ * parts of the response classes
+ */
+/**
+ * resolves the event handlers lazly
+ * so that if some decoration happens in between we can deal with it
+ *
+ * @param funcName
+ */
+function resolveHandlerFunc(requestContext, responseContext, funcName) {
+    return responseContext.getIf(funcName)
+        .orElse(requestContext.getIf(funcName).value)
+        .orElse(Const_1.EMPTY_FUNC).value;
+}
+exports.resolveHandlerFunc = resolveHandlerFunc;
+function resolveTargetUrl(srcFormElement) {
+    return (typeof srcFormElement.elements[Const_1.ENCODED_URL] == 'undefined') ?
+        srcFormElement.action :
+        srcFormElement.elements[Const_1.ENCODED_URL].value;
+}
+exports.resolveTargetUrl = resolveTargetUrl;
+function resolveFinalUrl(sourceForm, formData, ajaxType) {
+    if (ajaxType === void 0) { ajaxType = Const_1.REQ_TYPE_POST; }
+    var targetUrl = this.resolveTargetUrl(sourceForm.getAsElem(0).value);
+    return targetUrl + (ajaxType == Const_1.REQ_TYPE_GET ? "?" + formData.toString() : Const_1.EMPTY_STR);
+}
+exports.resolveFinalUrl = resolveFinalUrl;
+/**
+ * form resolution the same way our old implementation did
+ * it is either the id or the parent form of the element or an embedded form
+ * of the element
+ *
+ * @param requestCtx
+ * @param elem
+ * @param event
+ */
+function resolveForm(requestCtx, elem, event) {
+    var _a, _b, _c;
+    var configId = (_c = (_b = (_a = requestCtx.value) === null || _a === void 0 ? void 0 : _a.myfaces) === null || _b === void 0 ? void 0 : _b.form, (_c !== null && _c !== void 0 ? _c : Const_1.MF_NONE)); //requestCtx.getIf(MYFACES, "form").orElse(MF_NONE).value;
+    return monadish_1.DQ
+        .byId(configId)
+        .orElseLazy(function () { return Lang_1.ExtLang.getForm(elem.getAsElem(0).value, event); });
+}
+exports.resolveForm = resolveForm;
+function resolveTimeout(options) {
+    var _a;
+    var getCfg = Lang_1.ExtLang.getLocalOrGlobalConfig;
+    return _a = options.getIf(Const_1.CTX_PARAM_TIMEOUT).value, (_a !== null && _a !== void 0 ? _a : getCfg(options.value, Const_1.CTX_PARAM_TIMEOUT, 0));
+}
+exports.resolveTimeout = resolveTimeout;
+/**
+ * resolve the delay from the options and/or the request context and or the configuration
+ *
+ * @param options ... the options object, in most cases it will host the delay value
+ */
+function resolveDelay(options) {
+    var _a;
+    var getCfg = Lang_1.ExtLang.getLocalOrGlobalConfig;
+    return _a = options.getIf(Const_1.CTX_PARAM_DELAY).value, (_a !== null && _a !== void 0 ? _a : getCfg(options.value, Const_1.CTX_PARAM_DELAY, 0));
+}
+exports.resolveDelay = resolveDelay;
+/**
+ * resolves the window Id from various sources
+ *
+ * @param options
+ */
+function resolveWindowId(options) {
+    var _a, _b, _c;
+    return _c = (_b = (_a = options) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.windowId, (_c !== null && _c !== void 0 ? _c : ExtDomQuery_1.ExtDomquery.windowId);
+}
+exports.resolveWindowId = resolveWindowId;
+/**
+ * determines the correct event depending
+ * on the browsers state
+ *
+ * @param evt incoming event object (note not all browsers
+ * have this)
+ *
+ * @return an event object no matter what is incoming
+ */
+function resolveEvent(evt) {
+    var _a, _b;
+    return _b = (evt !== null && evt !== void 0 ? evt : (_a = window) === null || _a === void 0 ? void 0 : _a.event), (_b !== null && _b !== void 0 ? _b : {});
+}
+exports.resolveEvent = resolveEvent;
+/**
+ * cross port from the dojo lib
+ * browser save event resolution
+ * @param evt the event object
+ * (with a fallback for ie events if none is present)
+ */
+function getEventTarget(evt) {
+    var _a, _b, _c, _d, _e;
+    //ie6 and 7 fallback
+    var finalEvent = this.resolveEvent(evt);
+    /**
+     * evt source is defined in the jsf events
+     * seems like some component authors use our code
+     * so we add it here see also
+     * https://issues.apache.org/jira/browse/MYFACES-2458
+     * not entirely a bug but makes sense to add this
+     * behavior. I dont use it that way but nevertheless it
+     * does not break anything so why not
+     * */
+    var t = (_d = (_b = (_a = finalEvent) === null || _a === void 0 ? void 0 : _a.srcElement, (_b !== null && _b !== void 0 ? _b : (_c = finalEvent) === null || _c === void 0 ? void 0 : _c.target)), (_d !== null && _d !== void 0 ? _d : (_e = finalEvent) === null || _e === void 0 ? void 0 : _e.source));
+    while ((t) && (t.nodeType != 1)) {
+        t = t.parentNode;
+    }
+    return t;
+}
+exports.getEventTarget = getEventTarget;
+/**
+ * resolves a bunch of default values
+ * which can be further processed from the given
+ * call parameters of jsf.ajax.request
+ *
+ * @param event
+ * @param opts
+ * @param el
+ */
+function resolveDefaults(event, opts, el) {
+    if (opts === void 0) { opts = {}; }
+    if (el === void 0) { el = null; }
+    var _a;
+    var resolvedEvent = resolveEvent(event);
+    //deep copy the options, so that further transformations to not backfire into the callers
+    var options = new monadish_1.Config(opts).deepCopy;
+    var elem = monadish_1.DQ.byId(el || resolvedEvent.target);
+    var elementId = elem.id;
+    var requestCtx = new monadish_1.Config({});
+    var internalCtx = new monadish_1.Config({});
+    var windowId = resolveWindowId(options);
+    var isResetValues = true === ((_a = options.value) === null || _a === void 0 ? void 0 : _a.resetValues);
+    return { resolvedEvent: resolvedEvent, options: options, elem: elem, elementId: elementId, requestCtx: requestCtx, internalCtx: internalCtx, windowId: windowId, isResetValues: isResetValues };
+}
+exports.resolveDefaults = resolveDefaults;
+;
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/xhrCore/ResonseDataResolver.ts":
+/*!*****************************************************************!*\
+  !*** ./src/main/typescript/impl/xhrCore/ResonseDataResolver.ts ***!
+  \*****************************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
+var Assertions_1 = __webpack_require__(/*! ../util/Assertions */ "./src/main/typescript/impl/util/Assertions.ts");
+var monadish_2 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
+var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
+/**
+ * Resolver functions for various aspects of the response data
+ *
+ * stateless because it might be called from various
+ * parts of the response classes
+ */
+/**
+ * fetches the response XML
+ * as XML Query object
+ *
+ * @param request the request hosting the responseXML
+ *
+ * Throws an error in case of non existent or wrong xml data
+ *
+ */
+function resolveResponseXML(request) {
+    var ret = new monadish_1.XMLQuery(request.getIf(Const_1.SEL_RESPONSE_XML).value);
+    Assertions_1.Assertions.assertValidXMLResponse(ret);
+    return ret;
+}
+exports.resolveResponseXML = resolveResponseXML;
+/**
+ * Splits the incoming passthrough context apart
+ * in an internal and an external nomalized context
+ * the internal one is just for our internal processing
+ *
+ * @param context the root context as associative array
+ */
+function resolveContexts(context) {
+    /**
+     * we split the context apart into the external one and
+     * some internal values
+     */
+    var externalContext = monadish_1.Config.fromNullable(context);
+    var internalContext = externalContext.getIf(Const_1.CTX_PARAM_MF_INTERNAL);
+    if (!internalContext.isPresent()) {
+        internalContext = monadish_1.Config.fromNullable({});
+    }
+    /**
+     * prepare storage for some deferred operations
+     */
+    internalContext.assign(Const_1.UPDATE_FORMS).value = [];
+    internalContext.assign(Const_1.UPDATE_ELEMS).value = [];
+    return { externalContext: externalContext, internalContext: internalContext };
+}
+exports.resolveContexts = resolveContexts;
+/**
+ * fetches the source element out of our conexts
+ *
+ * @param context the external context which shpuld host the source id
+ * @param internalContext internal passthrough fall back
+ *
+ */
+function resolveSourceElement(context, internalContext) {
+    var elemId = resolveSourceElementId(context, internalContext);
+    return monadish_2.DQ.byId(elemId.value);
+}
+exports.resolveSourceElement = resolveSourceElement;
+/**
+ * fetches the source form if it still exists
+ * also embedded forms and parent forms are taken into consideration
+ * as fallbacks
+ *
+ * @param internalContext
+ * @param elem
+ */
+function resolveSourceForm(internalContext, elem) {
+    var sourceFormId = internalContext.getIf(Const_1.CTX_PARAM_SRC_FRM_ID);
+    var sourceForm = new monadish_2.DQ(sourceFormId.isPresent() ? document.forms[sourceFormId.value] : null);
+    sourceForm = sourceForm.orElse(elem.parents(Const_1.TAG_FORM))
+        .orElse(elem.querySelectorAll(Const_1.TAG_FORM))
+        .orElse(monadish_2.DQ.querySelectorAll(Const_1.TAG_FORM));
+    return sourceForm;
+}
+exports.resolveSourceForm = resolveSourceForm;
+function resolveSourceElementId(context, internalContext) {
+    //?internal context?? used to be external one
+    return internalContext.getIf(Const_1.CTX_PARAM_SRC_CTL_ID)
+        .orElseLazy(function () { return context.getIf(Const_1.SOURCE, "id").value; });
+}
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/xhrCore/Response.ts":
+/*!******************************************************!*\
+  !*** ./src/main/typescript/impl/xhrCore/Response.ts ***!
+  \******************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
+var ResponseProcessor_1 = __webpack_require__(/*! ./ResponseProcessor */ "./src/main/typescript/impl/xhrCore/ResponseProcessor.ts");
+var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
+var ResonseDataResolver_1 = __webpack_require__(/*! ./ResonseDataResolver */ "./src/main/typescript/impl/xhrCore/ResonseDataResolver.ts");
+var Response;
+(function (Response) {
+    /**
+     * Standardized jsf.js response
+     * this one is called straight from jsf.js.response
+     *
+     * The processing follows the spec by going for the responseXML
+     * and processing its tags
+     *
+     * @param {XMLHttpRequest} request (xhrRequest) - xhr request object
+     * @param {[key: string]: any} context (Map) - AJAX context
+     *
+     */
+    function processResponse(request, context) {
+        var req = monadish_1.Config.fromNullable(request);
+        var _a = ResonseDataResolver_1.resolveContexts(context), externalContext = _a.externalContext, internalContext = _a.internalContext;
+        var responseXML = ResonseDataResolver_1.resolveResponseXML(req);
+        var responseProcessor = new ResponseProcessor_1.ResponseProcessor(req, externalContext, internalContext);
+        internalContext.assign(Const_1.RESPONSE_XML).value = responseXML;
+        //we now process the partial tags, or in none given raise an error
+        responseXML.querySelectorAll(Const_1.RESP_PARTIAL)
+            .each(function (item) { return processPartialTag(item, responseProcessor, internalContext); });
+        //we now process the viewstates and the evals deferred
+        //the reason for this is that often it is better
+        //to wait until the document has caught up before
+        //doing any evals even on embedded scripts
+        responseProcessor.fixViewStates();
+        responseProcessor.globalEval();
+        responseProcessor.done();
+    }
+    Response.processResponse = processResponse;
+    /**
+     * highest node partial-response from there the main operations are triggered
+     */
+    function processPartialTag(node, responseProcessor, internalContext) {
+        internalContext.assign(Const_1.PARTIAL_ID).value = node.id;
+        var SEL_SUB_TAGS = [Const_1.CMD_ERROR, Const_1.CMD_REDIRECT, Const_1.CMD_CHANGES].join(",");
+        //now we can process the main operations
+        node.getIf(SEL_SUB_TAGS).each(function (node) {
+            switch (node.tagName.value) {
+                case Const_1.CMD_ERROR:
+                    responseProcessor.error(node);
+                    break;
+                case Const_1.CMD_REDIRECT:
+                    responseProcessor.redirect(node);
+                    break;
+                case Const_1.CMD_CHANGES:
+                    processChangesTag(node, responseProcessor);
+                    break;
+            }
+        });
+    }
+    var processInsert = function (responseProcessor, node) {
+        //path1 insert after as child tags
+        if (node.querySelectorAll([Const_1.TAG_BEFORE, Const_1.TAG_AFTER].join(",")).length) {
+            responseProcessor.insertWithSubtags(node);
+        }
+        else { //insert before after with id
+            responseProcessor.insert(node);
+        }
+    };
+    /**
+     * next level changes tag
+     *
+     * @param node
+     * @param responseProcessor
+     */
+    function processChangesTag(node, responseProcessor) {
+        var ALLOWED_TAGS = [Const_1.CMD_UPDATE, Const_1.CMD_EVAL, Const_1.CMD_INSERT, Const_1.CMD_DELETE, Const_1.CMD_ATTRIBUTES, Const_1.CMD_EXTENSION].join(",");
+        node.getIf(ALLOWED_TAGS).each(function (node) {
+            switch (node.tagName.value) {
+                case Const_1.CMD_UPDATE:
+                    processUpdateTag(node, responseProcessor);
+                    break;
+                case Const_1.CMD_EVAL:
+                    responseProcessor.eval(node);
+                    break;
+                case Const_1.CMD_INSERT:
+                    processInsert(responseProcessor, node);
+                    break;
+                case Const_1.CMD_DELETE:
+                    responseProcessor.delete(node);
+                    break;
+                case Const_1.CMD_ATTRIBUTES:
+                    responseProcessor.attributes(node);
+                    break;
+                case Const_1.CMD_EXTENSION:
+                    break;
+            }
+        });
+        return true;
+    }
+    /**
+     * branch tag update.. drill further down into the updates
+     * special case viewstate in that case it is a leaf
+     * and the viewstate must be processed
+     *
+     * @param node
+     * @param responseProcessor
+     */
+    function processUpdateTag(node, responseProcessor) {
+        if (!responseProcessor.processViewState(node)) {
+            handleElementUpdate(node, responseProcessor);
+        }
+    }
+    /**
+     * element update
+     *
+     * @param node
+     * @param responseProcessor
+     */
+    function handleElementUpdate(node, responseProcessor) {
+        var cdataBlock = node.cDATAAsString;
+        switch (node.id.value) {
+            case Const_1.P_VIEWROOT:
+                responseProcessor.replaceViewRoot(monadish_1.DQ.fromMarkup(cdataBlock.substring(cdataBlock.indexOf("<html"))));
+                break;
+            case Const_1.P_VIEWHEAD:
+                responseProcessor.replaceHead(monadish_1.DQ.fromMarkup(cdataBlock));
+                break;
+            case Const_1.P_VIEWBODY:
+                responseProcessor.replaceBody(monadish_1.DQ.fromMarkup(cdataBlock));
+                break;
+            default: //htmlItem replacement
+                responseProcessor.update(node, cdataBlock);
+                break;
+        }
+    }
+})(Response = exports.Response || (exports.Response = {}));
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/xhrCore/ResponseProcessor.ts":
+/*!***************************************************************!*\
+  !*** ./src/main/typescript/impl/xhrCore/ResponseProcessor.ts ***!
+  \***************************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var __spreadArrays = (this && this.__spreadArrays) || function () {
+    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
+    for (var r = Array(s), k = 0, i = 0; i < il; i++)
+        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
+            r[k] = a[j];
+    return r;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
+var AjaxImpl_1 = __webpack_require__(/*! ../AjaxImpl */ "./src/main/typescript/impl/AjaxImpl.ts");
+var Assertions_1 = __webpack_require__(/*! ../util/Assertions */ "./src/main/typescript/impl/util/Assertions.ts");
+var ErrorData_1 = __webpack_require__(/*! ./ErrorData */ "./src/main/typescript/impl/xhrCore/ErrorData.ts");
+var ImplTypes_1 = __webpack_require__(/*! ../core/ImplTypes */ "./src/main/typescript/impl/core/ImplTypes.ts");
+var EventData_1 = __webpack_require__(/*! ./EventData */ "./src/main/typescript/impl/xhrCore/EventData.ts");
+var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
+var trim = monadish_1.Lang.trim;
+/**
+ * Response processor
+ *
+ * Each  XML tag is either a node or a leaf
+ * or both
+ *
+ * the processor provides a set of operations
+ * which are executed on a single leaf node per operation
+ * and present the core functionality of our response
+ *
+ * Note the response processor is stateful hence we bundle it in a class
+ * to reduce code we keep references tot contexts in place
+ */
+var ResponseProcessor = /** @class */ (function () {
+    function ResponseProcessor(request, externalContext, internalContext) {
+        this.request = request;
+        this.externalContext = externalContext;
+        this.internalContext = internalContext;
+    }
+    ResponseProcessor.prototype.replaceHead = function (shadowDocument) {
+        var shadowHead = shadowDocument.querySelectorAll(Const_1.TAG_HEAD);
+        if (!shadowHead.isPresent()) {
+            return;
+        }
+        var oldHead = monadish_1.DQ.querySelectorAll(Const_1.TAG_HEAD);
+        //delete all to avoid script and style overlays
+        oldHead.querySelectorAll(Const_1.SEL_SCRIPTS_STYLES).delete();
+        this.storeForEval(shadowHead);
+    };
+    /**
+     * replaces the body in the expected manner
+     * which means the entire body content is refreshed
+     * however also the body attributes must be transferred
+     * keeping event handlers etc... in place
+     *
+     * @param shadowDocument .. an incoming shadow document hosting the new nodes
+     */
+    ResponseProcessor.prototype.replaceBody = function (shadowDocument) {
+        var shadowBody = shadowDocument.querySelectorAll(Const_1.TAG_BODY);
+        if (!shadowBody.isPresent()) {
+            return;
+        }
+        var shadowInnerHTML = shadowBody.html().value;
+        var resultingBody = monadish_1.DQ.querySelectorAll(Const_1.TAG_BODY).html(shadowInnerHTML);
+        var updateForms = resultingBody.querySelectorAll(Const_1.TAG_FORM);
+        resultingBody.copyAttrs(shadowBody);
+        this.storeForPostProcessing(updateForms, resultingBody);
+    };
+    /**
+     * Leaf Tag eval... process whatever is in the evals cdata block
+     *
+     * @param node the node to eval
+     */
+    ResponseProcessor.prototype.eval = function (node) {
+        monadish_1.DQ.globalEval(node.cDATAAsString);
+    };
+    /**
+     * processes an incoming error from the response
+     * which is hosted under the &lt;error&gt; tag
+     * @param node the node hosting the error in our response xml
+     * @param node the node in the xml hosting the error message
+     */
+    ResponseProcessor.prototype.error = function (node) {
+        /**
+         * <error>
+         *      <error-name>String</error-name>
+         *      <error-message><![CDATA[message]]></error-message>
+         * <error>
+         */
+        var mergedErrorData = new monadish_1.Config({});
+        mergedErrorData.assign(Const_1.SOURCE).value = this.externalContext.getIf(Const_1.P_PARTIAL_SOURCE).get(0).value;
+        mergedErrorData.assign(Const_1.ERROR_NAME).value = node.getIf(Const_1.ERROR_NAME).textContent(Const_1.EMPTY_STR);
+        mergedErrorData.assign(Const_1.ERROR_MESSAGE).value = node.getIf(Const_1.ERROR_MESSAGE).cDATAAsString;
+        var hasResponseXML = this.internalContext.get(Const_1.RESPONSE_XML).isPresent();
+        mergedErrorData.assignIf(hasResponseXML, Const_1.RESPONSE_XML).value = this.internalContext.getIf(Const_1.RESPONSE_XML).value.get(0).value;
+        var errorData = ErrorData_1.ErrorData.fromServerError(mergedErrorData);
+        this.externalContext.getIf(Const_1.ON_ERROR).orElse(this.internalContext.getIf(Const_1.ON_ERROR).value).orElse(Const_1.EMPTY_FUNC).value(errorData);
+        AjaxImpl_1.Implementation.sendError(errorData);
+    };
+    /**
+     * process the redirect operation
+     *
+     * @param node
+     */
+    ResponseProcessor.prototype.redirect = function (node) {
+        Assertions_1.Assertions.assertUrlExists(node);
+        var redirectUrl = trim(node.attr(Const_1.ATTR_URL).value);
+        if (redirectUrl != Const_1.EMPTY_STR) {
+            window.location.href = redirectUrl;
+        }
+    };
+    /**
+     * processes the update operation and updates the node with the cdata block
+     * @param node the xml response node hosting the update info
+     * @param cdataBlock the cdata block with the new html code
+     */
+    ResponseProcessor.prototype.update = function (node, cdataBlock) {
+        var _a;
+        var result = monadish_1.DQ.byId(node.id.value).outerHTML(cdataBlock, false, false);
+        var sourceForm = (_a = result) === null || _a === void 0 ? void 0 : _a.parents(Const_1.TAG_FORM).orElse(result.byTagName(Const_1.TAG_FORM, true));
+        if (sourceForm) {
+            this.storeForPostProcessing(sourceForm, result);
+        }
+    };
+    ResponseProcessor.prototype.delete = function (node) {
+        monadish_1.DQ.byId(node.id.value).delete();
+    };
+    /**
+     * attributes leaf tag... process the attributes
+     *
+     * @param node
+     */
+    ResponseProcessor.prototype.attributes = function (node) {
+        var elem = monadish_1.DQ.byId(node.id.value);
+        node.byTagName(Const_1.TAG_ATTR).each(function (item) {
+            elem.attr(item.attr(Const_1.ATTR_NAME).value).value = item.attr(Const_1.ATTR_VALUE).value;
+        });
+    };
+    /**
+     * @param shadowDocument a shadow document which is needed for further processing
+     */
+    ResponseProcessor.prototype.replaceViewRoot = function (shadowDocument) {
+        this.replaceHead(shadowDocument);
+        this.replaceBody(shadowDocument);
+    };
+    /**
+     * insert handling, either before or after
+     *
+     * @param node
+     */
+    ResponseProcessor.prototype.insert = function (node) {
+        //let insertId = node.id; //not used atm
+        var before = node.attr(Const_1.TAG_BEFORE);
+        var after = node.attr(Const_1.TAG_AFTER);
+        var insertNodes = monadish_1.DQ.fromMarkup(node.cDATAAsString);
+        if (before.isPresent()) {
+            monadish_1.DQ.byId(before.value).insertBefore(insertNodes);
+            this.internalContext.assign(Const_1.UPDATE_ELEMS).value.push(insertNodes);
+        }
+        if (after.isPresent()) {
+            var domQuery = monadish_1.DQ.byId(after.value);
+            domQuery.insertAfter(insertNodes);
+            this.internalContext.assign(Const_1.UPDATE_ELEMS).value.push(insertNodes);
+        }
+    };
+    /**
+     * handler for the case &lt;insert <&lt; before id="...
+     *
+     * @param node the node hosting the insert data
+     */
+    ResponseProcessor.prototype.insertWithSubtags = function (node) {
+        var _this = this;
+        var before = node.querySelectorAll(Const_1.TAG_BEFORE);
+        var after = node.querySelectorAll(Const_1.TAG_AFTER);
+        before.each(function (item) {
+            var insertId = item.attr(Const_1.ATTR_ID);
+            var insertNodes = monadish_1.DQ.fromMarkup(item.cDATAAsString);
+            if (insertId.isPresent()) {
+                monadish_1.DQ.byId(insertId.value).insertBefore(insertNodes);
+                _this.internalContext.assign(Const_1.UPDATE_ELEMS).value.push(insertNodes);
+            }
+        });
+        after.each(function (item) {
+            var insertId = item.attr(Const_1.ATTR_ID);
+            var insertNodes = monadish_1.DQ.fromMarkup(item.cDATAAsString);
+            if (insertId.isPresent()) {
+                monadish_1.DQ.byId(insertId.value).insertAfter(insertNodes);
+                _this.internalContext.assign(Const_1.UPDATE_ELEMS).value.push(insertNodes);
+            }
+        });
+    };
+    /**
+     * process the viewState update, update the affected
+     * forms with their respective new viewstate values
+     *
+     */
+    ResponseProcessor.prototype.processViewState = function (node) {
+        if (ResponseProcessor.isViewStateNode(node)) {
+            var viewStateValue = node.cDATAAsString;
+            this.internalContext.assign(Const_1.APPLIED_VST, node.id.value).value = new ImplTypes_1.ViewState(node.id.value, viewStateValue);
+            return true;
+        }
+        return false;
+    };
+    /**
+     * generic global eval which runs the embedded css and scripts
+     */
+    ResponseProcessor.prototype.globalEval = function () {
+        var updateElems = new (monadish_1.DQ.bind.apply(monadish_1.DQ, __spreadArrays([void 0], this.internalContext.getIf(Const_1.UPDATE_ELEMS).value)))();
+        updateElems.runCss();
+        updateElems.runScripts();
+    };
+    /**
+     * post processing viewstate fixing
+     */
+    ResponseProcessor.prototype.fixViewStates = function () {
+        var _this = this;
+        monadish_1.Stream.ofAssoc(this.internalContext.getIf(Const_1.APPLIED_VST).orElse({}).value)
+            .each(function (item) {
+            var value = item[1];
+            var nameSpace = monadish_1.DQ.byId(value.nameSpace).orElse(document.body);
+            var affectedForms = nameSpace.byTagName(Const_1.TAG_FORM);
+            var affectedForms2 = nameSpace.filter(function (item) { return item.tagName.orElse(Const_1.EMPTY_STR).value.toLowerCase() == Const_1.TAG_FORM; });
+            _this.appendViewStateToForms(new monadish_1.DomQuery(affectedForms, affectedForms2), value.value);
+        });
+    };
+    /**
+     * all processing done we can close the request and send the appropriate events
+     */
+    ResponseProcessor.prototype.done = function () {
+        var eventData = EventData_1.EventData.createFromRequest(this.request.value, this.externalContext, Const_1.SUCCESS);
+        //because some frameworks might decorate them over the context in the response
+        var eventHandler = this.externalContext.getIf(Const_1.ON_EVENT).orElse(this.internalContext.getIf(Const_1.ON_EVENT).value).orElse(Const_1.EMPTY_FUNC).value;
+        AjaxImpl_1.Implementation.sendEvent(eventData, eventHandler);
+    };
+    /**
+     * proper viewstate -> form assignment
+     *
+     * @param forms the forms to append the viewstate to
+     * @param viewState the final viewstate
+     */
+    ResponseProcessor.prototype.appendViewStateToForms = function (forms, viewState) {
+        forms.each(function (form) {
+            var viewStateElems = form.querySelectorAll(Const_1.SEL_VIEWSTATE_ELEM)
+                .orElseLazy(function () { return ResponseProcessor.newViewStateElement(form); });
+            viewStateElems.attr("value").value = viewState;
+        });
+    };
+    /**
+     * Helper to Create a new JSF ViewState Element
+     *
+     * @param parent, the parent node to attach the viewstate element to
+     * (usually a form node)
+     */
+    ResponseProcessor.newViewStateElement = function (parent) {
+        var newViewState = monadish_1.DQ.fromMarkup(Const_1.HTML_VIEWSTATE);
+        newViewState.appendTo(parent);
+        return newViewState;
+    };
+    /**
+     * Stores certain aspects of the dom for later post processing
+     *
+     * @param updateForms the update forms which should receive standardized internal jsf data
+     * @param toBeEvaled the resulting elements which should be evaled
+     */
+    ResponseProcessor.prototype.storeForPostProcessing = function (updateForms, toBeEvaled) {
+        this.storeForUpdate(updateForms);
+        this.storeForEval(toBeEvaled);
+    };
+    /**
+     * helper to store a given form for the update post processing (viewstate)
+     *
+     * @param updateForms the dom query object pointing to the forms which need to be updated
+     */
+    ResponseProcessor.prototype.storeForUpdate = function (updateForms) {
+        this.internalContext.assign(Const_1.UPDATE_FORMS).value.push(updateForms);
+    };
+    /**
+     * same for eval (js and css)
+     *
+     * @param toBeEvaled
+     */
+    ResponseProcessor.prototype.storeForEval = function (toBeEvaled) {
+        this.internalContext.assign(Const_1.UPDATE_ELEMS).value.push(toBeEvaled);
+    };
+    /**
+     * check whether a given XMLQuery node is an explicit viewstate node
+     *
+     * @param node the node to check
+     * @returns true of it ii
+     */
+    ResponseProcessor.isViewStateNode = function (node) {
+        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
+        var separatorChar = window.jsf.separatorchar;
+        return "undefined" != typeof ((_b = (_a = node) === null || _a === void 0 ? void 0 : _a.id) === null || _b === void 0 ? void 0 : _b.value) && (((_d = (_c = node) === null || _c === void 0 ? void 0 : _c.id) === null || _d === void 0 ? void 0 : _d.value) == Const_1.P_VIEWSTATE ||
+            ((_g = (_f = (_e = node) === null || _e === void 0 ? void 0 : _e.id) === null || _f === void 0 ? void 0 : _f.value) === null || _g === void 0 ? void 0 : _g.indexOf([separatorChar, Const_1.P_VIEWSTATE].join(Const_1.EMPTY_STR))) != -1 ||
+            ((_k = (_j = (_h = node) === null || _h === void 0 ? void 0 : _h.id) === null || _j === void 0 ? void 0 : _j.value) === null || _k === void 0 ? void 0 : _k.indexOf([Const_1.P_VIEWSTATE, separatorChar].join(Const_1.EMPTY_STR))) != -1);
+    };
+    return ResponseProcessor;
+}());
+exports.ResponseProcessor = ResponseProcessor;
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/xhrCore/XhrFormData.ts":
+/*!*********************************************************!*\
+  !*** ./src/main/typescript/impl/xhrCore/XhrFormData.ts ***!
+  \*********************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+var __spreadArrays = (this && this.__spreadArrays) || function () {
+    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
+    for (var r = Array(s), k = 0, i = 0; i < il; i++)
+        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
+            r[k] = a[j];
+    return r;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
+var monadish_2 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
+var monadish_3 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
+var isString = monadish_1.Lang.isString;
+var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
+/**
+ * A unified form data class
+ * which builds upon our configuration.
+ *
+ * We cannot use standard html5 forms everywhere
+ * due to api constraints on the HTML Form object in IE11
+ * and due to the url encoding constraint given by the jsf.js spec
+ */
+var XhrFormData = /** @class */ (function (_super) {
+    __extends(XhrFormData, _super);
+    /**
+     * data collector from a given form
+     *
+     * @param dataSource either a form as DomQuery object or an encoded url string
+     * @param partialIdsArray partial ids to collect, to reduce the data sent down
+     */
+    function XhrFormData(dataSource, partialIdsArray, encode) {
+        if (encode === void 0) { encode = true; }
+        var _this = _super.call(this, {}) || this;
+        _this.dataSource = dataSource;
+        _this.partialIdsArray = partialIdsArray;
+        _this.encode = encode;
+        //a call to getViewState before must pass the encoded line
+        //a call from getViewState passes the form element as datasource
+        //so we have two call points
+        if (isString(dataSource)) {
+            _this.assignEncodedString(_this.dataSource);
+        }
+        else {
+            _this.handleFormSource();
+        }
+        return _this;
+    }
+    XhrFormData.prototype.handleFormSource = function () {
+        //encode and append the issuing item if not a partial ids array of ids is passed
+        /*
+         * Spec. 13.3.1
+         * Collect and encode input elements.
+         * Additionally the hidden element javax.faces.ViewState
+         * Enhancement partial page submit
+         *
+         */
+        this.encodeSubmittableFields(this, this.dataSource, this.partialIdsArray);
+        if (this.getIf(Const_1.P_VIEWSTATE).isPresent()) {
+            return;
+        }
+        this.applyViewState(this.dataSource);
+    };
+    /**
+     * special case viewstate handling
+     *
+     * @param form the form holding the viewstate value
+     */
+    XhrFormData.prototype.applyViewState = function (form) {
+        var viewState = form.byId(Const_1.P_VIEWSTATE).inputValue;
+        this.assignIf(viewState.isPresent(), Const_1.P_VIEWSTATE).value = viewState.value;
+    };
+    /**
+     * assignes a url encoded string to this xhrFormData object
+     * as key value entry
+     * @param encoded
+     */
+    XhrFormData.prototype.assignEncodedString = function (encoded) {
+        var _this = this;
+        var keyValueEntries = encoded.split(/&/gi);
+        monadish_2.Stream.of.apply(monadish_2.Stream, keyValueEntries).map(function (line) { return line.split(/=(.*)/gi); })
+            //special case of having keys without values
+            .map(function (keyVal) { var _a, _b, _c, _d; return keyVal.length < 3 ? [(_b = (_a = keyVal) === null || _a === void 0 ? void 0 : _a[0], (_b !== null && _b !== void 0 ? _b : [])), (_d = (_c = keyVal) === null || _c === void 0 ? void 0 : _c[1], (_d !== null && _d !== void 0 ? _d : []))] : keyVal; })
+            .each(function (keyVal) {
+            var _a, _b, _c;
+            _this.assign(keyVal[0]).value = (_c = (_b = (_a = keyVal) === null || _a === void 0 ? void 0 : _a.splice(1)) === null || _b === void 0 ? void 0 : _b.join(""), (_c !== null && _c !== void 0 ? _c : ""));
+        });
+    };
+    // noinspection JSUnusedGlobalSymbols
+    /**
+     * @returns a Form data representation
+     */
+    XhrFormData.prototype.toFormData = function () {
+        var ret = new FormData();
+        for (var key in this.value) {
+            if (this.value.hasOwnProperty(key)) {
+                ret.append(key, this.value[key]);
+            }
+        }
+        return ret;
+    };
+    /**
+     * returns an encoded string representation of our xhr form data
+     *
+     * @param defaultStr optional default value if nothing is there to encode
+     */
+    XhrFormData.prototype.toString = function (defaultStr) {
+        if (defaultStr === void 0) { defaultStr = Const_1.EMPTY_STR; }
+        if (this.isAbsent()) {
+            return defaultStr;
+        }
+        var entries = [];
+        for (var key in this.value) {
+            if (this.value.hasOwnProperty(key)) {
+                //key value already encoded so no need to reencode them again
+                entries.push(encodeURIComponent(key) + "=" + encodeURIComponent(this.value[key]));
+            }
+        }
+        return entries.join("&");
+    };
+    /**
+     * determines fields to submit
+     * @param {Object} targetBuf - the target form buffer receiving the data
+     * @param {Node} parentItem - form element item is nested in
+     * @param {Array} partialIds - ids fo PPS
+     */
+    XhrFormData.prototype.encodeSubmittableFields = function (targetBuf, parentItem, partialIds) {
+        var toEncode = null;
+        if (this.partialIdsArray && this.partialIdsArray.length) {
+            //in case of our myfaces reduced ppr we only
+            //only submit the partials
+            this._value = {};
+            toEncode = new (monadish_3.DQ.bind.apply(monadish_3.DQ, __spreadArrays([void 0], this.partialIdsArray)))();
+        }
+        else {
+            if (parentItem.isAbsent())
+                throw "NO_PARITEM";
+            toEncode = parentItem;
+        }
+        //lets encode the form elements
+        this.shallowMerge(toEncode.querySelectorAll("input, checkbox, select, textarea").encodeFormElement());
+    };
+    Object.defineProperty(XhrFormData.prototype, "isMultipartRequest", {
+        /**
+         * checks if the given datasource is a multipart request source
+         */
+        get: function () {
+            return this.dataSource instanceof monadish_3.DQ && this.dataSource.querySelectorAll("input[type='file']").isPresent();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    return XhrFormData;
+}(monadish_1.Config));
+exports.XhrFormData = XhrFormData;
+
+
+/***/ }),
+
+/***/ "./src/main/typescript/impl/xhrCore/XhrRequest.ts":
+/*!********************************************************!*\
+  !*** ./src/main/typescript/impl/xhrCore/XhrRequest.ts ***!
+  \********************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
+var AjaxImpl_1 = __webpack_require__(/*! ../AjaxImpl */ "./src/main/typescript/impl/AjaxImpl.ts");
+var XhrFormData_1 = __webpack_require__(/*! ./XhrFormData */ "./src/main/typescript/impl/xhrCore/XhrFormData.ts");
+var ErrorData_1 = __webpack_require__(/*! ./ErrorData */ "./src/main/typescript/impl/xhrCore/ErrorData.ts");
+var EventData_1 = __webpack_require__(/*! ./EventData */ "./src/main/typescript/impl/xhrCore/EventData.ts");
+var Lang_1 = __webpack_require__(/*! ../util/Lang */ "./src/main/typescript/impl/util/Lang.ts");
+var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
+var RequestDataResolver_1 = __webpack_require__(/*! ./RequestDataResolver */ "./src/main/typescript/impl/xhrCore/RequestDataResolver.ts");
+var failSaveExecute = Lang_1.ExtLang.failSaveExecute;
+var XhrRequest = /** @class */ (function () {
+    /**
+     * Reqired Parameters
+     *
+     * @param source the issuing element
+     * @param sourceForm the form which is related to the issuing element
+     * @param requestContext the request context with allö pass through values
+     *
+     * Optional Parameters
+     *
+     * @param partialIdsArray an optional restricting partial ids array for encoding
+     * @param timeout optional xhr timeout
+     * @param ajaxType optional request type, default "POST"
+     * @param contentType optional content type, default "application/x-www-form-urlencoded"
+     * @param xhrObject optional xhr object which must fullfill the XMLHTTPRequest api, default XMLHttpRequest
+     */
+    function XhrRequest(source, sourceForm, requestContext, internalContext, partialIdsArray, timeout, ajaxType, contentType, xhrObject) {
+        var _this = this;
+        if (partialIdsArray === void 0) { partialIdsArray = []; }
+        if (timeout === void 0) { timeout = Const_1.NO_TIMEOUT; }
+        if (ajaxType === void 0) { ajaxType = Const_1.REQ_TYPE_POST; }
+        if (contentType === void 0) { contentType = Const_1.URL_ENCODED; }
+        if (xhrObject === void 0) { xhrObject = new XMLHttpRequest(); }
+        this.source = source;
+        this.sourceForm = sourceForm;
+        this.requestContext = requestContext;
+        this.internalContext = internalContext;
+        this.partialIdsArray = partialIdsArray;
+        this.timeout = timeout;
+        this.ajaxType = ajaxType;
+        this.contentType = contentType;
+        this.xhrObject = xhrObject;
+        this.stopProgress = false;
+        /**
+         * helper support so that we do not have to drag in Promise shims
+         */
+        this.catchFuncs = [];
+        this.thenFunc = [];
+        /*
+        * we omit promises here
+        * some browsers do not support it and we do not need shim code
+        */
+        this.registerXhrCallbacks(function (data) { _this.resolve(data); }, function (data) { _this.reject(data); });
+    }
+    XhrRequest.prototype.start = function () {
+        var _this = this;
+        var ignoreErr = failSaveExecute;
+        var xhrObject = this.xhrObject;
+        try {
+            var viewState = jsf.getViewState(this.sourceForm.getAsElem(0).value);
+            //encoded we need to decode
+            var formData = new XhrFormData_1.XhrFormData(decodeURIComponent(viewState));
+            this.contentType = formData.isMultipartRequest ? Const_1.MULTIPART : this.contentType;
+            //next step the pass through parameters are merged in for post params
+            var requestContext = this.requestContext;
+            var passThroughParams = requestContext.getIf(Const_1.CTX_PARAM_PASS_THR);
+            formData.shallowMerge(passThroughParams);
+            this.responseContext = passThroughParams.deepCopy;
+            //we have to shift the internal passthroughs around to build up our response context
+            var responseContext = this.responseContext;
+            responseContext.assign(Const_1.CTX_PARAM_MF_INTERNAL).value = this.internalContext.value;
+            //per spec the onevent and onerrors must be passed through to the response
+            responseContext.assign(Const_1.ON_EVENT).value = requestContext.getIf(Const_1.ON_EVENT).value;
+            responseContext.assign(Const_1.ON_ERROR).value = requestContext.getIf(Const_1.ON_ERROR).value;
+            xhrObject.open(this.ajaxType, RequestDataResolver_1.resolveFinalUrl(this.sourceForm, formData, this.ajaxType), true);
+            //adding timeout
+            this.timeout ? xhrObject.timeout = this.timeout : null;
+            //a bug in the xhr stub library prevents the setRequestHeader to be properly executed on fake xhr objects
+            //normal browsers should resolve this
+            //tests can quietly fail on this one
+            ignoreErr(function () { return xhrObject.setRequestHeader(Const_1.CONTENT_TYPE, _this.contentType + "; charset=utf-8"); });
+            ignoreErr(function () { return xhrObject.setRequestHeader(Const_1.HEAD_FACES_REQ, Const_1.VAL_AJAX); });
+            //probably not needed anymore, will test this
+            //some webkit based mobile browsers do not follow the w3c spec of
+            // setting the accept headers automatically
+            ignoreErr(function () { return xhrObject.setRequestHeader(Const_1.REQ_ACCEPT, Const_1.STD_ACCEPT); });
+            this.sendEvent(Const_1.BEGIN);
+            this.sendRequest(formData);
+        }
+        catch (e) {
+            //_onError//_onError
+            this.handleError(e);
+        }
+        return this;
+    };
+    XhrRequest.prototype.cancel = function () {
+        try {
+            this.xhrObject.abort();
+        }
+        catch (e) {
+            this.handleError(e);
+        }
+    };
+    XhrRequest.prototype.resolve = function (data) {
+        monadish_1.Stream.of.apply(monadish_1.Stream, this.thenFunc).reduce(function (inputVal, thenFunc) {
+            return thenFunc(inputVal);
+        }, data);
+    };
+    XhrRequest.prototype.reject = function (data) {
+        monadish_1.Stream.of.apply(monadish_1.Stream, this.catchFuncs).reduce(function (inputVal, catchFunc) {
+            return catchFunc(inputVal);
+        }, data);
+    };
+    XhrRequest.prototype.catch = function (func) {
+        //this.$promise.catch(func);
+        this.catchFuncs.push(func);
+        return this;
+    };
+    XhrRequest.prototype.finally = function (func) {
+        //no ie11 support we probably are going to revert to shims for that one
+        //(<any>this.$promise).then(func).catch(func);
+        this.catchFuncs.push(func);
+        this.thenFunc.push(func);
+        return this;
+    };
+    XhrRequest.prototype.then = function (func) {
+        //this.$promise.then(func);
+        this.thenFunc.push(func);
+        return this;
+    };
+    /**
+     * attaches the internal event and processing
+     * callback within the promise to our xhr object
+     *
+     * @param resolve
+     * @param reject
+     */
+    XhrRequest.prototype.registerXhrCallbacks = function (resolve, reject) {
+        var _this = this;
+        var xhrObject = this.xhrObject;
+        xhrObject.onabort = function () {
+            _this.onAbort(resolve, reject);
+        };
+        xhrObject.ontimeout = function () {
+            _this.onTimeout(resolve, reject);
+        };
+        xhrObject.onload = function () {
+            _this.onSuccess(_this.xhrObject, resolve, reject);
+        };
+        xhrObject.onloadend = function () {
+            _this.onDone(_this.xhrObject, resolve, reject);
+        };
+        xhrObject.onerror = function (errorData) {
+            _this.onError(errorData, resolve, reject);
+        };
+    };
+    /*
+     * xhr processing callbacks
+     *
+     * Those methods are the callbacks called by
+     * the xhr object depending on its own state
+     */
+    XhrRequest.prototype.onAbort = function (resolve, reject) {
+        reject();
+    };
+    XhrRequest.prototype.onTimeout = function (resolve, reject) {
+        this.sendEvent(Const_1.STATE_EVT_TIMEOUT);
+        reject();
+    };
+    XhrRequest.prototype.onSuccess = function (data, resolve, reject) {
+        var _a, _b, _c;
+        this.sendEvent(Const_1.COMPLETE);
+        //malforms always result in empty response xml
+        if (!((_b = (_a = this) === null || _a === void 0 ? void 0 : _a.xhrObject) === null || _b === void 0 ? void 0 : _b.responseXML)) {
+            this.handleMalFormedXML(resolve);
+            return;
+        }
+        jsf.ajax.response(this.xhrObject, (_c = this.responseContext.value, (_c !== null && _c !== void 0 ? _c : {})));
+    };
+    XhrRequest.prototype.handleMalFormedXML = function (resolve) {
+        var _a;
+        this.stopProgress = true;
+        var errorData = {
+            type: Const_1.ERROR,
+            status: Const_1.MALFORMEDXML,
+            responseCode: 200,
+            responseText: (_a = this.xhrObject) === null || _a === void 0 ? void 0 : _a.responseText,
+            source: {
+                id: this.source.id.value
+            }
+        };
+        try {
+            AjaxImpl_1.Implementation.sendError(errorData);
+        }
+        finally {
+            resolve(errorData);
+        }
+        //non blocking non clearing
+    };
+    XhrRequest.prototype.onDone = function (data, resolve, reject) {
+        if (this.stopProgress) {
+            return;
+        }
+        resolve(data);
+    };
+    XhrRequest.prototype.onError = function (errorData, resolve, reject) {
+        this.handleError(errorData);
+        reject();
+    };
+    /*
+     * other helpers
+     */
+    XhrRequest.prototype.sendEvent = function (evtType) {
+        var eventData = EventData_1.EventData.createFromRequest(this.xhrObject, this.requestContext, evtType);
+        try {
+            //user code error, we might cover
+            //this in onError but also we cannot swallow it
+            //we need to resolve the local handlers lazyly,
+            //because some frameworks might decorate them over the context in the response
+            var eventHandler = RequestDataResolver_1.resolveHandlerFunc(this.requestContext, this.responseContext, Const_1.ON_EVENT);
+            ;
+            AjaxImpl_1.Implementation.sendEvent(eventData, eventHandler);
+        }
+        catch (e) {
+            this.handleError(e);
+            throw e;
+        }
+    };
+    XhrRequest.prototype.handleError = function (exception) {
+        var errorData = ErrorData_1.ErrorData.fromClient(exception);
+        var eventHandler = RequestDataResolver_1.resolveHandlerFunc(this.requestContext, this.responseContext, Const_1.ON_ERROR);
+        AjaxImpl_1.Implementation.sendError(errorData, eventHandler);
+    };
+    XhrRequest.prototype.sendRequest = function (formData) {
+        var isPost = this.ajaxType != Const_1.REQ_TYPE_GET;
+        if (formData.isMultipartRequest) {
+            this.xhrObject.send((isPost) ? formData.toFormData() : null);
+        }
+        else {
+            this.xhrObject.send((isPost) ? formData.toString() : null);
+        }
+    };
+    return XhrRequest;
+}());
+exports.XhrRequest = XhrRequest;
+
+
+/***/ })
+
+/******/ })));
+//# sourceMappingURL=jsf-development.js.map
+//# sourceMappingURL=jsf-development.js.map.jsf?ln=scripts
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/js/tobago-myfaces.js.map b/tobago-theme/tobago-theme-standard/src/main/npm/js/jsf-development.js.map
similarity index 100%
rename from tobago-theme/tobago-theme-standard/src/main/npm/js/tobago-myfaces.js.map
rename to tobago-theme/tobago-theme-standard/src/main/npm/js/jsf-development.js.map
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/js/jsf.js b/tobago-theme/tobago-theme-standard/src/main/npm/js/jsf.js
new file mode 100644
index 0000000..df8926b
--- /dev/null
+++ b/tobago-theme/tobago-theme-standard/src/main/npm/js/jsf.js
@@ -0,0 +1,3 @@
+!function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=13)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.P_PARTIAL_SOURCE="javax.faces.source",t.PARTIAL_ID="partialId",t.P_VIEWSTATE="javax.faces.ViewState",t.P_VIEWROOT="javax.faces.ViewRoot",t.P_VIEWHEAD="javax.faces.ViewHead",t.P_VIEWBODY="javax.faces.ViewBody",t.EMPTY_FUNC=Object.freeze((function(){})),t.EMPTY_STR="",t.EMPTY_MAP=Object.freeze({}),t.HTML_VIEWSTATE=["<input type='hidden'","id='",t.P_VIEWSTATE,"' name='",t.P_VIEWSTATE,"' value='' />"].join(t.EMPTY_STR),t.IDENT_ALL="@all",t.IDENT_NONE="@none",t.IDENT_THIS="@this",t.IDENT_FORM="@form",t.P_AJAX="javax.faces.partial.ajax",t.P_EXECUTE="javax.faces.partial.execute",t.P_RENDER="javax.faces.partial.render",t.P_EVT="javax.faces.partial.event",t.P_CLIENT_WINDOW="javax.faces.ClientWindow",t.P_RESET_VALUES="javax.faces.partial.resetValues",t.P_WINDOW_ID="javax.faces.windowId",t.RENDER="render",t.WINDOW_ID="windowId",t.ERROR="error",t.EVENT="event",t.ON_ERROR="onerror",t.ON_EVENT="onevent",t.BEGIN="begin",t.COMPLETE="complete",t.SUCCESS="success",t.SOURCE="source",t.STATUS="status",t.ERROR_NAME="error-name",t.ERROR_MESSAGE="error-message",t.RESPONSE_TEXT="responseText",t.RESPONSE_XML="responseXML",t.HTTPERROR="httpError",t.EMPTY_RESPONSE="emptyResponse",t.MALFORMEDXML="malformedXML",t.SERVER_ERROR="serverError",t.CLIENT_ERROR="clientError",t.TIMEOUT_EVENT="timeout",t.CTX_PARAM_MF_INTERNAL="_mfInternal",t.CTX_PARAM_SRC_FRM_ID="_mfSourceFormId",t.CTX_PARAM_SRC_CTL_ID="_mfSourceControlId",t.CTX_PARAM_TR_TYPE="_mfTransportType",t.CTX_PARAM_PASS_THR="passThrgh",t.CTX_PARAM_DELAY="delay",t.CTX_PARAM_TIMEOUT="timeout",t.CTX_PARAM_RST="resetValues",t.CTX_PARAM_EXECUTE="execute",t.STAGE_DEVELOPMENT="Development",t.CONTENT_TYPE="Content-Type",t.HEAD_FACES_REQ="Faces-Request",t.REQ_ACCEPT="Accept",t.VAL_AJAX="partial/ajax",t.ENCODED_URL="javax.faces.encodedURL",t.REQ_TYPE_GET="GET",t.REQ_TYPE_POST="POST",t.STATE_EVT_BEGIN="begin",t.STATE_EVT_TIMEOUT="TIMEOUT_EVENT",t.STATE_EVT_COMPLETE="complete",t.URL_ENCODED="application/x-www-form-urlencoded",t.MULTIPART="multipart/form-data",t.NO_TIMEOUT=0,t.STD_ACCEPT="text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",t.TAG_HEAD="head",t.TAG_FORM="form",t.TAG_BODY="body",t.TAG_BEFORE="before",t.TAG_AFTER="after",t.TAG_ATTR="attribute",t.SEL_VIEWSTATE_ELEM="[name='"+t.P_VIEWSTATE+"']",t.SEL_RESPONSE_XML="responseXML",t.PHASE_PROCESS_RESPONSE="processResponse",t.ERR_NO_PARTIAL_RESPONSE="Partial response not set",t.ATTR_URL="url",t.ATTR_NAME="name",t.ATTR_VALUE="value",t.ATTR_ID="id",t.RESP_PARTIAL="partial-response",t.CMD_CHANGES="changes",t.CMD_UPDATE="update",t.CMD_DELETE="delete",t.CMD_INSERT="insert",t.CMD_EVAL="eval",t.CMD_ERROR="error",t.CMD_ATTRIBUTES="attributes",t.CMD_EXTENSION="extension",t.CMD_REDIRECT="redirect",t.UPDATE_FORMS="_updateForms",t.UPDATE_ELEMS="_updateElems",t.MYFACES="myfaces",t.SEL_SCRIPTS_STYLES="script, style, link",t.MF_NONE="__mf_none__",t.REASON_EXPIRED="Expired",t.APPLIED_VST="appliedViewState",t.RECONNECT_INTERVAL=500,t.MAX_RECONNECT_ATTEMPTS=25},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(5);t.DomQuery=r.DomQuery,t.ElementAttribute=r.ElementAttribute,t.DomQueryCollector=r.DomQueryCollector,t.DQ=r.DQ;var o=n(3);t.Lang=o.Lang;var i=n(2);t.Config=i.Config,t.Monad=i.Monad,t.Optional=i.Optional,t.ValueEmbedder=i.ValueEmbedder;var a=n(18);t.XMLQuery=a.XMLQuery,t.XQ=a.XQ;var s=n(6);t.Stream=s.Stream,t.LazyStream=s.LazyStream;var u=n(8);t.ArrayStreamDataSource=u.ArrayStreamDataSource,t.MappedStreamDataSource=u.MappedStreamDataSource,t.FilteredStreamDatasource=u.FilteredStreamDatasource,t.FlatMapStreamDataSource=u.FlatMapStreamDataSource,t.QueryFormStringCollector=u.QueryFormStringCollector,t.ArrayCollector=u.ArrayCollector,t.AssocArrayCollector=u.AssocArrayCollector,t.FormDataCollector=u.FormDataCollector,t.QueryFormDataCollector=u.QueryFormDataCollector},function(e,t,n){"use strict";var r,o=this&&this.__extends||(r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)});Object.defineProperty(t,"__esModule",{value:!0});var i=n(3),a=n(8),s=n(6),u=i.Lang.objAssign,l=function(){function e(e){this._value=e}return Object.defineProperty(e.prototype,"value",{get:function(){return this._value},enumerable:!0,configurable:!0}),e.prototype.map=function(t){return t||(t=function(e){return e}),new e(t(this.value))},e.prototype.flatMap=function(t){for(var n,r=this.map(t);(null===(n=r)||void 0===n?void 0:n.value)instanceof e;)r=r.value;return r},e}();t.Monad=l;var c=function(e){function t(t){return e.call(this,t)||this}return o(t,e),Object.defineProperty(t.prototype,"value",{get:function(){return this._value instanceof l?this._value.flatMap().value:this._value},enumerable:!0,configurable:!0}),t.fromNullable=function(e){return new t(e)},t.prototype.isAbsent=function(){return void 0===this.value||null==this.value},t.prototype.isPresent=function(e){var t=this.isAbsent();return!t&&e&&e.call(this,this),!t},t.prototype.ifPresentLazy=function(e){return void 0===e&&(e=function(){}),this.isPresent.call(this,e),this},t.prototype.orElse=function(e){return this.isPresent()?this:null==e?t.absent:this.flatMap((function(){return e}))},t.prototype.orElseLazy=function(e){return this.isPresent()?this:this.flatMap(e)},t.prototype.flatMap=function(n){var r=e.prototype.flatMap.call(this,n);return r instanceof t?r.flatMap():t.fromNullable(r.value)},t.prototype.getIf=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];for(var n=this,r=0;r<e.length;r++){var o=this.keyVal(e[r]),i=this.arrayIndex(e[r]);if(""===o&&i>=0){if((n=this.getClass().fromNullable(n.value instanceof Array?n.value.length<i?null:n.value[i]:null)).isAbsent())return n}else if(o&&i>=0){if(n.getIfPresent(o).isAbsent())return n;if((n=n.getIfPresent(o).value instanceof Array?this.getClass().fromNullable(n.getIfPresent(o).value[i]):this.getClass().absent).isAbsent())return n}else{if((n=n.getIfPresent(o)).isAbsent())return n;i>-1&&(n=this.getClass().fromNullable(n.value[i]))}}return n},t.prototype.match=function(e){return!this.isAbsent()&&e(this.value)},t.prototype.get=function(e){return void 0===e&&(e=t.absent),this.isAbsent()?this.getClass().fromNullable(e).flatMap():this.getClass().fromNullable(this.value).flatMap()},t.prototype.toJson=function(){return JSON.stringify(this.value)},t.prototype.getClass=function(){return t},t.prototype.arrayIndex=function(e){var t=e.indexOf("["),n=e.indexOf("]");return t>=0&&n>0&&t<n?parseInt(e.substring(t+1,n)):-1},t.prototype.keyVal=function(e){var t=e.indexOf("[");return t>=0?e.substring(0,t):e},t.prototype.getIfPresent=function(e){return this.isAbsent()?this.getClass().absent:this.getClass().fromNullable(this.value[e]).flatMap()},t.prototype.resolve=function(e){if(this.isAbsent())return t.absent;try{return t.fromNullable(e(this.value))}catch(e){return t.absent}},t.absent=t.fromNullable(null),t}(l);t.Optional=c;var f=function(e){function t(t,n){void 0===n&&(n="value");var r=e.call(this,t)||this;return r.key=n,r}return o(t,e),Object.defineProperty(t.prototype,"value",{get:function(){return this._value?this._value[this.key]:null},set:function(e){this._value&&(this._value[this.key]=e)},enumerable:!0,configurable:!0}),t.prototype.orElse=function(e){var n={};return n[this.key]=e,this.isPresent()?this:new t(n,this.key)},t.prototype.orElseLazy=function(e){if(this.isPresent())return this;var n={};return n[this.key]=e(),new t(n,this.key)},t.prototype.getClass=function(){return t},t.fromNullable=function(e,n){return void 0===n&&(n="value"),new t(e,n)},t.absent=t.fromNullable(null),t}(c);t.ValueEmbedder=f;var p=function(e){function t(t,n,r){var o=e.call(this,t,n)||this;return o.arrPos=null!=r?r:-1,o}return o(t,e),Object.defineProperty(t.prototype,"value",{get:function(){return""==this.key&&this.arrPos>=0?this._value[this.arrPos]:this.key&&this.arrPos>=0?this._value[this.key][this.arrPos]:this._value[this.key]},set:function(e){""==this.key&&this.arrPos>=0?this._value[this.arrPos]=e:this.key&&this.arrPos>=0?this._value[this.key][this.arrPos]=e:this._value[this.key]=e},enumerable:!0,configurable:!0}),t.absent=t.fromNullable(null),t}(f),h=function(e){function t(t){return e.call(this,t)||this}return o(t,e),Object.defineProperty(t.prototype,"shallowCopy",{get:function(){return new t(s.Stream.ofAssoc(this.value).collect(new a.AssocArrayCollector))},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"deepCopy",{get:function(){return new t(u({},this.value))},enumerable:!0,configurable:!0}),t.fromNullable=function(e){return new t(e)},t.prototype.shallowMerge=function(e,t){for(var n in void 0===t&&(t=!0),e.value)!t&&n in this.value||(this.assign(n).value=e.getIf(n).value)},t.prototype.assign=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];if(!(e.length<1)){this.buildPath(e);var n=this.keyVal(e[e.length-1]),r=this.arrayIndex(e[e.length-1]),o=new p(1==e.length?this.value:this.getIf.apply(this,e.slice(0,e.length-1)).value,n,r);return o}},t.prototype.assignIf=function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];return e?this.assign.apply(this,t):{value:null}},t.prototype.getIf=function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];return this.getClass().fromNullable(e.prototype.getIf.apply(this,t).value)},t.prototype.get=function(t){return this.getClass().fromNullable(e.prototype.get.call(this,t).value)},t.prototype.delete=function(e){return e in this.value&&delete this.value[e],this},t.prototype.toJson=function(){return JSON.stringify(this.value)},t.prototype.getClass=function(){return t},t.prototype.setVal=function(e){this._value=e},t.prototype.buildPath=function(e){for(var t=this,n=this.getClass().fromNullable(null),r=-1,o=function(e,t){for(var n=e.length,r=n+t,o=n;o<r;o++)e.push({})},i=0;i<e.length;i++){var a=this.keyVal(e[i]),s=this.arrayIndex(e[i]);if(""===a&&s>=0)t.setVal(t.value instanceof Array?t.value:[]),o(t.value,s+1),r>=0&&(n.value[r]=t.value),n=t,r=s,t=this.getClass().fromNullable(t.value[s]);else{var u=t.getIf(a);if(-1==s)u.isAbsent()?u=this.getClass().fromNullable(t.value[a]={}):t=u;else{var l=u.value instanceof Array?u.value:[];o(l,s+1),t.value[a]=l,u=this.getClass().fromNullable(l[s])}n=t,r=s,t=u}}return this},t}(c);t.Config=h},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(2);!function(e){function t(e){for(var t=/\s/,n=(e=e.replace(/^\s\s*/,"")).length;t.test(e.charAt(--n)););return e.slice(0,n+1)}function n(e){return!!arguments.length&&null!=e&&("string"==typeof e||e instanceof String)}e.saveResolve=function(e,t){void 0===t&&(t=null);try{var n=e();return r.Optional.fromNullable(null!=n?n:t)}catch(e){return r.Optional.absent}},e.saveResolveLazy=function(e,t){void 0===t&&(t=null);try{var n=e();return r.Optional.fromNullable(null!=n?n:t())}catch(e){return r.Optional.absent}},e.strToArray=function(e,n){void 0===n&&(n=/\./gi);var r=[];return e.split(n).forEach((function(e){r.push(t(e))})),r},e.trim=t,e.objToArray=function(e,t,n){return void 0===t&&(t=0),void 0===n&&(n=[]),"__undefined__"==(null!=e?e:"__undefined__")?null!=n?n:null:e instanceof Array&&!t&&!n?e:n.concat(Array.prototype.slice.call(e,t))},e.equalsIgnoreCase=function(e,t){var n=null!=t?t:"___no_value__";return(null!=e?e:"___no_value__").toLowerCase()===n.toLowerCase()},e.assertType=function(e,t){return n(t)?typeof e==t:e instanceof t},e.isString=n,e.isFunc=function(e){return e instanceof Function||"function"==typeof e},e.objAssign=function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];if(null==e)throw new TypeError("Cannot convert undefined or null to object");var r=Object(e);return Object.assign?(t.forEach((function(e){return Object.assign(r,e)})),r):(t.forEach((function(e){var t=e;if(null!=t)for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(r[n]=t[n])})),r)}}(t.Lang||(t.Lang={}))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(3),o=n(20),i=n(5),a=n(1),s=n(0),u=n(10);!function(e){var t,n="impl/util/Lang/";function l(e,n){for(var r,i,u=[],l=2;l<arguments.length;l++)u[l-2]=arguments[l];var c=null!=(i=null!=(r=(t=null!=t?t:new o.Messages)[e])?r:n)?i:e+" - undefined message";return a.Stream.of.apply(a.Stream,u).each((function(e,t){c=c.replace(new RegExp(["\\{",t,"\\}"].join(s.EMPTY_STR),"g"),e)})),c}function c(e,t,r,o,i,a){var u;return new Error(null!=(u=a+(null!=o?o:n)+i)?u:s.EMPTY_STR+arguments.caller.toString())}e.getLanguage=function(){var e,t,n,r=null!=(t=null===(e=navigator.languages)||void 0===e?void 0:e[0])?t:null===(n=navigator)||void 0===n?void 0:n.language;return r=r.split("-")[0]},e.failSaveResolve=function(e,t){return void 0===t&&(t=null),r.Lang.saveResolve(e,t)},e.failSaveExecute=function(e,t){void 0===t&&(t=null),r.Lang.saveResolve(e,t)},e.getMessage=l,e.keyValToStr=function(e,t,n){return void 0===n&&(n="\n"),[e,t].join(n)},e.makeException=c,e.getGlobalConfig=function(e,t){var n,r,o,i;return null!=(i=null===(o=null===(r=null===(n=window)||void 0===n?void 0:n.myfaces)||void 0===r?void 0:r.config)||void 0===o?void 0:o[e])?i:t},e.getForm=function(e,t){var n="form",r=new i.DQ(e),o=new i.DQ(u.getEventTarget(t));if(r.isTag(n))return r;if(r.attr(n).isPresent()){var a=r.attr(n).value,s=i.DQ.byId(a);if(s.isPresent())return s}var f=r.parents(n).orElseLazy((function(){return r.byTagName(n,!0)})).orElseLazy((function(){return o.parents(n)})).orElseLazy((function(){return o.byTagName(n)})).first();return function(e){if(e.isAbsent())throw c(new Error,null,null,"Impl","getForm",l("ERR_FORM"))}(f),f},e.getLocalOrGlobalConfig=function(e,t,n){var r,o,i,a,s,u,l,c;return null!=(c=null!=(a=null===(i=null===(o=null===(r=e.value)||void 0===r?void 0:r.myfaces)||void 0===o?void 0:o.config)||void 0===i?void 0:i[t])?a:null===(l=null===(u=null===(s=window)||void 0===s?void 0:s.myfaces)||void 0===u?void 0:u.config)||void 0===l?void 0:l[t])?c:n}}(t.ExtLang||(t.ExtLang={}))},function(e,t,n){"use strict";var r,o=this&&this.__extends||(r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),i=this&&this.__spreadArrays||function(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),o=0;for(t=0;t<n;t++)for(var i=arguments[t],a=0,s=i.length;a<s;a++,o++)r[o]=i[a];return r};Object.defineProperty(t,"__esModule",{value:!0});var a=n(2),s=n(6),u=n(3),l=u.Lang.trim,c=u.Lang.objToArray,f=u.Lang.isString,p=u.Lang.equalsIgnoreCase,h=function(e){function t(t,n,r){void 0===r&&(r=null);var o=e.call(this,t,n)||this;return o.element=t,o.name=n,o.defaultVal=r,o}return o(t,e),Object.defineProperty(t.prototype,"value",{get:function(){var e,t=(e=this.element.get(0)).orElse.apply(e,[]).values;return t.length?t[0].getAttribute(this.name):this.defaultVal},set:function(e){for(var t,n=(t=this.element.get(0)).orElse.apply(t,[]).values,r=0;r<n.length;r++)n[r].setAttribute(this.name,e);n[0].setAttribute(this.name,e)},enumerable:!0,configurable:!0}),t.prototype.getClass=function(){return t},t.fromNullable=function(e,n){return void 0===n&&(n="value"),new t(e,n)},t}(a.ValueEmbedder);t.ElementAttribute=h;var v=function(e){return-1==e.indexOf("ln=scripts")&&-1==e.indexOf("ln=javax.faces")||-1==e.indexOf("/jsf.js")&&-1==e.indexOf("/jsf-uncompressed.js")},d=function(){function e(){for(var t,n=[],r=0;r<arguments.length;r++)n[r]=arguments[r];if(this.rootNode=[],this.pos=-1,this._limits=-1,!a.Optional.fromNullable(n).isAbsent()&&n.length)for(var o=0;o<n.length;o++)if(f(n[o])){var i=e.querySelectorAll(n[o]);i.isAbsent()||n.push.apply(n,i.values)}else n[o]instanceof e?(t=this.rootNode).push.apply(t,n[o].values):this.rootNode.push(n[o])}return Object.defineProperty(e.prototype,"value",{get:function(){return this.getAsElem(0)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"values",{get:function(){return this.allElems()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"id",{get:function(){return new h(this.get(0),"id")},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"length",{get:function(){return this.rootNode.length},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"tagName",{get:function(){return this.getAsElem(0).getIf("tagName")},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"nodeName",{get:function(){return this.getAsElem(0).getIf("nodeName")},enumerable:!0,configurable:!0}),e.prototype.isTag=function(e){return!this.isAbsent()&&(this.nodeName.orElse("__none___").value.toLowerCase()==e.toLowerCase()||this.tagName.orElse("__none___").value.toLowerCase()==e.toLowerCase())},Object.defineProperty(e.prototype,"type",{get:function(){return this.getAsElem(0).getIf("type")},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"name",{get:function(){return new a.ValueEmbedder(this.getAsElem(0).value,"name")},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"inputValue",{get:function(){return this.getAsElem(0).getIf("value").isPresent()?new a.ValueEmbedder(this.getAsElem(0).value):a.ValueEmbedder.absent},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"checked",{get:function(){return s.Stream.of.apply(s.Stream,this.values).allMatch((function(e){return!!e.checked}))},set:function(e){this.eachElem((function(t){return t.checked=e}))},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"elements",{get:function(){var e=this;return this.stream.flatMap((function(e){var t=e.value.value;return new s.Stream(t.elements?c(t.elements):[])})).filter((function(e){return!!e})).collect(new E).orElseLazy((function(){return e.querySelectorAll("input, select, textarea, fieldset")}))},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"disabled",{get:function(){return this.attr("disabled").isPresent()},set:function(e){e?this.attr("disabled").value="disabled":this.removeAttribute("disabled")},enumerable:!0,configurable:!0}),e.prototype.removeAttribute=function(e){this.eachElem((function(t){return t.removeAttribute(e)}))},Object.defineProperty(e.prototype,"childNodes",{get:function(){var t=[];return this.eachElem((function(e){t=t.concat(c(e.childNodes))})),new(e.bind.apply(e,i([void 0],t)))},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"stream",{get:function(){return new(s.Stream.bind.apply(s.Stream,i([void 0],this.asArray)))},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"lazyStream",{get:function(){return s.LazyStream.ofStreamDataSource(this)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"asArray",{get:function(){var e=[];return this.each((function(t){e.push(t)})),e},enumerable:!0,configurable:!0}),e.querySelectorAll=function(t){return new e(document).querySelectorAll(t)},e.byId=function(t){return f(t)?new e(document).byId(t):new e(t)},e.byTagName=function(t){return f(t)?new e(document).byTagName(t):new e(t)},e.globalEval=function(t,n){return new e(document).globalEval(t,n)},e.fromMarkup=function(t){var n=document.implementation.createHTMLDocument(""),r=(t=l(t)).toLowerCase();if(-1!=r.indexOf("<!doctype")||-1!=r.indexOf("<html")||-1!=r.indexOf("<head")||-1!=r.indexOf("<body"))return n.documentElement.innerHTML=t,new e(n.documentElement);var o=function(e,t){var n=["<",t,">"].join(""),r=["<",t," "].join("");return 0==e.indexOf(n)||0==e.indexOf(r)},i=new e(document.createElement("div"));return o(r,"thead")||o(r,"tbody")?(i.html("<table>"+t+"</table>"),i.querySelectorAll("table").get(0).childNodes.detach()):o(r,"tfoot")?(i.html("<table><thead></thead><tbody><tbody"+t+"</table>"),i.querySelectorAll("table").get(2).childNodes.detach()):o(r,"tr")?(i.html("<table><tbody>"+t+"</tbody></table>"),i.querySelectorAll("tbody").get(0).childNodes.detach()):o(r,"td")?(i.html("<table><tbody><tr>"+t+"</tr></tbody></table>"),i.querySelectorAll("tr").get(0).childNodes.detach()):(i.html(t),i.childNodes.detach())},e.prototype.get=function(t){return t<this.rootNode.length?new e(this.rootNode[t]):e.absent},e.prototype.getAsElem=function(e,t){return void 0===t&&(t=a.Optional.absent),e<this.rootNode.length?a.Optional.fromNullable(this.rootNode[e]):t},e.prototype.allElems=function(){return this.rootNode},e.prototype.isAbsent=function(){return 0==this.length},e.prototype.isPresent=function(e){var t=this.isAbsent();return!t&&e&&e.call(this,this),!t},e.prototype.ifPresentLazy=function(e){return void 0===e&&(e=function(){}),this.isPresent.call(this,e),this},e.prototype.delete=function(){this.eachElem((function(e){e.parentNode&&e.parentNode.removeChild(e)}))},e.prototype.querySelectorAll=function(t){var n,r;if(!(null===(n=null===this||void 0===this?void 0:this.rootNode)||void 0===n?void 0:n.length))return this;for(var o=[],a=0;a<this.rootNode.length;a++)if(null===(r=this.rootNode[a])||void 0===r?void 0:r.querySelectorAll){var s=this.rootNode[a].querySelectorAll(t);o=o.concat(c(s))}return new(e.bind.apply(e,i([void 0],o)))},e.prototype.byId=function(t,n){for(var r,o=[],a=0;n&&a<this.rootNode.length;a++)(null===(r=this.rootNode[a])||void 0===r?void 0:r.id)==t&&o.push(new e(this.rootNode[a]));return o=o.concat(this.querySelectorAll('[id="'+t+'"]')),new(e.bind.apply(e,i([void 0],o)))},e.prototype.byTagName=function(t,n){for(var r,o=[],a=0;n&&a<this.rootNode.length;a++)(null===(r=this.rootNode[a])||void 0===r?void 0:r.tagName)==t&&o.push(new e(this.rootNode[a]));return o=o.concat(this.querySelectorAll(t)),new(e.bind.apply(e,i([void 0],o)))},e.prototype.attr=function(e,t){return void 0===t&&(t=null),new h(this,e,t)},e.prototype.hasClass=function(e){var t=!1;return this.each((function(n){var r=n.attr("class").value||"";if(-1!=r.toLowerCase().indexOf(e.toLowerCase())){for(var o=r.split(/\s+/gi),i=!1,a=0;a<o.length&&!i;a++)i=o[a].toLowerCase()==e.toLowerCase();return!(t=t||i)&&void 0}})),t},e.prototype.addClass=function(e){var t=this;return this.each((function(n){var r=n.attr("class").value||"";t.hasClass(e)||(n.attr("class").value=l(r+" "+e))})),this},e.prototype.removeClass=function(e){var t=this;return this.each((function(n){if(t.hasClass(e)){for(var r=[],o=(n.attr("class").value||"").split(/\s+/gi),i=0;i<o.length;i++)o[i].toLowerCase()!=e.toLowerCase()&&r.push(o[i]);n.attr("class").value=r.join(" ")}})),this},e.prototype.isMultipartCandidate=function(){return this.querySelectorAll("input[type='file']").firstElem().isPresent()},e.prototype.html=function(e){return a.Optional.fromNullable(e).isAbsent()?this.isPresent()?a.Optional.fromNullable(this.innerHtml):a.Optional.absent:(this.innerHtml=e,this)},Object.defineProperty(e.prototype,"innerHtml",{get:function(){var e=[];return this.eachElem((function(t){return e.push(t.innerHTML)})),e.join("")},set:function(e){this.eachElem((function(t){return t.innerHTML=e}))},enumerable:!0,configurable:!0}),e.prototype._mozMatchesSelector=function(e,t){var n=e;return(n.matchesSelector||n.mozMatchesSelector||n.msMatchesSelector||n.oMatchesSelector||n.webkitMatchesSelector||function(t){for(var n=(document||window.ownerDocument).querySelectorAll(t),r=n.length;--r>=0&&n.item(r)!==e;);return r>-1}).call(e,t)},e.prototype.filterSelector=function(t){var n=this,r=[];return this.eachElem((function(e){n._mozMatchesSelector(e,t)&&r.push(e)})),new(e.bind.apply(e,i([void 0],r)))},e.prototype.matchesSelector=function(e){var t=this;return this.eachElem((function(n){if(!t._mozMatchesSelector(n,e))return!1})),!0},e.prototype.getIf=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];for(var n=this.childNodes,r=0;r<e.length;r++)if((n=n.filterSelector(e[r])).isAbsent())return n;return n},e.prototype.eachElem=function(e){for(var t=0,n=this.rootNode.length;t<n&&!1!==e(this.rootNode[t],t);t++);return this},e.prototype.firstElem=function(e){return void 0===e&&(e=function(e){return e}),this.rootNode.length>1&&e(this.rootNode[0],0),this},e.prototype.each=function(t){return s.Stream.of.apply(s.Stream,this.rootNode).each((function(n,r){if(null!=n)return t(e.byId(n),r)})),this},e.prototype.first=function(e){return void 0===e&&(e=function(e){return e}),this.rootNode.length>=1?(e(this.get(0),0),this.get(0)):this},e.prototype.filter=function(t){var n=[];return this.each((function(e){t(e)&&n.push(e)})),new(e.bind.apply(e,i([void 0],n)))},e.prototype.globalEval=function(e,t){var n=document.getElementsByTagName("head")[0]||document.documentElement,r=document.createElement("script");t&&r.setAttribute("nonce",t),r.type="text/javascript",r.innerHTML=e;var o=n.appendChild(r);return n.removeChild(o),this},e.prototype.detach=function(){return this.eachElem((function(e){e.parentNode.removeChild(e)})),this},e.prototype.appendTo=function(e){this.eachElem((function(t){e.getAsElem(0).orElseLazy((function(){return{appendChild:function(e){}}})).value.appendChild(t)}))},e.prototype.loadScriptEval=function(e,t,n){var r=this;void 0===t&&(t=0),void 0===n&&(n="utf-8");var o=new XMLHttpRequest;return o.open("GET",e,!1),n&&o.setRequestHeader("Content-Type","application/x-javascript; charset:"+n),o.send(null),o.onload=function(n){t?setTimeout((function(){r.globalEval(o.responseText+"\r\n//@ sourceURL="+e)}),t):r.globalEval(o.responseText.replace("\n","\r\n")+"\r\n//@ sourceURL="+e)},o.onerror=function(e){throw Error(e)},this},e.prototype.insertAfter=function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];this.each((function(e){for(var n=e.getAsElem(0).value,r=n.parentNode,o=function(e){var o=n.nextSibling;t[e].eachElem((function(e){o?(r.insertBefore(e,o),n=o):r.appendChild(e)}))},i=0;i<t.length;i++)o(i)}));var r=[];return r.push(this),r=r.concat(t),new(e.bind.apply(e,i([void 0],r)))},e.prototype.insertBefore=function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];this.each((function(e){for(var n=e.getAsElem(0).value,r=n.parentNode,o=0;o<t.length;o++)t[o].eachElem((function(e){r.insertBefore(e,n)}))}));var r=[];return r.push(this),r=r.concat(t),new(e.bind.apply(e,i([void 0],r)))},e.prototype.orElse=function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];return this.isPresent()?this:new(e.bind.apply(e,i([void 0],t)))},e.prototype.orElseLazy=function(t){return this.isPresent()?this:new e(t())},e.prototype.parents=function(t){var n=new Set,r=[],o=t.toLowerCase(),a=function(e){(e.tagName||"").toLowerCase()!=o||n.has(e)||(n.add(e),r.push(e))};return this.eachElem((function(e){for(;e.parentNode;)if(e=e.parentNode,a(e),"form"==t&&r.length)return!1})),new(e.bind.apply(e,i([void 0],r)))},e.prototype.copyAttrs=function(e){var t=this;return e.eachElem((function(e){for(var n=0,r=c(e.attributes);n<r.length;n++){var o=r[n],i=o.value,a=o.name;switch(a){case"id":t.id.value=i;break;case"disabled":t.resolveAttributeHolder("disabled").disabled=i;break;case"checked":t.resolveAttributeHolder("checked").checked=i;break;default:t.attr(a).value=i}}})),this},e.prototype.resolveAttributeHolder=function(e){void 0===e&&(e="value");var t=[];return t[e]=null,e in this.getAsElem(0).value?this.getAsElem(0).value:t},e.prototype.outerHTML=function(t,n,r){var o,a;if(!this.isAbsent()){var s=null===(a=null===(o=document)||void 0===o?void 0:o.activeElement)||void 0===a?void 0:a.id,u=s?e.getCaretPosition(document.activeElement):null,l=e.fromMarkup(t),c=[],f=this.getAsElem(0).value,p=l.get(0),h=f.parentNode,v=p.getAsElem(0).value;if(h.replaceChild(v,f),c.push(new e(v)),this.isAbsent())return this;var d=[];l.length>1&&(d=d.concat.apply(d,l.values.slice(1)),c.push(e.byId(v).insertAfter(new(e.bind.apply(e,i([void 0],d)))))),n&&this.runScripts(),r&&this.runCss();var E=e.byId(s);return s&&E.isPresent()&&null!=u&&void 0!==u&&E.eachElem((function(t){return e.setCaretPosition(t,u)})),l}},e.prototype.runScripts=function(t){var n=this;void 0===t&&(t=v);var r=[],o=p,i=function(e){var i=e.tagName,a=e.type||"";if(i&&o(i,"script")&&(""===a||o(a,"text/javascript")||o(a,"javascript")||o(a,"text/ecmascript")||o(a,"ecmascript"))){var s=e.getAttribute("src");if(void 0!==s&&null!=s&&s.length>0)t(s)&&(r.length&&(n.globalEval(r.join("\n")),r=[]),n.loadScriptEval(s,0,"UTF-8"));else{for(var u=l(e.text||e.innerText||e.innerHTML),c=!0;c;)c=!1,"\x3c!--"==u.substring(0,4)&&(u=u.substring(4),c=!0),"//\x3c!--"==u.substring(0,4)&&(u=u.substring(6),c=!0),"//<![CDATA["==u.substring(0,11)&&(u=u.substring(11),c=!0);r.push(u)}}};try{new e(this.filterSelector("script"),this.querySelectorAll("script")).stream.flatMap((function(e){return s.Stream.of(e.values)})).sort((function(e,t){return e.compareDocumentPosition(t)-3})).each((function(e){return i(e)})),r.length&&this.globalEval(r.join("\n"))}catch(e){window.console&&window.console.error&&console.error(e.message||e.description)}finally{i=null}return this},e.prototype.runCss=function(){var t=function(e,t){var n,r,o,i,a,s=document.createElement("style");document.getElementsByTagName("head")[0].appendChild(s);var u=null!=(n=s.sheet)?n:s.styleSheet;s.setAttribute("rel",null!=(r=e.getAttribute("rel"))?r:"stylesheet"),s.setAttribute("type",null!=(o=e.getAttribute("type"))?o:"text/css"),null!=(a=null===(i=u)||void 0===i?void 0:i.cssText)&&a?u.cssText=t:s.appendChild(document.createTextNode(t))};return new e(this.filterSelector("link, style"),this.querySelectorAll("link, style")).stream.flatMap((function(e){return s.Stream.of(e.values)})).sort((function(e,t){return e.compareDocumentPosition(t)-3})).each((function(e){return function(e){var n=e.tagName;if(n&&p(n,"link")&&p(e.getAttribute("type"),"text/css"))t(e,"@import url('"+e.getAttribute("href")+"');");else if(n&&p(n,"style")&&p(e.getAttribute("type"),"text/css")){var r=[],o=e.childNodes;if(o)for(var i=o.length,a=0;a<i;a++)r.push(o[a].innerHTML||o[a].data);else e.innerHTML&&r.push(e.innerHTML);t(e,r.join(""))}}(e)})),this},e.prototype.click=function(){return this.fireEvent("click"),this},e.prototype.addEventListener=function(e,t,n){return this.eachElem((function(r){r.addEventListener(e,t,n)})),this},e.prototype.removeEventListener=function(e,t,n){return this.eachElem((function(r){r.removeEventListener(e,t,n)})),this},e.prototype.fireEvent=function(e){this.eachElem((function(t){var n;if(t.ownerDocument)n=t.ownerDocument;else{if(9!=t.nodeType)throw new Error("Invalid node passed to fireEvent: "+t.id);n=t}if(t.dispatchEvent){var r="";switch(e){case"click":case"mousedown":case"mouseup":r="MouseEvents";break;case"focus":case"change":case"blur":case"select":r="HTMLEvents";break;default:throw"fireEvent: Couldn't find an event class for event '"+e+"'."}var o=n.createEvent(r);o.initEvent(e,!0,!0),o.synthetic=!0,t.dispatchEvent(o)}else if(t.fireEvent){var i=n.createEventObject();i.synthetic=!0,t.fireEvent("on"+e,i)}}))},e.prototype.textContent=function(e){return void 0===e&&(e=""),this.stream.map((function(e){return e.getAsElem(0).orElseLazy((function(){return{textContent:""}})).value.textContent||""})).reduce((function(t,n){return t+e+n}),"").value},e.prototype.innerText=function(e){return void 0===e&&(e=""),this.stream.map((function(e){return e.getAsElem(0).orElseLazy((function(){return{innerText:""}})).value.innerText||""})).reduce((function(t,n){return[t,n].join(e)}),"").value},e.prototype.encodeFormElement=function(e){if(void 0===e&&(e=new a.Config({})),!this.name.isAbsent()){var t=e.shallowCopy;return this.each((function(e){if(!e.name.isAbsent()){var n=e.name.value,r=e.tagName.orElse("__none__").value.toLowerCase(),o=e.type.orElse("__none__").value.toLowerCase();if(o=o.toLowerCase(),("input"==r||"textarea"==r||"select"==r)&&null!=n&&""!=n&&!e.disabled){if("select"==r){var i=e.getAsElem(0).value;if(i.selectedIndex>=0)for(var a=i.options.length,s=0;s<a;s++)if(i.options[s].selected){var u=i.options[s];t.assign(n).value=null!=u.getAttribute("value")?u.value:u.text}}if("select"!=r&&"button"!=o&&"reset"!=o&&"submit"!=o&&"image"!=o&&("checkbox"!=o&&"radio"!=o||e.checked)){var l=e.value.files;l&&l.length?t.assign(n).value=l[0]:t.assign(n).value=e.inputValue.value}}}})),t}},Object.defineProperty(e.prototype,"cDATAAsString",{get:function(){return this.stream.flatMap((function(e){return e.childNodes.stream})).reduce((function(e,t){var n,r,o,i,a,s,u;return 4==(null===(o=null===(r=null===(n=t)||void 0===n?void 0:n.value)||void 0===r?void 0:r.value)||void 0===o?void 0:o.nodeType)&&e.push(null!=(u=null===(s=null===(a=null===(i=t)||void 0===i?void 0:i.value)||void 0===a?void 0:a.value)||void 0===s?void 0:s.data)?u:""),e}),[]).value.join("")},enumerable:!0,configurable:!0}),e.prototype.subNodes=function(t,n){return a.Optional.fromNullable(n).isAbsent()&&(n=this.length),new(e.bind.apply(e,i([void 0],this.rootNode.slice(t,Math.min(n,this.length)))))},e.prototype.limits=function(e){return this._limits=e,this},e.prototype.hasNext=function(){var e=-1!=this._limits&&this.pos>=this._limits-1,t=this.pos>=this.values.length-1;return!(e||t)},e.prototype.next=function(){return this.hasNext()?(this.pos++,new e(this.values[this.pos])):null},e.prototype.reset=function(){this.pos=-1},e.getCaretPosition=function(e){var t,n=0;try{if(null===(t=document)||void 0===t?void 0:t.selection){e.focus();var r=document.selection.createRange();r.moveStart("character",-e.value.length),n=r.text.length}}catch(e){}return n},e.setCaretPosition=function(e,t){e.focus(),e.setSelectionRange(t,t)},e.absent=new e,e}();t.DomQuery=d;var E=function(){function e(){this.data=[]}return e.prototype.collect=function(e){this.data.push(e)},Object.defineProperty(e.prototype,"finalValue",{get:function(){return new(d.bind.apply(d,i([void 0],this.data)))},enumerable:!0,configurable:!0}),e}();t.DomQueryCollector=E,t.DQ=d},function(e,t,n){"use strict";var r=this&&this.__spreadArrays||function(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),o=0;for(t=0;t<n;t++)for(var i=arguments[t],a=0,s=i.length;a<s;a++,o++)r[o]=i[a];return r};Object.defineProperty(t,"__esModule",{value:!0});var o=n(2),i=n(8),a=function(){function e(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];this._limits=-1,this.pos=-1,this.value=e}return e.of=function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];return new(e.bind.apply(e,r([void 0],t)))},e.ofAssoc=function(e){return this.of.apply(this,Object.keys(e)).map((function(t){return[t,e[t]]}))},e.ofDataSource=function(t){for(var n=[];t.hasNext();)n.push(t.next());return new(e.bind.apply(e,r([void 0],n)))},e.prototype.limits=function(e){return this._limits=e,this},e.prototype.onElem=function(e){for(var t=0;t<this.value.length&&(-1==this._limits||t<this._limits)&&!1!==e(this.value[t],t);t++);return this},e.prototype.each=function(e){this.onElem(e)},e.prototype.map=function(t){t||(t=function(e){return e});var n=[];return this.each((function(e,r){n.push(t(e))})),new(e.bind.apply(e,r([void 0],n)))},e.prototype.flatMap=function(t){var n=[];return this.each((function(e){var r=t(e);n=Array.isArray(r)?n.concat(r):n.concat.apply(n,r.value)})),e.of.apply(e,n)},e.prototype.filter=function(t){var n=[];return this.each((function(e){t(e)&&n.push(e)})),new(e.bind.apply(e,r([void 0],n)))},e.prototype.reduce=function(e,t){void 0===t&&(t=null);for(var n=null!=t?0:1,r=null!=t?t:this.value.length?this.value[0]:null,i=n;i<this.value.length&&(-1==this._limits||i<this._limits);i++)r=e(r,this.value[i]);return o.Optional.fromNullable(r)},e.prototype.first=function(){return this.value&&this.value.length?o.Optional.fromNullable(this.value[0]):o.Optional.absent},e.prototype.last=function(){var e=this._limits>0?Math.min(this._limits,this.value.length):this.value.length;return o.Optional.fromNullable(e?this.value[e-1]:null)},e.prototype.anyMatch=function(e){for(var t=0;t<this.value.length&&(-1==this._limits||t<this._limits);t++)if(e(this.value[t]))return!0;return!1},e.prototype.allMatch=function(e){if(!this.value.length)return!1;for(var t=0,n=0;n<this.value.length;n++)e(this.value[n])&&t++;return t==this.value.length},e.prototype.noneMatch=function(e){for(var t=0,n=0;n<this.value.length;n++)e(this.value[n])||t++;return t==this.value.length},e.prototype.sort=function(t){var n=this.value.slice().sort(t);return e.of.apply(e,n)},e.prototype.collect=function(e){return this.each((function(t){return e.collect(t)})),e.finalValue},e.prototype.hasNext=function(){var e=-1!=this._limits&&this.pos>=this._limits-1,t=this.pos>=this.value.length-1;return!(e||t)},e.prototype.next=function(){return this.hasNext()?(this.pos++,this.value[this.pos]):null},e.prototype.reset=function(){this.pos=-1},e}();t.Stream=a;var s=function(){function e(e){this._limits=-1,this.pos=-1,this.dataSource=e}return e.of=function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];return new e(new(i.ArrayStreamDataSource.bind.apply(i.ArrayStreamDataSource,r([void 0],t))))},e.ofAssoc=function(e){return this.of.apply(this,Object.keys(e)).map((function(t){return[t,e[t]]}))},e.ofStreamDataSource=function(t){return new e(t)},e.prototype.hasNext=function(){return!this.isOverLimits()&&this.dataSource.hasNext()},e.prototype.next=function(){var e=this.dataSource.next();return this.pos++,e},e.prototype.reset=function(){this.dataSource.reset(),this.pos=0,this._limits=-1},e.prototype.nextFilter=function(e){if(this.hasNext()){var t=this.next();return e(t)?t:this.nextFilter(e)}return null},e.prototype.limits=function(e){return this._limits=e,this},e.prototype.collect=function(e){for(;this.hasNext();){var t=this.next();e.collect(t)}return e.finalValue},e.prototype.onElem=function(t){var n=this;return new e(new i.MappedStreamDataSource((function(e){return!1===t(e,n.pos)&&n.stop(),e}),this))},e.prototype.filter=function(t){return new e(new i.FilteredStreamDatasource(t,this))},e.prototype.map=function(t){return new e(new i.MappedStreamDataSource(t,this))},e.prototype.flatMap=function(t){return new e(new i.FlatMapStreamDataSource(t,this))},e.prototype.each=function(e){for(;this.hasNext();)!1===e(this.next())&&this.stop()},e.prototype.reduce=function(e,t){if(void 0===t&&(t=null),!this.hasNext())return o.Optional.absent;var n=null,r=null;if(null!=t)n=t,r=this.next();else{if(n=this.next(),!this.hasNext())return o.Optional.fromNullable(n);r=this.next()}for(n=e(n,r);this.hasNext();)n=e(n,r=this.next());return o.Optional.fromNullable(n)},e.prototype.last=function(){return this.hasNext()?this.reduce((function(e,t){return t})):o.Optional.absent},e.prototype.first=function(){return this.reset(),this.hasNext()?o.Optional.fromNullable(this.next()):o.Optional.absent},e.prototype.anyMatch=function(e){for(;this.hasNext();)if(e(this.next()))return!0;return!1},e.prototype.allMatch=function(e){for(;this.hasNext();)if(!e(this.next()))return!1;return!0},e.prototype.noneMatch=function(e){for(;this.hasNext();)if(e(this.next()))return!1;return!0},e.prototype.sort=function(t){var n=this.collect(new i.ArrayCollector);return n=n.sort(t),e.of.apply(e,n)},Object.defineProperty(e.prototype,"value",{get:function(){return this.collect(new i.ArrayCollector)},enumerable:!0,configurable:!0}),e.prototype.stop=function(){this.pos=this._limits+1e9},e.prototype.isOverLimits=function(){return-1!=this._limits&&this.pos>=this._limits-1},e}();t.LazyStream=s},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r,o,i=n(16),a=n(17),s=n(23),u=n(24),l=n(1),c=n(9),f=n(15),p=n(14),h=n(11),v=n(4),d=n(0),E=n(10);!function(e){e.Production="Production",e.Development="Development",e.SystemTest="SystemTest",e.UnitTest="UnitTest"}(r||(r={})),function(e){e.onerror="onerror",e.onevent="onevent",e.render="render",e.execute="execute",e.myfaces="myfaces",e.delay="delay",e.timeout="timeout",e.windowId="windowId"}(o||(o={})),function(e){var t=l.Lang.trim,n=v.ExtLang.getMessage,y=v.ExtLang.getGlobalConfig,_=c.Assertions.assert,m=(i.myfaces.config,[]),g=[];e.requestQueue=null;var T="ERROR";function R(){var e=p.ExtDomquery.searchJsfJsFor(/stage=([^&;]*)/).value;return e in r?e:null}function A(e,t){void 0===t&&(t=function(e){}),t(e),g.forEach((function(t){t(e)})),y("defaultErrorOutput",console?console.error:alert)(e)}function S(e,n,r,o,i){for(var a=r?t(r).split(/\s+/gi):[],s=[],u={},l=0;l<a.length;l++)if(!(a[l]in u))switch(a[l]){case d.IDENT_NONE:return e.delete(n);case d.IDENT_ALL:return e.assign(n).value=d.IDENT_ALL,e;case d.IDENT_FORM:s.push(o.id.value),u[o.id.value]=!0;break;case d.IDENT_THIS:i in u||(s.push(i),u[i]=!0);break;default:s.push(a[l]),u[a[l]]=!0}return e.assign(n).value=s.join(" "),e}e.getSeparatorChar=function(){var e,t,n;return null!=(n=null!=(t=null===(e=null===this||void 0===this?void 0:this.globalConfig)||void 0===e?void 0:e.separator)?t:null===this||void 0===this?void 0:this.separator)?n:p.ExtDomquery.searchJsfJsFor(/separator=([^&;]*)/).orElse(":").value},e.reset=function(){i.myfaces.config,null,null,m=[],g=[],e.requestQueue=null},e.getProjectStage=function(){var e,t,n;return null!=(n=null!=(t=null===(e=null===this||void 0===this?void 0:this.globalConfig)||void 0===e?void 0:e.projectStage)?t:null===this||void 0===this?void 0:this.projectStage)?n:R()},e.resolveProjectStateFromURL=R,e.chain=function(e,n){for(var r=[],o=2;o<arguments.length;o++)r[o-2]=arguments[o];var i=!0;return l.Stream.of.apply(l.Stream,r).each((function(r){return function(r){if("string"!=typeof r)return i=i&&!1!==r.call(e,n);var o=t(r);return 0==o.indexOf("function ")&&(o="return "+o+" (event)"),i=i&&!1!==new Function("event",o).call(e,n)}(r)})),i},e.request=function(t,n,r){var i,a,s,u,f,p=E.resolveDefaults(n,r,t),h=p.resolvedEvent,v=p.options,y=p.elem,_=p.elementId,m=p.requestCtx,g=p.internalCtx,T=p.windowId,R=p.isResetValues;c.Assertions.assertRequestIntegrity(v,y),m.assignIf(!!T,d.P_WINDOW_ID).value=T,m.assign(d.CTX_PARAM_PASS_THR).value=(f=v.value,l.Stream.ofAssoc(f).filter((function(e){return!(e[0]in o)})).collect(new l.AssocArrayCollector)),m.assignIf(!!h,d.CTX_PARAM_PASS_THR,d.P_EVT).value=null===(i=h)||void 0===i?void 0:i.type,m.assign(d.SOURCE).value=_.value,m.assign(d.ON_EVENT).value=null===(a=v.value)||void 0===a?void 0:a.onevent,m.assign(d.ON_ERROR).value=null===(s=v.value)||void 0===s?void 0:s.onerror,m.assign(d.MYFACES).value=null===(u=v.value)||void 0===u?void 0:u.myfaces;var A,b,P,O,M=E.resolveForm(m,y,h);m.assign(d.CTX_PARAM_PASS_THR,d.P_PARTIAL_SOURCE).value=_.value,m.assign(d.CTX_PARAM_PASS_THR,d.P_AJAX).value=!0,m.assign(d.CTX_PARAM_PASS_THR,d.P_PARTIAL_SOURCE).value=_.value,m.assignIf(R,d.CTX_PARAM_PASS_THR,d.P_RESET_VALUES).value=!0,g.assign(d.CTX_PARAM_SRC_FRM_ID).value=M.id.value,g.assign(d.CTX_PARAM_SRC_CTL_ID).value=_.value,g.assign(d.CTX_PARAM_TR_TYPE).value=d.REQ_TYPE_POST,m.assign(d.CTX_PARAM_PASS_THR,M.id.value).value=M.id.value,function(e,t){var n=jsf.getClientWindow(e.getAsElem(0).value);n&&(t.assign(d.CTX_PARAM_PASS_THR,d.P_CLIENT_WINDOW).value=n)}(M,m),A=v,b=m,P=M,O=_.value,A.getIf(d.CTX_PARAM_EXECUTE).isPresent()?(A.assign(d.CTX_PARAM_EXECUTE).value=[A.getIf(d.CTX_PARAM_EXECUTE).value,d.IDENT_THIS].join(" "),S(b.getIf(d.CTX_PARAM_PASS_THR).get({}),d.P_EXECUTE,A.getIf(d.CTX_PARAM_EXECUTE).value,P,O)):b.assign(d.CTX_PARAM_PASS_THR,d.P_EXECUTE).value=O,function(e,t,n,r){e.getIf(d.RENDER).isPresent()&&S(t.getIf(d.CTX_PARAM_PASS_THR).get({}),d.P_RENDER,e.getIf(d.RENDER).value,n,r)}(v,m,M,_.value);var N=E.resolveDelay(v),C=E.resolveTimeout(v);e.queueHandler.addRequestToQueue(y,M,m,g,N,C)},e.response=function(e,t){a.Response.processResponse(e,t)},e.addOnError=function(e){g.push(e)},e.addOnEvent=function(e){m.push(e)},e.sendEvent=function(e,t){void 0===t&&(t=function(e){}),t(e),m.forEach((function(t){return t(e)}))},e.stdErrorHandler=function(t,n,r,o){void 0===o&&(o=!1);try{if("ERROR"==T)A(h.ErrorData.fromClient(r))}finally{o&&e.requestQueue.cleanup()}},e.sendError=A,e.getClientWindow=function(e){var t,n="___mf_id_altered__",r=new l.DQ(e||document.body).stream.map((function(e){return e.attr("value").value})).reduce((function(e,t){return e==n?e:"___init____"==e?t:e!=t?n:t}),"___init____");return _(r.value!=n,"Multiple different windowIds found in document"),null!=(t=r.value)?t:p.ExtDomquery.searchJsfJsFor(/jfwid=([^&;]*)/).orElse(null).value},e.getViewState=function(e){var t=l.DQ.byId(e);if(!t.isTag(d.TAG_FORM))throw new Error(n("ERR_VIEWSTATE"));return new f.XhrFormData(t).toString()},e.queueHandler={addRequestToQueue:function(t,n,r,o,i,a){void 0===i&&(i=0),void 0===a&&(a=0),e.requestQueue=null!==e.requestQueue&&void 0!==e.requestQueue?e.requestQueue:new u.AsynchronouseQueue,e.requestQueue.enqueue(new s.XhrRequest(t,n,r,o,[],a),i)}}}(t.Implementation||(t.Implementation={}))},function(e,t,n){"use strict";var r=this&&this.__spreadArrays||function(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),o=0;for(t=0;t<n;t++)for(var i=arguments[t],a=0,s=i.length;a<s;a++,o++)r[o]=i[a];return r};Object.defineProperty(t,"__esModule",{value:!0});var o=n(6),i=function(){function e(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];this.dataPos=-1,this.value=e}return e.prototype.hasNext=function(){return this.value.length-1>this.dataPos},e.prototype.next=function(){return this.dataPos++,this.value[this.dataPos]},e.prototype.reset=function(){this.dataPos=-1},e}();t.ArrayStreamDataSource=i;var a=function(){function e(e,t){this.filteredNext=null,this.filterFunc=e,this.inputDataSource=t}return e.prototype.hasNext=function(){for(;null==this.filteredNext&&this.inputDataSource.hasNext();){var e=this.inputDataSource.next();if(this.filterFunc(e))return this.filteredNext=e,!0;this.filteredNext=null}return null!=this.filteredNext},e.prototype.next=function(){var e=this.filteredNext;return this.filteredNext=null,this.hasNext(),e},e.prototype.reset=function(){this.filteredNext=null,this.inputDataSource.reset()},e}();t.FilteredStreamDatasource=a;var s=function(){function e(e,t){this.mapFunc=e,this.inputDataSource=t}return e.prototype.hasNext=function(){return this.inputDataSource.hasNext()},e.prototype.next=function(){return this.mapFunc(this.inputDataSource.next())},e.prototype.reset=function(){this.inputDataSource.reset()},e}();t.MappedStreamDataSource=s;var u=function(){function e(e,t){this.mapFunc=e,this.inputDataSource=t}return e.prototype.hasNext=function(){return this.resolveCurrentNext()||this.resolveNextNext()},e.prototype.resolveCurrentNext=function(){var e=!1;return this.activeDataSource&&(e=this.activeDataSource.hasNext()),e},e.prototype.resolveNextNext=function(){for(var e=!1;!e&&this.inputDataSource.hasNext();){var t=this.mapFunc(this.inputDataSource.next());Array.isArray(t)?this.activeDataSource=new(i.bind.apply(i,r([void 0],t))):this.activeDataSource=t,e=this.activeDataSource.hasNext()}return e},e.prototype.next=function(){return this.activeDataSource.next()},e.prototype.reset=function(){this.inputDataSource.reset()},e}();t.FlatMapStreamDataSource=u;var l=function(){function e(){this.data=[]}return e.prototype.collect=function(e){this.data.push(e)},Object.defineProperty(e.prototype,"finalValue",{get:function(){return this.data},enumerable:!0,configurable:!0}),e}();t.ArrayCollector=l;var c=function(){function e(){this.finalValue={}}return e.prototype.collect=function(e){var t,n;this.finalValue[(t=e[0],null!=t?t:e)]=null==(n=e[1])||n},e}();t.AssocArrayCollector=c;var f=function(){function e(){this.finalValue=new FormData}return e.prototype.collect=function(e){this.finalValue.append(e.key,e.value)},e}();t.FormDataCollector=f;var p=function(){function e(){this.finalValue=new FormData}return e.prototype.collect=function(e){var t=e.encodeFormElement();t.isPresent()&&this.finalValue.append(e.name.value,t.get(e.name).value)},e}();t.QueryFormDataCollector=p;var h=function(){function e(){this.formData=[]}return e.prototype.collect=function(e){var t=e.encodeFormElement();t.isPresent()&&this.formData.push([e.name.value,t.get(e.name).value])},Object.defineProperty(e.prototype,"finalValue",{get:function(){return o.Stream.of.apply(o.Stream,this.formData).map((function(e){return e.join("=")})).reduce((function(e,t){return[e,t].join("&")})).orElse("").value},enumerable:!0,configurable:!0}),e}();t.QueryFormStringCollector=h},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n(4),i=o.ExtLang.getMessage,a=o.ExtLang.makeException,s=n(0);!function(e){function t(t,n,r,o){if(void 0===n&&(n=s.EMPTY_STR),void 0===r&&(r=s.EMPTY_STR),void 0===o&&(o="Assertion Error"),!t)throw e.raiseError(new Error,n,r,o)}function n(t,n,o,i,a){if(void 0===o&&(o=s.EMPTY_STR),void 0===i&&(i=s.EMPTY_STR),void 0===a&&(a="Type Assertion Error"),t&&!r.Lang.assertType(t,n))throw e.raiseError(new Error,o,i,a)}function o(e,t,r,o){void 0===t&&(t=s.EMPTY_STR),void 0===r&&(r=s.EMPTY_STR),void 0===o&&(o="Assertion Error"),n(e,"function",t,r,o)}e.assertRequestIntegrity=function(e,n){o(e.getIf(s.ON_ERROR).value),o(e.getIf(s.ON_EVENT).value),t(n.isPresent(),i("ERR_MUST_BE_PROVIDED1","{0}: source  must be provided or exist","source element id"),"jsf.ajax.request","ArgNotSet")},e.assertUrlExists=function(t){if(t.attr(s.ATTR_URL).isAbsent())throw e.raiseError(new Error,i("ERR_RED_URL",null,"_Ajaxthis.processRedirect"),"processRedirect")},e.assertValidXMLResponse=function(e){t(!e.isAbsent(),s.EMPTY_RESPONSE,s.PHASE_PROCESS_RESPONSE),t(!e.isXMLParserError(),e.parserErrorText(s.EMPTY_STR),s.PHASE_PROCESS_RESPONSE),t(e.querySelectorAll(s.RESP_PARTIAL).isPresent(),s.ERR_NO_PARTIAL_RESPONSE,s.PHASE_PROCESS_RESPONSE)},e.raiseError=function(e,t,n,r,o){var i=null!=r?r:s.MALFORMEDXML,u=null!=o?o:s.MALFORMEDXML,l=null!=t?t:s.EMPTY_STR;return a(e,i,u,"Response",n||(arguments.caller?arguments.caller.toString():"_raiseError"),l)},e.assert=t,e.assertType=n,e.assertFunction=o}(t.Assertions||(t.Assertions={}))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n(0),i=n(4),a=n(14);function s(e){var t,n,r;return null!=(r=null===(n=null===(t=e)||void 0===t?void 0:t.value)||void 0===n?void 0:n.windowId)?r:a.ExtDomquery.windowId}function u(e){var t,n;return null!=(n=null!=e?e:null===(t=window)||void 0===t?void 0:t.event)?n:{}}t.resolveHandlerFunc=function(e,t,n){return t.getIf(n).orElse(e.getIf(n).value).orElse(o.EMPTY_FUNC).value},t.resolveTargetUrl=function(e){return void 0===e.elements[o.ENCODED_URL]?e.action:e.elements[o.ENCODED_URL].value},t.resolveFinalUrl=function(e,t,n){return void 0===n&&(n=o.REQ_TYPE_POST),this.resolveTargetUrl(e.getAsElem(0).value)+(n==o.REQ_TYPE_GET?"?"+t.toString():o.EMPTY_STR)},t.resolveForm=function(e,t,n){var a,s,u,l=null!=(u=null===(s=null===(a=e.value)||void 0===a?void 0:a.myfaces)||void 0===s?void 0:s.form)?u:o.MF_NONE;return r.DQ.byId(l).orElseLazy((function(){return i.ExtLang.getForm(t.getAsElem(0).value,n)}))},t.resolveTimeout=function(e){var t,n=i.ExtLang.getLocalOrGlobalConfig;return null!=(t=e.getIf(o.CTX_PARAM_TIMEOUT).value)?t:n(e.value,o.CTX_PARAM_TIMEOUT,0)},t.resolveDelay=function(e){var t,n=i.ExtLang.getLocalOrGlobalConfig;return null!=(t=e.getIf(o.CTX_PARAM_DELAY).value)?t:n(e.value,o.CTX_PARAM_DELAY,0)},t.resolveWindowId=s,t.resolveEvent=u,t.getEventTarget=function(e){for(var t,n,r,o,i,a=this.resolveEvent(e),s=null!=(o=null!=(n=null===(t=a)||void 0===t?void 0:t.srcElement)?n:null===(r=a)||void 0===r?void 0:r.target)?o:null===(i=a)||void 0===i?void 0:i.source;s&&1!=s.nodeType;)s=s.parentNode;return s},t.resolveDefaults=function(e,t,n){var o;void 0===t&&(t={}),void 0===n&&(n=null);var i=u(e),a=new r.Config(t).deepCopy,l=r.DQ.byId(n||i.target);return{resolvedEvent:i,options:a,elem:l,elementId:l.id,requestCtx:new r.Config({}),internalCtx:new r.Config({}),windowId:s(a),isResetValues:!0===(null===(o=a.value)||void 0===o?void 0:o.resetValues)}}},function(e,t,n){"use strict";var r,o=this&&this.__extends||(r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)});Object.defineProperty(t,"__esModule",{value:!0});var i,a=n(0),s=n(12),u=n(4).ExtLang.getMessage;!function(e){e.SERVER_ERROR="serverError",e.HTTP_ERROR="httpError",e.CLIENT_ERROR="clientErrror",e.TIMEOUT="timeout"}(i=t.ErrorType||(t.ErrorType={}));var l=function(e){function t(t,n,r,o,a,s,u,l){void 0===o&&(o=null),void 0===a&&(a=null),void 0===s&&(s="200"),void 0===u&&(u="UNKNOWN"),void 0===l&&(l=i.CLIENT_ERROR);var c=e.call(this)||this;return c.type="error",c.source=t,c.type="error",c.errorName=n,c.message=c.errorMessage=r,c.responseCode=s,c.responseText=o,c.status=u,c.typeDetails=l,l==i.SERVER_ERROR&&(c.serverErrorName=c.errorName,c.serverErrorMessage=c.errorMessage),c}return o(t,e),t.fromClient=function(e){return new t("client",e.name,e.message,e.stack)},t.fromHttpConnection=function(e,n,r,o,a){return new t(e,n,r,o,a,null,"UNKNOWN",i.HTTP_ERROR)},t.fromGeneric=function(e,n,r){void 0===r&&(r=i.SERVER_ERROR);var o=this.getMsg,s=o(e,a.SOURCE),u=(o(e,a.ERROR_NAME),o(e,a.ERROR_MESSAGE)),l=o(e,a.STATUS),c=o(e,a.RESPONSE_TEXT),f=o(e,a.RESPONSE_XML);return new t(s,name,u,c,f,n+a.EMPTY_STR,l,r)},t.getMsg=function(e,t){return u(e.getIf(t).orElse("UNKNOWN").value)},t.fromServerError=function(e){return this.fromGeneric(e,-1)},t}(s.EventData);t.ErrorData=l},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n(0),i=function(){function e(){}return e.createFromRequest=function(t,n,i){var a,s,u,l,c=new e;c.type=o.EVENT,c.status=i;var f=n.getIf(o.SOURCE).orElse(n.getIf(o.P_PARTIAL_SOURCE).value).orElse(n.getIf(o.CTX_PARAM_PASS_THR,o.P_PARTIAL_SOURCE).value).value;return f&&(c.source=r.DQ.byId(f).first().value.value),i!==o.BEGIN&&(c.responseCode=null===(s=null===(a=t)||void 0===a?void 0:a.status)||void 0===s?void 0:s.toString(),c.responseText=null===(u=t)||void 0===u?void 0:u.responseText,c.responseXML=null===(l=t)||void 0===l?void 0:l.responseXML),c},e}();t.EventData=i},function(e,t,n){"use strict";var r,o,i,a=this&&this.__spreadArrays||function(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),o=0;for(t=0;t<n;t++)for(var i=arguments[t],a=0,s=i.length;a<s;a++,o++)r[o]=i[a];return r};Object.defineProperty(t,"__esModule",{value:!0});var s,u=n(7),l=n(25),c=null!=(i=null===(o=null===(r=window)||void 0===r?void 0:r.myfaces)||void 0===o?void 0:o._impl)?i:{};!function(e){e.specversion=22e4,e.implversion=0,e.separatorchar=u.Implementation.getSeparatorChar(),e.getProjectStage=function(){return u.Implementation.getProjectStage()},e.getViewState=function(e){return u.Implementation.getViewState(e)},e.getClientWindow=function(e){return u.Implementation.getClientWindow(e)},function(e){e.request=function(e,t,n){u.Implementation.request(e,t,n)},e.response=function(e,t){u.Implementation.response(e,t)},e.addOnError=function(e){u.Implementation.addOnError(e)},e.addOnEvent=function(e){u.Implementation.addOnEvent(e)}}(e.ajax||(e.ajax={})),function(e){e.chain=function(e,t){for(var n=[],r=2;r<arguments.length;r++)n[r-2]=arguments[r];return u.Implementation.chain.apply(u.Implementation,a([e,t],n))}}(e.util||(e.util={})),function(e){e.init=function(e,t,n,r,o,i,a,s){l.PushImpl.init(e,t,n,r,o,i,a,s)},e.open=function(e){l.PushImpl.open(e)},e.close=function(e){l.PushImpl.close(e)}}(e.push||(e.push={}))}(s=t.jsf||(t.jsf={})),function(e){var t,n,r;function o(e,t,n,r,o,i){void 0===i&&(i={}),n&&(i["javax.faces.behavior.event"]=n),r&&(i.execute=r),o&&(i.render=o),s.ajax.request(e,t,i)}e._impl=c,e.ab=o,"undefined"==(null===(n=null===(t=window)||void 0===t?void 0:t.myfaces)||void 0===n?void 0:n.ab)&&(window.myfaces=null!=(r=window.myfaces)?r:{},window.myfaces.ab=o)}(t.myfaces||(t.myfaces={}))},function(e,t,n){"use strict";var r,o=this&&this.__extends||(r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)});Object.defineProperty(t,"__esModule",{value:!0});var i=n(2),a=n(5),s=n(0),u=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return o(t,e),Object.defineProperty(t,"windowId",{get:function(){return new t(document.body).windowId},enumerable:!0,configurable:!0}),Object.defineProperty(t,"nonce",{get:function(){return new t(document.body).nonce},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"windowId",{get:function(){var e=function(){var e=window.location.href,t=new RegExp("[\\?&]windowId=([^&#\\;]*)").exec(e);return null!=t?t[1]:null};if(this.value.isPresent()){var t=this.querySelectorAll("form input[name='"+s.P_WINDOW_ID+"']");if(t.length>0)throw Error("Multiple different windowIds found in document");return t.isPresent()?t.getAsElem(0).value.value:e()}return e()},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"nonce",{get:function(){var e=new i.Config(window.myfaces).assign("config","cspMeta","nonce");if(e.value)return e.value;var t=new a.DQ(document.currentScript);if(null!=t.attr("nonce").value)return t.attr("nonce").value;var n=a.DQ.querySelectorAll("script[src], link[src]").lazyStream.filter((function(e){return null!=e.attr("nonce").value&&null!=e.attr("src")})).map((function(e){return!e.attr("src").value.match(/jsf\.js\?ln\=javax\.faces/gi)})).first();return n.isPresent()&&(e.value=a.DomQuery.byId(n.value).attr("nonce").value),e.value},enumerable:!0,configurable:!0}),t.searchJsfJsFor=function(e){return new t(document).searchJsfJsFor(e)},t.prototype.searchJsfJsFor=function(e){return a.DQ.querySelectorAll("script").lazyStream.filter((function(e){var t;return-1!=(t=e.attr("src").value,null!=t?t:s.EMPTY_STR).search(/\/javax\.faces\.resource.*\/jsf\.js.*separator/)})).map((function(t){var n=t.attr("src").value.match(e);return decodeURIComponent(n[1])})).first()},t.prototype.globalEval=function(t,n){return e.prototype.globalEval.call(this,t,null!=n?n:this.nonce)},t}(a.DQ);t.ExtDomquery=u,t.ExtDQ=a.DQ},function(e,t,n){"use strict";var r,o=this&&this.__extends||(r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),i=this&&this.__spreadArrays||function(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),o=0;for(t=0;t<n;t++)for(var i=arguments[t],a=0,s=i.length;a<s;a++,o++)r[o]=i[a];return r};Object.defineProperty(t,"__esModule",{value:!0});var a=n(1),s=n(1),u=n(1),l=a.Lang.isString,c=n(0),f=function(e){function t(t,n,r){void 0===r&&(r=!0);var o=e.call(this,{})||this;return o.dataSource=t,o.partialIdsArray=n,o.encode=r,l(t)?o.assignEncodedString(o.dataSource):o.handleFormSource(),o}return o(t,e),t.prototype.handleFormSource=function(){this.encodeSubmittableFields(this,this.dataSource,this.partialIdsArray),this.getIf(c.P_VIEWSTATE).isPresent()||this.applyViewState(this.dataSource)},t.prototype.applyViewState=function(e){var t=e.byId(c.P_VIEWSTATE).inputValue;this.assignIf(t.isPresent(),c.P_VIEWSTATE).value=t.value},t.prototype.assignEncodedString=function(e){var t=this,n=e.split(/&/gi);s.Stream.of.apply(s.Stream,n).map((function(e){return e.split(/=(.*)/gi)})).map((function(e){var t,n,r,o;return e.length<3?[(n=null===(t=e)||void 0===t?void 0:t[0],null!=n?n:[]),(o=null===(r=e)||void 0===r?void 0:r[1],null!=o?o:[])]:e})).each((function(e){var n,r,o;t.assign(e[0]).value=null!=(o=null===(r=null===(n=e)||void 0===n?void 0:n.splice(1))||void 0===r?void 0:r.join(""))?o:""}))},t.prototype.toFormData=function(){var e=new FormData;for(var t in this.value)this.value.hasOwnProperty(t)&&e.append(t,this.value[t]);return e},t.prototype.toString=function(e){if(void 0===e&&(e=c.EMPTY_STR),this.isAbsent())return e;var t=[];for(var n in this.value)this.value.hasOwnProperty(n)&&t.push(encodeURIComponent(n)+"="+encodeURIComponent(this.value[n]));return t.join("&")},t.prototype.encodeSubmittableFields=function(e,t,n){var r=null;if(this.partialIdsArray&&this.partialIdsArray.length)this._value={},r=new(u.DQ.bind.apply(u.DQ,i([void 0],this.partialIdsArray)));else{if(t.isAbsent())throw"NO_PARITEM";r=t}this.shallowMerge(r.querySelectorAll("input, checkbox, select, textarea").encodeFormElement())},Object.defineProperty(t.prototype,"isMultipartRequest",{get:function(){return this.dataSource instanceof u.DQ&&this.dataSource.querySelectorAll("input[type='file']").isPresent()},enumerable:!0,configurable:!0}),t}(a.Config);t.XhrFormData=f},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e){var t=function(){this.projectStage=null,this.separator=null};e.ConfigHolder=t,e.config=new t}(t.myfaces||(t.myfaces={}))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n(19),i=n(0),a=n(22);!function(e){e.processResponse=function(e,n){var s=r.Config.fromNullable(e),u=a.resolveContexts(n),l=u.externalContext,c=u.internalContext,f=a.resolveResponseXML(s),p=new o.ResponseProcessor(s,l,c);c.assign(i.RESPONSE_XML).value=f,f.querySelectorAll(i.RESP_PARTIAL).each((function(e){return function(e,n,o){o.assign(i.PARTIAL_ID).value=e.id;var a=[i.CMD_ERROR,i.CMD_REDIRECT,i.CMD_CHANGES].join(",");e.getIf(a).each((function(e){switch(e.tagName.value){case i.CMD_ERROR:n.error(e);break;case i.CMD_REDIRECT:n.redirect(e);break;case i.CMD_CHANGES:!function(e,n){var o=[i.CMD_UPDATE,i.CMD_EVAL,i.CMD_INSERT,i.CMD_DELETE,i.CMD_ATTRIBUTES,i.CMD_EXTENSION].join(",");e.getIf(o).each((function(e){switch(e.tagName.value){case i.CMD_UPDATE:!function(e,t){t.processViewState(e)||function(e,t){var n=e.cDATAAsString;switch(e.id.value){case i.P_VIEWROOT:t.replaceViewRoot(r.DQ.fromMarkup(n.substring(n.indexOf("<html"))));break;case i.P_VIEWHEAD:t.replaceHead(r.DQ.fromMarkup(n));break;case i.P_VIEWBODY:t.replaceBody(r.DQ.fromMarkup(n));break;default:t.update(e,n)}}(e,t)}(e,n);break;case i.CMD_EVAL:n.eval(e);break;case i.CMD_INSERT:t(n,e);break;case i.CMD_DELETE:n.delete(e);break;case i.CMD_ATTRIBUTES:n.attributes(e);break;case i.CMD_EXTENSION:}}))}(e,n)}}))}(e,p,c)})),p.fixViewStates(),p.globalEval(),p.done()};var t=function(e,t){t.querySelectorAll([i.TAG_BEFORE,i.TAG_AFTER].join(",")).length?e.insertWithSubtags(t):e.insert(t)}}(t.Response||(t.Response={}))},function(e,t,n){"use strict";var r,o=this&&this.__extends||(r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)});Object.defineProperty(t,"__esModule",{value:!0});var i=n(3),a=n(5),s=i.Lang.isString,u=function(e){function t(t,n){void 0===n&&(n="text/xml");var r;return s(t)?e.call(this,null==(r=t)?null:i.Lang.saveResolveLazy((function(){return new window.DOMParser}),(function(){return(e=new ActiveXObject("Microsoft.XMLDOM")).async=!1,{parseFromString:function(t,n){return e.loadXML(t)}};var e})).value.parseFromString(r,n))||this:e.call(this,t)||this}return o(t,e),t.prototype.isXMLParserError=function(){return this.querySelectorAll("parsererror").isPresent()},t.prototype.toString=function(){var e=[];return this.eachElem((function(t){var n,r,o,i,a,s=null!=(i=null===(o=null===(r=null===(n=window)||void 0===n?void 0:n.XMLSerializer)||void 0===r?void 0:r.constructor())||void 0===o?void 0:o.serializeToString(t))?i:null===(a=t)||void 0===a?void 0:a.xml;s&&e.push(s)})),e.join("")},t.prototype.parserErrorText=function(e){return this.querySelectorAll("parsererror").textContent(e)},t.parseXML=function(e){return new t(e)},t.parseHTML=function(e){return new t(e,"text/html")},t.fromString=function(e,n){return void 0===n&&(n="text/xml"),new t(e,n)},t}(a.DomQuery);t.XMLQuery=u,t.XQ=u},function(e,t,n){"use strict";var r=this&&this.__spreadArrays||function(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),o=0;for(t=0;t<n;t++)for(var i=arguments[t],a=0,s=i.length;a<s;a++,o++)r[o]=i[a];return r};Object.defineProperty(t,"__esModule",{value:!0});var o=n(1),i=n(7),a=n(9),s=n(11),u=n(21),l=n(12),c=n(0),f=o.Lang.trim,p=function(){function e(e,t,n){this.request=e,this.externalContext=t,this.internalContext=n}return e.prototype.replaceHead=function(e){var t=e.querySelectorAll(c.TAG_HEAD);t.isPresent()&&(o.DQ.querySelectorAll(c.TAG_HEAD).querySelectorAll(c.SEL_SCRIPTS_STYLES).delete(),this.storeForEval(t))},e.prototype.replaceBody=function(e){var t=e.querySelectorAll(c.TAG_BODY);if(t.isPresent()){var n=t.html().value,r=o.DQ.querySelectorAll(c.TAG_BODY).html(n),i=r.querySelectorAll(c.TAG_FORM);r.copyAttrs(t),this.storeForPostProcessing(i,r)}},e.prototype.eval=function(e){o.DQ.globalEval(e.cDATAAsString)},e.prototype.error=function(e){var t=new o.Config({});t.assign(c.SOURCE).value=this.externalContext.getIf(c.P_PARTIAL_SOURCE).get(0).value,t.assign(c.ERROR_NAME).value=e.getIf(c.ERROR_NAME).textContent(c.EMPTY_STR),t.assign(c.ERROR_MESSAGE).value=e.getIf(c.ERROR_MESSAGE).cDATAAsString;var n=this.internalContext.get(c.RESPONSE_XML).isPresent();t.assignIf(n,c.RESPONSE_XML).value=this.internalContext.getIf(c.RESPONSE_XML).value.get(0).value;var r=s.ErrorData.fromServerError(t);this.externalContext.getIf(c.ON_ERROR).orElse(this.internalContext.getIf(c.ON_ERROR).value).orElse(c.EMPTY_FUNC).value(r),i.Implementation.sendError(r)},e.prototype.redirect=function(e){a.Assertions.assertUrlExists(e);var t=f(e.attr(c.ATTR_URL).value);t!=c.EMPTY_STR&&(window.location.href=t)},e.prototype.update=function(e,t){var n,r=o.DQ.byId(e.id.value).outerHTML(t,!1,!1),i=null===(n=r)||void 0===n?void 0:n.parents(c.TAG_FORM).orElse(r.byTagName(c.TAG_FORM,!0));i&&this.storeForPostProcessing(i,r)},e.prototype.delete=function(e){o.DQ.byId(e.id.value).delete()},e.prototype.attributes=function(e){var t=o.DQ.byId(e.id.value);e.byTagName(c.TAG_ATTR).each((function(e){t.attr(e.attr(c.ATTR_NAME).value).value=e.attr(c.ATTR_VALUE).value}))},e.prototype.replaceViewRoot=function(e){this.replaceHead(e),this.replaceBody(e)},e.prototype.insert=function(e){var t=e.attr(c.TAG_BEFORE),n=e.attr(c.TAG_AFTER),r=o.DQ.fromMarkup(e.cDATAAsString);(t.isPresent()&&(o.DQ.byId(t.value).insertBefore(r),this.internalContext.assign(c.UPDATE_ELEMS).value.push(r)),n.isPresent())&&(o.DQ.byId(n.value).insertAfter(r),this.internalContext.assign(c.UPDATE_ELEMS).value.push(r))},e.prototype.insertWithSubtags=function(e){var t=this,n=e.querySelectorAll(c.TAG_BEFORE),r=e.querySelectorAll(c.TAG_AFTER);n.each((function(e){var n=e.attr(c.ATTR_ID),r=o.DQ.fromMarkup(e.cDATAAsString);n.isPresent()&&(o.DQ.byId(n.value).insertBefore(r),t.internalContext.assign(c.UPDATE_ELEMS).value.push(r))})),r.each((function(e){var n=e.attr(c.ATTR_ID),r=o.DQ.fromMarkup(e.cDATAAsString);n.isPresent()&&(o.DQ.byId(n.value).insertAfter(r),t.internalContext.assign(c.UPDATE_ELEMS).value.push(r))}))},e.prototype.processViewState=function(t){if(e.isViewStateNode(t)){var n=t.cDATAAsString;return this.internalContext.assign(c.APPLIED_VST,t.id.value).value=new u.ViewState(t.id.value,n),!0}return!1},e.prototype.globalEval=function(){var e=new(o.DQ.bind.apply(o.DQ,r([void 0],this.internalContext.getIf(c.UPDATE_ELEMS).value)));e.runCss(),e.runScripts()},e.prototype.fixViewStates=function(){var e=this;o.Stream.ofAssoc(this.internalContext.getIf(c.APPLIED_VST).orElse({}).value).each((function(t){var n=t[1],r=o.DQ.byId(n.nameSpace).orElse(document.body),i=r.byTagName(c.TAG_FORM),a=r.filter((function(e){return e.tagName.orElse(c.EMPTY_STR).value.toLowerCase()==c.TAG_FORM}));e.appendViewStateToForms(new o.DomQuery(i,a),n.value)}))},e.prototype.done=function(){var e=l.EventData.createFromRequest(this.request.value,this.externalContext,c.SUCCESS),t=this.externalContext.getIf(c.ON_EVENT).orElse(this.internalContext.getIf(c.ON_EVENT).value).orElse(c.EMPTY_FUNC).value;i.Implementation.sendEvent(e,t)},e.prototype.appendViewStateToForms=function(t,n){t.each((function(t){t.querySelectorAll(c.SEL_VIEWSTATE_ELEM).orElseLazy((function(){return e.newViewStateElement(t)})).attr("value").value=n}))},e.newViewStateElement=function(e){var t=o.DQ.fromMarkup(c.HTML_VIEWSTATE);return t.appendTo(e),t},e.prototype.storeForPostProcessing=function(e,t){this.storeForUpdate(e),this.storeForEval(t)},e.prototype.storeForUpdate=function(e){this.internalContext.assign(c.UPDATE_FORMS).value.push(e)},e.prototype.storeForEval=function(e){this.internalContext.assign(c.UPDATE_ELEMS).value.push(e)},e.isViewStateNode=function(e){var t,n,r,o,i,a,s,u,l,f,p=window.jsf.separatorchar;return void 0!==(null===(n=null===(t=e)||void 0===t?void 0:t.id)||void 0===n?void 0:n.value)&&((null===(o=null===(r=e)||void 0===r?void 0:r.id)||void 0===o?void 0:o.value)==c.P_VIEWSTATE||-1!=(null===(s=null===(a=null===(i=e)||void 0===i?void 0:i.id)||void 0===a?void 0:a.value)||void 0===s?void 0:s.indexOf([p,c.P_VIEWSTATE].join(c.EMPTY_STR)))||-1!=(null===(f=null===(l=null===(u=e)||void 0===u?void 0:u.id)||void 0===l?void 0:l.value)||void 0===f?void 0:f.indexOf([c.P_VIEWSTATE,p].join(c.EMPTY_STR))))},e}();t.ResponseProcessor=p},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){this.MSG_TEST="Testmessage",this.MSG_DEV_MODE="Note, this message is only sent, because project stage is development and no other error listeners are registered.",this.MSG_AFFECTED_CLASS="Affected Class=",this.MSG_AFFECTED_METHOD="Affected Method=",this.MSG_ERROR_NAME="Error Name=",this.MSG_ERROR_MESSAGE="Error Message=",this.MSG_SERVER_ERROR_NAME="Server Error Name=",this.MSG_ERROR_DESC="Error Description=",this.MSG_ERROR_NO="Error Number=",this.MSG_ERROR_LINENO="Error Line Number=",this.ERR_FORM="Sourceform could not be determined, either because element is not attached to a form or we have multiple forms with named elements of the same identifier or name, stopping the ajax processing",this.ERR_VIEWSTATE="jsf.viewState= param value not of type form!",this.ERR_TRANSPORT="Transport type {0} does not exist",this.ERR_EVT_PASS="an event must be passed down (either a an event object null or undefined) ",this.ERR_CONSTRUCT="Parts of the response couldn't be retrieved when constructing the event data= {0} ",this.ERR_MALFORMEDXML="The server response could not be parsed, the server has returned with a response which is not xml !",this.ERR_SOURCE_FUNC="source cannot be a function (probably source and event were not defined or set to null",this.ERR_EV_OR_UNKNOWN="An event object or unknown must be passed as second parameter",this.ERR_SOURCE_NOSTR="source cannot be a string",this.ERR_SOURCE_DEF_NULL="source must be defined or null",this.ERR_MUST_STRING="{0}: {1} namespace must be of type String",this.ERR_REF_OR_ID="{0}: {1} a reference node or identifier must be provided",this.ERR_PARAM_GENERIC="{0}: parameter {1} must be of type {2}",this.ERR_PARAM_STR="{0}: {1} param must be of type string",this.ERR_PARAM_STR_RE="{0}: {1} param must be of type string or a regular expression",this.ERR_PARAM_MIXMAPS="{0}: both a source as well as a destination map must be provided",this.ERR_MUST_BE_PROVIDED="{0}: an {1} and a {2} must be provided",this.ERR_MUST_BE_PROVIDED1="{0}: {1} must be set",this.ERR_REPLACE_EL="replaceElements called while evalNodes is not an array",this.ERR_EMPTY_RESPONSE="{0}: The response cannot be null or empty!",this.ERR_ITEM_ID_NOTFOUND="{0}: item with identifier {1} could not be found",this.ERR_PPR_IDREQ="{0}: Error in PPR Insert, id must be present",this.ERR_PPR_INSERTBEFID="{0}: Error in PPR Insert, before id or after id must be present",this.ERR_PPR_INSERTBEFID_1="{0}: Error in PPR Insert, before  node of id {1} does not exist in document",this.ERR_PPR_INSERTBEFID_2="{0}: Error in PPR Insert, after  node of id {1} does not exist in document",this.ERR_PPR_DELID="{0}: Error in delete, id not in xml markup",this.ERR_PPR_UNKNOWNCID="{0}:  Unknown Html-Component-ID= {1}",this.ERR_NO_VIEWROOTATTR="{0}: Changing of ViewRoot attributes is not supported",this.ERR_NO_HEADATTR="{0}: Changing of Head attributes is not supported",this.ERR_RED_URL="{0}: Redirect without url",this.ERR_REQ_FAILED_UNKNOWN="Request failed with unknown status",this.ERR_REQU_FAILED="Request failed with status {0} and reason {1}",this.UNKNOWN="UNKNOWN"};t.Messages=r},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(0),o=function(){function e(e,t){this.id=e,this.value=t;var n=e.indexOf(r.P_VIEWSTATE);this.nameSpace=n>0?e.substr(0,n-1):r.EMPTY_STR}return Object.defineProperty(e.prototype,"hasNameSpace",{get:function(){var e;return!!(e=null===this||void 0===this?void 0:this.nameSpace,null!=e?e:r.EMPTY_STR).length},enumerable:!0,configurable:!0}),e}();t.ViewState=o},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n(9),i=n(1),a=n(0);t.resolveResponseXML=function(e){var t=new r.XMLQuery(e.getIf(a.SEL_RESPONSE_XML).value);return o.Assertions.assertValidXMLResponse(t),t},t.resolveContexts=function(e){var t=r.Config.fromNullable(e),n=t.getIf(a.CTX_PARAM_MF_INTERNAL);return n.isPresent()||(n=r.Config.fromNullable({})),n.assign(a.UPDATE_FORMS).value=[],n.assign(a.UPDATE_ELEMS).value=[],{externalContext:t,internalContext:n}},t.resolveSourceElement=function(e,t){var n=function(e,t){return t.getIf(a.CTX_PARAM_SRC_CTL_ID).orElseLazy((function(){return e.getIf(a.SOURCE,"id").value}))}(e,t);return i.DQ.byId(n.value)},t.resolveSourceForm=function(e,t){var n=e.getIf(a.CTX_PARAM_SRC_FRM_ID),r=new i.DQ(n.isPresent()?document.forms[n.value]:null);return r=r.orElse(t.parents(a.TAG_FORM)).orElse(t.querySelectorAll(a.TAG_FORM)).orElse(i.DQ.querySelectorAll(a.TAG_FORM))}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),o=n(7),i=n(15),a=n(11),s=n(12),u=n(4),l=n(0),c=n(10),f=u.ExtLang.failSaveExecute,p=function(){function e(e,t,n,r,o,i,a,s,u){var c=this;void 0===o&&(o=[]),void 0===i&&(i=l.NO_TIMEOUT),void 0===a&&(a=l.REQ_TYPE_POST),void 0===s&&(s=l.URL_ENCODED),void 0===u&&(u=new XMLHttpRequest),this.source=e,this.sourceForm=t,this.requestContext=n,this.internalContext=r,this.partialIdsArray=o,this.timeout=i,this.ajaxType=a,this.contentType=s,this.xhrObject=u,this.stopProgress=!1,this.catchFuncs=[],this.thenFunc=[],this.registerXhrCallbacks((function(e){c.resolve(e)}),(function(e){c.reject(e)}))}return e.prototype.start=function(){var e=this,t=f,n=this.xhrObject;try{var r=jsf.getViewState(this.sourceForm.getAsElem(0).value),o=new i.XhrFormData(decodeURIComponent(r));this.contentType=o.isMultipartRequest?l.MULTIPART:this.contentType;var a=this.requestContext,s=a.getIf(l.CTX_PARAM_PASS_THR);o.shallowMerge(s),this.responseContext=s.deepCopy;var u=this.responseContext;u.assign(l.CTX_PARAM_MF_INTERNAL).value=this.internalContext.value,u.assign(l.ON_EVENT).value=a.getIf(l.ON_EVENT).value,u.assign(l.ON_ERROR).value=a.getIf(l.ON_ERROR).value,n.open(this.ajaxType,c.resolveFinalUrl(this.sourceForm,o,this.ajaxType),!0),this.timeout&&(n.timeout=this.timeout),t((function(){return n.setRequestHeader(l.CONTENT_TYPE,e.contentType+"; charset=utf-8")})),t((function(){return n.setRequestHeader(l.HEAD_FACES_REQ,l.VAL_AJAX)})),t((function(){return n.setRequestHeader(l.REQ_ACCEPT,l.STD_ACCEPT)})),this.sendEvent(l.BEGIN),this.sendRequest(o)}catch(e){this.handleError(e)}return this},e.prototype.cancel=function(){try{this.xhrObject.abort()}catch(e){this.handleError(e)}},e.prototype.resolve=function(e){r.Stream.of.apply(r.Stream,this.thenFunc).reduce((function(e,t){return t(e)}),e)},e.prototype.reject=function(e){r.Stream.of.apply(r.Stream,this.catchFuncs).reduce((function(e,t){return t(e)}),e)},e.prototype.catch=function(e){return this.catchFuncs.push(e),this},e.prototype.finally=function(e){return this.catchFuncs.push(e),this.thenFunc.push(e),this},e.prototype.then=function(e){return this.thenFunc.push(e),this},e.prototype.registerXhrCallbacks=function(e,t){var n=this,r=this.xhrObject;r.onabort=function(){n.onAbort(e,t)},r.ontimeout=function(){n.onTimeout(e,t)},r.onload=function(){n.onSuccess(n.xhrObject,e,t)},r.onloadend=function(){n.onDone(n.xhrObject,e,t)},r.onerror=function(r){n.onError(r,e,t)}},e.prototype.onAbort=function(e,t){t()},e.prototype.onTimeout=function(e,t){this.sendEvent(l.STATE_EVT_TIMEOUT),t()},e.prototype.onSuccess=function(e,t,n){var r,o;this.sendEvent(l.COMPLETE),(null===(r=null===this||void 0===this?void 0:this.xhrObject)||void 0===r?void 0:r.responseXML)?jsf.ajax.response(this.xhrObject,null!=(o=this.responseContext.value)?o:{}):this.handleMalFormedXML(t)},e.prototype.handleMalFormedXML=function(e){var t;this.stopProgress=!0;var n={type:l.ERROR,status:l.MALFORMEDXML,responseCode:200,responseText:null===(t=this.xhrObject)||void 0===t?void 0:t.responseText,source:{id:this.source.id.value}};try{o.Implementation.sendError(n)}finally{e(n)}},e.prototype.onDone=function(e,t,n){this.stopProgress||t(e)},e.prototype.onError=function(e,t,n){this.handleError(e),n()},e.prototype.sendEvent=function(e){var t=s.EventData.createFromRequest(this.xhrObject,this.requestContext,e);try{var n=c.resolveHandlerFunc(this.requestContext,this.responseContext,l.ON_EVENT);o.Implementation.sendEvent(t,n)}catch(e){throw this.handleError(e),e}},e.prototype.handleError=function(e){var t=a.ErrorData.fromClient(e),n=c.resolveHandlerFunc(this.requestContext,this.responseContext,l.ON_ERROR);o.Implementation.sendError(t,n)},e.prototype.sendRequest=function(e){var t=this.ajaxType!=l.REQ_TYPE_GET;e.isMultipartRequest?this.xhrObject.send(t?e.toFormData():null):this.xhrObject.send(t?e.toString():null)},e}();t.XhrRequest=p},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(){this.runnableQueue=[]}return Object.defineProperty(e.prototype,"isEmpty",{get:function(){return!this.runnableQueue.length},enumerable:!0,configurable:!0}),e.prototype.enqueue=function(e,t){var n=this;void 0===t&&(t=0),this.delayTimeout&&(clearTimeout(this.delayTimeout),this.delayTimeout=null),t?this.delayTimeout=setTimeout((function(){n.appendElement(e)})):this.appendElement(e)},e.prototype.dequeue=function(){return this.runnableQueue.shift()},e.prototype.cleanup=function(){this.currentlyRunning=null,this.runnableQueue.length=0},e.prototype.appendElement=function(e){this.runnableQueue.push(e),this.currentlyRunning||this.runEntry()},e.prototype.runEntry=function(){var e=this;this.isEmpty?this.currentlyRunning=null:(this.currentlyRunning=this.dequeue(),this.currentlyRunning.catch((function(t){throw e.cleanup(),t})).then((function(){return e.callForNextElementToProcess()})).start())},e.prototype.cancel=function(){try{this.currentlyRunning&&this.currentlyRunning.cancel()}finally{this.cleanup()}},e.prototype.callForNextElementToProcess=function(){this.runEntry()},e.prototype.processNextElement=function(){this.currentlyRunning=null,this.isEmpty||this.runEntry()},e.EVT_NEXT="__mf_queue_next__",e}();t.AsynchronouseQueue=r},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(13),o=n(0);!function(e){var t=window.location.protocol.replace("http","ws")+"//";e.sockets={},e.components={},e.clientIdsByTokens={},e.reset=function(){e.sockets={},e.components={},e.clientIdsByTokens={}},e.init=function(o,i,s,u,l,c,f,p){if(c=a(c),window.WebSocket){var h=i.substr(i.indexOf("?")+1);e.components[o]||(e.components[o]={channelToken:h,onopen:a(u),onmessage:a(l),onclose:c,behaviors:f,autoconnect:p},e.clientIdsByTokens[h]||(e.clientIdsByTokens[h]=[]),e.clientIdsByTokens[h].push(o),e.sockets[h]||(e.sockets[h]=new n(h,function(e){if(e.indexOf("://")<0){var n=window.location.hostname+":"+window.location.port;return t+n+e}return e}(i),s))),p&&r.jsf.push.open(o)}else c(-1,s)},e.open=function(t){var n,r;i(null===(r=null===(n=e.components)||void 0===n?void 0:n[t])||void 0===r?void 0:r.channelToken).open()},e.close=function(t){var n;i(null===(n=e.components)||void 0===n?void 0:n[t].channelToken).close()};var n=function(){function t(e,t,n){this.channelToken=e,this.url=t,this.channel=n,this.reconnectAttempts=0}return t.prototype.open=function(){this.socket&&1==this.socket.readyState||(this.socket=new WebSocket(this.url),this.bindCallbacks())},t.prototype.onopen=function(t){if(!this.reconnectAttempts)for(var n=e.clientIdsByTokens[this.channelToken],r=n.length-1;r>=0;r--){var o=n[r];e.components[o].onopen(this.channel)}this.reconnectAttempts=0},t.prototype.onmmessage=function(t){for(var n=JSON.parse(t.data),r=e.clientIdsByTokens[this.channelToken].length-1;r>=0;r--){var o=e.clientIdsByTokens[this.channelToken][r];if(document.getElementById(o)){try{e.components[o].onmessage(n,this.channel,t)}catch(e){}var i=e.components[o].behaviors[n];if(i&&i.length)for(var a=0;a<i.length;a++)try{i[a](null)}catch(e){}}else e.clientIdsByTokens[this.channelToken].splice(r,1)}0==e.clientIdsByTokens[this.channelToken].length&&this.close()},t.prototype.onclose=function(t){var n;if(!this.socket||1e3==t.code&&t.reason==o.REASON_EXPIRED||1008==t.code||!this.reconnectAttempts||this.reconnectAttempts>=o.MAX_RECONNECT_ATTEMPTS)for(var r=e.clientIdsByTokens[this.channelToken],i=r.length-1;i>=0;i--){var a=r[i];e.components[a].onclose(null===(n=t)||void 0===n?void 0:n.code,null===this||void 0===this?void 0:this.channel,t)}else setTimeout(this.open,o.RECONNECT_INTERVAL*this.reconnectAttempts++)},t.prototype.close=function(){if(this.socket){var e=this.socket;this.socket=null,e.close()}},t.prototype.bindCallbacks=function(){var e=this;this.socket.onopen=function(t){return e.onopen(t)},this.socket.onmessage=function(t){return e.onmmessage(t)},this.socket.onclose=function(t){return e.onclose(t)}},t}();function i(t){var n=e.sockets[t];if(n)return n;throw new Error("Unknown channelToken: "+t)}function a(e){return void 0===e&&(e=function(){}),"function"!=typeof e&&(e=window[e]),e}}(t.PushImpl||(t.PushImpl={}))}]));
+//# sourceMappingURL=jsf.js.map
+//# sourceMappingURL=jsf.js.map.jsf?ln=scripts
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/js/jsf.js.map b/tobago-theme/tobago-theme-standard/src/main/npm/js/jsf.js.map
new file mode 100644
index 0000000..b278d84
--- /dev/null
+++ b/tobago-theme/tobago-theme-standard/src/main/npm/js/jsf.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/main/typescript/impl/core/Const.ts","webpack:///./src/main/typescript/ext/monadish/index.ts","webpack:///./src/main/typescript/ext/monadish/Monad.ts","webpack:///./src/main/typescript/ext/monadish/Lang.ts","webpack:///./src/main/typescript/impl/util/Lang.ts","webpack:///./src/main/typescript/ext/monadish/DomQuery.ts","webpack:///./src/main/typescript/ext/monadish/Stream.ts","webpack:///./src/main/typescript/impl/AjaxImpl.ts","webpack:///./src/main/typescript/ext/monadish/SourcesCollectors.ts","webpack:///./src/main/typescript/impl/util/Assertions.ts","webpack:///./src/main/typescript/impl/xhrCore/RequestDataResolver.ts","webpack:///./src/main/typescript/impl/xhrCore/ErrorData.ts","webpack:///./src/main/typescript/impl/xhrCore/EventData.ts","webpack:///./src/main/typescript/api/Jsf.ts","webpack:///./src/main/typescript/impl/util/ExtDomQuery.ts","webpack:///./src/main/typescript/impl/xhrCore/XhrFormData.ts","webpack:///./src/main/typescript/api/Myfaces.ts","webpack:///./src/main/typescript/impl/xhrCore/Response.ts","webpack:///./src/main/typescript/ext/monadish/XmlQuery.ts","webpack:///./src/main/typescript/impl/xhrCore/ResponseProcessor.ts","webpack:///./src/main/typescript/impl/i18n/Messages.ts","webpack:///./src/main/typescript/impl/core/ImplTypes.ts","webpack:///./src/main/typescript/impl/xhrCore/ResonseDataResolver.ts","webpack:///./src/main/typescript/impl/xhrCore/XhrRequest.ts","webpack:///./src/main/typescript/impl/util/AsyncQueue.ts","webpack:///./src/main/typescript/impl/PushImpl.ts"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","P_PARTIAL_SOURCE","PARTIAL_ID","P_VIEWSTATE","P_VIEWROOT","P_VIEWHEAD","P_VIEWBODY","EMPTY_FUNC","freeze","EMPTY_STR","EMPTY_MAP","HTML_VIEWSTATE","join","IDENT_ALL","IDENT_NONE","IDENT_THIS","IDENT_FORM","P_AJAX","P_EXECUTE","P_RENDER","P_EVT","P_CLIENT_WINDOW","P_RESET_VALUES","P_WINDOW_ID","RENDER","WINDOW_ID","ERROR","EVENT","ON_ERROR","ON_EVENT","BEGIN","COMPLETE","SUCCESS","SOURCE","STATUS","ERROR_NAME","ERROR_MESSAGE","RESPONSE_TEXT","RESPONSE_XML","HTTPERROR","EMPTY_RESPONSE","MALFORMEDXML","SERVER_ERROR","CLIENT_ERROR","TIMEOUT_EVENT","CTX_PARAM_MF_INTERNAL","CTX_PARAM_SRC_FRM_ID","CTX_PARAM_SRC_CTL_ID","CTX_PARAM_TR_TYPE","CTX_PARAM_PASS_THR","CTX_PARAM_DELAY","CTX_PARAM_TIMEOUT","CTX_PARAM_RST","CTX_PARAM_EXECUTE","STAGE_DEVELOPMENT","CONTENT_TYPE","HEAD_FACES_REQ","REQ_ACCEPT","VAL_AJAX","ENCODED_URL","REQ_TYPE_GET","REQ_TYPE_POST","STATE_EVT_BEGIN","STATE_EVT_TIMEOUT","STATE_EVT_COMPLETE","URL_ENCODED","MULTIPART","NO_TIMEOUT","STD_ACCEPT","TAG_HEAD","TAG_FORM","TAG_BODY","TAG_BEFORE","TAG_AFTER","TAG_ATTR","SEL_VIEWSTATE_ELEM","SEL_RESPONSE_XML","PHASE_PROCESS_RESPONSE","ERR_NO_PARTIAL_RESPONSE","ATTR_URL","ATTR_NAME","ATTR_VALUE","ATTR_ID","RESP_PARTIAL","CMD_CHANGES","CMD_UPDATE","CMD_DELETE","CMD_INSERT","CMD_EVAL","CMD_ERROR","CMD_ATTRIBUTES","CMD_EXTENSION","CMD_REDIRECT","UPDATE_FORMS","UPDATE_ELEMS","MYFACES","SEL_SCRIPTS_STYLES","MF_NONE","REASON_EXPIRED","APPLIED_VST","RECONNECT_INTERVAL","MAX_RECONNECT_ATTEMPTS","DomQuery","ElementAttribute","DomQueryCollector","DQ","Lang","Config","Monad","Optional","ValueEmbedder","XMLQuery","XQ","Stream","LazyStream","ArrayStreamDataSource","MappedStreamDataSource","FilteredStreamDatasource","FlatMapStreamDataSource","QueryFormStringCollector","ArrayCollector","AssocArrayCollector","FormDataCollector","QueryFormDataCollector","objAssign","this","_value","map","fn","inval","flatMap","mapped","fromNullable","isAbsent","isPresent","presentRunnable","absent","ifPresentLazy","orElse","elseValue","orElseLazy","func","val","getIf","currentPos","cnt","length","currKey","keyVal","arrPos","arrayIndex","getClass","Array","getIfPresent","match","defaultVal","toJson","JSON","stringify","start","indexOf","end","parseInt","substring","resolve","resolver","e","rootElem","valueKey","newVal","alternative","ConfigEntry","root","ofAssoc","collect","shallowMerge","other","overwrite","assign","keys","buildPath","retVal","apply","slice","assignIf","condition","delete","setVal","parentVal","parentPos","alloc","arr","length1","length2","push","tempVal","trim","str","ws","replace","test","charAt","isString","it","arguments","String","saveResolve","resolverProducer","defaultValue","result","saveResolveLazy","strToArray","splitter","ret","split","forEach","element","objToArray","obj","offset","pack","concat","equalsIgnoreCase","source","destination","finalDest","toLowerCase","assertType","probe","theType","isFunc","Function","target","TypeError","to","theArgs","item","nextSource","nextKey","ExtLang","installedLocale","nameSpace","getMessage","defaultMessage","msg","Messages","of","templateParams","each","param","RegExp","makeException","error","title","callerCls","callFunc","message","Error","caller","toString","getLanguage","language","navigator","languages","failSaveResolve","failSaveExecute","keyValToStr","delimiter","getGlobalConfig","configName","window","myfaces","config","getForm","elem","event","FORM","queryElem","eventTarget","getEventTarget","isTag","attr","formId","foundForm","byId","form","parents","byTagName","first","assertFormExists","getLocalOrGlobalConfig","localOptions","values","getAttribute","setAttribute","DEFAULT_JSF_WHITELIST","src","rootNode","pos","_limits","foundElement","querySelectorAll","getAsElem","allElems","tagName","nodeName","allMatch","el","checked","newChecked","eachElem","stream","formElement","elements","filter","disabled","removeAttribute","childNodeArr","childNodes","asArray","ofStreamDataSource","selector","document","globalEval","code","nonce","fromMarkup","markup","doc","implementation","createHTMLDocument","lowerMarkup","documentElement","innerHTML","startsWithTag","tag1","tag2","dummyPlaceHolder","createElement","html","detach","index","defaults","node","parentNode","removeChild","nodes","res","id","includeRoot","hasClass","clazz","hasIt","oldClass","oldClasses","found","addClass","removeClass","newClasses","isMultipartCandidate","firstElem","innerHtml","retArr","inVal","_mozMatchesSelector","toMatch","prot","matchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","webkitMatchesSelector","matches","ownerDocument","filterSelector","matched","selectorStage","nodeSelector","len","reArr","head","getElementsByTagName","script","type","newScriptElement","appendChild","appendTo","theItem","loadScriptEval","defer","charSet","xhr","XMLHttpRequest","open","setRequestHeader","send","onload","responseData","setTimeout","responseText","onerror","data","insertAfter","existingItem","existingElement","nextSibling","toInsertParams","insertElem","insertBefore","retSet","Set","lowerTagName","resolveItem","has","add","copyAttrs","sourceItem","sourceNode","attributes","resolveAttributeHolder","attrName","outerHTML","runEmbeddedScripts","runEmbeddedCss","focusElementId","activeElement","caretPosition","getCaretPosition","toReplace","firstInsert","replaced","replaceChild","insertAdditionalItems","runScripts","runCss","focusElement","setCaretPosition","whilteListed","finalScripts","equi","execScrpt","itemType","evalText","text","innerText","go","sort","node1","node2","compareDocumentPosition","console","description","applyStyle","style","newSS","styleSheet","sheet","cssText","createTextNode","execCss","click","fireEvent","addEventListener","listener","options","removeEventListener","eventName","nodeType","dispatchEvent","eventClass","createEvent","initEvent","synthetic","createEventObject","textContent","joinstr","reduce","text1","text2","encodeFormElement","toMerge","shallowCopy","elemType","selectElem","selectedIndex","uLen","u","selected","elementOption","files","inputValue","reduced","subNodes","from","Math","min","limits","hasNext","isLimitsReached","isEndOfArray","next","reset","ctrl","caretPos","selection","focus","createRange","moveStart","setSelectionRange","ofDataSource","dataSource","onElem","strmR","isArray","startVal","val1","last","anyMatch","noneMatch","comparator","newArr","collector","finalValue","parent","isOverLimits","nextFilter","max","stop","value1","value2","el1","el2","ProjectStages","BlockFilter","Implementation","assert","Assertions","eventQueue","myfacesConfig","errorQueue","requestQueue","threshold","resolveProjectStateFromURL","foundStage","ExtDomquery","searchJsfJsFor","sendError","errorData","localHandler","errorCallback","alert","displayError","remapDefaultConstants","targetConfig","targetKey","userValues","issuingForm","issuingElementId","iterValues","processed","getSeparatorChar","globalConfig","separator","getProjectStage","projectStage","chain","funcs","sourceCode","resolveAndExecute","request","opts","mappedOpts","resolvedEvent","elementId","requestCtx","internalCtx","windowId","isResetValues","assertRequestIntegrity","onevent","requestOptions","targetContext","sourceElementId","resolveForm","clientWindow","jsf","getClientWindow","assignClientWindowId","assignRender","delay","resolveDelay","timeout","resolveTimeout","queueHandler","addRequestToQueue","response","context","Response","processResponse","addOnError","errorListener","addOnEvent","eventListener","sendEvent","stdErrorHandler","exception","clearRequestQueue","ErrorData","fromClient","cleanup","ALTERED","formWindowId","body","getViewState","XhrFormData","reqCtx","respPassThr","AsynchronouseQueue","enqueue","XhrRequest","dataPos","filterFunc","filteredNext","inputDataSource","mapFunc","resolveCurrentNext","resolveNextNext","activeDataSource","FormData","append","formData","item1","item2","raiseError","assertFunction","assertUrlExists","assertValidXMLResponse","responseXML","isXMLParserError","parserErrorText","finalTitle","finalName","finalMessage","resolveWindowId","resolveEvent","evt","requestContext","responseContext","funcName","srcFormElement","action","sourceForm","ajaxType","resolveTargetUrl","configId","getCfg","finalEvent","srcElement","deepCopy","resetValues","ErrorType","errorName","errorMessage","responseCode","status","typeDetails","serverErrorName","serverErrorMessage","stack","fromHttpConnection","HTTP_ERROR","fromGeneric","errorCode","errorType","getMsg","fromServerError","EventData","createFromRequest","eventData","sourceId","mf_impl","_impl","specversion","implversion","separatorchar","ajax","errorFunc","eventFunc","util","init","socketClientId","uri","channel","onopen","onmessage","onclose","behaviorScripts","autoconnect","PushImpl","close","ab","execute","render","fetchWindowIdFromURL","href","location","results","exec","curScript","currentScript","nonceScript","lazyStream","rexp","search","decodeURIComponent","ExtDQ","partialIdsArray","encode","assignEncodedString","handleFormSource","encodeSubmittableFields","applyViewState","viewState","encoded","keyValueEntries","line","splice","toFormData","defaultStr","entries","encodeURIComponent","targetBuf","parentItem","partialIds","toEncode","ConfigHolder","req","externalContext","internalContext","resolveResponseXML","responseProcessor","ResponseProcessor","SEL_SUB_TAGS","redirect","ALLOWED_TAGS","processViewState","cdataBlock","cDATAAsString","replaceViewRoot","replaceHead","replaceBody","update","handleElementUpdate","processUpdateTag","eval","processInsert","processChangesTag","processPartialTag","fixViewStates","done","insertWithSubtags","insert","docType","xml","DOMParser","parser","ActiveXObject","async","parseFromString","contentType","loadXML","serialized","XMLSerializer","constructor","serializeToString","parseXML","txt","parseHTML","fromString","parseType","shadowDocument","shadowHead","storeForEval","shadowBody","shadowInnerHTML","resultingBody","updateForms","storeForPostProcessing","mergedErrorData","hasResponseXML","redirectUrl","before","after","insertNodes","insertId","isViewStateNode","viewStateValue","ViewState","updateElems","affectedForms","affectedForms2","appendViewStateToForms","eventHandler","forms","newViewStateElement","newViewState","toBeEvaled","storeForUpdate","separatorChar","MSG_TEST","MSG_DEV_MODE","MSG_AFFECTED_CLASS","MSG_AFFECTED_METHOD","MSG_ERROR_NAME","MSG_ERROR_MESSAGE","MSG_SERVER_ERROR_NAME","MSG_ERROR_DESC","MSG_ERROR_NO","MSG_ERROR_LINENO","ERR_FORM","ERR_VIEWSTATE","ERR_TRANSPORT","ERR_EVT_PASS","ERR_CONSTRUCT","ERR_MALFORMEDXML","ERR_SOURCE_FUNC","ERR_EV_OR_UNKNOWN","ERR_SOURCE_NOSTR","ERR_SOURCE_DEF_NULL","ERR_MUST_STRING","ERR_REF_OR_ID","ERR_PARAM_GENERIC","ERR_PARAM_STR","ERR_PARAM_STR_RE","ERR_PARAM_MIXMAPS","ERR_MUST_BE_PROVIDED","ERR_MUST_BE_PROVIDED1","ERR_REPLACE_EL","ERR_EMPTY_RESPONSE","ERR_ITEM_ID_NOTFOUND","ERR_PPR_IDREQ","ERR_PPR_INSERTBEFID","ERR_PPR_INSERTBEFID_1","ERR_PPR_INSERTBEFID_2","ERR_PPR_DELID","ERR_PPR_UNKNOWNCID","ERR_NO_VIEWROOTATTR","ERR_NO_HEADATTR","ERR_RED_URL","ERR_REQ_FAILED_UNKNOWN","ERR_REQU_FAILED","UNKNOWN","viewStatePos","substr","elemId","resolveSourceElementId","sourceFormId","xhrObject","stopProgress","catchFuncs","thenFunc","registerXhrCallbacks","reject","ignoreErr","isMultipartRequest","passThroughParams","resolveFinalUrl","sendRequest","handleError","cancel","abort","inputVal","catchFunc","catch","finally","then","onabort","onAbort","ontimeout","onTimeout","onSuccess","onloadend","onDone","onError","handleMalFormedXML","evtType","resolveHandlerFunc","isPost","runnableQueue","delayTimeout","clearTimeout","appendElement","dequeue","shift","currentlyRunning","runEntry","isEmpty","callForNextElementToProcess","processNextElement","EVT_NEXT","URL_PROTOCOL","protocol","sockets","components","clientIdsByTokens","resolveFunction","WebSocket","channelToken","Socket","url","base","hostname","port","getBaseURL","getSocket","reconnectAttempts","socket","readyState","bindCallbacks","clientIds","onmmessage","parse","getElementById","functions","j","reason"],"mappings":"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","file":"jsf.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 13);\n","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * [export const] constants\n */\n\nexport const P_PARTIAL_SOURCE = \"javax.faces.source\";\nexport const PARTIAL_ID = \"partialId\";\nexport const P_VIEWSTATE = \"javax.faces.ViewState\";\nexport const P_VIEWROOT = \"javax.faces.ViewRoot\";\nexport const P_VIEWHEAD = \"javax.faces.ViewHead\";\nexport const P_VIEWBODY = \"javax.faces.ViewBody\";\n\n/*some useful definitions*/\n\nexport const EMPTY_FUNC = Object.freeze(() => {\n});\nexport const EMPTY_STR = \"\";\nexport const EMPTY_MAP = Object.freeze({});\n\nexport const HTML_VIEWSTATE = [\"<input type='hidden'\", \"id='\", P_VIEWSTATE, \"' name='\", P_VIEWSTATE, \"' value='' />\"].join(EMPTY_STR);\n\n\n/*internal identifiers for options*/\nexport const IDENT_ALL = \"@all\";\nexport const IDENT_NONE = \"@none\";\nexport const IDENT_THIS = \"@this\";\nexport const IDENT_FORM = \"@form\";\n\n\nexport const P_AJAX = \"javax.faces.partial.ajax\";\nexport const P_EXECUTE = \"javax.faces.partial.execute\";\nexport const P_RENDER = \"javax.faces.partial.render\";\nexport const P_EVT = \"javax.faces.partial.event\";\nexport const P_CLIENT_WINDOW = \"javax.faces.ClientWindow\";\nexport const P_RESET_VALUES = \"javax.faces.partial.resetValues\";\n\nexport const P_WINDOW_ID = \"javax.faces.windowId\";\n\nexport const RENDER = \"render\";\nexport const WINDOW_ID = \"windowId\";\n\n/* message types */\nexport const ERROR = \"error\";\nexport const EVENT = \"event\";\n\nexport const ON_ERROR = \"onerror\";\nexport const ON_EVENT = \"onevent\";\n\n/* event emitting stages */\nexport const BEGIN = \"begin\";\nexport const COMPLETE = \"complete\";\nexport const SUCCESS = \"success\";\n\nexport const SOURCE = \"source\";\nexport const STATUS = \"status\";\n\n\nexport const ERROR_NAME = \"error-name\";\nexport const ERROR_MESSAGE = \"error-message\";\n\n\nexport const RESPONSE_TEXT = \"responseText\";\nexport const RESPONSE_XML = \"responseXML\";\n\n/*ajax errors spec 14.4.2*/\nexport const HTTPERROR = \"httpError\";\nexport const EMPTY_RESPONSE = \"emptyResponse\";\nexport const MALFORMEDXML = \"malformedXML\";\nexport const SERVER_ERROR = \"serverError\";\nexport const CLIENT_ERROR = \"clientError\";\nexport const TIMEOUT_EVENT = \"timeout\";\n\nexport const CTX_PARAM_MF_INTERNAL = \"_mfInternal\";\n\nexport const CTX_PARAM_SRC_FRM_ID = \"_mfSourceFormId\";\nexport const CTX_PARAM_SRC_CTL_ID = \"_mfSourceControlId\";\nexport const CTX_PARAM_TR_TYPE = \"_mfTransportType\";\nexport const CTX_PARAM_PASS_THR = \"passThrgh\";\nexport const CTX_PARAM_DELAY = \"delay\";\nexport const CTX_PARAM_TIMEOUT = \"timeout\";\nexport const CTX_PARAM_RST = \"resetValues\";\nexport const CTX_PARAM_EXECUTE = \"execute\";\n\nexport const STAGE_DEVELOPMENT = \"Development\";\n\n\nexport const CONTENT_TYPE = \"Content-Type\";\nexport const HEAD_FACES_REQ = \"Faces-Request\";\nexport const REQ_ACCEPT = \"Accept\";\nexport const VAL_AJAX = \"partial/ajax\";\nexport const ENCODED_URL = \"javax.faces.encodedURL\";\nexport const REQ_TYPE_GET = \"GET\";\nexport const REQ_TYPE_POST = \"POST\";\nexport const STATE_EVT_BEGIN = \"begin\"; //TODO remove this\nexport const STATE_EVT_TIMEOUT = \"TIMEOUT_EVENT\";\nexport const STATE_EVT_COMPLETE = \"complete\"; //TODO remove this\nexport const URL_ENCODED = \"application/x-www-form-urlencoded\";\nexport const MULTIPART = \"multipart/form-data\";\nexport const NO_TIMEOUT = 0;\nexport const STD_ACCEPT = \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\";\n\nexport const TAG_HEAD = \"head\";\nexport const TAG_FORM = \"form\";\nexport const TAG_BODY = \"body\";\nexport const TAG_BEFORE = \"before\";\nexport const TAG_AFTER = \"after\";\n\nexport const TAG_ATTR = \"attribute\";\n\n\nexport const SEL_VIEWSTATE_ELEM = \"[name='\" + P_VIEWSTATE + \"']\";\nexport const SEL_RESPONSE_XML = \"responseXML\";\n\nexport const PHASE_PROCESS_RESPONSE = \"processResponse\";\n\n\nexport const ERR_NO_PARTIAL_RESPONSE = \"Partial response not set\";\n\nexport const ATTR_URL = \"url\";\nexport const ATTR_NAME = \"name\";\nexport const ATTR_VALUE = \"value\";\nexport const ATTR_ID = \"id\";\n\n/*partial response types*/\nexport const RESP_PARTIAL = \"partial-response\";\n\n/*partial commands*/\nexport const CMD_CHANGES = \"changes\";\nexport const CMD_UPDATE = \"update\";\nexport const CMD_DELETE = \"delete\";\nexport const CMD_INSERT = \"insert\";\nexport const CMD_EVAL = \"eval\";\nexport const CMD_ERROR = \"error\";\nexport const CMD_ATTRIBUTES = \"attributes\";\nexport const CMD_EXTENSION = \"extension\";\nexport const CMD_REDIRECT = \"redirect\";\n\n/*other constants*/\n\nexport const UPDATE_FORMS = \"_updateForms\";\nexport const UPDATE_ELEMS = \"_updateElems\";\n\nexport const MYFACES = \"myfaces\";\n\nexport const SEL_SCRIPTS_STYLES = \"script, style, link\";\n\nexport const MF_NONE = \"__mf_none__\";\n\nexport const REASON_EXPIRED = \"Expired\";\n\nexport const APPLIED_VST = \"appliedViewState\";\n\nexport const RECONNECT_INTERVAL = 500;\nexport const MAX_RECONNECT_ATTEMPTS = 25;\n\n\n","export {DomQuery, ElementAttribute, DomQueryCollector, DQ} from \"./DomQuery\";\nexport {Lang} from \"./Lang\";\nexport {Config, Monad, IValueHolder, IFunctor, IMonad, IIdentity, Optional, ValueEmbedder} from \"./Monad\";\nexport {XMLQuery, XQ} from \"./XmlQuery\";\nexport {Stream, LazyStream, IteratableConsumer, IStream} from \"./Stream\";\nexport {\n    ArrayStreamDataSource,\n    MappedStreamDataSource,\n    FilteredStreamDatasource,\n    FlatMapStreamDataSource,\n    QueryFormStringCollector,\n    IStreamDataSource,\n    ICollector,\n    ArrayCollector,\n    AssocArrayCollector,\n    FormDataCollector,\n    QueryFormDataCollector\n} from \"./SourcesCollectors\";\n\n\n","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * A module which keeps  basic monadish like definitions in place without any sidedependencies to other modules.\n * Useful if you need the functions in another library to keep its dependencies down\n */\n\n/*IMonad definitions*/\n\nimport {Lang} from \"./Lang\";\nimport {AssocArrayCollector} from \"./SourcesCollectors\";\nimport {Stream} from \"./Stream\";\nimport objAssign = Lang.objAssign;\n\n/**\n * IFunctor interface,\n * defines an interface which allows to map a functor\n * via a first order function to another functor\n */\nexport interface IFunctor<T> {\n    map<R>(fn: (data: T) => R): IFunctor<R>;\n}\n\n/**\n * IMonad definition, basically a functor with a flaptmap implementation (flatmap reduces all nested monads after a\n * function call f into a monad with the nesting level of 1\n *\n * flatmap flats nested Monads into a IMonad of the deepest nested implementation\n */\nexport interface IMonad<T, M extends IMonad<any, any>> extends IFunctor<T> {\n    flatMap<T, M>(f: (T) => M): IMonad<any, any>;\n}\n\n/**\n * a stateful functor which holds a value upn which a\n * function can be applied\n *\n * as value holder of type T\n */\nexport interface IIdentity<T> extends IFunctor<T> {\n    readonly value: T;\n}\n\n/**\n *  custom value holder definition, since we are not pure functional\n *  but iterative we have structures which allow the assignment of a value\n *  also not all structures are sideffect free\n */\nexport interface IValueHolder<T> {\n    value: T | Array<T>;\n}\n\n/**\n * Implementation of a monad\n * (Sideffect free), no write allowed directly on the monads\n * value state\n */\nexport class Monad<T> implements IMonad<T, Monad<any>>, IValueHolder<T> {\n    constructor(value: T) {\n        this._value = value;\n    }\n\n    protected _value: T;\n\n    get value(): T {\n        return this._value;\n    }\n\n    map<R>(fn?: (data: T) => R): Monad<R> {\n        if (!fn) {\n            fn = (inval: any) => <R>inval;\n        }\n        let result: R = fn(this.value);\n        return new Monad(result);\n    }\n\n    flatMap<R>(fn?: (data: T) => R): Monad<any> {\n        let mapped: Monad<any> = this.map(fn);\n        while (mapped?.value instanceof Monad) {\n            mapped = mapped.value\n        }\n        return mapped;\n    }\n\n}\n\n\n\n\n/**\n * optional implementation, an optional is basically an implementation of a Monad with additional syntactic\n * sugar on top\n * (Sideeffect free, since value assignment is not allowed)\n * */\nexport class Optional<T> extends Monad<T> {\n\n    /*default value for absent*/\n    static absent = Optional.fromNullable(null);\n\n    constructor(value: T) {\n        super(value);\n    }\n\n    get value(): T {\n        if (this._value instanceof Monad) {\n            return this._value.flatMap().value\n        }\n        return this._value;\n    }\n\n    static fromNullable<T>(value?: T): Optional<T> {\n        return new Optional(value);\n    }\n\n    /*syntactic sugar for absent and present checks*/\n    isAbsent(): boolean {\n        return \"undefined\" == typeof this.value || null == this.value;\n    }\n\n    /**\n     * any value present\n     */\n    isPresent(presentRunnable ?: (val ?: Monad<T>) => void): boolean {\n        let absent = this.isAbsent();\n        if (!absent && presentRunnable) {\n            presentRunnable.call(this, this)\n        }\n        return !absent;\n    }\n\n    ifPresentLazy(presentRunnable: (val ?: Monad<T>) => void = () => {\n    }): Monad<T> {\n        this.isPresent.call(this, presentRunnable);\n        return this;\n    }\n\n    orElse(elseValue: any): Optional<any> {\n        if (this.isPresent()) {\n            return this;\n        } else {\n            //shortcut\n            if (elseValue == null) {\n                return Optional.absent;\n            }\n            return this.flatMap(() => elseValue);\n        }\n    }\n\n    /**\n     * lazy, passes a function which then is lazily evaluated\n     * instead of a direct value\n     * @param func\n     */\n    orElseLazy(func: () => any): Optional<any> {\n        if (this.isPresent()) {\n            return this;\n        } else {\n            return this.flatMap(func);\n        }\n    }\n\n    /*\n     * we need to implement it to fullfill the contract, although it is used only internally\n     * all values are flattened when accessed anyway, so there is no need to call this methiod\n     */\n    flatMap<R>(fn?: (data: T) => R): Optional<any> {\n        let val = super.flatMap(fn);\n        if (!(val instanceof Optional)) {\n            return Optional.fromNullable(val.value);\n        }\n\n        return <Optional<any>>val.flatMap();\n    }\n\n    /*\n     * elvis operation, take care, if you use this you lose typesafety and refactoring\n     * capabilites, unfortunately typesceript does not allow to have its own elvis operator\n     * this is some syntactic sugar however which is quite useful*/\n    getIf<R>(...key: string[]): Optional<R> {\n\n        let currentPos: Optional<any> = this;\n        for (let cnt = 0; cnt < key.length; cnt++) {\n            let currKey = this.keyVal(key[cnt]);\n            let arrPos = this.arrayIndex(key[cnt]);\n\n            if (currKey === \"\" && arrPos >= 0) {\n                currentPos = this.getClass().fromNullable(!(currentPos.value instanceof Array) ? null : (currentPos.value.length < arrPos ? null : currentPos.value[arrPos]));\n                if (currentPos.isAbsent()) {\n                    return currentPos;\n                }\n                continue;\n            } else if (currKey && arrPos >= 0) {\n                if (currentPos.getIfPresent(currKey).isAbsent()) {\n                    return currentPos;\n                }\n                currentPos = (currentPos.getIfPresent(currKey).value instanceof Array) ? this.getClass().fromNullable(currentPos.getIfPresent(currKey).value[arrPos]) : this.getClass().absent;\n                if (currentPos.isAbsent()) {\n                    return currentPos;\n                }\n                continue;\n\n            } else {\n                currentPos = currentPos.getIfPresent(currKey);\n            }\n            if (currentPos.isAbsent()) {\n                return currentPos;\n            } else if (arrPos > -1) {\n                currentPos = this.getClass().fromNullable(currentPos.value[arrPos]);\n            }\n        }\n        let retVal = currentPos;\n\n        return retVal;\n    }\n\n    /**\n     * simple match, if the first order function call returns\n     * true then there is a match, if the value is not present\n     * it never matches\n     *\n     * @param fn the first order function performing the match\n     */\n    match(fn: (item: T) => boolean): boolean {\n        if (this.isAbsent()) {\n            return false\n        }\n        return fn(this.value);\n    }\n\n    /**\n     * convenience function to flatmap the internal value\n     * and replace it with a default in case of being absent\n     *\n     * @param defaultVal\n     * @returns {Optional<any>}\n     */\n    get<R>(defaultVal: any = Optional.absent): Optional<R> {\n        if (this.isAbsent()) {\n            return this.getClass().fromNullable(defaultVal).flatMap();\n        }\n\n        return this.getClass().fromNullable(this.value).flatMap();\n    }\n\n    toJson(): string {\n        return JSON.stringify(this.value);\n    }\n\n    /**\n     * helper to override several implementations in a more fluent way\n     * by having a getClass operation we can avoid direct calls into the constructor or\n     * static methods and do not have to implement several methods which rely on the type\n     * of \"this\"\n     * @returns {Monadish.Optional}\n     */\n    protected getClass(): any {\n        return Optional;\n    }\n\n    /*helper method for getIf with array access aka <name>[<indexPos>]*/\n    protected arrayIndex(key: string): number {\n        let start = key.indexOf(\"[\");\n        let end = key.indexOf(\"]\");\n        if (start >= 0 && end > 0 && start < end) {\n            return parseInt(key.substring(start + 1, end));\n        } else {\n            return -1;\n        }\n    }\n\n    /*helper method for getIf with array access aka <name>[<indexPos>]*/\n    protected keyVal(key: string): string {\n        let start = key.indexOf(\"[\");\n\n        if (start >= 0) {\n            return key.substring(0, start);\n        } else {\n            return key;\n        }\n    }\n\n    /**\n     * additional syntactic sugar which is not part of the usual optional implementation\n     * but makes life easier, if you want to sacrifice typesafety and refactoring\n     * capabilities in typescript\n     */\n    getIfPresent<R>(key: string): Optional<R> {\n        if (this.isAbsent()) {\n            return this.getClass().absent;\n        }\n        return this.getClass().fromNullable(this.value[key]).flatMap();\n    }\n\n    /**\n     * elvis like typesafe functional save resolver\n     * a typesafe option for getIfPresent\n     *\n     * usage myOptional.resolve(value => value.subAttr.subAttr2).orElseLazy(....)\n     * if this is resolvable without any errors an Optional with the value is returned\n     * if not, then an Optional absent is returned, also if you return Optional absent\n     * it is flatmapped into absent\n     *\n     * @param resolver the resolver function, can throw any arbitrary errors, int  the error case\n     * the resolution goes towards absent\n     */\n    resolve<V>(resolver: (item: T) => V): Optional<V> {\n        if(this.isAbsent()) {\n            return Optional.absent;\n        }\n        try {\n            return Optional.fromNullable(resolver(this.value))\n        } catch(e) {\n            return Optional.absent;\n        }\n    }\n\n}\n\n\n// --------------------- From here onwards we break out the sideffects free limits ------------\n\n\n/**\n * ValueEmbedder is the writeable version\n * of optional, it basically is a wrappber\n * around a construct which has a state\n * and can be written to.\n *\n * For the readonly version see Optional\n */\nexport class ValueEmbedder<T> extends Optional<T> implements IValueHolder<T> {\n\n    /*default value for absent*/\n    static absent =  ValueEmbedder.fromNullable(null);\n\n    protected key: string;\n\n    constructor(rootElem: any, valueKey: string = \"value\") {\n        super(rootElem);\n\n        this.key = valueKey;\n    }\n\n    get value(): T {\n        return this._value ? <T>this._value[this.key] : null;\n    }\n\n    set value(newVal: T) {\n        if(!this._value) {\n            return;\n        }\n        this._value[this.key] = newVal\n    }\n\n    orElse(elseValue: any): Optional<any> {\n        let alternative = {};\n        alternative[this.key] = elseValue;\n        return this.isPresent() ? this : new ValueEmbedder(alternative, this.key);\n    }\n\n    orElseLazy(func: () => any): Optional<any> {\n        if (this.isPresent()) {\n            return this;\n        } else {\n            let alternative = {};\n            alternative[this.key] = func();\n            return new ValueEmbedder(alternative, this.key);\n        }\n    }\n\n    /**\n     * helper to override several implementations in a more fluent way\n     * by having a getClass operation we can avoid direct calls into the constructor or\n     * static methods and do not have to implement several methods which rely on the type\n     * of \"this\"\n     * @returns {Monadish.Optional}\n     */\n    protected getClass(): any {\n        return ValueEmbedder;\n    }\n\n    static fromNullable<T>(value?: any, valueKey: string = \"value\"): ValueEmbedder<T> {\n        return new ValueEmbedder(value, valueKey);\n    }\n\n}\n\n\n\n/**\n * specialized value embedder\n * for our Configuration\n */\nclass ConfigEntry<T> extends ValueEmbedder<T> {\n\n    /*default value for absent*/\n    static absent = ConfigEntry.fromNullable(null);\n\n    arrPos: number;\n\n    constructor(rootElem: any, key: any, arrPos?: number) {\n        super(rootElem, key);\n\n        this.arrPos =  arrPos ?? -1;\n    }\n\n    get value() {\n        if (this.key == \"\" && this.arrPos >= 0) {\n            return this._value[this.arrPos];\n        } else if (this.key && this.arrPos >= 0) {\n            return this._value[this.key][this.arrPos];\n        }\n        return this._value[this.key];\n    }\n\n    set value(val: T) {\n        if (this.key == \"\" && this.arrPos >= 0) {\n            this._value[this.arrPos] = val;\n            return;\n        } else if (this.key && this.arrPos >= 0) {\n            this._value[this.key][this.arrPos] = val;\n            return;\n        }\n        this._value[this.key] = val;\n    }\n}\n\n/**\n * Config, basically an optional wrapper for a json structure\n * (not sideeffect free, since we can alter the internal config state\n * without generating a new config), not sure if we should make it sideffect free\n * since this would swallow a lot of performane and ram\n */\nexport class Config extends Optional<any> {\n    constructor(root: any) {\n        super(root);\n    }\n\n    get shallowCopy(): Config {\n        return new Config(Stream.ofAssoc(this.value).collect(new AssocArrayCollector()));\n    }\n\n    get deepCopy(): Config {\n        return new Config(objAssign({}, this.value));\n    }\n\n    static fromNullable<T>(value?: any): Config {\n        return new Config(value);\n    }\n\n    /**\n     * simple merge for the root configs\n     */\n    shallowMerge(other: Config, overwrite = true) {\n        for (let key in other.value) {\n            if (overwrite || !(key in this.value)) {\n                this.assign(key).value = other.getIf(key).value;\n            }\n        }\n    }\n\n    assign(...keys): IValueHolder<any> {\n        if (keys.length < 1) {\n            return;\n        }\n\n        this.buildPath(keys);\n\n        let currKey = this.keyVal(keys[keys.length - 1]);\n        let arrPos = this.arrayIndex(keys[keys.length - 1]);\n        let retVal = new ConfigEntry(keys.length == 1 ? this.value : this.getIf.apply(this, keys.slice(0, keys.length - 1)).value,\n            currKey, arrPos\n        );\n\n        return retVal;\n    }\n\n    assignIf(condition: boolean, ...keys: Array<any>): IValueHolder<any> {\n        return condition ? this.assign(...keys) : {value: null};\n    }\n\n\n    getIf(...keys: Array<string>): Config {\n        return this.getClass().fromNullable(super.getIf.apply(this, keys).value);\n    }\n\n    get(defaultVal: any): Config {\n        return this.getClass().fromNullable(super.get(defaultVal).value);\n    }\n\n    //empties the current config entry\n    delete(key: string): Config {\n        if (key in this.value) {\n            delete this.value[key];\n        }\n        return this;\n    }\n\n    toJson(): any {\n        return JSON.stringify(this.value);\n    }\n\n    protected getClass(): any {\n        return Config;\n    }\n\n    private setVal(val: any) {\n        this._value = val;\n    }\n\n    private buildPath(keys: Array<any>): Config {\n        let val = this;\n        let parentVal = this.getClass().fromNullable(null);\n        let parentPos = -1;\n        let alloc = function (arr: Array<any>, length: number) {\n            let length1 = arr.length;\n            let length2 = length1 + length;\n            for(let cnt = length1; cnt < length2; cnt++) {\n                arr.push({});\n            }\n        };\n\n        for (let cnt = 0; cnt < keys.length; cnt++) {\n            let currKey = this.keyVal(keys[cnt]);\n            let arrPos = this.arrayIndex(keys[cnt]);\n\n            if (currKey === \"\" && arrPos >= 0) {\n\n                val.setVal((val.value instanceof Array) ? val.value : []);\n                alloc(val.value, arrPos + 1);\n                if (parentPos >= 0) {\n                    parentVal.value[parentPos] = val.value;\n                }\n                parentVal = val;\n                parentPos = arrPos;\n                val = this.getClass().fromNullable(val.value[arrPos]);\n                continue;\n            }\n\n            let tempVal = <Config>val.getIf(currKey);\n            if (arrPos == -1) {\n                if (tempVal.isAbsent()) {\n                    tempVal = <Config>this.getClass().fromNullable(val.value[currKey] = {});\n                } else {\n                    val = <any>tempVal;\n                }\n            } else {\n                let arr = (tempVal.value instanceof Array) ? tempVal.value : [];\n                alloc(arr, arrPos + 1);\n                val.value[currKey] = arr;\n                tempVal = this.getClass().fromNullable(arr[arrPos]);\n            }\n            parentVal = val;\n            parentPos = arrPos;\n            val = <any>tempVal;\n        }\n\n        return this;\n    }\n}\n\n\n","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Optional} from \"./Monad\";\n\n/**\n * Lang helpers crossported from the apache myfaces project\n */\nexport module Lang {\n    \n\n    //should be in lang, but for now here to avoid recursive imports, not sure if typescript still has a problem with those\n    /**\n     * helper function to savely resolve anything\n     * this is not an elvis operator, it resolves\n     * a value without exception in a tree and if\n     * it is not resolvable then an optional of\n     * a default value is restored or Optional.empty\n     * if none is given\n     *\n     * usage\n     * <code>\n     *     let var: Optiona<string> = saveResolve(() => a.b.c.d.e, \"foobaz\")\n     * </code>\n     *\n     * @param resolverProducer a lambda which can produce the value\n     * @param defaultValue an optional default value if the producer failes to produce anything\n     * @returns an Optional of the produced value\n     */\n    export function saveResolve<T>(resolverProducer: () => T, defaultValue: T = null): Optional<T> {\n        try {\n            let result = resolverProducer();\n            return Optional.fromNullable(result ?? defaultValue);\n        } catch (e) {\n            return Optional.absent;\n        }\n    }\n\n    export function saveResolveLazy<T>(resolverProducer: () => T, defaultValue: () => T = null): Optional<T> {\n        try {\n            let result = resolverProducer();\n            return Optional.fromNullable(result ?? defaultValue());\n        } catch (e) {\n            return Optional.absent;\n        }\n    }\n\n    /**\n     * String to array function performs a string to array transformation\n     * @param {String} it the string which has to be changed into an array\n     * @param {RegExp} splitter our splitter reglar expression\n     * @return a trimmed array of the splitted string\n     */\n    export function strToArray(it: string, splitter: string | RegExp = /\\./gi): Array<string> {\n\n        let ret = [];\n        it.split(splitter).forEach((element => {\n            ret.push(trim(element));\n        }));\n        return ret;\n    }\n\n    /**\n     * hyperfast trim\n     * http://blog.stevenlevithan.com/archives/faster-trim-javascript\n     * crossported from dojo\n     */\n    export function trim(str: string): string {\n        str = str.replace(/^\\s\\s*/, '');\n        let ws = /\\s/, i = str.length;\n\n        while (ws.test(str.charAt(--i))) {\n            //do nothing\n        }\n        return str.slice(0, i + 1);\n    }\n\n    /**\n     * generic object arrays like dom definitions to array conversion method which\n     * transforms any object to something array like\n     * @param obj\n     * @param offset\n     * @param pack\n     * @returns an array converted from the object\n     */\n    export function objToArray<T>(obj: any, offset: number = 0, pack: Array<T> = []): Array<T> {\n        if ((obj ?? \"__undefined__\") == \"__undefined__\") {\n            return pack ?? null;\n        }\n        //since offset is numeric we cannot use the shortcut due to 0 being false\n        //special condition array delivered no offset no pack\n        if ((<any>obj) instanceof Array && !offset && !pack) return obj;\n\n        return pack.concat(Array.prototype.slice.call(obj, offset));\n    }\n\n    /**\n     * equalsIgnoreCase, case insensitive comparison of two strings\n     *\n     * @param source\n     * @param destination\n     */\n    export function equalsIgnoreCase(source?: string, destination?: string): boolean {\n        let finalSource = source ?? \"___no_value__\";\n        let finalDest = destination ?? \"___no_value__\";\n\n        //in any other case we do a strong string comparison\n        return finalSource.toLowerCase() === finalDest.toLowerCase();\n    }\n\n    /**\n     * runtime type assertion\n     *\n     * @param probe the probe to be tested for a type\n     * @param theType the type to be tested for\n     */\n    export function assertType(probe: any, theType: any): boolean {\n        return isString(theType) ? typeof probe == theType : probe instanceof theType;\n    }\n\n    /**\n     * Backported from dojo\n     * a failsafe string determination method\n     * (since in javascript String != \"\" typeof alone fails!)\n     * @param it {|Object|} the object to be checked for being a string\n     * @return true in case of being a string false otherwise\n     */\n    export function isString(it?: any): boolean {\n        //\tsummary:\n        //\t\tReturn true if it is a String\n        return !!arguments.length && it != null && (typeof it == \"string\" || it instanceof String); // Boolean\n    }\n\n    export function isFunc(it: any): boolean {\n        return it instanceof Function || typeof it === \"function\";\n    }\n\n    // code from https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n    // license https://creativecommons.org/licenses/by-sa/2.5/\n    export function objAssign(target: any, ...theArgs: any) { // .length of function is 2\n        if (target == null) { // TypeError if undefined or null\n            throw new TypeError('Cannot convert undefined or null to object');\n        }\n\n        let to = Object(target);\n        if((<any>Object).assign) {\n            theArgs.forEach(item => (<any>Object).assign(to, item));\n            return to;\n        }\n\n        theArgs.forEach(item => {\n            let nextSource = item;\n            if (nextSource != null) { // Skip over if undefined or null\n                for (let nextKey in nextSource) {\n                    // Avoid bugs when hasOwnProperty is shadowed\n                    if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n                        to[nextKey] = nextSource[nextKey];\n                    }\n                }\n            }\n        });\n        return to;\n    }\n}\n\n","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * todo replace singleton with module definition\n *\n */\n\nimport {Lang as LangBase} from \"../../ext/monadish/Lang\";\nimport {Messages} from \"../i18n/Messages\";\nimport {Config, Optional} from \"../../ext/monadish/Monad\";\nimport {DomQuery, DQ} from \"../../ext/monadish/DomQuery\";\nimport {Stream} from \"../../ext/monadish\";\nimport {EMPTY_STR} from \"../core/Const\";\nimport {getEventTarget} from \"../xhrCore/RequestDataResolver\";\n\n\nexport module ExtLang {\n\n     let installedLocale: Messages;\n     let nameSpace = \"impl/util/Lang/\";\n\n\n    export function getLanguage(): string {\n        //TODO global config override\n\n        let language: string = (<any>navigator).languages?.[0] ?? navigator?.language;\n        language = language.split(\"-\")[0];\n        return language;\n    }\n\n    //should be in lang, but for now here to avoid recursive imports, not sure if typescript still has a problem with those\n    /**\n     * helper function to savely resolve anything\n     * this is not an elvis operator, it resolves\n     * a value without exception in a tree and if\n     * it is not resolvable then an optional of\n     * a default value is restored or Optional.empty\n     * if none is given\n     *\n     * usage\n     * <code>\n     *     let var: Optional<string> = saveResolve(() => a.b.c.d.e, \"foobaz\")\n     * </code>\n     *\n     * @param resolverProducer a lambda which can produce the value\n     * @param defaultValue an optional default value if the producer failes to produce anything\n     * @returns an Optional of the produced value\n     */\n    export function failSaveResolve<T>(resolverProducer: () => T, defaultValue: T = null): Optional<T> {\n        return LangBase.saveResolve(resolverProducer, defaultValue);\n    }\n\n    /**\n     * under some conditions it makes sense to swallow errors and return a default value in the error case\n     * classical example the optional resolution of values in a chain (thankfully now covered by Typescript itself)\n     * another example which we have in our system is that some operations fail only under test due to test framework\n     * limitations while they cannot fail in the real world.\n     *\n     * @param resolverProducer a producer function which produces a value in the non error case\n     * @param defaultValue the default value in case of a fail of the function\n     */\n    export function failSaveExecute<T>(resolverProducer: () => any, defaultValue: T = null): void {\n        LangBase.saveResolve(resolverProducer, defaultValue);\n    }\n\n    /**\n     * returns a given localized message upon a given key\n     * basic java log like templating functionality is included\n     *\n     * @param {String} key the key for the message\n     * @param {String} defaultMessage optional default message if none was found\n     *\n     * Additionally you can pass additional arguments, which are used\n     * in the same way java log templates use the params\n     *\n     * @param templateParams the param list to be filled in\n     */\n    export function getMessage(key: string, defaultMessage?: string, ...templateParams: Array<string>): string {\n        installedLocale = installedLocale ?? new Messages();\n\n        let msg = installedLocale[key] ?? defaultMessage ?? key + \" - undefined message\";\n\n        Stream.of(...templateParams).each((param, cnt) => {\n            msg = msg.replace(new RegExp([\"\\\\{\", cnt, \"\\\\}\"].join(EMPTY_STR), \"g\"), param);\n        });\n\n        return msg;\n    }\n\n\n\n    /**\n     * transforms a key value pair into a string\n     * @param key the key\n     * @param val the value\n     * @param delimiter the delimiter\n     */\n    export function keyValToStr(key: string, val: string, delimiter: string = \"\\n\") {\n        return [key, val].join(delimiter);\n    }\n\n\n    /**\n     * creates an exeption with additional internal parameters\n     * for extra information\n     *\n     * @param {String} title the exception title\n     * @param {String} name  the exception name\n     * @param {String} callerCls the caller class\n     * @param {String} callFunc the caller function\n     * @param {String} message the message for the exception\n     */\n    export function makeException(error: Error, title: string, name: string, callerCls: string, callFunc: string, message: string): Error {\n\n        return new Error(message + (callerCls ?? nameSpace) + callFunc ?? (EMPTY_STR + (<any>arguments).caller.toString()));\n\n    }\n\n    /**\n     * fetches a global config entry\n     * @param {String} configName the name of the configuration entry\n     * @param {Object} defaultValue\n     *\n     * @return either the config entry or if none is given the default value\n     */\n    export function getGlobalConfig(configName: string, defaultValue: any): any {\n        /**\n         * note we could use exists but this is an heavy operation, since the config name usually\n         * given this function here is called very often\n         * is a single entry without . in between we can do the lighter shortcut\n         */\n        return (<any>window)?.myfaces?.config?.[configName] ?? defaultValue;\n    }\n\n\n\n\n    /**\n     * fetches the form in an unprecise manner depending\n     * on an element or event target.\n     *\n     * The idea is that according to the jsf spec\n     * the enclosing form of the issuing element needs to be fetched.\n     *\n     * This is fine, but since then html5 came into the picture with the form attribute the element\n     * can be anywhere referencing its parent form.\n     *\n     * Also theoretically you can have the case of an issuing element enclosing a set of forms\n     * (not really often used, but theoretically it could be input button allows to embed html for instance)\n     *\n     * So the idea is not to limit the issuing form determination to the spec case\n     * but also cover the theoretical and html5 corner case.\n     *\n     * @param elem\n     * @param event\n     */\n    export function getForm(elem: Element, event ?: Event): DQ | never {\n\n        const FORM = \"form\";\n\n        let queryElem = new DQ(elem);\n        let eventTarget = new DQ(getEventTarget(event));\n\n        if (queryElem.isTag(FORM)) {\n            return queryElem;\n        }\n\n        //html 5 for handling\n        if (queryElem.attr(FORM).isPresent()) {\n            let formId = queryElem.attr(FORM).value;\n            let foundForm = DQ.byId(formId);\n            if (foundForm.isPresent()) {\n                return foundForm;\n            }\n        }\n\n        let form = queryElem.parents(FORM)\n            .orElseLazy(() => queryElem.byTagName(FORM, true))\n            .orElseLazy(() => eventTarget.parents(FORM))\n            .orElseLazy(() => eventTarget.byTagName(FORM))\n            .first();\n\n        assertFormExists(form);\n\n        return form;\n    }\n\n    /**\n     * gets the local or global options with local ones having higher priority\n     * if no local or global one was found then the default value is given back\n     *\n     * @param {String} configName the name of the configuration entry\n     * @param {String} localOptions the local options root for the configuration myfaces as default marker is added implicitely\n     *\n     * @param {Object} defaultValue\n     *\n     * @return either the config entry or if none is given the default value\n     */\n    export function getLocalOrGlobalConfig(localOptions: Config, configName: string, defaultValue: any): any {\n        return localOptions.value?.myfaces?.config?.[configName] ??\n            (<any>window)?.myfaces?.config?.[configName] ??\n            defaultValue;\n    }\n\n    /**\n     * assert that the form exists and throw an exception in the case it does not\n     * (TODO move this into the assertions)\n     *\n     * @param form the form to check for\n     */\n    function assertFormExists(form: DomQuery): void | never {\n        if (form.isAbsent()) {\n            throw makeException(new Error(), null, null, \"Impl\", \"getForm\", getMessage(\"ERR_FORM\"));\n        }\n    }\n\n\n\n}","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Config, Optional, ValueEmbedder} from \"./Monad\";\nimport {XMLQuery} from \"./XmlQuery\";\nimport {IStream, LazyStream, Stream} from \"./Stream\";\nimport {ICollector, IStreamDataSource} from \"./SourcesCollectors\";\nimport {Lang} from \"./Lang\";\nimport trim = Lang.trim;\nimport objToArray = Lang.objToArray;\nimport isString = Lang.isString;\nimport equalsIgnoreCase = Lang.equalsIgnoreCase;\n\n// @ts-ignore supression needed here due to fromnullable\nexport class ElementAttribute extends ValueEmbedder<string> {\n\n    constructor(private element: DomQuery, private name: string, private defaultVal: string = null) {\n        super(element, name);\n    }\n\n    get value(): string {\n        let val: Element[] = this.element.get(0).orElse(...[]).values;\n        if (!val.length) {\n            return this.defaultVal;\n        }\n        return val[0].getAttribute(this.name);\n    }\n\n    set value(value: string) {\n        let val: Element[] = this.element.get(0).orElse(...[]).values;\n        for (let cnt = 0; cnt < val.length; cnt++) {\n            val[cnt].setAttribute(this.name, value);\n        }\n        val[0].setAttribute(this.name, value);\n    }\n\n    protected getClass(): any {\n        return ElementAttribute;\n    }\n\n    static fromNullable(value?: any, valueKey: string = \"value\"): ElementAttribute {\n        return new ElementAttribute(value, valueKey);\n    }\n\n}\n\n/**\n * small helper for the specialized jsf case\n * @param src\n * @constructor\n */\nconst DEFAULT_JSF_WHITELIST = (src: string) => {\n    return (src.indexOf(\"ln=scripts\") == -1 &&\n        src.indexOf(\"ln=javax.faces\") == -1) ||\n        (src.indexOf(\"/jsf.js\") == -1 &&\n            src.indexOf(\"/jsf-uncompressed.js\") == -1);\n};\n\ninterface IDomQuery {\n    /**\n     * reads the first element if it exists and returns an optional\n     */\n    readonly value: Optional<Element>;\n    /**\n     * All elements as array\n     */\n    readonly values: Element[];\n    /**\n     * returns the id as settable value (See also ValueEmbedder)\n     */\n    readonly id: ValueEmbedder<string>;\n    /**\n     * returns the length of embedded nodes (top level)\n     */\n    readonly length: number;\n    /**\n     * the tag name of the first element\n     */\n    readonly tagName: Optional<string>;\n    /**\n     * the node name of the first element\n     */\n    readonly nodeName: Optional<string>;\n    /**\n     * the type of the first element\n     */\n    readonly type: Optional<string>;\n    /**\n     * The name as changeable value\n     */\n    readonly name: ValueEmbedder<string>;\n    /**\n     * The the value in case of inputs as changeable value\n     */\n    readonly inputValue: ValueEmbedder<string | boolean>;\n    /**\n     * the underlying form elements as domquery object\n     */\n    readonly elements: DomQuery;\n    /**\n     * settable flag for disabled\n     */\n    disabled: boolean;\n    /**\n     * The child nodes of this node collection as readonly attribute\n     */\n    readonly childNodes: DomQuery;\n    /**\n     * an early stream representation for this DomQuery\n     */\n    readonly stream: Stream<DomQuery>;\n    /**\n     * lazy stream representation for this DomQuery\n     */\n    readonly lazyStream: LazyStream<DomQuery>;\n    /**\n     * transform this node collection to an array\n     */\n    readonly asArray: Array<DomQuery>;\n\n    /**\n     * returns true if the elements have the tag *tagName* as tag embedded (highest level)\n     * @param tagName\n     */\n    isTag(tagName: string): boolean;\n\n    /**\n     * returns the nth element as domquery\n     * from the internal elements\n     * note if you try to reach a non existing element position\n     * you will get back an absent entry\n     *\n     * @param index the nth index\n     */\n    get(index: number): DomQuery;\n\n    /**\n     * returns the nth element as optional of an Element object\n     * @param index the number from the index\n     * @param defaults the default value if the index is overrun default Optional.absent\n     */\n    getAsElem(index: number, defaults: Optional<any>): Optional<Element>;\n\n    /**\n     * returns the value array< of all elements\n     */\n    allElems(): Array<Element>;\n\n    /**\n     * absent no values reached?\n     */\n    isAbsent(): boolean;\n\n    /**\n     * should make the code clearer\n     * note if you pass a function\n     * this refers to the active dopmquery object\n     */\n    isPresent(presentRunnable ?: (elem ?: DomQuery) => void): boolean;\n\n    /**\n     * should make the code clearer\n     * note if you pass a function\n     * this refers to the active dopmquery object\n     *\n     *\n     * @param presentRunnable\n     */\n    ifPresentLazy(presentRunnable: (elem ?: DomQuery) => void): DomQuery;\n\n    /**\n     * remove all affected nodes from this query object from the dom tree\n     */\n    delete(): void;\n\n    /**\n     * query selector all on the existing dom query object\n     *\n     * @param selector the standard selector\n     * @return a DomQuery with the results\n     */\n    querySelectorAll(selector): DomQuery;\n\n    /**\n     * core byId method\n     * @param id the id to search for\n     * @param includeRoot also match the root element?\n     */\n    byId(id: string, includeRoot?: boolean): DomQuery;\n\n    /**\n     * same as byId just for the tag name\n     * @param tagName\n     * @param includeRoot\n     */\n    byTagName(tagName: string, includeRoot ?: boolean): DomQuery;\n\n    /**\n     * attr accessor, usage myQuery.attr(\"class\").value = \"bla\"\n     * or let value myQuery.attr(\"class\").value\n     * @param attr the attribute to set\n     * @param defaultValue the default value in case nothing is presented (defaults to null)\n     */\n    attr(attr: string, defaultValue: string): ElementAttribute;\n\n    /**\n     * hasclass, checks for an existing class in the class attributes\n     *\n     * @param clazz the class to search for\n     */\n    hasClass(clazz: string): boolean;\n\n    /**\n     * appends a class string if not already in the element(s)\n     *\n     * @param clazz the style class to append\n     */\n    addClass(clazz: string): DomQuery;\n\n    /**\n     * remove the style class if in the class definitions\n     *\n     * @param clazz\n     */\n    removeClass(clazz: string): DomQuery;\n\n    /**\n     * checks whether we have a multipart element in our children\n     */\n    isMultipartCandidate(): boolean;\n\n    /**\n     * innerHtml equivalkent\n     * equivalent to jqueries html\n     * as setter the html is set and the\n     * DomQuery is given back\n     * as getter the html string is returned\n     *\n     * @param inval\n     */\n    html(inval?: string): DomQuery | Optional<string>;\n\n    /**\n     * easy node traversal, you can pass\n     * a set of node selectors which are joined as direct childs\n     *\n     * not the rootnodes are not in the getIf, those are always the child nodes\n     *\n     * @param nodeSelector\n     */\n    getIf(...nodeSelector: Array<string>): DomQuery;\n\n    /**\n     * iterate over each element and perform something on the element\n     * (Dom element is passed instead of DomQuery)\n     * @param func\n     */\n    eachElem(func: (item: Element, cnt?: number) => any): DomQuery;\n\n    /**\n     * perform an operation on the first element\n     * returns a DomQuery on the first element only\n     * @param func\n     */\n    firstElem(func: (item: Element, cnt?: number) => any): DomQuery;\n\n    /**\n     * same as eachElem, but a DomQuery object is passed down\n     *\n     * @param func\n     */\n    each(func: (item: DomQuery, cnt?: number) => any): DomQuery;\n\n    /**\n     * returns a new dom query containing only the first element max\n     *\n     * @param func a an optional callback function to perform an operation on the first element\n     */\n    first(func: (item: DomQuery, cnt?: number) => any): DomQuery;\n\n    /**\n     * filter function which filters a subset\n     *\n     * @param func\n     */\n    filter(func: (item: DomQuery) => boolean): DomQuery;\n\n    /**\n     * global eval head appendix method\n     * no other methods are supported anymore\n     * @param code the code to be evaled\n     * @param  nonce optional  nonce key for higher security\n     */\n    globalEval(code: string, nonce ?: string): DomQuery;\n\n    /**\n     * detaches a set of nodes from their parent elements\n     * in a browser independend manner\n     * @param {Object} items the items which need to be detached\n     * @return {Array} an array of nodes with the detached dom nodes\n     */\n    detach(): DomQuery;\n\n    /**\n     * appends the current set of elements\n     * to the element or first element passed via elem\n     * @param elem\n     */\n    appendTo(elem: DomQuery): void;\n\n    /**\n     * loads and evals a script from a source uri\n     *\n     * @param src the source to be loaded and evaled\n     * @param defer in miliseconds execution default (0 == no defer)\n     * @param charSet\n     */\n    loadScriptEval(src: string, defer: number, charSet: string): void;\n\n    /**\n     * insert toInsert after the current element\n     *\n     * @param toInsert an array of DomQuery objects\n     */\n    insertAfter(...toInsert: Array<DomQuery>): DomQuery;\n\n    /**\n     * inserts the elements before the current element\n     *\n     * @param toInsert\n     */\n    insertBefore(...toInsert: Array<DomQuery>): DomQuery;\n\n    /**\n     * in case the domquery is pointing to nothing the else value is taken into consideration\n     * als alternative\n     *\n     * @param elseValue the else value\n     */\n    orElse(...elseValue: any): DomQuery;\n\n    /**\n     * the same with lazy evaluation for cases where getting the else value\n     * is a heavy operation\n     *\n     * @param func the else provider function\n     */\n    orElseLazy(func: () => any): DomQuery;\n\n    /**\n     * all parents with TagName\n     * @param tagName\n     */\n    parents(tagName: string): DomQuery;\n\n    /**\n     * copy all attributes of sourceItem to this DomQuery items\n     *\n     * @param sourceItem the source item to copy over (can be another domquery or a parsed XML Query item)\n     */\n    copyAttrs(sourceItem: DomQuery | XMLQuery): DomQuery;\n\n    /**\n     * outerhtml convenience method\n     * browsers only support innerHTML but\n     * for instance for your jsf.js we have a full\n     * replace pattern which needs outerHTML processing\n     *\n     * @param markup\n     * @param runEmbeddedScripts\n     * @param runEmbeddedCss\n     */\n    outerHTML(markup: string, runEmbeddedScripts ?: boolean, runEmbeddedCss ?: boolean): DomQuery;\n\n    /**\n     * Run through the given nodes in the DomQuery execute the inline scripts\n     * @param whilteListed: optional whitelist function which can filter out script tags which are not processed\n     * defaults to the standard jsf.js exclusion (we use this code for myfaces)\n     */\n    runScripts(whilteListed: (val: string) => boolean): DomQuery;\n\n    /**\n     * runs the embedded css\n     */\n    runCss(): DomQuery;\n\n    /**\n     * fires a click event on the underlying dom elements\n     */\n    click(): DomQuery;\n\n    /**\n     * adds an event listener\n     *\n     * @param type\n     * @param listener\n     * @param options\n     */\n    addEventListener(type: string, listener: (evt: Event) => void, options?: boolean | EventListenerOptions): DomQuery;\n\n    /**\n     * removes an event listener\n     *\n     * @param type\n     * @param listener\n     * @param options\n     */\n    removeEventListener(type: string, listener: (evt: Event) => void, options?: boolean | EventListenerOptions): DomQuery;\n\n    /**\n     * fires an event\n     */\n    fireEvent(eventName: string): void;\n\n    /*\n     * pushes  in optionally a new textContent, and/or returns the current text content\n     */\n    textContent(joinstr?: string): string;\n\n    /*\n     * pushes  in optionally a new innerText, and/or returns the current innerText\n     */\n    innerText(joinstr?: string): string;\n\n    /**\n     * encodes all input elements properly into respective\n     * config entries, this can be used\n     * for legacy systems, for newer usecases, use the\n     * HTML5 Form class which all newer browsers provide\n     *\n     * @param toMerge optional config which can be merged in\n     * @return a copy pf\n     */\n    encodeFormElement(toMerge): Config;\n\n    /**\n     * fetches the subnodes from ... to..\n     * @param from\n     * @param to\n     */\n    subNodes(from: number, to?: number): DomQuery;\n}\n\n/**\n * Monadic DomNode representation, ala jquery\n * This is a thin wrapper over querySelectorAll\n * to get slim monadic support\n * to reduce implementation code on the users side.\n * This is vital for frameworks which want to rely on\n * plain dom but still do not want to lose\n * the reduced code footprint of querying dom trees and traversing\n * by using functional patterns.\n *\n * Also a few convenience methods are added to reduce\n * the code footprint of standard dom processing\n * operations like eval\n *\n * TODO add jquery fallback support, since it is supported\n * in most older systems\n * Note parts of this code still stem from the Dom.js I have written 10 years\n * ago, those parts look a little bit ancient and will be replaced over time.\n *\n */\nexport class DomQuery implements IDomQuery, IStreamDataSource<DomQuery> {\n\n    static absent = new DomQuery();\n\n    private rootNode: Array<Element> = [];\n\n    pos = -1;\n\n    constructor(...rootNode: Array<Element | DomQuery | Document | Array<any> | string>) {\n\n        if (Optional.fromNullable(rootNode).isAbsent() || !rootNode.length) {\n            return;\n        } else {\n            //we need to flatten out the arrays\n\n            for (let cnt = 0; cnt < rootNode.length; cnt++) {\n                if (isString(rootNode[cnt])) {\n                    let foundElement = DomQuery.querySelectorAll(<string>rootNode[cnt]);\n                    if (!foundElement.isAbsent()) {\n                        rootNode.push(...foundElement.values)\n                    }\n                } else if (rootNode[cnt] instanceof DomQuery) {\n                    this.rootNode.push(...(<any>rootNode[cnt]).values);\n                } else {\n                    this.rootNode.push(<any>rootNode[cnt]);\n                }\n            }\n        }\n    }\n\n    /**\n     * returns the first element\n     */\n    get value(): Optional<Element> {\n        return this.getAsElem(0);\n    }\n\n    get values(): Element[] {\n        return this.allElems();\n    }\n\n    /**\n     * returns the id of the first element\n     */\n    get id(): ValueEmbedder<string> {\n        return new ElementAttribute(this.get(0), \"id\");\n    }\n\n    /**\n     * length of the entire query set\n     */\n    get length(): number {\n        return this.rootNode.length\n    }\n\n    /**\n     * convenience method for tagName\n     */\n    get tagName(): Optional<string> {\n        return <Optional<string>>this.getAsElem(0).getIf(\"tagName\");\n    }\n\n    /**\n     * convenience method for nodeName\n     */\n    get nodeName(): Optional<string> {\n        return <Optional<string>>this.getAsElem(0).getIf(\"nodeName\");\n    }\n\n    isTag(tagName: string): boolean {\n        return !this.isAbsent()\n            && (this.nodeName.orElse(\"__none___\")\n                    .value.toLowerCase() == tagName.toLowerCase()\n                || this.tagName.orElse(\"__none___\")\n                    .value.toLowerCase() == tagName.toLowerCase()\n            )\n    }\n\n    /**\n     * convenience property for type\n     *\n     * returns null in case of no type existing otherwise\n     * the type of the first element\n     */\n    get type(): Optional<string> {\n        return this.getAsElem(0).getIf(\"type\");\n    }\n\n    /**\n     * convenience property for name\n     *\n     * returns null in case of no type existing otherwise\n     * the name of the first element\n     */\n    get name(): ValueEmbedder<string> {\n        return new ValueEmbedder(this.getAsElem(0).value, \"name\");\n    }\n\n    /**\n     * convenience property for value\n     *\n     * returns null in case of no type existing otherwise\n     * the value of the first element\n     */\n    get inputValue(): ValueEmbedder<string | boolean> {\n        if (this.getAsElem(0).getIf(\"value\").isPresent()) {\n            return new ValueEmbedder<string>(this.getAsElem(0).value);\n        } else {\n            return <any>ValueEmbedder.absent;\n        }\n    }\n\n    get checked(): boolean {\n        return Stream.of(...this.values).allMatch(el => !!(<any>el).checked);\n    }\n\n    set checked(newChecked: boolean) {\n        this.eachElem(el => (<any>el).checked = newChecked);\n    }\n\n    get elements(): DomQuery {\n        let elements: DomQuery = this.stream.flatMap((item: DomQuery) => {\n            let formElement: HTMLFormElement = <HTMLFormElement>item.value.value;\n            return new Stream(formElement.elements ? objToArray(formElement.elements) : []);\n        }).filter(item => !!item).collect(new DomQueryCollector());\n\n        return elements\n            .orElseLazy(() => this.querySelectorAll(\"input, select, textarea, fieldset\"));\n    }\n\n    /**\n     * todo align this api with the rest of the apis\n     */\n    get disabled(): boolean {\n        return this.attr(\"disabled\").isPresent();\n    }\n\n    set disabled(disabled: boolean) {\n        // this.attr(\"disabled\").value = disabled + \"\";\n        if (!disabled) {\n            this.removeAttribute(\"disabled\");\n        } else {\n            this.attr(\"disabled\").value = \"disabled\";\n        }\n\n    }\n\n    removeAttribute(name: string) {\n        this.eachElem(item => item.removeAttribute(name));\n    }\n\n    get childNodes(): DomQuery {\n        let childNodeArr: Array<Element> = [];\n        this.eachElem((item: Element) => {\n            childNodeArr = childNodeArr.concat(objToArray(item.childNodes));\n        });\n        return new DomQuery(...childNodeArr);\n    }\n\n    /**\n     * binding into stream\n     */\n    get stream(): Stream<DomQuery> {\n        return new Stream<DomQuery>(...this.asArray);\n    }\n\n    /**\n     * fetches a lazy stream representation\n     * lazy should be applied if you have some filters etc\n     * in between, this can reduce the number of post filter operations\n     * and ram usage\n     * significantly because the operations are done lazily and stop\n     * once they hit a dead end.\n     */\n    get lazyStream(): LazyStream<DomQuery> {\n        return LazyStream.ofStreamDataSource(this);\n    }\n\n    get asArray(): Array<DomQuery> {\n        let ret: Array<DomQuery> = [];\n        this.each((item) => {\n            ret.push(item);\n        });\n        return ret;\n    }\n\n    /**\n     * easy query selector all producer\n     *\n     * @param selector the selector\n     * @returns a results dom query object\n     */\n    static querySelectorAll(selector: string): DomQuery {\n        return new DomQuery(document).querySelectorAll(selector);\n    }\n\n    /**\n     * byId producer\n     *\n     * @param selector id\n     * @return a DomQuery containing the found elements\n     */\n    static byId(selector: string | DomQuery | Element): DomQuery {\n        if (isString(selector)) {\n            return new DomQuery(document).byId(<string>selector);\n        } else {\n            return new DomQuery(<any>selector);\n        }\n    }\n\n    /**\n     * byTagName producer\n     *\n     * @param selector name\n     * @return a DomQuery containing the found elements\n     */\n    static byTagName(selector: string | DomQuery | Element): DomQuery {\n        if (isString(selector)) {\n            return new DomQuery(document).byTagName(<string>selector);\n        } else {\n            return new DomQuery(<any>selector);\n        }\n    }\n\n    static globalEval(code: string, nonce?: string): DomQuery {\n        return new DomQuery(document).globalEval(code, nonce);\n    }\n\n    /**\n     * builds the ie nodes properly in a placeholder\n     * and bypasses a non script insert bug that way\n     * @param markup the marku code\n     */\n    static fromMarkup(markup: string): DomQuery {\n\n        //https://developer.mozilla.org/de/docs/Web/API/DOMParser license creative commons\n        const doc = document.implementation.createHTMLDocument(\"\");\n        markup = trim(markup);\n        let lowerMarkup = markup.toLowerCase();\n        if (lowerMarkup.indexOf('<!doctype') != -1 ||\n            lowerMarkup.indexOf('<html') != -1 ||\n            lowerMarkup.indexOf('<head') != -1 || //TODO proper regexps here to avoid embedded tags with same element names to be triggered\n            lowerMarkup.indexOf('<body') != -1) {\n            doc.documentElement.innerHTML = markup;\n            return new DomQuery(doc.documentElement);\n        } else {\n            let startsWithTag = function (str: string, tagName: string) {\n                let tag1 = [\"<\", tagName, \">\"].join(\"\");\n                let tag2 = [\"<\", tagName, \" \"].join(\"\");\n                return (str.indexOf(tag1) == 0) || (str.indexOf(tag2) == 0);\n            };\n\n            let dummyPlaceHolder = new DomQuery(document.createElement(\"div\"));\n\n            //table needs special treatment due to the browsers auto creation\n            if (startsWithTag(lowerMarkup, \"thead\") || startsWithTag(lowerMarkup, \"tbody\")) {\n                dummyPlaceHolder.html(`<table>${markup}</table>`);\n                return dummyPlaceHolder.querySelectorAll(\"table\").get(0).childNodes.detach();\n            } else if (startsWithTag(lowerMarkup, \"tfoot\")) {\n                dummyPlaceHolder.html(`<table><thead></thead><tbody><tbody${markup}</table>`);\n                return dummyPlaceHolder.querySelectorAll(\"table\").get(2).childNodes.detach();\n            } else if (startsWithTag(lowerMarkup, \"tr\")) {\n                dummyPlaceHolder.html(`<table><tbody>${markup}</tbody></table>`);\n                return dummyPlaceHolder.querySelectorAll(\"tbody\").get(0).childNodes.detach();\n            } else if (startsWithTag(lowerMarkup, \"td\")) {\n                dummyPlaceHolder.html(`<table><tbody><tr>${markup}</tr></tbody></table>`);\n                return dummyPlaceHolder.querySelectorAll(\"tr\").get(0).childNodes.detach();\n            }\n\n            dummyPlaceHolder.html(markup);\n            return dummyPlaceHolder.childNodes.detach();\n        }\n\n    }\n\n    /**\n     * returns the nth element as domquery\n     * from the internal elements\n     * note if you try to reach a non existing element position\n     * you will get back an absent entry\n     *\n     * @param index the nth index\n     */\n    get(index: number): DomQuery {\n        return (index < this.rootNode.length) ? new DomQuery(this.rootNode[index]) : DomQuery.absent;\n    }\n\n    /**\n     * returns the nth element as optional of an Element object\n     * @param index the number from the index\n     * @param defaults the default value if the index is overrun default Optional.absent\n     */\n    getAsElem(index: number, defaults: Optional<any> = Optional.absent): Optional<Element> {\n        return (index < this.rootNode.length) ? Optional.fromNullable(this.rootNode[index]) : defaults;\n    }\n\n    /**\n     * returns the value array< of all elements\n     */\n    allElems(): Array<Element> {\n        return this.rootNode;\n    }\n\n    /**\n     * absent no values reached?\n     */\n    isAbsent(): boolean {\n        return this.length == 0;\n    }\n\n    /**\n     * should make the code clearer\n     * note if you pass a function\n     * this refers to the active dopmquery object\n     */\n    isPresent(presentRunnable ?: (elem ?: DomQuery) => void): boolean {\n        let absent = this.isAbsent();\n        if (!absent && presentRunnable) {\n            presentRunnable.call(this, this)\n        }\n        return !absent;\n    }\n\n    /**\n     * should make the code clearer\n     * note if you pass a function\n     * this refers to the active dopmquery object\n     *\n     *\n     * @param presentRunnable\n     */\n    ifPresentLazy(presentRunnable: (elem ?: DomQuery) => void = function () {\n    }): DomQuery {\n        this.isPresent.call(this, presentRunnable);\n        return this;\n    }\n\n    /**\n     * remove all affected nodes from this query object from the dom tree\n     */\n    delete() {\n        this.eachElem((node: Element) => {\n            if (node.parentNode) {\n                node.parentNode.removeChild(node);\n            }\n        });\n    }\n\n    /**\n     * query selector all on the existing dom query object\n     *\n     * @param selector the standard selector\n     * @return a DomQuery with the results\n     */\n    querySelectorAll(selector): DomQuery {\n        if (!this?.rootNode?.length) {\n            return this;\n        }\n        let nodes = [];\n        for (let cnt = 0; cnt < this.rootNode.length; cnt++) {\n            if (!this.rootNode[cnt]?.querySelectorAll) {\n                continue;\n            }\n            let res = this.rootNode[cnt].querySelectorAll(selector);\n            nodes = nodes.concat(objToArray(res));\n        }\n\n        return new DomQuery(...nodes);\n    }\n\n    /**\n     * core byId method\n     * @param id the id to search for\n     * @param includeRoot also match the root element?\n     */\n    byId(id: string, includeRoot?: boolean): DomQuery {\n        let res: Array<DomQuery> = [];\n        for (let cnt = 0; includeRoot && cnt < this.rootNode.length; cnt++) {\n            if (this.rootNode[cnt]?.id == id) {\n                res.push(new DomQuery(this.rootNode[cnt]));\n            }\n        }\n        //for some strange kind of reason the # selector fails\n        //on hidden elements we use the attributes match selector\n        //that works\n        res = res.concat(this.querySelectorAll(`[id=\"${id}\"]`));\n        return new DomQuery(...res);\n    }\n\n    /**\n     * same as byId just for the tag name\n     * @param tagName\n     * @param includeRoot\n     */\n    byTagName(tagName: string, includeRoot ?: boolean): DomQuery {\n        let res = [];\n        for (let cnt = 0; includeRoot && cnt < this.rootNode.length; cnt++) {\n            if (this.rootNode[cnt]?.tagName == tagName) {\n                res.push(new DomQuery(this.rootNode[cnt]));\n            }\n        }\n        res = res.concat(this.querySelectorAll(tagName));\n        return new DomQuery(...res);\n    }\n\n    /**\n     * attr accessor, usage myQuery.attr(\"class\").value = \"bla\"\n     * or let value myQuery.attr(\"class\").value\n     * @param attr the attribute to set\n     * @param defaultValue the default value in case nothing is presented (defaults to null)\n     */\n    attr(attr: string, defaultValue: string = null): ElementAttribute {\n        return new ElementAttribute(this, attr, defaultValue);\n    }\n\n    /**\n     * hasclass, checks for an existing class in the class attributes\n     *\n     * @param clazz the class to search for\n     */\n    hasClass(clazz: string) {\n        let hasIt = false;\n\n        this.each((item) => {\n            let oldClass = item.attr(\"class\").value || \"\";\n            if (oldClass.toLowerCase().indexOf(clazz.toLowerCase()) == -1) {\n                return;\n            } else {\n                let oldClasses = oldClass.split(/\\s+/gi);\n                let found = false;\n                for (let cnt = 0; cnt < oldClasses.length && !found; cnt++) {\n                    found = oldClasses[cnt].toLowerCase() == clazz.toLowerCase();\n                }\n                hasIt = hasIt || found;\n                if (hasIt) {\n                    return false;\n                }\n            }\n        });\n        return hasIt;\n    }\n\n    /**\n     * appends a class string if not already in the element(s)\n     *\n     * @param clazz the style class to append\n     */\n    addClass(clazz: string): DomQuery {\n        this.each((item) => {\n            let oldClass = item.attr(\"class\").value || \"\";\n            if (!this.hasClass(clazz)) {\n                item.attr(\"class\").value = trim(oldClass + \" \" + clazz);\n                return;\n            }\n        });\n        return this;\n    }\n\n    /**\n     * remove the style class if in the class definitions\n     *\n     * @param clazz\n     */\n    removeClass(clazz: string): DomQuery {\n        this.each((item) => {\n            if (this.hasClass(clazz)) {\n                let oldClass = item.attr(\"class\").value || \"\";\n                let newClasses = [];\n                let oldClasses = oldClass.split(/\\s+/gi);\n                for (let cnt = 0; cnt < oldClasses.length; cnt++) {\n                    if (oldClasses[cnt].toLowerCase() != clazz.toLowerCase()) {\n                        newClasses.push(oldClasses[cnt]);\n                    }\n                }\n                item.attr(\"class\").value = newClasses.join(\" \");\n            }\n        });\n        return this;\n    }\n\n    /**\n     * checks whether we have a multipart element in our children\n     */\n    isMultipartCandidate(): boolean {\n        return this.querySelectorAll(\"input[type='file']\").firstElem().isPresent();\n    }\n\n    /**\n     * innerHtml equivalkent\n     * equivalent to jqueries html\n     * as setter the html is set and the\n     * DomQuery is given back\n     * as getter the html string is returned\n     *\n     * @param inval\n     */\n    html(inval?: string): DomQuery | Optional<string> {\n        if (Optional.fromNullable(inval).isAbsent()) {\n            return this.isPresent() ? Optional.fromNullable(this.innerHtml) : Optional.absent;\n        }\n        this.innerHtml = inval;\n\n        return this;\n    }\n\n    set innerHtml(inVal: string) {\n        this.eachElem(elem => elem.innerHTML = inVal);\n    }\n\n    get innerHtml(): string {\n        let retArr = [];\n        this.eachElem(elem => retArr.push(elem.innerHTML));\n        return retArr.join(\"\");\n    }\n\n    //source: https://developer.mozilla.org/en-US/docs/Web/API/Element/matches\n    //code snippet license: https://creativecommons.org/licenses/by-sa/2.5/\n    private _mozMatchesSelector(toMatch: Element, selector: string): boolean {\n        let prot: { [key: string]: Function } = (<any>toMatch);\n        let matchesSelector: Function = prot.matchesSelector ||\n            prot.mozMatchesSelector ||\n            prot.msMatchesSelector ||\n            prot.oMatchesSelector ||\n            prot.webkitMatchesSelector ||\n            function (s: string) {\n                let matches: NodeListOf<HTMLElement> = (document || (<any>window).ownerDocument).querySelectorAll(s),\n                    i = matches.length;\n                while (--i >= 0 && matches.item(i) !== toMatch) {\n                }\n                return i > -1;\n            };\n        return matchesSelector.call(toMatch, selector);\n    }\n\n    /**\n     * filters the current dom query elements\n     * upon a given selector\n     *\n     * @param selector\n     */\n    filterSelector(selector: string): DomQuery {\n        let matched = [];\n\n        this.eachElem(item => {\n            if (this._mozMatchesSelector(item, selector)) {\n                matched.push(item)\n            }\n        });\n        return new DomQuery(...matched);\n    }\n\n    matchesSelector(selector: string): boolean {\n        this.eachElem(item => {\n            if (!this._mozMatchesSelector(item, selector)) {\n                return false;\n            }\n        });\n        return true;\n    }\n\n    /**\n     * easy node traversal, you can pass\n     * a set of node selectors which are joined as direct childs\n     *\n     * not the rootnodes are not in the getIf, those are always the child nodes\n     *\n     * @param nodeSelector\n     */\n    getIf(...nodeSelector: Array<string>): DomQuery {\n\n        let selectorStage: DomQuery = this.childNodes;\n        for (let cnt = 0; cnt < nodeSelector.length; cnt++) {\n            selectorStage = selectorStage.filterSelector(nodeSelector[cnt]);\n            if (selectorStage.isAbsent()) {\n                return selectorStage;\n            }\n        }\n        return selectorStage;\n    }\n\n    eachElem(func: (item: Element, cnt?: number) => any): DomQuery {\n        for (let cnt = 0, len = this.rootNode.length; cnt < len; cnt++) {\n            if (func(this.rootNode[cnt], cnt) === false) {\n                break;\n            }\n        }\n        return this;\n    }\n\n    firstElem(func: (item: Element, cnt?: number) => any = item => item): DomQuery {\n        if (this.rootNode.length > 1) {\n            func(this.rootNode[0], 0);\n        }\n        return this;\n    }\n\n    each(func: (item: DomQuery, cnt?: number) => any): DomQuery {\n        Stream.of(...this.rootNode)\n            .each((item, cnt) => {\n                //we could use a filter, but for the best performance we dont\n                if (item == null) {\n                    return;\n                }\n                return func(DomQuery.byId(item), cnt);\n            });\n\n        return this;\n    }\n\n    /**\n     * returns a new dom query containing only the first element max\n     *\n     * @param func a an optional callback function to perform an operation on the first element\n     */\n    first(func: (item: DomQuery, cnt?: number) => any = (item) => item): DomQuery {\n        if (this.rootNode.length >= 1) {\n            func(this.get(0), 0);\n            return this.get(0);\n        }\n        return this;\n    }\n\n    /**\n     * filter function which filters a subset\n     *\n     * @param func\n     */\n    filter(func: (item: DomQuery) => boolean): DomQuery {\n        let reArr: Array<DomQuery> = [];\n        this.each((item: DomQuery) => {\n            func(item) ? reArr.push(item) : null;\n        });\n        return new DomQuery(...<any>reArr);\n    }\n\n    //TODO append prepend\n\n    /**\n     * global eval head appendix method\n     * no other methods are supported anymore\n     * @param code the code to be evaled\n     * @param  nonce optional  nonce key for higher security\n     */\n    globalEval(code: string, nonce ?: string): DomQuery {\n        let head = document.getElementsByTagName(\"head\")[0] || document.documentElement;\n        let script = document.createElement(\"script\");\n        if (nonce) {\n            script.setAttribute(\"nonce\", nonce);\n        }\n        script.type = \"text/javascript\";\n        script.innerHTML = code;\n        let newScriptElement = head.appendChild(script);\n        head.removeChild(newScriptElement);\n        return this;\n    }\n\n    /**\n     * detaches a set of nodes from their parent elements\n     * in a browser independend manner\n     * @param {Object} items the items which need to be detached\n     * @return {Array} an array of nodes with the detached dom nodes\n     */\n    detach(): DomQuery {\n        this.eachElem((item: Element) => {\n            item.parentNode.removeChild(item);\n        });\n        return this;\n    }\n\n    /**\n     * appends the current set of elements\n     * to the element or first element passed via elem\n     * @param elem\n     */\n    appendTo(elem: DomQuery) {\n        this.eachElem((item) => {\n            let value1: Element = <Element>elem.getAsElem(0).orElseLazy(() => {\n                return {\n                    appendChild: (theItem: any) => {\n                    }\n                }\n            }).value;\n            value1.appendChild(item);\n        });\n    }\n\n    /**\n     * loads and evals a script from a source uri\n     *\n     * @param src the source to be loaded and evaled\n     * @param defer in miliseconds execution default (0 == no defer)\n     * @param charSet\n     */\n    loadScriptEval(src: string, defer: number = 0, charSet: string = \"utf-8\") {\n        let xhr = new XMLHttpRequest();\n        xhr.open(\"GET\", src, false);\n\n        if (charSet) {\n            xhr.setRequestHeader(\"Content-Type\", \"application/x-javascript; charset:\" + charSet);\n        }\n\n        xhr.send(null);\n\n        xhr.onload = (responseData: any) => {\n            //defer also means we have to process after the ajax response\n            //has been processed\n            //we can achieve that with a small timeout, the timeout\n            //triggers after the processing is done!\n            if (!defer) {\n                this.globalEval(xhr.responseText.replace(\"\\n\", \"\\r\\n\") + \"\\r\\n//@ sourceURL=\" + src);\n            } else {\n                //TODO not ideal we maybe ought to move to something else here\n                //but since it is not in use yet, it is ok\n                setTimeout(() => {\n                    this.globalEval(xhr.responseText + \"\\r\\n//@ sourceURL=\" + src);\n                }, defer);\n            }\n        };\n\n        xhr.onerror = (data: any) => {\n            throw Error(data);\n        };\n        //since we are synchronous we do it after not with onReadyStateChange\n\n        return this;\n    }\n\n    insertAfter(...toInsertParams: Array<DomQuery>): DomQuery {\n\n        this.each(existingItem => {\n            let existingElement = existingItem.getAsElem(0).value;\n            let rootNode = existingElement.parentNode;\n            for (let cnt = 0; cnt < toInsertParams.length; cnt++) {\n                let nextSibling: Element = <any>existingElement.nextSibling;\n                toInsertParams[cnt].eachElem(insertElem => {\n                    if (nextSibling) {\n                        rootNode.insertBefore(insertElem, nextSibling);\n                        existingElement = nextSibling;\n                    } else {\n                        rootNode.appendChild(insertElem);\n                    }\n                });\n\n            }\n        });\n\n        let res = [];\n        res.push(this);\n        res = res.concat(toInsertParams);\n        return new DomQuery(...res);\n    }\n\n    insertBefore(...toInsertParams: Array<DomQuery>): DomQuery {\n        this.each(existingItem => {\n            let existingElement = existingItem.getAsElem(0).value;\n            let rootNode = existingElement.parentNode;\n            for (let cnt = 0; cnt < toInsertParams.length; cnt++) {\n                toInsertParams[cnt].eachElem(insertElem => {\n                    rootNode.insertBefore(insertElem, existingElement);\n                });\n            }\n        });\n        let res = [];\n        res.push(this);\n        res = res.concat(toInsertParams);\n        return new DomQuery(...res);\n    }\n\n    orElse(...elseValue: any): DomQuery {\n        if (this.isPresent()) {\n            return this;\n        } else {\n            return new DomQuery(...elseValue);\n        }\n    }\n\n    orElseLazy(func: () => any): DomQuery {\n        if (this.isPresent()) {\n            return this;\n        } else {\n            return new DomQuery(func());\n        }\n    }\n\n    parents(tagName: string): DomQuery {\n        const retSet: Set<Element> = new Set();\n        const retArr: Array<Element> = [];\n        const lowerTagName = tagName.toLowerCase();\n\n        let resolveItem = (item: Element) => {\n            if ((item.tagName || \"\").toLowerCase() == lowerTagName && !retSet.has(item)) {\n                retSet.add(item);\n                retArr.push(item);\n            }\n        };\n\n        this.eachElem((item: Element) => {\n            while (item.parentNode) {\n                item = <Element>item.parentNode;\n                resolveItem(item);\n                //nested forms not possible, performance shortcut\n                if (tagName == \"form\" && retArr.length) {\n                    return false;\n                }\n            }\n        });\n\n        return new DomQuery(...retArr);\n    }\n\n    copyAttrs(sourceItem: DomQuery | XMLQuery): DomQuery {\n        sourceItem.eachElem((sourceNode: Element) => {\n            let attrs: Array<Attr> = objToArray(sourceNode.attributes);\n            for (let item of attrs) {\n                let value: string = item.value;\n                let name: string = item.name;\n\n                switch (name) {\n                    case \"id\":\n                        this.id.value = value;\n                        break;\n                    case \"disabled\":\n                        this.resolveAttributeHolder(\"disabled\").disabled = value;\n                        break;\n                    case \"checked\":\n                        this.resolveAttributeHolder(\"checked\").checked = value;\n                        break;\n                    default:\n                        this.attr(name).value = value;\n                }\n            }\n        });\n        return this;\n    }\n\n    /**\n     * resolves an attribute holder compared\n     * @param attrName the attribute name\n     */\n    private resolveAttributeHolder(attrName: string = \"value\"): HTMLFormElement | any {\n        let ret = [];\n        ret[attrName] = null;\n        return (attrName in this.getAsElem(0).value) ?\n            this.getAsElem(0).value :\n            ret;\n    }\n\n    /**\n     * outerhtml convenience method\n     * browsers only support innerHTML but\n     * for instance for your jsf.js we have a full\n     * replace pattern which needs outerHTML processing\n     *\n     * @param markup\n     * @param runEmbeddedScripts\n     * @param runEmbeddedCss\n     */\n    outerHTML(markup: string, runEmbeddedScripts ?: boolean, runEmbeddedCss ?: boolean): DomQuery {\n        if (this.isAbsent()) {\n            return;\n        }\n\n        let focusElementId = document?.activeElement?.id;\n        let caretPosition = (focusElementId) ? DomQuery.getCaretPosition(document.activeElement) : null;\n        let nodes = DomQuery.fromMarkup(markup);\n        let res = [];\n        let toReplace = this.getAsElem(0).value;\n        let firstInsert = nodes.get(0);\n        let parentNode = toReplace.parentNode;\n        let replaced = firstInsert.getAsElem(0).value;\n        parentNode.replaceChild(replaced, toReplace);\n        res.push(new DomQuery(replaced));\n        //no replacement possible\n        if (this.isAbsent()) {\n            return this;\n        }\n\n        let insertAdditionalItems = [];\n\n        if (nodes.length > 1) {\n            insertAdditionalItems = insertAdditionalItems.concat(...nodes.values.slice(1));\n            res.push(DomQuery.byId(replaced).insertAfter(new DomQuery(...insertAdditionalItems)));\n        }\n\n        if (runEmbeddedScripts) {\n            this.runScripts();\n        }\n        if (runEmbeddedCss) {\n            this.runCss();\n        }\n\n        let focusElement = DomQuery.byId(focusElementId);\n        if (focusElementId && focusElement.isPresent() &&\n            caretPosition != null && \"undefined\" != typeof caretPosition) {\n            focusElement.eachElem(item => DomQuery.setCaretPosition(item, caretPosition));\n        }\n\n        return nodes;\n    }\n\n    /**\n     * Run through the given nodes in the DomQuery execute the inline scripts\n     * @param whilteListed: optional whitelist function which can filter out script tags which are not processed\n     * defaults to the standard jsf.js exclusion (we use this code for myfaces)\n     */\n    runScripts(whilteListed: (val: string) => boolean = DEFAULT_JSF_WHITELIST): DomQuery {\n        let finalScripts = [],\n            equi = equalsIgnoreCase,\n            execScrpt = (item) => {\n                let tagName = item.tagName;\n                let itemType = item.type || \"\";\n                if (tagName && equi(tagName, \"script\") &&\n                    (itemType === \"\" || equi(itemType, \"text/javascript\") ||\n                        equi(itemType, \"javascript\") ||\n                        equi(itemType, \"text/ecmascript\") ||\n                        equi(itemType, \"ecmascript\"))) {\n                    let src = item.getAttribute('src');\n                    if ('undefined' != typeof src\n                        && null != src\n                        && src.length > 0\n                    ) {\n                        //we have to move this into an inner if because chrome otherwise chokes\n                        //due to changing the and order instead of relying on left to right\n                        //if jsf.js is already registered we do not replace it anymore\n                        if (whilteListed(src)) {\n                            if (finalScripts.length) {\n                                //script source means we have to eval the existing\n                                //scripts before running the include\n                                this.globalEval(finalScripts.join(\"\\n\"));\n\n                                finalScripts = [];\n                            }\n                            this.loadScriptEval(src, 0, \"UTF-8\");\n                        }\n\n                    } else {\n                        // embedded script auto eval\n                        //TODO this probably needs to be changed due to our new parsing structures\n                        //probably not needed anymore\n                        let evalText = trim(item.text || item.innerText || item.innerHTML);\n                        let go = true;\n\n                        while (go) {\n                            go = false;\n                            if (evalText.substring(0, 4) == \"<!--\") {\n                                evalText = evalText.substring(4);\n                                go = true;\n                            }\n                            if (evalText.substring(0, 4) == \"//<!--\") {\n                                evalText = evalText.substring(6);\n                                go = true;\n                            }\n                            if (evalText.substring(0, 11) == \"//<![CDATA[\") {\n                                evalText = evalText.substring(11);\n                                go = true;\n                            }\n                        }\n                        // we have to run the script under a global context\n                        //we store the script for less calls to eval\n                        finalScripts.push(evalText);\n\n                    }\n                }\n            };\n        try {\n            let scriptElements = new DomQuery(this.filterSelector(\"script\"), this.querySelectorAll(\"script\"));\n            //script execution order by relative pos in their dom tree\n            scriptElements.stream\n                .flatMap(item => {\n                    return Stream.of(item.values)\n                })\n                .sort((node1, node2) => {\n                    return node1.compareDocumentPosition(node2) - 3; //preceding 2, following == 4\n                })\n                .each(item => execScrpt(item));\n\n            if (finalScripts.length) {\n                this.globalEval(finalScripts.join(\"\\n\"));\n            }\n        } catch (e) {\n            if (window.console && window.console.error) {\n                //not sure if we\n                //should use our standard\n                //error mechanisms here\n                //because in the head appendix\n                //method only a console\n                //error would be raised as well\n                console.error(e.message || e.description);\n            }\n        } finally {\n            //the usual ie6 fix code\n            //the IE6 garbage collector is broken\n            //nulling closures helps somewhat to reduce\n            //mem leaks, which are impossible to avoid\n            //at this browser\n            execScrpt = null;\n        }\n        return this;\n    }\n\n    runCss(): DomQuery {\n\n        const applyStyle = (item: Element, style: string) => {\n                let newSS: HTMLStyleElement = document.createElement(\"style\");\n                document.getElementsByTagName(\"head\")[0].appendChild(newSS);\n\n                let styleSheet = newSS.sheet ?? (<any>newSS).styleSheet;\n\n                newSS.setAttribute(\"rel\", item.getAttribute(\"rel\") ?? \"stylesheet\");\n                newSS.setAttribute(\"type\", item.getAttribute(\"type\") ?? \"text/css\");\n\n                if (styleSheet?.cssText ?? false) {\n                    styleSheet.cssText = style;\n                } else {\n                    newSS.appendChild(document.createTextNode(style));\n                }\n            },\n\n            execCss = (item: Element) => {\n                const tagName = item.tagName;\n                if (tagName && equalsIgnoreCase(tagName, \"link\") && equalsIgnoreCase(item.getAttribute(\"type\"), \"text/css\")) {\n                    applyStyle(item, \"@import url('\" + item.getAttribute(\"href\") + \"');\");\n                } else if (tagName && equalsIgnoreCase(tagName, \"style\") && equalsIgnoreCase(item.getAttribute(\"type\"), \"text/css\")) {\n                    let innerText = [];\n                    //compliant browsers know child nodes\n                    let childNodes: NodeList = item.childNodes;\n                    if (childNodes) {\n                        const len = childNodes.length;\n                        for (let cnt = 0; cnt < len; cnt++) {\n                            innerText.push((<Element>childNodes[cnt]).innerHTML || (<CharacterData>childNodes[cnt]).data);\n                        }\n                        //non compliant ones innerHTML\n                    } else if (item.innerHTML) {\n                        innerText.push(item.innerHTML);\n                    }\n\n                    applyStyle(item, innerText.join(\"\"));\n                }\n            };\n\n        const scriptElements: DomQuery = new DomQuery(this.filterSelector(\"link, style\"), this.querySelectorAll(\"link, style\"));\n\n        scriptElements.stream\n            .flatMap(item => {\n                return Stream.of(item.values)\n            })\n            .sort((node1, node2) => {\n                return node1.compareDocumentPosition(node2) - 3; //preceding 2, following == 4\n            })\n            .each(item => execCss(item));\n\n        return this;\n    }\n\n    /**\n     * fires a click event on the underlying dom elements\n     */\n    click(): DomQuery {\n        this.fireEvent(\"click\");\n        return this;\n    }\n\n    addEventListener(type: string, listener: (evt: Event) => void, options?: boolean | EventListenerOptions): DomQuery {\n        this.eachElem((node: Element) => {\n            node.addEventListener(type, listener, options);\n        });\n        return this;\n    }\n\n    removeEventListener(type: string, listener: (evt: Event) => void, options?: boolean | EventListenerOptions): DomQuery {\n        this.eachElem((node: Element) => {\n            node.removeEventListener(type, listener, options);\n        });\n        return this;\n    }\n\n    /**\n     * fires an event\n     */\n    fireEvent(eventName: string) {\n        this.eachElem((node: Element) => {\n            let doc;\n            if (node.ownerDocument) {\n                doc = node.ownerDocument;\n            } else if (node.nodeType == 9) {\n                // the node may be the document itself, nodeType 9 = DOCUMENT_NODE\n                doc = node;\n            } else {\n                throw new Error(\"Invalid node passed to fireEvent: \" + node.id);\n            }\n\n            if (node.dispatchEvent) {\n                // Gecko-style approach (now the standard) takes more work\n                let eventClass = \"\";\n\n                // Different events have different event classes.\n                // If this switch statement can't map an eventName to an eventClass,\n                // the event firing is going to fail.\n                switch (eventName) {\n                    case \"click\": // Dispatching of 'click' appears to not work correctly in Safari. Use 'mousedown' or 'mouseup' instead.\n                    case \"mousedown\":\n                    case \"mouseup\":\n                        eventClass = \"MouseEvents\";\n                        break;\n\n                    case \"focus\":\n                    case \"change\":\n                    case \"blur\":\n                    case \"select\":\n                        eventClass = \"HTMLEvents\";\n                        break;\n\n                    default:\n                        throw \"fireEvent: Couldn't find an event class for event '\" + eventName + \"'.\";\n                        break;\n                }\n                let event = doc.createEvent(eventClass);\n                event.initEvent(eventName, true, true); // All events created as bubbling and cancelable.\n\n                event.synthetic = true; // allow detection of synthetic events\n                // The second parameter says go ahead with the default action\n                node.dispatchEvent(event);\n            } else if ((<any>node).fireEvent) {\n                // IE-old school style, you can drop this if you don't need to support IE8 and lower\n                let event = doc.createEventObject();\n                event.synthetic = true; // allow detection of synthetic events\n                (<any>node).fireEvent(\"on\" + eventName, event);\n            }\n        })\n    }\n\n    textContent(joinstr: string = \"\"): string {\n        return this.stream\n            .map((value: DomQuery) => {\n                let item = value.getAsElem(0).orElseLazy(() => {\n                    return <any>{\n                        textContent: \"\"\n                    };\n                }).value;\n                return (<any>item).textContent || \"\";\n            })\n            .reduce((text1, text2) => text1 + joinstr + text2, \"\").value;\n    }\n\n    innerText(joinstr: string = \"\"): string {\n        return this.stream\n            .map((value: DomQuery) => {\n                let item = value.getAsElem(0).orElseLazy(() => {\n                    return <any>{\n                        innerText: \"\"\n                    };\n                }).value;\n                return (<any>item).innerText || \"\";\n            })\n            .reduce((text1, text2) => [text1, text2].join(joinstr), \"\").value;\n\n    }\n\n    /**\n     * encodes all input elements properly into respective\n     * config entries, this can be used\n     * for legacy systems, for newer usecases, use the\n     * HTML5 Form class which all newer browsers provide\n     *\n     * @param toMerge optional config which can be merged in\n     * @return a copy pf\n     */\n    encodeFormElement(toMerge = new Config({})): Config {\n\n        //browser behavior no element name no encoding (normal submit fails in that case)\n        //https://issues.apache.org/jira/browse/MYFACES-2847\n        if (this.name.isAbsent()) {\n            return;\n        }\n\n        //lets keep it sideffects free\n        let target = toMerge.shallowCopy;\n\n        this.each((element: DomQuery) => {\n            if (element.name.isAbsent()) {//no name, no encoding\n                return;\n            }\n            let name = element.name.value;\n            let tagName = element.tagName.orElse(\"__none__\").value.toLowerCase();\n            let elemType = element.type.orElse(\"__none__\").value.toLowerCase();\n\n            elemType = elemType.toLowerCase();\n\n            // routine for all elements\n            // rules:\n            // - process only inputs, textareas and selects\n            // - elements muest have attribute \"name\"\n            // - elements must not be disabled\n            if (((tagName == \"input\" || tagName == \"textarea\" || tagName == \"select\") &&\n                (name != null && name != \"\")) && !element.disabled) {\n\n                // routine for select elements\n                // rules:\n                // - if select-one and value-Attribute exist => \"name=value\"\n                // (also if value empty => \"name=\")\n                // - if select-one and value-Attribute don't exist =>\n                // \"name=DisplayValue\"\n                // - if select multi and multple selected => \"name=value1&name=value2\"\n                // - if select and selectedIndex=-1 don't submit\n                if (tagName == \"select\") {\n                    // selectedIndex must be >= 0 sein to be submittet\n                    let selectElem: HTMLSelectElement = <HTMLSelectElement>element.getAsElem(0).value;\n                    if (selectElem.selectedIndex >= 0) {\n                        let uLen = selectElem.options.length;\n                        for (let u = 0; u < uLen; u++) {\n                            // find all selected options\n                            //let subBuf = [];\n                            if (selectElem.options[u].selected) {\n                                let elementOption = selectElem.options[u];\n                                target.assign(name).value = (elementOption.getAttribute(\"value\") != null) ?\n                                    elementOption.value : elementOption.text;\n                            }\n                        }\n                    }\n                }\n\n                // routine for remaining elements\n                // rules:\n                // - don't submit no selects (processed above), buttons, reset buttons, submit buttons,\n                // - submit checkboxes and radio inputs only if checked\n                if ((tagName != \"select\" && elemType != \"button\"\n                    && elemType != \"reset\" && elemType != \"submit\" && elemType != \"image\")\n                    && ((elemType != \"checkbox\" && elemType != \"radio\") || element.checked)) {\n                    let files: any = (<any>element.value).files;\n                    if (files && files.length) {\n                        //xhr level2\n                        target.assign(name).value = files[0];\n                    } else {\n                        target.assign(name).value = element.inputValue.value;\n                    }\n                }\n\n            }\n        });\n\n        return target;\n\n    }\n\n    get cDATAAsString(): string {\n        let cDataBlock = [];\n        let TYPE_CDATA_BLOCK = 4;\n        // response may contain several blocks\n        return this.stream\n            .flatMap(item => item.childNodes.stream).reduce((reduced: Array<any>, item: DomQuery) => {\n                if (item?.value?.value?.nodeType == TYPE_CDATA_BLOCK) {\n                    reduced.push((<any>item?.value?.value)?.data ?? \"\");\n                }\n                return reduced;\n            }, []).value.join(\"\");\n    }\n\n    subNodes(from: number, to?: number): DomQuery {\n        if (Optional.fromNullable(to).isAbsent()) {\n            to = this.length;\n        }\n        return new DomQuery(...this.rootNode.slice(from, Math.min(to, this.length)));\n    }\n\n    _limits = -1;\n\n    limits(end: number): IStream<DomQuery> {\n        this._limits = end;\n        return <any>this;\n    }\n\n    //-- internally exposed methods needed for the interconnectivity\n    hasNext() {\n        let isLimitsReached = this._limits != -1 && this.pos >= this._limits - 1;\n        let isEndOfArray = this.pos >= this.values.length - 1;\n        return !(isLimitsReached ||\n            isEndOfArray);\n    }\n\n    next(): DomQuery {\n        if (!this.hasNext()) {\n            return null;\n        }\n        this.pos++;\n        return new DomQuery(this.values[this.pos]);\n    }\n\n    reset() {\n        this.pos = -1;\n    }\n\n    //from\n    // http://blog.vishalon.net/index.php/javascript-getting-and-setting-caret-position-in-textarea/\n    static getCaretPosition(ctrl: any) {\n        let caretPos = 0;\n\n        try {\n            if ((<any>document)?.selection) {\n                ctrl.focus();\n                let selection = (<any>document).selection.createRange();\n                //the selection now is start zero\n                selection.moveStart('character', -ctrl.value.length);\n                //the caretposition is the selection start\n                caretPos = selection.text.length;\n            }\n        } catch (e) {\n            //now this is ugly, but not supported input types throw errors for selectionStart\n            //just in case someone dumps this code onto unsupported browsers\n        }\n        return caretPos;\n    }\n\n    static setCaretPosition(ctrl: any, pos: number) {\n        ctrl.focus();\n        //the selection range is our caret position\n        ctrl.setSelectionRange(pos, pos);\n    }\n}\n\n/**\n * Various collectors\n * which can be used in conjunction with Streams\n */\n\n/**\n * A collector which bundles a full dom query stream into a single dom query element\n *\n * This connects basically our stream back into DomQuery\n */\nexport class DomQueryCollector implements ICollector<DomQuery, DomQuery> {\n\n    data: DomQuery[] = [];\n\n    collect(element: DomQuery) {\n        this.data.push(element);\n    }\n\n    get finalValue(): DomQuery {\n        return new DomQuery(...this.data);\n    }\n}\n\n/**\n * abbreviation for DomQuery\n */\nexport const DQ = DomQuery;\nexport type DQ = DomQuery;\n","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * A small stream implementation\n */\nimport {IMonad, IValueHolder, Optional} from \"./Monad\";\nimport {\n    ArrayCollector,\n    ArrayStreamDataSource,\n    FilteredStreamDatasource, FlatMapStreamDataSource,\n    ICollector,\n    IStreamDataSource,\n    MappedStreamDataSource\n} from \"./SourcesCollectors\";\n\n/*\n * some typedefs to make the code more reabable\n */\nexport type StreamMapper<T> = (data: T) => IStreamDataSource<any>;\nexport type ArrayMapper<T> = (data: T) => Array<any>;\nexport type IteratableConsumer<T> = (data: T, pos ?: number) => void | boolean;\nexport type Reducable<T> = (val1: T, val2: T) => T;\nexport type Matchable<T> = (data: T) => boolean;\nexport type Mappable<T, R> = (data: T) => R;\nexport type Comparator<T> = (el1: T, el2: T) => number;\n\n/**\n * Generic interface defining a stream\n */\nexport interface IStream<T> {\n    /**\n     * Perform the operation fn on a single element in the stream at a time\n     * then pass the stream over for further processing\n     * This is basically an intermediate point in the stream\n     * with further processing happening later, do not use\n     * this method to gather data or iterate over all date for processing\n     * (for the second case each has to be used)\n     *\n     * @param fn the processing function, if it returns false, further processing is stopped\n     */\n    onElem(fn: IteratableConsumer<T>): IStream<T>;\n\n    /**\n     * Iterate over all elements in the stream and do some processing via fn\n     *\n     * @param fn takes a single element and if it returns false\n     * then further processing is stopped\n     */\n    each(fn: IteratableConsumer<T>): void;\n\n    /**\n     * maps a single element into another via fn\n     * @param fn function which takes one element in and returns another\n     */\n    map<R>(fn?: Mappable<T, R>): IStream<R>;\n\n    /**\n     * Takes an element in and returns a set of something\n     * the set then is flatted into a single stream to be further processed\n     *\n     * @param fn\n     */\n    flatMap<R>(fn?: StreamMapper<T> | ArrayMapper<T>): IStream<R>;\n\n    /**\n     * filtering, takes an element in and is processed by fn.\n     * If it returns false then further processing on this element is skipped\n     * if it returns true it is passed down the chain.\n     *\n     * @param fn\n     */\n    filter(fn?: Matchable<T>): IStream<T>;\n\n    /**\n     * functional reduce... takes two elements in the stream and reduces to\n     * one from left to right\n     *\n     * @param fn the reduction function for instance (val1,val2) => val1l+val2\n     * @param startVal an optional starting value, if provided the the processing starts with this element\n     * and further goes down into the stream, if not, then the first two elements are taken as reduction starting point\n     */\n    reduce(fn: Reducable<T>, startVal: T): Optional<T>;\n\n    /**\n     * returns the first element in the stream is given as Optional\n     */\n    first(): Optional<T>;\n\n    /**\n     * Returns the last stream element (note in endless streams without filtering and limiting you will never reach that\n     * point hence producing an endless loop)\n     */\n    last(): Optional<T>;\n\n    /**\n     * returns true if there is at least one element where a call fn(element) produces true\n     *\n     * @param fn\n     */\n    anyMatch(fn: Matchable<T>): boolean;\n\n    /**\n     * returns true if all elmements produce true on a call to fn(element)\n     *\n     * @param fn\n     */\n    allMatch(fn: Matchable<T>): boolean;\n\n    /**\n     * returns true if no elmements produce true on a call to fn(element)\n     *\n     * @param fn\n     */\n    noneMatch(fn: Matchable<T>): boolean;\n\n    /**\n     * Collect the elements with a collector given\n     * There are a number of collectors provided\n     *\n     * @param collector\n     */\n    collect(collector: ICollector<T, any>): any;\n\n    /**\n     * sort on the stream, this is a special case\n     * of an endpoint, so your data which is fed in needs\n     * to be limited otherwise it will fail\n     * it still returns a stream for further processing\n     *\n     * @param comparator\n     */\n    sort(comparator: Comparator<T>): IStream<T>;\n\n    /**\n     * Limits the stream to a certain number of elements\n     *\n     * @param end the limit of the stream\n     */\n    limits(end: number): IStream<T>;\n\n    /**\n     * returns the stream collected into an array (90% use-case abbreviation\n     */\n    value: Array<T>;\n}\n\n/**\n * A simple typescript based reimplementation of streams\n *\n * This is the early eval version\n * for a lazy eval version check, LazyStream, which is api compatible\n * to this implementation, however with the benefit of being able\n * to provide infinite data sources and generic data providers, the downside\n * is, it might be a tad slower in some situations\n */\nexport class Stream<T> implements IMonad<T, Stream<any>>, IValueHolder<Array<T>>, IStream<T> {\n\n    value: Array<T>;\n    _limits = -1;\n\n    private pos = -1;\n\n    constructor(...value: T[]) {\n        this.value = value;\n    }\n\n    static of<T>(...data: Array<T>): Stream<T> {\n        return new Stream<T>(...data);\n    }\n\n    static ofAssoc<T>(data: {[key: string]: T}): Stream<[string, T]> {\n        return this.of(...Object.keys(data)).map(key => [key, data[key]]);\n    }\n\n    static ofDataSource<T>(dataSource: IStreamDataSource<T>) {\n        let value: T[] = [];\n        while (dataSource.hasNext()) {\n            value.push(dataSource.next());\n        }\n\n        return new Stream(...value);\n    }\n\n    limits(end: number): Stream<T> {\n        this._limits = end;\n        return this;\n    }\n\n    onElem(fn: (data: T, pos ?: number) => void | boolean): Stream<T> {\n        for (let cnt = 0; cnt < this.value.length && (this._limits == -1 || cnt < this._limits); cnt++) {\n            if (fn(this.value[cnt], cnt) === false) {\n                break;\n            }\n        }\n        return this;\n    }\n\n    each(fn: (data: T, pos ?: number) => void | boolean) {\n        this.onElem(fn);\n    }\n\n    map<R>(fn?: (data: T) => R): Stream<R> {\n        if (!fn) {\n            fn = (inval: any) => <R>inval;\n        }\n        let res: R[] = [];\n        this.each((item, cnt) => {\n            res.push(fn(item))\n        });\n\n        return new Stream<R>(...res);\n    }\n\n    /*\n     * we need to implement it to fullfill the contract, although it is used only internally\n     * all values are flattened when accessed anyway, so there is no need to call this methiod\n     */\n\n    flatMap<IStreamDataSource>(fn: (data: T) => IStreamDataSource | Array<any>): Stream<any> {\n        let ret = [];\n        this.each(item => {\n            let strmR: any = fn(item);\n            ret = Array.isArray(strmR) ? ret.concat(strmR) : ret.concat(...strmR.value);\n        });\n        return <Stream<any>>Stream.of(...ret);\n    }\n\n    filter(fn?: (data: T) => boolean): Stream<T> {\n        let res: Array<T> = [];\n        this.each((data) => {\n            if (fn(data)) {\n                res.push(data);\n            }\n        });\n        return new Stream<T>(...res);\n    }\n\n    reduce(fn: Reducable<T>, startVal: T = null): Optional<T> {\n        let offset = startVal != null ? 0 : 1;\n        let val1 = startVal != null ? startVal : this.value.length ? this.value[0] : null;\n\n        for (let cnt = offset; cnt < this.value.length && (this._limits == -1 || cnt < this._limits); cnt++) {\n            val1 = fn(val1, this.value[cnt]);\n        }\n        return Optional.fromNullable(val1);\n    }\n\n    first(): Optional<T> {\n        return this.value && this.value.length ? Optional.fromNullable(this.value[0]) : Optional.absent;\n    }\n\n    last(): Optional<T> {\n        //could be done via reduce, but is faster this way\n        let length = this._limits > 0 ? Math.min(this._limits, this.value.length) : this.value.length;\n\n        return Optional.fromNullable(length ? this.value[length - 1] : null);\n    }\n\n    anyMatch(fn: Matchable<T>): boolean {\n        for (let cnt = 0; cnt < this.value.length && (this._limits == -1 || cnt < this._limits); cnt++) {\n            if (fn(this.value[cnt])) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    allMatch(fn: Matchable<T>): boolean {\n        if (!this.value.length) {\n            return false;\n        }\n        let matches = 0;\n        for (let cnt = 0; cnt < this.value.length; cnt++) {\n            if (fn(this.value[cnt])) {\n                matches++;\n            }\n        }\n        return matches == this.value.length;\n    }\n\n    noneMatch(fn: Matchable<T>): boolean {\n        let matches = 0;\n        for (let cnt = 0; cnt < this.value.length; cnt++) {\n            if (!fn(this.value[cnt])) {\n                matches++;\n            }\n        }\n        return matches == this.value.length;\n    }\n\n    sort(comparator: Comparator<T>): IStream<T> {\n        let newArr = this.value.slice().sort(comparator);\n        return Stream.of(...newArr);\n    }\n\n\n    collect(collector: ICollector<T, any>): any {\n        this.each(data => collector.collect(data));\n        return collector.finalValue;\n    }\n\n    //-- internally exposed methods needed for the interconnectivity\n    hasNext() {\n        let isLimitsReached = this._limits != -1 && this.pos >= this._limits - 1;\n        let isEndOfArray = this.pos >= this.value.length - 1;\n        return !(isLimitsReached || isEndOfArray);\n    }\n\n    next(): T {\n        if (!this.hasNext()) {\n            return null;\n        }\n        this.pos++;\n        return this.value[this.pos];\n    }\n\n    reset() {\n        this.pos = -1;\n    }\n\n}\n\n/**\n * Lazy implementation of a Stream\n * The idea is to connect the intermediate\n * streams as datasources like a linked list\n * with reverse referencing and for special\n * operations like filtering flatmapping\n * have intermediate datasources in the list\n * with specialized functions.\n *\n * Sort of a modified pipe valve pattern\n * the streams are the pipes the intermediate\n * data sources are the valves\n *\n * We then can use passed in functions to control\n * the flow in the valves\n *\n * That way we can have a lazy evaluating stream\n *\n * So if an endpoint requests data\n * a callback trace goes back the stream list\n * which triggers an operation upwards\n * which sends data down the drain which then is processed\n * and filtered until one element hits the endpoint.\n *\n * That is repeated, until all elements are processed\n * or an internal limit is hit.\n *\n */\nexport class LazyStream<T> implements IStreamDataSource<T>, IStream<T>, IMonad<T, LazyStream<any>> {\n\n    protected dataSource: IStreamDataSource<T>;\n    _limits = -1;\n\n    /*\n     * needed to have the limits check working\n     * we need to keep track of the current position\n     * in the stream\n     */\n    pos = -1;\n\n    static of<T>(...values: Array<T>): LazyStream<T> {\n        return new LazyStream<T>(new ArrayStreamDataSource(...values));\n    }\n\n    static ofAssoc<T>(data: {[key: string]: T}): LazyStream<[string, T]> {\n        return this.of(...Object.keys(data)).map(key => [key, data[key]]);\n    }\n\n    static ofStreamDataSource<T>(value: IStreamDataSource<T>): LazyStream<T> {\n        return new LazyStream(value);\n    }\n\n    constructor(parent: IStreamDataSource<T>) {\n        this.dataSource = parent;\n\n    }\n\n    hasNext(): boolean {\n        if (this.isOverLimits()) {\n            return false;\n        }\n\n        return this.dataSource.hasNext();\n    }\n\n    next(): T {\n        let next = this.dataSource.next();\n        // @ts-ignore\n        this.pos++;\n        return next;\n    }\n\n    reset(): void {\n        this.dataSource.reset();\n        this.pos = 0;\n        this._limits = -1;\n    }\n\n    nextFilter(fn: Matchable<T>): T {\n        if (this.hasNext()) {\n            let newVal: T = this.next();\n            if (!fn(newVal)) {\n                return this.nextFilter(fn);\n            }\n            return <T>newVal;\n        }\n        return null;\n    }\n\n    limits(max: number): LazyStream<T> {\n        this._limits = max;\n        return this;\n    }\n\n    //main stream methods\n    collect(collector: ICollector<T, any>): any {\n        while (this.hasNext()) {\n            let t = this.next();\n            collector.collect(<T>t);\n        }\n        return collector.finalValue;\n    }\n\n    onElem(fn: IteratableConsumer<T>): LazyStream<T> {\n        return new LazyStream(new MappedStreamDataSource((el) => {\n            if (fn(el, this.pos) === false) {\n                this.stop();\n            }\n            return el;\n        }, this));\n    }\n\n    filter(fn: Matchable<T>): LazyStream<T> {\n        return <LazyStream<T>>new LazyStream<T>(new FilteredStreamDatasource<any>(fn, this));\n    }\n\n    map<R>(fn: Mappable<T, R>): LazyStream<any> {\n        return new LazyStream(new MappedStreamDataSource(fn, this));\n    }\n\n    flatMap<StreamMapper>(fn: StreamMapper | ArrayMapper<any>): LazyStream<any> {\n\n        return new LazyStream<any>(new FlatMapStreamDataSource(<any>fn, this));\n    }\n\n    //endpoint\n    each(fn: IteratableConsumer<T>) {\n        while (this.hasNext()) {\n            if (fn(this.next()) === false) {\n                this.stop();\n            }\n        }\n    }\n\n    reduce(fn: Reducable<T>, startVal: T = null): Optional<T> {\n        if (!this.hasNext()) {\n            return Optional.absent;\n        }\n        let value1 = null;\n        let value2 = null;\n        if (startVal != null) {\n            value1 = startVal;\n            value2 = this.next();\n        } else {\n            value1 = this.next();\n            if (!this.hasNext()) {\n                return Optional.fromNullable(value1);\n            }\n            value2 = this.next();\n        }\n        value1 = fn(value1, value2);\n        while (this.hasNext()) {\n            value2 = this.next();\n            value1 = fn(value1, value2);\n        }\n\n        return Optional.fromNullable(value1);\n    }\n\n    last(): Optional<T> {\n        if (!this.hasNext()) {\n            return Optional.absent;\n        }\n        return this.reduce((el1, el2) => el2);\n    }\n\n    first(): Optional<T> {\n        this.reset();\n        if (!this.hasNext()) {\n            return Optional.absent;\n        }\n        return Optional.fromNullable(this.next());\n    }\n\n    anyMatch(fn: Matchable<T>): boolean {\n        while (this.hasNext()) {\n            if (fn(this.next())) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    allMatch(fn: Matchable<T>): boolean {\n        while (this.hasNext()) {\n            if (!fn(this.next())) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    noneMatch(fn: Matchable<T>): boolean {\n        while (this.hasNext()) {\n            if (fn(this.next())) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    sort(comparator: Comparator<T>): IStream<T> {\n        let arr = this.collect(new ArrayCollector());\n        arr = arr.sort(comparator);\n        return LazyStream.of(...arr);\n    }\n\n    get value(): Array<T> {\n        return this.collect(new ArrayCollector<T>());\n    }\n\n    private stop() {\n        this.pos = this._limits + 1000000000;\n    }\n\n    private isOverLimits() {\n        return this._limits != -1 && this.pos >= this._limits - 1;\n    }\n\n}\n\n\n","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as myfacesConfig from \"../api/Myfaces\";\n\nimport {IListener} from \"./util/ListenerQueue\";\nimport {Response} from \"./xhrCore/Response\";\nimport {XhrRequest} from \"./xhrCore/XhrRequest\";\nimport {AsynchronouseQueue} from \"./util/AsyncQueue\";\nimport {AssocArrayCollector, Config, DQ, Lang, Optional, Stream} from \"../ext/monadish\";\nimport {Assertions} from \"./util/Assertions\";\nimport {XhrFormData} from \"./xhrCore/XhrFormData\";\nimport {ExtDomquery} from \"./util/ExtDomQuery\";\nimport {ErrorData} from \"./xhrCore/ErrorData\";\nimport {EventData} from \"./xhrCore/EventData\";\nimport {ExtLang} from \"./util/Lang\";\nimport {\n    CTX_PARAM_EXECUTE,\n    CTX_PARAM_PASS_THR,\n    CTX_PARAM_SRC_CTL_ID,\n    CTX_PARAM_SRC_FRM_ID,\n    CTX_PARAM_TR_TYPE,\n    IDENT_ALL,\n    IDENT_FORM,\n    IDENT_NONE,\n    IDENT_THIS,\n    MYFACES,\n    ON_ERROR,\n    ON_EVENT,\n    P_AJAX,\n    P_CLIENT_WINDOW,\n    P_EVT,\n    P_EXECUTE,\n    P_PARTIAL_SOURCE,\n    P_RENDER,\n    P_RESET_VALUES,\n    P_WINDOW_ID,\n    RENDER,\n    REQ_TYPE_POST,\n    SOURCE,\n    TAG_FORM\n} from \"./core/Const\";\nimport {\n    resolveDefaults,\n    resolveDelay,\n    resolveForm,\n    resolveTimeout\n} from \"./xhrCore/RequestDataResolver\";\n\ndeclare var jsf: any;\n\n/*\n * allowed project stages\n */\nenum ProjectStages {\n    Production = \"Production\",\n    Development = \"Development\",\n    SystemTest = \"SystemTest\",\n    UnitTest = \"UnitTest\"\n}\n\n/*\n *   blockfilter for the passthrough filtering; the attributes given here\n *   will not be transmitted from the options into the passthrough\n */\nenum BlockFilter {\n    onerror = \"onerror\",\n    onevent = \"onevent\",\n    render = \"render\",\n    execute = \"execute\",\n    myfaces = \"myfaces\",\n    delay = \"delay\",\n    timeout = \"timeout\",\n    windowId = \"windowId\"\n}\n\n/**\n * Core Implementation\n * to distinct between api and impl\n *\n * The original idea was to make the implementation pluggable\n * but this is pointless, you always can overwrite the thin api layer\n * however a dedicated api makes sense for readability reasons\n */\nexport module Implementation {\n\n    import trim = Lang.trim;\n    import getMessage = ExtLang.getMessage;\n    import getGlobalConfig = ExtLang.getGlobalConfig;\n    import assert = Assertions.assert;\n\n    let globalConfig = myfacesConfig.myfaces.config;\n\n    let projectStage: string = null;\n    let separator: string = null;\n    let eventQueue = [];\n    let errorQueue = [];\n    export let requestQueue: AsynchronouseQueue<XhrRequest> = null;\n    /*error reporting threshold*/\n    let threshold = \"ERROR\";\n\n    /**\n     * fetches the separator char from the given script tags\n     *\n     * @return {char} the separator char for the given script tags\n     */\n    export function getSeparatorChar(): string {\n        return this?.globalConfig?.separator ??\n            this?.separator ??\n            (separator = ExtDomquery.searchJsfJsFor(/separator=([^&;]*)/).orElse(\":\").value);\n    }\n\n    /**\n     * this is for testing purposes only, since AjaxImpl is a module\n     * we need to reset for every unit test its internal states\n     */\n    export function reset() {\n        globalConfig = myfacesConfig.myfaces.config;\n\n        projectStage = null;\n        separator = null;\n        eventQueue = [];\n        errorQueue = [];\n        requestQueue = null;\n    }\n\n    /**\n     * @return the project stage also emitted by the server:\n     * it cannot be cached and must be delivered over the server\n     * The value for it comes from the requestInternal parameter of the jsf.js script called \"stage\".\n     */\n    export function getProjectStage(): string | null {\n        return this?.globalConfig?.projectStage ??\n            this?.projectStage ??\n            (projectStage = resolveProjectStateFromURL());\n    }\n\n    /**\n     * resolves the project stage as url parameter\n     * @return the project stage or null\n     */\n    export function resolveProjectStateFromURL(): string | null {\n\n        /* run through all script tags and try to find the one that includes jsf.js */\n        let foundStage = <string>ExtDomquery.searchJsfJsFor(/stage=([^&;]*)/).value;\n        return (foundStage in ProjectStages) ? foundStage : null;\n    }\n\n    /**\n     * implementation of the jsf.util.chain functionality\n     *\n     * @param source\n     * @param event\n     * @param funcs\n     */\n    export function chain(source: any, event: Event, ...funcs: EvalFuncs): boolean {\n\n        let ret = true;\n        let resolveAndExecute = function (func: Function | string) {\n            if (\"string\" != typeof func) {\n                //function is passed down as chain parameter, can be executed as is\n                return (ret = ret && ((<Function>func).call(source, event) !== false));\n            } else {\n                //either a function or a string can be passed in case of a string we have to wrap it into another function\n                //it it is not a plain executable code but a definition\n                let sourceCode = trim(<string>func);\n                if (sourceCode.indexOf(\"function \") == 0) {\n                    sourceCode = `return ${sourceCode} (event)`;\n                }\n                return (ret = ret && (new Function(\"event\", sourceCode).call(source, event) !== false));\n            }\n        };\n\n        //we can use our stream each functionality to run our chain here..\n        //the no return value == false stop stream functionality is handled by our resolveAndExecute\n        <any>Stream.of(...funcs).each(func => resolveAndExecute(func));\n        return ret;\n    }\n\n    /**\n     * this function has to send the ajax requests\n     *\n     * following request conditions must be met:\n     * <ul>\n     *  <li> the request must be sent asynchronously! </li>\n     *  <li> the request must be a POST!!! request </li>\n     *  <li> the request url must be the form action attribute </li>\n     *  <li> all requests must be queued with a client side request queue to ensure the request ordering!</li>\n     * </ul>\n     *\n     * @param el any dom element no matter being it html or jsf, from which the event is emitted\n     * @param event any javascript event supported by that object\n     * @param opts  map of options being pushed into the ajax cycle\n     *\n     * a) transformArguments out of the function\n     * b) passThrough handling with a map copy with a filter map block map\n     */\n    export function request(el: ElemDef, event?: Event, opts ?: Options) {\n\n        const {\n            resolvedEvent,\n            options,\n            elem,\n            elementId,\n            requestCtx,\n            internalCtx,\n            windowId,\n            isResetValues\n        } = resolveDefaults(event, opts, el);\n\n        Assertions.assertRequestIntegrity(options, elem);\n\n        requestCtx.assignIf(!!windowId, P_WINDOW_ID).value = windowId;\n\n        requestCtx.assign(CTX_PARAM_PASS_THR).value = filterPassthroughValues(options.value);\n\n        requestCtx.assignIf(!!resolvedEvent, CTX_PARAM_PASS_THR, P_EVT).value = resolvedEvent?.type;\n\n        /**\n         * ajax pass through context with the source\n         * onresolvedEvent and onerror\n         */\n        requestCtx.assign(SOURCE).value = elementId.value;\n\n        /**\n         * on resolvedEvent and onError...\n         * those values will be traversed later on\n         * also into the response context\n         */\n        requestCtx.assign(ON_EVENT).value = options.value?.onevent;\n        requestCtx.assign(ON_ERROR).value = options.value?.onerror;\n\n        /**\n         * lets drag the myfaces config params also in\n         */\n        requestCtx.assign(MYFACES).value = options.value?.myfaces;\n        /**\n         * fetch the parent form\n         *\n         * note we also add an override possibility here\n         * so that people can use dummy forms and work\n         * with detached objects\n         */\n        let form: DQ = resolveForm(requestCtx, elem, resolvedEvent);\n\n        /**\n         * binding contract the javax.faces.source must be set\n         */\n        requestCtx.assign(CTX_PARAM_PASS_THR, P_PARTIAL_SOURCE).value = elementId.value;\n\n        /**\n         * javax.faces.partial.ajax must be set to true\n         */\n        requestCtx.assign(CTX_PARAM_PASS_THR, P_AJAX).value = true;\n\n        /**\n         * binding contract the javax.faces.source must be set\n         */\n        requestCtx.assign(CTX_PARAM_PASS_THR, P_PARTIAL_SOURCE).value = elementId.value;\n\n        /**\n         * if resetValues is set to true\n         * then we have to set javax.faces.resetValues as well\n         * as pass through parameter\n         * the value has to be explicitly true, according to\n         * the specs jsdoc\n         */\n        requestCtx.assignIf(isResetValues, CTX_PARAM_PASS_THR, P_RESET_VALUES).value = true;\n\n        //additional meta information to speed things up, note internal non jsf\n        //pass through options are stored under _mfInternal in the context\n        internalCtx.assign(CTX_PARAM_SRC_FRM_ID).value = form.id.value;\n        internalCtx.assign(CTX_PARAM_SRC_CTL_ID).value = elementId.value;\n        internalCtx.assign(CTX_PARAM_TR_TYPE).value = REQ_TYPE_POST;\n\n        //mojarra compatibility, mojarra is sending the form id as well\n        //this is not documented behavior but can be determined by running\n        //mojarra under blackbox conditions\n        //i assume it does the same as our formId_submit=1 so leaving it out\n        //wont hurt but for the sake of compatibility we are going to add it\n\n        requestCtx.assign(CTX_PARAM_PASS_THR, form.id.value).value = form.id.value;\n\n        assignClientWindowId(form, requestCtx);\n\n        assignExecute(options, requestCtx, form, elementId.value);\n        assignRender(options, requestCtx, form, elementId.value);\n\n        let delay: number = resolveDelay(options);\n        let timeout: number = resolveTimeout(options);\n\n        //now we enqueue the request as asynchronous runnable into our request\n        //queue and let the queue take over the rest\n        queueHandler.addRequestToQueue(elem, form, requestCtx, internalCtx, delay, timeout);\n    }\n\n    /**\n     * Spec. 13.3.3\n     * Examining the response markup and updating the DOM tree\n     * @param {XMLHttpRequest} request - the ajax request\n     * @param {Object} context - the ajax context\n     */\n    export function response(request: XMLHttpRequest, context: Context) {\n        Response.processResponse(request, context);\n    }\n\n    /**\n     * adds an error handler to the error queue\n     *\n     * @param errorListener the error listener handler\n     */\n    export function addOnError(errorListener: IListener<ErrorData>) {\n        /*error handling already done in the assert of the queue*/\n        errorQueue.push(errorListener);\n    }\n\n    /**\n     * adds an event handler to the event queue\n     *\n     * @param eventListener the event listener handler\n     */\n    export function addOnEvent(eventListener: IListener<EventData>) {\n        /*error handling already done in the assert of the queue*/\n        eventQueue.push(eventListener);\n    }\n\n    // noinspection JSUnusedLocalSymbols\n    /**\n     * sends an event to the event handlers\n     *\n     * @param data the event data object hosting the event data according to the spec @see EventData for what is reachable\n     * @param localHandler an optional event handler, which is processed before the event handler chain\n     */\n    export function sendEvent(data: EventData, localHandler = function (data: EventData) {\n    }) {\n        /*now we serve the queue as well*/\n        localHandler(data);\n        eventQueue.forEach(fn => fn(data));\n    }\n\n    /**\n     * error handler behavior called internally\n     * and only into the impl it takes care of the\n     * internal message transformation to a myfaces internal error\n     * and then uses the standard send error mechanisms\n     * also a double error logging prevention is done as well\n     *\n     * @param request the request currently being processed\n     * @param context the context affected by this error\n     * @param exception the exception being thrown\n     * @param clearRequestQueue if set to true, clears the request queue of all pending requests\n     */\n    export function stdErrorHandler(request: XMLHttpRequest,\n                                    context: Config,\n                                    exception: any,\n                                    clearRequestQueue = false) {\n        //newer browsers do not allow to hold additional values on native objects like exceptions\n        //we hence capsule it into the request, which is gced automatically\n        //on ie as well, since the stdErrorHandler usually is called between requests\n        //this is a valid approach\n        try {\n            if (threshold == \"ERROR\") {\n                let errorData = ErrorData.fromClient(exception);\n                sendError(errorData);\n            }\n        } finally {\n            if (clearRequestQueue) {\n                requestQueue.cleanup();\n            }\n        }\n    }\n\n    // noinspection JSUnusedLocalSymbols\n    /**\n     * implementation triggering the error chain\n     *\n     *\n     *\n     *  handles the errors, in case of an onError exists within the context the onError is called as local error handler\n     *  the registered error handlers in the queue receiv an error message to be dealt with\n     *  and if the projectStage is at development an alert box is displayed\n     *\n     *  note: we have additional functionality here, via the global config myfaces.config.defaultErrorOutput a function can be provided\n     *  which changes the default output behavior from alert to something else\n     *\n     * @param errorData the error data to be displayed\n     * @param localHandler an optional local error handler which has to be processed before the error handler queue\n     */\n    export function sendError(errorData: ErrorData, localHandler = function (data: any) {\n    }) {\n\n        localHandler(errorData);\n        errorQueue.forEach((errorCallback: Function) => {\n            errorCallback(errorData);\n        });\n        let displayError: (string) => void = getGlobalConfig(\"defaultErrorOutput\", (console ? console.error : alert));\n        displayError(errorData);\n    }\n\n    /**\n     * @node optional element or id defining a rootnode where an element with the id \"javax.faces.windowId\" is hosted\n     * @return the client window id of the current window, if one is given if none is found, null is returned\n     */\n    export function getClientWindow(node ?: Element | string): string | null {\n        const ALTERED = \"___mf_id_altered__\";\n        const INIT = \"___init____\";\n\n        /**\n         * the search root for the dom element search\n         */\n        let searchRoot = new DQ(node || document.body);\n\n        /**\n         * lazy helper to fetch the window id from the window url\n         */\n        let fetchWindowIdFromUrl = () => ExtDomquery.searchJsfJsFor(/jfwid=([^&;]*)/).orElse(null).value;\n\n        /**\n         * functional double check based on stream reduction\n         * the values should be identical or on INIT value which is a premise to\n         * skip the first check\n         *\n         * @param value1\n         * @param value2\n         */\n        let doubleCheck = (value1: string, value2: string) => {\n            if (value1 == ALTERED) {\n                return value1;\n            } else if (value1 == INIT) {\n                return value2;\n            } else if (value1 != value2) {\n                return ALTERED;\n            }\n            return value2;\n        };\n\n        /**\n         * helper for cleaner code, maps the value from an item\n         *\n         * @param item\n         */\n        let getValue = (item: DQ) => item.attr(\"value\").value;\n        /**\n         * fetch the window id from the forms\n         * window ids must be present in all forms\n         * or non existent. If they exist all of them must be the same\n         */\n        let formWindowId: Optional<string> = searchRoot.stream.map<string>(getValue).reduce(doubleCheck, INIT);\n\n        //if the resulting window id is set on altered then we have an unresolvable problem\n        assert(formWindowId.value != ALTERED, \"Multiple different windowIds found in document\");\n\n        /**\n         * return the window id or null\n         * prio, forms under node/document and if not given then from the url\n         */\n        return formWindowId.value ?? fetchWindowIdFromUrl();\n    }\n\n    /**\n     * collect and encode data for a given form element (must be of type form)\n     * find the javax.faces.ViewState element and encode its value as well!\n     * @return a concatenated string of the encoded values!\n     *\n     * @throws Error in case of the given element not being of type form!\n     * https://issues.apache.org/jira/browse/MYFACES-2110\n     */\n    export function getViewState(form: Element | string): string {\n        /**\n         *  typecheck assert!, we opt for strong typing here\n         *  because it makes it easier to detect bugs\n         */\n\n        let element: DQ = DQ.byId(form);\n        if (!element.isTag(TAG_FORM)) {\n            throw new Error(getMessage(\"ERR_VIEWSTATE\"));\n        }\n\n        let formData = new XhrFormData(element);\n        return formData.toString();\n    }\n\n    /**\n     * this at the first sight looks like a weird construct, but we need to do it this way\n     * for testing, we cannot proxy addRequestToQueue from the testing frameworks directly\n     * but we need to keep it under unit tests.\n     */\n    export let queueHandler = {\n        /**\n         * public to make it shimmable for tests\n         *\n         * adds a new request to our queue for further processing\n         */\n        addRequestToQueue: function (elem: DQ, form: DQ, reqCtx: Config, respPassThr: Config, delay = 0, timeout = 0) {\n            requestQueue = requestQueue ?? new AsynchronouseQueue<XhrRequest>();\n            requestQueue.enqueue(new XhrRequest(elem, form, reqCtx, respPassThr, [], timeout), delay);\n        }\n    };\n\n    //----------------------------------------------- Methods ---------------------------------------------------------------------\n\n    /**\n     * the idea is to replace some placeholder parameters with their respective values\n     * placeholder params like  @all, @none, @form, @this need to be replaced by\n     * the values defined by the specification\n     *\n     * This function does it for the render parameters\n     *\n     * @param requestOptions the source options coming in as options object from jsf.ajax.request (options parameter)\n     * @param targetContext the receiving target context\n     * @param issuingForm the issuing form\n     * @param sourceElementId the executing element triggering the jsf.ajax.request (id of it)\n     */\n    function assignRender(requestOptions: Config, targetContext: Config, issuingForm: DQ, sourceElementId: string) {\n        if (requestOptions.getIf(RENDER).isPresent()) {\n            remapDefaultConstants(targetContext.getIf(CTX_PARAM_PASS_THR).get({}), P_RENDER, <string>requestOptions.getIf(RENDER).value, issuingForm, <any>sourceElementId);\n        }\n    }\n\n    /**\n     * the idea is to replace some placeholder parameters with their respective values\n     * placeholder params like  @all, @none, @form, @this need to be replaced by\n     * the values defined by the specification\n     *\n     * This function does it for the execute parameters\n     *\n     * @param requestOptions the source options coming in as options object from jsf.ajax.request (options parameter)\n     * @param targetContext the receiving target context\n     * @param issuingForm the issuing form\n     * @param sourceElementId the executing element triggering the jsf.ajax.request (id of it)\n     */\n    function assignExecute(requestOptions: Config, targetContext: Config, issuingForm: DQ, sourceElementId: string) {\n\n        if (requestOptions.getIf(CTX_PARAM_EXECUTE).isPresent()) {\n            /*the options must be a blank delimited list of strings*/\n            /*compliance with Mojarra which automatically adds @this to an execute\n             * the spec rev 2.0a however states, if none is issued nothing at all should be sent down\n             */\n            requestOptions.assign(CTX_PARAM_EXECUTE).value = [requestOptions.getIf(CTX_PARAM_EXECUTE).value, IDENT_THIS].join(\" \");\n            remapDefaultConstants(targetContext.getIf(CTX_PARAM_PASS_THR).get({}), P_EXECUTE, <string>requestOptions.getIf(CTX_PARAM_EXECUTE).value, issuingForm, <any>sourceElementId);\n        } else {\n            targetContext.assign(CTX_PARAM_PASS_THR, P_EXECUTE).value = sourceElementId;\n        }\n    }\n\n    /**\n     * apply the browser tab where the request was originating from\n     *\n     * @param form the form hosting the client window id\n     * @param targetContext the target context receiving the value\n     */\n    function assignClientWindowId(form: DQ, targetContext: Config) {\n        let clientWindow = jsf.getClientWindow(form.getAsElem(0).value);\n        if (clientWindow) {\n            targetContext.assign(CTX_PARAM_PASS_THR, P_CLIENT_WINDOW).value = clientWindow;\n        }\n    }\n\n    /**\n     * transforms the user values to the expected one\n     * with the proper none all form and this handling\n     * (note we also could use a simple string replace but then\n     * we would have had double entries under some circumstances)\n     *\n     * there are several standardized constants which need a special treatment\n     * like @all, @none, @form, @this\n     *\n     * @param targetConfig the target configuration receiving the final values\n     * @param targetKey the target key\n     * @param userValues the passed user values (aka input string which needs to be transformed)\n     * @param issuingForm the form where the issuing element originates\n     * @param issuingElementId the issuing element\n     */\n    function remapDefaultConstants(targetConfig: Config, targetKey: string, userValues: string, issuingForm: DQ, issuingElementId: string): Config {\n        //a cleaner implementation of the transform list method\n\n        let iterValues = (userValues) ? trim(userValues).split(/\\s+/gi) : [];\n        let ret = [];\n        let processed = {};\n\n        //the idea is simply to loop over all values and then replace\n        //their generic values and filter out doubles\n        //this is more readable than the old indexed based solution\n        //and not really slower because we had to build up the index in our old solution\n        //anyway\n        for (let cnt = 0; cnt < iterValues.length; cnt++) {\n            //avoid doubles\n            if (iterValues[cnt] in processed) {\n                continue;\n            }\n            switch (iterValues[cnt]) {\n                //@none no values should be sent\n                case IDENT_NONE:\n                    return targetConfig.delete(targetKey);\n                //@all is a pass through case according to the spec\n                case IDENT_ALL:\n                    targetConfig.assign(targetKey).value = IDENT_ALL;\n                    return targetConfig;\n                //@form pushes the issuing form id into our list\n                case IDENT_FORM:\n                    ret.push(issuingForm.id.value);\n                    processed[issuingForm.id.value] = true;\n                    break;\n                //@this is replaced with the current issuing element id\n                case IDENT_THIS:\n                    if (!(issuingElementId in processed)) {\n                        ret.push(issuingElementId);\n                        processed[issuingElementId] = true;\n                    }\n                    break;\n                default:\n                    ret.push(iterValues[cnt]);\n                    processed[iterValues[cnt]] = true;\n            }\n        }\n        //We now add the target as joined list\n        targetConfig.assign(targetKey).value = ret.join(\" \");\n        return targetConfig;\n    }\n\n    /**\n     * filter the options tiven with a blacklist so that only\n     * the values required for passthough land in the ajax request\n     *\n     * @param mappedOpts the options to be filtered\n     */\n    function filterPassthroughValues(mappedOpts: { [key: string]: any }) {\n        //we now can use the full code reduction given by our stream api\n        //to filter\n        return Stream.ofAssoc(mappedOpts)\n            .filter(item => !(item[0] in BlockFilter))\n            .collect(new AssocArrayCollector());\n    }\n\n}\n","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Stream, StreamMapper} from \"./Stream\";\nimport {DomQuery} from \"./DomQuery\";\n\n/**\n * Every data source wich feeds data into the lazy stream\n * or stream generally must implement this interface\n *\n * It is basically an iteratable to the core\n */\nexport interface IStreamDataSource<T> {\n\n    /**\n     * @returns true if additional data is present\n     */\n    hasNext(): boolean;\n\n    /**\n     * false if not\n     */\n    next(): T;\n\n    /**\n     * resets the position to the beginning\n     */\n    reset(): void;\n}\n\n/**\n * A collector, needs to be implemented\n */\nexport interface ICollector<T, S> {\n    /**\n     * this method basically takes a single stream element\n     * and does something with it (collecting it one way or the other\n     * in most cases)\n     *\n     * @param element\n     */\n    collect(element: T);\n\n    /**\n     * the final result after all the collecting is done\n     */\n    finalValue: S;\n}\n\n/**\n * implementation of iteratable on top of array\n */\nexport class ArrayStreamDataSource<T> implements IStreamDataSource<T> {\n    value: Array<T>;\n    dataPos = -1;\n\n    constructor(...value: Array<T>) {\n        this.value = value;\n    }\n\n    hasNext(): boolean {\n        return this.value.length - 1 > this.dataPos;\n    }\n\n    next(): T {\n        this.dataPos++;\n        return this.value[this.dataPos];\n    }\n\n    reset() {\n        this.dataPos = -1;\n    }\n}\n\n/**\n * an intermediate data source wich prefilters\n * incoming stream data\n * and lets only the data out which\n * passes the filter function check\n */\nexport class FilteredStreamDatasource<T> implements IStreamDataSource<T> {\n\n    filterFunc: (T) => boolean;\n    inputDataSource: IStreamDataSource<T>;\n\n    filteredNext: T = null;\n\n    constructor(filterFunc: (T) => boolean, parent: IStreamDataSource<T>) {\n        this.filterFunc = filterFunc;\n        this.inputDataSource = parent;\n    }\n\n    /**\n     * in order to filter we have to make a look ahead until the\n     * first next allowed element\n     * hence we prefetch the element and then\n     * serve it via next\n     */\n    hasNext(): boolean {\n        while (this.filteredNext == null && this.inputDataSource.hasNext()) {\n            let next: T = <T>this.inputDataSource.next();\n            if (this.filterFunc(next)) {\n                this.filteredNext = next;\n                return true;\n            } else {\n                this.filteredNext = null;\n            }\n        }\n        return this.filteredNext != null;\n\n    }\n\n    /**\n     * serve the next element\n     */\n    next(): T {\n        let ret = this.filteredNext;\n        this.filteredNext = null;\n        //We have to call hasNext, to roll another\n        //prefetch in case someone runs next\n        //sequentially without calling hasNext\n        this.hasNext();\n        return ret;\n    }\n\n    reset(): void {\n        this.filteredNext = null;\n        this.inputDataSource.reset();\n    }\n}\n\n/**\n * an intermediate datasource which maps the items from\n * one into another\n */\nexport class MappedStreamDataSource<T, S> implements IStreamDataSource<S> {\n\n    mapFunc: (T) => S;\n    inputDataSource: IStreamDataSource<T>;\n\n    constructor(mapFunc: (T) => S, parent: IStreamDataSource<T>) {\n        this.mapFunc = mapFunc;\n        this.inputDataSource = parent;\n    }\n\n    hasNext(): boolean {\n        return this.inputDataSource.hasNext();\n    }\n\n    next(): S {\n        return this.mapFunc(this.inputDataSource.next());\n    }\n\n    reset(): void {\n        this.inputDataSource.reset();\n    }\n}\n\n/**\n * Same for flatmap to deal with element -> stream mappings\n */\nexport class FlatMapStreamDataSource<T, S> implements IStreamDataSource<S> {\n\n    mapFunc: StreamMapper<T>;\n\n    inputDataSource: IStreamDataSource<T>;\n\n    /**\n     * the currently active stream\n     * coming from an incoming element\n     * once the end of this one is reached\n     * it is swapped out by another one\n     * from the next element\n     */\n    activeDataSource: IStreamDataSource<S>;\n\n    constructor(func: StreamMapper<T>, parent: IStreamDataSource<T>) {\n        this.mapFunc = func;\n        this.inputDataSource = parent;\n    }\n\n    hasNext(): boolean {\n        return this.resolveCurrentNext() || this.resolveNextNext();\n    }\n\n    private resolveCurrentNext() {\n        let next = false;\n        if (this.activeDataSource) {\n            next = this.activeDataSource.hasNext();\n        }\n        return next;\n    }\n\n    private resolveNextNext() {\n        let next = false;\n        while (!next && this.inputDataSource.hasNext()) {\n            let mapped =  this.mapFunc(this.inputDataSource.next());\n            if(Array.isArray(mapped)) {\n                this.activeDataSource = new ArrayStreamDataSource(...mapped);\n            } else {\n                this.activeDataSource = mapped;\n            }\n            next = this.activeDataSource.hasNext();\n        }\n        return next;\n    }\n\n    next(): S {\n        return this.activeDataSource.next();\n    }\n\n    reset(): void {\n        this.inputDataSource.reset();\n    }\n}\n\n/**\n * For the time being we only need one collector\n * a collector which collects a stream back into arrays\n */\nexport class ArrayCollector<S> implements ICollector<S, Array<S>> {\n    private data: Array<S> = [];\n\n    collect(element: S) {\n        this.data.push(element);\n    }\n\n    get finalValue(): Array<S> {\n        return this.data;\n    }\n}\n\n/**\n * collects an assoc stream back to an assoc array\n */\nexport class AssocArrayCollector<S> implements ICollector<[string, S] | string, {[key:string]:S}> {\n\n    finalValue: {[key:string]:any} = {};\n\n    collect(element: [string, S] | string) {\n        this.finalValue[element[0] ?? <string>element] = element[1] ?? true;\n    }\n}\n\n/**\n * Form data collector for key value pair streams\n */\nexport class FormDataCollector implements ICollector<{ key: string, value: any }, FormData> {\n    finalValue: FormData = new FormData();\n\n    collect(element: { key: string; value: any }) {\n        this.finalValue.append(element.key, element.value);\n    }\n}\n\n/**\n * Form data collector for DomQuery streams\n */\nexport class QueryFormDataCollector implements ICollector<DomQuery, FormData> {\n    finalValue: FormData = new FormData();\n\n    collect(element: DomQuery) {\n        let toMerge = element.encodeFormElement();\n        if (toMerge.isPresent()) {\n            this.finalValue.append(element.name.value, toMerge.get(element.name).value);\n        }\n    }\n}\n\n/**\n * Encoded String collector from dom query streams\n */\nexport class QueryFormStringCollector implements ICollector<DomQuery, string> {\n\n    formData: [[string, string]] = <any>[];\n\n    collect(element: DomQuery) {\n        let toMerge = element.encodeFormElement();\n        if (toMerge.isPresent()) {\n            this.formData.push([element.name.value, toMerge.get(element.name).value]);\n        }\n    }\n\n    get finalValue(): string {\n        return Stream.of(...this.formData)\n            .map<string>(keyVal => keyVal.join(\"=\"))\n            .reduce((item1, item2) => [item1, item2].join(\"&\"))\n            .orElse(\"\").value;\n    }\n}","import {Config, Lang, XMLQuery} from \"../../ext/monadish\";\n\nimport {DQ} from \"../../ext/monadish\";\nimport {ExtLang} from \"./Lang\";\nimport getMessage = ExtLang.getMessage;\nimport makeException = ExtLang.makeException;\nimport {\n    ATTR_URL,\n    EMPTY_RESPONSE,\n    EMPTY_STR, ERR_NO_PARTIAL_RESPONSE, MALFORMEDXML,\n    ON_ERROR,\n    ON_EVENT,\n    PHASE_PROCESS_RESPONSE,\n    RESP_PARTIAL\n} from \"../core/Const\";\n\n/**\n * a set of internal code assertions\n * which raise an error\n *\n */\nexport module Assertions {\n\n    export function assertRequestIntegrity(options: Config, elem: DQ): void | never {\n        /*assert if the onerror is set and once if it is set it must be of type function*/\n        assertFunction(options.getIf(ON_ERROR).value);\n        /*assert if the onevent is set and once if it is set it must be of type function*/\n        assertFunction(options.getIf(ON_EVENT).value);\n        //improve the error messages if an empty elem is passed\n        //Assertions.assertElementExists(elem);\n        assert(elem.isPresent(), getMessage(\"ERR_MUST_BE_PROVIDED1\", \"{0}: source  must be provided or exist\", \"source element id\"), \"jsf.ajax.request\", \"ArgNotSet\",  )\n    }\n\n    export function assertUrlExists(node: XMLQuery): void | never {\n        if (node.attr(ATTR_URL).isAbsent()) {\n            throw Assertions.raiseError(new Error(), getMessage(\"ERR_RED_URL\", null, \"_Ajaxthis.processRedirect\"), \"processRedirect\");\n        }\n    }\n\n    /**\n     * checks the xml for various issues which can occur\n     * and prevent a proper processing\n     */\n    export function assertValidXMLResponse(responseXML: XMLQuery) : void | never  {\n        assert(!responseXML.isAbsent(), EMPTY_RESPONSE, PHASE_PROCESS_RESPONSE);\n        assert(!responseXML.isXMLParserError(),  responseXML.parserErrorText(EMPTY_STR), PHASE_PROCESS_RESPONSE);\n        assert(responseXML.querySelectorAll(RESP_PARTIAL).isPresent(), ERR_NO_PARTIAL_RESPONSE, PHASE_PROCESS_RESPONSE);\n    }\n\n    /**\n     * internal helper which raises an error in the\n     * format we need for further processing\n     *\n     * @param message the message\n     * @param title the title of the error (optional)\n     * @param name the name of the error (optional)\n     */\n    export function raiseError(error: any, message: string, caller ?: string, title ?: string, name ?: string): Error {\n\n        let finalTitle = title ?? MALFORMEDXML;\n        let finalName = name ?? MALFORMEDXML;\n        let finalMessage = message ?? EMPTY_STR;\n\n        //TODO clean up the messy makeException, this is a perfect case for encapsulation and sane defaults\n        return makeException(error, finalTitle, finalName, \"Response\", caller || (((<any>arguments).caller) ? (<any>arguments).caller.toString() : \"_raiseError\"), finalMessage);\n    }\n\n    /*\n     * using the new typescript 3.7 compiler assertion functionality to improve compiler hinting\n     * we are not fully there yet, but soon\n     */\n\n    export function assert(value: any, msg = EMPTY_STR, caller=EMPTY_STR, title=\"Assertion Error\"): asserts value {\n        if(!value) {\n            throw Assertions.raiseError(new Error(), msg ,caller, title);\n        }\n    }\n\n\n    export function assertType(value: any, theType: any, msg = EMPTY_STR, caller=EMPTY_STR, title=\"Type Assertion Error\"): asserts value {\n        if((!!value) && !Lang.assertType(value,theType)) {\n            throw Assertions.raiseError(new Error(), msg ,caller, title);\n        }\n    }\n\n    export function assertFunction(value: any, msg = EMPTY_STR, caller=EMPTY_STR, title=\"Assertion Error\"): asserts value is Function {\n        assertType(value, \"function\", msg, caller, title);\n    }\n}\n\n\n","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Config, DomQuery, DQ} from \"../../ext/monadish\";\nimport {\n    CTX_PARAM_DELAY,\n    CTX_PARAM_TIMEOUT,\n    EMPTY_FUNC,\n    EMPTY_STR,\n    ENCODED_URL,\n    MF_NONE,\n    REQ_TYPE_GET,\n    REQ_TYPE_POST\n} from \"../core/Const\";\nimport {XhrFormData} from \"./XhrFormData\";\nimport {ExtLang} from \"../util/Lang\";\nimport {ExtDomquery} from \"../util/ExtDomQuery\";\n\n/**\n * Resolver functions for various aspects of the request data\n *\n * stateless because it might be called from various\n * parts of the response classes\n */\n\n/**\n * resolves the event handlers lazly\n * so that if some decoration happens in between we can deal with it\n *\n * @param funcName\n */\nexport function resolveHandlerFunc(requestContext: Config, responseContext: Config, funcName: string) {\n    return responseContext.getIf(funcName)\n        .orElse(requestContext.getIf(funcName).value)\n        .orElse(EMPTY_FUNC).value;\n}\n\nexport function resolveTargetUrl(srcFormElement: HTMLFormElement) {\n    return (typeof srcFormElement.elements[ENCODED_URL] == 'undefined') ?\n        srcFormElement.action :\n        srcFormElement.elements[ENCODED_URL].value;\n}\n\nexport function resolveFinalUrl(sourceForm: DomQuery, formData: XhrFormData, ajaxType = REQ_TYPE_POST) {\n    let targetUrl = this.resolveTargetUrl(<HTMLFormElement>sourceForm.getAsElem(0).value);\n\n    return targetUrl + (ajaxType == REQ_TYPE_GET ? \"?\" + formData.toString() : EMPTY_STR);\n}\n\n/**\n * form resolution the same way our old implementation did\n * it is either the id or the parent form of the element or an embedded form\n * of the element\n *\n * @param requestCtx\n * @param elem\n * @param event\n */\nexport function resolveForm(requestCtx: Config, elem: DQ, event: Event): DQ {\n    const configId = requestCtx.value?.myfaces?.form ?? MF_NONE; //requestCtx.getIf(MYFACES, \"form\").orElse(MF_NONE).value;\n    return DQ\n        .byId(configId)\n        .orElseLazy(() => ExtLang.getForm(elem.getAsElem(0).value, event));\n}\n\nexport function resolveTimeout(options: Config): number {\n    let getCfg = ExtLang.getLocalOrGlobalConfig;\n    return options.getIf(CTX_PARAM_TIMEOUT).value ?? getCfg(options.value, CTX_PARAM_TIMEOUT, 0);\n}\n\n/**\n * resolve the delay from the options and/or the request context and or the configuration\n *\n * @param options ... the options object, in most cases it will host the delay value\n */\nexport function resolveDelay(options: Config): number {\n    let getCfg = ExtLang.getLocalOrGlobalConfig;\n\n    return options.getIf(CTX_PARAM_DELAY).value ?? getCfg(options.value, CTX_PARAM_DELAY, 0);\n}\n\n/**\n * resolves the window Id from various sources\n *\n * @param options\n */\nexport function resolveWindowId(options: Config) {\n    return options?.value?.windowId ?? ExtDomquery.windowId;\n}\n\n/**\n * determines the correct event depending\n * on the browsers state\n *\n * @param evt incoming event object (note not all browsers\n * have this)\n *\n * @return an event object no matter what is incoming\n */\nexport function resolveEvent(evt: Event): Event {\n    return evt ?? <any>window?.event ?? {};\n}\n\n/**\n * cross port from the dojo lib\n * browser save event resolution\n * @param evt the event object\n * (with a fallback for ie events if none is present)\n */\nexport function getEventTarget(evt: Event): Element {\n    //ie6 and 7 fallback\n    let finalEvent = this.resolveEvent(evt);\n    /**\n     * evt source is defined in the jsf events\n     * seems like some component authors use our code\n     * so we add it here see also\n     * https://issues.apache.org/jira/browse/MYFACES-2458\n     * not entirely a bug but makes sense to add this\n     * behavior. I dont use it that way but nevertheless it\n     * does not break anything so why not\n     * */\n    let t = finalEvent?.srcElement ?? finalEvent?.target ?? (<any>finalEvent)?.source;\n    while ((t) && (t.nodeType != 1)) {\n        t = t.parentNode;\n    }\n    return t;\n}\n\n/**\n * resolves a bunch of default values\n * which can be further processed from the given\n * call parameters of jsf.ajax.request\n *\n * @param event\n * @param opts\n * @param el\n */\nexport function resolveDefaults(event: Event, opts: any = {}, el: Element | string = null) {\n    const resolvedEvent = resolveEvent(event);\n\n    //deep copy the options, so that further transformations to not backfire into the callers\n    const options = new Config(opts).deepCopy;\n    const elem = DQ.byId(el || <Element>resolvedEvent.target);\n    const elementId = elem.id;\n    const requestCtx = new Config({});\n    const internalCtx = new Config({});\n    const windowId = resolveWindowId(options);\n    const isResetValues = true === options.value?.resetValues;\n    return {resolvedEvent, options, elem, elementId, requestCtx, internalCtx, windowId, isResetValues};\n};","import {EMPTY_STR, ERROR_MESSAGE, ERROR_NAME, RESPONSE_TEXT, RESPONSE_XML, SOURCE, STATUS} from \"../core/Const\";\nimport {Config} from \"../../ext/monadish\";\n\nimport {EventData} from \"./EventData\";\nimport {ExtLang} from \"../util/Lang\";\nimport getMessage = ExtLang.getMessage;\n\n\nexport enum ErrorType {\n    SERVER_ERROR = \"serverError\",\n    HTTP_ERROR = \"httpError\",\n    CLIENT_ERROR = \"clientErrror\",\n    TIMEOUT = \"timeout\"\n}\n\n/**\n * the spec has a problem of having the error\n * object somewhat underspecified, there is no clear\n * description of the required contents.\n * I want to streamline it with mojarra here\n * hence we are going to move\n * everything into the same attributes,\n * I will add deprecated myfaces backwards compatibility attributes as well\n */\nexport class ErrorData extends EventData {\n\n    type: string = \"error\";\n    source: string;\n    errorName: string;\n    errorMessage: string;\n\n    responseText: string;\n    responseXML: any;\n\n    status: string;\n    typeDetails: ErrorType;\n\n    //TODO backwards compatible attributes\n    serverErrorName: string;\n    serverErrorMessage: string;\n    message: string;\n\n    constructor(source: string, errorName: string, errorMessage: string, responseText: string = null, responseXML: any = null, responseCode: string = \"200\", status: string = \"UNKNOWN\", type = ErrorType.CLIENT_ERROR) {\n        super();\n        this.source = source;\n        this.type = \"error\";\n        this.errorName = errorName;\n        this.message = this.errorMessage = errorMessage;\n        this.responseCode = responseCode;\n        this.responseText = responseText;\n        this.status = status;\n        this.typeDetails = type;\n\n        if (type == ErrorType.SERVER_ERROR) {\n            this.serverErrorName = this.errorName;\n            this.serverErrorMessage = this.errorMessage;\n        }\n    }\n\n    static fromClient(e: Error): ErrorData {\n        return new ErrorData(\"client\", e.name, e.message, e.stack);\n    }\n\n    static fromHttpConnection(source: string, name: string, message: string, responseText, responseCode: number): ErrorData {\n        return new ErrorData(source, name, message, responseText, responseCode, null, \"UNKNOWN\", ErrorType.HTTP_ERROR);\n    }\n\n    static fromGeneric(context: Config, errorCode: number, errorType: ErrorType = ErrorType.SERVER_ERROR): ErrorData {\n\n        let UNKNOWN = \"UNKNOWN\";\n        let getMsg = this.getMsg;\n\n        let source = getMsg(context, SOURCE);\n        let errorName = getMsg(context, ERROR_NAME);\n        let errorMessage = getMsg(context, ERROR_MESSAGE);\n        let status = getMsg(context, STATUS);\n        let responseText = getMsg(context, RESPONSE_TEXT);\n        let responseXML = getMsg(context, RESPONSE_XML);\n        return new ErrorData(source, name, errorMessage, responseText, responseXML, errorCode + EMPTY_STR, status, errorType);\n    }\n\n    private static getMsg(context, param) {\n        let UNKNOWN = \"UNKNOWN\";\n        return getMessage(context.getIf(param).orElse(UNKNOWN).value);\n    }\n\n    static fromServerError(context: Config): ErrorData {\n        return this.fromGeneric(context, -1);\n    }\n\n}","import {Config, DQ} from \"../../ext/monadish\";\nimport {BEGIN, CTX_PARAM_PASS_THR, EVENT, P_PARTIAL_SOURCE, SOURCE} from \"../core/Const\";\n\nexport class EventData {\n    type: string;\n    status: string;\n    source: any;\n    responseCode: string;\n    responseText: string;\n    responseXML: Document;\n\n    static createFromRequest(request: XMLHttpRequest, context: Config, /*event name*/ name: string): EventData {\n\n        let eventData = new EventData();\n\n        eventData.type = EVENT;\n        eventData.status = name;\n\n        let sourceId: string = context.getIf(SOURCE)\n            .orElse(context.getIf(P_PARTIAL_SOURCE).value)\n            .orElse(context.getIf(CTX_PARAM_PASS_THR, P_PARTIAL_SOURCE).value).value;\n        if(sourceId) {\n            eventData.source = DQ.byId(sourceId).first().value.value;\n        }\n\n\n        if (name !== BEGIN) {\n            eventData.responseCode = request?.status?.toString();\n            eventData.responseText = request?.responseText;\n            eventData.responseXML = request?.responseXML;\n        }\n        return eventData;\n    }\n}\n","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n///<reference path='./ApiInterfaces.ts'/>\n///<reference types='../../types/typedefs'/>\n\nimport {Implementation} from \"../impl/AjaxImpl\";\nimport {PushImpl} from \"../impl/PushImpl\";\n\ndeclare let window: any;\ndeclare type Context = { [key: string]: any };\n\nlet mf_impl = window?.myfaces?._impl ?? {};\n\nexport module jsf {\n    \"use strict\";\n\n    /*\n     * Version of the implementation for the jsf.js.\n     * <p />\n     * as specified within the jsf specifications jsf.html:\n     * <ul>\n     * <li>left two digits major release number</li>\n     * <li>middle two digits minor spec release number</li>\n     * <li>right two digits bug release number</li>\n     * </ul>\n     * @constant\n     */\n    export var specversion = 220000;\n    /**\n     * Implementation version as specified within the jsf specification.\n     * <p />\n     * A number increased with every implementation version\n     * and reset by moving to a new spec release number\n     *\n     * @constant\n     */\n    export var implversion = 0;\n\n    /**\n     * SeparatorChar as defined by UINamingContainer.getNamingContainerSeparatorChar()\n     * @type {Char}\n     */\n    export var separatorchar = getSeparatorChar();\n\n    /**\n     * This method is responsible for the return of a given project stage as defined\n     * by the jsf specification.\n     * <p/>\n     * Valid return values are:\n     * <ul>\n     *     <li>&quot;Production&quot;</li>\n     *     <li>&quot;Development&quot;</li>\n     *     <li>&quot;SystemTest&quot;</li>\n     *     <li>&quot;UnitTest&quot;</li>\n     * </li>\n     *\n     * @return {String} the current project state emitted by the server side method:\n     * <i>javax.faces.application.Application.getProjectStage()</i>\n     */\n    export function getProjectStage(): string {\n        return Implementation.getProjectStage();\n    }\n\n    /**\n     * collect and encode data for a given form element (must be of type form)\n     * find the javax.faces.ViewState element and encode its value as well!\n     * return a concatenated string of the encoded values!\n     *\n     * @throws an exception in case of the given element not being of type form!\n     * https://issues.apache.org/jira/browse/MYFACES-2110\n     */\n    export function getViewState(formElement: Element | string): string {\n        return Implementation.getViewState(formElement);\n    }\n\n    /**\n     * returns the window identifier for the given node / window\n     * @param {optional String | DomNode}  the node for which the client identifier has to be determined\n     * @return the window identifier or null if none is found\n     */\n    export function getClientWindow(rootNode?: Element | string): string {\n        return Implementation.getClientWindow(rootNode);\n    }\n\n    //private helper functions\n    function getSeparatorChar() {\n        return Implementation.getSeparatorChar();\n    }\n\n\n    export module ajax {\n        \"use strict\";\n\n        /**\n         * this function has to send the ajax requests\n         *\n         * following requestInternal conditions must be met:\n         * <ul>\n         *  <li> the requestInternal must be sent asynchronously! </li>\n         *  <li> the requestInternal must be a POST!!! requestInternal </li>\n         *  <li> the requestInternal url must be the form action attribute </li>\n         *  <li> all requests must be queued with a client side requestInternal queue to ensure the requestInternal ordering!</li>\n         * </ul>\n         *\n         * @param {String|Node} element: any dom element no matter being it html or jsf, from which the event is emitted\n         * @param {EVENT} event: any javascript event supported by that object\n         * @param {Map} options : map of options being pushed into the ajax cycle\n         */\n        export function request(element: Element, event?: Event, options?: Context) {\n            Implementation.request(element, event, options)\n            //Implementation.getInstance().requestInternal(element, event, options);\n        }\n\n        /**\n         * response handler\n         * @param request the request object having triggered this response\n         * @param context the request context\n         *\n         * TODO add info on what can be in the context\n         */\n        export function response(request: XMLHttpRequest, context?: Context) {\n            Implementation.response(request, context);\n        }\n\n        /**\n         * Adds an error handler to our global error queue.\n         * the error handler must be of the format <i>function errorListener(&lt;errorData&gt;)</i>\n         * with errorData being of following format:\n         * <ul>\n         *     <li> errorData.type : &quot;error&quot;</li>\n         *     <li> errorData.status : the error status message</li>\n         *     <li> errorData.serverErrorName : the server error name in case of a server error</li>\n         *     <li> errorData.serverErrorMessage : the server error message in case of a server error</li>\n         *     <li> errorData.source  : the issuing source element which triggered the requestInternal </li>\n         *     <li> eventData.responseCode: the response code (aka http requestInternal response code, 401 etc...) </li>\n         *     <li> eventData.responseText: the requestInternal response text </li>\n         *     <li> eventData.responseXML: the requestInternal response xml </li>\n         * </ul>\n         *\n         * @param {function} errorListener error handler must be of the format <i>function errorListener(&lt;errorData&gt;)</i>\n         */\n        export function addOnError(errorFunc: (data: _apiInterfaces.ErrorData) => void) {\n            Implementation.addOnError(<any>errorFunc);\n        }\n\n        /**\n         * Adds a global event listener to the ajax event queue. The event listener must be a function\n         * of following format: <i>function eventListener(&lt;eventData&gt;)</i>\n         *\n         * @param {function} eventListener event must be of the format <i>function eventListener(&lt;eventData&gt;)</i>\n         */\n        export function addOnEvent(eventFunc: (data: _apiInterfaces.EventData) => void) {\n            Implementation.addOnEvent(<any>eventFunc);\n        }\n    }\n\n    export module util {\n\n        /**\n         * varargs function which executes a chain of code (functions or any other code)\n         *\n         * if any of the code returns false, the execution\n         * is terminated prematurely skipping the rest of the code!\n         *\n         * @param {DomNode} source, the callee object\n         * @param {Event} event, the event object of the callee event triggering this function\n         * @param funcs ... arbitrary array of functions or strings\n         * @returns true if the chain has succeeded false otherwise\n         */\n        export function chain(source, event, ...funcs: Array<Function | string>): boolean {\n            return Implementation.chain(source, event, ...funcs);\n        }\n    }\n\n    export module push {\n        /**\n         * @param {function} onopen The function to be invoked when the web socket is opened.\n         * @param {function} onmessage The function to be invoked when a message is received.\n         * @param {function} onclose The function to be invoked when the web socket is closed.\n         * @param {boolean} autoconnect Whether or not to immediately open the socket. Defaults to <code>false</code>.\n         */\n        export function init(socketClientId: string,\n                    uri: string,\n                    channel: string,\n                    onopen: Function,\n                    onmessage: Function,\n                    onclose: Function,\n                    behaviorScripts: any,\n                    autoconnect: boolean) {\n            PushImpl.init(socketClientId, uri, channel, onopen, onmessage, onclose, behaviorScripts, autoconnect);\n        }\n\n        /**\n         * Open the web socket on the given channel.\n         * @param {string} channel The name of the web socket channel.\n         * @throws {Error} When channel is unknown.\n         */\n        export function open(socketClientId: string) {\n            PushImpl.open(socketClientId);\n        }\n\n        /**\n         * Close the web socket on the given channel.\n         * @param {string} channel The name of the web socket channel.\n         * @throws {Error} When channel is unknown.\n         */\n        export function close(socketClientId: string) {\n            PushImpl.close(socketClientId);\n        }\n\n    }\n\n    //We hook the old namespace system into our npm system\n    //if (\"undefined\" == window.jsf) {\n    //    window.jsf = jsf;\n    //}\n\n\n}\n\n\n\n//fullfill the window contract\nexport module myfaces {\n\n    //legacy compatibility\n    export var _impl = mf_impl;\n\n    /**\n     * AB function similar to mojarra and Primefaces\n     * not part of the spec but a convenience accessor method\n     * Code provided by Thomas Andraschko\n     *\n     * @param source the event source\n     * @param event the event\n     * @param eventName event name for java.javax.faces.behavior.evemnt\n     * @param execute execute list as passed down in jsf.ajax.request\n     * @param render\n     * @param options\n     */\n    export function ab(source: Element, event: Event, eventName: string, execute: string, render: string, options: Context = {}) {\n        if (eventName) {\n            options[\"javax.faces.behavior.event\"] = eventName;\n        }\n        if (execute) {\n            options[\"execute\"] = execute;\n        }\n        if (render) {\n            options[\"render\"] = render;\n        }\n\n        jsf.ajax.request(source, event, options);\n    }\n\n    //We hook the old namespace system into our npm system\n    if (\"undefined\" == window?.myfaces?.ab) {\n        window[\"myfaces\"] = window.myfaces ?? {} ;\n        window.myfaces[\"ab\"] = ab;\n    }\n}\n\n\n","import {Config, IValueHolder, Optional} from \"../../ext/monadish/Monad\";\nimport {DomQuery, DQ} from \"../../ext/monadish/DomQuery\";\nimport {EMPTY_STR, P_WINDOW_ID} from \"../core/Const\";\n\ndeclare let window: any;\n\n/**\n * Extension which adds implementation specific\n * meta data to our dom qury\n *\n * Usage\n * el = new ExtDQ(oldReference)\n * nonce = el.nonce\n * windowId = el.getWindowId\n */\nexport class ExtDomquery extends DQ {\n\n    static get windowId() {\n        return new ExtDomquery(document.body).windowId;\n    }\n\n    static get nonce(): string {\n        return new ExtDomquery(document.body).nonce;\n    }\n\n    get windowId() {\n\n        const fetchWindowIdFromURL = function () {\n            let href = window.location.href;\n            let windowId = \"windowId\";\n            let regex = new RegExp(\"[\\\\?&]\" + windowId + \"=([^&#\\\\;]*)\");\n            let results = regex.exec(href);\n            //initial trial over the url and a regexp\n            if (results != null) return results[1];\n            return null;\n        };\n\n        //byId ($)\n        if (this.value.isPresent()) {\n            let result = this.querySelectorAll(\"form input[name='\" + P_WINDOW_ID + \"']\");\n            if (result.length > 0) {\n                throw Error(\"Multiple different windowIds found in document\");\n            }\n\n            return (result.isPresent()) ? (<HTMLInputElement>result.getAsElem(0).value).value : fetchWindowIdFromURL();\n        } else {\n            return fetchWindowIdFromURL();\n        }\n    }\n\n    /*\n    determines the jsfjs nonce and adds them to the namespace\n    * this is done once and only lazily\n    */\n    get nonce(): string {\n        //already processed\n        let myfacesConfig = new Config(window.myfaces);\n        let nonce: IValueHolder<string> = myfacesConfig.assign(\"config\", \"cspMeta\", \"nonce\");\n        if (nonce.value) {\n            return <string>nonce.value;\n        }\n\n        let curScript = new DQ(document.currentScript);\n        //since our baseline atm is ie11 we cannot use document.currentScript globally\n        if (curScript.attr(\"nonce\").value != null) {\n            //fastpath for modern browsers\n            return curScript.attr(\"nonce\").value;\n        }\n\n        let nonceScript = DQ.querySelectorAll(\"script[src], link[src]\").lazyStream\n            .filter((item) => item.attr(\"nonce\").value != null && item.attr(\"src\") != null)\n            .map((item => !item.attr(\"src\").value.match(/jsf\\.js\\?ln\\=javax\\.faces/gi)))\n            .first();\n\n        if (nonceScript.isPresent()) {\n            nonce.value = DomQuery.byId(nonceScript.value).attr(\"nonce\").value;\n        }\n        return <string>nonce.value;\n    }\n\n    static searchJsfJsFor(item: RegExp): Optional<String> {\n        return new ExtDomquery(document).searchJsfJsFor(item);\n    }\n\n    searchJsfJsFor(rexp: RegExp): Optional<string> {\n        //perfect application for lazy stream\n        return DQ.querySelectorAll(\"script\").lazyStream\n                .filter(item => {\n                    return (item.attr(\"src\").value ?? EMPTY_STR).search(/\\/javax\\.faces\\.resource.*\\/jsf\\.js.*separator/) != -1;\n                }).map((item: DQ) => {\n                    let result = item.attr(\"src\").value.match(rexp);\n                    return decodeURIComponent(result[1]);\n                }).first();\n    }\n\n    globalEval(code: string, nonce ?: string): DQ {\n        return super.globalEval(code, nonce ?? this.nonce);\n    }\n}\n\nexport const ExtDQ = DQ;","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {Config, Lang} from \"../../ext/monadish\";\n\nimport {Stream} from \"../../ext/monadish\";\nimport {DQ} from \"../../ext/monadish\";\nimport isString = Lang.isString;\nimport {EMPTY_STR, P_VIEWSTATE} from \"../core/Const\";\n\n\n/**\n * A unified form data class\n * which builds upon our configuration.\n *\n * We cannot use standard html5 forms everywhere\n * due to api constraints on the HTML Form object in IE11\n * and due to the url encoding constraint given by the jsf.js spec\n */\nexport class XhrFormData extends Config {\n\n    /**\n     * data collector from a given form\n     *\n     * @param dataSource either a form as DomQuery object or an encoded url string\n     * @param partialIdsArray partial ids to collect, to reduce the data sent down\n     */\n    constructor(private dataSource: DQ | string, private partialIdsArray?: string[], private encode = true) {\n        super({});\n        //a call to getViewState before must pass the encoded line\n        //a call from getViewState passes the form element as datasource\n        //so we have two call points\n        if (isString(dataSource)) {\n            this.assignEncodedString(<string>this.dataSource);\n        } else {\n            this.handleFormSource();\n        }\n    }\n\n    private handleFormSource() {\n        //encode and append the issuing item if not a partial ids array of ids is passed\n        /*\n         * Spec. 13.3.1\n         * Collect and encode input elements.\n         * Additionally the hidden element javax.faces.ViewState\n         * Enhancement partial page submit\n         *\n         */\n        this.encodeSubmittableFields(this, <DQ>this.dataSource, this.partialIdsArray);\n\n        if (this.getIf(P_VIEWSTATE).isPresent()) {\n            return;\n        }\n\n        this.applyViewState(<DQ>this.dataSource);\n    }\n\n    /**\n     * special case viewstate handling\n     *\n     * @param form the form holding the viewstate value\n     */\n    private applyViewState(form: DQ) {\n        let viewState = form.byId(P_VIEWSTATE).inputValue;\n        this.assignIf(viewState.isPresent() ,P_VIEWSTATE).value = viewState.value;\n    }\n\n    /**\n     * assignes a url encoded string to this xhrFormData object\n     * as key value entry\n     * @param encoded\n     */\n    assignEncodedString(encoded: string) {\n        let keyValueEntries = encoded.split(/&/gi);\n        Stream.of(...keyValueEntries)\n            //split only the first =\n            .map(line => line.split(/=(.*)/gi))\n            //special case of having keys without values\n            .map(keyVal => keyVal.length < 3 ? [keyVal?.[0] ?? [], keyVal?.[1] ?? []] : keyVal)\n            .each(keyVal => {\n                this.assign(keyVal [0]).value = keyVal?.splice(1)?.join(\"\") ?? \"\";\n            });\n    }\n\n    // noinspection JSUnusedGlobalSymbols\n    /**\n     * @returns a Form data representation\n     */\n    toFormData(): FormData {\n        let ret: any = new FormData();\n        for (let key in this.value) {\n            if (this.value.hasOwnProperty(key)) {\n                ret.append(key, this.value[key])\n            }\n        }\n        return ret;\n    }\n\n    /**\n     * returns an encoded string representation of our xhr form data\n     *\n     * @param defaultStr optional default value if nothing is there to encode\n     */\n    toString(defaultStr = EMPTY_STR): string {\n        if (this.isAbsent()) {\n            return defaultStr;\n        }\n        let entries = [];\n        for (let key in this.value) {\n            if (this.value.hasOwnProperty(key)) {\n                //key value already encoded so no need to reencode them again\n                entries.push(`${encodeURIComponent(key)}=${encodeURIComponent(this.value[key])}`)\n            }\n        }\n        return entries.join(\"&\")\n    }\n\n    /**\n     * determines fields to submit\n     * @param {Object} targetBuf - the target form buffer receiving the data\n     * @param {Node} parentItem - form element item is nested in\n     * @param {Array} partialIds - ids fo PPS\n     */\n    private encodeSubmittableFields(targetBuf: Config,\n                                    parentItem: DQ, partialIds ?: string[]) {\n        let toEncode = null;\n        if (this.partialIdsArray && this.partialIdsArray.length) {\n            //in case of our myfaces reduced ppr we only\n            //only submit the partials\n            this._value = {};\n            toEncode = new DQ(...this.partialIdsArray);\n\n        } else {\n            if (parentItem.isAbsent()) throw \"NO_PARITEM\";\n            toEncode = parentItem;\n        }\n\n        //lets encode the form elements\n        this.shallowMerge(toEncode.querySelectorAll(\"input, checkbox, select, textarea\").encodeFormElement());\n    }\n\n    /**\n     * checks if the given datasource is a multipart request source\n     */\n    get isMultipartRequest(): boolean {\n        return  this.dataSource instanceof DQ && (<DQ> this.dataSource).querySelectorAll(\"input[type='file']\").isPresent();\n    }\n\n}","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * internal myfaces config override params\n */\ndeclare var window: any;\nexport module myfaces {\n\n    export class ConfigHolder {\n        projectStage: string = null;\n        separator: string = null;\n    }\n\n    export var config = new ConfigHolder();\n\n    //if (window && \"undefined\" == typeof window.myfaces) {\n    //    window.myfaces = myfaces;\n    //}\n}\n","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Config, DQ, XMLQuery} from \"../../ext/monadish\";\nimport {ResponseProcessor} from \"./ResponseProcessor\";\n\nimport {IResponseProcessor} from \"./IResponseProcessor\";\nimport {\n    CMD_ATTRIBUTES,\n    CMD_CHANGES,\n    CMD_DELETE,\n    CMD_ERROR,\n    CMD_EVAL,\n    CMD_EXTENSION,\n    CMD_INSERT,\n    CMD_REDIRECT,\n    CMD_UPDATE,\n    P_VIEWBODY,\n    P_VIEWHEAD,\n    P_VIEWROOT,\n    PARTIAL_ID,\n    RESP_PARTIAL,\n    RESPONSE_XML,\n    TAG_AFTER,\n    TAG_BEFORE\n} from \"../core/Const\";\nimport {resolveContexts, resolveResponseXML} from \"./ResonseDataResolver\";\n\n\nexport module Response {\n\n\n    /**\n     * Standardized jsf.js response\n     * this one is called straight from jsf.js.response\n     *\n     * The processing follows the spec by going for the responseXML\n     * and processing its tags\n     *\n     * @param {XMLHttpRequest} request (xhrRequest) - xhr request object\n     * @param {[key: string]: any} context (Map) - AJAX context\n     *\n     */\n    export function processResponse(request: XMLHttpRequest, context: { [key: string]: any }) {\n\n        let req = Config.fromNullable(request);\n        let {externalContext, internalContext} = resolveContexts(context);\n        let responseXML: XMLQuery = resolveResponseXML(req);\n        let responseProcessor = new ResponseProcessor(req, externalContext, internalContext);\n\n        internalContext.assign(RESPONSE_XML).value = responseXML;\n\n        //we now process the partial tags, or in none given raise an error\n        responseXML.querySelectorAll(RESP_PARTIAL)\n            .each(item => processPartialTag(<XMLQuery>item, responseProcessor, internalContext));\n\n        //we now process the viewstates and the evals deferred\n        //the reason for this is that often it is better\n        //to wait until the document has caught up before\n        //doing any evals even on embedded scripts\n        responseProcessor.fixViewStates();\n        responseProcessor.globalEval();\n\n        responseProcessor.done();\n    }\n\n    /**\n     * highest node partial-response from there the main operations are triggered\n     */\n     function processPartialTag(node: XMLQuery, responseProcessor: IResponseProcessor, internalContext) {\n\n        internalContext.assign(PARTIAL_ID).value = node.id;\n        const SEL_SUB_TAGS = [CMD_ERROR, CMD_REDIRECT, CMD_CHANGES].join(\",\");\n\n        //now we can process the main operations\n        node.getIf(SEL_SUB_TAGS).each((node: XMLQuery) => {\n            switch (node.tagName.value) {\n                case CMD_ERROR:\n                    responseProcessor.error(node);\n                    break;\n                case CMD_REDIRECT:\n                    responseProcessor.redirect(node);\n                    break;\n                case CMD_CHANGES:\n                    processChangesTag(node, responseProcessor);\n                    break;\n            }\n        });\n\n    }\n\n    let processInsert = function (responseProcessor: IResponseProcessor, node: XMLQuery) {\n         //path1 insert after as child tags\n         if(node.querySelectorAll([TAG_BEFORE, TAG_AFTER].join(\",\")).length) {\n             responseProcessor.insertWithSubtags(node);\n         } else { //insert before after with id\n             responseProcessor.insert(node);\n         }\n\n    };\n\n    /**\n     * next level changes tag\n     *\n     * @param node\n     * @param responseProcessor\n     */\n     function processChangesTag(node: XMLQuery, responseProcessor: IResponseProcessor): boolean {\n        const ALLOWED_TAGS = [CMD_UPDATE, CMD_EVAL, CMD_INSERT, CMD_DELETE, CMD_ATTRIBUTES, CMD_EXTENSION].join(\",\");\n        node.getIf(ALLOWED_TAGS).each(\n            (node: XMLQuery) => {\n                switch (node.tagName.value) {\n                    case CMD_UPDATE:\n                        processUpdateTag(node, responseProcessor);\n                        break;\n\n                    case CMD_EVAL:\n                        responseProcessor.eval(node);\n                        break;\n\n                    case CMD_INSERT:\n                        processInsert(responseProcessor, node);\n                        break;\n\n                    case CMD_DELETE:\n                        responseProcessor.delete(node);\n                        break;\n\n                    case CMD_ATTRIBUTES:\n                        responseProcessor.attributes(node);\n                        break;\n\n                    case CMD_EXTENSION:\n                        break;\n                }\n            }\n        );\n        return true;\n    }\n\n    /**\n     * branch tag update.. drill further down into the updates\n     * special case viewstate in that case it is a leaf\n     * and the viewstate must be processed\n     *\n     * @param node\n     * @param responseProcessor\n     */\n     function processUpdateTag(node: XMLQuery, responseProcessor: IResponseProcessor) {\n        if (!responseProcessor.processViewState(node)) {\n            handleElementUpdate(node, responseProcessor);\n        }\n    }\n\n    /**\n     * element update\n     *\n     * @param node\n     * @param responseProcessor\n     */\n     function handleElementUpdate(node: XMLQuery, responseProcessor: IResponseProcessor) {\n        let cdataBlock = node.cDATAAsString;\n        switch (node.id.value) {\n            case P_VIEWROOT :\n                responseProcessor.replaceViewRoot(DQ.fromMarkup(cdataBlock.substring(cdataBlock.indexOf(\"<html\"))));\n                break;\n\n            case P_VIEWHEAD:\n                responseProcessor.replaceHead(DQ.fromMarkup(cdataBlock));\n                break;\n\n            case P_VIEWBODY:\n                responseProcessor.replaceBody(DQ.fromMarkup(cdataBlock));\n                break;\n\n            default://htmlItem replacement\n                responseProcessor.update(node, cdataBlock);\n                break;\n\n        }\n    }\n}","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Lang} from \"./Lang\";\nimport {DomQuery} from \"./DomQuery\";\nimport isString = Lang.isString;\n\ndeclare let ActiveXObject: any;\n\n/**\n * xml query as specialized case for DomQuery\n */\nexport class XMLQuery extends DomQuery {\n\n    constructor(rootNode: Document | string | DomQuery, docType: SupportedType = \"text/xml\") {\n\n\n        let createIe11DomQueryShim = (): DOMParser => {\n            //at the time if wroting ie11 is the only relevant browser\n            //left withut any DomQuery support\n            let parser = new ActiveXObject(\"Microsoft.XMLDOM\");\n            parser.async = false;\n            //we shim th dom parser from ie in\n            return <any> {\n                parseFromString: (text: string, contentType: string): Document => {\n                    return parser.loadXML(text);\n                }\n            }\n        };\n\n        let parseXML = (xml: string): Document => {\n            if(xml == null) {\n                return null;\n            }\n            let domParser: DOMParser = Lang.saveResolveLazy<DOMParser>(\n                () => new window.DOMParser(),\n                (): DOMParser =>  createIe11DomQueryShim()\n            ).value;\n            return domParser.parseFromString(xml, docType);\n        };\n\n        if(isString(rootNode)) {\n            super(parseXML(<string>rootNode))\n        } else {\n            super(rootNode);\n        }\n    }\n\n\n    isXMLParserError(): boolean {\n        return this.querySelectorAll(\"parsererror\").isPresent();\n    }\n\n\n\n    toString(): string {\n        let ret = [];\n        this.eachElem((node: any) => {\n            let serialized = (<any>window)?.XMLSerializer?.constructor()?.serializeToString(node) ?? node?.xml;\n            if(!!serialized) {\n                ret.push(serialized);\n            }\n        });\n        return ret.join(\"\");\n    }\n\n\n    parserErrorText(joinstr: string): string {\n        return this.querySelectorAll(\"parsererror\").textContent(joinstr);\n    }\n\n    static parseXML(txt: string): XMLQuery {\n        return new  XMLQuery(txt);\n    }\n    static parseHTML(txt: string): XMLQuery {\n        return new  XMLQuery(txt, \"text/html\");\n    }\n\n    static fromString(txt: string, parseType: SupportedType = \"text/xml\"): XMLQuery {\n        return new  XMLQuery(txt,parseType);\n    }\n}\n\nexport const XQ = XMLQuery;\nexport type XQ = XMLQuery;","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Config, DomQuery, DQ, Lang, Stream, XMLQuery} from \"../../ext/monadish\";\nimport {Implementation} from \"../AjaxImpl\";\nimport {Assertions} from \"../util/Assertions\";\nimport {IResponseProcessor} from \"./IResponseProcessor\";\nimport {ErrorData} from \"./ErrorData\";\nimport {ExtLang} from \"../util/Lang\";\n\nimport {ViewState} from \"../core/ImplTypes\";\nimport {EventData} from \"./EventData\";\nimport {\n    APPLIED_VST,\n    ATTR_ID,\n    ATTR_NAME,\n    ATTR_URL,\n    ATTR_VALUE,\n    EMPTY_FUNC,\n    EMPTY_STR,\n    ERROR_MESSAGE,\n    ERROR_NAME,\n    HTML_VIEWSTATE,\n    ON_ERROR,\n    ON_EVENT,\n    P_PARTIAL_SOURCE,\n    P_VIEWSTATE,\n    RESPONSE_XML,\n    SEL_SCRIPTS_STYLES,\n    SEL_VIEWSTATE_ELEM,\n    SOURCE,\n    SUCCESS,\n    TAG_AFTER,\n    TAG_ATTR,\n    TAG_BEFORE,\n    TAG_BODY,\n    TAG_FORM,\n    TAG_HEAD,\n    UPDATE_ELEMS,\n    UPDATE_FORMS\n} from \"../core/Const\";\nimport trim = Lang.trim;\nimport getLocalOrGlobalConfig = ExtLang.getLocalOrGlobalConfig;\n\n/**\n * Response processor\n *\n * Each  XML tag is either a node or a leaf\n * or both\n *\n * the processor provides a set of operations\n * which are executed on a single leaf node per operation\n * and present the core functionality of our response\n *\n * Note the response processor is stateful hence we bundle it in a class\n * to reduce code we keep references tot contexts in place\n */\nexport class ResponseProcessor implements IResponseProcessor {\n\n    constructor(private request: Config, private externalContext: Config, private internalContext: Config) {\n\n    }\n\n    replaceHead(shadowDocument: XMLQuery | DQ) {\n        let shadowHead = shadowDocument.querySelectorAll(TAG_HEAD);\n        if (!shadowHead.isPresent()) {\n            return;\n        }\n\n        let oldHead = DQ.querySelectorAll(TAG_HEAD);\n\n        //delete all to avoid script and style overlays\n        oldHead.querySelectorAll(SEL_SCRIPTS_STYLES).delete();\n\n        this.storeForEval(shadowHead);\n    }\n\n    /**\n     * replaces the body in the expected manner\n     * which means the entire body content is refreshed\n     * however also the body attributes must be transferred\n     * keeping event handlers etc... in place\n     *\n     * @param shadowDocument .. an incoming shadow document hosting the new nodes\n     */\n    replaceBody(shadowDocument: XMLQuery | DQ) {\n\n        let shadowBody = shadowDocument.querySelectorAll(TAG_BODY);\n        if (!shadowBody.isPresent()) {\n            return;\n        }\n\n        let shadowInnerHTML: string = <string>shadowBody.html().value;\n\n        let resultingBody = <DQ>DQ.querySelectorAll(TAG_BODY).html(shadowInnerHTML);\n        let updateForms = resultingBody.querySelectorAll(TAG_FORM);\n\n        resultingBody.copyAttrs(shadowBody);\n\n        this.storeForPostProcessing(updateForms, resultingBody);\n    }\n\n    /**\n     * Leaf Tag eval... process whatever is in the evals cdata block\n     *\n     * @param node the node to eval\n     */\n    eval(node: XMLQuery) {\n        DQ.globalEval(node.cDATAAsString);\n    }\n\n    /**\n     * processes an incoming error from the response\n     * which is hosted under the &lt;error&gt; tag\n     * @param node the node hosting the error in our response xml\n     * @param node the node in the xml hosting the error message\n     */\n    error(node: XMLQuery) {\n        /**\n         * <error>\n         *      <error-name>String</error-name>\n         *      <error-message><![CDATA[message]]></error-message>\n         * <error>\n         */\n\n        let mergedErrorData = new Config({});\n        mergedErrorData.assign(SOURCE).value = this.externalContext.getIf(P_PARTIAL_SOURCE).get(0).value;\n        mergedErrorData.assign(ERROR_NAME).value = node.getIf(ERROR_NAME).textContent(EMPTY_STR);\n        mergedErrorData.assign(ERROR_MESSAGE).value = node.getIf(ERROR_MESSAGE).cDATAAsString;\n\n        let hasResponseXML = this.internalContext.get(RESPONSE_XML).isPresent();\n        mergedErrorData.assignIf(hasResponseXML, RESPONSE_XML).value = this.internalContext.getIf(RESPONSE_XML).value.get(0).value;\n\n        let errorData = ErrorData.fromServerError(mergedErrorData);\n\n        this.externalContext.getIf(ON_ERROR).orElse(this.internalContext.getIf(ON_ERROR).value).orElse(EMPTY_FUNC).value(errorData);\n        Implementation.sendError(errorData);\n    }\n\n    /**\n     * process the redirect operation\n     *\n     * @param node\n     */\n    redirect(node: XMLQuery) {\n        Assertions.assertUrlExists(node);\n\n        let redirectUrl = trim(node.attr(ATTR_URL).value);\n        if (redirectUrl != EMPTY_STR) {\n            (<any>window).location.href = redirectUrl;\n        }\n    }\n\n    /**\n     * processes the update operation and updates the node with the cdata block\n     * @param node the xml response node hosting the update info\n     * @param cdataBlock the cdata block with the new html code\n     */\n    update(node: XMLQuery, cdataBlock: string) {\n        let result = DQ.byId(node.id.value).outerHTML(cdataBlock, false, false);\n        let sourceForm = result?.parents(TAG_FORM).orElse(result.byTagName(TAG_FORM, true));\n        if (sourceForm) {\n            this.storeForPostProcessing(sourceForm, result);\n        }\n    }\n\n    delete(node: XMLQuery) {\n        DQ.byId(node.id.value).delete();\n    }\n\n    /**\n     * attributes leaf tag... process the attributes\n     *\n     * @param node\n     */\n    attributes(node: XMLQuery) {\n        let elem = DQ.byId(node.id.value);\n\n        node.byTagName(TAG_ATTR).each((item: XMLQuery) => {\n            elem.attr(item.attr(ATTR_NAME).value).value = item.attr(ATTR_VALUE).value;\n        });\n    }\n\n    /**\n     * @param shadowDocument a shadow document which is needed for further processing\n     */\n    replaceViewRoot(shadowDocument: XMLQuery) {\n        this.replaceHead(shadowDocument);\n        this.replaceBody(shadowDocument);\n    }\n\n    /**\n     * insert handling, either before or after\n     *\n     * @param node\n     */\n    insert(node: XMLQuery) {\n        //let insertId = node.id; //not used atm\n\n        let before = node.attr(TAG_BEFORE);\n        let after = node.attr(TAG_AFTER);\n\n        let insertNodes = DQ.fromMarkup(<any>node.cDATAAsString);\n\n        if (before.isPresent()) {\n            DQ.byId(before.value).insertBefore(insertNodes);\n            this.internalContext.assign(UPDATE_ELEMS).value.push(insertNodes);\n        }\n        if (after.isPresent()) {\n            let domQuery = DQ.byId(after.value);\n            domQuery.insertAfter(insertNodes);\n\n            this.internalContext.assign(UPDATE_ELEMS).value.push(insertNodes);\n        }\n    }\n\n    /**\n     * handler for the case &lt;insert <&lt; before id=\"...\n     *\n     * @param node the node hosting the insert data\n     */\n    insertWithSubtags(node: XMLQuery) {\n        let before = node.querySelectorAll(TAG_BEFORE);\n        let after = node.querySelectorAll(TAG_AFTER);\n\n        before.each(item => {\n            let insertId = item.attr(ATTR_ID);\n            let insertNodes = DQ.fromMarkup(<any>item.cDATAAsString);\n            if (insertId.isPresent()) {\n                DQ.byId(insertId.value).insertBefore(insertNodes);\n                this.internalContext.assign(UPDATE_ELEMS).value.push(insertNodes);\n            }\n        });\n\n        after.each(item => {\n            let insertId = item.attr(ATTR_ID);\n            let insertNodes = DQ.fromMarkup(<any>item.cDATAAsString);\n            if (insertId.isPresent()) {\n                DQ.byId(insertId.value).insertAfter(insertNodes);\n                this.internalContext.assign(UPDATE_ELEMS).value.push(insertNodes);\n            }\n        });\n    }\n\n    /**\n     * process the viewState update, update the affected\n     * forms with their respective new viewstate values\n     *\n     */\n    processViewState(node: XMLQuery): boolean {\n        if (ResponseProcessor.isViewStateNode(node)) {\n            let viewStateValue = node.cDATAAsString;\n            this.internalContext.assign(APPLIED_VST, node.id.value).value = new ViewState(node.id.value, viewStateValue);\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * generic global eval which runs the embedded css and scripts\n     */\n    globalEval() {\n        let updateElems = new DQ(...this.internalContext.getIf(UPDATE_ELEMS).value);\n        updateElems.runCss();\n        updateElems.runScripts();\n    }\n\n    /**\n     * post processing viewstate fixing\n     */\n    fixViewStates() {\n        Stream.ofAssoc<ViewState>(this.internalContext.getIf(APPLIED_VST).orElse({}).value)\n            .each((item: Array<any>) => {\n                let value: ViewState =item[1];\n                let nameSpace = DQ.byId(value.nameSpace).orElse(document.body);\n                let affectedForms = nameSpace.byTagName(TAG_FORM);\n                let affectedForms2 = nameSpace.filter(item => item.tagName.orElse(EMPTY_STR).value.toLowerCase() == TAG_FORM);\n\n\n                this.appendViewStateToForms(new DomQuery(affectedForms, affectedForms2), value.value);\n            });\n    }\n\n    /**\n     * all processing done we can close the request and send the appropriate events\n     */\n    done() {\n        let eventData = EventData.createFromRequest(this.request.value, this.externalContext, SUCCESS);\n\n        //because some frameworks might decorate them over the context in the response\n        let eventHandler = this.externalContext.getIf(ON_EVENT).orElse(this.internalContext.getIf(ON_EVENT).value).orElse(EMPTY_FUNC).value;\n        Implementation.sendEvent(eventData, eventHandler);\n    }\n\n    /**\n     * proper viewstate -> form assignment\n     *\n     * @param forms the forms to append the viewstate to\n     * @param viewState the final viewstate\n     */\n    private appendViewStateToForms(forms: DQ, viewState: string) {\n        forms.each((form: DQ) => {\n            let viewStateElems = form.querySelectorAll(SEL_VIEWSTATE_ELEM)\n                .orElseLazy(() => ResponseProcessor.newViewStateElement(form));\n\n            viewStateElems.attr(\"value\").value = viewState;\n        });\n    }\n\n    /**\n     * Helper to Create a new JSF ViewState Element\n     *\n     * @param parent, the parent node to attach the viewstate element to\n     * (usually a form node)\n     */\n    private static newViewStateElement(parent: DQ): DQ {\n        let newViewState = DQ.fromMarkup(HTML_VIEWSTATE);\n        newViewState.appendTo(parent);\n        return newViewState;\n    }\n\n    /**\n     * Stores certain aspects of the dom for later post processing\n     *\n     * @param updateForms the update forms which should receive standardized internal jsf data\n     * @param toBeEvaled the resulting elements which should be evaled\n     */\n    private storeForPostProcessing(updateForms: DQ, toBeEvaled: DQ) {\n        this.storeForUpdate(updateForms);\n        this.storeForEval(toBeEvaled);\n    }\n\n    /**\n     * helper to store a given form for the update post processing (viewstate)\n     *\n     * @param updateForms the dom query object pointing to the forms which need to be updated\n     */\n    private storeForUpdate(updateForms: DQ) {\n        this.internalContext.assign(UPDATE_FORMS).value.push(updateForms);\n    }\n\n    /**\n     * same for eval (js and css)\n     *\n     * @param toBeEvaled\n     */\n    private storeForEval(toBeEvaled: DQ) {\n        this.internalContext.assign(UPDATE_ELEMS).value.push(toBeEvaled);\n    }\n\n    /**\n     * check whether a given XMLQuery node is an explicit viewstate node\n     *\n     * @param node the node to check\n     * @returns true of it ii\n     */\n    private static isViewStateNode(node: XMLQuery): boolean {\n        let separatorChar = (<any>window).jsf.separatorchar;\n        return \"undefined\" != typeof node?.id?.value && (node?.id?.value == P_VIEWSTATE ||\n            node?.id?.value?.indexOf([separatorChar, P_VIEWSTATE].join(EMPTY_STR)) != -1 ||\n            node?.id?.value?.indexOf([P_VIEWSTATE, separatorChar].join(EMPTY_STR)) != -1);\n    }\n\n}","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport class Messages {\n    MSG_TEST = \"Testmessage\";\n\n    /*Messages*/\n    /** @constant */\n    MSG_DEV_MODE = \"Note, this message is only sent, because project stage is development and no \" +\n        \"other error listeners are registered.\";\n    /** @constant */\n    MSG_AFFECTED_CLASS = \"Affected Class=\";\n    /** @constant */\n    MSG_AFFECTED_METHOD = \"Affected Method=\";\n    /** @constant */\n    MSG_ERROR_NAME = \"Error Name=\";\n    /** @constant */\n    MSG_ERROR_MESSAGE = \"Error Message=\";\n    /** @constant */\n    MSG_SERVER_ERROR_NAME = \"Server Error Name=\";\n\n    /** @constant */\n    MSG_ERROR_DESC = \"Error Description=\";\n    /** @constant */\n    MSG_ERROR_NO = \"Error Number=\";\n    /** @constant */\n    MSG_ERROR_LINENO = \"Error Line Number=\";\n\n    /*Errors and messages*/\n    /** @constant */\n    ERR_FORM = \"Sourceform could not be determined, either because element is not attached to a form or we have multiple forms with named elements of the same identifier or name, stopping the ajax processing\";\n    /** @constant */\n    ERR_VIEWSTATE = \"jsf.viewState= param value not of type form!\";\n    /** @constant */\n    ERR_TRANSPORT = \"Transport type {0} does not exist\";\n    /** @constant */\n    ERR_EVT_PASS = \"an event must be passed down (either a an event object null or undefined) \";\n    /** @constant */\n    ERR_CONSTRUCT = \"Parts of the response couldn't be retrieved when constructing the event data= {0} \";\n    /** @constant */\n    ERR_MALFORMEDXML = \"The server response could not be parsed, the server has returned with a response which is not xml !\";\n    /** @constant */\n    ERR_SOURCE_FUNC = \"source cannot be a function (probably source and event were not defined or set to null\";\n    /** @constant */\n    ERR_EV_OR_UNKNOWN = \"An event object or unknown must be passed as second parameter\";\n    /** @constant */\n    ERR_SOURCE_NOSTR = \"source cannot be a string\";\n    /** @constant */\n    ERR_SOURCE_DEF_NULL = \"source must be defined or null\";\n\n    //_Lang.js\n    /** @constant */\n    ERR_MUST_STRING = \"{0}: {1} namespace must be of type String\";\n    /** @constant */\n    ERR_REF_OR_ID = \"{0}: {1} a reference node or identifier must be provided\";\n    /** @constant */\n    ERR_PARAM_GENERIC = \"{0}: parameter {1} must be of type {2}\";\n    /** @constant */\n    ERR_PARAM_STR = \"{0}: {1} param must be of type string\";\n    /** @constant */\n    ERR_PARAM_STR_RE = \"{0}: {1} param must be of type string or a regular expression\";\n    /** @constant */\n    ERR_PARAM_MIXMAPS = \"{0}: both a source as well as a destination map must be provided\";\n    /** @constant */\n    ERR_MUST_BE_PROVIDED = \"{0}: an {1} and a {2} must be provided\";\n    /** @constant */\n    ERR_MUST_BE_PROVIDED1 = \"{0}: {1} must be set\";\n\n    /** @constant */\n    ERR_REPLACE_EL = \"replaceElements called while evalNodes is not an array\";\n\n    /** @constant */\n    ERR_EMPTY_RESPONSE = \"{0}: The response cannot be null or empty!\";\n    /** @constant */\n    ERR_ITEM_ID_NOTFOUND = \"{0}: item with identifier {1} could not be found\";\n    /** @constant */\n    ERR_PPR_IDREQ = \"{0}: Error in PPR Insert, id must be present\";\n    /** @constant */\n    ERR_PPR_INSERTBEFID = \"{0}: Error in PPR Insert, before id or after id must be present\";\n    /** @constant */\n    ERR_PPR_INSERTBEFID_1 = \"{0}: Error in PPR Insert, before  node of id {1} does not exist in document\";\n    /** @constant */\n    ERR_PPR_INSERTBEFID_2 = \"{0}: Error in PPR Insert, after  node of id {1} does not exist in document\";\n\n    /** @constant */\n    ERR_PPR_DELID = \"{0}: Error in delete, id not in xml markup\";\n    /** @constant */\n    ERR_PPR_UNKNOWNCID = \"{0}:  Unknown Html-Component-ID= {1}\";\n\n    /** @constant */\n    ERR_NO_VIEWROOTATTR = \"{0}: Changing of ViewRoot attributes is not supported\";\n    /** @constant */\n    ERR_NO_HEADATTR = \"{0}: Changing of Head attributes is not supported\";\n    /** @constant */\n    ERR_RED_URL = \"{0}: Redirect without url\";\n\n    /** @constant */\n    ERR_REQ_FAILED_UNKNOWN = \"Request failed with unknown status\";\n\n    /** @constant */\n    ERR_REQU_FAILED = \"Request failed with status {0} and reason {1}\";\n\n    /** @constant */\n    UNKNOWN = \"UNKNOWN\";\n}","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\nimport {EMPTY_STR, P_VIEWSTATE} from \"./Const\";\n\nexport interface IdValueHolder {\n\n    readonly id: string;\n    readonly value: string;\n\n}\n\n/**\n * a helper class to isolate the\n * view state data processing\n */\nexport class ViewState implements IdValueHolder {\n\n    nameSpace: string;\n\n    constructor(public id: string, public value: string) {\n        let viewStatePos = id.indexOf(P_VIEWSTATE);\n        this.nameSpace = viewStatePos > 0 ? id.substr(0, viewStatePos - 1) : EMPTY_STR;\n    }\n\n    get hasNameSpace(): boolean {\n        return !!(this?.nameSpace ?? EMPTY_STR).length;\n    }\n}","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {Config, Optional, XMLQuery} from \"../../ext/monadish\";\n\nimport {Assertions} from \"../util/Assertions\";\nimport {DQ} from \"../../ext/monadish\";\nimport {\n    CTX_PARAM_MF_INTERNAL,\n    CTX_PARAM_SRC_CTL_ID,\n    CTX_PARAM_SRC_FRM_ID,\n    SEL_RESPONSE_XML,\n    SOURCE,\n    TAG_FORM,\n    UPDATE_ELEMS,\n    UPDATE_FORMS\n} from \"../core/Const\";\n\n/**\n * Resolver functions for various aspects of the response data\n *\n * stateless because it might be called from various\n * parts of the response classes\n */\n\n/**\n * fetches the response XML\n * as XML Query object\n *\n * @param request the request hosting the responseXML\n *\n * Throws an error in case of non existent or wrong xml data\n *\n */\nexport function resolveResponseXML(request: Config): XMLQuery {\n    let ret = new XMLQuery(request.getIf(SEL_RESPONSE_XML).value);\n    Assertions.assertValidXMLResponse(ret);\n\n    return ret;\n}\n\n/**\n * Splits the incoming passthrough context apart\n * in an internal and an external nomalized context\n * the internal one is just for our internal processing\n *\n * @param context the root context as associative array\n */\nexport function resolveContexts(context: { [p: string]: any }): any {\n    /**\n     * we split the context apart into the external one and\n     * some internal values\n     */\n    let externalContext = Config.fromNullable(context);\n    let internalContext = externalContext.getIf(CTX_PARAM_MF_INTERNAL);\n    if (!internalContext.isPresent()) {\n        internalContext = Config.fromNullable({});\n    }\n\n    /**\n     * prepare storage for some deferred operations\n     */\n    internalContext.assign(UPDATE_FORMS).value = [];\n    internalContext.assign(UPDATE_ELEMS).value = [];\n    return {externalContext, internalContext};\n}\n\n/**\n * fetches the source element out of our conexts\n *\n * @param context the external context which shpuld host the source id\n * @param internalContext internal passthrough fall back\n *\n */\nexport function resolveSourceElement(context: Config, internalContext: Config): DQ {\n    let elemId = resolveSourceElementId(context, internalContext);\n    return DQ.byId(elemId.value);\n}\n\n/**\n * fetches the source form if it still exists\n * also embedded forms and parent forms are taken into consideration\n * as fallbacks\n *\n * @param internalContext\n * @param elem\n */\nexport function resolveSourceForm(internalContext: Config, elem: DQ): DQ {\n    let sourceFormId = internalContext.getIf(CTX_PARAM_SRC_FRM_ID);\n    let sourceForm = new DQ(sourceFormId.isPresent() ? document.forms[sourceFormId.value] : null);\n\n    sourceForm = sourceForm.orElse(elem.parents(TAG_FORM))\n        .orElse(elem.querySelectorAll(TAG_FORM))\n        .orElse(DQ.querySelectorAll(TAG_FORM));\n\n    return sourceForm;\n}\n\nfunction resolveSourceElementId(context: Config, internalContext: Config): Optional<string> {\n    //?internal context?? used to be external one\n    return internalContext.getIf(CTX_PARAM_SRC_CTL_ID)\n        .orElseLazy(() => context.getIf(SOURCE, \"id\").value);\n}\n\n","/* Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {AsyncRunnable} from \"../util/AsyncRunnable\";\nimport {Config, DQ, Stream} from \"../../ext/monadish\";\nimport {Implementation} from \"../AjaxImpl\";\n\nimport {XhrFormData} from \"./XhrFormData\";\nimport {ErrorData} from \"./ErrorData\";\nimport {EventData} from \"./EventData\";\nimport {ExtLang} from \"../util/Lang\";\nimport {\n    BEGIN,\n    COMPLETE,\n    CONTENT_TYPE,\n    CTX_PARAM_MF_INTERNAL,\n    CTX_PARAM_PASS_THR,\n    ERROR,\n    HEAD_FACES_REQ,\n    MALFORMEDXML,\n    MULTIPART,\n    NO_TIMEOUT,\n    ON_ERROR,\n    ON_EVENT,\n    REQ_ACCEPT,\n    REQ_TYPE_GET,\n    REQ_TYPE_POST,\n    STATE_EVT_TIMEOUT,\n    STD_ACCEPT,\n    URL_ENCODED,\n    VAL_AJAX\n} from \"../core/Const\";\nimport {resolveFinalUrl, resolveHandlerFunc} from \"./RequestDataResolver\";\nimport failSaveExecute = ExtLang.failSaveExecute;\n\n/**\n * JSFed XHR Request Wrapper\n * as Asyncrunnable for our Asynchronous queue\n *\n * The idea is that we basically just enqueue\n * a single ajax request into our queue\n * and let the queue do the processing.\n *\n */\n\ndeclare let jsf: any;\n\n\n\nexport class XhrRequest implements AsyncRunnable<XMLHttpRequest> {\n\n    private responseContext: Config;\n\n    private stopProgress = false;\n\n    /**\n     * helper support so that we do not have to drag in Promise shims\n     */\n    private catchFuncs: Array<Function> = [];\n    private  thenFunc: Array<Function> = [];\n\n    /**\n     * Reqired Parameters\n     *\n     * @param source the issuing element\n     * @param sourceForm the form which is related to the issuing element\n     * @param requestContext the request context with allö pass through values\n     *\n     * Optional Parameters\n     *\n     * @param partialIdsArray an optional restricting partial ids array for encoding\n     * @param timeout optional xhr timeout\n     * @param ajaxType optional request type, default \"POST\"\n     * @param contentType optional content type, default \"application/x-www-form-urlencoded\"\n     * @param xhrObject optional xhr object which must fullfill the XMLHTTPRequest api, default XMLHttpRequest\n     */\n    constructor(\n        private source: DQ,\n        private sourceForm: DQ,\n        private requestContext: Config,\n        private internalContext: Config,\n        private partialIdsArray = [],\n        private timeout = NO_TIMEOUT,\n        private ajaxType = REQ_TYPE_POST,\n        private contentType = URL_ENCODED,\n        private xhrObject = new XMLHttpRequest()\n    ) {\n        /*\n        * we omit promises here\n        * some browsers do not support it and we do not need shim code\n        */\n        this.registerXhrCallbacks((data: any) => {this.resolve(data)}, (data: any) => {this.reject(data)});\n    }\n\n    start(): AsyncRunnable<XMLHttpRequest> {\n\n        let ignoreErr = failSaveExecute;\n        let xhrObject = this.xhrObject;\n\n        try {\n\n            let viewState = jsf.getViewState(this.sourceForm.getAsElem(0).value);\n            //encoded we need to decode\n            let formData: XhrFormData = new XhrFormData(decodeURIComponent(viewState));\n\n            this.contentType = formData.isMultipartRequest ? MULTIPART : this.contentType;\n\n            //next step the pass through parameters are merged in for post params\n            let requestContext = this.requestContext;\n            let passThroughParams = requestContext.getIf(CTX_PARAM_PASS_THR);\n            formData.shallowMerge(passThroughParams);\n\n            this.responseContext = passThroughParams.deepCopy;\n\n            //we have to shift the internal passthroughs around to build up our response context\n            let responseContext = this.responseContext;\n\n            responseContext.assign(CTX_PARAM_MF_INTERNAL).value = this.internalContext.value;\n\n            //per spec the onevent and onerrors must be passed through to the response\n            responseContext.assign(ON_EVENT).value = requestContext.getIf(ON_EVENT).value;\n            responseContext.assign(ON_ERROR).value = requestContext.getIf(ON_ERROR).value;\n\n            xhrObject.open(this.ajaxType, resolveFinalUrl(this.sourceForm, formData, this.ajaxType), true);\n\n            //adding timeout\n            this.timeout ? xhrObject.timeout = this.timeout : null;\n\n            //a bug in the xhr stub library prevents the setRequestHeader to be properly executed on fake xhr objects\n            //normal browsers should resolve this\n            //tests can quietly fail on this one\n\n            ignoreErr(() => xhrObject.setRequestHeader(CONTENT_TYPE, `${this.contentType}; charset=utf-8`));\n            ignoreErr(() => xhrObject.setRequestHeader(HEAD_FACES_REQ, VAL_AJAX));\n\n            //probably not needed anymore, will test this\n            //some webkit based mobile browsers do not follow the w3c spec of\n            // setting the accept headers automatically\n            ignoreErr(() => xhrObject.setRequestHeader(REQ_ACCEPT, STD_ACCEPT));\n\n            this.sendEvent(BEGIN);\n\n            this.sendRequest(formData);\n\n        } catch (e) {\n            //_onError//_onError\n            this.handleError(e);\n        }\n        return this;\n    }\n\n    cancel() {\n        try {\n            this.xhrObject.abort();\n        } catch (e) {\n            this.handleError(e);\n        }\n    }\n\n    resolve(data: any) {\n        Stream.of(...this.thenFunc).reduce((inputVal: any, thenFunc: any) => {\n            return thenFunc(inputVal);\n        }, data);\n    }\n\n    reject(data: any) {\n        Stream.of(...this.catchFuncs).reduce((inputVal: any, catchFunc: any) => {\n            return catchFunc(inputVal);\n        }, data);\n    }\n\n\n    catch(func: (data: any) => any): AsyncRunnable<XMLHttpRequest> {\n        //this.$promise.catch(func);\n        this.catchFuncs.push(func);\n        return this;\n    }\n\n    finally(func: () => void): AsyncRunnable<XMLHttpRequest> {\n        //no ie11 support we probably are going to revert to shims for that one\n        //(<any>this.$promise).then(func).catch(func);\n        this.catchFuncs.push(func);\n        this.thenFunc.push(func);\n        return this;\n    }\n\n    then(func: (data: any) => any): AsyncRunnable<XMLHttpRequest> {\n        //this.$promise.then(func);\n        this.thenFunc.push(func);\n        return this;\n    }\n\n    /**\n     * attaches the internal event and processing\n     * callback within the promise to our xhr object\n     *\n     * @param resolve\n     * @param reject\n     */\n    protected registerXhrCallbacks(resolve: Consumer<any>, reject: Consumer<any>) {\n        let xhrObject = this.xhrObject;\n\n        xhrObject.onabort = () => {\n            this.onAbort(resolve, reject);\n        };\n        xhrObject.ontimeout = () => {\n            this.onTimeout(resolve, reject);\n        };\n        xhrObject.onload = () => {\n            this.onSuccess(this.xhrObject, resolve, reject)\n        };\n        xhrObject.onloadend = () => {\n            this.onDone(this.xhrObject, resolve, reject);\n        };\n        xhrObject.onerror = (errorData: any) => {\n            this.onError(errorData, resolve, reject);\n        };\n    }\n\n    /*\n     * xhr processing callbacks\n     *\n     * Those methods are the callbacks called by\n     * the xhr object depending on its own state\n     */\n\n    protected onAbort(resolve: Consumer<any>, reject: Consumer<any>) {\n        reject();\n    }\n\n    protected onTimeout(resolve: Consumer<any>, reject: Consumer<any>) {\n        this.sendEvent(STATE_EVT_TIMEOUT);\n        reject();\n    }\n\n    protected onSuccess(data: any, resolve: Consumer<any>, reject: Consumer<any>) {\n\n        this.sendEvent(COMPLETE);\n\n        //malforms always result in empty response xml\n        if(!this?.xhrObject?.responseXML) {\n            this.handleMalFormedXML(resolve);\n            return;\n        }\n\n        jsf.ajax.response(this.xhrObject, this.responseContext.value ?? {});\n    }\n\n    private handleMalFormedXML(resolve: Function) {\n        this.stopProgress = true;\n        let errorData = {\n            type: ERROR,\n            status: MALFORMEDXML,\n            responseCode: 200,\n            responseText: this.xhrObject?.responseText,\n            source: {\n                id: this.source.id.value\n            }\n        };\n        try {\n            Implementation.sendError(<any>errorData);\n        } finally {\n            resolve(errorData);\n        }\n        //non blocking non clearing\n    }\n\n    protected onDone(data: any, resolve: Consumer<any>, reject: Consumer<any>) {\n        if(this.stopProgress) {\n            return;\n        }\n        resolve(data);\n    }\n\n    protected onError(errorData: any, resolve: Consumer<any>, reject: Consumer<any>) {\n        this.handleError(errorData);\n        reject();\n    }\n\n    /*\n     * other helpers\n     */\n    private sendEvent(evtType: string) {\n        let eventData = EventData.createFromRequest(this.xhrObject, this.requestContext, evtType);\n        try {\n            //user code error, we might cover\n            //this in onError but also we cannot swallow it\n            //we need to resolve the local handlers lazyly,\n            //because some frameworks might decorate them over the context in the response\n            let eventHandler = resolveHandlerFunc(this.requestContext, this.responseContext, ON_EVENT);;\n            Implementation.sendEvent(eventData,  eventHandler);\n        } catch (e) {\n            this.handleError(e);\n            throw e;\n        }\n    }\n\n    private handleError(exception) {\n        let errorData = ErrorData.fromClient(exception);\n\n        let eventHandler = resolveHandlerFunc(this.requestContext, this.responseContext, ON_ERROR);\n        Implementation.sendError(errorData, eventHandler);\n    }\n\n\n\n    protected sendRequest(formData: XhrFormData) {\n        let isPost = this.ajaxType != REQ_TYPE_GET;\n        if(formData.isMultipartRequest) {\n            this.xhrObject.send((isPost) ? formData.toFormData() : null);\n        } else {\n            this.xhrObject.send((isPost) ? formData.toString() : null);\n        }\n    }\n\n}","import {AsyncRunnable} from \"./AsyncRunnable\";\n\n\n/**\n * Asynchronous queue which starts to work\n * through the callbacks until the queue is empty\n *\n * Every callback must be of async runnable\n * which is sort of an extended promise which has\n * added a decicated cancel and start point\n *\n * This interface can be used as wrapper contract\n * for normal promises if needed.\n */\nexport class AsynchronouseQueue<T extends AsyncRunnable<any>> {\n    static EVT_NEXT = \"__mf_queue_next__\";\n\n    private runnableQueue = [];\n    private delayTimeout: number;\n\n    currentlyRunning: AsyncRunnable<any>;\n\n    constructor() {\n    }\n\n    get isEmpty(): boolean {\n        return !this.runnableQueue.length;\n    }\n\n    /**\n     * enequeues an element and starts the\n     * asynchronous work loop if not already running\n     *\n     * @param element the element to be queued and processed\n     * @param delay possible delay after our usual process or drop if something newer is incoming algorithm\n     */\n    enqueue(element: T, delay = 0) {\n        if (this.delayTimeout) {\n            clearTimeout(this.delayTimeout);\n            this.delayTimeout = null;\n        }\n        if (delay) {\n            this.delayTimeout = setTimeout(() => {\n                this.appendElement(element);\n            });\n        } else {\n            this.appendElement(element);\n        }\n    }\n\n    dequeue(): T {\n        return this.runnableQueue.shift();\n    }\n\n    cleanup() {\n        this.currentlyRunning = null;\n        this.runnableQueue.length = 0;\n    }\n\n    private appendElement(element: T) {\n        //only if the first element is added we start with a trigger\n        //otherwise a process already is running and not finished yet at that\n        //time\n        this.runnableQueue.push(element);\n        if (!this.currentlyRunning) {\n            this.runEntry();\n        }\n    }\n\n    private runEntry() {\n        if (this.isEmpty) {\n            this.currentlyRunning = null;\n            return;\n        }\n        this.currentlyRunning = this.dequeue();\n        this.currentlyRunning\n            .catch((e) => {\n                //in case of an error we always clean up the remaining calls\n                //to allow a clean recovery of the application\n                this.cleanup();\n                throw e;\n            })\n            .then(\n                //the idea is to trigger the next over an event to reduce\n                //the number of recursive calls (stacks might be limited\n                //compared to ram)\n                //naturally give we have a DOM, the DOM is the natural event dispatch system\n                //which we can use, to decouple the calls from a recursive stack call\n                //(the browser engine will take care of that)\n                () => this.callForNextElementToProcess()\n            ).start();\n    }\n\n    cancel() {\n        try {\n            if (this.currentlyRunning) {\n                this.currentlyRunning.cancel();\n            }\n        } finally {\n            this.cleanup();\n        }\n    }\n\n    private callForNextElementToProcess() {\n        this.runEntry();\n    }\n\n    private processNextElement() {\n        this.currentlyRunning = null;\n        if (!this.isEmpty) {\n            this.runEntry();\n        }\n    }\n\n}","/**\n * Typescript port of the jsf.push part in the myfaces implementation\n */\n\n//TODO still work in progress\n//this is a 1:1 port for the time being\nimport {jsf} from \"../api/Jsf\";\nimport {MAX_RECONNECT_ATTEMPTS, REASON_EXPIRED, RECONNECT_INTERVAL} from \"./core/Const\";\n\n\n/**\n * Implementation class for the push functionality\n */\nexport module PushImpl {\n\n\n\n    const URL_PROTOCOL = window.location.protocol.replace(\"http\", \"ws\") + \"//\";\n\n\n    //we expose the member variables for testing purposes\n    //they are not directly touched outside of tests\n\n    /* socket map by token */\n    export let sockets = {};\n    /* component attributes by clientId */\n    export let components = {};\n    /* client ids by token (share websocket connection) */\n    export let clientIdsByTokens = {};\n\n\n    //needed for testing\n    export function reset() {\n        sockets = {};\n        components = {}\n        clientIdsByTokens = {}\n    }\n\n    /*\n     * Api implementations, exposed functions\n     */\n\n    /**\n     *\n     * @param {function} onopen The function to be invoked when the web socket is opened.\n     * @param {function} onmessage The function to be invoked when a message is received.\n     * @param {function} onclose The function to be invoked when the web socket is closed.\n     * @param {boolean} autoconnect Whether or not to immediately open the socket. Defaults to <code>false</code>.\n     */\n    export function init(socketClientId: string,\n                         uri: string,\n                         channel: string,\n                         onopen: Function,\n                         onmessage: Function,\n                         onclose: Function,\n                         behaviorScripts: any,\n                         autoconnect: boolean) {\n        onclose = resolveFunction(onclose);\n\n        if (!window.WebSocket) { // IE6-9.\n            onclose(-1, channel);\n            return;\n        }\n\n        let channelToken = uri.substr(uri.indexOf('?') + 1);\n\n        if (!components[socketClientId]) {\n            components[socketClientId] = {\n                'channelToken': channelToken,\n                'onopen': resolveFunction(onopen),\n                'onmessage' : resolveFunction(onmessage),\n                'onclose': onclose,\n                'behaviors': behaviorScripts,\n                'autoconnect': autoconnect};\n            if (!clientIdsByTokens[channelToken]) {\n                clientIdsByTokens[channelToken] = [];\n            }\n            clientIdsByTokens[channelToken].push(socketClientId);\n            if (!sockets[channelToken]){\n                sockets[channelToken] = new Socket(channelToken,\n                    getBaseURL(uri), channel);\n            }\n        }\n\n        if (autoconnect) {\n            jsf.push.open(socketClientId);\n        }\n    }\n\n    export function open(socketClientId: string) {\n        getSocket(components?.[socketClientId]?.channelToken).open();\n    }\n\n    export function close(socketClientId: string) {\n        getSocket(components?.[socketClientId].channelToken).close();\n    }\n\n    // Private helper classes\n    // Private classes functions ----------------------------------------------------------------------------------\n    /**\n     * Creates a reconnecting web socket. When the web socket successfully connects on first attempt, then it will\n     * automatically reconnect on timeout with cumulative intervals of 500ms with a maximum of 25 attempts (~3 minutes).\n     * The <code>onclose</code> function will be called with the error code of the last attempt.\n     * @constructor\n     * @param {string} channelToken the channel token associated with this websocket connection\n     * @param {string} url The URL of the web socket\n     * @param {string} channel The name of the web socket channel.\n     */\n\n    class Socket {\n\n        socket: WebSocket;\n        reconnectAttempts = 0;\n\n        constructor(private channelToken: string, private url: string, private channel: string) {\n        }\n\n        open() {\n            if (this.socket && this.socket.readyState == 1) {\n                return;\n            }\n            this.socket = new WebSocket(this.url);\n\n            this.bindCallbacks();\n        }\n\n        onopen(event: any) {\n            if (!this.reconnectAttempts) {\n                let clientIds = clientIdsByTokens[this.channelToken];\n                for (let i = clientIds.length - 1; i >= 0; i--) {\n                    let socketClientId = clientIds[i];\n                    components[socketClientId]['onopen'](this.channel);\n                }\n            }\n            this.reconnectAttempts = 0;\n        }\n\n        onmmessage(event: any) {\n            let message = JSON.parse(event.data);\n            for (let i = clientIdsByTokens[this.channelToken].length - 1; i >= 0; i--) {\n                let socketClientId = clientIdsByTokens[this.channelToken][i];\n                if (document.getElementById(socketClientId)) {\n                    try {\n                        components[socketClientId]['onmessage'](message, this.channel, event);\n                    } catch (e) {\n                        //Ignore\n                    }\n                    let behaviors = components[socketClientId]['behaviors'];\n                    let functions = behaviors[message];\n                    if (functions && functions.length) {\n                        for (let j = 0; j < functions.length; j++) {\n                            try {\n                                functions[j](null);\n                            } catch (e) {\n                                //Ignore\n                            }\n                        }\n                    }\n                } else {\n                    clientIdsByTokens[this.channelToken].splice(i, 1);\n                }\n            }\n            if (clientIdsByTokens[this.channelToken].length == 0) {\n                //tag dissapeared\n                this.close();\n            }\n        }\n\n        onclose(event: any) {\n            if (!this.socket\n                || (event.code == 1000 && event.reason == REASON_EXPIRED)\n                || (event.code == 1008)\n                || (!this.reconnectAttempts)\n                || (this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS)) {\n                let clientIds = clientIdsByTokens[this.channelToken];\n                for (let i = clientIds.length - 1; i >= 0; i--) {\n                    let socketClientId = clientIds[i];\n                    components[socketClientId]['onclose'](event?.code, this?.channel, event);\n                }\n            } else {\n                setTimeout(this.open, RECONNECT_INTERVAL * this.reconnectAttempts++);\n            }\n        };\n\n        close() {\n            if (this.socket) {\n                let s = this.socket;\n                this.socket = null;\n                s.close();\n            }\n        }\n\n        /**\n         * bind the callbacks to the socket callbacks\n         */\n        private bindCallbacks() {\n            this.socket.onopen = (event: Event) => this.onopen(event);\n            this.socket.onmessage = (event: Event) => this.onmmessage(event);\n            this.socket.onclose = (event: Event) => this.onclose(event);\n        }\n    }\n\n    // Private static functions ---------------------------------------------------------------------------------------\n\n    function getBaseURL(url: string) {\n        if (url.indexOf(\"://\") < 0) {\n            let base = window.location.hostname + \":\" + window.location.port;\n            return URL_PROTOCOL + base + url;\n        } else {\n            return url;\n        }\n    }\n\n    /**\n     * Get socket associated with given channelToken.\n     * @param {string} channelToken The name of the web socket channelToken.\n     * @return {Socket} Socket associated with given channelToken.\n     * @throws {Error} When channelToken is unknown, you may need to initialize\n     *                 it first via <code>init()</code> function.\n     */\n    function getSocket(channelToken: string): Socket {\n        let socket = sockets[channelToken];\n        if (socket) {\n            return socket;\n        } else {\n            throw new Error(\"Unknown channelToken: \" + channelToken);\n        }\n    }\n\n    function resolveFunction(fn: Function | string = () => {\n    }): Function {\n        return <Function>((typeof fn !== \"function\") && (fn = window[fn]), fn);\n    }\n\n}"],"sourceRoot":""}
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/js/tobago-myfaces.js b/tobago-theme/tobago-theme-standard/src/main/npm/js/tobago-myfaces.js
deleted file mode 100644
index d5a6849..0000000
--- a/tobago-theme/tobago-theme-standard/src/main/npm/js/tobago-myfaces.js
+++ /dev/null
@@ -1,6521 +0,0 @@
-(function(e, a) { for(var i in a) e[i] = a[i]; }(window, /******/ (function(modules) { // webpackBootstrap
-  /******/ 	// The module cache
-  /******/ 	var installedModules = {};
-  /******/
-  /******/ 	// The require function
-  /******/ 	function __webpack_require__(moduleId) {
-    /******/
-    /******/ 		// Check if module is in cache
-    /******/ 		if(installedModules[moduleId]) {
-      /******/ 			return installedModules[moduleId].exports;
-      /******/ 		}
-    /******/ 		// Create a new module (and put it into the cache)
-    /******/ 		var module = installedModules[moduleId] = {
-      /******/ 			i: moduleId,
-      /******/ 			l: false,
-      /******/ 			exports: {}
-      /******/ 		};
-    /******/
-    /******/ 		// Execute the module function
-    /******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-    /******/
-    /******/ 		// Flag the module as loaded
-    /******/ 		module.l = true;
-    /******/
-    /******/ 		// Return the exports of the module
-    /******/ 		return module.exports;
-    /******/ 	}
-  /******/
-  /******/
-  /******/ 	// expose the modules object (__webpack_modules__)
-  /******/ 	__webpack_require__.m = modules;
-  /******/
-  /******/ 	// expose the module cache
-  /******/ 	__webpack_require__.c = installedModules;
-  /******/
-  /******/ 	// define getter function for harmony exports
-  /******/ 	__webpack_require__.d = function(exports, name, getter) {
-    /******/ 		if(!__webpack_require__.o(exports, name)) {
-      /******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
-      /******/ 		}
-    /******/ 	};
-  /******/
-  /******/ 	// define __esModule on exports
-  /******/ 	__webpack_require__.r = function(exports) {
-    /******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
-      /******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
-      /******/ 		}
-    /******/ 		Object.defineProperty(exports, '__esModule', { value: true });
-    /******/ 	};
-  /******/
-  /******/ 	// create a fake namespace object
-  /******/ 	// mode & 1: value is a module id, require it
-  /******/ 	// mode & 2: merge all properties of value into the ns
-  /******/ 	// mode & 4: return value when already ns object
-  /******/ 	// mode & 8|1: behave like require
-  /******/ 	__webpack_require__.t = function(value, mode) {
-    /******/ 		if(mode & 1) value = __webpack_require__(value);
-    /******/ 		if(mode & 8) return value;
-    /******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
-    /******/ 		var ns = Object.create(null);
-    /******/ 		__webpack_require__.r(ns);
-    /******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
-    /******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
-    /******/ 		return ns;
-    /******/ 	};
-  /******/
-  /******/ 	// getDefaultExport function for compatibility with non-harmony modules
-  /******/ 	__webpack_require__.n = function(module) {
-    /******/ 		var getter = module && module.__esModule ?
-        /******/ 			function getDefault() { return module['default']; } :
-        /******/ 			function getModuleExports() { return module; };
-    /******/ 		__webpack_require__.d(getter, 'a', getter);
-    /******/ 		return getter;
-    /******/ 	};
-  /******/
-  /******/ 	// Object.prototype.hasOwnProperty.call
-  /******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
-  /******/
-  /******/ 	// __webpack_public_path__
-  /******/ 	__webpack_require__.p = "";
-  /******/
-  /******/
-  /******/ 	// Load entry module and return exports
-  /******/ 	return __webpack_require__(__webpack_require__.s = "./src/main/typescript/api/Jsf.ts");
-  /******/ })
-/************************************************************************/
-/******/ ({
-
-  /***/ "./src/main/typescript/api/Jsf.ts":
-  /*!****************************************!*\
-  !*** ./src/main/typescript/api/Jsf.ts ***!
-  \****************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    var __spreadArrays = (this && this.__spreadArrays) || function () {
-      for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
-      for (var r = Array(s), k = 0, i = 0; i < il; i++)
-        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
-          r[k] = a[j];
-      return r;
-    };
-    var _a, _b, _c;
-    Object.defineProperty(exports, "__esModule", { value: true });
-///<reference path='./ApiInterfaces.ts'/>
-///<reference types='../../types/typedefs'/>
-    var AjaxImpl_1 = __webpack_require__(/*! ../impl/AjaxImpl */ "./src/main/typescript/impl/AjaxImpl.ts");
-    var PushImpl_1 = __webpack_require__(/*! ../impl/PushImpl */ "./src/main/typescript/impl/PushImpl.ts");
-    var mf_impl = (_c = (_b = (_a = window) === null || _a === void 0 ? void 0 : _a.myfaces) === null || _b === void 0 ? void 0 : _b._impl, (_c !== null && _c !== void 0 ? _c : {}));
-    var jsf;
-    (function (jsf) {
-      "use strict";
-      /*
-     * Version of the implementation for the jsf.js.
-     * <p />
-     * as specified within the jsf specifications jsf.html:
-     * <ul>
-     * <li>left two digits major release number</li>
-     * <li>middle two digits minor spec release number</li>
-     * <li>right two digits bug release number</li>
-     * </ul>
-     * @constant
-     */
-      jsf.specversion = 220000;
-      /**
-       * Implementation version as specified within the jsf specification.
-       * <p />
-       * A number increased with every implementation version
-       * and reset by moving to a new spec release number
-       *
-       * @constant
-       */
-      jsf.implversion = 0;
-      /**
-       * SeparatorChar as defined by UINamingContainer.getNamingContainerSeparatorChar()
-       * @type {Char}
-       */
-      jsf.separatorchar = getSeparatorChar();
-      /**
-       * This method is responsible for the return of a given project stage as defined
-       * by the jsf specification.
-       * <p/>
-       * Valid return values are:
-       * <ul>
-       *     <li>&quot;Production&quot;</li>
-       *     <li>&quot;Development&quot;</li>
-       *     <li>&quot;SystemTest&quot;</li>
-       *     <li>&quot;UnitTest&quot;</li>
-       * </li>
-       *
-       * @return {String} the current project state emitted by the server side method:
-       * <i>javax.faces.application.Application.getProjectStage()</i>
-       */
-      function getProjectStage() {
-        return AjaxImpl_1.Implementation.getProjectStage();
-      }
-      jsf.getProjectStage = getProjectStage;
-      /**
-       * collect and encode data for a given form element (must be of type form)
-       * find the javax.faces.ViewState element and encode its value as well!
-       * return a concatenated string of the encoded values!
-       *
-       * @throws an exception in case of the given element not being of type form!
-       * https://issues.apache.org/jira/browse/MYFACES-2110
-       */
-      function getViewState(formElement) {
-        return AjaxImpl_1.Implementation.getViewState(formElement);
-      }
-      jsf.getViewState = getViewState;
-      /**
-       * returns the window identifier for the given node / window
-       * @param {optional String | DomNode}  the node for which the client identifier has to be determined
-       * @return the window identifier or null if none is found
-       */
-      function getClientWindow(rootNode) {
-        return AjaxImpl_1.Implementation.getClientWindow(rootNode);
-      }
-      jsf.getClientWindow = getClientWindow;
-      //private helper functions
-      function getSeparatorChar() {
-        return AjaxImpl_1.Implementation.getSeparatorChar();
-      }
-      var ajax;
-      (function (ajax) {
-        "use strict";
-        /**
-         * this function has to send the ajax requests
-         *
-         * following requestInternal conditions must be met:
-         * <ul>
-         *  <li> the requestInternal must be sent asynchronously! </li>
-         *  <li> the requestInternal must be a POST!!! requestInternal </li>
-         *  <li> the requestInternal url must be the form action attribute </li>
-         *  <li> all requests must be queued with a client side requestInternal queue to ensure the requestInternal ordering!</li>
-         * </ul>
-         *
-         * @param {String|Node} element: any dom element no matter being it html or jsf, from which the event is emitted
-         * @param {EVENT} event: any javascript event supported by that object
-         * @param {Map} options : map of options being pushed into the ajax cycle
-         */
-        function request(element, event, options) {
-          AjaxImpl_1.Implementation.request(element, event, options);
-          //Implementation.getInstance().requestInternal(element, event, options);
-        }
-        ajax.request = request;
-        /**
-         * response handler
-         * @param request the request object having triggered this response
-         * @param context the request context
-         *
-         * TODO add info on what can be in the context
-         */
-        function response(request, context) {
-          AjaxImpl_1.Implementation.response(request, context);
-        }
-        ajax.response = response;
-        /**
-         * Adds an error handler to our global error queue.
-         * the error handler must be of the format <i>function errorListener(&lt;errorData&gt;)</i>
-         * with errorData being of following format:
-         * <ul>
-         *     <li> errorData.type : &quot;error&quot;</li>
-         *     <li> errorData.status : the error status message</li>
-         *     <li> errorData.serverErrorName : the server error name in case of a server error</li>
-         *     <li> errorData.serverErrorMessage : the server error message in case of a server error</li>
-         *     <li> errorData.source  : the issuing source element which triggered the requestInternal </li>
-         *     <li> eventData.responseCode: the response code (aka http requestInternal response code, 401 etc...) </li>
-         *     <li> eventData.responseText: the requestInternal response text </li>
-         *     <li> eventData.responseXML: the requestInternal response xml </li>
-         * </ul>
-         *
-         * @param {function} errorListener error handler must be of the format <i>function errorListener(&lt;errorData&gt;)</i>
-         */
-        function addOnError(errorFunc) {
-          AjaxImpl_1.Implementation.addOnError(errorFunc);
-        }
-        ajax.addOnError = addOnError;
-        /**
-         * Adds a global event listener to the ajax event queue. The event listener must be a function
-         * of following format: <i>function eventListener(&lt;eventData&gt;)</i>
-         *
-         * @param {function} eventListener event must be of the format <i>function eventListener(&lt;eventData&gt;)</i>
-         */
-        function addOnEvent(eventFunc) {
-          AjaxImpl_1.Implementation.addOnEvent(eventFunc);
-        }
-        ajax.addOnEvent = addOnEvent;
-      })(ajax = jsf.ajax || (jsf.ajax = {}));
-      var util;
-      (function (util) {
-        /**
-         * varargs function which executes a chain of code (functions or any other code)
-         *
-         * if any of the code returns false, the execution
-         * is terminated prematurely skipping the rest of the code!
-         *
-         * @param {DomNode} source, the callee object
-         * @param {Event} event, the event object of the callee event triggering this function
-         * @param funcs ... arbitrary array of functions or strings
-         * @returns true if the chain has succeeded false otherwise
-         */
-        function chain(source, event) {
-          var funcs = [];
-          for (var _i = 2; _i < arguments.length; _i++) {
-            funcs[_i - 2] = arguments[_i];
-          }
-          return AjaxImpl_1.Implementation.chain.apply(AjaxImpl_1.Implementation, __spreadArrays([source, event], funcs));
-        }
-        util.chain = chain;
-      })(util = jsf.util || (jsf.util = {}));
-      var push;
-      (function (push) {
-        /**
-         * @param {function} onopen The function to be invoked when the web socket is opened.
-         * @param {function} onmessage The function to be invoked when a message is received.
-         * @param {function} onclose The function to be invoked when the web socket is closed.
-         * @param {boolean} autoconnect Whether or not to immediately open the socket. Defaults to <code>false</code>.
-         */
-        function init(socketClientId, uri, channel, onopen, onmessage, onclose, behaviorScripts, autoconnect) {
-          PushImpl_1.PushImpl.init(socketClientId, uri, channel, onopen, onmessage, onclose, behaviorScripts, autoconnect);
-        }
-        push.init = init;
-        /**
-         * Open the web socket on the given channel.
-         * @param {string} channel The name of the web socket channel.
-         * @throws {Error} When channel is unknown.
-         */
-        function open(socketClientId) {
-          PushImpl_1.PushImpl.open(socketClientId);
-        }
-        push.open = open;
-        /**
-         * Close the web socket on the given channel.
-         * @param {string} channel The name of the web socket channel.
-         * @throws {Error} When channel is unknown.
-         */
-        function close(socketClientId) {
-          PushImpl_1.PushImpl.close(socketClientId);
-        }
-        push.close = close;
-      })(push = jsf.push || (jsf.push = {}));
-      //We hook the old namespace system into our npm system
-      //if ("undefined" == window.jsf) {
-      //    window.jsf = jsf;
-      //}
-    })(jsf = exports.jsf || (exports.jsf = {}));
-//fullfill the window contract
-    var myfaces;
-    (function (myfaces) {
-      var _a, _b, _c;
-      //legacy compatibility
-      myfaces._impl = mf_impl;
-      /**
-       * AB function similar to mojarra and Primefaces
-       * not part of the spec but a convenience accessor method
-       * Code provided by Thomas Andraschko
-       *
-       * @param source the event source
-       * @param event the event
-       * @param eventName event name for java.javax.faces.behavior.evemnt
-       * @param execute execute list as passed down in jsf.ajax.request
-       * @param render
-       * @param options
-       */
-      function ab(source, event, eventName, execute, render, options) {
-        if (options === void 0) { options = {}; }
-        if (eventName) {
-          options["javax.faces.behavior.event"] = eventName;
-        }
-        if (execute) {
-          options["execute"] = execute;
-        }
-        if (render) {
-          options["render"] = render;
-        }
-        jsf.ajax.request(source, event, options);
-      }
-      myfaces.ab = ab;
-      //We hook the old namespace system into our npm system
-      if ("undefined" == ((_b = (_a = window) === null || _a === void 0 ? void 0 : _a.myfaces) === null || _b === void 0 ? void 0 : _b.ab)) {
-        window["myfaces"] = (_c = window.myfaces, (_c !== null && _c !== void 0 ? _c : {}));
-        window.myfaces["ab"] = ab;
-      }
-    })(myfaces = exports.myfaces || (exports.myfaces = {}));
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/api/Myfaces.ts":
-  /*!********************************************!*\
-  !*** ./src/main/typescript/api/Myfaces.ts ***!
-  \********************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var myfaces;
-    (function (myfaces) {
-      var ConfigHolder = /** @class */ (function () {
-        function ConfigHolder() {
-          this.projectStage = null;
-          this.separator = null;
-        }
-        return ConfigHolder;
-      }());
-      myfaces.ConfigHolder = ConfigHolder;
-      myfaces.config = new ConfigHolder();
-      //if (window && "undefined" == typeof window.myfaces) {
-      //    window.myfaces = myfaces;
-      //}
-    })(myfaces = exports.myfaces || (exports.myfaces = {}));
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/ext/monadish/DomQuery.ts":
-  /*!******************************************************!*\
-  !*** ./src/main/typescript/ext/monadish/DomQuery.ts ***!
-  \******************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    var __extends = (this && this.__extends) || (function () {
-      var extendStatics = function (d, b) {
-        extendStatics = Object.setPrototypeOf ||
-            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
-        return extendStatics(d, b);
-      };
-      return function (d, b) {
-        extendStatics(d, b);
-        function __() { this.constructor = d; }
-        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-      };
-    })();
-    var __spreadArrays = (this && this.__spreadArrays) || function () {
-      for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
-      for (var r = Array(s), k = 0, i = 0; i < il; i++)
-        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
-          r[k] = a[j];
-      return r;
-    };
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var Monad_1 = __webpack_require__(/*! ./Monad */ "./src/main/typescript/ext/monadish/Monad.ts");
-    var Stream_1 = __webpack_require__(/*! ./Stream */ "./src/main/typescript/ext/monadish/Stream.ts");
-    var Lang_1 = __webpack_require__(/*! ./Lang */ "./src/main/typescript/ext/monadish/Lang.ts");
-    var trim = Lang_1.Lang.trim;
-    var objToArray = Lang_1.Lang.objToArray;
-    var isString = Lang_1.Lang.isString;
-    var equalsIgnoreCase = Lang_1.Lang.equalsIgnoreCase;
-// @ts-ignore supression needed here due to fromnullable
-    var ElementAttribute = /** @class */ (function (_super) {
-      __extends(ElementAttribute, _super);
-      function ElementAttribute(element, name, defaultVal) {
-        if (defaultVal === void 0) { defaultVal = null; }
-        var _this = _super.call(this, element, name) || this;
-        _this.element = element;
-        _this.name = name;
-        _this.defaultVal = defaultVal;
-        return _this;
-      }
-      Object.defineProperty(ElementAttribute.prototype, "value", {
-        get: function () {
-          var _a;
-          var val = (_a = this.element.get(0)).orElse.apply(_a, []).values;
-          if (!val.length) {
-            return this.defaultVal;
-          }
-          return val[0].getAttribute(this.name);
-        },
-        set: function (value) {
-          var _a;
-          var val = (_a = this.element.get(0)).orElse.apply(_a, []).values;
-          for (var cnt = 0; cnt < val.length; cnt++) {
-            val[cnt].setAttribute(this.name, value);
-          }
-          val[0].setAttribute(this.name, value);
-        },
-        enumerable: true,
-        configurable: true
-      });
-      ElementAttribute.prototype.getClass = function () {
-        return ElementAttribute;
-      };
-      ElementAttribute.fromNullable = function (value, valueKey) {
-        if (valueKey === void 0) { valueKey = "value"; }
-        return new ElementAttribute(value, valueKey);
-      };
-      return ElementAttribute;
-    }(Monad_1.ValueEmbedder));
-    exports.ElementAttribute = ElementAttribute;
-    /**
-     * small helper for the specialized jsf case
-     * @param src
-     * @constructor
-     */
-    var DEFAULT_JSF_WHITELIST = function (src) {
-      return (src.indexOf("ln=scripts") == -1 &&
-          src.indexOf("ln=javax.faces") == -1) ||
-          (src.indexOf("/jsf.js") == -1 &&
-              src.indexOf("/jsf-uncompressed.js") == -1);
-    };
-    /**
-     * Monadic DomNode representation, ala jquery
-     * This is a thin wrapper over querySelectorAll
-     * to get slim monadic support
-     * to reduce implementation code on the users side.
-     * This is vital for frameworks which want to rely on
-     * plain dom but still do not want to lose
-     * the reduced code footprint of querying dom trees and traversing
-     * by using functional patterns.
-     *
-     * Also a few convenience methods are added to reduce
-     * the code footprint of standard dom processing
-     * operations like eval
-     *
-     * TODO add jquery fallback support, since it is supported
-     * in most older systems
-     * Note parts of this code still stem from the Dom.js I have written 10 years
-     * ago, those parts look a little bit ancient and will be replaced over time.
-     *
-     */
-    var DomQuery = /** @class */ (function () {
-      function DomQuery() {
-        var _a;
-        var rootNode = [];
-        for (var _i = 0; _i < arguments.length; _i++) {
-          rootNode[_i] = arguments[_i];
-        }
-        this.rootNode = [];
-        this.pos = -1;
-        this._limits = -1;
-        if (Monad_1.Optional.fromNullable(rootNode).isAbsent() || !rootNode.length) {
-          return;
-        }
-        else {
-          //we need to flatten out the arrays
-          for (var cnt = 0; cnt < rootNode.length; cnt++) {
-            if (isString(rootNode[cnt])) {
-              var foundElement = DomQuery.querySelectorAll(rootNode[cnt]);
-              if (!foundElement.isAbsent()) {
-                rootNode.push.apply(rootNode, foundElement.values);
-              }
-            }
-            else if (rootNode[cnt] instanceof DomQuery) {
-              (_a = this.rootNode).push.apply(_a, rootNode[cnt].values);
-            }
-            else {
-              this.rootNode.push(rootNode[cnt]);
-            }
-          }
-        }
-      }
-      Object.defineProperty(DomQuery.prototype, "value", {
-        /**
-         * returns the first element
-         */
-        get: function () {
-          return this.getAsElem(0);
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(DomQuery.prototype, "values", {
-        get: function () {
-          return this.allElems();
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(DomQuery.prototype, "id", {
-        /**
-         * returns the id of the first element
-         */
-        get: function () {
-          return new ElementAttribute(this.get(0), "id");
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(DomQuery.prototype, "length", {
-        /**
-         * length of the entire query set
-         */
-        get: function () {
-          return this.rootNode.length;
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(DomQuery.prototype, "tagName", {
-        /**
-         * convenience method for tagName
-         */
-        get: function () {
-          return this.getAsElem(0).getIf("tagName");
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(DomQuery.prototype, "nodeName", {
-        /**
-         * convenience method for nodeName
-         */
-        get: function () {
-          return this.getAsElem(0).getIf("nodeName");
-        },
-        enumerable: true,
-        configurable: true
-      });
-      DomQuery.prototype.isTag = function (tagName) {
-        return !this.isAbsent()
-            && (this.nodeName.orElse("__none___")
-                    .value.toLowerCase() == tagName.toLowerCase()
-                || this.tagName.orElse("__none___")
-                    .value.toLowerCase() == tagName.toLowerCase());
-      };
-      Object.defineProperty(DomQuery.prototype, "type", {
-        /**
-         * convenience property for type
-         *
-         * returns null in case of no type existing otherwise
-         * the type of the first element
-         */
-        get: function () {
-          return this.getAsElem(0).getIf("type");
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(DomQuery.prototype, "name", {
-        /**
-         * convenience property for name
-         *
-         * returns null in case of no type existing otherwise
-         * the name of the first element
-         */
-        get: function () {
-          return new Monad_1.ValueEmbedder(this.getAsElem(0).value, "name");
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(DomQuery.prototype, "inputValue", {
-        /**
-         * convenience property for value
-         *
-         * returns null in case of no type existing otherwise
-         * the value of the first element
-         */
-        get: function () {
-          if (this.getAsElem(0).getIf("value").isPresent()) {
-            return new Monad_1.ValueEmbedder(this.getAsElem(0).value);
-          }
-          else {
-            return Monad_1.ValueEmbedder.absent;
-          }
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(DomQuery.prototype, "checked", {
-        get: function () {
-          return Stream_1.Stream.of.apply(Stream_1.Stream, this.values).allMatch(function (el) { return !!el.checked; });
-        },
-        set: function (newChecked) {
-          this.eachElem(function (el) { return el.checked = newChecked; });
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(DomQuery.prototype, "elements", {
-        get: function () {
-          var _this = this;
-          var elements = this.stream.flatMap(function (item) {
-            var formElement = item.value.value;
-            return new Stream_1.Stream(formElement.elements ? objToArray(formElement.elements) : []);
-          }).filter(function (item) { return !!item; }).collect(new DomQueryCollector());
-          return elements
-              .orElseLazy(function () { return _this.querySelectorAll("input, select, textarea, fieldset"); });
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(DomQuery.prototype, "disabled", {
-        /**
-         * todo align this api with the rest of the apis
-         */
-        get: function () {
-          return this.attr("disabled").isPresent();
-        },
-        set: function (disabled) {
-          // this.attr("disabled").value = disabled + "";
-          if (!disabled) {
-            this.removeAttribute("disabled");
-          }
-          else {
-            this.attr("disabled").value = "disabled";
-          }
-        },
-        enumerable: true,
-        configurable: true
-      });
-      DomQuery.prototype.removeAttribute = function (name) {
-        this.eachElem(function (item) { return item.removeAttribute(name); });
-      };
-      Object.defineProperty(DomQuery.prototype, "childNodes", {
-        get: function () {
-          var childNodeArr = [];
-          this.eachElem(function (item) {
-            childNodeArr = childNodeArr.concat(objToArray(item.childNodes));
-          });
-          return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], childNodeArr)))();
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(DomQuery.prototype, "stream", {
-        /**
-         * binding into stream
-         */
-        get: function () {
-          return new (Stream_1.Stream.bind.apply(Stream_1.Stream, __spreadArrays([void 0], this.asArray)))();
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(DomQuery.prototype, "lazyStream", {
-        /**
-         * fetches a lazy stream representation
-         * lazy should be applied if you have some filters etc
-         * in between, this can reduce the number of post filter operations
-         * and ram usage
-         * significantly because the operations are done lazily and stop
-         * once they hit a dead end.
-         */
-        get: function () {
-          return Stream_1.LazyStream.ofStreamDataSource(this);
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(DomQuery.prototype, "asArray", {
-        get: function () {
-          var ret = [];
-          this.each(function (item) {
-            ret.push(item);
-          });
-          return ret;
-        },
-        enumerable: true,
-        configurable: true
-      });
-      /**
-       * easy query selector all producer
-       *
-       * @param selector the selector
-       * @returns a results dom query object
-       */
-      DomQuery.querySelectorAll = function (selector) {
-        return new DomQuery(document).querySelectorAll(selector);
-      };
-      /**
-       * byId producer
-       *
-       * @param selector id
-       * @return a DomQuery containing the found elements
-       */
-      DomQuery.byId = function (selector) {
-        if (isString(selector)) {
-          return new DomQuery(document).byId(selector);
-        }
-        else {
-          return new DomQuery(selector);
-        }
-      };
-      /**
-       * byTagName producer
-       *
-       * @param selector name
-       * @return a DomQuery containing the found elements
-       */
-      DomQuery.byTagName = function (selector) {
-        if (isString(selector)) {
-          return new DomQuery(document).byTagName(selector);
-        }
-        else {
-          return new DomQuery(selector);
-        }
-      };
-      DomQuery.globalEval = function (code, nonce) {
-        return new DomQuery(document).globalEval(code, nonce);
-      };
-      /**
-       * builds the ie nodes properly in a placeholder
-       * and bypasses a non script insert bug that way
-       * @param markup the marku code
-       */
-      DomQuery.fromMarkup = function (markup) {
-        //https://developer.mozilla.org/de/docs/Web/API/DOMParser license creative commons
-        var doc = document.implementation.createHTMLDocument("");
-        markup = trim(markup);
-        var lowerMarkup = markup.toLowerCase();
-        if (lowerMarkup.indexOf('<!doctype') != -1 ||
-            lowerMarkup.indexOf('<html') != -1 ||
-            lowerMarkup.indexOf('<head') != -1 || //TODO proper regexps here to avoid embedded tags with same element names to be triggered
-            lowerMarkup.indexOf('<body') != -1) {
-          doc.documentElement.innerHTML = markup;
-          return new DomQuery(doc.documentElement);
-        }
-        else {
-          var startsWithTag = function (str, tagName) {
-            var tag1 = ["<", tagName, ">"].join("");
-            var tag2 = ["<", tagName, " "].join("");
-            return (str.indexOf(tag1) == 0) || (str.indexOf(tag2) == 0);
-          };
-          var dummyPlaceHolder = new DomQuery(document.createElement("div"));
-          //table needs special treatment due to the browsers auto creation
-          if (startsWithTag(lowerMarkup, "thead") || startsWithTag(lowerMarkup, "tbody")) {
-            dummyPlaceHolder.html("<table>" + markup + "</table>");
-            return dummyPlaceHolder.querySelectorAll("table").get(0).childNodes.detach();
-          }
-          else if (startsWithTag(lowerMarkup, "tfoot")) {
-            dummyPlaceHolder.html("<table><thead></thead><tbody><tbody" + markup + "</table>");
-            return dummyPlaceHolder.querySelectorAll("table").get(2).childNodes.detach();
-          }
-          else if (startsWithTag(lowerMarkup, "tr")) {
-            dummyPlaceHolder.html("<table><tbody>" + markup + "</tbody></table>");
-            return dummyPlaceHolder.querySelectorAll("tbody").get(0).childNodes.detach();
-          }
-          else if (startsWithTag(lowerMarkup, "td")) {
-            dummyPlaceHolder.html("<table><tbody><tr>" + markup + "</tr></tbody></table>");
-            return dummyPlaceHolder.querySelectorAll("tr").get(0).childNodes.detach();
-          }
-          dummyPlaceHolder.html(markup);
-          return dummyPlaceHolder.childNodes.detach();
-        }
-      };
-      /**
-       * returns the nth element as domquery
-       * from the internal elements
-       * note if you try to reach a non existing element position
-       * you will get back an absent entry
-       *
-       * @param index the nth index
-       */
-      DomQuery.prototype.get = function (index) {
-        return (index < this.rootNode.length) ? new DomQuery(this.rootNode[index]) : DomQuery.absent;
-      };
-      /**
-       * returns the nth element as optional of an Element object
-       * @param index the number from the index
-       * @param defaults the default value if the index is overrun default Optional.absent
-       */
-      DomQuery.prototype.getAsElem = function (index, defaults) {
-        if (defaults === void 0) { defaults = Monad_1.Optional.absent; }
-        return (index < this.rootNode.length) ? Monad_1.Optional.fromNullable(this.rootNode[index]) : defaults;
-      };
-      /**
-       * returns the value array< of all elements
-       */
-      DomQuery.prototype.allElems = function () {
-        return this.rootNode;
-      };
-      /**
-       * absent no values reached?
-       */
-      DomQuery.prototype.isAbsent = function () {
-        return this.length == 0;
-      };
-      /**
-       * should make the code clearer
-       * note if you pass a function
-       * this refers to the active dopmquery object
-       */
-      DomQuery.prototype.isPresent = function (presentRunnable) {
-        var absent = this.isAbsent();
-        if (!absent && presentRunnable) {
-          presentRunnable.call(this, this);
-        }
-        return !absent;
-      };
-      /**
-       * should make the code clearer
-       * note if you pass a function
-       * this refers to the active dopmquery object
-       *
-       *
-       * @param presentRunnable
-       */
-      DomQuery.prototype.ifPresentLazy = function (presentRunnable) {
-        if (presentRunnable === void 0) { presentRunnable = function () {
-        }; }
-        this.isPresent.call(this, presentRunnable);
-        return this;
-      };
-      /**
-       * remove all affected nodes from this query object from the dom tree
-       */
-      DomQuery.prototype.delete = function () {
-        this.eachElem(function (node) {
-          if (node.parentNode) {
-            node.parentNode.removeChild(node);
-          }
-        });
-      };
-      /**
-       * query selector all on the existing dom query object
-       *
-       * @param selector the standard selector
-       * @return a DomQuery with the results
-       */
-      DomQuery.prototype.querySelectorAll = function (selector) {
-        var _a, _b, _c;
-        if (!((_b = (_a = this) === null || _a === void 0 ? void 0 : _a.rootNode) === null || _b === void 0 ? void 0 : _b.length)) {
-          return this;
-        }
-        var nodes = [];
-        for (var cnt = 0; cnt < this.rootNode.length; cnt++) {
-          if (!((_c = this.rootNode[cnt]) === null || _c === void 0 ? void 0 : _c.querySelectorAll)) {
-            continue;
-          }
-          var res = this.rootNode[cnt].querySelectorAll(selector);
-          nodes = nodes.concat(objToArray(res));
-        }
-        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], nodes)))();
-      };
-      /**
-       * core byId method
-       * @param id the id to search for
-       * @param includeRoot also match the root element?
-       */
-      DomQuery.prototype.byId = function (id, includeRoot) {
-        var _a;
-        var res = [];
-        for (var cnt = 0; includeRoot && cnt < this.rootNode.length; cnt++) {
-          if (((_a = this.rootNode[cnt]) === null || _a === void 0 ? void 0 : _a.id) == id) {
-            res.push(new DomQuery(this.rootNode[cnt]));
-          }
-        }
-        //for some strange kind of reason the # selector fails
-        //on hidden elements we use the attributes match selector
-        //that works
-        res = res.concat(this.querySelectorAll("[id=\"" + id + "\"]"));
-        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], res)))();
-      };
-      /**
-       * same as byId just for the tag name
-       * @param tagName
-       * @param includeRoot
-       */
-      DomQuery.prototype.byTagName = function (tagName, includeRoot) {
-        var _a;
-        var res = [];
-        for (var cnt = 0; includeRoot && cnt < this.rootNode.length; cnt++) {
-          if (((_a = this.rootNode[cnt]) === null || _a === void 0 ? void 0 : _a.tagName) == tagName) {
-            res.push(new DomQuery(this.rootNode[cnt]));
-          }
-        }
-        res = res.concat(this.querySelectorAll(tagName));
-        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], res)))();
-      };
-      /**
-       * attr accessor, usage myQuery.attr("class").value = "bla"
-       * or let value myQuery.attr("class").value
-       * @param attr the attribute to set
-       * @param defaultValue the default value in case nothing is presented (defaults to null)
-       */
-      DomQuery.prototype.attr = function (attr, defaultValue) {
-        if (defaultValue === void 0) { defaultValue = null; }
-        return new ElementAttribute(this, attr, defaultValue);
-      };
-      /**
-       * hasclass, checks for an existing class in the class attributes
-       *
-       * @param clazz the class to search for
-       */
-      DomQuery.prototype.hasClass = function (clazz) {
-        var hasIt = false;
-        this.each(function (item) {
-          var oldClass = item.attr("class").value || "";
-          if (oldClass.toLowerCase().indexOf(clazz.toLowerCase()) == -1) {
-            return;
-          }
-          else {
-            var oldClasses = oldClass.split(/\s+/gi);
-            var found = false;
-            for (var cnt = 0; cnt < oldClasses.length && !found; cnt++) {
-              found = oldClasses[cnt].toLowerCase() == clazz.toLowerCase();
-            }
-            hasIt = hasIt || found;
-            if (hasIt) {
-              return false;
-            }
-          }
-        });
-        return hasIt;
-      };
-      /**
-       * appends a class string if not already in the element(s)
-       *
-       * @param clazz the style class to append
-       */
-      DomQuery.prototype.addClass = function (clazz) {
-        var _this = this;
-        this.each(function (item) {
-          var oldClass = item.attr("class").value || "";
-          if (!_this.hasClass(clazz)) {
-            item.attr("class").value = trim(oldClass + " " + clazz);
-            return;
-          }
-        });
-        return this;
-      };
-      /**
-       * remove the style class if in the class definitions
-       *
-       * @param clazz
-       */
-      DomQuery.prototype.removeClass = function (clazz) {
-        var _this = this;
-        this.each(function (item) {
-          if (_this.hasClass(clazz)) {
-            var oldClass = item.attr("class").value || "";
-            var newClasses = [];
-            var oldClasses = oldClass.split(/\s+/gi);
-            for (var cnt = 0; cnt < oldClasses.length; cnt++) {
-              if (oldClasses[cnt].toLowerCase() != clazz.toLowerCase()) {
-                newClasses.push(oldClasses[cnt]);
-              }
-            }
-            item.attr("class").value = newClasses.join(" ");
-          }
-        });
-        return this;
-      };
-      /**
-       * checks whether we have a multipart element in our children
-       */
-      DomQuery.prototype.isMultipartCandidate = function () {
-        return this.querySelectorAll("input[type='file']").firstElem().isPresent();
-      };
-      /**
-       * innerHtml equivalkent
-       * equivalent to jqueries html
-       * as setter the html is set and the
-       * DomQuery is given back
-       * as getter the html string is returned
-       *
-       * @param inval
-       */
-      DomQuery.prototype.html = function (inval) {
-        if (Monad_1.Optional.fromNullable(inval).isAbsent()) {
-          return this.isPresent() ? Monad_1.Optional.fromNullable(this.innerHtml) : Monad_1.Optional.absent;
-        }
-        this.innerHtml = inval;
-        return this;
-      };
-      Object.defineProperty(DomQuery.prototype, "innerHtml", {
-        get: function () {
-          var retArr = [];
-          this.eachElem(function (elem) { return retArr.push(elem.innerHTML); });
-          return retArr.join("");
-        },
-        set: function (inVal) {
-          this.eachElem(function (elem) { return elem.innerHTML = inVal; });
-        },
-        enumerable: true,
-        configurable: true
-      });
-      //source: https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
-      //code snippet license: https://creativecommons.org/licenses/by-sa/2.5/
-      DomQuery.prototype._mozMatchesSelector = function (toMatch, selector) {
-        var prot = toMatch;
-        var matchesSelector = prot.matchesSelector ||
-            prot.mozMatchesSelector ||
-            prot.msMatchesSelector ||
-            prot.oMatchesSelector ||
-            prot.webkitMatchesSelector ||
-            function (s) {
-              var matches = (document || window.ownerDocument).querySelectorAll(s), i = matches.length;
-              while (--i >= 0 && matches.item(i) !== toMatch) {
-              }
-              return i > -1;
-            };
-        return matchesSelector.call(toMatch, selector);
-      };
-      /**
-       * filters the current dom query elements
-       * upon a given selector
-       *
-       * @param selector
-       */
-      DomQuery.prototype.filterSelector = function (selector) {
-        var _this = this;
-        var matched = [];
-        this.eachElem(function (item) {
-          if (_this._mozMatchesSelector(item, selector)) {
-            matched.push(item);
-          }
-        });
-        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], matched)))();
-      };
-      DomQuery.prototype.matchesSelector = function (selector) {
-        var _this = this;
-        this.eachElem(function (item) {
-          if (!_this._mozMatchesSelector(item, selector)) {
-            return false;
-          }
-        });
-        return true;
-      };
-      /**
-       * easy node traversal, you can pass
-       * a set of node selectors which are joined as direct childs
-       *
-       * not the rootnodes are not in the getIf, those are always the child nodes
-       *
-       * @param nodeSelector
-       */
-      DomQuery.prototype.getIf = function () {
-        var nodeSelector = [];
-        for (var _i = 0; _i < arguments.length; _i++) {
-          nodeSelector[_i] = arguments[_i];
-        }
-        var selectorStage = this.childNodes;
-        for (var cnt = 0; cnt < nodeSelector.length; cnt++) {
-          selectorStage = selectorStage.filterSelector(nodeSelector[cnt]);
-          if (selectorStage.isAbsent()) {
-            return selectorStage;
-          }
-        }
-        return selectorStage;
-      };
-      DomQuery.prototype.eachElem = function (func) {
-        for (var cnt = 0, len = this.rootNode.length; cnt < len; cnt++) {
-          if (func(this.rootNode[cnt], cnt) === false) {
-            break;
-          }
-        }
-        return this;
-      };
-      DomQuery.prototype.firstElem = function (func) {
-        if (func === void 0) { func = function (item) { return item; }; }
-        if (this.rootNode.length > 1) {
-          func(this.rootNode[0], 0);
-        }
-        return this;
-      };
-      DomQuery.prototype.each = function (func) {
-        Stream_1.Stream.of.apply(Stream_1.Stream, this.rootNode).each(function (item, cnt) {
-          //we could use a filter, but for the best performance we dont
-          if (item == null) {
-            return;
-          }
-          return func(DomQuery.byId(item), cnt);
-        });
-        return this;
-      };
-      /**
-       * returns a new dom query containing only the first element max
-       *
-       * @param func a an optional callback function to perform an operation on the first element
-       */
-      DomQuery.prototype.first = function (func) {
-        if (func === void 0) { func = function (item) { return item; }; }
-        if (this.rootNode.length >= 1) {
-          func(this.get(0), 0);
-          return this.get(0);
-        }
-        return this;
-      };
-      /**
-       * filter function which filters a subset
-       *
-       * @param func
-       */
-      DomQuery.prototype.filter = function (func) {
-        var reArr = [];
-        this.each(function (item) {
-          func(item) ? reArr.push(item) : null;
-        });
-        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], reArr)))();
-      };
-      //TODO append prepend
-      /**
-       * global eval head appendix method
-       * no other methods are supported anymore
-       * @param code the code to be evaled
-       * @param  nonce optional  nonce key for higher security
-       */
-      DomQuery.prototype.globalEval = function (code, nonce) {
-        var head = document.getElementsByTagName("head")[0] || document.documentElement;
-        var script = document.createElement("script");
-        if (nonce) {
-          script.setAttribute("nonce", nonce);
-        }
-        script.type = "text/javascript";
-        script.innerHTML = code;
-        var newScriptElement = head.appendChild(script);
-        head.removeChild(newScriptElement);
-        return this;
-      };
-      /**
-       * detaches a set of nodes from their parent elements
-       * in a browser independend manner
-       * @param {Object} items the items which need to be detached
-       * @return {Array} an array of nodes with the detached dom nodes
-       */
-      DomQuery.prototype.detach = function () {
-        this.eachElem(function (item) {
-          item.parentNode.removeChild(item);
-        });
-        return this;
-      };
-      /**
-       * appends the current set of elements
-       * to the element or first element passed via elem
-       * @param elem
-       */
-      DomQuery.prototype.appendTo = function (elem) {
-        this.eachElem(function (item) {
-          var value1 = elem.getAsElem(0).orElseLazy(function () {
-            return {
-              appendChild: function (theItem) {
-              }
-            };
-          }).value;
-          value1.appendChild(item);
-        });
-      };
-      /**
-       * loads and evals a script from a source uri
-       *
-       * @param src the source to be loaded and evaled
-       * @param defer in miliseconds execution default (0 == no defer)
-       * @param charSet
-       */
-      DomQuery.prototype.loadScriptEval = function (src, defer, charSet) {
-        var _this = this;
-        if (defer === void 0) { defer = 0; }
-        if (charSet === void 0) { charSet = "utf-8"; }
-        var xhr = new XMLHttpRequest();
-        xhr.open("GET", src, false);
-        if (charSet) {
-          xhr.setRequestHeader("Content-Type", "application/x-javascript; charset:" + charSet);
-        }
-        xhr.send(null);
-        xhr.onload = function (responseData) {
-          //defer also means we have to process after the ajax response
-          //has been processed
-          //we can achieve that with a small timeout, the timeout
-          //triggers after the processing is done!
-          if (!defer) {
-            _this.globalEval(xhr.responseText.replace("\n", "\r\n") + "\r\n//@ sourceURL=" + src);
-          }
-          else {
-            //TODO not ideal we maybe ought to move to something else here
-            //but since it is not in use yet, it is ok
-            setTimeout(function () {
-              _this.globalEval(xhr.responseText + "\r\n//@ sourceURL=" + src);
-            }, defer);
-          }
-        };
-        xhr.onerror = function (data) {
-          throw Error(data);
-        };
-        //since we are synchronous we do it after not with onReadyStateChange
-        return this;
-      };
-      DomQuery.prototype.insertAfter = function () {
-        var toInsertParams = [];
-        for (var _i = 0; _i < arguments.length; _i++) {
-          toInsertParams[_i] = arguments[_i];
-        }
-        this.each(function (existingItem) {
-          var existingElement = existingItem.getAsElem(0).value;
-          var rootNode = existingElement.parentNode;
-          var _loop_1 = function (cnt) {
-            var nextSibling = existingElement.nextSibling;
-            toInsertParams[cnt].eachElem(function (insertElem) {
-              if (nextSibling) {
-                rootNode.insertBefore(insertElem, nextSibling);
-                existingElement = nextSibling;
-              }
-              else {
-                rootNode.appendChild(insertElem);
-              }
-            });
-          };
-          for (var cnt = 0; cnt < toInsertParams.length; cnt++) {
-            _loop_1(cnt);
-          }
-        });
-        var res = [];
-        res.push(this);
-        res = res.concat(toInsertParams);
-        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], res)))();
-      };
-      DomQuery.prototype.insertBefore = function () {
-        var toInsertParams = [];
-        for (var _i = 0; _i < arguments.length; _i++) {
-          toInsertParams[_i] = arguments[_i];
-        }
-        this.each(function (existingItem) {
-          var existingElement = existingItem.getAsElem(0).value;
-          var rootNode = existingElement.parentNode;
-          for (var cnt = 0; cnt < toInsertParams.length; cnt++) {
-            toInsertParams[cnt].eachElem(function (insertElem) {
-              rootNode.insertBefore(insertElem, existingElement);
-            });
-          }
-        });
-        var res = [];
-        res.push(this);
-        res = res.concat(toInsertParams);
-        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], res)))();
-      };
-      DomQuery.prototype.orElse = function () {
-        var elseValue = [];
-        for (var _i = 0; _i < arguments.length; _i++) {
-          elseValue[_i] = arguments[_i];
-        }
-        if (this.isPresent()) {
-          return this;
-        }
-        else {
-          return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], elseValue)))();
-        }
-      };
-      DomQuery.prototype.orElseLazy = function (func) {
-        if (this.isPresent()) {
-          return this;
-        }
-        else {
-          return new DomQuery(func());
-        }
-      };
-      DomQuery.prototype.parents = function (tagName) {
-        var retSet = new Set();
-        var retArr = [];
-        var lowerTagName = tagName.toLowerCase();
-        var resolveItem = function (item) {
-          if ((item.tagName || "").toLowerCase() == lowerTagName && !retSet.has(item)) {
-            retSet.add(item);
-            retArr.push(item);
-          }
-        };
-        this.eachElem(function (item) {
-          while (item.parentNode) {
-            item = item.parentNode;
-            resolveItem(item);
-            //nested forms not possible, performance shortcut
-            if (tagName == "form" && retArr.length) {
-              return false;
-            }
-          }
-        });
-        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], retArr)))();
-      };
-      DomQuery.prototype.copyAttrs = function (sourceItem) {
-        var _this = this;
-        sourceItem.eachElem(function (sourceNode) {
-          var attrs = objToArray(sourceNode.attributes);
-          for (var _i = 0, attrs_1 = attrs; _i < attrs_1.length; _i++) {
-            var item = attrs_1[_i];
-            var value = item.value;
-            var name_1 = item.name;
-            switch (name_1) {
-              case "id":
-                _this.id.value = value;
-                break;
-              case "disabled":
-                _this.resolveAttributeHolder("disabled").disabled = value;
-                break;
-              case "checked":
-                _this.resolveAttributeHolder("checked").checked = value;
-                break;
-              default:
-                _this.attr(name_1).value = value;
-            }
-          }
-        });
-        return this;
-      };
-      /**
-       * resolves an attribute holder compared
-       * @param attrName the attribute name
-       */
-      DomQuery.prototype.resolveAttributeHolder = function (attrName) {
-        if (attrName === void 0) { attrName = "value"; }
-        var ret = [];
-        ret[attrName] = null;
-        return (attrName in this.getAsElem(0).value) ?
-            this.getAsElem(0).value :
-            ret;
-      };
-      /**
-       * outerhtml convenience method
-       * browsers only support innerHTML but
-       * for instance for your jsf.js we have a full
-       * replace pattern which needs outerHTML processing
-       *
-       * @param markup
-       * @param runEmbeddedScripts
-       * @param runEmbeddedCss
-       */
-      DomQuery.prototype.outerHTML = function (markup, runEmbeddedScripts, runEmbeddedCss) {
-        var _a, _b;
-        if (this.isAbsent()) {
-          return;
-        }
-        var focusElementId = (_b = (_a = document) === null || _a === void 0 ? void 0 : _a.activeElement) === null || _b === void 0 ? void 0 : _b.id;
-        var caretPosition = (focusElementId) ? DomQuery.getCaretPosition(document.activeElement) : null;
-        var nodes = DomQuery.fromMarkup(markup);
-        var res = [];
-        var toReplace = this.getAsElem(0).value;
-        var firstInsert = nodes.get(0);
-        var parentNode = toReplace.parentNode;
-        var replaced = firstInsert.getAsElem(0).value;
-        parentNode.replaceChild(replaced, toReplace);
-        res.push(new DomQuery(replaced));
-        //no replacement possible
-        if (this.isAbsent()) {
-          return this;
-        }
-        var insertAdditionalItems = [];
-        if (nodes.length > 1) {
-          insertAdditionalItems = insertAdditionalItems.concat.apply(insertAdditionalItems, nodes.values.slice(1));
-          res.push(DomQuery.byId(replaced).insertAfter(new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], insertAdditionalItems)))()));
-        }
-        if (runEmbeddedScripts) {
-          this.runScripts();
-        }
-        if (runEmbeddedCss) {
-          this.runCss();
-        }
-        var focusElement = DomQuery.byId(focusElementId);
-        if (focusElementId && focusElement.isPresent() &&
-            caretPosition != null && "undefined" != typeof caretPosition) {
-          focusElement.eachElem(function (item) { return DomQuery.setCaretPosition(item, caretPosition); });
-        }
-        return nodes;
-      };
-      /**
-       * Run through the given nodes in the DomQuery execute the inline scripts
-       * @param whilteListed: optional whitelist function which can filter out script tags which are not processed
-       * defaults to the standard jsf.js exclusion (we use this code for myfaces)
-       */
-      DomQuery.prototype.runScripts = function (whilteListed) {
-        var _this = this;
-        if (whilteListed === void 0) { whilteListed = DEFAULT_JSF_WHITELIST; }
-        var finalScripts = [], equi = equalsIgnoreCase, execScrpt = function (item) {
-          var tagName = item.tagName;
-          var itemType = item.type || "";
-          if (tagName && equi(tagName, "script") &&
-              (itemType === "" || equi(itemType, "text/javascript") ||
-                  equi(itemType, "javascript") ||
-                  equi(itemType, "text/ecmascript") ||
-                  equi(itemType, "ecmascript"))) {
-            var src = item.getAttribute('src');
-            if ('undefined' != typeof src
-                && null != src
-                && src.length > 0) {
-              //we have to move this into an inner if because chrome otherwise chokes
-              //due to changing the and order instead of relying on left to right
-              //if jsf.js is already registered we do not replace it anymore
-              if (whilteListed(src)) {
-                if (finalScripts.length) {
-                  //script source means we have to eval the existing
-                  //scripts before running the include
-                  _this.globalEval(finalScripts.join("\n"));
-                  finalScripts = [];
-                }
-                _this.loadScriptEval(src, 0, "UTF-8");
-              }
-            }
-            else {
-              // embedded script auto eval
-              //TODO this probably needs to be changed due to our new parsing structures
-              //probably not needed anymore
-              var evalText = trim(item.text || item.innerText || item.innerHTML);
-              var go = true;
-              while (go) {
-                go = false;
-                if (evalText.substring(0, 4) == "<!--") {
-                  evalText = evalText.substring(4);
-                  go = true;
-                }
-                if (evalText.substring(0, 4) == "//<!--") {
-                  evalText = evalText.substring(6);
-                  go = true;
-                }
-                if (evalText.substring(0, 11) == "//<![CDATA[") {
-                  evalText = evalText.substring(11);
-                  go = true;
-                }
-              }
-              // we have to run the script under a global context
-              //we store the script for less calls to eval
-              finalScripts.push(evalText);
-            }
-          }
-        };
-        try {
-          var scriptElements = new DomQuery(this.filterSelector("script"), this.querySelectorAll("script"));
-          //script execution order by relative pos in their dom tree
-          scriptElements.stream
-              .flatMap(function (item) {
-                return Stream_1.Stream.of(item.values);
-              })
-              .sort(function (node1, node2) {
-                return node1.compareDocumentPosition(node2) - 3; //preceding 2, following == 4
-              })
-              .each(function (item) { return execScrpt(item); });
-          if (finalScripts.length) {
-            this.globalEval(finalScripts.join("\n"));
-          }
-        }
-        catch (e) {
-          if (window.console && window.console.error) {
-            //not sure if we
-            //should use our standard
-            //error mechanisms here
-            //because in the head appendix
-            //method only a console
-            //error would be raised as well
-            console.error(e.message || e.description);
-          }
-        }
-        finally {
-          //the usual ie6 fix code
-          //the IE6 garbage collector is broken
-          //nulling closures helps somewhat to reduce
-          //mem leaks, which are impossible to avoid
-          //at this browser
-          execScrpt = null;
-        }
-        return this;
-      };
-      DomQuery.prototype.runCss = function () {
-        var applyStyle = function (item, style) {
-          var _a, _b, _c, _d, _e;
-          var newSS = document.createElement("style");
-          document.getElementsByTagName("head")[0].appendChild(newSS);
-          var styleSheet = (_a = newSS.sheet, (_a !== null && _a !== void 0 ? _a : newSS.styleSheet));
-          newSS.setAttribute("rel", (_b = item.getAttribute("rel"), (_b !== null && _b !== void 0 ? _b : "stylesheet")));
-          newSS.setAttribute("type", (_c = item.getAttribute("type"), (_c !== null && _c !== void 0 ? _c : "text/css")));
-          if (_e = (_d = styleSheet) === null || _d === void 0 ? void 0 : _d.cssText, (_e !== null && _e !== void 0 ? _e : false)) {
-            styleSheet.cssText = style;
-          }
-          else {
-            newSS.appendChild(document.createTextNode(style));
-          }
-        }, execCss = function (item) {
-          var tagName = item.tagName;
-          if (tagName && equalsIgnoreCase(tagName, "link") && equalsIgnoreCase(item.getAttribute("type"), "text/css")) {
-            applyStyle(item, "@import url('" + item.getAttribute("href") + "');");
-          }
-          else if (tagName && equalsIgnoreCase(tagName, "style") && equalsIgnoreCase(item.getAttribute("type"), "text/css")) {
-            var innerText = [];
-            //compliant browsers know child nodes
-            var childNodes = item.childNodes;
-            if (childNodes) {
-              var len = childNodes.length;
-              for (var cnt = 0; cnt < len; cnt++) {
-                innerText.push(childNodes[cnt].innerHTML || childNodes[cnt].data);
-              }
-              //non compliant ones innerHTML
-            }
-            else if (item.innerHTML) {
-              innerText.push(item.innerHTML);
-            }
-            applyStyle(item, innerText.join(""));
-          }
-        };
-        var scriptElements = new DomQuery(this.filterSelector("link, style"), this.querySelectorAll("link, style"));
-        scriptElements.stream
-            .flatMap(function (item) {
-              return Stream_1.Stream.of(item.values);
-            })
-            .sort(function (node1, node2) {
-              return node1.compareDocumentPosition(node2) - 3; //preceding 2, following == 4
-            })
-            .each(function (item) { return execCss(item); });
-        return this;
-      };
-      /**
-       * fires a click event on the underlying dom elements
-       */
-      DomQuery.prototype.click = function () {
-        this.fireEvent("click");
-        return this;
-      };
-      DomQuery.prototype.addEventListener = function (type, listener, options) {
-        this.eachElem(function (node) {
-          node.addEventListener(type, listener, options);
-        });
-        return this;
-      };
-      DomQuery.prototype.removeEventListener = function (type, listener, options) {
-        this.eachElem(function (node) {
-          node.removeEventListener(type, listener, options);
-        });
-        return this;
-      };
-      /**
-       * fires an event
-       */
-      DomQuery.prototype.fireEvent = function (eventName) {
-        this.eachElem(function (node) {
-          var doc;
-          if (node.ownerDocument) {
-            doc = node.ownerDocument;
-          }
-          else if (node.nodeType == 9) {
-            // the node may be the document itself, nodeType 9 = DOCUMENT_NODE
-            doc = node;
-          }
-          else {
-            throw new Error("Invalid node passed to fireEvent: " + node.id);
-          }
-          if (node.dispatchEvent) {
-            // Gecko-style approach (now the standard) takes more work
-            var eventClass = "";
-            // Different events have different event classes.
-            // If this switch statement can't map an eventName to an eventClass,
-            // the event firing is going to fail.
-            switch (eventName) {
-              case "click": // Dispatching of 'click' appears to not work correctly in Safari. Use 'mousedown' or 'mouseup' instead.
-              case "mousedown":
-              case "mouseup":
-                eventClass = "MouseEvents";
-                break;
-              case "focus":
-              case "change":
-              case "blur":
-              case "select":
-                eventClass = "HTMLEvents";
-                break;
-              default:
-                throw "fireEvent: Couldn't find an event class for event '" + eventName + "'.";
-                break;
-            }
-            var event_1 = doc.createEvent(eventClass);
-            event_1.initEvent(eventName, true, true); // All events created as bubbling and cancelable.
-            event_1.synthetic = true; // allow detection of synthetic events
-            // The second parameter says go ahead with the default action
-            node.dispatchEvent(event_1);
-          }
-          else if (node.fireEvent) {
-            // IE-old school style, you can drop this if you don't need to support IE8 and lower
-            var event_2 = doc.createEventObject();
-            event_2.synthetic = true; // allow detection of synthetic events
-            node.fireEvent("on" + eventName, event_2);
-          }
-        });
-      };
-      DomQuery.prototype.textContent = function (joinstr) {
-        if (joinstr === void 0) { joinstr = ""; }
-        return this.stream
-            .map(function (value) {
-              var item = value.getAsElem(0).orElseLazy(function () {
-                return {
-                  textContent: ""
-                };
-              }).value;
-              return item.textContent || "";
-            })
-            .reduce(function (text1, text2) { return text1 + joinstr + text2; }, "").value;
-      };
-      DomQuery.prototype.innerText = function (joinstr) {
-        if (joinstr === void 0) { joinstr = ""; }
-        return this.stream
-            .map(function (value) {
-              var item = value.getAsElem(0).orElseLazy(function () {
-                return {
-                  innerText: ""
-                };
-              }).value;
-              return item.innerText || "";
-            })
-            .reduce(function (text1, text2) { return [text1, text2].join(joinstr); }, "").value;
-      };
-      /**
-       * encodes all input elements properly into respective
-       * config entries, this can be used
-       * for legacy systems, for newer usecases, use the
-       * HTML5 Form class which all newer browsers provide
-       *
-       * @param toMerge optional config which can be merged in
-       * @return a copy pf
-       */
-      DomQuery.prototype.encodeFormElement = function (toMerge) {
-        if (toMerge === void 0) { toMerge = new Monad_1.Config({}); }
-        //browser behavior no element name no encoding (normal submit fails in that case)
-        //https://issues.apache.org/jira/browse/MYFACES-2847
-        if (this.name.isAbsent()) {
-          return;
-        }
-        //lets keep it sideffects free
-        var target = toMerge.shallowCopy;
-        this.each(function (element) {
-          if (element.name.isAbsent()) { //no name, no encoding
-            return;
-          }
-          var name = element.name.value;
-          var tagName = element.tagName.orElse("__none__").value.toLowerCase();
-          var elemType = element.type.orElse("__none__").value.toLowerCase();
-          elemType = elemType.toLowerCase();
-          // routine for all elements
-          // rules:
-          // - process only inputs, textareas and selects
-          // - elements muest have attribute "name"
-          // - elements must not be disabled
-          if (((tagName == "input" || tagName == "textarea" || tagName == "select") &&
-              (name != null && name != "")) && !element.disabled) {
-            // routine for select elements
-            // rules:
-            // - if select-one and value-Attribute exist => "name=value"
-            // (also if value empty => "name=")
-            // - if select-one and value-Attribute don't exist =>
-            // "name=DisplayValue"
-            // - if select multi and multple selected => "name=value1&name=value2"
-            // - if select and selectedIndex=-1 don't submit
-            if (tagName == "select") {
-              // selectedIndex must be >= 0 sein to be submittet
-              var selectElem = element.getAsElem(0).value;
-              if (selectElem.selectedIndex >= 0) {
-                var uLen = selectElem.options.length;
-                for (var u = 0; u < uLen; u++) {
-                  // find all selected options
-                  //let subBuf = [];
-                  if (selectElem.options[u].selected) {
-                    var elementOption = selectElem.options[u];
-                    target.assign(name).value = (elementOption.getAttribute("value") != null) ?
-                        elementOption.value : elementOption.text;
-                  }
-                }
-              }
-            }
-            // routine for remaining elements
-            // rules:
-            // - don't submit no selects (processed above), buttons, reset buttons, submit buttons,
-            // - submit checkboxes and radio inputs only if checked
-            if ((tagName != "select" && elemType != "button"
-                && elemType != "reset" && elemType != "submit" && elemType != "image")
-                && ((elemType != "checkbox" && elemType != "radio") || element.checked)) {
-              var files = element.value.files;
-              if (files && files.length) {
-                //xhr level2
-                target.assign(name).value = files[0];
-              }
-              else {
-                target.assign(name).value = element.inputValue.value;
-              }
-            }
-          }
-        });
-        return target;
-      };
-      Object.defineProperty(DomQuery.prototype, "cDATAAsString", {
-        get: function () {
-          var cDataBlock = [];
-          var TYPE_CDATA_BLOCK = 4;
-          // response may contain several blocks
-          return this.stream
-              .flatMap(function (item) { return item.childNodes.stream; }).reduce(function (reduced, item) {
-                var _a, _b, _c, _d, _e, _f, _g;
-                if (((_c = (_b = (_a = item) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.value) === null || _c === void 0 ? void 0 : _c.nodeType) == TYPE_CDATA_BLOCK) {
-                  reduced.push((_g = (_f = (_e = (_d = item) === null || _d === void 0 ? void 0 : _d.value) === null || _e === void 0 ? void 0 : _e.value) === null || _f === void 0 ? void 0 : _f.data, (_g !== null && _g !== void 0 ? _g : "")));
-                }
-                return reduced;
-              }, []).value.join("");
-        },
-        enumerable: true,
-        configurable: true
-      });
-      DomQuery.prototype.subNodes = function (from, to) {
-        if (Monad_1.Optional.fromNullable(to).isAbsent()) {
-          to = this.length;
-        }
-        return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], this.rootNode.slice(from, Math.min(to, this.length)))))();
-      };
-      DomQuery.prototype.limits = function (end) {
-        this._limits = end;
-        return this;
-      };
-      //-- internally exposed methods needed for the interconnectivity
-      DomQuery.prototype.hasNext = function () {
-        var isLimitsReached = this._limits != -1 && this.pos >= this._limits - 1;
-        var isEndOfArray = this.pos >= this.values.length - 1;
-        return !(isLimitsReached ||
-            isEndOfArray);
-      };
-      DomQuery.prototype.next = function () {
-        if (!this.hasNext()) {
-          return null;
-        }
-        this.pos++;
-        return new DomQuery(this.values[this.pos]);
-      };
-      DomQuery.prototype.reset = function () {
-        this.pos = -1;
-      };
-      //from
-      // http://blog.vishalon.net/index.php/javascript-getting-and-setting-caret-position-in-textarea/
-      DomQuery.getCaretPosition = function (ctrl) {
-        var _a;
-        var caretPos = 0;
-        try {
-          if ((_a = document) === null || _a === void 0 ? void 0 : _a.selection) {
-            ctrl.focus();
-            var selection = document.selection.createRange();
-            //the selection now is start zero
-            selection.moveStart('character', -ctrl.value.length);
-            //the caretposition is the selection start
-            caretPos = selection.text.length;
-          }
-        }
-        catch (e) {
-          //now this is ugly, but not supported input types throw errors for selectionStart
-          //just in case someone dumps this code onto unsupported browsers
-        }
-        return caretPos;
-      };
-      DomQuery.setCaretPosition = function (ctrl, pos) {
-        ctrl.focus();
-        //the selection range is our caret position
-        ctrl.setSelectionRange(pos, pos);
-      };
-      DomQuery.absent = new DomQuery();
-      return DomQuery;
-    }());
-    exports.DomQuery = DomQuery;
-    /**
-     * Various collectors
-     * which can be used in conjunction with Streams
-     */
-    /**
-     * A collector which bundles a full dom query stream into a single dom query element
-     *
-     * This connects basically our stream back into DomQuery
-     */
-    var DomQueryCollector = /** @class */ (function () {
-      function DomQueryCollector() {
-        this.data = [];
-      }
-      DomQueryCollector.prototype.collect = function (element) {
-        this.data.push(element);
-      };
-      Object.defineProperty(DomQueryCollector.prototype, "finalValue", {
-        get: function () {
-          return new (DomQuery.bind.apply(DomQuery, __spreadArrays([void 0], this.data)))();
-        },
-        enumerable: true,
-        configurable: true
-      });
-      return DomQueryCollector;
-    }());
-    exports.DomQueryCollector = DomQueryCollector;
-    /**
-     * abbreviation for DomQuery
-     */
-    exports.DQ = DomQuery;
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/ext/monadish/Lang.ts":
-  /*!**************************************************!*\
-  !*** ./src/main/typescript/ext/monadish/Lang.ts ***!
-  \**************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var Monad_1 = __webpack_require__(/*! ./Monad */ "./src/main/typescript/ext/monadish/Monad.ts");
-    /**
-     * Lang helpers crossported from the apache myfaces project
-     */
-    var Lang;
-    (function (Lang) {
-      //should be in lang, but for now here to avoid recursive imports, not sure if typescript still has a problem with those
-      /**
-       * helper function to savely resolve anything
-       * this is not an elvis operator, it resolves
-       * a value without exception in a tree and if
-       * it is not resolvable then an optional of
-       * a default value is restored or Optional.empty
-       * if none is given
-       *
-       * usage
-       * <code>
-       *     let var: Optiona<string> = saveResolve(() => a.b.c.d.e, "foobaz")
-       * </code>
-       *
-       * @param resolverProducer a lambda which can produce the value
-       * @param defaultValue an optional default value if the producer failes to produce anything
-       * @returns an Optional of the produced value
-       */
-      function saveResolve(resolverProducer, defaultValue) {
-        if (defaultValue === void 0) { defaultValue = null; }
-        try {
-          var result = resolverProducer();
-          return Monad_1.Optional.fromNullable((result !== null && result !== void 0 ? result : defaultValue));
-        }
-        catch (e) {
-          return Monad_1.Optional.absent;
-        }
-      }
-      Lang.saveResolve = saveResolve;
-      function saveResolveLazy(resolverProducer, defaultValue) {
-        if (defaultValue === void 0) { defaultValue = null; }
-        try {
-          var result = resolverProducer();
-          return Monad_1.Optional.fromNullable((result !== null && result !== void 0 ? result : defaultValue()));
-        }
-        catch (e) {
-          return Monad_1.Optional.absent;
-        }
-      }
-      Lang.saveResolveLazy = saveResolveLazy;
-      /**
-       * String to array function performs a string to array transformation
-       * @param {String} it the string which has to be changed into an array
-       * @param {RegExp} splitter our splitter reglar expression
-       * @return a trimmed array of the splitted string
-       */
-      function strToArray(it, splitter) {
-        if (splitter === void 0) { splitter = /\./gi; }
-        var ret = [];
-        it.split(splitter).forEach((function (element) {
-          ret.push(trim(element));
-        }));
-        return ret;
-      }
-      Lang.strToArray = strToArray;
-      /**
-       * hyperfast trim
-       * http://blog.stevenlevithan.com/archives/faster-trim-javascript
-       * crossported from dojo
-       */
-      function trim(str) {
-        str = str.replace(/^\s\s*/, '');
-        var ws = /\s/, i = str.length;
-        while (ws.test(str.charAt(--i))) {
-          //do nothing
-        }
-        return str.slice(0, i + 1);
-      }
-      Lang.trim = trim;
-      /**
-       * generic object arrays like dom definitions to array conversion method which
-       * transforms any object to something array like
-       * @param obj
-       * @param offset
-       * @param pack
-       * @returns an array converted from the object
-       */
-      function objToArray(obj, offset, pack) {
-        if (offset === void 0) { offset = 0; }
-        if (pack === void 0) { pack = []; }
-        if (((obj !== null && obj !== void 0 ? obj : "__undefined__")) == "__undefined__") {
-          return (pack !== null && pack !== void 0 ? pack : null);
-        }
-        //since offset is numeric we cannot use the shortcut due to 0 being false
-        //special condition array delivered no offset no pack
-        if (obj instanceof Array && !offset && !pack)
-          return obj;
-        return pack.concat(Array.prototype.slice.call(obj, offset));
-      }
-      Lang.objToArray = objToArray;
-      /**
-       * equalsIgnoreCase, case insensitive comparison of two strings
-       *
-       * @param source
-       * @param destination
-       */
-      function equalsIgnoreCase(source, destination) {
-        var finalSource = (source !== null && source !== void 0 ? source : "___no_value__");
-        var finalDest = (destination !== null && destination !== void 0 ? destination : "___no_value__");
-        //in any other case we do a strong string comparison
-        return finalSource.toLowerCase() === finalDest.toLowerCase();
-      }
-      Lang.equalsIgnoreCase = equalsIgnoreCase;
-      /**
-       * runtime type assertion
-       *
-       * @param probe the probe to be tested for a type
-       * @param theType the type to be tested for
-       */
-      function assertType(probe, theType) {
-        return isString(theType) ? typeof probe == theType : probe instanceof theType;
-      }
-      Lang.assertType = assertType;
-      /**
-       * Backported from dojo
-       * a failsafe string determination method
-       * (since in javascript String != "" typeof alone fails!)
-       * @param it {|Object|} the object to be checked for being a string
-       * @return true in case of being a string false otherwise
-       */
-      function isString(it) {
-        //	summary:
-        //		Return true if it is a String
-        return !!arguments.length && it != null && (typeof it == "string" || it instanceof String); // Boolean
-      }
-      Lang.isString = isString;
-      function isFunc(it) {
-        return it instanceof Function || typeof it === "function";
-      }
-      Lang.isFunc = isFunc;
-      // code from https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
-      // license https://creativecommons.org/licenses/by-sa/2.5/
-      function objAssign(target) {
-        var theArgs = [];
-        for (var _i = 1; _i < arguments.length; _i++) {
-          theArgs[_i - 1] = arguments[_i];
-        }
-        if (target == null) { // TypeError if undefined or null
-          throw new TypeError('Cannot convert undefined or null to object');
-        }
-        var to = Object(target);
-        if (Object.assign) {
-          theArgs.forEach(function (item) { return Object.assign(to, item); });
-          return to;
-        }
-        theArgs.forEach(function (item) {
-          var nextSource = item;
-          if (nextSource != null) { // Skip over if undefined or null
-            for (var nextKey in nextSource) {
-              // Avoid bugs when hasOwnProperty is shadowed
-              if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
-                to[nextKey] = nextSource[nextKey];
-              }
-            }
-          }
-        });
-        return to;
-      }
-      Lang.objAssign = objAssign;
-    })(Lang = exports.Lang || (exports.Lang = {}));
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/ext/monadish/Monad.ts":
-  /*!***************************************************!*\
-  !*** ./src/main/typescript/ext/monadish/Monad.ts ***!
-  \***************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    var __extends = (this && this.__extends) || (function () {
-      var extendStatics = function (d, b) {
-        extendStatics = Object.setPrototypeOf ||
-            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
-        return extendStatics(d, b);
-      };
-      return function (d, b) {
-        extendStatics(d, b);
-        function __() { this.constructor = d; }
-        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-      };
-    })();
-    Object.defineProperty(exports, "__esModule", { value: true });
-    /**
-     * A module which keeps  basic monadish like definitions in place without any sidedependencies to other modules.
-     * Useful if you need the functions in another library to keep its dependencies down
-     */
-    /*IMonad definitions*/
-    var Lang_1 = __webpack_require__(/*! ./Lang */ "./src/main/typescript/ext/monadish/Lang.ts");
-    var SourcesCollectors_1 = __webpack_require__(/*! ./SourcesCollectors */ "./src/main/typescript/ext/monadish/SourcesCollectors.ts");
-    var Stream_1 = __webpack_require__(/*! ./Stream */ "./src/main/typescript/ext/monadish/Stream.ts");
-    var objAssign = Lang_1.Lang.objAssign;
-    /**
-     * Implementation of a monad
-     * (Sideffect free), no write allowed directly on the monads
-     * value state
-     */
-    var Monad = /** @class */ (function () {
-      function Monad(value) {
-        this._value = value;
-      }
-      Object.defineProperty(Monad.prototype, "value", {
-        get: function () {
-          return this._value;
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Monad.prototype.map = function (fn) {
-        if (!fn) {
-          fn = function (inval) { return inval; };
-        }
-        var result = fn(this.value);
-        return new Monad(result);
-      };
-      Monad.prototype.flatMap = function (fn) {
-        var _a;
-        var mapped = this.map(fn);
-        while (((_a = mapped) === null || _a === void 0 ? void 0 : _a.value) instanceof Monad) {
-          mapped = mapped.value;
-        }
-        return mapped;
-      };
-      return Monad;
-    }());
-    exports.Monad = Monad;
-    /**
-     * optional implementation, an optional is basically an implementation of a Monad with additional syntactic
-     * sugar on top
-     * (Sideeffect free, since value assignment is not allowed)
-     * */
-    var Optional = /** @class */ (function (_super) {
-      __extends(Optional, _super);
-      function Optional(value) {
-        return _super.call(this, value) || this;
-      }
-      Object.defineProperty(Optional.prototype, "value", {
-        get: function () {
-          if (this._value instanceof Monad) {
-            return this._value.flatMap().value;
-          }
-          return this._value;
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Optional.fromNullable = function (value) {
-        return new Optional(value);
-      };
-      /*syntactic sugar for absent and present checks*/
-      Optional.prototype.isAbsent = function () {
-        return "undefined" == typeof this.value || null == this.value;
-      };
-      /**
-       * any value present
-       */
-      Optional.prototype.isPresent = function (presentRunnable) {
-        var absent = this.isAbsent();
-        if (!absent && presentRunnable) {
-          presentRunnable.call(this, this);
-        }
-        return !absent;
-      };
-      Optional.prototype.ifPresentLazy = function (presentRunnable) {
-        if (presentRunnable === void 0) { presentRunnable = function () {
-        }; }
-        this.isPresent.call(this, presentRunnable);
-        return this;
-      };
-      Optional.prototype.orElse = function (elseValue) {
-        if (this.isPresent()) {
-          return this;
-        }
-        else {
-          //shortcut
-          if (elseValue == null) {
-            return Optional.absent;
-          }
-          return this.flatMap(function () { return elseValue; });
-        }
-      };
-      /**
-       * lazy, passes a function which then is lazily evaluated
-       * instead of a direct value
-       * @param func
-       */
-      Optional.prototype.orElseLazy = function (func) {
-        if (this.isPresent()) {
-          return this;
-        }
-        else {
-          return this.flatMap(func);
-        }
-      };
-      /*
-     * we need to implement it to fullfill the contract, although it is used only internally
-     * all values are flattened when accessed anyway, so there is no need to call this methiod
-     */
-      Optional.prototype.flatMap = function (fn) {
-        var val = _super.prototype.flatMap.call(this, fn);
-        if (!(val instanceof Optional)) {
-          return Optional.fromNullable(val.value);
-        }
-        return val.flatMap();
-      };
-      /*
-     * elvis operation, take care, if you use this you lose typesafety and refactoring
-     * capabilites, unfortunately typesceript does not allow to have its own elvis operator
-     * this is some syntactic sugar however which is quite useful*/
-      Optional.prototype.getIf = function () {
-        var key = [];
-        for (var _i = 0; _i < arguments.length; _i++) {
-          key[_i] = arguments[_i];
-        }
-        var currentPos = this;
-        for (var cnt = 0; cnt < key.length; cnt++) {
-          var currKey = this.keyVal(key[cnt]);
-          var arrPos = this.arrayIndex(key[cnt]);
-          if (currKey === "" && arrPos >= 0) {
-            currentPos = this.getClass().fromNullable(!(currentPos.value instanceof Array) ? null : (currentPos.value.length < arrPos ? null : currentPos.value[arrPos]));
-            if (currentPos.isAbsent()) {
-              return currentPos;
-            }
-            continue;
-          }
-          else if (currKey && arrPos >= 0) {
-            if (currentPos.getIfPresent(currKey).isAbsent()) {
-              return currentPos;
-            }
-            currentPos = (currentPos.getIfPresent(currKey).value instanceof Array) ? this.getClass().fromNullable(currentPos.getIfPresent(currKey).value[arrPos]) : this.getClass().absent;
-            if (currentPos.isAbsent()) {
-              return currentPos;
-            }
-            continue;
-          }
-          else {
-            currentPos = currentPos.getIfPresent(currKey);
-          }
-          if (currentPos.isAbsent()) {
-            return currentPos;
-          }
-          else if (arrPos > -1) {
-            currentPos = this.getClass().fromNullable(currentPos.value[arrPos]);
-          }
-        }
-        var retVal = currentPos;
-        return retVal;
-      };
-      /**
-       * simple match, if the first order function call returns
-       * true then there is a match, if the value is not present
-       * it never matches
-       *
-       * @param fn the first order function performing the match
-       */
-      Optional.prototype.match = function (fn) {
-        if (this.isAbsent()) {
-          return false;
-        }
-        return fn(this.value);
-      };
-      /**
-       * convenience function to flatmap the internal value
-       * and replace it with a default in case of being absent
-       *
-       * @param defaultVal
-       * @returns {Optional<any>}
-       */
-      Optional.prototype.get = function (defaultVal) {
-        if (defaultVal === void 0) { defaultVal = Optional.absent; }
-        if (this.isAbsent()) {
-          return this.getClass().fromNullable(defaultVal).flatMap();
-        }
-        return this.getClass().fromNullable(this.value).flatMap();
-      };
-      Optional.prototype.toJson = function () {
-        return JSON.stringify(this.value);
-      };
-      /**
-       * helper to override several implementations in a more fluent way
-       * by having a getClass operation we can avoid direct calls into the constructor or
-       * static methods and do not have to implement several methods which rely on the type
-       * of "this"
-       * @returns {Monadish.Optional}
-       */
-      Optional.prototype.getClass = function () {
-        return Optional;
-      };
-      /*helper method for getIf with array access aka <name>[<indexPos>]*/
-      Optional.prototype.arrayIndex = function (key) {
-        var start = key.indexOf("[");
-        var end = key.indexOf("]");
-        if (start >= 0 && end > 0 && start < end) {
-          return parseInt(key.substring(start + 1, end));
-        }
-        else {
-          return -1;
-        }
-      };
-      /*helper method for getIf with array access aka <name>[<indexPos>]*/
-      Optional.prototype.keyVal = function (key) {
-        var start = key.indexOf("[");
-        if (start >= 0) {
-          return key.substring(0, start);
-        }
-        else {
-          return key;
-        }
-      };
-      /**
-       * additional syntactic sugar which is not part of the usual optional implementation
-       * but makes life easier, if you want to sacrifice typesafety and refactoring
-       * capabilities in typescript
-       */
-      Optional.prototype.getIfPresent = function (key) {
-        if (this.isAbsent()) {
-          return this.getClass().absent;
-        }
-        return this.getClass().fromNullable(this.value[key]).flatMap();
-      };
-      /**
-       * elvis like typesafe functional save resolver
-       * a typesafe option for getIfPresent
-       *
-       * usage myOptional.resolve(value => value.subAttr.subAttr2).orElseLazy(....)
-       * if this is resolvable without any errors an Optional with the value is returned
-       * if not, then an Optional absent is returned, also if you return Optional absent
-       * it is flatmapped into absent
-       *
-       * @param resolver the resolver function, can throw any arbitrary errors, int  the error case
-       * the resolution goes towards absent
-       */
-      Optional.prototype.resolve = function (resolver) {
-        if (this.isAbsent()) {
-          return Optional.absent;
-        }
-        try {
-          return Optional.fromNullable(resolver(this.value));
-        }
-        catch (e) {
-          return Optional.absent;
-        }
-      };
-      /*default value for absent*/
-      Optional.absent = Optional.fromNullable(null);
-      return Optional;
-    }(Monad));
-    exports.Optional = Optional;
-// --------------------- From here onwards we break out the sideffects free limits ------------
-    /**
-     * ValueEmbedder is the writeable version
-     * of optional, it basically is a wrappber
-     * around a construct which has a state
-     * and can be written to.
-     *
-     * For the readonly version see Optional
-     */
-    var ValueEmbedder = /** @class */ (function (_super) {
-      __extends(ValueEmbedder, _super);
-      function ValueEmbedder(rootElem, valueKey) {
-        if (valueKey === void 0) { valueKey = "value"; }
-        var _this = _super.call(this, rootElem) || this;
-        _this.key = valueKey;
-        return _this;
-      }
-      Object.defineProperty(ValueEmbedder.prototype, "value", {
-        get: function () {
-          return this._value ? this._value[this.key] : null;
-        },
-        set: function (newVal) {
-          if (!this._value) {
-            return;
-          }
-          this._value[this.key] = newVal;
-        },
-        enumerable: true,
-        configurable: true
-      });
-      ValueEmbedder.prototype.orElse = function (elseValue) {
-        var alternative = {};
-        alternative[this.key] = elseValue;
-        return this.isPresent() ? this : new ValueEmbedder(alternative, this.key);
-      };
-      ValueEmbedder.prototype.orElseLazy = function (func) {
-        if (this.isPresent()) {
-          return this;
-        }
-        else {
-          var alternative = {};
-          alternative[this.key] = func();
-          return new ValueEmbedder(alternative, this.key);
-        }
-      };
-      /**
-       * helper to override several implementations in a more fluent way
-       * by having a getClass operation we can avoid direct calls into the constructor or
-       * static methods and do not have to implement several methods which rely on the type
-       * of "this"
-       * @returns {Monadish.Optional}
-       */
-      ValueEmbedder.prototype.getClass = function () {
-        return ValueEmbedder;
-      };
-      ValueEmbedder.fromNullable = function (value, valueKey) {
-        if (valueKey === void 0) { valueKey = "value"; }
-        return new ValueEmbedder(value, valueKey);
-      };
-      /*default value for absent*/
-      ValueEmbedder.absent = ValueEmbedder.fromNullable(null);
-      return ValueEmbedder;
-    }(Optional));
-    exports.ValueEmbedder = ValueEmbedder;
-    /**
-     * specialized value embedder
-     * for our Configuration
-     */
-    var ConfigEntry = /** @class */ (function (_super) {
-      __extends(ConfigEntry, _super);
-      function ConfigEntry(rootElem, key, arrPos) {
-        var _this = _super.call(this, rootElem, key) || this;
-        _this.arrPos = (arrPos !== null && arrPos !== void 0 ? arrPos : -1);
-        return _this;
-      }
-      Object.defineProperty(ConfigEntry.prototype, "value", {
-        get: function () {
-          if (this.key == "" && this.arrPos >= 0) {
-            return this._value[this.arrPos];
-          }
-          else if (this.key && this.arrPos >= 0) {
-            return this._value[this.key][this.arrPos];
-          }
-          return this._value[this.key];
-        },
-        set: function (val) {
-          if (this.key == "" && this.arrPos >= 0) {
-            this._value[this.arrPos] = val;
-            return;
-          }
-          else if (this.key && this.arrPos >= 0) {
-            this._value[this.key][this.arrPos] = val;
-            return;
-          }
-          this._value[this.key] = val;
-        },
-        enumerable: true,
-        configurable: true
-      });
-      /*default value for absent*/
-      ConfigEntry.absent = ConfigEntry.fromNullable(null);
-      return ConfigEntry;
-    }(ValueEmbedder));
-    /**
-     * Config, basically an optional wrapper for a json structure
-     * (not sideeffect free, since we can alter the internal config state
-     * without generating a new config), not sure if we should make it sideffect free
-     * since this would swallow a lot of performane and ram
-     */
-    var Config = /** @class */ (function (_super) {
-      __extends(Config, _super);
-      function Config(root) {
-        return _super.call(this, root) || this;
-      }
-      Object.defineProperty(Config.prototype, "shallowCopy", {
-        get: function () {
-          return new Config(Stream_1.Stream.ofAssoc(this.value).collect(new SourcesCollectors_1.AssocArrayCollector()));
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(Config.prototype, "deepCopy", {
-        get: function () {
-          return new Config(objAssign({}, this.value));
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Config.fromNullable = function (value) {
-        return new Config(value);
-      };
-      /**
-       * simple merge for the root configs
-       */
-      Config.prototype.shallowMerge = function (other, overwrite) {
-        if (overwrite === void 0) { overwrite = true; }
-        for (var key in other.value) {
-          if (overwrite || !(key in this.value)) {
-            this.assign(key).value = other.getIf(key).value;
-          }
-        }
-      };
-      Config.prototype.assign = function () {
-        var keys = [];
-        for (var _i = 0; _i < arguments.length; _i++) {
-          keys[_i] = arguments[_i];
-        }
-        if (keys.length < 1) {
-          return;
-        }
-        this.buildPath(keys);
-        var currKey = this.keyVal(keys[keys.length - 1]);
-        var arrPos = this.arrayIndex(keys[keys.length - 1]);
-        var retVal = new ConfigEntry(keys.length == 1 ? this.value : this.getIf.apply(this, keys.slice(0, keys.length - 1)).value, currKey, arrPos);
-        return retVal;
-      };
-      Config.prototype.assignIf = function (condition) {
-        var keys = [];
-        for (var _i = 1; _i < arguments.length; _i++) {
-          keys[_i - 1] = arguments[_i];
-        }
-        return condition ? this.assign.apply(this, keys) : { value: null };
-      };
-      Config.prototype.getIf = function () {
-        var keys = [];
-        for (var _i = 0; _i < arguments.length; _i++) {
-          keys[_i] = arguments[_i];
-        }
-        return this.getClass().fromNullable(_super.prototype.getIf.apply(this, keys).value);
-      };
-      Config.prototype.get = function (defaultVal) {
-        return this.getClass().fromNullable(_super.prototype.get.call(this, defaultVal).value);
-      };
-      //empties the current config entry
-      Config.prototype.delete = function (key) {
-        if (key in this.value) {
-          delete this.value[key];
-        }
-        return this;
-      };
-      Config.prototype.toJson = function () {
-        return JSON.stringify(this.value);
-      };
-      Config.prototype.getClass = function () {
-        return Config;
-      };
-      Config.prototype.setVal = function (val) {
-        this._value = val;
-      };
-      Config.prototype.buildPath = function (keys) {
-        var val = this;
-        var parentVal = this.getClass().fromNullable(null);
-        var parentPos = -1;
-        var alloc = function (arr, length) {
-          var length1 = arr.length;
-          var length2 = length1 + length;
-          for (var cnt = length1; cnt < length2; cnt++) {
-            arr.push({});
-          }
-        };
-        for (var cnt = 0; cnt < keys.length; cnt++) {
-          var currKey = this.keyVal(keys[cnt]);
-          var arrPos = this.arrayIndex(keys[cnt]);
-          if (currKey === "" && arrPos >= 0) {
-            val.setVal((val.value instanceof Array) ? val.value : []);
-            alloc(val.value, arrPos + 1);
-            if (parentPos >= 0) {
-              parentVal.value[parentPos] = val.value;
-            }
-            parentVal = val;
-            parentPos = arrPos;
-            val = this.getClass().fromNullable(val.value[arrPos]);
-            continue;
-          }
-          var tempVal = val.getIf(currKey);
-          if (arrPos == -1) {
-            if (tempVal.isAbsent()) {
-              tempVal = this.getClass().fromNullable(val.value[currKey] = {});
-            }
-            else {
-              val = tempVal;
-            }
-          }
-          else {
-            var arr = (tempVal.value instanceof Array) ? tempVal.value : [];
-            alloc(arr, arrPos + 1);
-            val.value[currKey] = arr;
-            tempVal = this.getClass().fromNullable(arr[arrPos]);
-          }
-          parentVal = val;
-          parentPos = arrPos;
-          val = tempVal;
-        }
-        return this;
-      };
-      return Config;
-    }(Optional));
-    exports.Config = Config;
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/ext/monadish/SourcesCollectors.ts":
-  /*!***************************************************************!*\
-  !*** ./src/main/typescript/ext/monadish/SourcesCollectors.ts ***!
-  \***************************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    var __spreadArrays = (this && this.__spreadArrays) || function () {
-      for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
-      for (var r = Array(s), k = 0, i = 0; i < il; i++)
-        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
-          r[k] = a[j];
-      return r;
-    };
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var Stream_1 = __webpack_require__(/*! ./Stream */ "./src/main/typescript/ext/monadish/Stream.ts");
-    /**
-     * implementation of iteratable on top of array
-     */
-    var ArrayStreamDataSource = /** @class */ (function () {
-      function ArrayStreamDataSource() {
-        var value = [];
-        for (var _i = 0; _i < arguments.length; _i++) {
-          value[_i] = arguments[_i];
-        }
-        this.dataPos = -1;
-        this.value = value;
-      }
-      ArrayStreamDataSource.prototype.hasNext = function () {
-        return this.value.length - 1 > this.dataPos;
-      };
-      ArrayStreamDataSource.prototype.next = function () {
-        this.dataPos++;
-        return this.value[this.dataPos];
-      };
-      ArrayStreamDataSource.prototype.reset = function () {
-        this.dataPos = -1;
-      };
-      return ArrayStreamDataSource;
-    }());
-    exports.ArrayStreamDataSource = ArrayStreamDataSource;
-    /**
-     * an intermediate data source wich prefilters
-     * incoming stream data
-     * and lets only the data out which
-     * passes the filter function check
-     */
-    var FilteredStreamDatasource = /** @class */ (function () {
-      function FilteredStreamDatasource(filterFunc, parent) {
-        this.filteredNext = null;
-        this.filterFunc = filterFunc;
-        this.inputDataSource = parent;
-      }
-      /**
-       * in order to filter we have to make a look ahead until the
-       * first next allowed element
-       * hence we prefetch the element and then
-       * serve it via next
-       */
-      FilteredStreamDatasource.prototype.hasNext = function () {
-        while (this.filteredNext == null && this.inputDataSource.hasNext()) {
-          var next = this.inputDataSource.next();
-          if (this.filterFunc(next)) {
-            this.filteredNext = next;
-            return true;
-          }
-          else {
-            this.filteredNext = null;
-          }
-        }
-        return this.filteredNext != null;
-      };
-      /**
-       * serve the next element
-       */
-      FilteredStreamDatasource.prototype.next = function () {
-        var ret = this.filteredNext;
-        this.filteredNext = null;
-        //We have to call hasNext, to roll another
-        //prefetch in case someone runs next
-        //sequentially without calling hasNext
-        this.hasNext();
-        return ret;
-      };
-      FilteredStreamDatasource.prototype.reset = function () {
-        this.filteredNext = null;
-        this.inputDataSource.reset();
-      };
-      return FilteredStreamDatasource;
-    }());
-    exports.FilteredStreamDatasource = FilteredStreamDatasource;
-    /**
-     * an intermediate datasource which maps the items from
-     * one into another
-     */
-    var MappedStreamDataSource = /** @class */ (function () {
-      function MappedStreamDataSource(mapFunc, parent) {
-        this.mapFunc = mapFunc;
-        this.inputDataSource = parent;
-      }
-      MappedStreamDataSource.prototype.hasNext = function () {
-        return this.inputDataSource.hasNext();
-      };
-      MappedStreamDataSource.prototype.next = function () {
-        return this.mapFunc(this.inputDataSource.next());
-      };
-      MappedStreamDataSource.prototype.reset = function () {
-        this.inputDataSource.reset();
-      };
-      return MappedStreamDataSource;
-    }());
-    exports.MappedStreamDataSource = MappedStreamDataSource;
-    /**
-     * Same for flatmap to deal with element -> stream mappings
-     */
-    var FlatMapStreamDataSource = /** @class */ (function () {
-      function FlatMapStreamDataSource(func, parent) {
-        this.mapFunc = func;
-        this.inputDataSource = parent;
-      }
-      FlatMapStreamDataSource.prototype.hasNext = function () {
-        return this.resolveCurrentNext() || this.resolveNextNext();
-      };
-      FlatMapStreamDataSource.prototype.resolveCurrentNext = function () {
-        var next = false;
-        if (this.activeDataSource) {
-          next = this.activeDataSource.hasNext();
-        }
-        return next;
-      };
-      FlatMapStreamDataSource.prototype.resolveNextNext = function () {
-        var next = false;
-        while (!next && this.inputDataSource.hasNext()) {
-          var mapped = this.mapFunc(this.inputDataSource.next());
-          if (Array.isArray(mapped)) {
-            this.activeDataSource = new (ArrayStreamDataSource.bind.apply(ArrayStreamDataSource, __spreadArrays([void 0], mapped)))();
-          }
-          else {
-            this.activeDataSource = mapped;
-          }
-          next = this.activeDataSource.hasNext();
-        }
-        return next;
-      };
-      FlatMapStreamDataSource.prototype.next = function () {
-        return this.activeDataSource.next();
-      };
-      FlatMapStreamDataSource.prototype.reset = function () {
-        this.inputDataSource.reset();
-      };
-      return FlatMapStreamDataSource;
-    }());
-    exports.FlatMapStreamDataSource = FlatMapStreamDataSource;
-    /**
-     * For the time being we only need one collector
-     * a collector which collects a stream back into arrays
-     */
-    var ArrayCollector = /** @class */ (function () {
-      function ArrayCollector() {
-        this.data = [];
-      }
-      ArrayCollector.prototype.collect = function (element) {
-        this.data.push(element);
-      };
-      Object.defineProperty(ArrayCollector.prototype, "finalValue", {
-        get: function () {
-          return this.data;
-        },
-        enumerable: true,
-        configurable: true
-      });
-      return ArrayCollector;
-    }());
-    exports.ArrayCollector = ArrayCollector;
-    /**
-     * collects an assoc stream back to an assoc array
-     */
-    var AssocArrayCollector = /** @class */ (function () {
-      function AssocArrayCollector() {
-        this.finalValue = {};
-      }
-      AssocArrayCollector.prototype.collect = function (element) {
-        var _a, _b;
-        this.finalValue[_a = element[0], (_a !== null && _a !== void 0 ? _a : element)] = (_b = element[1], (_b !== null && _b !== void 0 ? _b : true));
-      };
-      return AssocArrayCollector;
-    }());
-    exports.AssocArrayCollector = AssocArrayCollector;
-    /**
-     * Form data collector for key value pair streams
-     */
-    var FormDataCollector = /** @class */ (function () {
-      function FormDataCollector() {
-        this.finalValue = new FormData();
-      }
-      FormDataCollector.prototype.collect = function (element) {
-        this.finalValue.append(element.key, element.value);
-      };
-      return FormDataCollector;
-    }());
-    exports.FormDataCollector = FormDataCollector;
-    /**
-     * Form data collector for DomQuery streams
-     */
-    var QueryFormDataCollector = /** @class */ (function () {
-      function QueryFormDataCollector() {
-        this.finalValue = new FormData();
-      }
-      QueryFormDataCollector.prototype.collect = function (element) {
-        var toMerge = element.encodeFormElement();
-        if (toMerge.isPresent()) {
-          this.finalValue.append(element.name.value, toMerge.get(element.name).value);
-        }
-      };
-      return QueryFormDataCollector;
-    }());
-    exports.QueryFormDataCollector = QueryFormDataCollector;
-    /**
-     * Encoded String collector from dom query streams
-     */
-    var QueryFormStringCollector = /** @class */ (function () {
-      function QueryFormStringCollector() {
-        this.formData = [];
-      }
-      QueryFormStringCollector.prototype.collect = function (element) {
-        var toMerge = element.encodeFormElement();
-        if (toMerge.isPresent()) {
-          this.formData.push([element.name.value, toMerge.get(element.name).value]);
-        }
-      };
-      Object.defineProperty(QueryFormStringCollector.prototype, "finalValue", {
-        get: function () {
-          return Stream_1.Stream.of.apply(Stream_1.Stream, this.formData).map(function (keyVal) { return keyVal.join("="); })
-              .reduce(function (item1, item2) { return [item1, item2].join("&"); })
-              .orElse("").value;
-        },
-        enumerable: true,
-        configurable: true
-      });
-      return QueryFormStringCollector;
-    }());
-    exports.QueryFormStringCollector = QueryFormStringCollector;
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/ext/monadish/Stream.ts":
-  /*!****************************************************!*\
-  !*** ./src/main/typescript/ext/monadish/Stream.ts ***!
-  \****************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    var __spreadArrays = (this && this.__spreadArrays) || function () {
-      for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
-      for (var r = Array(s), k = 0, i = 0; i < il; i++)
-        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
-          r[k] = a[j];
-      return r;
-    };
-    Object.defineProperty(exports, "__esModule", { value: true });
-    /*
- * A small stream implementation
- */
-    var Monad_1 = __webpack_require__(/*! ./Monad */ "./src/main/typescript/ext/monadish/Monad.ts");
-    var SourcesCollectors_1 = __webpack_require__(/*! ./SourcesCollectors */ "./src/main/typescript/ext/monadish/SourcesCollectors.ts");
-    /**
-     * A simple typescript based reimplementation of streams
-     *
-     * This is the early eval version
-     * for a lazy eval version check, LazyStream, which is api compatible
-     * to this implementation, however with the benefit of being able
-     * to provide infinite data sources and generic data providers, the downside
-     * is, it might be a tad slower in some situations
-     */
-    var Stream = /** @class */ (function () {
-      function Stream() {
-        var value = [];
-        for (var _i = 0; _i < arguments.length; _i++) {
-          value[_i] = arguments[_i];
-        }
-        this._limits = -1;
-        this.pos = -1;
-        this.value = value;
-      }
-      Stream.of = function () {
-        var data = [];
-        for (var _i = 0; _i < arguments.length; _i++) {
-          data[_i] = arguments[_i];
-        }
-        return new (Stream.bind.apply(Stream, __spreadArrays([void 0], data)))();
-      };
-      Stream.ofAssoc = function (data) {
-        return this.of.apply(this, Object.keys(data)).map(function (key) { return [key, data[key]]; });
-      };
-      Stream.ofDataSource = function (dataSource) {
-        var value = [];
-        while (dataSource.hasNext()) {
-          value.push(dataSource.next());
-        }
-        return new (Stream.bind.apply(Stream, __spreadArrays([void 0], value)))();
-      };
-      Stream.prototype.limits = function (end) {
-        this._limits = end;
-        return this;
-      };
-      Stream.prototype.onElem = function (fn) {
-        for (var cnt = 0; cnt < this.value.length && (this._limits == -1 || cnt < this._limits); cnt++) {
-          if (fn(this.value[cnt], cnt) === false) {
-            break;
-          }
-        }
-        return this;
-      };
-      Stream.prototype.each = function (fn) {
-        this.onElem(fn);
-      };
-      Stream.prototype.map = function (fn) {
-        if (!fn) {
-          fn = function (inval) { return inval; };
-        }
-        var res = [];
-        this.each(function (item, cnt) {
-          res.push(fn(item));
-        });
-        return new (Stream.bind.apply(Stream, __spreadArrays([void 0], res)))();
-      };
-      /*
-     * we need to implement it to fullfill the contract, although it is used only internally
-     * all values are flattened when accessed anyway, so there is no need to call this methiod
-     */
-      Stream.prototype.flatMap = function (fn) {
-        var ret = [];
-        this.each(function (item) {
-          var strmR = fn(item);
-          ret = Array.isArray(strmR) ? ret.concat(strmR) : ret.concat.apply(ret, strmR.value);
-        });
-        return Stream.of.apply(Stream, ret);
-      };
-      Stream.prototype.filter = function (fn) {
-        var res = [];
-        this.each(function (data) {
-          if (fn(data)) {
-            res.push(data);
-          }
-        });
-        return new (Stream.bind.apply(Stream, __spreadArrays([void 0], res)))();
-      };
-      Stream.prototype.reduce = function (fn, startVal) {
-        if (startVal === void 0) { startVal = null; }
-        var offset = startVal != null ? 0 : 1;
-        var val1 = startVal != null ? startVal : this.value.length ? this.value[0] : null;
-        for (var cnt = offset; cnt < this.value.length && (this._limits == -1 || cnt < this._limits); cnt++) {
-          val1 = fn(val1, this.value[cnt]);
-        }
-        return Monad_1.Optional.fromNullable(val1);
-      };
-      Stream.prototype.first = function () {
-        return this.value && this.value.length ? Monad_1.Optional.fromNullable(this.value[0]) : Monad_1.Optional.absent;
-      };
-      Stream.prototype.last = function () {
-        //could be done via reduce, but is faster this way
-        var length = this._limits > 0 ? Math.min(this._limits, this.value.length) : this.value.length;
-        return Monad_1.Optional.fromNullable(length ? this.value[length - 1] : null);
-      };
-      Stream.prototype.anyMatch = function (fn) {
-        for (var cnt = 0; cnt < this.value.length && (this._limits == -1 || cnt < this._limits); cnt++) {
-          if (fn(this.value[cnt])) {
-            return true;
-          }
-        }
-        return false;
-      };
-      Stream.prototype.allMatch = function (fn) {
-        if (!this.value.length) {
-          return false;
-        }
-        var matches = 0;
-        for (var cnt = 0; cnt < this.value.length; cnt++) {
-          if (fn(this.value[cnt])) {
-            matches++;
-          }
-        }
-        return matches == this.value.length;
-      };
-      Stream.prototype.noneMatch = function (fn) {
-        var matches = 0;
-        for (var cnt = 0; cnt < this.value.length; cnt++) {
-          if (!fn(this.value[cnt])) {
-            matches++;
-          }
-        }
-        return matches == this.value.length;
-      };
-      Stream.prototype.sort = function (comparator) {
-        var newArr = this.value.slice().sort(comparator);
-        return Stream.of.apply(Stream, newArr);
-      };
-      Stream.prototype.collect = function (collector) {
-        this.each(function (data) { return collector.collect(data); });
-        return collector.finalValue;
-      };
-      //-- internally exposed methods needed for the interconnectivity
-      Stream.prototype.hasNext = function () {
-        var isLimitsReached = this._limits != -1 && this.pos >= this._limits - 1;
-        var isEndOfArray = this.pos >= this.value.length - 1;
-        return !(isLimitsReached || isEndOfArray);
-      };
-      Stream.prototype.next = function () {
-        if (!this.hasNext()) {
-          return null;
-        }
-        this.pos++;
-        return this.value[this.pos];
-      };
-      Stream.prototype.reset = function () {
-        this.pos = -1;
-      };
-      return Stream;
-    }());
-    exports.Stream = Stream;
-    /**
-     * Lazy implementation of a Stream
-     * The idea is to connect the intermediate
-     * streams as datasources like a linked list
-     * with reverse referencing and for special
-     * operations like filtering flatmapping
-     * have intermediate datasources in the list
-     * with specialized functions.
-     *
-     * Sort of a modified pipe valve pattern
-     * the streams are the pipes the intermediate
-     * data sources are the valves
-     *
-     * We then can use passed in functions to control
-     * the flow in the valves
-     *
-     * That way we can have a lazy evaluating stream
-     *
-     * So if an endpoint requests data
-     * a callback trace goes back the stream list
-     * which triggers an operation upwards
-     * which sends data down the drain which then is processed
-     * and filtered until one element hits the endpoint.
-     *
-     * That is repeated, until all elements are processed
-     * or an internal limit is hit.
-     *
-     */
-    var LazyStream = /** @class */ (function () {
-      function LazyStream(parent) {
-        this._limits = -1;
-        /*
-         * needed to have the limits check working
-         * we need to keep track of the current position
-         * in the stream
-         */
-        this.pos = -1;
-        this.dataSource = parent;
-      }
-      LazyStream.of = function () {
-        var values = [];
-        for (var _i = 0; _i < arguments.length; _i++) {
-          values[_i] = arguments[_i];
-        }
-        return new LazyStream(new (SourcesCollectors_1.ArrayStreamDataSource.bind.apply(SourcesCollectors_1.ArrayStreamDataSource, __spreadArrays([void 0], values)))());
-      };
-      LazyStream.ofAssoc = function (data) {
-        return this.of.apply(this, Object.keys(data)).map(function (key) { return [key, data[key]]; });
-      };
-      LazyStream.ofStreamDataSource = function (value) {
-        return new LazyStream(value);
-      };
-      LazyStream.prototype.hasNext = function () {
-        if (this.isOverLimits()) {
-          return false;
-        }
-        return this.dataSource.hasNext();
-      };
-      LazyStream.prototype.next = function () {
-        var next = this.dataSource.next();
-        // @ts-ignore
-        this.pos++;
-        return next;
-      };
-      LazyStream.prototype.reset = function () {
-        this.dataSource.reset();
-        this.pos = 0;
-        this._limits = -1;
-      };
-      LazyStream.prototype.nextFilter = function (fn) {
-        if (this.hasNext()) {
-          var newVal = this.next();
-          if (!fn(newVal)) {
-            return this.nextFilter(fn);
-          }
-          return newVal;
-        }
-        return null;
-      };
-      LazyStream.prototype.limits = function (max) {
-        this._limits = max;
-        return this;
-      };
-      //main stream methods
-      LazyStream.prototype.collect = function (collector) {
-        while (this.hasNext()) {
-          var t = this.next();
-          collector.collect(t);
-        }
-        return collector.finalValue;
-      };
-      LazyStream.prototype.onElem = function (fn) {
-        var _this = this;
-        return new LazyStream(new SourcesCollectors_1.MappedStreamDataSource(function (el) {
-          if (fn(el, _this.pos) === false) {
-            _this.stop();
-          }
-          return el;
-        }, this));
-      };
-      LazyStream.prototype.filter = function (fn) {
-        return new LazyStream(new SourcesCollectors_1.FilteredStreamDatasource(fn, this));
-      };
-      LazyStream.prototype.map = function (fn) {
-        return new LazyStream(new SourcesCollectors_1.MappedStreamDataSource(fn, this));
-      };
-      LazyStream.prototype.flatMap = function (fn) {
-        return new LazyStream(new SourcesCollectors_1.FlatMapStreamDataSource(fn, this));
-      };
-      //endpoint
-      LazyStream.prototype.each = function (fn) {
-        while (this.hasNext()) {
-          if (fn(this.next()) === false) {
-            this.stop();
-          }
-        }
-      };
-      LazyStream.prototype.reduce = function (fn, startVal) {
-        if (startVal === void 0) { startVal = null; }
-        if (!this.hasNext()) {
-          return Monad_1.Optional.absent;
-        }
-        var value1 = null;
-        var value2 = null;
-        if (startVal != null) {
-          value1 = startVal;
-          value2 = this.next();
-        }
-        else {
-          value1 = this.next();
-          if (!this.hasNext()) {
-            return Monad_1.Optional.fromNullable(value1);
-          }
-          value2 = this.next();
-        }
-        value1 = fn(value1, value2);
-        while (this.hasNext()) {
-          value2 = this.next();
-          value1 = fn(value1, value2);
-        }
-        return Monad_1.Optional.fromNullable(value1);
-      };
-      LazyStream.prototype.last = function () {
-        if (!this.hasNext()) {
-          return Monad_1.Optional.absent;
-        }
-        return this.reduce(function (el1, el2) { return el2; });
-      };
-      LazyStream.prototype.first = function () {
-        this.reset();
-        if (!this.hasNext()) {
-          return Monad_1.Optional.absent;
-        }
-        return Monad_1.Optional.fromNullable(this.next());
-      };
-      LazyStream.prototype.anyMatch = function (fn) {
-        while (this.hasNext()) {
-          if (fn(this.next())) {
-            return true;
-          }
-        }
-        return false;
-      };
-      LazyStream.prototype.allMatch = function (fn) {
-        while (this.hasNext()) {
-          if (!fn(this.next())) {
-            return false;
-          }
-        }
-        return true;
-      };
-      LazyStream.prototype.noneMatch = function (fn) {
-        while (this.hasNext()) {
-          if (fn(this.next())) {
-            return false;
-          }
-        }
-        return true;
-      };
-      LazyStream.prototype.sort = function (comparator) {
-        var arr = this.collect(new SourcesCollectors_1.ArrayCollector());
-        arr = arr.sort(comparator);
-        return LazyStream.of.apply(LazyStream, arr);
-      };
-      Object.defineProperty(LazyStream.prototype, "value", {
-        get: function () {
-          return this.collect(new SourcesCollectors_1.ArrayCollector());
-        },
-        enumerable: true,
-        configurable: true
-      });
-      LazyStream.prototype.stop = function () {
-        this.pos = this._limits + 1000000000;
-      };
-      LazyStream.prototype.isOverLimits = function () {
-        return this._limits != -1 && this.pos >= this._limits - 1;
-      };
-      return LazyStream;
-    }());
-    exports.LazyStream = LazyStream;
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/ext/monadish/XmlQuery.ts":
-  /*!******************************************************!*\
-  !*** ./src/main/typescript/ext/monadish/XmlQuery.ts ***!
-  \******************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    var __extends = (this && this.__extends) || (function () {
-      var extendStatics = function (d, b) {
-        extendStatics = Object.setPrototypeOf ||
-            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
-        return extendStatics(d, b);
-      };
-      return function (d, b) {
-        extendStatics(d, b);
-        function __() { this.constructor = d; }
-        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-      };
-    })();
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var Lang_1 = __webpack_require__(/*! ./Lang */ "./src/main/typescript/ext/monadish/Lang.ts");
-    var DomQuery_1 = __webpack_require__(/*! ./DomQuery */ "./src/main/typescript/ext/monadish/DomQuery.ts");
-    var isString = Lang_1.Lang.isString;
-    /**
-     * xml query as specialized case for DomQuery
-     */
-    var XMLQuery = /** @class */ (function (_super) {
-      __extends(XMLQuery, _super);
-      function XMLQuery(rootNode, docType) {
-        if (docType === void 0) { docType = "text/xml"; }
-        var _this = this;
-        var createIe11DomQueryShim = function () {
-          //at the time if wroting ie11 is the only relevant browser
-          //left withut any DomQuery support
-          var parser = new ActiveXObject("Microsoft.XMLDOM");
-          parser.async = false;
-          //we shim th dom parser from ie in
-          return {
-            parseFromString: function (text, contentType) {
-              return parser.loadXML(text);
-            }
-          };
-        };
-        var parseXML = function (xml) {
-          if (xml == null) {
-            return null;
-          }
-          var domParser = Lang_1.Lang.saveResolveLazy(function () { return new window.DOMParser(); }, function () { return createIe11DomQueryShim(); }).value;
-          return domParser.parseFromString(xml, docType);
-        };
-        if (isString(rootNode)) {
-          _this = _super.call(this, parseXML(rootNode)) || this;
-        }
-        else {
-          _this = _super.call(this, rootNode) || this;
-        }
-        return _this;
-      }
-      XMLQuery.prototype.isXMLParserError = function () {
-        return this.querySelectorAll("parsererror").isPresent();
-      };
-      XMLQuery.prototype.toString = function () {
-        var ret = [];
-        this.eachElem(function (node) {
-          var _a, _b, _c, _d, _e;
-          var serialized = (_d = (_c = (_b = (_a = window) === null || _a === void 0 ? void 0 : _a.XMLSerializer) === null || _b === void 0 ? void 0 : _b.constructor()) === null || _c === void 0 ? void 0 : _c.serializeToString(node), (_d !== null && _d !== void 0 ? _d : (_e = node) === null || _e === void 0 ? void 0 : _e.xml));
-          if (!!serialized) {
-            ret.push(serialized);
-          }
-        });
-        return ret.join("");
-      };
-      XMLQuery.prototype.parserErrorText = function (joinstr) {
-        return this.querySelectorAll("parsererror").textContent(joinstr);
-      };
-      XMLQuery.parseXML = function (txt) {
-        return new XMLQuery(txt);
-      };
-      XMLQuery.parseHTML = function (txt) {
-        return new XMLQuery(txt, "text/html");
-      };
-      XMLQuery.fromString = function (txt, parseType) {
-        if (parseType === void 0) { parseType = "text/xml"; }
-        return new XMLQuery(txt, parseType);
-      };
-      return XMLQuery;
-    }(DomQuery_1.DomQuery));
-    exports.XMLQuery = XMLQuery;
-    exports.XQ = XMLQuery;
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/ext/monadish/index.ts":
-  /*!***************************************************!*\
-  !*** ./src/main/typescript/ext/monadish/index.ts ***!
-  \***************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var DomQuery_1 = __webpack_require__(/*! ./DomQuery */ "./src/main/typescript/ext/monadish/DomQuery.ts");
-    exports.DomQuery = DomQuery_1.DomQuery;
-    exports.ElementAttribute = DomQuery_1.ElementAttribute;
-    exports.DomQueryCollector = DomQuery_1.DomQueryCollector;
-    exports.DQ = DomQuery_1.DQ;
-    var Lang_1 = __webpack_require__(/*! ./Lang */ "./src/main/typescript/ext/monadish/Lang.ts");
-    exports.Lang = Lang_1.Lang;
-    var Monad_1 = __webpack_require__(/*! ./Monad */ "./src/main/typescript/ext/monadish/Monad.ts");
-    exports.Config = Monad_1.Config;
-    exports.Monad = Monad_1.Monad;
-    exports.Optional = Monad_1.Optional;
-    exports.ValueEmbedder = Monad_1.ValueEmbedder;
-    var XmlQuery_1 = __webpack_require__(/*! ./XmlQuery */ "./src/main/typescript/ext/monadish/XmlQuery.ts");
-    exports.XMLQuery = XmlQuery_1.XMLQuery;
-    exports.XQ = XmlQuery_1.XQ;
-    var Stream_1 = __webpack_require__(/*! ./Stream */ "./src/main/typescript/ext/monadish/Stream.ts");
-    exports.Stream = Stream_1.Stream;
-    exports.LazyStream = Stream_1.LazyStream;
-    var SourcesCollectors_1 = __webpack_require__(/*! ./SourcesCollectors */ "./src/main/typescript/ext/monadish/SourcesCollectors.ts");
-    exports.ArrayStreamDataSource = SourcesCollectors_1.ArrayStreamDataSource;
-    exports.MappedStreamDataSource = SourcesCollectors_1.MappedStreamDataSource;
-    exports.FilteredStreamDatasource = SourcesCollectors_1.FilteredStreamDatasource;
-    exports.FlatMapStreamDataSource = SourcesCollectors_1.FlatMapStreamDataSource;
-    exports.QueryFormStringCollector = SourcesCollectors_1.QueryFormStringCollector;
-    exports.ArrayCollector = SourcesCollectors_1.ArrayCollector;
-    exports.AssocArrayCollector = SourcesCollectors_1.AssocArrayCollector;
-    exports.FormDataCollector = SourcesCollectors_1.FormDataCollector;
-    exports.QueryFormDataCollector = SourcesCollectors_1.QueryFormDataCollector;
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/AjaxImpl.ts":
-  /*!**********************************************!*\
-  !*** ./src/main/typescript/impl/AjaxImpl.ts ***!
-  \**********************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var myfacesConfig = __webpack_require__(/*! ../api/Myfaces */ "./src/main/typescript/api/Myfaces.ts");
-    var Response_1 = __webpack_require__(/*! ./xhrCore/Response */ "./src/main/typescript/impl/xhrCore/Response.ts");
-    var XhrRequest_1 = __webpack_require__(/*! ./xhrCore/XhrRequest */ "./src/main/typescript/impl/xhrCore/XhrRequest.ts");
-    var AsyncQueue_1 = __webpack_require__(/*! ./util/AsyncQueue */ "./src/main/typescript/impl/util/AsyncQueue.ts");
-    var monadish_1 = __webpack_require__(/*! ../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
-    var Assertions_1 = __webpack_require__(/*! ./util/Assertions */ "./src/main/typescript/impl/util/Assertions.ts");
-    var XhrFormData_1 = __webpack_require__(/*! ./xhrCore/XhrFormData */ "./src/main/typescript/impl/xhrCore/XhrFormData.ts");
-    var ExtDomQuery_1 = __webpack_require__(/*! ./util/ExtDomQuery */ "./src/main/typescript/impl/util/ExtDomQuery.ts");
-    var ErrorData_1 = __webpack_require__(/*! ./xhrCore/ErrorData */ "./src/main/typescript/impl/xhrCore/ErrorData.ts");
-    var Lang_1 = __webpack_require__(/*! ./util/Lang */ "./src/main/typescript/impl/util/Lang.ts");
-    var Const_1 = __webpack_require__(/*! ./core/Const */ "./src/main/typescript/impl/core/Const.ts");
-    var RequestDataResolver_1 = __webpack_require__(/*! ./xhrCore/RequestDataResolver */ "./src/main/typescript/impl/xhrCore/RequestDataResolver.ts");
-    /*
- * allowed project stages
- */
-    var ProjectStages;
-    (function (ProjectStages) {
-      ProjectStages["Production"] = "Production";
-      ProjectStages["Development"] = "Development";
-      ProjectStages["SystemTest"] = "SystemTest";
-      ProjectStages["UnitTest"] = "UnitTest";
-    })(ProjectStages || (ProjectStages = {}));
-    /*
- *   blockfilter for the passthrough filtering; the attributes given here
- *   will not be transmitted from the options into the passthrough
- */
-    var BlockFilter;
-    (function (BlockFilter) {
-      BlockFilter["onerror"] = "onerror";
-      BlockFilter["onevent"] = "onevent";
-      BlockFilter["render"] = "render";
-      BlockFilter["execute"] = "execute";
-      BlockFilter["myfaces"] = "myfaces";
-      BlockFilter["delay"] = "delay";
-      BlockFilter["timeout"] = "timeout";
-      BlockFilter["windowId"] = "windowId";
-    })(BlockFilter || (BlockFilter = {}));
-    /**
-     * Core Implementation
-     * to distinct between api and impl
-     *
-     * The original idea was to make the implementation pluggable
-     * but this is pointless, you always can overwrite the thin api layer
-     * however a dedicated api makes sense for readability reasons
-     */
-    var Implementation;
-    (function (Implementation) {
-      var trim = monadish_1.Lang.trim;
-      var getMessage = Lang_1.ExtLang.getMessage;
-      var getGlobalConfig = Lang_1.ExtLang.getGlobalConfig;
-      var assert = Assertions_1.Assertions.assert;
-      var globalConfig = myfacesConfig.myfaces.config;
-      var projectStage = null;
-      var separator = null;
-      var eventQueue = [];
-      var errorQueue = [];
-      Implementation.requestQueue = null;
-      /*error reporting threshold*/
-      var threshold = "ERROR";
-      /**
-       * fetches the separator char from the given script tags
-       *
-       * @return {char} the separator char for the given script tags
-       */
-      function getSeparatorChar() {
-        var _a, _b, _c, _d, _e;
-        return _e = (_c = (_b = (_a = this) === null || _a === void 0 ? void 0 : _a.globalConfig) === null || _b === void 0 ? void 0 : _b.separator, (_c !== null && _c !== void 0 ? _c : (_d = this) === null || _d === void 0 ? void 0 : _d.separator)), (_e !== null && _e !== void 0 ? _e : (separator = ExtDomQuery_1.ExtDomquery.searchJsfJsFor(/separator=([^&;]*)/).orElse(":").value));
-      }
-      Implementation.getSeparatorChar = getSeparatorChar;
-      /**
-       * this is for testing purposes only, since AjaxImpl is a module
-       * we need to reset for every unit test its internal states
-       */
-      function reset() {
-        globalConfig = myfacesConfig.myfaces.config;
-        projectStage = null;
-        separator = null;
-        eventQueue = [];
-        errorQueue = [];
-        Implementation.requestQueue = null;
-      }
-      Implementation.reset = reset;
-      /**
-       * @return the project stage also emitted by the server:
-       * it cannot be cached and must be delivered over the server
-       * The value for it comes from the requestInternal parameter of the jsf.js script called "stage".
-       */
-      function getProjectStage() {
-        var _a, _b, _c, _d, _e;
-        return _e = (_c = (_b = (_a = this) === null || _a === void 0 ? void 0 : _a.globalConfig) === null || _b === void 0 ? void 0 : _b.projectStage, (_c !== null && _c !== void 0 ? _c : (_d = this) === null || _d === void 0 ? void 0 : _d.projectStage)), (_e !== null && _e !== void 0 ? _e : (projectStage = resolveProjectStateFromURL()));
-      }
-      Implementation.getProjectStage = getProjectStage;
-      /**
-       * resolves the project stage as url parameter
-       * @return the project stage or null
-       */
-      function resolveProjectStateFromURL() {
-        /* run through all script tags and try to find the one that includes jsf.js */
-        var foundStage = ExtDomQuery_1.ExtDomquery.searchJsfJsFor(/stage=([^&;]*)/).value;
-        return (foundStage in ProjectStages) ? foundStage : null;
-      }
-      Implementation.resolveProjectStateFromURL = resolveProjectStateFromURL;
-      /**
-       * implementation of the jsf.util.chain functionality
-       *
-       * @param source
-       * @param event
-       * @param funcs
-       */
-      function chain(source, event) {
-        var funcs = [];
-        for (var _i = 2; _i < arguments.length; _i++) {
-          funcs[_i - 2] = arguments[_i];
-        }
-        var ret = true;
-        var resolveAndExecute = function (func) {
-          if ("string" != typeof func) {
-            //function is passed down as chain parameter, can be executed as is
-            return (ret = ret && (func.call(source, event) !== false));
-          }
-          else {
-            //either a function or a string can be passed in case of a string we have to wrap it into another function
-            //it it is not a plain executable code but a definition
-            var sourceCode = trim(func);
-            if (sourceCode.indexOf("function ") == 0) {
-              sourceCode = "return " + sourceCode + " (event)";
-            }
-            return (ret = ret && (new Function("event", sourceCode).call(source, event) !== false));
-          }
-        };
-        //we can use our stream each functionality to run our chain here..
-        //the no return value == false stop stream functionality is handled by our resolveAndExecute
-        monadish_1.Stream.of.apply(monadish_1.Stream, funcs).each(function (func) { return resolveAndExecute(func); });
-        return ret;
-      }
-      Implementation.chain = chain;
-      /**
-       * this function has to send the ajax requests
-       *
-       * following request conditions must be met:
-       * <ul>
-       *  <li> the request must be sent asynchronously! </li>
-       *  <li> the request must be a POST!!! request </li>
-       *  <li> the request url must be the form action attribute </li>
-       *  <li> all requests must be queued with a client side request queue to ensure the request ordering!</li>
-       * </ul>
-       *
-       * @param el any dom element no matter being it html or jsf, from which the event is emitted
-       * @param event any javascript event supported by that object
-       * @param opts  map of options being pushed into the ajax cycle
-       *
-       * a) transformArguments out of the function
-       * b) passThrough handling with a map copy with a filter map block map
-       */
-      function request(el, event, opts) {
-        var _a, _b, _c, _d;
-        var _e = RequestDataResolver_1.resolveDefaults(event, opts, el), resolvedEvent = _e.resolvedEvent, options = _e.options, elem = _e.elem, elementId = _e.elementId, requestCtx = _e.requestCtx, internalCtx = _e.internalCtx, windowId = _e.windowId, isResetValues = _e.isResetValues;
-        Assertions_1.Assertions.assertRequestIntegrity(options, elem);
-        requestCtx.assignIf(!!windowId, Const_1.P_WINDOW_ID).value = windowId;
-        requestCtx.assign(Const_1.CTX_PARAM_PASS_THR).value = filterPassthroughValues(options.value);
-        requestCtx.assignIf(!!resolvedEvent, Const_1.CTX_PARAM_PASS_THR, Const_1.P_EVT).value = (_a = resolvedEvent) === null || _a === void 0 ? void 0 : _a.type;
-        /**
-         * ajax pass through context with the source
-         * onresolvedEvent and onerror
-         */
-        requestCtx.assign(Const_1.SOURCE).value = elementId.value;
-        /**
-         * on resolvedEvent and onError...
-         * those values will be traversed later on
-         * also into the response context
-         */
-        requestCtx.assign(Const_1.ON_EVENT).value = (_b = options.value) === null || _b === void 0 ? void 0 : _b.onevent;
-        requestCtx.assign(Const_1.ON_ERROR).value = (_c = options.value) === null || _c === void 0 ? void 0 : _c.onerror;
-        /**
-         * lets drag the myfaces config params also in
-         */
-        requestCtx.assign(Const_1.MYFACES).value = (_d = options.value) === null || _d === void 0 ? void 0 : _d.myfaces;
-        /**
-         * fetch the parent form
-         *
-         * note we also add an override possibility here
-         * so that people can use dummy forms and work
-         * with detached objects
-         */
-        var form = RequestDataResolver_1.resolveForm(requestCtx, elem, resolvedEvent);
-        /**
-         * binding contract the javax.faces.source must be set
-         */
-        requestCtx.assign(Const_1.CTX_PARAM_PASS_THR, Const_1.P_PARTIAL_SOURCE).value = elementId.value;
-        /**
-         * javax.faces.partial.ajax must be set to true
-         */
-        requestCtx.assign(Const_1.CTX_PARAM_PASS_THR, Const_1.P_AJAX).value = true;
-        /**
-         * binding contract the javax.faces.source must be set
-         */
-        requestCtx.assign(Const_1.CTX_PARAM_PASS_THR, Const_1.P_PARTIAL_SOURCE).value = elementId.value;
-        /**
-         * if resetValues is set to true
-         * then we have to set javax.faces.resetValues as well
-         * as pass through parameter
-         * the value has to be explicitly true, according to
-         * the specs jsdoc
-         */
-        requestCtx.assignIf(isResetValues, Const_1.CTX_PARAM_PASS_THR, Const_1.P_RESET_VALUES).value = true;
-        //additional meta information to speed things up, note internal non jsf
-        //pass through options are stored under _mfInternal in the context
-        internalCtx.assign(Const_1.CTX_PARAM_SRC_FRM_ID).value = form.id.value;
-        internalCtx.assign(Const_1.CTX_PARAM_SRC_CTL_ID).value = elementId.value;
-        internalCtx.assign(Const_1.CTX_PARAM_TR_TYPE).value = Const_1.REQ_TYPE_POST;
-        //mojarra compatibility, mojarra is sending the form id as well
-        //this is not documented behavior but can be determined by running
-        //mojarra under blackbox conditions
-        //i assume it does the same as our formId_submit=1 so leaving it out
-        //wont hurt but for the sake of compatibility we are going to add it
-        requestCtx.assign(Const_1.CTX_PARAM_PASS_THR, form.id.value).value = form.id.value;
-        assignClientWindowId(form, requestCtx);
-        assignExecute(options, requestCtx, form, elementId.value);
-        assignRender(options, requestCtx, form, elementId.value);
-        var delay = RequestDataResolver_1.resolveDelay(options);
-        var timeout = RequestDataResolver_1.resolveTimeout(options);
-        //now we enqueue the request as asynchronous runnable into our request
-        //queue and let the queue take over the rest
-        Implementation.queueHandler.addRequestToQueue(elem, form, requestCtx, internalCtx, delay, timeout);
-      }
-      Implementation.request = request;
-      /**
-       * Spec. 13.3.3
-       * Examining the response markup and updating the DOM tree
-       * @param {XMLHttpRequest} request - the ajax request
-       * @param {Object} context - the ajax context
-       */
-      function response(request, context) {
-        Response_1.Response.processResponse(request, context);
-      }
-      Implementation.response = response;
-      /**
-       * adds an error handler to the error queue
-       *
-       * @param errorListener the error listener handler
-       */
-      function addOnError(errorListener) {
-        /*error handling already done in the assert of the queue*/
-        errorQueue.push(errorListener);
-      }
-      Implementation.addOnError = addOnError;
-      /**
-       * adds an event handler to the event queue
-       *
-       * @param eventListener the event listener handler
-       */
-      function addOnEvent(eventListener) {
-        /*error handling already done in the assert of the queue*/
-        eventQueue.push(eventListener);
-      }
-      Implementation.addOnEvent = addOnEvent;
-      // noinspection JSUnusedLocalSymbols
-      /**
-       * sends an event to the event handlers
-       *
-       * @param data the event data object hosting the event data according to the spec @see EventData for what is reachable
-       * @param localHandler an optional event handler, which is processed before the event handler chain
-       */
-      function sendEvent(data, localHandler) {
-        if (localHandler === void 0) { localHandler = function (data) {
-        }; }
-        /*now we serve the queue as well*/
-        localHandler(data);
-        eventQueue.forEach(function (fn) { return fn(data); });
-      }
-      Implementation.sendEvent = sendEvent;
-      /**
-       * error handler behavior called internally
-       * and only into the impl it takes care of the
-       * internal message transformation to a myfaces internal error
-       * and then uses the standard send error mechanisms
-       * also a double error logging prevention is done as well
-       *
-       * @param request the request currently being processed
-       * @param context the context affected by this error
-       * @param exception the exception being thrown
-       * @param clearRequestQueue if set to true, clears the request queue of all pending requests
-       */
-      function stdErrorHandler(request, context, exception, clearRequestQueue) {
-        if (clearRequestQueue === void 0) { clearRequestQueue = false; }
-        //newer browsers do not allow to hold additional values on native objects like exceptions
-        //we hence capsule it into the request, which is gced automatically
-        //on ie as well, since the stdErrorHandler usually is called between requests
-        //this is a valid approach
-        try {
-          if (threshold == "ERROR") {
-            var errorData = ErrorData_1.ErrorData.fromClient(exception);
-            sendError(errorData);
-          }
-        }
-        finally {
-          if (clearRequestQueue) {
-            Implementation.requestQueue.cleanup();
-          }
-        }
-      }
-      Implementation.stdErrorHandler = stdErrorHandler;
-      // noinspection JSUnusedLocalSymbols
-      /**
-       * implementation triggering the error chain
-       *
-       *
-       *
-       *  handles the errors, in case of an onError exists within the context the onError is called as local error handler
-       *  the registered error handlers in the queue receiv an error message to be dealt with
-       *  and if the projectStage is at development an alert box is displayed
-       *
-       *  note: we have additional functionality here, via the global config myfaces.config.defaultErrorOutput a function can be provided
-       *  which changes the default output behavior from alert to something else
-       *
-       * @param errorData the error data to be displayed
-       * @param localHandler an optional local error handler which has to be processed before the error handler queue
-       */
-      function sendError(errorData, localHandler) {
-        if (localHandler === void 0) { localHandler = function (data) {
-        }; }
-        localHandler(errorData);
-        errorQueue.forEach(function (errorCallback) {
-          errorCallback(errorData);
-        });
-        var displayError = getGlobalConfig("defaultErrorOutput", (console ? console.error : alert));
-        displayError(errorData);
-      }
-      Implementation.sendError = sendError;
-      /**
-       * @node optional element or id defining a rootnode where an element with the id "javax.faces.windowId" is hosted
-       * @return the client window id of the current window, if one is given if none is found, null is returned
-       */
-      function getClientWindow(node) {
-        var _a;
-        var ALTERED = "___mf_id_altered__";
-        var INIT = "___init____";
-        /**
-         * the search root for the dom element search
-         */
-        var searchRoot = new monadish_1.DQ(node || document.body);
-        /**
-         * lazy helper to fetch the window id from the window url
-         */
-        var fetchWindowIdFromUrl = function () { return ExtDomQuery_1.ExtDomquery.searchJsfJsFor(/jfwid=([^&;]*)/).orElse(null).value; };
-        /**
-         * functional double check based on stream reduction
-         * the values should be identical or on INIT value which is a premise to
-         * skip the first check
-         *
-         * @param value1
-         * @param value2
-         */
-        var doubleCheck = function (value1, value2) {
-          if (value1 == ALTERED) {
-            return value1;
-          }
-          else if (value1 == INIT) {
-            return value2;
-          }
-          else if (value1 != value2) {
-            return ALTERED;
-          }
-          return value2;
-        };
-        /**
-         * helper for cleaner code, maps the value from an item
-         *
-         * @param item
-         */
-        var getValue = function (item) { return item.attr("value").value; };
-        /**
-         * fetch the window id from the forms
-         * window ids must be present in all forms
-         * or non existent. If they exist all of them must be the same
-         */
-        var formWindowId = searchRoot.stream.map(getValue).reduce(doubleCheck, INIT);
-        //if the resulting window id is set on altered then we have an unresolvable problem
-        assert(formWindowId.value != ALTERED, "Multiple different windowIds found in document");
-        /**
-         * return the window id or null
-         * prio, forms under node/document and if not given then from the url
-         */
-        return _a = formWindowId.value, (_a !== null && _a !== void 0 ? _a : fetchWindowIdFromUrl());
-      }
-      Implementation.getClientWindow = getClientWindow;
-      /**
-       * collect and encode data for a given form element (must be of type form)
-       * find the javax.faces.ViewState element and encode its value as well!
-       * @return a concatenated string of the encoded values!
-       *
-       * @throws Error in case of the given element not being of type form!
-       * https://issues.apache.org/jira/browse/MYFACES-2110
-       */
-      function getViewState(form) {
-        /**
-         *  typecheck assert!, we opt for strong typing here
-         *  because it makes it easier to detect bugs
-         */
-        var element = monadish_1.DQ.byId(form);
-        if (!element.isTag(Const_1.TAG_FORM)) {
-          throw new Error(getMessage("ERR_VIEWSTATE"));
-        }
-        var formData = new XhrFormData_1.XhrFormData(element);
-        return formData.toString();
-      }
-      Implementation.getViewState = getViewState;
-      /**
-       * this at the first sight looks like a weird construct, but we need to do it this way
-       * for testing, we cannot proxy addRequestToQueue from the testing frameworks directly
-       * but we need to keep it under unit tests.
-       */
-      Implementation.queueHandler = {
-        /**
-         * public to make it shimmable for tests
-         *
-         * adds a new request to our queue for further processing
-         */
-        addRequestToQueue: function (elem, form, reqCtx, respPassThr, delay, timeout) {
-          if (delay === void 0) { delay = 0; }
-          if (timeout === void 0) { timeout = 0; }
-          Implementation.requestQueue = (Implementation.requestQueue !== null && Implementation.requestQueue !== void 0 ? Implementation.requestQueue : new AsyncQueue_1.AsynchronouseQueue());
-          Implementation.requestQueue.enqueue(new XhrRequest_1.XhrRequest(elem, form, reqCtx, respPassThr, [], timeout), delay);
-        }
-      };
-      //----------------------------------------------- Methods ---------------------------------------------------------------------
-      /**
-       * the idea is to replace some placeholder parameters with their respective values
-       * placeholder params like  @all, @none, @form, @this need to be replaced by
-       * the values defined by the specification
-       *
-       * This function does it for the render parameters
-       *
-       * @param requestOptions the source options coming in as options object from jsf.ajax.request (options parameter)
-       * @param targetContext the receiving target context
-       * @param issuingForm the issuing form
-       * @param sourceElementId the executing element triggering the jsf.ajax.request (id of it)
-       */
-      function assignRender(requestOptions, targetContext, issuingForm, sourceElementId) {
-        if (requestOptions.getIf(Const_1.RENDER).isPresent()) {
-          remapDefaultConstants(targetContext.getIf(Const_1.CTX_PARAM_PASS_THR).get({}), Const_1.P_RENDER, requestOptions.getIf(Const_1.RENDER).value, issuingForm, sourceElementId);
-        }
-      }
-      /**
-       * the idea is to replace some placeholder parameters with their respective values
-       * placeholder params like  @all, @none, @form, @this need to be replaced by
-       * the values defined by the specification
-       *
-       * This function does it for the execute parameters
-       *
-       * @param requestOptions the source options coming in as options object from jsf.ajax.request (options parameter)
-       * @param targetContext the receiving target context
-       * @param issuingForm the issuing form
-       * @param sourceElementId the executing element triggering the jsf.ajax.request (id of it)
-       */
-      function assignExecute(requestOptions, targetContext, issuingForm, sourceElementId) {
-        if (requestOptions.getIf(Const_1.CTX_PARAM_EXECUTE).isPresent()) {
-          /*the options must be a blank delimited list of strings*/
-          /*compliance with Mojarra which automatically adds @this to an execute
-             * the spec rev 2.0a however states, if none is issued nothing at all should be sent down
-             */
-          requestOptions.assign(Const_1.CTX_PARAM_EXECUTE).value = [requestOptions.getIf(Const_1.CTX_PARAM_EXECUTE).value, Const_1.IDENT_THIS].join(" ");
-          remapDefaultConstants(targetContext.getIf(Const_1.CTX_PARAM_PASS_THR).get({}), Const_1.P_EXECUTE, requestOptions.getIf(Const_1.CTX_PARAM_EXECUTE).value, issuingForm, sourceElementId);
-        }
-        else {
-          targetContext.assign(Const_1.CTX_PARAM_PASS_THR, Const_1.P_EXECUTE).value = sourceElementId;
-        }
-      }
-      /**
-       * apply the browser tab where the request was originating from
-       *
-       * @param form the form hosting the client window id
-       * @param targetContext the target context receiving the value
-       */
-      function assignClientWindowId(form, targetContext) {
-        var clientWindow = jsf.getClientWindow(form.getAsElem(0).value);
-        if (clientWindow) {
-          targetContext.assign(Const_1.CTX_PARAM_PASS_THR, Const_1.P_CLIENT_WINDOW).value = clientWindow;
-        }
-      }
-      /**
-       * transforms the user values to the expected one
-       * with the proper none all form and this handling
-       * (note we also could use a simple string replace but then
-       * we would have had double entries under some circumstances)
-       *
-       * there are several standardized constants which need a special treatment
-       * like @all, @none, @form, @this
-       *
-       * @param targetConfig the target configuration receiving the final values
-       * @param targetKey the target key
-       * @param userValues the passed user values (aka input string which needs to be transformed)
-       * @param issuingForm the form where the issuing element originates
-       * @param issuingElementId the issuing element
-       */
-      function remapDefaultConstants(targetConfig, targetKey, userValues, issuingForm, issuingElementId) {
-        //a cleaner implementation of the transform list method
-        var iterValues = (userValues) ? trim(userValues).split(/\s+/gi) : [];
-        var ret = [];
-        var processed = {};
-        //the idea is simply to loop over all values and then replace
-        //their generic values and filter out doubles
-        //this is more readable than the old indexed based solution
-        //and not really slower because we had to build up the index in our old solution
-        //anyway
-        for (var cnt = 0; cnt < iterValues.length; cnt++) {
-          //avoid doubles
-          if (iterValues[cnt] in processed) {
-            continue;
-          }
-          switch (iterValues[cnt]) {
-              //@none no values should be sent
-            case Const_1.IDENT_NONE:
-              return targetConfig.delete(targetKey);
-              //@all is a pass through case according to the spec
-            case Const_1.IDENT_ALL:
-              targetConfig.assign(targetKey).value = Const_1.IDENT_ALL;
-              return targetConfig;
-              //@form pushes the issuing form id into our list
-            case Const_1.IDENT_FORM:
-              ret.push(issuingForm.id.value);
-              processed[issuingForm.id.value] = true;
-              break;
-              //@this is replaced with the current issuing element id
-            case Const_1.IDENT_THIS:
-              if (!(issuingElementId in processed)) {
-                ret.push(issuingElementId);
-                processed[issuingElementId] = true;
-              }
-              break;
-            default:
-              ret.push(iterValues[cnt]);
-              processed[iterValues[cnt]] = true;
-          }
-        }
-        //We now add the target as joined list
-        targetConfig.assign(targetKey).value = ret.join(" ");
-        return targetConfig;
-      }
-      /**
-       * filter the options tiven with a blacklist so that only
-       * the values required for passthough land in the ajax request
-       *
-       * @param mappedOpts the options to be filtered
-       */
-      function filterPassthroughValues(mappedOpts) {
-        //we now can use the full code reduction given by our stream api
-        //to filter
-        return monadish_1.Stream.ofAssoc(mappedOpts)
-            .filter(function (item) { return !(item[0] in BlockFilter); })
-            .collect(new monadish_1.AssocArrayCollector());
-      }
-    })(Implementation = exports.Implementation || (exports.Implementation = {}));
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/PushImpl.ts":
-  /*!**********************************************!*\
-  !*** ./src/main/typescript/impl/PushImpl.ts ***!
-  \**********************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /**
-     * Typescript port of the jsf.push part in the myfaces implementation
-     */
-    Object.defineProperty(exports, "__esModule", { value: true });
-//TODO still work in progress
-//this is a 1:1 port for the time being
-    var Jsf_1 = __webpack_require__(/*! ../api/Jsf */ "./src/main/typescript/api/Jsf.ts");
-    var Const_1 = __webpack_require__(/*! ./core/Const */ "./src/main/typescript/impl/core/Const.ts");
-    /**
-     * Implementation class for the push functionality
-     */
-    var PushImpl;
-    (function (PushImpl) {
-      var URL_PROTOCOL = window.location.protocol.replace("http", "ws") + "//";
-      //we expose the member variables for testing purposes
-      //they are not directly touched outside of tests
-      /* socket map by token */
-      PushImpl.sockets = {};
-      /* component attributes by clientId */
-      PushImpl.components = {};
-      /* client ids by token (share websocket connection) */
-      PushImpl.clientIdsByTokens = {};
-      //needed for testing
-      function reset() {
-        PushImpl.sockets = {};
-        PushImpl.components = {};
-        PushImpl.clientIdsByTokens = {};
-      }
-      PushImpl.reset = reset;
-      /*
-     * Api implementations, exposed functions
-     */
-      /**
-       *
-       * @param {function} onopen The function to be invoked when the web socket is opened.
-       * @param {function} onmessage The function to be invoked when a message is received.
-       * @param {function} onclose The function to be invoked when the web socket is closed.
-       * @param {boolean} autoconnect Whether or not to immediately open the socket. Defaults to <code>false</code>.
-       */
-      function init(socketClientId, uri, channel, onopen, onmessage, onclose, behaviorScripts, autoconnect) {
-        onclose = resolveFunction(onclose);
-        if (!window.WebSocket) { // IE6-9.
-          onclose(-1, channel);
-          return;
-        }
-        var channelToken = uri.substr(uri.indexOf('?') + 1);
-        if (!PushImpl.components[socketClientId]) {
-          PushImpl.components[socketClientId] = {
-            'channelToken': channelToken,
-            'onopen': resolveFunction(onopen),
-            'onmessage': resolveFunction(onmessage),
-            'onclose': onclose,
-            'behaviors': behaviorScripts,
-            'autoconnect': autoconnect
-          };
-          if (!PushImpl.clientIdsByTokens[channelToken]) {
-            PushImpl.clientIdsByTokens[channelToken] = [];
-          }
-          PushImpl.clientIdsByTokens[channelToken].push(socketClientId);
-          if (!PushImpl.sockets[channelToken]) {
-            PushImpl.sockets[channelToken] = new Socket(channelToken, getBaseURL(uri), channel);
-          }
-        }
-        if (autoconnect) {
-          Jsf_1.jsf.push.open(socketClientId);
-        }
-      }
-      PushImpl.init = init;
-      function open(socketClientId) {
-        var _a, _b;
-        getSocket((_b = (_a = PushImpl.components) === null || _a === void 0 ? void 0 : _a[socketClientId]) === null || _b === void 0 ? void 0 : _b.channelToken).open();
-      }
-      PushImpl.open = open;
-      function close(socketClientId) {
-        var _a;
-        getSocket((_a = PushImpl.components) === null || _a === void 0 ? void 0 : _a[socketClientId].channelToken).close();
-      }
-      PushImpl.close = close;
-      // Private helper classes
-      // Private classes functions ----------------------------------------------------------------------------------
-      /**
-       * Creates a reconnecting web socket. When the web socket successfully connects on first attempt, then it will
-       * automatically reconnect on timeout with cumulative intervals of 500ms with a maximum of 25 attempts (~3 minutes).
-       * The <code>onclose</code> function will be called with the error code of the last attempt.
-       * @constructor
-       * @param {string} channelToken the channel token associated with this websocket connection
-       * @param {string} url The URL of the web socket
-       * @param {string} channel The name of the web socket channel.
-       */
-      var Socket = /** @class */ (function () {
-        function Socket(channelToken, url, channel) {
-          this.channelToken = channelToken;
-          this.url = url;
-          this.channel = channel;
-          this.reconnectAttempts = 0;
-        }
-        Socket.prototype.open = function () {
-          if (this.socket && this.socket.readyState == 1) {
-            return;
-          }
-          this.socket = new WebSocket(this.url);
-          this.bindCallbacks();
-        };
-        Socket.prototype.onopen = function (event) {
-          if (!this.reconnectAttempts) {
-            var clientIds = PushImpl.clientIdsByTokens[this.channelToken];
-            for (var i = clientIds.length - 1; i >= 0; i--) {
-              var socketClientId = clientIds[i];
-              PushImpl.components[socketClientId]['onopen'](this.channel);
-            }
-          }
-          this.reconnectAttempts = 0;
-        };
-        Socket.prototype.onmmessage = function (event) {
-          var message = JSON.parse(event.data);
-          for (var i = PushImpl.clientIdsByTokens[this.channelToken].length - 1; i >= 0; i--) {
-            var socketClientId = PushImpl.clientIdsByTokens[this.channelToken][i];
-            if (document.getElementById(socketClientId)) {
-              try {
-                PushImpl.components[socketClientId]['onmessage'](message, this.channel, event);
-              }
-              catch (e) {
-                //Ignore
-              }
-              var behaviors = PushImpl.components[socketClientId]['behaviors'];
-              var functions = behaviors[message];
-              if (functions && functions.length) {
-                for (var j = 0; j < functions.length; j++) {
-                  try {
-                    functions[j](null);
-                  }
-                  catch (e) {
-                    //Ignore
-                  }
-                }
-              }
-            }
-            else {
-              PushImpl.clientIdsByTokens[this.channelToken].splice(i, 1);
-            }
-          }
-          if (PushImpl.clientIdsByTokens[this.channelToken].length == 0) {
-            //tag dissapeared
-            this.close();
-          }
-        };
-        Socket.prototype.onclose = function (event) {
-          var _a, _b;
-          if (!this.socket
-              || (event.code == 1000 && event.reason == Const_1.REASON_EXPIRED)
-              || (event.code == 1008)
-              || (!this.reconnectAttempts)
-              || (this.reconnectAttempts >= Const_1.MAX_RECONNECT_ATTEMPTS)) {
-            var clientIds = PushImpl.clientIdsByTokens[this.channelToken];
-            for (var i = clientIds.length - 1; i >= 0; i--) {
-              var socketClientId = clientIds[i];
-              PushImpl.components[socketClientId]['onclose']((_a = event) === null || _a === void 0 ? void 0 : _a.code, (_b = this) === null || _b === void 0 ? void 0 : _b.channel, event);
-            }
-          }
-          else {
-            setTimeout(this.open, Const_1.RECONNECT_INTERVAL * this.reconnectAttempts++);
-          }
-        };
-        ;
-        Socket.prototype.close = function () {
-          if (this.socket) {
-            var s = this.socket;
-            this.socket = null;
-            s.close();
-          }
-        };
-        /**
-         * bind the callbacks to the socket callbacks
-         */
-        Socket.prototype.bindCallbacks = function () {
-          var _this = this;
-          this.socket.onopen = function (event) { return _this.onopen(event); };
-          this.socket.onmessage = function (event) { return _this.onmmessage(event); };
-          this.socket.onclose = function (event) { return _this.onclose(event); };
-        };
-        return Socket;
-      }());
-      // Private static functions ---------------------------------------------------------------------------------------
-      function getBaseURL(url) {
-        if (url.indexOf("://") < 0) {
-          var base = window.location.hostname + ":" + window.location.port;
-          return URL_PROTOCOL + base + url;
-        }
-        else {
-          return url;
-        }
-      }
-      /**
-       * Get socket associated with given channelToken.
-       * @param {string} channelToken The name of the web socket channelToken.
-       * @return {Socket} Socket associated with given channelToken.
-       * @throws {Error} When channelToken is unknown, you may need to initialize
-       *                 it first via <code>init()</code> function.
-       */
-      function getSocket(channelToken) {
-        var socket = PushImpl.sockets[channelToken];
-        if (socket) {
-          return socket;
-        }
-        else {
-          throw new Error("Unknown channelToken: " + channelToken);
-        }
-      }
-      function resolveFunction(fn) {
-        if (fn === void 0) { fn = function () {
-        }; }
-        return ((typeof fn !== "function") && (fn = window[fn]), fn);
-      }
-    })(PushImpl = exports.PushImpl || (exports.PushImpl = {}));
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/core/Const.ts":
-  /*!************************************************!*\
-  !*** ./src/main/typescript/impl/core/Const.ts ***!
-  \************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    Object.defineProperty(exports, "__esModule", { value: true });
-    /*
- * [export const] constants
- */
-    exports.P_PARTIAL_SOURCE = "javax.faces.source";
-    exports.PARTIAL_ID = "partialId";
-    exports.P_VIEWSTATE = "javax.faces.ViewState";
-    exports.P_VIEWROOT = "javax.faces.ViewRoot";
-    exports.P_VIEWHEAD = "javax.faces.ViewHead";
-    exports.P_VIEWBODY = "javax.faces.ViewBody";
-    /*some useful definitions*/
-    exports.EMPTY_FUNC = Object.freeze(function () {
-    });
-    exports.EMPTY_STR = "";
-    exports.EMPTY_MAP = Object.freeze({});
-    exports.HTML_VIEWSTATE = ["<input type='hidden'", "id='", exports.P_VIEWSTATE, "' name='", exports.P_VIEWSTATE, "' value='' />"].join(exports.EMPTY_STR);
-    /*internal identifiers for options*/
-    exports.IDENT_ALL = "@all";
-    exports.IDENT_NONE = "@none";
-    exports.IDENT_THIS = "@this";
-    exports.IDENT_FORM = "@form";
-    exports.P_AJAX = "javax.faces.partial.ajax";
-    exports.P_EXECUTE = "javax.faces.partial.execute";
-    exports.P_RENDER = "javax.faces.partial.render";
-    exports.P_EVT = "javax.faces.partial.event";
-    exports.P_CLIENT_WINDOW = "javax.faces.ClientWindow";
-    exports.P_RESET_VALUES = "javax.faces.partial.resetValues";
-    exports.P_WINDOW_ID = "javax.faces.windowId";
-    exports.RENDER = "render";
-    exports.WINDOW_ID = "windowId";
-    /* message types */
-    exports.ERROR = "error";
-    exports.EVENT = "event";
-    exports.ON_ERROR = "onerror";
-    exports.ON_EVENT = "onevent";
-    /* event emitting stages */
-    exports.BEGIN = "begin";
-    exports.COMPLETE = "complete";
-    exports.SUCCESS = "success";
-    exports.SOURCE = "source";
-    exports.STATUS = "status";
-    exports.ERROR_NAME = "error-name";
-    exports.ERROR_MESSAGE = "error-message";
-    exports.RESPONSE_TEXT = "responseText";
-    exports.RESPONSE_XML = "responseXML";
-    /*ajax errors spec 14.4.2*/
-    exports.HTTPERROR = "httpError";
-    exports.EMPTY_RESPONSE = "emptyResponse";
-    exports.MALFORMEDXML = "malformedXML";
-    exports.SERVER_ERROR = "serverError";
-    exports.CLIENT_ERROR = "clientError";
-    exports.TIMEOUT_EVENT = "timeout";
-    exports.CTX_PARAM_MF_INTERNAL = "_mfInternal";
-    exports.CTX_PARAM_SRC_FRM_ID = "_mfSourceFormId";
-    exports.CTX_PARAM_SRC_CTL_ID = "_mfSourceControlId";
-    exports.CTX_PARAM_TR_TYPE = "_mfTransportType";
-    exports.CTX_PARAM_PASS_THR = "passThrgh";
-    exports.CTX_PARAM_DELAY = "delay";
-    exports.CTX_PARAM_TIMEOUT = "timeout";
-    exports.CTX_PARAM_RST = "resetValues";
-    exports.CTX_PARAM_EXECUTE = "execute";
-    exports.STAGE_DEVELOPMENT = "Development";
-    exports.CONTENT_TYPE = "Content-Type";
-    exports.HEAD_FACES_REQ = "Faces-Request";
-    exports.REQ_ACCEPT = "Accept";
-    exports.VAL_AJAX = "partial/ajax";
-    exports.ENCODED_URL = "javax.faces.encodedURL";
-    exports.REQ_TYPE_GET = "GET";
-    exports.REQ_TYPE_POST = "POST";
-    exports.STATE_EVT_BEGIN = "begin"; //TODO remove this
-    exports.STATE_EVT_TIMEOUT = "TIMEOUT_EVENT";
-    exports.STATE_EVT_COMPLETE = "complete"; //TODO remove this
-    exports.URL_ENCODED = "application/x-www-form-urlencoded";
-    exports.MULTIPART = "multipart/form-data";
-    exports.NO_TIMEOUT = 0;
-    exports.STD_ACCEPT = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
-    exports.TAG_HEAD = "head";
-    exports.TAG_FORM = "form";
-    exports.TAG_BODY = "body";
-    exports.TAG_BEFORE = "before";
-    exports.TAG_AFTER = "after";
-    exports.TAG_ATTR = "attribute";
-    exports.SEL_VIEWSTATE_ELEM = "[name='" + exports.P_VIEWSTATE + "']";
-    exports.SEL_RESPONSE_XML = "responseXML";
-    exports.PHASE_PROCESS_RESPONSE = "processResponse";
-    exports.ERR_NO_PARTIAL_RESPONSE = "Partial response not set";
-    exports.ATTR_URL = "url";
-    exports.ATTR_NAME = "name";
-    exports.ATTR_VALUE = "value";
-    exports.ATTR_ID = "id";
-    /*partial response types*/
-    exports.RESP_PARTIAL = "partial-response";
-    /*partial commands*/
-    exports.CMD_CHANGES = "changes";
-    exports.CMD_UPDATE = "update";
-    exports.CMD_DELETE = "delete";
-    exports.CMD_INSERT = "insert";
-    exports.CMD_EVAL = "eval";
-    exports.CMD_ERROR = "error";
-    exports.CMD_ATTRIBUTES = "attributes";
-    exports.CMD_EXTENSION = "extension";
-    exports.CMD_REDIRECT = "redirect";
-    /*other constants*/
-    exports.UPDATE_FORMS = "_updateForms";
-    exports.UPDATE_ELEMS = "_updateElems";
-    exports.MYFACES = "myfaces";
-    exports.SEL_SCRIPTS_STYLES = "script, style, link";
-    exports.MF_NONE = "__mf_none__";
-    exports.REASON_EXPIRED = "Expired";
-    exports.APPLIED_VST = "appliedViewState";
-    exports.RECONNECT_INTERVAL = 500;
-    exports.MAX_RECONNECT_ATTEMPTS = 25;
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/core/ImplTypes.ts":
-  /*!****************************************************!*\
-  !*** ./src/main/typescript/impl/core/ImplTypes.ts ***!
-  \****************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var Const_1 = __webpack_require__(/*! ./Const */ "./src/main/typescript/impl/core/Const.ts");
-    /**
-     * a helper class to isolate the
-     * view state data processing
-     */
-    var ViewState = /** @class */ (function () {
-      function ViewState(id, value) {
-        this.id = id;
-        this.value = value;
-        var viewStatePos = id.indexOf(Const_1.P_VIEWSTATE);
-        this.nameSpace = viewStatePos > 0 ? id.substr(0, viewStatePos - 1) : Const_1.EMPTY_STR;
-      }
-      Object.defineProperty(ViewState.prototype, "hasNameSpace", {
-        get: function () {
-          var _a, _b;
-          return !!(_b = (_a = this) === null || _a === void 0 ? void 0 : _a.nameSpace, (_b !== null && _b !== void 0 ? _b : Const_1.EMPTY_STR)).length;
-        },
-        enumerable: true,
-        configurable: true
-      });
-      return ViewState;
-    }());
-    exports.ViewState = ViewState;
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/i18n/Messages.ts":
-  /*!***************************************************!*\
-  !*** ./src/main/typescript/impl/i18n/Messages.ts ***!
-  \***************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var Messages = /** @class */ (function () {
-      function Messages() {
-        this.MSG_TEST = "Testmessage";
-        /*Messages*/
-        /** @constant */
-        this.MSG_DEV_MODE = "Note, this message is only sent, because project stage is development and no " +
-            "other error listeners are registered.";
-        /** @constant */
-        this.MSG_AFFECTED_CLASS = "Affected Class=";
-        /** @constant */
-        this.MSG_AFFECTED_METHOD = "Affected Method=";
-        /** @constant */
-        this.MSG_ERROR_NAME = "Error Name=";
-        /** @constant */
-        this.MSG_ERROR_MESSAGE = "Error Message=";
-        /** @constant */
-        this.MSG_SERVER_ERROR_NAME = "Server Error Name=";
-        /** @constant */
-        this.MSG_ERROR_DESC = "Error Description=";
-        /** @constant */
-        this.MSG_ERROR_NO = "Error Number=";
-        /** @constant */
-        this.MSG_ERROR_LINENO = "Error Line Number=";
-        /*Errors and messages*/
-        /** @constant */
-        this.ERR_FORM = "Sourceform could not be determined, either because element is not attached to a form or we have multiple forms with named elements of the same identifier or name, stopping the ajax processing";
-        /** @constant */
-        this.ERR_VIEWSTATE = "jsf.viewState= param value not of type form!";
-        /** @constant */
-        this.ERR_TRANSPORT = "Transport type {0} does not exist";
-        /** @constant */
-        this.ERR_EVT_PASS = "an event must be passed down (either a an event object null or undefined) ";
-        /** @constant */
-        this.ERR_CONSTRUCT = "Parts of the response couldn't be retrieved when constructing the event data= {0} ";
-        /** @constant */
-        this.ERR_MALFORMEDXML = "The server response could not be parsed, the server has returned with a response which is not xml !";
-        /** @constant */
-        this.ERR_SOURCE_FUNC = "source cannot be a function (probably source and event were not defined or set to null";
-        /** @constant */
-        this.ERR_EV_OR_UNKNOWN = "An event object or unknown must be passed as second parameter";
-        /** @constant */
-        this.ERR_SOURCE_NOSTR = "source cannot be a string";
-        /** @constant */
-        this.ERR_SOURCE_DEF_NULL = "source must be defined or null";
-        //_Lang.js
-        /** @constant */
-        this.ERR_MUST_STRING = "{0}: {1} namespace must be of type String";
-        /** @constant */
-        this.ERR_REF_OR_ID = "{0}: {1} a reference node or identifier must be provided";
-        /** @constant */
-        this.ERR_PARAM_GENERIC = "{0}: parameter {1} must be of type {2}";
-        /** @constant */
-        this.ERR_PARAM_STR = "{0}: {1} param must be of type string";
-        /** @constant */
-        this.ERR_PARAM_STR_RE = "{0}: {1} param must be of type string or a regular expression";
-        /** @constant */
-        this.ERR_PARAM_MIXMAPS = "{0}: both a source as well as a destination map must be provided";
-        /** @constant */
-        this.ERR_MUST_BE_PROVIDED = "{0}: an {1} and a {2} must be provided";
-        /** @constant */
-        this.ERR_MUST_BE_PROVIDED1 = "{0}: {1} must be set";
-        /** @constant */
-        this.ERR_REPLACE_EL = "replaceElements called while evalNodes is not an array";
-        /** @constant */
-        this.ERR_EMPTY_RESPONSE = "{0}: The response cannot be null or empty!";
-        /** @constant */
-        this.ERR_ITEM_ID_NOTFOUND = "{0}: item with identifier {1} could not be found";
-        /** @constant */
-        this.ERR_PPR_IDREQ = "{0}: Error in PPR Insert, id must be present";
-        /** @constant */
-        this.ERR_PPR_INSERTBEFID = "{0}: Error in PPR Insert, before id or after id must be present";
-        /** @constant */
-        this.ERR_PPR_INSERTBEFID_1 = "{0}: Error in PPR Insert, before  node of id {1} does not exist in document";
-        /** @constant */
-        this.ERR_PPR_INSERTBEFID_2 = "{0}: Error in PPR Insert, after  node of id {1} does not exist in document";
-        /** @constant */
-        this.ERR_PPR_DELID = "{0}: Error in delete, id not in xml markup";
-        /** @constant */
-        this.ERR_PPR_UNKNOWNCID = "{0}:  Unknown Html-Component-ID= {1}";
-        /** @constant */
-        this.ERR_NO_VIEWROOTATTR = "{0}: Changing of ViewRoot attributes is not supported";
-        /** @constant */
-        this.ERR_NO_HEADATTR = "{0}: Changing of Head attributes is not supported";
-        /** @constant */
-        this.ERR_RED_URL = "{0}: Redirect without url";
-        /** @constant */
-        this.ERR_REQ_FAILED_UNKNOWN = "Request failed with unknown status";
-        /** @constant */
-        this.ERR_REQU_FAILED = "Request failed with status {0} and reason {1}";
-        /** @constant */
-        this.UNKNOWN = "UNKNOWN";
-      }
-      return Messages;
-    }());
-    exports.Messages = Messages;
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/util/Assertions.ts":
-  /*!*****************************************************!*\
-  !*** ./src/main/typescript/impl/util/Assertions.ts ***!
-  \*****************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
-    var Lang_1 = __webpack_require__(/*! ./Lang */ "./src/main/typescript/impl/util/Lang.ts");
-    var getMessage = Lang_1.ExtLang.getMessage;
-    var makeException = Lang_1.ExtLang.makeException;
-    var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
-    /**
-     * a set of internal code assertions
-     * which raise an error
-     *
-     */
-    var Assertions;
-    (function (Assertions) {
-      function assertRequestIntegrity(options, elem) {
-        /*assert if the onerror is set and once if it is set it must be of type function*/
-        assertFunction(options.getIf(Const_1.ON_ERROR).value);
-        /*assert if the onevent is set and once if it is set it must be of type function*/
-        assertFunction(options.getIf(Const_1.ON_EVENT).value);
-        //improve the error messages if an empty elem is passed
-        //Assertions.assertElementExists(elem);
-        assert(elem.isPresent(), getMessage("ERR_MUST_BE_PROVIDED1", "{0}: source  must be provided or exist", "source element id"), "jsf.ajax.request", "ArgNotSet");
-      }
-      Assertions.assertRequestIntegrity = assertRequestIntegrity;
-      function assertUrlExists(node) {
-        if (node.attr(Const_1.ATTR_URL).isAbsent()) {
-          throw Assertions.raiseError(new Error(), getMessage("ERR_RED_URL", null, "_Ajaxthis.processRedirect"), "processRedirect");
-        }
-      }
-      Assertions.assertUrlExists = assertUrlExists;
-      /**
-       * checks the xml for various issues which can occur
-       * and prevent a proper processing
-       */
-      function assertValidXMLResponse(responseXML) {
-        assert(!responseXML.isAbsent(), Const_1.EMPTY_RESPONSE, Const_1.PHASE_PROCESS_RESPONSE);
-        assert(!responseXML.isXMLParserError(), responseXML.parserErrorText(Const_1.EMPTY_STR), Const_1.PHASE_PROCESS_RESPONSE);
-        assert(responseXML.querySelectorAll(Const_1.RESP_PARTIAL).isPresent(), Const_1.ERR_NO_PARTIAL_RESPONSE, Const_1.PHASE_PROCESS_RESPONSE);
-      }
-      Assertions.assertValidXMLResponse = assertValidXMLResponse;
-      /**
-       * internal helper which raises an error in the
-       * format we need for further processing
-       *
-       * @param message the message
-       * @param title the title of the error (optional)
-       * @param name the name of the error (optional)
-       */
-      function raiseError(error, message, caller, title, name) {
-        var finalTitle = (title !== null && title !== void 0 ? title : Const_1.MALFORMEDXML);
-        var finalName = (name !== null && name !== void 0 ? name : Const_1.MALFORMEDXML);
-        var finalMessage = (message !== null && message !== void 0 ? message : Const_1.EMPTY_STR);
-        //TODO clean up the messy makeException, this is a perfect case for encapsulation and sane defaults
-        return makeException(error, finalTitle, finalName, "Response", caller || ((arguments.caller) ? arguments.caller.toString() : "_raiseError"), finalMessage);
-      }
-      Assertions.raiseError = raiseError;
-      /*
-     * using the new typescript 3.7 compiler assertion functionality to improve compiler hinting
-     * we are not fully there yet, but soon
-     */
-      function assert(value, msg, caller, title) {
-        if (msg === void 0) { msg = Const_1.EMPTY_STR; }
-        if (caller === void 0) { caller = Const_1.EMPTY_STR; }
-        if (title === void 0) { title = "Assertion Error"; }
-        if (!value) {
-          throw Assertions.raiseError(new Error(), msg, caller, title);
-        }
-      }
-      Assertions.assert = assert;
-      function assertType(value, theType, msg, caller, title) {
-        if (msg === void 0) { msg = Const_1.EMPTY_STR; }
-        if (caller === void 0) { caller = Const_1.EMPTY_STR; }
-        if (title === void 0) { title = "Type Assertion Error"; }
-        if ((!!value) && !monadish_1.Lang.assertType(value, theType)) {
-          throw Assertions.raiseError(new Error(), msg, caller, title);
-        }
-      }
-      Assertions.assertType = assertType;
-      function assertFunction(value, msg, caller, title) {
-        if (msg === void 0) { msg = Const_1.EMPTY_STR; }
-        if (caller === void 0) { caller = Const_1.EMPTY_STR; }
-        if (title === void 0) { title = "Assertion Error"; }
-        assertType(value, "function", msg, caller, title);
-      }
-      Assertions.assertFunction = assertFunction;
-    })(Assertions = exports.Assertions || (exports.Assertions = {}));
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/util/AsyncQueue.ts":
-  /*!*****************************************************!*\
-  !*** ./src/main/typescript/impl/util/AsyncQueue.ts ***!
-  \*****************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    Object.defineProperty(exports, "__esModule", { value: true });
-    /**
-     * Asynchronous queue which starts to work
-     * through the callbacks until the queue is empty
-     *
-     * Every callback must be of async runnable
-     * which is sort of an extended promise which has
-     * added a decicated cancel and start point
-     *
-     * This interface can be used as wrapper contract
-     * for normal promises if needed.
-     */
-    var AsynchronouseQueue = /** @class */ (function () {
-      function AsynchronouseQueue() {
-        this.runnableQueue = [];
-      }
-      Object.defineProperty(AsynchronouseQueue.prototype, "isEmpty", {
-        get: function () {
-          return !this.runnableQueue.length;
-        },
-        enumerable: true,
-        configurable: true
-      });
-      /**
-       * enequeues an element and starts the
-       * asynchronous work loop if not already running
-       *
-       * @param element the element to be queued and processed
-       * @param delay possible delay after our usual process or drop if something newer is incoming algorithm
-       */
-      AsynchronouseQueue.prototype.enqueue = function (element, delay) {
-        var _this = this;
-        if (delay === void 0) { delay = 0; }
-        if (this.delayTimeout) {
-          clearTimeout(this.delayTimeout);
-          this.delayTimeout = null;
-        }
-        if (delay) {
-          this.delayTimeout = setTimeout(function () {
-            _this.appendElement(element);
-          });
-        }
-        else {
-          this.appendElement(element);
-        }
-      };
-      AsynchronouseQueue.prototype.dequeue = function () {
-        return this.runnableQueue.shift();
-      };
-      AsynchronouseQueue.prototype.cleanup = function () {
-        this.currentlyRunning = null;
-        this.runnableQueue.length = 0;
-      };
-      AsynchronouseQueue.prototype.appendElement = function (element) {
-        //only if the first element is added we start with a trigger
-        //otherwise a process already is running and not finished yet at that
-        //time
-        this.runnableQueue.push(element);
-        if (!this.currentlyRunning) {
-          this.runEntry();
-        }
-      };
-      AsynchronouseQueue.prototype.runEntry = function () {
-        var _this = this;
-        if (this.isEmpty) {
-          this.currentlyRunning = null;
-          return;
-        }
-        this.currentlyRunning = this.dequeue();
-        this.currentlyRunning
-            .catch(function (e) {
-              //in case of an error we always clean up the remaining calls
-              //to allow a clean recovery of the application
-              _this.cleanup();
-              throw e;
-            })
-            .then(
-                //the idea is to trigger the next over an event to reduce
-                //the number of recursive calls (stacks might be limited
-                //compared to ram)
-                //naturally give we have a DOM, the DOM is the natural event dispatch system
-                //which we can use, to decouple the calls from a recursive stack call
-                //(the browser engine will take care of that)
-                function () { return _this.callForNextElementToProcess(); }).start();
-      };
-      AsynchronouseQueue.prototype.cancel = function () {
-        try {
-          if (this.currentlyRunning) {
-            this.currentlyRunning.cancel();
-          }
-        }
-        finally {
-          this.cleanup();
-        }
-      };
-      AsynchronouseQueue.prototype.callForNextElementToProcess = function () {
-        this.runEntry();
-      };
-      AsynchronouseQueue.prototype.processNextElement = function () {
-        this.currentlyRunning = null;
-        if (!this.isEmpty) {
-          this.runEntry();
-        }
-      };
-      AsynchronouseQueue.EVT_NEXT = "__mf_queue_next__";
-      return AsynchronouseQueue;
-    }());
-    exports.AsynchronouseQueue = AsynchronouseQueue;
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/util/ExtDomQuery.ts":
-  /*!******************************************************!*\
-  !*** ./src/main/typescript/impl/util/ExtDomQuery.ts ***!
-  \******************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    var __extends = (this && this.__extends) || (function () {
-      var extendStatics = function (d, b) {
-        extendStatics = Object.setPrototypeOf ||
-            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
-        return extendStatics(d, b);
-      };
-      return function (d, b) {
-        extendStatics(d, b);
-        function __() { this.constructor = d; }
-        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-      };
-    })();
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var Monad_1 = __webpack_require__(/*! ../../ext/monadish/Monad */ "./src/main/typescript/ext/monadish/Monad.ts");
-    var DomQuery_1 = __webpack_require__(/*! ../../ext/monadish/DomQuery */ "./src/main/typescript/ext/monadish/DomQuery.ts");
-    var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
-    /**
-     * Extension which adds implementation specific
-     * meta data to our dom qury
-     *
-     * Usage
-     * el = new ExtDQ(oldReference)
-     * nonce = el.nonce
-     * windowId = el.getWindowId
-     */
-    var ExtDomquery = /** @class */ (function (_super) {
-      __extends(ExtDomquery, _super);
-      function ExtDomquery() {
-        return _super !== null && _super.apply(this, arguments) || this;
-      }
-      Object.defineProperty(ExtDomquery, "windowId", {
-        get: function () {
-          return new ExtDomquery(document.body).windowId;
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(ExtDomquery, "nonce", {
-        get: function () {
-          return new ExtDomquery(document.body).nonce;
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(ExtDomquery.prototype, "windowId", {
-        get: function () {
-          var fetchWindowIdFromURL = function () {
-            var href = window.location.href;
-            var windowId = "windowId";
-            var regex = new RegExp("[\\?&]" + windowId + "=([^&#\\;]*)");
-            var results = regex.exec(href);
-            //initial trial over the url and a regexp
-            if (results != null)
-              return results[1];
-            return null;
-          };
-          //byId ($)
-          if (this.value.isPresent()) {
-            var result = this.querySelectorAll("form input[name='" + Const_1.P_WINDOW_ID + "']");
-            if (result.length > 0) {
-              throw Error("Multiple different windowIds found in document");
-            }
-            return (result.isPresent()) ? result.getAsElem(0).value.value : fetchWindowIdFromURL();
-          }
-          else {
-            return fetchWindowIdFromURL();
-          }
-        },
-        enumerable: true,
-        configurable: true
-      });
-      Object.defineProperty(ExtDomquery.prototype, "nonce", {
-        /*
-        determines the jsfjs nonce and adds them to the namespace
-        * this is done once and only lazily
-        */
-        get: function () {
-          //already processed
-          var myfacesConfig = new Monad_1.Config(window.myfaces);
-          var nonce = myfacesConfig.assign("config", "cspMeta", "nonce");
-          if (nonce.value) {
-            return nonce.value;
-          }
-          var curScript = new DomQuery_1.DQ(document.currentScript);
-          //since our baseline atm is ie11 we cannot use document.currentScript globally
-          if (curScript.attr("nonce").value != null) {
-            //fastpath for modern browsers
-            return curScript.attr("nonce").value;
-          }
-          var nonceScript = DomQuery_1.DQ.querySelectorAll("script[src], link[src]").lazyStream
-              .filter(function (item) { return item.attr("nonce").value != null && item.attr("src") != null; })
-              .map((function (item) { return !item.attr("src").value.match(/jsf\.js\?ln\=javax\.faces/gi); }))
-              .first();
-          if (nonceScript.isPresent()) {
-            nonce.value = DomQuery_1.DomQuery.byId(nonceScript.value).attr("nonce").value;
-          }
-          return nonce.value;
-        },
-        enumerable: true,
-        configurable: true
-      });
-      ExtDomquery.searchJsfJsFor = function (item) {
-        return new ExtDomquery(document).searchJsfJsFor(item);
-      };
-      ExtDomquery.prototype.searchJsfJsFor = function (rexp) {
-        //perfect application for lazy stream
-        return DomQuery_1.DQ.querySelectorAll("script").lazyStream
-            .filter(function (item) {
-              var _a;
-              return (_a = item.attr("src").value, (_a !== null && _a !== void 0 ? _a : Const_1.EMPTY_STR)).search(/\/javax\.faces\.resource.*\/jsf\.js.*separator/) != -1;
-            }).map(function (item) {
-              var result = item.attr("src").value.match(rexp);
-              return decodeURIComponent(result[1]);
-            }).first();
-      };
-      ExtDomquery.prototype.globalEval = function (code, nonce) {
-        return _super.prototype.globalEval.call(this, code, (nonce !== null && nonce !== void 0 ? nonce : this.nonce));
-      };
-      return ExtDomquery;
-    }(DomQuery_1.DQ));
-    exports.ExtDomquery = ExtDomquery;
-    exports.ExtDQ = DomQuery_1.DQ;
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/util/Lang.ts":
-  /*!***********************************************!*\
-  !*** ./src/main/typescript/impl/util/Lang.ts ***!
-  \***********************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * todo replace singleton with module definition
- *
- */
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var Lang_1 = __webpack_require__(/*! ../../ext/monadish/Lang */ "./src/main/typescript/ext/monadish/Lang.ts");
-    var Messages_1 = __webpack_require__(/*! ../i18n/Messages */ "./src/main/typescript/impl/i18n/Messages.ts");
-    var DomQuery_1 = __webpack_require__(/*! ../../ext/monadish/DomQuery */ "./src/main/typescript/ext/monadish/DomQuery.ts");
-    var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
-    var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
-    var RequestDataResolver_1 = __webpack_require__(/*! ../xhrCore/RequestDataResolver */ "./src/main/typescript/impl/xhrCore/RequestDataResolver.ts");
-    var ExtLang;
-    (function (ExtLang) {
-      var installedLocale;
-      var nameSpace = "impl/util/Lang/";
-      function getLanguage() {
-        //TODO global config override
-        var _a, _b, _c;
-        var language = (_b = (_a = navigator.languages) === null || _a === void 0 ? void 0 : _a[0], (_b !== null && _b !== void 0 ? _b : (_c = navigator) === null || _c === void 0 ? void 0 : _c.language));
-        language = language.split("-")[0];
-        return language;
-      }
-      ExtLang.getLanguage = getLanguage;
-      //should be in lang, but for now here to avoid recursive imports, not sure if typescript still has a problem with those
-      /**
-       * helper function to savely resolve anything
-       * this is not an elvis operator, it resolves
-       * a value without exception in a tree and if
-       * it is not resolvable then an optional of
-       * a default value is restored or Optional.empty
-       * if none is given
-       *
-       * usage
-       * <code>
-       *     let var: Optional<string> = saveResolve(() => a.b.c.d.e, "foobaz")
-       * </code>
-       *
-       * @param resolverProducer a lambda which can produce the value
-       * @param defaultValue an optional default value if the producer failes to produce anything
-       * @returns an Optional of the produced value
-       */
-      function failSaveResolve(resolverProducer, defaultValue) {
-        if (defaultValue === void 0) { defaultValue = null; }
-        return Lang_1.Lang.saveResolve(resolverProducer, defaultValue);
-      }
-      ExtLang.failSaveResolve = failSaveResolve;
-      /**
-       * under some conditions it makes sense to swallow errors and return a default value in the error case
-       * classical example the optional resolution of values in a chain (thankfully now covered by Typescript itself)
-       * another example which we have in our system is that some operations fail only under test due to test framework
-       * limitations while they cannot fail in the real world.
-       *
-       * @param resolverProducer a producer function which produces a value in the non error case
-       * @param defaultValue the default value in case of a fail of the function
-       */
-      function failSaveExecute(resolverProducer, defaultValue) {
-        if (defaultValue === void 0) { defaultValue = null; }
-        Lang_1.Lang.saveResolve(resolverProducer, defaultValue);
-      }
-      ExtLang.failSaveExecute = failSaveExecute;
-      /**
-       * returns a given localized message upon a given key
-       * basic java log like templating functionality is included
-       *
-       * @param {String} key the key for the message
-       * @param {String} defaultMessage optional default message if none was found
-       *
-       * Additionally you can pass additional arguments, which are used
-       * in the same way java log templates use the params
-       *
-       * @param templateParams the param list to be filled in
-       */
-      function getMessage(key, defaultMessage) {
-        var templateParams = [];
-        for (var _i = 2; _i < arguments.length; _i++) {
-          templateParams[_i - 2] = arguments[_i];
-        }
-        var _a, _b;
-        installedLocale = (installedLocale !== null && installedLocale !== void 0 ? installedLocale : new Messages_1.Messages());
-        var msg = (_b = (_a = installedLocale[key], (_a !== null && _a !== void 0 ? _a : defaultMessage)), (_b !== null && _b !== void 0 ? _b : key + " - undefined message"));
-        monadish_1.Stream.of.apply(monadish_1.Stream, templateParams).each(function (param, cnt) {
-          msg = msg.replace(new RegExp(["\\{", cnt, "\\}"].join(Const_1.EMPTY_STR), "g"), param);
-        });
-        return msg;
-      }
-      ExtLang.getMessage = getMessage;
-      /**
-       * transforms a key value pair into a string
-       * @param key the key
-       * @param val the value
-       * @param delimiter the delimiter
-       */
-      function keyValToStr(key, val, delimiter) {
-        if (delimiter === void 0) { delimiter = "\n"; }
-        return [key, val].join(delimiter);
-      }
-      ExtLang.keyValToStr = keyValToStr;
-      /**
-       * creates an exeption with additional internal parameters
-       * for extra information
-       *
-       * @param {String} title the exception title
-       * @param {String} name  the exception name
-       * @param {String} callerCls the caller class
-       * @param {String} callFunc the caller function
-       * @param {String} message the message for the exception
-       */
-      function makeException(error, title, name, callerCls, callFunc, message) {
-        var _a;
-        return new Error((_a = message + ((callerCls !== null && callerCls !== void 0 ? callerCls : nameSpace)) + callFunc, (_a !== null && _a !== void 0 ? _a : (Const_1.EMPTY_STR + arguments.caller.toString()))));
-      }
-      ExtLang.makeException = makeException;
-      /**
-       * fetches a global config entry
-       * @param {String} configName the name of the configuration entry
-       * @param {Object} defaultValue
-       *
-       * @return either the config entry or if none is given the default value
-       */
-      function getGlobalConfig(configName, defaultValue) {
-        var _a, _b, _c, _d;
-        /**
-         * note we could use exists but this is an heavy operation, since the config name usually
-         * given this function here is called very often
-         * is a single entry without . in between we can do the lighter shortcut
-         */
-        return _d = (_c = (_b = (_a = window) === null || _a === void 0 ? void 0 : _a.myfaces) === null || _b === void 0 ? void 0 : _b.config) === null || _c === void 0 ? void 0 : _c[configName], (_d !== null && _d !== void 0 ? _d : defaultValue);
-      }
-      ExtLang.getGlobalConfig = getGlobalConfig;
-      /**
-       * fetches the form in an unprecise manner depending
-       * on an element or event target.
-       *
-       * The idea is that according to the jsf spec
-       * the enclosing form of the issuing element needs to be fetched.
-       *
-       * This is fine, but since then html5 came into the picture with the form attribute the element
-       * can be anywhere referencing its parent form.
-       *
-       * Also theoretically you can have the case of an issuing element enclosing a set of forms
-       * (not really often used, but theoretically it could be input button allows to embed html for instance)
-       *
-       * So the idea is not to limit the issuing form determination to the spec case
-       * but also cover the theoretical and html5 corner case.
-       *
-       * @param elem
-       * @param event
-       */
-      function getForm(elem, event) {
-        var FORM = "form";
-        var queryElem = new DomQuery_1.DQ(elem);
-        var eventTarget = new DomQuery_1.DQ(RequestDataResolver_1.getEventTarget(event));
-        if (queryElem.isTag(FORM)) {
-          return queryElem;
-        }
-        //html 5 for handling
-        if (queryElem.attr(FORM).isPresent()) {
-          var formId = queryElem.attr(FORM).value;
-          var foundForm = DomQuery_1.DQ.byId(formId);
-          if (foundForm.isPresent()) {
-            return foundForm;
-          }
-        }
-        var form = queryElem.parents(FORM)
-            .orElseLazy(function () { return queryElem.byTagName(FORM, true); })
-            .orElseLazy(function () { return eventTarget.parents(FORM); })
-            .orElseLazy(function () { return eventTarget.byTagName(FORM); })
-            .first();
-        assertFormExists(form);
-        return form;
-      }
-      ExtLang.getForm = getForm;
-      /**
-       * gets the local or global options with local ones having higher priority
-       * if no local or global one was found then the default value is given back
-       *
-       * @param {String} configName the name of the configuration entry
-       * @param {String} localOptions the local options root for the configuration myfaces as default marker is added implicitely
-       *
-       * @param {Object} defaultValue
-       *
-       * @return either the config entry or if none is given the default value
-       */
-      function getLocalOrGlobalConfig(localOptions, configName, defaultValue) {
-        var _a, _b, _c, _d, _e, _f, _g, _h;
-        return _h = (_d = (_c = (_b = (_a = localOptions.value) === null || _a === void 0 ? void 0 : _a.myfaces) === null || _b === void 0 ? void 0 : _b.config) === null || _c === void 0 ? void 0 : _c[configName], (_d !== null && _d !== void 0 ? _d : (_g = (_f = (_e = window) === null || _e === void 0 ? void 0 : _e.myfaces) === null || _f === void 0 ? void 0 : _f.config) === null || _g === void 0 ? void 0 : _g[configName])), (_h !== null && _h !== void 0 ? _h : defaultValue);
-      }
-      ExtLang.getLocalOrGlobalConfig = getLocalOrGlobalConfig;
-      /**
-       * assert that the form exists and throw an exception in the case it does not
-       * (TODO move this into the assertions)
-       *
-       * @param form the form to check for
-       */
-      function assertFormExists(form) {
-        if (form.isAbsent()) {
-          throw makeException(new Error(), null, null, "Impl", "getForm", getMessage("ERR_FORM"));
-        }
-      }
-    })(ExtLang = exports.ExtLang || (exports.ExtLang = {}));
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/xhrCore/ErrorData.ts":
-  /*!*******************************************************!*\
-  !*** ./src/main/typescript/impl/xhrCore/ErrorData.ts ***!
-  \*******************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    var __extends = (this && this.__extends) || (function () {
-      var extendStatics = function (d, b) {
-        extendStatics = Object.setPrototypeOf ||
-            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
-        return extendStatics(d, b);
-      };
-      return function (d, b) {
-        extendStatics(d, b);
-        function __() { this.constructor = d; }
-        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-      };
-    })();
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
-    var EventData_1 = __webpack_require__(/*! ./EventData */ "./src/main/typescript/impl/xhrCore/EventData.ts");
-    var Lang_1 = __webpack_require__(/*! ../util/Lang */ "./src/main/typescript/impl/util/Lang.ts");
-    var getMessage = Lang_1.ExtLang.getMessage;
-    var ErrorType;
-    (function (ErrorType) {
-      ErrorType["SERVER_ERROR"] = "serverError";
-      ErrorType["HTTP_ERROR"] = "httpError";
-      ErrorType["CLIENT_ERROR"] = "clientErrror";
-      ErrorType["TIMEOUT"] = "timeout";
-    })(ErrorType = exports.ErrorType || (exports.ErrorType = {}));
-    /**
-     * the spec has a problem of having the error
-     * object somewhat underspecified, there is no clear
-     * description of the required contents.
-     * I want to streamline it with mojarra here
-     * hence we are going to move
-     * everything into the same attributes,
-     * I will add deprecated myfaces backwards compatibility attributes as well
-     */
-    var ErrorData = /** @class */ (function (_super) {
-      __extends(ErrorData, _super);
-      function ErrorData(source, errorName, errorMessage, responseText, responseXML, responseCode, status, type) {
-        if (responseText === void 0) { responseText = null; }
-        if (responseXML === void 0) { responseXML = null; }
-        if (responseCode === void 0) { responseCode = "200"; }
-        if (status === void 0) { status = "UNKNOWN"; }
-        if (type === void 0) { type = ErrorType.CLIENT_ERROR; }
-        var _this = _super.call(this) || this;
-        _this.type = "error";
-        _this.source = source;
-        _this.type = "error";
-        _this.errorName = errorName;
-        _this.message = _this.errorMessage = errorMessage;
-        _this.responseCode = responseCode;
-        _this.responseText = responseText;
-        _this.status = status;
-        _this.typeDetails = type;
-        if (type == ErrorType.SERVER_ERROR) {
-          _this.serverErrorName = _this.errorName;
-          _this.serverErrorMessage = _this.errorMessage;
-        }
-        return _this;
-      }
-      ErrorData.fromClient = function (e) {
-        return new ErrorData("client", e.name, e.message, e.stack);
-      };
-      ErrorData.fromHttpConnection = function (source, name, message, responseText, responseCode) {
-        return new ErrorData(source, name, message, responseText, responseCode, null, "UNKNOWN", ErrorType.HTTP_ERROR);
-      };
-      ErrorData.fromGeneric = function (context, errorCode, errorType) {
-        if (errorType === void 0) { errorType = ErrorType.SERVER_ERROR; }
-        var UNKNOWN = "UNKNOWN";
-        var getMsg = this.getMsg;
-        var source = getMsg(context, Const_1.SOURCE);
-        var errorName = getMsg(context, Const_1.ERROR_NAME);
-        var errorMessage = getMsg(context, Const_1.ERROR_MESSAGE);
-        var status = getMsg(context, Const_1.STATUS);
-        var responseText = getMsg(context, Const_1.RESPONSE_TEXT);
-        var responseXML = getMsg(context, Const_1.RESPONSE_XML);
-        return new ErrorData(source, name, errorMessage, responseText, responseXML, errorCode + Const_1.EMPTY_STR, status, errorType);
-      };
-      ErrorData.getMsg = function (context, param) {
-        var UNKNOWN = "UNKNOWN";
-        return getMessage(context.getIf(param).orElse(UNKNOWN).value);
-      };
-      ErrorData.fromServerError = function (context) {
-        return this.fromGeneric(context, -1);
-      };
-      return ErrorData;
-    }(EventData_1.EventData));
-    exports.ErrorData = ErrorData;
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/xhrCore/EventData.ts":
-  /*!*******************************************************!*\
-  !*** ./src/main/typescript/impl/xhrCore/EventData.ts ***!
-  \*******************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
-    var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
-    var EventData = /** @class */ (function () {
-      function EventData() {
-      }
-      EventData.createFromRequest = function (request, context, /*event name*/ name) {
-        var _a, _b, _c, _d;
-        var eventData = new EventData();
-        eventData.type = Const_1.EVENT;
-        eventData.status = name;
-        var sourceId = context.getIf(Const_1.SOURCE)
-            .orElse(context.getIf(Const_1.P_PARTIAL_SOURCE).value)
-            .orElse(context.getIf(Const_1.CTX_PARAM_PASS_THR, Const_1.P_PARTIAL_SOURCE).value).value;
-        if (sourceId) {
-          eventData.source = monadish_1.DQ.byId(sourceId).first().value.value;
-        }
-        if (name !== Const_1.BEGIN) {
-          eventData.responseCode = (_b = (_a = request) === null || _a === void 0 ? void 0 : _a.status) === null || _b === void 0 ? void 0 : _b.toString();
-          eventData.responseText = (_c = request) === null || _c === void 0 ? void 0 : _c.responseText;
-          eventData.responseXML = (_d = request) === null || _d === void 0 ? void 0 : _d.responseXML;
-        }
-        return eventData;
-      };
-      return EventData;
-    }());
-    exports.EventData = EventData;
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/xhrCore/RequestDataResolver.ts":
-  /*!*****************************************************************!*\
-  !*** ./src/main/typescript/impl/xhrCore/RequestDataResolver.ts ***!
-  \*****************************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
-    var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
-    var Lang_1 = __webpack_require__(/*! ../util/Lang */ "./src/main/typescript/impl/util/Lang.ts");
-    var ExtDomQuery_1 = __webpack_require__(/*! ../util/ExtDomQuery */ "./src/main/typescript/impl/util/ExtDomQuery.ts");
-    /**
-     * Resolver functions for various aspects of the request data
-     *
-     * stateless because it might be called from various
-     * parts of the response classes
-     */
-    /**
-     * resolves the event handlers lazly
-     * so that if some decoration happens in between we can deal with it
-     *
-     * @param funcName
-     */
-    function resolveHandlerFunc(requestContext, responseContext, funcName) {
-      return responseContext.getIf(funcName)
-          .orElse(requestContext.getIf(funcName).value)
-          .orElse(Const_1.EMPTY_FUNC).value;
-    }
-    exports.resolveHandlerFunc = resolveHandlerFunc;
-    function resolveTargetUrl(srcFormElement) {
-      return (typeof srcFormElement.elements[Const_1.ENCODED_URL] == 'undefined') ?
-          srcFormElement.action :
-          srcFormElement.elements[Const_1.ENCODED_URL].value;
-    }
-    exports.resolveTargetUrl = resolveTargetUrl;
-    function resolveFinalUrl(sourceForm, formData, ajaxType) {
-      if (ajaxType === void 0) { ajaxType = Const_1.REQ_TYPE_POST; }
-      var targetUrl = this.resolveTargetUrl(sourceForm.getAsElem(0).value);
-      return targetUrl + (ajaxType == Const_1.REQ_TYPE_GET ? "?" + formData.toString() : Const_1.EMPTY_STR);
-    }
-    exports.resolveFinalUrl = resolveFinalUrl;
-    /**
-     * form resolution the same way our old implementation did
-     * it is either the id or the parent form of the element or an embedded form
-     * of the element
-     *
-     * @param requestCtx
-     * @param elem
-     * @param event
-     */
-    function resolveForm(requestCtx, elem, event) {
-      var _a, _b, _c;
-      var configId = (_c = (_b = (_a = requestCtx.value) === null || _a === void 0 ? void 0 : _a.myfaces) === null || _b === void 0 ? void 0 : _b.form, (_c !== null && _c !== void 0 ? _c : Const_1.MF_NONE)); //requestCtx.getIf(MYFACES, "form").orElse(MF_NONE).value;
-      return monadish_1.DQ
-          .byId(configId)
-          .orElseLazy(function () { return Lang_1.ExtLang.getForm(elem.getAsElem(0).value, event); });
-    }
-    exports.resolveForm = resolveForm;
-    function resolveTimeout(options) {
-      var _a;
-      var getCfg = Lang_1.ExtLang.getLocalOrGlobalConfig;
-      return _a = options.getIf(Const_1.CTX_PARAM_TIMEOUT).value, (_a !== null && _a !== void 0 ? _a : getCfg(options.value, Const_1.CTX_PARAM_TIMEOUT, 0));
-    }
-    exports.resolveTimeout = resolveTimeout;
-    /**
-     * resolve the delay from the options and/or the request context and or the configuration
-     *
-     * @param options ... the options object, in most cases it will host the delay value
-     */
-    function resolveDelay(options) {
-      var _a;
-      var getCfg = Lang_1.ExtLang.getLocalOrGlobalConfig;
-      return _a = options.getIf(Const_1.CTX_PARAM_DELAY).value, (_a !== null && _a !== void 0 ? _a : getCfg(options.value, Const_1.CTX_PARAM_DELAY, 0));
-    }
-    exports.resolveDelay = resolveDelay;
-    /**
-     * resolves the window Id from various sources
-     *
-     * @param options
-     */
-    function resolveWindowId(options) {
-      var _a, _b, _c;
-      return _c = (_b = (_a = options) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.windowId, (_c !== null && _c !== void 0 ? _c : ExtDomQuery_1.ExtDomquery.windowId);
-    }
-    exports.resolveWindowId = resolveWindowId;
-    /**
-     * determines the correct event depending
-     * on the browsers state
-     *
-     * @param evt incoming event object (note not all browsers
-     * have this)
-     *
-     * @return an event object no matter what is incoming
-     */
-    function resolveEvent(evt) {
-      var _a, _b;
-      return _b = (evt !== null && evt !== void 0 ? evt : (_a = window) === null || _a === void 0 ? void 0 : _a.event), (_b !== null && _b !== void 0 ? _b : {});
-    }
-    exports.resolveEvent = resolveEvent;
-    /**
-     * cross port from the dojo lib
-     * browser save event resolution
-     * @param evt the event object
-     * (with a fallback for ie events if none is present)
-     */
-    function getEventTarget(evt) {
-      var _a, _b, _c, _d, _e;
-      //ie6 and 7 fallback
-      var finalEvent = this.resolveEvent(evt);
-      /**
-       * evt source is defined in the jsf events
-       * seems like some component authors use our code
-       * so we add it here see also
-       * https://issues.apache.org/jira/browse/MYFACES-2458
-       * not entirely a bug but makes sense to add this
-       * behavior. I dont use it that way but nevertheless it
-       * does not break anything so why not
-       * */
-      var t = (_d = (_b = (_a = finalEvent) === null || _a === void 0 ? void 0 : _a.srcElement, (_b !== null && _b !== void 0 ? _b : (_c = finalEvent) === null || _c === void 0 ? void 0 : _c.target)), (_d !== null && _d !== void 0 ? _d : (_e = finalEvent) === null || _e === void 0 ? void 0 : _e.source));
-      while ((t) && (t.nodeType != 1)) {
-        t = t.parentNode;
-      }
-      return t;
-    }
-    exports.getEventTarget = getEventTarget;
-    /**
-     * resolves a bunch of default values
-     * which can be further processed from the given
-     * call parameters of jsf.ajax.request
-     *
-     * @param event
-     * @param opts
-     * @param el
-     */
-    function resolveDefaults(event, opts, el) {
-      if (opts === void 0) { opts = {}; }
-      if (el === void 0) { el = null; }
-      var _a;
-      var resolvedEvent = resolveEvent(event);
-      //deep copy the options, so that further transformations to not backfire into the callers
-      var options = new monadish_1.Config(opts).deepCopy;
-      var elem = monadish_1.DQ.byId(el || resolvedEvent.target);
-      var elementId = elem.id;
-      var requestCtx = new monadish_1.Config({});
-      var internalCtx = new monadish_1.Config({});
-      var windowId = resolveWindowId(options);
-      var isResetValues = true === ((_a = options.value) === null || _a === void 0 ? void 0 : _a.resetValues);
-      return { resolvedEvent: resolvedEvent, options: options, elem: elem, elementId: elementId, requestCtx: requestCtx, internalCtx: internalCtx, windowId: windowId, isResetValues: isResetValues };
-    }
-    exports.resolveDefaults = resolveDefaults;
-    ;
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/xhrCore/ResonseDataResolver.ts":
-  /*!*****************************************************************!*\
-  !*** ./src/main/typescript/impl/xhrCore/ResonseDataResolver.ts ***!
-  \*****************************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
-    var Assertions_1 = __webpack_require__(/*! ../util/Assertions */ "./src/main/typescript/impl/util/Assertions.ts");
-    var monadish_2 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
-    var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
-    /**
-     * Resolver functions for various aspects of the response data
-     *
-     * stateless because it might be called from various
-     * parts of the response classes
-     */
-    /**
-     * fetches the response XML
-     * as XML Query object
-     *
-     * @param request the request hosting the responseXML
-     *
-     * Throws an error in case of non existent or wrong xml data
-     *
-     */
-    function resolveResponseXML(request) {
-      var ret = new monadish_1.XMLQuery(request.getIf(Const_1.SEL_RESPONSE_XML).value);
-      Assertions_1.Assertions.assertValidXMLResponse(ret);
-      return ret;
-    }
-    exports.resolveResponseXML = resolveResponseXML;
-    /**
-     * Splits the incoming passthrough context apart
-     * in an internal and an external nomalized context
-     * the internal one is just for our internal processing
-     *
-     * @param context the root context as associative array
-     */
-    function resolveContexts(context) {
-      /**
-       * we split the context apart into the external one and
-       * some internal values
-       */
-      var externalContext = monadish_1.Config.fromNullable(context);
-      var internalContext = externalContext.getIf(Const_1.CTX_PARAM_MF_INTERNAL);
-      if (!internalContext.isPresent()) {
-        internalContext = monadish_1.Config.fromNullable({});
-      }
-      /**
-       * prepare storage for some deferred operations
-       */
-      internalContext.assign(Const_1.UPDATE_FORMS).value = [];
-      internalContext.assign(Const_1.UPDATE_ELEMS).value = [];
-      return { externalContext: externalContext, internalContext: internalContext };
-    }
-    exports.resolveContexts = resolveContexts;
-    /**
-     * fetches the source element out of our conexts
-     *
-     * @param context the external context which shpuld host the source id
-     * @param internalContext internal passthrough fall back
-     *
-     */
-    function resolveSourceElement(context, internalContext) {
-      var elemId = resolveSourceElementId(context, internalContext);
-      return monadish_2.DQ.byId(elemId.value);
-    }
-    exports.resolveSourceElement = resolveSourceElement;
-    /**
-     * fetches the source form if it still exists
-     * also embedded forms and parent forms are taken into consideration
-     * as fallbacks
-     *
-     * @param internalContext
-     * @param elem
-     */
-    function resolveSourceForm(internalContext, elem) {
-      var sourceFormId = internalContext.getIf(Const_1.CTX_PARAM_SRC_FRM_ID);
-      var sourceForm = new monadish_2.DQ(sourceFormId.isPresent() ? document.forms[sourceFormId.value] : null);
-      sourceForm = sourceForm.orElse(elem.parents(Const_1.TAG_FORM))
-          .orElse(elem.querySelectorAll(Const_1.TAG_FORM))
-          .orElse(monadish_2.DQ.querySelectorAll(Const_1.TAG_FORM));
-      return sourceForm;
-    }
-    exports.resolveSourceForm = resolveSourceForm;
-    function resolveSourceElementId(context, internalContext) {
-      //?internal context?? used to be external one
-      return internalContext.getIf(Const_1.CTX_PARAM_SRC_CTL_ID)
-          .orElseLazy(function () { return context.getIf(Const_1.SOURCE, "id").value; });
-    }
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/xhrCore/Response.ts":
-  /*!******************************************************!*\
-  !*** ./src/main/typescript/impl/xhrCore/Response.ts ***!
-  \******************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
-    var ResponseProcessor_1 = __webpack_require__(/*! ./ResponseProcessor */ "./src/main/typescript/impl/xhrCore/ResponseProcessor.ts");
-    var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
-    var ResonseDataResolver_1 = __webpack_require__(/*! ./ResonseDataResolver */ "./src/main/typescript/impl/xhrCore/ResonseDataResolver.ts");
-    var Response;
-    (function (Response) {
-      /**
-       * Standardized jsf.js response
-       * this one is called straight from jsf.js.response
-       *
-       * The processing follows the spec by going for the responseXML
-       * and processing its tags
-       *
-       * @param {XMLHttpRequest} request (xhrRequest) - xhr request object
-       * @param {[key: string]: any} context (Map) - AJAX context
-       *
-       */
-      function processResponse(request, context) {
-        var req = monadish_1.Config.fromNullable(request);
-        var _a = ResonseDataResolver_1.resolveContexts(context), externalContext = _a.externalContext, internalContext = _a.internalContext;
-        var responseXML = ResonseDataResolver_1.resolveResponseXML(req);
-        var responseProcessor = new ResponseProcessor_1.ResponseProcessor(req, externalContext, internalContext);
-        internalContext.assign(Const_1.RESPONSE_XML).value = responseXML;
-        //we now process the partial tags, or in none given raise an error
-        responseXML.querySelectorAll(Const_1.RESP_PARTIAL)
-            .each(function (item) { return processPartialTag(item, responseProcessor, internalContext); });
-        //we now process the viewstates and the evals deferred
-        //the reason for this is that often it is better
-        //to wait until the document has caught up before
-        //doing any evals even on embedded scripts
-        responseProcessor.fixViewStates();
-        responseProcessor.globalEval();
-        responseProcessor.done();
-      }
-      Response.processResponse = processResponse;
-      /**
-       * highest node partial-response from there the main operations are triggered
-       */
-      function processPartialTag(node, responseProcessor, internalContext) {
-        internalContext.assign(Const_1.PARTIAL_ID).value = node.id;
-        var SEL_SUB_TAGS = [Const_1.CMD_ERROR, Const_1.CMD_REDIRECT, Const_1.CMD_CHANGES].join(",");
-        //now we can process the main operations
-        node.getIf(SEL_SUB_TAGS).each(function (node) {
-          switch (node.tagName.value) {
-            case Const_1.CMD_ERROR:
-              responseProcessor.error(node);
-              break;
-            case Const_1.CMD_REDIRECT:
-              responseProcessor.redirect(node);
-              break;
-            case Const_1.CMD_CHANGES:
-              processChangesTag(node, responseProcessor);
-              break;
-          }
-        });
-      }
-      var processInsert = function (responseProcessor, node) {
-        //path1 insert after as child tags
-        if (node.querySelectorAll([Const_1.TAG_BEFORE, Const_1.TAG_AFTER].join(",")).length) {
-          responseProcessor.insertWithSubtags(node);
-        }
-        else { //insert before after with id
-          responseProcessor.insert(node);
-        }
-      };
-      /**
-       * next level changes tag
-       *
-       * @param node
-       * @param responseProcessor
-       */
-      function processChangesTag(node, responseProcessor) {
-        var ALLOWED_TAGS = [Const_1.CMD_UPDATE, Const_1.CMD_EVAL, Const_1.CMD_INSERT, Const_1.CMD_DELETE, Const_1.CMD_ATTRIBUTES, Const_1.CMD_EXTENSION].join(",");
-        node.getIf(ALLOWED_TAGS).each(function (node) {
-          switch (node.tagName.value) {
-            case Const_1.CMD_UPDATE:
-              processUpdateTag(node, responseProcessor);
-              break;
-            case Const_1.CMD_EVAL:
-              responseProcessor.eval(node);
-              break;
-            case Const_1.CMD_INSERT:
-              processInsert(responseProcessor, node);
-              break;
-            case Const_1.CMD_DELETE:
-              responseProcessor.delete(node);
-              break;
-            case Const_1.CMD_ATTRIBUTES:
-              responseProcessor.attributes(node);
-              break;
-            case Const_1.CMD_EXTENSION:
-              break;
-          }
-        });
-        return true;
-      }
-      /**
-       * branch tag update.. drill further down into the updates
-       * special case viewstate in that case it is a leaf
-       * and the viewstate must be processed
-       *
-       * @param node
-       * @param responseProcessor
-       */
-      function processUpdateTag(node, responseProcessor) {
-        if (!responseProcessor.processViewState(node)) {
-          handleElementUpdate(node, responseProcessor);
-        }
-      }
-      /**
-       * element update
-       *
-       * @param node
-       * @param responseProcessor
-       */
-      function handleElementUpdate(node, responseProcessor) {
-        var cdataBlock = node.cDATAAsString;
-        switch (node.id.value) {
-          case Const_1.P_VIEWROOT:
-            responseProcessor.replaceViewRoot(monadish_1.DQ.fromMarkup(cdataBlock.substring(cdataBlock.indexOf("<html"))));
-            break;
-          case Const_1.P_VIEWHEAD:
-            responseProcessor.replaceHead(monadish_1.DQ.fromMarkup(cdataBlock));
-            break;
-          case Const_1.P_VIEWBODY:
-            responseProcessor.replaceBody(monadish_1.DQ.fromMarkup(cdataBlock));
-            break;
-          default: //htmlItem replacement
-            responseProcessor.update(node, cdataBlock);
-            break;
-        }
-      }
-    })(Response = exports.Response || (exports.Response = {}));
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/xhrCore/ResponseProcessor.ts":
-  /*!***************************************************************!*\
-  !*** ./src/main/typescript/impl/xhrCore/ResponseProcessor.ts ***!
-  \***************************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    var __spreadArrays = (this && this.__spreadArrays) || function () {
-      for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
-      for (var r = Array(s), k = 0, i = 0; i < il; i++)
-        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
-          r[k] = a[j];
-      return r;
-    };
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
-    var AjaxImpl_1 = __webpack_require__(/*! ../AjaxImpl */ "./src/main/typescript/impl/AjaxImpl.ts");
-    var Assertions_1 = __webpack_require__(/*! ../util/Assertions */ "./src/main/typescript/impl/util/Assertions.ts");
-    var ErrorData_1 = __webpack_require__(/*! ./ErrorData */ "./src/main/typescript/impl/xhrCore/ErrorData.ts");
-    var ImplTypes_1 = __webpack_require__(/*! ../core/ImplTypes */ "./src/main/typescript/impl/core/ImplTypes.ts");
-    var EventData_1 = __webpack_require__(/*! ./EventData */ "./src/main/typescript/impl/xhrCore/EventData.ts");
-    var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
-    var trim = monadish_1.Lang.trim;
-    /**
-     * Response processor
-     *
-     * Each  XML tag is either a node or a leaf
-     * or both
-     *
-     * the processor provides a set of operations
-     * which are executed on a single leaf node per operation
-     * and present the core functionality of our response
-     *
-     * Note the response processor is stateful hence we bundle it in a class
-     * to reduce code we keep references tot contexts in place
-     */
-    var ResponseProcessor = /** @class */ (function () {
-      function ResponseProcessor(request, externalContext, internalContext) {
-        this.request = request;
-        this.externalContext = externalContext;
-        this.internalContext = internalContext;
-      }
-      ResponseProcessor.prototype.replaceHead = function (shadowDocument) {
-        var shadowHead = shadowDocument.querySelectorAll(Const_1.TAG_HEAD);
-        if (!shadowHead.isPresent()) {
-          return;
-        }
-        var oldHead = monadish_1.DQ.querySelectorAll(Const_1.TAG_HEAD);
-        //delete all to avoid script and style overlays
-        oldHead.querySelectorAll(Const_1.SEL_SCRIPTS_STYLES).delete();
-        this.storeForEval(shadowHead);
-      };
-      /**
-       * replaces the body in the expected manner
-       * which means the entire body content is refreshed
-       * however also the body attributes must be transferred
-       * keeping event handlers etc... in place
-       *
-       * @param shadowDocument .. an incoming shadow document hosting the new nodes
-       */
-      ResponseProcessor.prototype.replaceBody = function (shadowDocument) {
-        var shadowBody = shadowDocument.querySelectorAll(Const_1.TAG_BODY);
-        if (!shadowBody.isPresent()) {
-          return;
-        }
-        var shadowInnerHTML = shadowBody.html().value;
-        var resultingBody = monadish_1.DQ.querySelectorAll(Const_1.TAG_BODY).html(shadowInnerHTML);
-        var updateForms = resultingBody.querySelectorAll(Const_1.TAG_FORM);
-        resultingBody.copyAttrs(shadowBody);
-        this.storeForPostProcessing(updateForms, resultingBody);
-      };
-      /**
-       * Leaf Tag eval... process whatever is in the evals cdata block
-       *
-       * @param node the node to eval
-       */
-      ResponseProcessor.prototype.eval = function (node) {
-        monadish_1.DQ.globalEval(node.cDATAAsString);
-      };
-      /**
-       * processes an incoming error from the response
-       * which is hosted under the &lt;error&gt; tag
-       * @param node the node hosting the error in our response xml
-       * @param node the node in the xml hosting the error message
-       */
-      ResponseProcessor.prototype.error = function (node) {
-        /**
-         * <error>
-         *      <error-name>String</error-name>
-         *      <error-message><![CDATA[message]]></error-message>
-         * <error>
-         */
-        var mergedErrorData = new monadish_1.Config({});
-        mergedErrorData.assign(Const_1.SOURCE).value = this.externalContext.getIf(Const_1.P_PARTIAL_SOURCE).get(0).value;
-        mergedErrorData.assign(Const_1.ERROR_NAME).value = node.getIf(Const_1.ERROR_NAME).textContent(Const_1.EMPTY_STR);
-        mergedErrorData.assign(Const_1.ERROR_MESSAGE).value = node.getIf(Const_1.ERROR_MESSAGE).cDATAAsString;
-        var hasResponseXML = this.internalContext.get(Const_1.RESPONSE_XML).isPresent();
-        mergedErrorData.assignIf(hasResponseXML, Const_1.RESPONSE_XML).value = this.internalContext.getIf(Const_1.RESPONSE_XML).value.get(0).value;
-        var errorData = ErrorData_1.ErrorData.fromServerError(mergedErrorData);
-        this.externalContext.getIf(Const_1.ON_ERROR).orElse(this.internalContext.getIf(Const_1.ON_ERROR).value).orElse(Const_1.EMPTY_FUNC).value(errorData);
-        AjaxImpl_1.Implementation.sendError(errorData);
-      };
-      /**
-       * process the redirect operation
-       *
-       * @param node
-       */
-      ResponseProcessor.prototype.redirect = function (node) {
-        Assertions_1.Assertions.assertUrlExists(node);
-        var redirectUrl = trim(node.attr(Const_1.ATTR_URL).value);
-        if (redirectUrl != Const_1.EMPTY_STR) {
-          window.location.href = redirectUrl;
-        }
-      };
-      /**
-       * processes the update operation and updates the node with the cdata block
-       * @param node the xml response node hosting the update info
-       * @param cdataBlock the cdata block with the new html code
-       */
-      ResponseProcessor.prototype.update = function (node, cdataBlock) {
-        var _a;
-        var result = monadish_1.DQ.byId(node.id.value).outerHTML(cdataBlock, false, false);
-        var sourceForm = (_a = result) === null || _a === void 0 ? void 0 : _a.parents(Const_1.TAG_FORM).orElse(result.byTagName(Const_1.TAG_FORM, true));
-        if (sourceForm) {
-          this.storeForPostProcessing(sourceForm, result);
-        }
-      };
-      ResponseProcessor.prototype.delete = function (node) {
-        monadish_1.DQ.byId(node.id.value).delete();
-      };
-      /**
-       * attributes leaf tag... process the attributes
-       *
-       * @param node
-       */
-      ResponseProcessor.prototype.attributes = function (node) {
-        var elem = monadish_1.DQ.byId(node.id.value);
-        node.byTagName(Const_1.TAG_ATTR).each(function (item) {
-          elem.attr(item.attr(Const_1.ATTR_NAME).value).value = item.attr(Const_1.ATTR_VALUE).value;
-        });
-      };
-      /**
-       * @param shadowDocument a shadow document which is needed for further processing
-       */
-      ResponseProcessor.prototype.replaceViewRoot = function (shadowDocument) {
-        this.replaceHead(shadowDocument);
-        this.replaceBody(shadowDocument);
-      };
-      /**
-       * insert handling, either before or after
-       *
-       * @param node
-       */
-      ResponseProcessor.prototype.insert = function (node) {
-        //let insertId = node.id; //not used atm
-        var before = node.attr(Const_1.TAG_BEFORE);
-        var after = node.attr(Const_1.TAG_AFTER);
-        var insertNodes = monadish_1.DQ.fromMarkup(node.cDATAAsString);
-        if (before.isPresent()) {
-          monadish_1.DQ.byId(before.value).insertBefore(insertNodes);
-          this.internalContext.assign(Const_1.UPDATE_ELEMS).value.push(insertNodes);
-        }
-        if (after.isPresent()) {
-          var domQuery = monadish_1.DQ.byId(after.value);
-          domQuery.insertAfter(insertNodes);
-          this.internalContext.assign(Const_1.UPDATE_ELEMS).value.push(insertNodes);
-        }
-      };
-      /**
-       * handler for the case &lt;insert <&lt; before id="...
-       *
-       * @param node the node hosting the insert data
-       */
-      ResponseProcessor.prototype.insertWithSubtags = function (node) {
-        var _this = this;
-        var before = node.querySelectorAll(Const_1.TAG_BEFORE);
-        var after = node.querySelectorAll(Const_1.TAG_AFTER);
-        before.each(function (item) {
-          var insertId = item.attr(Const_1.ATTR_ID);
-          var insertNodes = monadish_1.DQ.fromMarkup(item.cDATAAsString);
-          if (insertId.isPresent()) {
-            monadish_1.DQ.byId(insertId.value).insertBefore(insertNodes);
-            _this.internalContext.assign(Const_1.UPDATE_ELEMS).value.push(insertNodes);
-          }
-        });
-        after.each(function (item) {
-          var insertId = item.attr(Const_1.ATTR_ID);
-          var insertNodes = monadish_1.DQ.fromMarkup(item.cDATAAsString);
-          if (insertId.isPresent()) {
-            monadish_1.DQ.byId(insertId.value).insertAfter(insertNodes);
-            _this.internalContext.assign(Const_1.UPDATE_ELEMS).value.push(insertNodes);
-          }
-        });
-      };
-      /**
-       * process the viewState update, update the affected
-       * forms with their respective new viewstate values
-       *
-       */
-      ResponseProcessor.prototype.processViewState = function (node) {
-        if (ResponseProcessor.isViewStateNode(node)) {
-          var viewStateValue = node.cDATAAsString;
-          this.internalContext.assign(Const_1.APPLIED_VST, node.id.value).value = new ImplTypes_1.ViewState(node.id.value, viewStateValue);
-          return true;
-        }
-        return false;
-      };
-      /**
-       * generic global eval which runs the embedded css and scripts
-       */
-      ResponseProcessor.prototype.globalEval = function () {
-        var updateElems = new (monadish_1.DQ.bind.apply(monadish_1.DQ, __spreadArrays([void 0], this.internalContext.getIf(Const_1.UPDATE_ELEMS).value)))();
-        updateElems.runCss();
-        updateElems.runScripts();
-      };
-      /**
-       * post processing viewstate fixing
-       */
-      ResponseProcessor.prototype.fixViewStates = function () {
-        var _this = this;
-        monadish_1.Stream.ofAssoc(this.internalContext.getIf(Const_1.APPLIED_VST).orElse({}).value)
-            .each(function (item) {
-              var value = item[1];
-              var nameSpace = monadish_1.DQ.byId(value.nameSpace).orElse(document.body);
-              var affectedForms = nameSpace.byTagName(Const_1.TAG_FORM);
-              var affectedForms2 = nameSpace.filter(function (item) { return item.tagName.orElse(Const_1.EMPTY_STR).value.toLowerCase() == Const_1.TAG_FORM; });
-              _this.appendViewStateToForms(new monadish_1.DomQuery(affectedForms, affectedForms2), value.value);
-            });
-      };
-      /**
-       * all processing done we can close the request and send the appropriate events
-       */
-      ResponseProcessor.prototype.done = function () {
-        var eventData = EventData_1.EventData.createFromRequest(this.request.value, this.externalContext, Const_1.SUCCESS);
-        //because some frameworks might decorate them over the context in the response
-        var eventHandler = this.externalContext.getIf(Const_1.ON_EVENT).orElse(this.internalContext.getIf(Const_1.ON_EVENT).value).orElse(Const_1.EMPTY_FUNC).value;
-        AjaxImpl_1.Implementation.sendEvent(eventData, eventHandler);
-      };
-      /**
-       * proper viewstate -> form assignment
-       *
-       * @param forms the forms to append the viewstate to
-       * @param viewState the final viewstate
-       */
-      ResponseProcessor.prototype.appendViewStateToForms = function (forms, viewState) {
-        forms.each(function (form) {
-          var viewStateElems = form.querySelectorAll(Const_1.SEL_VIEWSTATE_ELEM)
-              .orElseLazy(function () { return ResponseProcessor.newViewStateElement(form); });
-          viewStateElems.attr("value").value = viewState;
-        });
-      };
-      /**
-       * Helper to Create a new JSF ViewState Element
-       *
-       * @param parent, the parent node to attach the viewstate element to
-       * (usually a form node)
-       */
-      ResponseProcessor.newViewStateElement = function (parent) {
-        var newViewState = monadish_1.DQ.fromMarkup(Const_1.HTML_VIEWSTATE);
-        newViewState.appendTo(parent);
-        return newViewState;
-      };
-      /**
-       * Stores certain aspects of the dom for later post processing
-       *
-       * @param updateForms the update forms which should receive standardized internal jsf data
-       * @param toBeEvaled the resulting elements which should be evaled
-       */
-      ResponseProcessor.prototype.storeForPostProcessing = function (updateForms, toBeEvaled) {
-        this.storeForUpdate(updateForms);
-        this.storeForEval(toBeEvaled);
-      };
-      /**
-       * helper to store a given form for the update post processing (viewstate)
-       *
-       * @param updateForms the dom query object pointing to the forms which need to be updated
-       */
-      ResponseProcessor.prototype.storeForUpdate = function (updateForms) {
-        this.internalContext.assign(Const_1.UPDATE_FORMS).value.push(updateForms);
-      };
-      /**
-       * same for eval (js and css)
-       *
-       * @param toBeEvaled
-       */
-      ResponseProcessor.prototype.storeForEval = function (toBeEvaled) {
-        this.internalContext.assign(Const_1.UPDATE_ELEMS).value.push(toBeEvaled);
-      };
-      /**
-       * check whether a given XMLQuery node is an explicit viewstate node
-       *
-       * @param node the node to check
-       * @returns true of it ii
-       */
-      ResponseProcessor.isViewStateNode = function (node) {
-        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
-        var separatorChar = window.jsf.separatorchar;
-        return "undefined" != typeof ((_b = (_a = node) === null || _a === void 0 ? void 0 : _a.id) === null || _b === void 0 ? void 0 : _b.value) && (((_d = (_c = node) === null || _c === void 0 ? void 0 : _c.id) === null || _d === void 0 ? void 0 : _d.value) == Const_1.P_VIEWSTATE ||
-            ((_g = (_f = (_e = node) === null || _e === void 0 ? void 0 : _e.id) === null || _f === void 0 ? void 0 : _f.value) === null || _g === void 0 ? void 0 : _g.indexOf([separatorChar, Const_1.P_VIEWSTATE].join(Const_1.EMPTY_STR))) != -1 ||
-            ((_k = (_j = (_h = node) === null || _h === void 0 ? void 0 : _h.id) === null || _j === void 0 ? void 0 : _j.value) === null || _k === void 0 ? void 0 : _k.indexOf([Const_1.P_VIEWSTATE, separatorChar].join(Const_1.EMPTY_STR))) != -1);
-      };
-      return ResponseProcessor;
-    }());
-    exports.ResponseProcessor = ResponseProcessor;
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/xhrCore/XhrFormData.ts":
-  /*!*********************************************************!*\
-  !*** ./src/main/typescript/impl/xhrCore/XhrFormData.ts ***!
-  \*********************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    var __extends = (this && this.__extends) || (function () {
-      var extendStatics = function (d, b) {
-        extendStatics = Object.setPrototypeOf ||
-            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
-        return extendStatics(d, b);
-      };
-      return function (d, b) {
-        extendStatics(d, b);
-        function __() { this.constructor = d; }
-        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-      };
-    })();
-    var __spreadArrays = (this && this.__spreadArrays) || function () {
-      for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
-      for (var r = Array(s), k = 0, i = 0; i < il; i++)
-        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
-          r[k] = a[j];
-      return r;
-    };
-    Object.defineProperty(exports, "__esModule", { value: true });
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
-    var monadish_2 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
-    var monadish_3 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
-    var isString = monadish_1.Lang.isString;
-    var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
-    /**
-     * A unified form data class
-     * which builds upon our configuration.
-     *
-     * We cannot use standard html5 forms everywhere
-     * due to api constraints on the HTML Form object in IE11
-     * and due to the url encoding constraint given by the jsf.js spec
-     */
-    var XhrFormData = /** @class */ (function (_super) {
-      __extends(XhrFormData, _super);
-      /**
-       * data collector from a given form
-       *
-       * @param dataSource either a form as DomQuery object or an encoded url string
-       * @param partialIdsArray partial ids to collect, to reduce the data sent down
-       */
-      function XhrFormData(dataSource, partialIdsArray, encode) {
-        if (encode === void 0) { encode = true; }
-        var _this = _super.call(this, {}) || this;
-        _this.dataSource = dataSource;
-        _this.partialIdsArray = partialIdsArray;
-        _this.encode = encode;
-        //a call to getViewState before must pass the encoded line
-        //a call from getViewState passes the form element as datasource
-        //so we have two call points
-        if (isString(dataSource)) {
-          _this.assignEncodedString(_this.dataSource);
-        }
-        else {
-          _this.handleFormSource();
-        }
-        return _this;
-      }
-      XhrFormData.prototype.handleFormSource = function () {
-        //encode and append the issuing item if not a partial ids array of ids is passed
-        /*
-         * Spec. 13.3.1
-         * Collect and encode input elements.
-         * Additionally the hidden element javax.faces.ViewState
-         * Enhancement partial page submit
-         *
-         */
-        this.encodeSubmittableFields(this, this.dataSource, this.partialIdsArray);
-        if (this.getIf(Const_1.P_VIEWSTATE).isPresent()) {
-          return;
-        }
-        this.applyViewState(this.dataSource);
-      };
-      /**
-       * special case viewstate handling
-       *
-       * @param form the form holding the viewstate value
-       */
-      XhrFormData.prototype.applyViewState = function (form) {
-        var viewState = form.byId(Const_1.P_VIEWSTATE).inputValue;
-        this.assignIf(viewState.isPresent(), Const_1.P_VIEWSTATE).value = viewState.value;
-      };
-      /**
-       * assignes a url encoded string to this xhrFormData object
-       * as key value entry
-       * @param encoded
-       */
-      XhrFormData.prototype.assignEncodedString = function (encoded) {
-        var _this = this;
-        var keyValueEntries = encoded.split(/&/gi);
-        monadish_2.Stream.of.apply(monadish_2.Stream, keyValueEntries).map(function (line) { return line.split(/=(.*)/gi); })
-        //special case of having keys without values
-            .map(function (keyVal) { var _a, _b, _c, _d; return keyVal.length < 3 ? [(_b = (_a = keyVal) === null || _a === void 0 ? void 0 : _a[0], (_b !== null && _b !== void 0 ? _b : [])), (_d = (_c = keyVal) === null || _c === void 0 ? void 0 : _c[1], (_d !== null && _d !== void 0 ? _d : []))] : keyVal; })
-            .each(function (keyVal) {
-              var _a, _b, _c;
-              _this.assign(keyVal[0]).value = (_c = (_b = (_a = keyVal) === null || _a === void 0 ? void 0 : _a.splice(1)) === null || _b === void 0 ? void 0 : _b.join(""), (_c !== null && _c !== void 0 ? _c : ""));
-            });
-      };
-      // noinspection JSUnusedGlobalSymbols
-      /**
-       * @returns a Form data representation
-       */
-      XhrFormData.prototype.toFormData = function () {
-        var ret = new FormData();
-        for (var key in this.value) {
-          if (this.value.hasOwnProperty(key)) {
-            ret.append(key, this.value[key]);
-          }
-        }
-        return ret;
-      };
-      /**
-       * returns an encoded string representation of our xhr form data
-       *
-       * @param defaultStr optional default value if nothing is there to encode
-       */
-      XhrFormData.prototype.toString = function (defaultStr) {
-        if (defaultStr === void 0) { defaultStr = Const_1.EMPTY_STR; }
-        if (this.isAbsent()) {
-          return defaultStr;
-        }
-        var entries = [];
-        for (var key in this.value) {
-          if (this.value.hasOwnProperty(key)) {
-            //key value already encoded so no need to reencode them again
-            entries.push(encodeURIComponent(key) + "=" + encodeURIComponent(this.value[key]));
-          }
-        }
-        return entries.join("&");
-      };
-      /**
-       * determines fields to submit
-       * @param {Object} targetBuf - the target form buffer receiving the data
-       * @param {Node} parentItem - form element item is nested in
-       * @param {Array} partialIds - ids fo PPS
-       */
-      XhrFormData.prototype.encodeSubmittableFields = function (targetBuf, parentItem, partialIds) {
-        var toEncode = null;
-        if (this.partialIdsArray && this.partialIdsArray.length) {
-          //in case of our myfaces reduced ppr we only
-          //only submit the partials
-          this._value = {};
-          toEncode = new (monadish_3.DQ.bind.apply(monadish_3.DQ, __spreadArrays([void 0], this.partialIdsArray)))();
-        }
-        else {
-          if (parentItem.isAbsent())
-            throw "NO_PARITEM";
-          toEncode = parentItem;
-        }
-        //lets encode the form elements
-        this.shallowMerge(toEncode.querySelectorAll("input, checkbox, select, textarea").encodeFormElement());
-      };
-      Object.defineProperty(XhrFormData.prototype, "isMultipartRequest", {
-        /**
-         * checks if the given datasource is a multipart request source
-         */
-        get: function () {
-          return this.dataSource instanceof monadish_3.DQ && this.dataSource.querySelectorAll("input[type='file']").isPresent();
-        },
-        enumerable: true,
-        configurable: true
-      });
-      return XhrFormData;
-    }(monadish_1.Config));
-    exports.XhrFormData = XhrFormData;
-
-
-    /***/ }),
-
-  /***/ "./src/main/typescript/impl/xhrCore/XhrRequest.ts":
-  /*!********************************************************!*\
-  !*** ./src/main/typescript/impl/xhrCore/XhrRequest.ts ***!
-  \********************************************************/
-  /*! no static exports found */
-  /***/ (function(module, exports, __webpack_require__) {
-
-    "use strict";
-
-    /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-    Object.defineProperty(exports, "__esModule", { value: true });
-    var monadish_1 = __webpack_require__(/*! ../../ext/monadish */ "./src/main/typescript/ext/monadish/index.ts");
-    var AjaxImpl_1 = __webpack_require__(/*! ../AjaxImpl */ "./src/main/typescript/impl/AjaxImpl.ts");
-    var XhrFormData_1 = __webpack_require__(/*! ./XhrFormData */ "./src/main/typescript/impl/xhrCore/XhrFormData.ts");
-    var ErrorData_1 = __webpack_require__(/*! ./ErrorData */ "./src/main/typescript/impl/xhrCore/ErrorData.ts");
-    var EventData_1 = __webpack_require__(/*! ./EventData */ "./src/main/typescript/impl/xhrCore/EventData.ts");
-    var Lang_1 = __webpack_require__(/*! ../util/Lang */ "./src/main/typescript/impl/util/Lang.ts");
-    var Const_1 = __webpack_require__(/*! ../core/Const */ "./src/main/typescript/impl/core/Const.ts");
-    var RequestDataResolver_1 = __webpack_require__(/*! ./RequestDataResolver */ "./src/main/typescript/impl/xhrCore/RequestDataResolver.ts");
-    var failSaveExecute = Lang_1.ExtLang.failSaveExecute;
-    var XhrRequest = /** @class */ (function () {
-      /**
-       * Reqired Parameters
-       *
-       * @param source the issuing element
-       * @param sourceForm the form which is related to the issuing element
-       * @param requestContext the request context with allö pass through values
-       *
-       * Optional Parameters
-       *
-       * @param partialIdsArray an optional restricting partial ids array for encoding
-       * @param timeout optional xhr timeout
-       * @param ajaxType optional request type, default "POST"
-       * @param contentType optional content type, default "application/x-www-form-urlencoded"
-       * @param xhrObject optional xhr object which must fullfill the XMLHTTPRequest api, default XMLHttpRequest
-       */
-      function XhrRequest(source, sourceForm, requestContext, internalContext, partialIdsArray, timeout, ajaxType, contentType, xhrObject) {
-        var _this = this;
-        if (partialIdsArray === void 0) { partialIdsArray = []; }
-        if (timeout === void 0) { timeout = Const_1.NO_TIMEOUT; }
-        if (ajaxType === void 0) { ajaxType = Const_1.REQ_TYPE_POST; }
-        if (contentType === void 0) { contentType = Const_1.URL_ENCODED; }
-        if (xhrObject === void 0) { xhrObject = new XMLHttpRequest(); }
-        this.source = source;
-        this.sourceForm = sourceForm;
-        this.requestContext = requestContext;
-        this.internalContext = internalContext;
-        this.partialIdsArray = partialIdsArray;
-        this.timeout = timeout;
-        this.ajaxType = ajaxType;
-        this.contentType = contentType;
-        this.xhrObject = xhrObject;
-        this.stopProgress = false;
-        /**
-         * helper support so that we do not have to drag in Promise shims
-         */
-        this.catchFuncs = [];
-        this.thenFunc = [];
-        /*
-        * we omit promises here
-        * some browsers do not support it and we do not need shim code
-        */
-        this.registerXhrCallbacks(function (data) { _this.resolve(data); }, function (data) { _this.reject(data); });
-      }
-      XhrRequest.prototype.start = function () {
-        var _this = this;
-        var ignoreErr = failSaveExecute;
-        var xhrObject = this.xhrObject;
-        try {
-          var viewState = jsf.getViewState(this.sourceForm.getAsElem(0).value);
-          //encoded we need to decode
-          var formData = new XhrFormData_1.XhrFormData(decodeURIComponent(viewState));
-          this.contentType = formData.isMultipartRequest ? Const_1.MULTIPART : this.contentType;
-          //next step the pass through parameters are merged in for post params
-          var requestContext = this.requestContext;
-          var passThroughParams = requestContext.getIf(Const_1.CTX_PARAM_PASS_THR);
-          formData.shallowMerge(passThroughParams);
-          this.responseContext = passThroughParams.deepCopy;
-          //we have to shift the internal passthroughs around to build up our response context
-          var responseContext = this.responseContext;
-          responseContext.assign(Const_1.CTX_PARAM_MF_INTERNAL).value = this.internalContext.value;
-          //per spec the onevent and onerrors must be passed through to the response
-          responseContext.assign(Const_1.ON_EVENT).value = requestContext.getIf(Const_1.ON_EVENT).value;
-          responseContext.assign(Const_1.ON_ERROR).value = requestContext.getIf(Const_1.ON_ERROR).value;
-          xhrObject.open(this.ajaxType, RequestDataResolver_1.resolveFinalUrl(this.sourceForm, formData, this.ajaxType), true);
-          //adding timeout
-          this.timeout ? xhrObject.timeout = this.timeout : null;
-          //a bug in the xhr stub library prevents the setRequestHeader to be properly executed on fake xhr objects
-          //normal browsers should resolve this
-          //tests can quietly fail on this one
-          ignoreErr(function () { return xhrObject.setRequestHeader(Const_1.CONTENT_TYPE, _this.contentType + "; charset=utf-8"); });
-          ignoreErr(function () { return xhrObject.setRequestHeader(Const_1.HEAD_FACES_REQ, Const_1.VAL_AJAX); });
-          //probably not needed anymore, will test this
-          //some webkit based mobile browsers do not follow the w3c spec of
-          // setting the accept headers automatically
-          ignoreErr(function () { return xhrObject.setRequestHeader(Const_1.REQ_ACCEPT, Const_1.STD_ACCEPT); });
-          this.sendEvent(Const_1.BEGIN);
-          this.sendRequest(formData);
-        }
-        catch (e) {
-          //_onError//_onError
-          this.handleError(e);
-        }
-        return this;
-      };
-      XhrRequest.prototype.cancel = function () {
-        try {
-          this.xhrObject.abort();
-        }
-        catch (e) {
-          this.handleError(e);
-        }
-      };
-      XhrRequest.prototype.resolve = function (data) {
-        monadish_1.Stream.of.apply(monadish_1.Stream, this.thenFunc).reduce(function (inputVal, thenFunc) {
-          return thenFunc(inputVal);
-        }, data);
-      };
-      XhrRequest.prototype.reject = function (data) {
-        monadish_1.Stream.of.apply(monadish_1.Stream, this.catchFuncs).reduce(function (inputVal, catchFunc) {
-          return catchFunc(inputVal);
-        }, data);
-      };
-      XhrRequest.prototype.catch = function (func) {
-        //this.$promise.catch(func);
-        this.catchFuncs.push(func);
-        return this;
-      };
-      XhrRequest.prototype.finally = function (func) {
-        //no ie11 support we probably are going to revert to shims for that one
-        //(<any>this.$promise).then(func).catch(func);
-        this.catchFuncs.push(func);
-        this.thenFunc.push(func);
-        return this;
-      };
-      XhrRequest.prototype.then = function (func) {
-        //this.$promise.then(func);
-        this.thenFunc.push(func);
-        return this;
-      };
-      /**
-       * attaches the internal event and processing
-       * callback within the promise to our xhr object
-       *
-       * @param resolve
-       * @param reject
-       */
-      XhrRequest.prototype.registerXhrCallbacks = function (resolve, reject) {
-        var _this = this;
-        var xhrObject = this.xhrObject;
-        xhrObject.onabort = function () {
-          _this.onAbort(resolve, reject);
-        };
-        xhrObject.ontimeout = function () {
-          _this.onTimeout(resolve, reject);
-        };
-        xhrObject.onload = function () {
-          _this.onSuccess(_this.xhrObject, resolve, reject);
-        };
-        xhrObject.onloadend = function () {
-          _this.onDone(_this.xhrObject, resolve, reject);
-        };
-        xhrObject.onerror = function (errorData) {
-          _this.onError(errorData, resolve, reject);
-        };
-      };
-      /*
-     * xhr processing callbacks
-     *
-     * Those methods are the callbacks called by
-     * the xhr object depending on its own state
-     */
-      XhrRequest.prototype.onAbort = function (resolve, reject) {
-        reject();
-      };
-      XhrRequest.prototype.onTimeout = function (resolve, reject) {
-        this.sendEvent(Const_1.STATE_EVT_TIMEOUT);
-        reject();
-      };
-      XhrRequest.prototype.onSuccess = function (data, resolve, reject) {
-        var _a, _b, _c;
-        this.sendEvent(Const_1.COMPLETE);
-        //malforms always result in empty response xml
-        if (!((_b = (_a = this) === null || _a === void 0 ? void 0 : _a.xhrObject) === null || _b === void 0 ? void 0 : _b.responseXML)) {
-          this.handleMalFormedXML(resolve);
-          return;
-        }
-        jsf.ajax.response(this.xhrObject, (_c = this.responseContext.value, (_c !== null && _c !== void 0 ? _c : {})));
-      };
-      XhrRequest.prototype.handleMalFormedXML = function (resolve) {
-        var _a;
-        this.stopProgress = true;
-        var errorData = {
-          type: Const_1.ERROR,
-          status: Const_1.MALFORMEDXML,
-          responseCode: 200,
-          responseText: (_a = this.xhrObject) === null || _a === void 0 ? void 0 : _a.responseText,
-          source: {
-            id: this.source.id.value
-          }
-        };
-        try {
-          AjaxImpl_1.Implementation.sendError(errorData);
-        }
-        finally {
-          resolve(errorData);
-        }
-        //non blocking non clearing
-      };
-      XhrRequest.prototype.onDone = function (data, resolve, reject) {
-        if (this.stopProgress) {
-          return;
-        }
-        resolve(data);
-      };
-      XhrRequest.prototype.onError = function (errorData, resolve, reject) {
-        this.handleError(errorData);
-        reject();
-      };
-      /*
-     * other helpers
-     */
-      XhrRequest.prototype.sendEvent = function (evtType) {
-        var eventData = EventData_1.EventData.createFromRequest(this.xhrObject, this.requestContext, evtType);
-        try {
-          //user code error, we might cover
-          //this in onError but also we cannot swallow it
-          //we need to resolve the local handlers lazyly,
-          //because some frameworks might decorate them over the context in the response
-          var eventHandler = RequestDataResolver_1.resolveHandlerFunc(this.requestContext, this.responseContext, Const_1.ON_EVENT);
-          ;
-          AjaxImpl_1.Implementation.sendEvent(eventData, eventHandler);
-        }
-        catch (e) {
-          this.handleError(e);
-          throw e;
-        }
-      };
-      XhrRequest.prototype.handleError = function (exception) {
-        var errorData = ErrorData_1.ErrorData.fromClient(exception);
-        var eventHandler = RequestDataResolver_1.resolveHandlerFunc(this.requestContext, this.responseContext, Const_1.ON_ERROR);
-        AjaxImpl_1.Implementation.sendError(errorData, eventHandler);
-      };
-      XhrRequest.prototype.sendRequest = function (formData) {
-        var isPost = this.ajaxType != Const_1.REQ_TYPE_GET;
-        if (formData.isMultipartRequest) {
-          this.xhrObject.send((isPost) ? formData.toFormData() : null);
-        }
-        else {
-          this.xhrObject.send((isPost) ? formData.toString() : null);
-        }
-      };
-      return XhrRequest;
-    }());
-    exports.XhrRequest = XhrRequest;
-
-
-    /***/ })
-
-  /******/ })));
-//# sourceMappingURL=jsf-development.js.map
-//# sourceMappingURL=jsf-development.js.map.jsf?ln=scripts
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/npm/package.json b/tobago-theme/tobago-theme-standard/src/main/npm/package.json
index 8797af8..ca6d0b0 100644
--- a/tobago-theme/tobago-theme-standard/src/main/npm/package.json
+++ b/tobago-theme/tobago-theme-standard/src/main/npm/package.json
@@ -26,7 +26,7 @@
     "ts": "npm-run-all --parallel ts-lint ts-compile --sequential rollup",
     "ts-lint": "tslint --project tsconfig.json --config tslint.json",
     "ts-compile": "tsc",
-    "js-minify": "uglifyjs --compress typeofs=false,drop_console=true --mangle --source-map includeSources --output js/tobago.min.js js/tobago-myfaces.js js/tobago-deltaspike.js js/tobago-polyfill.js js/tobago-listener.js js/tobago-core.js js/tobago-dropdown.js js/tobago-date.js js/tobago-command.js js/tobago-file.js js/tobago-focus.js js/tobago-header-footer.js js/tobago-in.js js/tobago-jsf.js js/tobago-overlay.js js/tobago-panel.js js/tobago-popover.js js/tobago-popup.js js/tobago-reload.js js/tobago-scroll.js js/tobago-select-boolean-checkbox.js js/tobago-select-boolean-toggle.js js/tobago-select-many-checkbox.js js/tobago-select-many-shuttle.js js/tobago-select-one-listbox.js js/tobago-select-one-radio.js js/tobago-sheet.js js/tobago-split-layout.js js/tobago-stars.js js/tobago-suggest.js js/tobago-tab.js js/tobago-tree.js js/tobago-tree-listbox.js js/tobago-utils.js",
+    "js-minify": "uglifyjs --compress typeofs=false,drop_console=true --mangle --source-map includeSources --output js/tobago.min.js js/tobago-deltaspike.js js/tobago-polyfill.js js/tobago-listener.js js/tobago-core.js js/tobago-dropdown.js js/tobago-date.js js/tobago-command.js js/tobago-file.js js/tobago-focus.js js/tobago-header-footer.js js/tobago-in.js js/tobago-jsf.js js/tobago-overlay.js js/tobago-panel.js js/tobago-popover.js js/tobago-popup.js js/tobago-reload.js js/tobago-scroll.js js/tobago-select-boolean-checkbox.js js/tobago-select-boolean-toggle.js js/tobago-select-many-checkbox.js js/tobago-select-many-shuttle.js js/tobago-select-one-listbox.js js/tobago-select-one-radio.js js/tobago-sheet.js js/tobago-split-layout.js js/tobago-stars.js js/tobago-suggest.js js/tobago-tab.js js/tobago-tree.js js/tobago-tree-listbox.js js/tobago-utils.js",
     "rollup": "rollup --config",
     "test": "jest"
   },
diff --git a/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml b/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml
index 8a11449..b385a05 100644
--- a/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml
+++ b/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml
@@ -43,6 +43,7 @@
           <script name="/webjars/tether/1.4.0/js/tether.min.js"/>
           <script name="/webjars/popper.js/1.14.3/umd/popper.min.js"/>
           <script name="/webjars/momentjs/2.24.0/min/moment-with-locales.min.js"/>
+          <script name="/tobago/standard/tobago-bootstrap/${project.version}/js/jsf.js"/>
 <!--          <script name="/tobago/standard/tobago-bootstrap/${project.version}/node_modules/@babel/polyfill/dist/polyfill.js"/>-->
           <script name="/tobago/standard/tobago-bootstrap/${project.version}/js/tobago-polyfill.js"/>
           <script name="/tobago/standard/tobago-bootstrap/${project.version}/js/tobago.min.js"/>
@@ -58,7 +59,7 @@
           <script name="/webjars/tether/1.4.0/js/tether.js"/>
           <script name="/webjars/popper.js/1.14.3/umd/popper.js"/>
           <script name="/webjars/momentjs/2.24.0/min/moment-with-locales.js"/>
-          <script name="/tobago/standard/tobago-bootstrap/${project.version}/js/tobago-myfaces.js"/>
+          <script name="/tobago/standard/tobago-bootstrap/${project.version}/js/jsf-development.js"/>
           <script name="/tobago/standard/tobago-bootstrap/${project.version}/js/tobago-deltaspike.js"/>
 <!--          <script name="/tobago/standard/tobago-bootstrap/${project.version}/node_modules/@babel/polyfill/dist/polyfill.js"/>-->
           <script name="/tobago/standard/tobago-bootstrap/${project.version}/js/tobago-polyfill.js"/>
