diff --git a/bin/build.sh b/bin/build.sh index db04690c..82a078e2 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -3,5 +3,4 @@ cd "${0%/*}" && \ cd .. && \ docker compose run --rm \ --u "$(id -u):$(id -g)" \ -annex bash -c "yarn install; gulp --color build" +annex bash -c 'yarn run build' diff --git a/bin/create.sh b/bin/create.sh new file mode 100755 index 00000000..c2187c5f --- /dev/null +++ b/bin/create.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +cd "${0%/*}" && \ +cd .. && \ +docker compose build --no-cache diff --git a/bin/documentation.sh b/bin/documentation.sh index 6d1acd8e..a767fd8c 100755 --- a/bin/documentation.sh +++ b/bin/documentation.sh @@ -3,5 +3,4 @@ cd "${0%/*}" && \ cd .. && \ docker compose run --rm \ --u "$(id -u):$(id -g)" \ -annex bash -c "yarn install; gulp --color documentation" +annex bash -c 'yarn run documentation' diff --git a/bin/install.sh b/bin/install.sh new file mode 100755 index 00000000..6f3b507a --- /dev/null +++ b/bin/install.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +cd "${0%/*}" && \ +cd .. && \ +docker compose run --rm \ +annex bash -c 'yarn install' diff --git a/bin/test.sh b/bin/test.sh index b333176d..b1cd2420 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -3,5 +3,4 @@ cd "${0%/*}" && \ cd .. && \ docker compose run --rm \ --u "$(id -u):$(id -g)" \ annex bash -c "yarn install; gulp --color test $1" diff --git a/dist/animation.js b/dist/animation.js index bb35dedc..e08f395c 100644 --- a/dist/animation.js +++ b/dist/animation.js @@ -1,5 +1,5 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Animation diff --git a/dist/animation.js.map b/dist/animation.js.map index b9504523..13fb6b34 100644 --- a/dist/animation.js.map +++ b/dist/animation.js.map @@ -1 +1 @@ -{"version":3,"file":"animation.js","names":["MODULE_NAME","hasValue","isPlainObject","isEmpty","isNaN","isElement","orDefault","assert","Deferred","warn","pschedule","countermand","waitForRepaint","applyStyles","RUNNING_TRANSITIONS","WeakMap","EasingFunctions","linear","t","easeInQuad","easeOutQuad","easeInOutQuad","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","transition","element","classChanges","styleChanges","rejectOnInterruption","__methodName__","deferred","runningTransition","get","timer","error","Error","reject","resolve","delete","transitionDurationProperties","transitionProperties","timingProperties","transitionDefinition","property","value","vendorPropertiesAdded","forEach","properties","transitionValue","remove","concat","removeClass","split","classList","trim","add","addClass","elementStyles","getComputedStyle","timingProperty","sTimings","match","msTimings","longestTiming","timing","parseFloat","Math","floor","parseInt","set"],"sources":["animation.js"],"mappings":"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","sourcesContent":["/*!\n * Module Animation\n */\n\n/**\n * @namespace Animation\n */\n\nconst MODULE_NAME = 'Animation';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {hasValue, isPlainObject, isEmpty, isNaN, isElement, orDefault, assert, Deferred} from './basic.js';\nimport {warn} from './logging.js';\nimport {pschedule, countermand, waitForRepaint} from './timers.js';\nimport {applyStyles} from './css.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst RUNNING_TRANSITIONS = new WeakMap();\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Animation:EasingFunctions\n */\n\n/**\n * A collection of all basic easing functions to be used in animations.\n * All functions here take a float parameter between 0 and 1 and return a mapped value between 0 and 1.\n *\n * Taken from: https://gist.github.com/gre/1650294\n *\n * Available functions:\n * - linear\n * - easeInQuad\n * - easeOutQuad\n * - easeInOutQuad\n * - easeInCubic\n * - easeOutCubic\n * - easeInOutCubic\n * - easeInQuart\n * - easeOutQuart\n * - easeInOutQuart\n * - easeInQuint\n * - easeOutQuint\n * - easeInOutQuint\n *\n * @memberof Animation:EasingFunctions\n * @alias EasingFunctions\n * @example\n * scrollTo(window, 1000, 0, EasingFunctions.easeInOutQuint);\n */\nexport const EasingFunctions = {\n\t// no easing, no acceleration\n\tlinear : t => t,\n\t// accelerating from zero velocity\n\teaseInQuad : t => t*t,\n\t// decelerating to zero velocity\n\teaseOutQuad : t => t*(2-t),\n\t// acceleration until halfway, then deceleration\n\teaseInOutQuad : t => t<.5 ? 2*t*t : -1+(4-2*t)*t,\n\t// accelerating from zero velocity\n\teaseInCubic : t => t*t*t,\n\t// decelerating to zero velocity\n\teaseOutCubic : t => (--t)*t*t+1,\n\t// acceleration until halfway, then deceleration\n\teaseInOutCubic : t => t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1,\n\t// accelerating from zero velocity\n\teaseInQuart : t => t*t*t*t,\n\t// decelerating to zero velocity\n\teaseOutQuart : t => 1-(--t)*t*t*t,\n\t// acceleration until halfway, then deceleration\n\teaseInOutQuart : t => t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t,\n\t// accelerating from zero velocity\n\teaseInQuint : t => t*t*t*t*t,\n\t// decelerating to zero velocity\n\teaseOutQuint : t => 1+(--t)*t*t*t*t,\n\t// acceleration until halfway, then deceleration\n\teaseInOutQuint : t => t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t\n};\n\n\n\n/**\n * @namespace Animation:transition\n */\n\n/**\n * This method offers the possibility to apply CSS transitions via classes and/or styles and wait for the transition\n * to finish, which results in the resolution of a Deferred.\n *\n * In general, this method remedies the pain of having to manage transitions manually in JS, entering precise ms for\n * timers waiting on conclusion of transitions.\n *\n * The general principle of this is the parsing of transition CSS attributes, which may contain transition\n * timings (transition and transition-duration) and looks for the longest currently running transition.\n * Values are excepted as milliseconds or seconds (int or float notation).\n *\n * Why would you do this, if there is something like the `animationend` event, you ask? Well, the problem is, that,\n * if the animation is interrupted or never finishes for any other reason, the event never fires. For that, there is\n * the `animationcancel` event, but that is not really robustly supported at the moment. So, in cases of complex\n * style changes, where we definitively want to have a callback when the animation has been (or would have been)\n * finished, this is still the safer option. But, for simple and small cases I'd strongly recommend using the native\n * `AnimationEvent` API.\n *\n * Calling this method successively on the same element replaces the currently running transition, normally\n * resulting in premature resolution of the Deferred and application of the newly provided changes.\n *\n * Be advised, that legacy browsers like IE11 and Edge <= 18 have problems connecting interrupted transitions,\n * especially when transition-durations change during animation, resulting in skipped or choppy animations. If you\n * experience this, try to keep timings stable during animation and chain animations without overlap.\n *\n * @param {Element} element - the element to transition, by applying class and/or style changes\n * @param {?Object} [classChanges=null] - plain object containing class changes to apply, add classes via the \"add\" key, remove them via the \"remove\" key (add has precedence over remove); values may be standard CSS class string notation or an array of standard CSS class notations\n * @param {?Object} [styleChanges=null] - plain object containing style changes to apply (via applyStyles)\n * @param {?Boolean} [rejectOnInterruption=false] - if a new transition is applied using this function while a previous transition is still running the Deferred would normally be resolved before continuing, set this to true to let the Deferred reject in that case (the rejection message is \"interrupted\", access the element using \"element)\n * @return {Basic.Deferred} resolves on transition completion or repeated call on the same element, with the resolution value being the element, rejects on repeated call on same element if rejectOnInterruption is true (the rejection message is \"interrupted\", access the element using \"element\")\n *\n * @memberof Animation:transition\n * @alias transition\n * @see applyStyles\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/animationend_event\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/animationcancel_event\n * @example\n * transition(element, {add : 'foobar'}).then(element => { return transition(element, {remove : 'foobar'}); }).then(() => { console.log('finished'); });\n * transition(element, null, {top : 0, left : 0, background : 'pink', transition : 'all 1500ms'}).then(() => { console.log('finished'); });\n * transition(element, {add : 'foobar'}).then(() => { console.log('finished'); }).catch(error => { console.log('cancelled'); });\n */\nexport function transition(element, classChanges=null, styleChanges=null, rejectOnInterruption=false){\n\tconst __methodName__ = 'cssTransition';\n\n\tclassChanges = orDefault(classChanges, {});\n\tstyleChanges = orDefault(styleChanges, {});\n\trejectOnInterruption = orDefault(rejectOnInterruption, false, 'bool');\n\n\tassert(isElement(element), `${MODULE_NAME}:${__methodName__} | element is not usable`);\n\tassert(isPlainObject(classChanges), `${MODULE_NAME}:${__methodName__} | classChanges is not a plain object`);\n\tassert(isPlainObject(styleChanges), `${MODULE_NAME}:${__methodName__} | styleChanges is not a plain object`);\n\n\tconst\n\t\tdeferred = new Deferred(),\n\t\trunningTransition = RUNNING_TRANSITIONS.get(element)\n\t;\n\n\tif( hasValue(runningTransition) ){\n\t\tcountermand(runningTransition.timer);\n\t\tif( !rejectOnInterruption ){\n\t\t\trunningTransition.deferred.resolve(element);\n\t\t} else {\n\t\t\tconst error = new Error('interrupted');\n\t\t\terror.element = element;\n\t\t\trunningTransition.deferred.reject(error);\n\t\t}\n\t}\n\tRUNNING_TRANSITIONS.delete(element);\n\n\tconst\n\t\ttransitionDurationProperties = [\n\t\t\t'transition-duration',\n\t\t\t'-webkit-transition-duration',\n\t\t\t'-moz-transition-duration',\n\t\t\t'-o-transition-duration'\n\t\t],\n\t\ttransitionProperties = [\n\t\t\t'transition',\n\t\t\t'-webkit-transition',\n\t\t\t'-moz-transition',\n\t\t\t'-o-transition'\n\t\t],\n\t\ttimingProperties = [\n\t\t\t...transitionDurationProperties,\n\t\t\t...transitionProperties\n\t\t],\n\t\ttransitionDefinition = {\n\t\t\tproperty : null,\n\t\t\tvalue : null\n\t\t}\n\t;\n\n\tif( !isEmpty(styleChanges) ){\n\t\tlet vendorPropertiesAdded;\n\t\t[transitionDurationProperties, transitionProperties].forEach(properties => {\n\t\t\tvendorPropertiesAdded = false;\n\t\t\tproperties.forEach(property => {\n\t\t\t\tconst transitionValue = styleChanges[property];\n\t\t\t\tif( !vendorPropertiesAdded && hasValue(transitionValue) ){\n\t\t\t\t\tvendorPropertiesAdded = true;\n\t\t\t\t\tproperties.forEach(property => {\n\t\t\t\t\t\tstyleChanges[property] = transitionValue;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tapplyStyles(element, styleChanges);\n\t}\n\n\tif( !isEmpty(classChanges?.remove) ){\n\t\t[].concat(classChanges.remove).forEach(removeClass => {\n\t\t\t`${removeClass}`.split(' ').forEach(removeClass => {\n\t\t\t\telement.classList.remove(removeClass.trim());\n\t\t\t});\n\t\t});\n\t}\n\n\tif( !isEmpty(classChanges?.add) ){\n\t\t[].concat(classChanges.add).forEach(addClass => {\n\t\t\t`${addClass}`.split(' ').forEach(addClass => {\n\t\t\t\telement.classList.add(addClass.trim());\n\t\t\t});\n\t\t});\n\t}\n\n\twaitForRepaint(() => {\n\t\tconst elementStyles = getComputedStyle(element);\n\t\ttimingProperties.forEach(timingProperty => {\n\t\t\tif( !hasValue(transitionDefinition.value) && hasValue(elementStyles[timingProperty]) ){\n\t\t\t\ttransitionDefinition.property = timingProperty;\n\t\t\t\ttransitionDefinition.value = elementStyles[timingProperty];\n\t\t\t}\n\t\t});\n\n\t\tif( !hasValue(transitionDefinition.value) ){\n\t\t\twarn(`${MODULE_NAME}:${__methodName__} | no usable transitions on element \"${element}\"`);\n\t\t\tdeferred.resolve(element);\n\t\t} else {\n\t\t\tconst\n\t\t\t\tsTimings = transitionDefinition.value.match(/(^|\\s)(\\d+(\\.\\d+)?)s(\\s|,|$)/g),\n\t\t\t\tmsTimings = transitionDefinition.value.match(/(^|\\s)(\\d+)ms(\\s|,|$)/g)\n\t\t\t;\n\t\t\tlet\tlongestTiming = 0;\n\n\t\t\t(sTimings ?? []).forEach(timing => {\n\t\t\t\ttiming = parseFloat(timing);\n\n\t\t\t\tif( !isNaN(timing) ){\n\t\t\t\t\ttiming = Math.floor(timing * 1000);\n\n\t\t\t\t\tif( timing > longestTiming ){\n\t\t\t\t\t\tlongestTiming = timing;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t(msTimings ?? []).forEach(timing => {\n\t\t\t\ttiming = parseInt(timing, 10);\n\n\t\t\t\tif( !isNaN(timing) && (timing > longestTiming) ){\n\t\t\t\t\tlongestTiming = timing;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tRUNNING_TRANSITIONS.set(element, {\n\t\t\t\tdeferred,\n\t\t\t\ttimer : pschedule(longestTiming, () => {\n\t\t\t\t\twaitForRepaint(() => {\n\t\t\t\t\t\tdeferred.resolve(element);\n\t\t\t\t\t\tRUNNING_TRANSITIONS.delete(element);\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t});\n\t\t}\n\t});\n\n\treturn deferred;\n}\n"]} \ No newline at end of file +{"version":3,"file":"animation.js","names":["MODULE_NAME","hasValue","isPlainObject","isEmpty","isNaN","isElement","orDefault","assert","Deferred","warn","pschedule","countermand","waitForRepaint","applyStyles","RUNNING_TRANSITIONS","WeakMap","EasingFunctions","linear","t","easeInQuad","easeOutQuad","easeInOutQuad","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","transition","element","classChanges","styleChanges","rejectOnInterruption","__methodName__","deferred","runningTransition","get","timer","error","Error","reject","resolve","delete","transitionDurationProperties","transitionProperties","timingProperties","transitionDefinition","property","value","vendorPropertiesAdded","forEach","properties","transitionValue","remove","concat","removeClass","split","classList","trim","add","addClass","elementStyles","getComputedStyle","timingProperty","sTimings","match","msTimings","longestTiming","timing","parseFloat","Math","floor","parseInt","set"],"sources":["animation.js"],"mappings":"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","ignoreList":[],"sourcesContent":["/*!\n * Module Animation\n */\n\n/**\n * @namespace Animation\n */\n\nconst MODULE_NAME = 'Animation';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {hasValue, isPlainObject, isEmpty, isNaN, isElement, orDefault, assert, Deferred} from './basic.js';\nimport {warn} from './logging.js';\nimport {pschedule, countermand, waitForRepaint} from './timers.js';\nimport {applyStyles} from './css.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst RUNNING_TRANSITIONS = new WeakMap();\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Animation:EasingFunctions\n */\n\n/**\n * A collection of all basic easing functions to be used in animations.\n * All functions here take a float parameter between 0 and 1 and return a mapped value between 0 and 1.\n *\n * Taken from: https://gist.github.com/gre/1650294\n *\n * Available functions:\n * - linear\n * - easeInQuad\n * - easeOutQuad\n * - easeInOutQuad\n * - easeInCubic\n * - easeOutCubic\n * - easeInOutCubic\n * - easeInQuart\n * - easeOutQuart\n * - easeInOutQuart\n * - easeInQuint\n * - easeOutQuint\n * - easeInOutQuint\n *\n * @memberof Animation:EasingFunctions\n * @alias EasingFunctions\n * @example\n * scrollTo(window, 1000, 0, EasingFunctions.easeInOutQuint);\n */\nexport const EasingFunctions = {\n\t// no easing, no acceleration\n\tlinear : t => t,\n\t// accelerating from zero velocity\n\teaseInQuad : t => t*t,\n\t// decelerating to zero velocity\n\teaseOutQuad : t => t*(2-t),\n\t// acceleration until halfway, then deceleration\n\teaseInOutQuad : t => t<.5 ? 2*t*t : -1+(4-2*t)*t,\n\t// accelerating from zero velocity\n\teaseInCubic : t => t*t*t,\n\t// decelerating to zero velocity\n\teaseOutCubic : t => (--t)*t*t+1,\n\t// acceleration until halfway, then deceleration\n\teaseInOutCubic : t => t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1,\n\t// accelerating from zero velocity\n\teaseInQuart : t => t*t*t*t,\n\t// decelerating to zero velocity\n\teaseOutQuart : t => 1-(--t)*t*t*t,\n\t// acceleration until halfway, then deceleration\n\teaseInOutQuart : t => t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t,\n\t// accelerating from zero velocity\n\teaseInQuint : t => t*t*t*t*t,\n\t// decelerating to zero velocity\n\teaseOutQuint : t => 1+(--t)*t*t*t*t,\n\t// acceleration until halfway, then deceleration\n\teaseInOutQuint : t => t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t\n};\n\n\n\n/**\n * @namespace Animation:transition\n */\n\n/**\n * This method offers the possibility to apply CSS transitions via classes and/or styles and wait for the transition\n * to finish, which results in the resolution of a Deferred.\n *\n * In general, this method remedies the pain of having to manage transitions manually in JS, entering precise ms for\n * timers waiting on conclusion of transitions.\n *\n * The general principle of this is the parsing of transition CSS attributes, which may contain transition\n * timings (transition and transition-duration) and looks for the longest currently running transition.\n * Values are excepted as milliseconds or seconds (int or float notation).\n *\n * Why would you do this, if there is something like the `animationend` event, you ask? Well, the problem is, that,\n * if the animation is interrupted or never finishes for any other reason, the event never fires. For that, there is\n * the `animationcancel` event, but that is not really robustly supported at the moment. So, in cases of complex\n * style changes, where we definitively want to have a callback when the animation has been (or would have been)\n * finished, this is still the safer option. But, for simple and small cases I'd strongly recommend using the native\n * `AnimationEvent` API.\n *\n * Calling this method successively on the same element replaces the currently running transition, normally\n * resulting in premature resolution of the Deferred and application of the newly provided changes.\n *\n * Be advised, that legacy browsers like IE11 and Edge <= 18 have problems connecting interrupted transitions,\n * especially when transition-durations change during animation, resulting in skipped or choppy animations. If you\n * experience this, try to keep timings stable during animation and chain animations without overlap.\n *\n * @param {Element} element - the element to transition, by applying class and/or style changes\n * @param {?Object} [classChanges=null] - plain object containing class changes to apply, add classes via the \"add\" key, remove them via the \"remove\" key (add has precedence over remove); values may be standard CSS class string notation or an array of standard CSS class notations\n * @param {?Object} [styleChanges=null] - plain object containing style changes to apply (via applyStyles)\n * @param {?Boolean} [rejectOnInterruption=false] - if a new transition is applied using this function while a previous transition is still running the Deferred would normally be resolved before continuing, set this to true to let the Deferred reject in that case (the rejection message is \"interrupted\", access the element using \"element)\n * @return {Basic.Deferred} resolves on transition completion or repeated call on the same element, with the resolution value being the element, rejects on repeated call on same element if rejectOnInterruption is true (the rejection message is \"interrupted\", access the element using \"element\")\n *\n * @memberof Animation:transition\n * @alias transition\n * @see applyStyles\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/animationend_event\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/animationcancel_event\n * @example\n * transition(element, {add : 'foobar'}).then(element => { return transition(element, {remove : 'foobar'}); }).then(() => { console.log('finished'); });\n * transition(element, null, {top : 0, left : 0, background : 'pink', transition : 'all 1500ms'}).then(() => { console.log('finished'); });\n * transition(element, {add : 'foobar'}).then(() => { console.log('finished'); }).catch(error => { console.log('cancelled'); });\n */\nexport function transition(element, classChanges=null, styleChanges=null, rejectOnInterruption=false){\n\tconst __methodName__ = 'cssTransition';\n\n\tclassChanges = orDefault(classChanges, {});\n\tstyleChanges = orDefault(styleChanges, {});\n\trejectOnInterruption = orDefault(rejectOnInterruption, false, 'bool');\n\n\tassert(isElement(element), `${MODULE_NAME}:${__methodName__} | element is not usable`);\n\tassert(isPlainObject(classChanges), `${MODULE_NAME}:${__methodName__} | classChanges is not a plain object`);\n\tassert(isPlainObject(styleChanges), `${MODULE_NAME}:${__methodName__} | styleChanges is not a plain object`);\n\n\tconst\n\t\tdeferred = new Deferred(),\n\t\trunningTransition = RUNNING_TRANSITIONS.get(element)\n\t;\n\n\tif( hasValue(runningTransition) ){\n\t\tcountermand(runningTransition.timer);\n\t\tif( !rejectOnInterruption ){\n\t\t\trunningTransition.deferred.resolve(element);\n\t\t} else {\n\t\t\tconst error = new Error('interrupted');\n\t\t\terror.element = element;\n\t\t\trunningTransition.deferred.reject(error);\n\t\t}\n\t}\n\tRUNNING_TRANSITIONS.delete(element);\n\n\tconst\n\t\ttransitionDurationProperties = [\n\t\t\t'transition-duration',\n\t\t\t'-webkit-transition-duration',\n\t\t\t'-moz-transition-duration',\n\t\t\t'-o-transition-duration'\n\t\t],\n\t\ttransitionProperties = [\n\t\t\t'transition',\n\t\t\t'-webkit-transition',\n\t\t\t'-moz-transition',\n\t\t\t'-o-transition'\n\t\t],\n\t\ttimingProperties = [\n\t\t\t...transitionDurationProperties,\n\t\t\t...transitionProperties\n\t\t],\n\t\ttransitionDefinition = {\n\t\t\tproperty : null,\n\t\t\tvalue : null\n\t\t}\n\t;\n\n\tif( !isEmpty(styleChanges) ){\n\t\tlet vendorPropertiesAdded;\n\t\t[transitionDurationProperties, transitionProperties].forEach(properties => {\n\t\t\tvendorPropertiesAdded = false;\n\t\t\tproperties.forEach(property => {\n\t\t\t\tconst transitionValue = styleChanges[property];\n\t\t\t\tif( !vendorPropertiesAdded && hasValue(transitionValue) ){\n\t\t\t\t\tvendorPropertiesAdded = true;\n\t\t\t\t\tproperties.forEach(property => {\n\t\t\t\t\t\tstyleChanges[property] = transitionValue;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tapplyStyles(element, styleChanges);\n\t}\n\n\tif( !isEmpty(classChanges?.remove) ){\n\t\t[].concat(classChanges.remove).forEach(removeClass => {\n\t\t\t`${removeClass}`.split(' ').forEach(removeClass => {\n\t\t\t\telement.classList.remove(removeClass.trim());\n\t\t\t});\n\t\t});\n\t}\n\n\tif( !isEmpty(classChanges?.add) ){\n\t\t[].concat(classChanges.add).forEach(addClass => {\n\t\t\t`${addClass}`.split(' ').forEach(addClass => {\n\t\t\t\telement.classList.add(addClass.trim());\n\t\t\t});\n\t\t});\n\t}\n\n\twaitForRepaint(() => {\n\t\tconst elementStyles = getComputedStyle(element);\n\t\ttimingProperties.forEach(timingProperty => {\n\t\t\tif( !hasValue(transitionDefinition.value) && hasValue(elementStyles[timingProperty]) ){\n\t\t\t\ttransitionDefinition.property = timingProperty;\n\t\t\t\ttransitionDefinition.value = elementStyles[timingProperty];\n\t\t\t}\n\t\t});\n\n\t\tif( !hasValue(transitionDefinition.value) ){\n\t\t\twarn(`${MODULE_NAME}:${__methodName__} | no usable transitions on element \"${element}\"`);\n\t\t\tdeferred.resolve(element);\n\t\t} else {\n\t\t\tconst\n\t\t\t\tsTimings = transitionDefinition.value.match(/(^|\\s)(\\d+(\\.\\d+)?)s(\\s|,|$)/g),\n\t\t\t\tmsTimings = transitionDefinition.value.match(/(^|\\s)(\\d+)ms(\\s|,|$)/g)\n\t\t\t;\n\t\t\tlet\tlongestTiming = 0;\n\n\t\t\t(sTimings ?? []).forEach(timing => {\n\t\t\t\ttiming = parseFloat(timing);\n\n\t\t\t\tif( !isNaN(timing) ){\n\t\t\t\t\ttiming = Math.floor(timing * 1000);\n\n\t\t\t\t\tif( timing > longestTiming ){\n\t\t\t\t\t\tlongestTiming = timing;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t(msTimings ?? []).forEach(timing => {\n\t\t\t\ttiming = parseInt(timing, 10);\n\n\t\t\t\tif( !isNaN(timing) && (timing > longestTiming) ){\n\t\t\t\t\tlongestTiming = timing;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tRUNNING_TRANSITIONS.set(element, {\n\t\t\t\tdeferred,\n\t\t\t\ttimer : pschedule(longestTiming, () => {\n\t\t\t\t\twaitForRepaint(() => {\n\t\t\t\t\t\tdeferred.resolve(element);\n\t\t\t\t\t\tRUNNING_TRANSITIONS.delete(element);\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t});\n\t\t}\n\t});\n\n\treturn deferred;\n}\n"]} \ No newline at end of file diff --git a/dist/arrays.js b/dist/arrays.js index 48c3aba2..e89b6f91 100644 --- a/dist/arrays.js +++ b/dist/arrays.js @@ -1,5 +1,5 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Arrays diff --git a/dist/arrays.js.map b/dist/arrays.js.map index 96cfcc41..b324085d 100644 --- a/dist/arrays.js.map +++ b/dist/arrays.js.map @@ -1 +1 @@ -{"version":3,"file":"arrays.js","names":["MODULE_NAME","assert","isArray","isNumber","isString","isMap","isSet","isPlainObject","orDefault","removeFrom","target","from","to","parseInt","rest","slice","length","concat","reduce","reducedArray","item","push","fromList","Object","values","Array","generateRange","step","__methodName__","cannotBeEmptyMessage","generateChars","charCodeAt","factor","range","diff","Math","abs","current","String","fromCharCode"],"sources":["arrays.js"],"mappings":";;;AAQA,MAAMA,YAAc,gBAMZC,OAAQC,QAASC,SAAUC,SAAUC,MAAOC,MAAOC,cAAeC,cAAgB,oBA8DnF,SAASC,WAAWC,EAAQC,EAAMC,EAAG,MAK3C,GAFAX,OAAOC,QAAQQ,GAAS,0CAEpBP,SAASQ,KAAiB,IAAPC,EAAc,CACpCD,EAAOE,SAASF,EAAM,IACtBC,EAAKJ,UAAUI,EAAI,KAAM,OAGzB,MAAME,GADNJ,EAASA,EAAOK,MAAM,IACFA,OAAOH,GAAMD,GAAQ,GAAKD,EAAOM,QAGrD,OAFAN,EAAOM,OAAUL,EAAO,EAAMD,EAAOM,OAASL,EAAQA,EAE/CD,EAAOO,OAAOH,EACtB,CAAO,GAAIV,SAASO,GACnB,OAAOD,EAAOQ,QAAO,CAACC,EAAcC,KAC/B,GAAGA,MAAWT,GACjBQ,EAAaE,KAAKD,GAEZD,IACL,IACG,CACN,IAAIG,EAWJ,OATCA,EADGf,cAAcI,GACNY,OAAOC,OAAOb,GACfN,MAAMM,IAENL,MAAMK,GADLc,MAAMd,KAAKA,EAAKa,UAIhBC,MAAMd,KAAKA,GAGlBW,EAASN,OAAS,IAAc,IAAPJ,EACtBU,EAASJ,QAAO,CAACC,EAAcC,IACrCD,EAAeV,WAAWU,EAAcC,GAAM,IAE5C,IAAIV,IAEAA,EAAOQ,QAAO,CAACC,EAAcC,KAC/BA,IAAST,GACZQ,EAAaE,KAAKD,GAEZD,IACL,GAEL,CACD,QA2BO,SAASO,cAAcf,EAAMC,EAAIe,EAAK,GAC5C,MACCC,EAAiB,gBACjBC,EAAuB,kBAGlBC,GAAiB3B,SAASQ,KAAUR,SAASS,GAC/CkB,IACE3B,SAASQ,KAEbV,QADAU,EAAO,GAAGA,KACGK,OAAS,EAAI,UAAkBY,cAA2BC,KACvElB,EAAOA,EAAKoB,WAAW,IAGnB5B,SAASS,KAEbX,QADAW,EAAK,GAAGA,KACGI,OAAS,EAAI,UAAkBY,YAAyBC,KACnEjB,EAAKA,EAAGmB,WAAW,KAIrBJ,EAAOnB,UAAUmB,EAAM,EAAG,SAE1B,MACCK,EAAWpB,EAAKD,EAAQ,GAAM,EAAI,EAClCsB,EAAQ,GAGT,IACCC,EAAOC,KAAKC,IAAIxB,EAAKD,GACrB0B,EAAU1B,EAGX,KAAOuB,GAAQ,GACdD,EAAMZ,KAAKS,EAAgBQ,OAAOC,aAAaF,GAAWA,GAC1DA,GAAWV,EAAOK,EAClBE,GAAQP,EAGT,OAAOM,CACR","sourcesContent":["/*!\n * Module Arrays\n */\n\n/**\n * @namespace Arrays\n */\n\nconst MODULE_NAME = 'Arrays';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {assert, isArray, isNumber, isString, isMap, isSet, isPlainObject, orDefault} from './basic.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Arrays:removeFrom\n */\n\n/**\n * Removes Elements from an Array, where to and from are inclusive.\n * If you only provide \"from\", that exact index is removed.\n *\n * Does not modify the original.\n *\n * Keep in mind, that \"from\" should normally be smaller than \"to\" to slice from left to right. This means that the elements\n * indexed by \"from\" and \"to\" should have the right order. For example: [1,2,3,4]. Here from=-1 and to=-3 are illegal since\n * \"from\" references a later element than \"to\", but there are also viable examples where \"from\" is numerically bigger. If we\n * use from=2 and to=-1, \"from\" is numerically bigger, but references an earlier element than -1 (which is the last element),\n * which is totally okay. Just make sure \"from\" comes before \"to\" in the element's order.\n *\n * If you provide a string for \"from\" everything matching that string with its string representation will be removed\n * (you can provide stringification for objects via the toString method, see:\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString).\n *\n * Everything else (except collections) provided for \"from\" will determine the element(s) to remove by identity (===).\n *\n * If you want to remove several elements at once, you may provide an iterable collection as \"from\" and\n * This also makes it possible to actually remove numbers from an array by identity: define the number(s) as an array,\n * to signal, that these are no indices. If you need to remove a collection from the array by reference, either put\n * the collection in an array or set \"to\" to true, to force the collection being treated as a reference.\n *\n * Iterable collections, usable in \"from\" in the sense of this method are:\n * - PlainObject (values)\n * - Array\n * - Set\n * - Map (values)\n * To remove these by reference from target, instead of iterating them, set \"to\" to true.\n *\n * @param {Array} target - the array to remove elements from\n * @param {*} from - numerical index to start removing from (can also be negative to start counting from back), a string to identify elements to remove by their string representation or any other value identifying elements to remove by identity, if this is an iterable collection, the collection is iterated instead of being treated as a reference, enforce treatment as a reference, by setting \"to\" to true\n * @param {?Number|Boolean} [to=null] - index to end removing (can also be negative to end counting from back), if true, \"from\" defines a given iterable collection to be removed by reference, instead of removing the contained values, with this you can remove an array from an array for example\n * @throws error if target is not an array\n * @returns {Array} new array without index/range/matches\n *\n * @memberof Arrays:removeFrom\n * @alias removeFrom\n * @example\n * removeFrom([1, 2, 3, 4, 5], 0, 2);\n * => [4, 5]\n * removeFrom([1, 2, 3, 4, 5], -3, -1);\n * => [1, 2]\n * removeFrom([{a : 'b', toString(){ return 'b'; }}, 'b', b, 1], 'b');\n * => [b, 1]\n * removeFrom([{a : 'b', toString(){ return 'b'; }}, 'b', b, 1], b);\n * => [{a : 'b', toString(){ return 'b'; }}, 'b', 1]\n * removeFrom([true, true, false, true, true], true)\n * => [false]\n * removeFrom([{a : 'b', toString(){ return 'b'; }}, 'b', b, 1, 2], ['b', b, 2]);\n * => [1]\n */\nexport function removeFrom(target, from, to=null){\n\tconst __methodName__ = 'removeFrom';\n\n\tassert(isArray(target), `${MODULE_NAME}:${__methodName__} | target is no array`);\n\n\tif( isNumber(from) && (to !== true) ){\n\t\tfrom = parseInt(from, 10);\n\t\tto = orDefault(to, null, 'int');\n\n\t\ttarget = target.slice(0);\n\t\tconst rest = target.slice((to || from) + 1 || target.length);\n\t\ttarget.length = (from < 0) ? (target.length + from) : from;\n\n\t\treturn target.concat(rest);\n\t} else if( isString(from) ){\n\t\treturn target.reduce((reducedArray, item) => {\n\t\t\tif( `${item}` !== from ){\n\t\t\t\treducedArray.push(item);\n\t\t\t}\n\t\t\treturn reducedArray;\n\t\t}, []);\n\t} else {\n\t\tlet fromList;\n\t\tif( isPlainObject(from) ){\n\t\t\tfromList = Object.values(from);\n\t\t} else if( isMap(from) ){\n\t\t\tfromList = Array.from(from.values());\n\t\t} else if( isSet(from) ){\n\t\t\tfromList = Array.from(from.values());\n\t\t} else {\n\t\t\tfromList = Array.from(from);\n\t\t}\n\n\t\tif( (fromList.length > 0) && (to !== true) ){\n\t\t\treturn fromList.reduce((reducedArray, item) => {\n\t\t\t\treducedArray = removeFrom(reducedArray, item, true);\n\t\t\t\treturn reducedArray;\n\t\t\t}, [...target]);\n\t\t} else {\n\t\t\treturn target.reduce((reducedArray, item) => {\n\t\t\t\tif( item !== from ){\n\t\t\t\t\treducedArray.push(item);\n\t\t\t\t}\n\t\t\t\treturn reducedArray;\n\t\t\t}, []);\n\t\t}\n\t}\n}\n\n\n\n/**\n * @namespace Arrays:generateRange\n */\n\n/**\n * To remove these by reference from target, instead of iterating them, set \"to\" to true.\n *\n * @param {Number|String} from - the start of the range, may also be negative, if larger than \"to\", the range is created in reverse, as a string, this can be a single character\n * @param {Number|String} to - the end of the range, may also be negative, if smaller than \"from\", the range is created in reverse, as a string, this can be a single character\n * @param {?Number} [step=null] - the (positive) step length in the range to use between individual range values, if the step length does not hit \"to\" exactly, the range will end at the last possible value before \"to\"\n * @throws error if \"from\" or \"to\" are empty strings\n * @returns {Array} new array with generated range\n *\n * @memberof Arrays:generateRange\n * @alias generateRange\n * @example\n * generateRange(0, 10, 2)\n * => [0, 2, 4, 6, 8, 10]\n * generateRange(5, -5, 3.5)\n * => [5, 1.5, -2]\n * generateRange('a', 'g, 3)\n * => ['a', 'd', 'g']\n */\nexport function generateRange(from, to, step=1){\n\tconst\n\t\t__methodName__ = 'generateRange',\n\t\tcannotBeEmptyMessage = 'cannot be empty'\n\t;\n\n\tconst generateChars = !isNumber(from) || !isNumber(to);\n\tif( generateChars ){\n\t\tif( !isNumber(from) ){\n\t\t\tfrom = `${from}`;\n\t\t\tassert((from.length > 0), `${MODULE_NAME}:${__methodName__} | \"from\" ${cannotBeEmptyMessage}`);\n\t\t\tfrom = from.charCodeAt(0);\n\t\t}\n\n\t\tif( !isNumber(to) ){\n\t\t\tto = `${to}`;\n\t\t\tassert((to.length > 0), `${MODULE_NAME}:${__methodName__} | \"to\" ${cannotBeEmptyMessage}`);\n\t\t\tto = to.charCodeAt(0);\n\t\t}\n\t}\n\n\tstep = orDefault(step, 1, 'float');\n\n\tconst\n\t\tfactor = ((to - from) < 0) ? -1 : 1,\n\t\trange = []\n\t;\n\n\tlet\n\t\tdiff = Math.abs(to - from),\n\t\tcurrent = from\n\t;\n\n\twhile( diff >= 0 ){\n\t\trange.push(generateChars ? String.fromCharCode(current) : current);\n\t\tcurrent += step * factor;\n\t\tdiff -= step;\n\t}\n\n\treturn range;\n}\n"]} \ No newline at end of file +{"version":3,"file":"arrays.js","names":["MODULE_NAME","assert","isArray","isNumber","isString","isMap","isSet","isPlainObject","orDefault","removeFrom","target","from","to","parseInt","rest","slice","length","concat","reduce","reducedArray","item","push","fromList","Object","values","Array","generateRange","step","__methodName__","cannotBeEmptyMessage","generateChars","charCodeAt","factor","range","diff","Math","abs","current","String","fromCharCode"],"sources":["arrays.js"],"mappings":";;;AAQA,MAAMA,YAAc,gBAMZC,OAAQC,QAASC,SAAUC,SAAUC,MAAOC,MAAOC,cAAeC,cAAgB,oBA8DnF,SAASC,WAAWC,EAAQC,EAAMC,EAAG,MAK3C,GAFAX,OAAOC,QAAQQ,GAAS,0CAEpBP,SAASQ,KAAiB,IAAPC,EAAc,CACpCD,EAAOE,SAASF,EAAM,IACtBC,EAAKJ,UAAUI,EAAI,KAAM,OAGzB,MAAME,GADNJ,EAASA,EAAOK,MAAM,IACFA,OAAOH,GAAMD,GAAQ,GAAKD,EAAOM,QAGrD,OAFAN,EAAOM,OAAUL,EAAO,EAAMD,EAAOM,OAASL,EAAQA,EAE/CD,EAAOO,OAAOH,EACtB,CAAO,GAAIV,SAASO,GACnB,OAAOD,EAAOQ,QAAO,CAACC,EAAcC,KAC/B,GAAGA,MAAWT,GACjBQ,EAAaE,KAAKD,GAEZD,IACL,IACG,CACN,IAAIG,EAWJ,OATCA,EADGf,cAAcI,GACNY,OAAOC,OAAOb,GACfN,MAAMM,IAENL,MAAMK,GADLc,MAAMd,KAAKA,EAAKa,UAIhBC,MAAMd,KAAKA,GAGlBW,EAASN,OAAS,IAAc,IAAPJ,EACtBU,EAASJ,QAAO,CAACC,EAAcC,IACrCD,EAAeV,WAAWU,EAAcC,GAAM,IAE5C,IAAIV,IAEAA,EAAOQ,QAAO,CAACC,EAAcC,KAC/BA,IAAST,GACZQ,EAAaE,KAAKD,GAEZD,IACL,GAEL,CACD,QA2BO,SAASO,cAAcf,EAAMC,EAAIe,EAAK,GAC5C,MACCC,EAAiB,gBACjBC,EAAuB,kBAGlBC,GAAiB3B,SAASQ,KAAUR,SAASS,GAC/CkB,IACE3B,SAASQ,KAEbV,QADAU,EAAO,GAAGA,KACGK,OAAS,EAAI,UAAkBY,cAA2BC,KACvElB,EAAOA,EAAKoB,WAAW,IAGnB5B,SAASS,KAEbX,QADAW,EAAK,GAAGA,KACGI,OAAS,EAAI,UAAkBY,YAAyBC,KACnEjB,EAAKA,EAAGmB,WAAW,KAIrBJ,EAAOnB,UAAUmB,EAAM,EAAG,SAE1B,MACCK,EAAWpB,EAAKD,EAAQ,GAAM,EAAI,EAClCsB,EAAQ,GAGT,IACCC,EAAOC,KAAKC,IAAIxB,EAAKD,GACrB0B,EAAU1B,EAGX,KAAOuB,GAAQ,GACdD,EAAMZ,KAAKS,EAAgBQ,OAAOC,aAAaF,GAAWA,GAC1DA,GAAWV,EAAOK,EAClBE,GAAQP,EAGT,OAAOM,CACR","ignoreList":[],"sourcesContent":["/*!\n * Module Arrays\n */\n\n/**\n * @namespace Arrays\n */\n\nconst MODULE_NAME = 'Arrays';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {assert, isArray, isNumber, isString, isMap, isSet, isPlainObject, orDefault} from './basic.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Arrays:removeFrom\n */\n\n/**\n * Removes Elements from an Array, where to and from are inclusive.\n * If you only provide \"from\", that exact index is removed.\n *\n * Does not modify the original.\n *\n * Keep in mind, that \"from\" should normally be smaller than \"to\" to slice from left to right. This means that the elements\n * indexed by \"from\" and \"to\" should have the right order. For example: [1,2,3,4]. Here from=-1 and to=-3 are illegal since\n * \"from\" references a later element than \"to\", but there are also viable examples where \"from\" is numerically bigger. If we\n * use from=2 and to=-1, \"from\" is numerically bigger, but references an earlier element than -1 (which is the last element),\n * which is totally okay. Just make sure \"from\" comes before \"to\" in the element's order.\n *\n * If you provide a string for \"from\" everything matching that string with its string representation will be removed\n * (you can provide stringification for objects via the toString method, see:\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString).\n *\n * Everything else (except collections) provided for \"from\" will determine the element(s) to remove by identity (===).\n *\n * If you want to remove several elements at once, you may provide an iterable collection as \"from\" and\n * This also makes it possible to actually remove numbers from an array by identity: define the number(s) as an array,\n * to signal, that these are no indices. If you need to remove a collection from the array by reference, either put\n * the collection in an array or set \"to\" to true, to force the collection being treated as a reference.\n *\n * Iterable collections, usable in \"from\" in the sense of this method are:\n * - PlainObject (values)\n * - Array\n * - Set\n * - Map (values)\n * To remove these by reference from target, instead of iterating them, set \"to\" to true.\n *\n * @param {Array} target - the array to remove elements from\n * @param {*} from - numerical index to start removing from (can also be negative to start counting from back), a string to identify elements to remove by their string representation or any other value identifying elements to remove by identity, if this is an iterable collection, the collection is iterated instead of being treated as a reference, enforce treatment as a reference, by setting \"to\" to true\n * @param {?Number|Boolean} [to=null] - index to end removing (can also be negative to end counting from back), if true, \"from\" defines a given iterable collection to be removed by reference, instead of removing the contained values, with this you can remove an array from an array for example\n * @throws error if target is not an array\n * @returns {Array} new array without index/range/matches\n *\n * @memberof Arrays:removeFrom\n * @alias removeFrom\n * @example\n * removeFrom([1, 2, 3, 4, 5], 0, 2);\n * => [4, 5]\n * removeFrom([1, 2, 3, 4, 5], -3, -1);\n * => [1, 2]\n * removeFrom([{a : 'b', toString(){ return 'b'; }}, 'b', b, 1], 'b');\n * => [b, 1]\n * removeFrom([{a : 'b', toString(){ return 'b'; }}, 'b', b, 1], b);\n * => [{a : 'b', toString(){ return 'b'; }}, 'b', 1]\n * removeFrom([true, true, false, true, true], true)\n * => [false]\n * removeFrom([{a : 'b', toString(){ return 'b'; }}, 'b', b, 1, 2], ['b', b, 2]);\n * => [1]\n */\nexport function removeFrom(target, from, to=null){\n\tconst __methodName__ = 'removeFrom';\n\n\tassert(isArray(target), `${MODULE_NAME}:${__methodName__} | target is no array`);\n\n\tif( isNumber(from) && (to !== true) ){\n\t\tfrom = parseInt(from, 10);\n\t\tto = orDefault(to, null, 'int');\n\n\t\ttarget = target.slice(0);\n\t\tconst rest = target.slice((to || from) + 1 || target.length);\n\t\ttarget.length = (from < 0) ? (target.length + from) : from;\n\n\t\treturn target.concat(rest);\n\t} else if( isString(from) ){\n\t\treturn target.reduce((reducedArray, item) => {\n\t\t\tif( `${item}` !== from ){\n\t\t\t\treducedArray.push(item);\n\t\t\t}\n\t\t\treturn reducedArray;\n\t\t}, []);\n\t} else {\n\t\tlet fromList;\n\t\tif( isPlainObject(from) ){\n\t\t\tfromList = Object.values(from);\n\t\t} else if( isMap(from) ){\n\t\t\tfromList = Array.from(from.values());\n\t\t} else if( isSet(from) ){\n\t\t\tfromList = Array.from(from.values());\n\t\t} else {\n\t\t\tfromList = Array.from(from);\n\t\t}\n\n\t\tif( (fromList.length > 0) && (to !== true) ){\n\t\t\treturn fromList.reduce((reducedArray, item) => {\n\t\t\t\treducedArray = removeFrom(reducedArray, item, true);\n\t\t\t\treturn reducedArray;\n\t\t\t}, [...target]);\n\t\t} else {\n\t\t\treturn target.reduce((reducedArray, item) => {\n\t\t\t\tif( item !== from ){\n\t\t\t\t\treducedArray.push(item);\n\t\t\t\t}\n\t\t\t\treturn reducedArray;\n\t\t\t}, []);\n\t\t}\n\t}\n}\n\n\n\n/**\n * @namespace Arrays:generateRange\n */\n\n/**\n * To remove these by reference from target, instead of iterating them, set \"to\" to true.\n *\n * @param {Number|String} from - the start of the range, may also be negative, if larger than \"to\", the range is created in reverse, as a string, this can be a single character\n * @param {Number|String} to - the end of the range, may also be negative, if smaller than \"from\", the range is created in reverse, as a string, this can be a single character\n * @param {?Number} [step=null] - the (positive) step length in the range to use between individual range values, if the step length does not hit \"to\" exactly, the range will end at the last possible value before \"to\"\n * @throws error if \"from\" or \"to\" are empty strings\n * @returns {Array} new array with generated range\n *\n * @memberof Arrays:generateRange\n * @alias generateRange\n * @example\n * generateRange(0, 10, 2)\n * => [0, 2, 4, 6, 8, 10]\n * generateRange(5, -5, 3.5)\n * => [5, 1.5, -2]\n * generateRange('a', 'g, 3)\n * => ['a', 'd', 'g']\n */\nexport function generateRange(from, to, step=1){\n\tconst\n\t\t__methodName__ = 'generateRange',\n\t\tcannotBeEmptyMessage = 'cannot be empty'\n\t;\n\n\tconst generateChars = !isNumber(from) || !isNumber(to);\n\tif( generateChars ){\n\t\tif( !isNumber(from) ){\n\t\t\tfrom = `${from}`;\n\t\t\tassert((from.length > 0), `${MODULE_NAME}:${__methodName__} | \"from\" ${cannotBeEmptyMessage}`);\n\t\t\tfrom = from.charCodeAt(0);\n\t\t}\n\n\t\tif( !isNumber(to) ){\n\t\t\tto = `${to}`;\n\t\t\tassert((to.length > 0), `${MODULE_NAME}:${__methodName__} | \"to\" ${cannotBeEmptyMessage}`);\n\t\t\tto = to.charCodeAt(0);\n\t\t}\n\t}\n\n\tstep = orDefault(step, 1, 'float');\n\n\tconst\n\t\tfactor = ((to - from) < 0) ? -1 : 1,\n\t\trange = []\n\t;\n\n\tlet\n\t\tdiff = Math.abs(to - from),\n\t\tcurrent = from\n\t;\n\n\twhile( diff >= 0 ){\n\t\trange.push(generateChars ? String.fromCharCode(current) : current);\n\t\tcurrent += step * factor;\n\t\tdiff -= step;\n\t}\n\n\treturn range;\n}\n"]} \ No newline at end of file diff --git a/dist/basic.js b/dist/basic.js index 7fff4acc..d5771320 100644 --- a/dist/basic.js +++ b/dist/basic.js @@ -1,8 +1,8 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Basic */ -const MODULE_NAME="Basic";import{log,warn}from"./logging.js";export function assert(t,e){if(!t)throw e=orDefault(e,"assert exception: assertion failed","str"),new Error(e)}export function attempt(t){assert(isFunction(t),"Basic:attempt | closure is no function");try{t()}catch(t){return!1}return!0}export function hasValue(){let t=!0;return Array.from(arguments).forEach((e=>{t&&=null!=e})),t}export function size(t,e=!0){if(isFunction(t?.values))return Array.from(t.values()).length;let r;switch(getType(t)){case"array":r=t.length;break;case"set":case"map":r=t.size;break;case"iterator":r=Array.from(t).length;break;case"string":r=e?[...t].length:t.length;break;case"object":r=Object.values(t).length;break;default:r=null}return r}export function isEmpty(){let t=!0,e=[void 0,null,"",0];return Array.from(arguments).forEach((t=>{isArray(t?.__additionalEmptyValues__)&&(e=e.concat(t.__additionalEmptyValues__))})),e=Array.from(new Set(e)),Array.from(arguments).forEach((r=>{t&&!isArray(r?.__additionalEmptyValues__)&&(t=e.includes(r),t||(t=0===size(r)))})),t}export function hasMembers(t,e,r=!1){e=orDefault(e,[],"arr"),r=orDefault(r,!1,"bool");let n=!0;return e.forEach((e=>{hasValue(t[`${e}`])||(r&&log().info(`Basic:hasMembers | missing member ${e}`),n=!1)})),n}export function orDefault(t,e,r=null,n=null){return n=hasValue(n)?[].concat(n):[],hasValue(r)?!isFunction(r)&&["str","string","int","integer","bool","boolean","float","arr","array"].includes(`${r.toLowerCase()}`)?(r=`${r}`.toLowerCase(),["str","string"].includes(r)?r=function(t){return`${t}`}:["int","integer"].includes(r)?r=function(t){return parseInt(t,10)}:["bool","boolean"].includes(r)?r=function(t){return!!t}:"float"===r?r=function(t){return parseFloat(t)}:["arr","array"].includes(r)&&(r=function(t){return[].concat(t)})):isFunction(r)||(r=function(t){return t}):r=function(t){return t},!hasValue(t)||n.includes(t)?e:r(t)}export function getType(t){if(!hasValue(t))return`${t}`.toLowerCase();const e=Object.prototype.toString.call(t).slice(8,-1).toLowerCase();return"generatorfunction"===e?"function":"document"===e?"htmldocument":"element"===e||/^html.*element$/.test(e)?"htmlelement":/^svg.*element$/.test(e)?"svgelement":/^.*iterator$/.test(e)?"iterator":e.match(/^(array|bigint|date|error|function|generator|regexp|symbol|set|weakset|map|weakmap|htmldocument|htmlcollection|nodelist|window|url|urlsearchparams)$/)?e:"object"==typeof t||"function"==typeof t?"object":typeof t}export function isA(t,e){return["undefined","null","boolean","number","bigint","string","symbol","function","object","array","date","error","generator","iterator","regexp","set","weakset","map","weakmap","htmldocument","htmlelement","svgelement","htmlcollection","nodelist","window","url","urlsearchparams"].includes(`${e}`.toLowerCase())?getType(t)===`${e}`.toLowerCase():(warn(`Basic:isA | "${e}" is not a recognized type`),!1)}export function isBoolean(t){return isA(t,"boolean")}export function isNumber(t){return isA(t,"number")}export function isBigInt(t){return isA(t,"bigint")}export function isInt(t){return parseInt(t,10)===t}export function isFloat(t){return parseFloat(t)===t}export function isNaN(t,e=!0){return(e=orDefault(e,!0,"bool"))?t!=t:isNaN(t)}export function isString(t){return isA(t,"string")}export function isSymbol(t){return isA(t,"symbol")}export function isFunction(t){return isA(t,"function")}export function isObject(t){return isA(t,"object")}export function isPlainObject(t){return isObject(t)&&hasValue(t)&&t.constructor===Object&&"[object Object]"===Object.prototype.toString.call(t)}export function isArray(t){return isA(t,"array")}export function isDate(t){return isA(t,"date")}export function isError(t){return isA(t,"error")}export function isGenerator(t){return isA(t,"generator")}export function isIterator(t){return isA(t,"iterator")}export function isRegExp(t){return isA(t,"regexp")}export function isSet(t){return isA(t,"set")}export function isWeakSet(t){return isA(t,"weakset")}export function isMap(t){return isA(t,"map")}export function isWeakMap(t){return isA(t,"weakmap")}export function isDocument(t){return isA(t,"htmldocument")}export function isElement(t){return isA(t,"htmlelement")}export function isSvg(t){return isA(t,"svgelement")}export function isCollection(t){return isA(t,"htmlcollection")}export function isNodeList(t){return isA(t,"nodelist")}export function isWindow(t){return isA(t,"window")}export function isUrl(t){return isA(t,"url")}export function isUrlSearchParams(t){return isA(t,"urlsearchparams")}export function isEventTarget(t){return hasValue(t)&&isFunction(t.addEventListener)&&isFunction(t.removeEventListener)&&isFunction(t.dispatchEvent)}export function isSelector(t){t=orDefault(t,0,"str");const e=document.createDocumentFragment();try{e.querySelector(t)}catch(t){return!1}return!0}export function isPotentialId(t,e="",r="[1-9][0-9]*",n="",o=!0){t=`${t}`,e=orDefault(e,"","str"),r=orDefault(r,"[1-9][0-9]*","str"),n=orDefault(n,"","str");const i=t=>`${t}`.replace(/([\-\[\]\/{}()*+?.\\^$|])/g,"\\$&");let s;s=(o=orDefault(o,!0,"bool"))?new RegExp(`^${i(e)}(${r})${i(n)}$`):new RegExp(`^${e}(${r})${n}$`);const u=s.exec(t);return!!hasValue(u)&&u[1]}export function min(t,e){return te?e:t}export function minMax(t,e,r){return assert(t<=r,"Basic:minMax | minValue can not be larger than maxValue"),min(max(e,r),t)}export function round(t,e=0){t=parseFloat(t),e=min(orDefault(e,0,"int"),0);const r=Math.pow(10,e);return Math.round(parseFloat(t)*r)/r}export class Deferred{constructor(){const t="fulfilled",e="rejected";this.resolve=null,this.reject=null,this.provision=null,this.status="pending",this.isSettled=()=>[t,e].includes(this.status),this.promise=new Promise(((r,n)=>{this.resolve=e=>{this.status=t,r(e)},this.reject=t=>{this.status=e,n(t)}}))}then(t){return this.promise.then(t)}catch(t){return this.promise.catch(t)}finally(t){return this.promise.finally(t)}}export class Observable{#t="Observable";#e;#r;constructor(t){this.#e=t,this.#r=[]}getValue(){return this.#e}setValue(t,e=!1){const r=this.#e,n=r!==t;this.#e=t,(n||e)&&this.#r.forEach((e=>e(t,r)))}subscribe(t){return assert(isFunction(t),`Basic:${this.#t}.subscribe | subscription must be function`),this.#r.indexOf(t)<0&&(this.#r=[...this.#r,t]),t}unsubscribe(t){this.#r=this.#r.filter((e=>e!==t))}toString(){return`${this.#e}`}} +const MODULE_NAME="Basic";import{log,warn}from"./logging.js";export function assert(t,e){if(!t)throw e=orDefault(e,"assert exception: assertion failed","str"),new Error(e)}export function attempt(t){assert(isFunction(t),`${MODULE_NAME}:attempt | closure is no function`);try{t()}catch(t){return!1}return!0}export function hasValue(){let t=!0;return Array.from(arguments).forEach((e=>{t&&=null!=e})),t}export function size(t,e=!0){if(isFunction(t?.values))return Array.from(t.values()).length;let r;switch(getType(t)){case"array":r=t.length;break;case"set":case"map":r=t.size;break;case"iterator":r=Array.from(t).length;break;case"string":r=e?[...t].length:t.length;break;case"object":r=Object.values(t).length;break;default:r=null}return r}export function isEmpty(){let t=!0,e=[void 0,null,"",0];return Array.from(arguments).forEach((t=>{isArray(t?.__additionalEmptyValues__)&&(e=e.concat(t.__additionalEmptyValues__))})),e=Array.from(new Set(e)),Array.from(arguments).forEach((r=>{t&&!isArray(r?.__additionalEmptyValues__)&&(t=e.includes(r),t||(t=0===size(r)))})),t}export function hasMembers(t,e,r=!1){e=orDefault(e,[],"arr"),r=orDefault(r,!1,"bool");let n=!0;return e.forEach((e=>{hasValue(t[`${e}`])||(r&&log().info(`${MODULE_NAME}:hasMembers | missing member ${e}`),n=!1)})),n}export function orDefault(t,e,r=null,n=null){return n=hasValue(n)?[].concat(n):[],hasValue(r)?!isFunction(r)&&["str","string","int","integer","bool","boolean","float","arr","array"].includes(`${r.toLowerCase()}`)?(r=`${r}`.toLowerCase(),["str","string"].includes(r)?r=function(t){return`${t}`}:["int","integer"].includes(r)?r=function(t){return parseInt(t,10)}:["bool","boolean"].includes(r)?r=function(t){return!!t}:"float"===r?r=function(t){return parseFloat(t)}:["arr","array"].includes(r)&&(r=function(t){return[].concat(t)})):isFunction(r)||(r=function(t){return t}):r=function(t){return t},!hasValue(t)||n.includes(t)?e:r(t)}export function getType(t){if(!hasValue(t))return`${t}`.toLowerCase();const e=Object.prototype.toString.call(t).slice(8,-1).toLowerCase();return"generatorfunction"===e?"function":"document"===e?"htmldocument":"element"===e||/^html.*element$/.test(e)?"htmlelement":/^svg.*element$/.test(e)?"svgelement":/^.*iterator$/.test(e)?"iterator":e.match(/^(array|bigint|date|error|function|generator|regexp|symbol|set|weakset|map|weakmap|htmldocument|htmlcollection|nodelist|window|url|urlsearchparams)$/)?e:"object"==typeof t||"function"==typeof t?"object":typeof t}export function isA(t,e){return["undefined","null","boolean","number","bigint","string","symbol","function","object","array","date","error","generator","iterator","regexp","set","weakset","map","weakmap","htmldocument","htmlelement","svgelement","htmlcollection","nodelist","window","url","urlsearchparams"].includes(`${e}`.toLowerCase())?getType(t)===`${e}`.toLowerCase():(warn(`${MODULE_NAME}:isA | "${e}" is not a recognized type`),!1)}export function isBoolean(t){return isA(t,"boolean")}export function isNumber(t){return isA(t,"number")}export function isBigInt(t){return isA(t,"bigint")}export function isInt(t){return parseInt(t,10)===t}export function isFloat(t){return parseFloat(t)===t}export function isNaN(t,e=!0){return(e=orDefault(e,!0,"bool"))?t!=t:isNaN(t)}export function isString(t){return isA(t,"string")}export function isSymbol(t){return isA(t,"symbol")}export function isFunction(t){return isA(t,"function")}export function isObject(t){return isA(t,"object")}export function isPlainObject(t){return isObject(t)&&hasValue(t)&&t.constructor===Object&&"[object Object]"===Object.prototype.toString.call(t)}export function isArray(t){return isA(t,"array")}export function isDate(t){return isA(t,"date")}export function isError(t){return isA(t,"error")}export function isGenerator(t){return isA(t,"generator")}export function isIterator(t){return isA(t,"iterator")}export function isRegExp(t){return isA(t,"regexp")}export function isSet(t){return isA(t,"set")}export function isWeakSet(t){return isA(t,"weakset")}export function isMap(t){return isA(t,"map")}export function isWeakMap(t){return isA(t,"weakmap")}export function isDocument(t){return isA(t,"htmldocument")}export function isElement(t){return isA(t,"htmlelement")}export function isSvg(t){return isA(t,"svgelement")}export function isCollection(t){return isA(t,"htmlcollection")}export function isNodeList(t){return isA(t,"nodelist")}export function isWindow(t){return isA(t,"window")}export function isUrl(t){return isA(t,"url")}export function isUrlSearchParams(t){return isA(t,"urlsearchparams")}export function isEventTarget(t){return hasValue(t)&&isFunction(t.addEventListener)&&isFunction(t.removeEventListener)&&isFunction(t.dispatchEvent)}export function isSelector(t){t=orDefault(t,0,"str");const e=document.createDocumentFragment();try{e.querySelector(t)}catch(t){return!1}return!0}export function isPotentialId(t,e="",r="[1-9][0-9]*",n="",o=!0){t=`${t}`,e=orDefault(e,"","str"),r=orDefault(r,"[1-9][0-9]*","str"),n=orDefault(n,"","str");const i=t=>`${t}`.replace(/([\-\[\]\/{}()*+?.\\^$|])/g,"\\$&");let s;s=(o=orDefault(o,!0,"bool"))?new RegExp(`^${i(e)}(${r})${i(n)}$`):new RegExp(`^${e}(${r})${n}$`);const u=s.exec(t);return!!hasValue(u)&&u[1]}export function min(t,e){return te?e:t}export function minMax(t,e,r){return assert(t<=r,`${MODULE_NAME}:minMax | minValue can not be larger than maxValue`),min(max(e,r),t)}export function round(t,e=0){t=parseFloat(t),e=min(orDefault(e,0,"int"),0);const r=Math.pow(10,e);return Math.round(parseFloat(t)*r)/r}export class Deferred{constructor(){const t="fulfilled",e="rejected";this.resolve=null,this.reject=null,this.provision=null,this.status="pending",this.isSettled=()=>[t,e].includes(this.status),this.promise=new Promise(((r,n)=>{this.resolve=e=>{this.status=t,r(e)},this.reject=t=>{this.status=e,n(t)}}))}then(t){return this.promise.then(t)}catch(t){return this.promise.catch(t)}finally(t){return this.promise.finally(t)}}export class Observable{#t="Observable";#e;#r;constructor(t){this.#e=t,this.#r=[]}getValue(){return this.#e}setValue(t,e=!1){const r=this.#e,n=r!==t;this.#e=t,(n||e)&&this.#r.forEach((e=>e(t,r)))}subscribe(t){return assert(isFunction(t),`${MODULE_NAME}:${this.#t}.subscribe | subscription must be function`),this.#r.indexOf(t)<0&&(this.#r=[...this.#r,t]),t}unsubscribe(t){this.#r=this.#r.filter((e=>e!==t))}toString(){return`${this.#e}`}} //# sourceMappingURL=basic.js.map diff --git a/dist/basic.js.map b/dist/basic.js.map index 8593a5b8..1401eeb0 100644 --- a/dist/basic.js.map +++ b/dist/basic.js.map @@ -1 +1 @@ -{"version":3,"file":"basic.js","names":["MODULE_NAME","log","warn","assert","condition","message","orDefault","Error","attempt","closure","isFunction","ex","hasValue","res","Array","from","arguments","forEach","value","size","target","countStringCharacters","values","length","getType","Object","isEmpty","emptyValues","undefined","obj","isArray","__additionalEmptyValues__","concat","Set","includes","hasMembers","memberNames","verbose","memberName","info","expression","defaultValue","caster","additionalEmptyValues","toLowerCase","parseInt","parseFloat","deepType","prototype","toString","call","slice","test","match","isA","type","isBoolean","isNumber","isBigInt","isInt","intVal","isFloat","floatVal","isNaN","checkForIdentity","isString","isSymbol","isObject","isPlainObject","constructor","isDate","isError","isGenerator","isIterator","isRegExp","isSet","isWeakSet","isMap","isWeakMap","isDocument","isElement","isSvg","isCollection","isNodeList","isWindow","isUrl","isUrlSearchParams","isEventTarget","addEventListener","removeEventListener","dispatchEvent","isSelector","fragment","document","createDocumentFragment","querySelector","isPotentialId","prefix","idRex","postfix","maskFixes","mask","str","replace","rex","RegExp","matches","exec","min","minValue","max","maxValue","minMax","round","number","precision","power","Math","pow","Deferred","STATUS_FULFILLED","STATUS_REJECTED","this","resolve","reject","provision","status","isSettled","promise","Promise","resolution","rejection","then","f","catch","finally","Observable","__className__","subscriptions","initialValue","getValue","setValue","newValue","force","oldValue","isNewValue","s","subscribe","subscription","indexOf","unsubscribe","filter"],"sources":["basic.js"],"mappings":"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","sourcesContent":["/*!\n * Module Basic\n */\n\n/**\n * @namespace Basic\n */\n\nconst MODULE_NAME = 'Basic';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {log, warn} from './logging.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Basic:assert\n */\n\n/**\n * Classical assert method. If condition is falsy, throw assert exception.\n *\n * @param {Boolean} condition - defines if an assertion is successful\n * @param {?String} [message='assert exception: assertion failed'] - to display if assertion fails\n * @throws assert exception\n *\n * @memberof Basic:assert\n * @alias assert\n * @example\n * function set(name, value){\n * assert(name.length > 0);\n * assert(isPlainObject(value), 'error: value must be plain object');\n * ...\n * }\n */\nexport function assert(condition, message){\n\tif( !condition ){\n\t\tmessage = orDefault(message, 'assert exception: assertion failed', 'str');\n\t\tthrow new Error(message);\n\t}\n}\n\n\n\n/**\n * @namespace Basic:attempt\n */\n\n/**\n * Attempt to compute contents of closure and catch all occurring exceptions.\n * The boolean result tells you if the operation was successful or not.\n *\n * This is most helpful, when used to test value conversions or other atomic/singluar operations, where it\n * just is important if something isolated works or not.\n *\n * Do not encapsulate complex code in the closure and mind recursively occurring exceptions!\n *\n * @param {Function} closure - the code to test\n * @throws error if closure is not a function\n * @returns {Boolean} true if no exception occurred\n *\n * @memberof Basic:attempt\n * @alias attempt\n * @example\n * if( !attempt(function(){ foobar(); }) ){ console.log('foobar cannot be executed!'); }\n */\nexport function attempt(closure){\n\tassert(isFunction(closure), `${MODULE_NAME}:attempt | closure is no function`);\n\n\ttry {\n\t\tclosure();\n\t} catch(ex){\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n\n\n/**\n * @namespace Basic:hasValue\n */\n\n/**\n * Check if variable(s) is set, by being neither undefined nor null.\n *\n * @param {...*} [...] - add any number of variables you wish to check\n * @returns {Boolean} variable(s) is/are set\n *\n * @memberof Basic:hasValue\n * @alias hasValue\n * @example\n * function set(name, value){\n * if( hasValue(name, value) ){\n * ...\n * }\n * }\n */\nexport function hasValue(){\n\tlet res = true;\n\n\tArray.from(arguments).forEach(value => {\n\t\tres &&= ((value !== undefined) && (value !== null));\n\t});\n\n\treturn res;\n}\n\n\n\n/**\n * @namespace Basic:size\n */\n\n/**\n * Determine the (value) size of a collection.\n *\n * A collection is an object with countable values:\n * - Arrays return their length\n * - Sets and Maps return their size\n * - Strings return their (character) length\n * - Iterators return the length of their value list\n * - Objects return the length of their value list\n * - any object implementing .values() returns the length of the returned value list\n *\n * @param {Object|Array|Set|Map|String|Iterable} target - a collection to determine the (value) size of\n * @param {?Boolean} [countStringCharacters=true] - if we want to determine the length of a string, we'd normally like to count actual characters, but length normally returns the technical length counting more than one for unicode chars, set this to \"false\" to use technical length instead of characters\n * @returns {Number|null} the size of the collection or null if no size could be determined\n *\n * @memberof Basic:size\n * @alias size\n * @example\n * size('日本国💩👻');\n * => 5\n * size('日本国💩👻', false);\n * => 7\n * size({a : 1, b : new Date(), c : [1, 2, 3]});\n * => 3\n * size(['test', 'test', 'test']);\n * => 3\n * size(new Set(['test1', 'test2', 'test3']));\n * => 3\n * size(new Set(['test1', 'test2', 'test3']).values());\n * => 3\n * size(new Map([[1, 1], [new Date(), new Date()], ['foo', 'bar']]));\n * => 3\n * size(new Map([[1, 1], [new Date(), new Date()], ['foo', 'bar']]).values());\n * => 3\n * size(null);\n * => null\n * size(undefined);\n * => null\n */\nexport function size(target, countStringCharacters=true){\n\tif( isFunction(target?.values) ) return Array.from(target.values()).length;\n\n\tlet res;\n\tswitch( getType(target) ){\n\t\tcase 'array':\n\t\t\tres = target.length;\n\t\tbreak;\n\n\t\tcase 'set':\n\t\tcase 'map':\n\t\t\tres = target.size;\n\t\tbreak;\n\n\t\tcase 'iterator':\n\t\t\tres = Array.from(target).length;\n\t\tbreak;\n\n\t\tcase 'string':\n\t\t\t// see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length#description\n\t\t\tres = countStringCharacters ? [...target].length : target.length;\n\t\tbreak;\n\n\t\tcase 'object':\n\t\t\tres = Object.values(target).length;\n\t\tbreak;\n\n\t\tdefault:\n\t\t\tres = null;\n\t\tbreak;\n\t}\n\n\treturn res;\n}\n\n\n\n/**\n * @namespace Basic:isEmpty\n */\n\n/**\n * Check if variable(s) contain non-empty value\n * (not undefined, null, '', 0, [], {} or an empty Set/Map).\n *\n * You can supply additional non-empty values by providing an object having the key \"__additionalEmptyValues__\" as\n * any single parameter. Multiple occurrences will be merged.\n *\n * @param {...*} [...] - add any number of variables you wish to check\n * @returns {Boolean} variable(s) is/are empty\n *\n * @memberof Basic:isEmpty\n * @alias isEmpty\n * @example\n * function set(name, value){\n * if( isEmpty(fooBar) || isEmpty({'__additionalEmptyValues__' : [false, '0']}, someArray, someSet, someString, value) ){\n * ...\n * }\n * }\n */\nexport function isEmpty(){\n\tlet\n\t\tres = true,\n\t\temptyValues = [undefined, null, '', 0]\n\t;\n\n\tArray.from(arguments).forEach(obj => {\n\t\tif( isArray(obj?.__additionalEmptyValues__) ){\n\t\t\temptyValues = emptyValues.concat(obj.__additionalEmptyValues__);\n\t\t}\n\t});\n\temptyValues = Array.from(new Set(emptyValues));\n\n\tArray.from(arguments).forEach(obj => {\n\t\tif( res && !isArray(obj?.__additionalEmptyValues__) ){\n\t\t\tres = emptyValues.includes(obj);\n\n\t\t\tif( !res ){\n\t\t\t\tres = (size(obj) === 0);\n\t\t\t}\n\t\t}\n\t});\n\n\treturn res;\n}\n\n\n\n/**\n * @namespace Basic:hasMembers\n */\n\n/**\n * \"Validates\" an object in a very basic way by checking if all given members are present and are not nullish.\n *\n * @param {Object} obj - the object to check\n * @param {String[]} memberNames - the names of the members to check\n * @param {Boolean} [verbose=false] - defines if method should output missing members to console\n * @returns {Boolean} all memberNames present and not nullish\n *\n * @memberof Basic:hasMembers\n * @alias hasMembers\n * @example\n * function pat(kitten){\n * if( hasMembers(kitten, ['fluff', 'meow', 'scratch']) ){\n * ...\n * }\n * }\n */\nexport function hasMembers(obj, memberNames, verbose=false){\n\tmemberNames = orDefault(memberNames, [], 'arr');\n\tverbose = orDefault(verbose, false, 'bool');\n\n\tlet res = true;\n\n\tmemberNames.forEach(memberName => {\n\t\tif( !hasValue(obj[`${memberName}`]) ){\n\t\t\tif( verbose ){\n\t\t\t\tlog().info(`${MODULE_NAME}:hasMembers | missing member ${memberName}`);\n\t\t\t}\n\n\t\t\tres = false;\n\t\t}\n\t});\n\n\treturn res;\n}\n\n\n\n/**\n * @namespace Basic:orDefault\n */\n\n/**\n * If an expression returns a non-value (undefined or null), use the default value instead.\n * Define a caster name, to force expression result/value into certain data type.\n *\n * @param {*} expression - the expression to evaluate\n * @param {*} defaultValue - the default value to use if the expression is considered empty\n * @param {?(String|Function)} [caster=null] - either a default caster by name ('str', 'string', 'int', 'integer', 'bool', 'boolean', 'float', 'arr', 'array') or a function getting the value and returning the transformed value\n * @param {?Array} [additionalEmptyValues=null] - if set, provides a list of additional values to be considered empty, apart from undefined and null\n * @returns {*} expression of defaultValue\n *\n * @memberof Basic:orDefault\n * @alias orDefault\n * @example\n * function set(name, value){\n * name = orDefault(name, 'kittens!', 'string', ['', 'none']);\n * value = orDefault(value, 42, 'int');\n * }\n */\nexport function orDefault(expression, defaultValue, caster=null, additionalEmptyValues=null){\n\tif( hasValue(additionalEmptyValues) ){\n\t\tadditionalEmptyValues = [].concat(additionalEmptyValues);\n\t} else {\n\t\tadditionalEmptyValues = [];\n\t}\n\n\tif( hasValue(caster) ){\n\t\tif(\n\t\t\t!isFunction(caster)\n\t\t\t&& ([\n\t\t\t\t'str', 'string',\n\t\t\t\t'int', 'integer',\n\t\t\t\t'bool', 'boolean',\n\t\t\t\t'float',\n\t\t\t\t'arr', 'array'\n\t\t\t].includes(`${caster.toLowerCase()}`))\n\t\t){\n\t\t\tcaster = `${caster}`.toLowerCase();\n\n\t\t\tif( ['str', 'string'].includes(caster) ){\n\t\t\t\tcaster = function(value){ return `${value}`; };\n\t\t\t} else if( ['int', 'integer'].includes(caster) ){\n\t\t\t\tcaster = function(value){ return parseInt(value, 10); };\n\t\t\t} else if( ['bool', 'boolean'].includes(caster) ){\n\t\t\t\tcaster = function(value){ return !!value; };\n\t\t\t} else if( caster === 'float' ){\n\t\t\t\tcaster = function(value){ return parseFloat(value); };\n\t\t\t} else if( ['arr', 'array'].includes(caster) ){\n\t\t\t\tcaster = function(value){ return [].concat(value); };\n\t\t\t}\n\t\t} else if( !isFunction(caster) ){\n\t\t\tcaster = function(value){ return value; };\n\t\t}\n\t} else {\n\t\tcaster = function(value){ return value; };\n\t}\n\n\tif( !hasValue(expression) || (additionalEmptyValues.includes(expression)) ){\n\t\treturn defaultValue;\n\t} else {\n\t\treturn caster(expression);\n\t}\n}\n\n\n\n/**\n * @namespace Basic:getType\n */\n\n/**\n * Prod-ready type detection for values, expanding on flawed typeof functionality, roughly following\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof, but expanding on\n * useful frontend types like \"htmldocument\", \"htmlelement\", \"htmlcollection\" and \"nodelist\"\n *\n * Types:\n * - \"undefined\"\n * - \"null\"\n * - \"boolean\"\n * - \"number\"\n * - \"bigint\"\n * - \"string\"\n * - \"symbol\"\n * - \"function\"\n * - \"object\"\n * - \"array\"\n * - \"date\"\n * - \"error\"\n * - \"generator\"\n * - \"iterator\"\n * - \"regexp\"\n * - \"set\"\n * - \"weakset\"\n * - \"map\"\n * - \"weakmap\"\n * - \"htmldocument\"\n * - \"htmlelement\"\n * - \"svgelement\"\n * - \"htmlcollection\"\n * - \"nodelist\"\n * - \"window\"\n * - \"url\"\n * - \"urlsearchparams\"\n *\n * @param {*} [value] - variable to check the type of\n * @returns {String} the value type in lower case\n *\n * @memberof Basic:getType\n * @alias getType\n * @example\n * if( getType(cb) === 'function' ){\n * ...\n * }\n */\nexport function getType(value) {\n\tif( !hasValue(value) ) return `${value}`.toLowerCase();\n\n\tconst deepType = Object.prototype.toString.call(value).slice(8,-1).toLowerCase();\n\n\tif( deepType === 'generatorfunction' ) return 'function';\n\tif( deepType === 'document' ) return 'htmldocument';\n\tif( deepType === 'element' ) return 'htmlelement';\n\tif( /^html.*element$/.test(deepType) ) return 'htmlelement';\n\tif( /^svg.*element$/.test(deepType) ) return 'svgelement';\n\tif( /^.*iterator$/.test(deepType) ) return 'iterator';\n\n\treturn deepType.match(/^(array|bigint|date|error|function|generator|regexp|symbol|set|weakset|map|weakmap|htmldocument|htmlcollection|nodelist|window|url|urlsearchparams)$/)\n\t\t? deepType\n\t\t: ((typeof value === 'object') || (typeof value === 'function')) ? 'object' : typeof value\n\t;\n}\n\n\n\n/**\n * @namespace Basic:isA\n */\n\n/**\n * Short form of \"getType\"-method with a more compact syntax.\n * Can identify all types listed in getType.\n *\n * @param {*} value - variable to check the type of\n * @param {String} type - the name of the type to check for, has to be a standard JS-type, is case insensitive\n * @returns {Boolean} target has type\n *\n * @memberof Basic:isA\n * @alias isA\n * @see getType\n * @example\n * let stringBool = (isA(test, 'boolean') && test) ? 'true' : 'false';\n */\nexport function isA(value, type){\n\tif(\n\t\t[\n\t\t\t'undefined',\n\t\t\t'null',\n\t\t\t'boolean',\n\t\t\t'number',\n\t\t\t'bigint',\n\t\t\t'string',\n\t\t\t'symbol',\n\t\t\t'function',\n\t\t\t'object',\n\t\t\t'array',\n\t\t\t'date',\n\t\t\t'error',\n\t\t\t'generator',\n\t\t\t'iterator',\n\t\t\t'regexp',\n\t\t\t'set',\n\t\t\t'weakset',\n\t\t\t'map',\n\t\t\t'weakmap',\n\t\t\t'htmldocument',\n\t\t\t'htmlelement',\n\t\t\t'svgelement',\n\t\t\t'htmlcollection',\n\t\t\t'nodelist',\n\t\t\t'window',\n\t\t\t'url',\n\t\t\t'urlsearchparams'\n\t\t].includes(`${type}`.toLowerCase())\n\t){\n\t\treturn getType(value) === `${type}`.toLowerCase();\n\t} else {\n\t\twarn(`${MODULE_NAME}:isA | \"${type}\" is not a recognized type`);\n\t\treturn false;\n\t}\n}\n\n\n\n/**\n * @namespace Basic:isBoolean\n */\n\n/**\n * Returns if a value is a boolean value.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a boolean\n *\n * @memberof Basic:isBoolean\n * @alias isBoolean\n * @example\n * if( isBoolean(val) ){\n * console.log('val must be either true or false');\n * }\n */\nexport function isBoolean(value){\n\treturn isA(value, 'boolean');\n}\n\n\n\n/**\n * @namespace Basic:isNumber\n */\n\n/**\n * Returns if a value is a number.\n *\n * Hint: to check numbers in more detail, use isInt, isFloat and isNaN\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a number\n *\n * @memberof Basic:isNumber\n * @alias isNumber\n * @see isInt\n * @see isFloat\n * @see isNaN\n * @example\n * if( isNumber(val) ){\n * result = val * 5;\n * }\n */\nexport function isNumber(value){\n\treturn isA(value, 'number');\n}\n\n\n\n/**\n * @namespace Basic:isBigInt\n */\n\n/**\n * Returns if a value is a BigInt value.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a BigInt\n *\n * @memberof Basic:isBigInt\n * @alias isBigInt\n * @example\n * if( isBigInt(val) ){\n * console.log('this is a really huge number!');\n * }\n */\nexport function isBigInt(value){\n\treturn isA(value, 'bigint');\n}\n\n\n\n/**\n * @namespace Basic:isInt\n */\n\n/**\n * Returns if a value is truly a real integer value and not just an int-parsable value for example.\n * Since JS only knows the data type \"number\" all numbers are usable as floats by default, but not the\n * other way round.\n *\n * @param {*} intVal - the value the check\n * @returns {Boolean} true if intVal is a true integer value\n *\n * @memberof Basic:isInt\n * @alias isInt\n * @example\n * if( !isInt(val) ){\n * val = parseInt(val, 10);\n * }\n */\nexport function isInt(intVal){\n\treturn parseInt(intVal, 10) === intVal;\n}\n\n\n\n/**\n * @namespace Basic:isFloat\n */\n\n/**\n * Returns if a value is a numeric value, usable as a float number in any calculation.\n * Any number that fulfills isInt, is also considered a valid float, which lies in JS's\n * nature of not differentiating ints and floats by putting them both into a \"number\"-type.\n * So ints are always floats, but not necessarily the other way round.\n *\n * @param {*} floatVal - the value to check\n * @returns {Boolean} true if floatVal is usable in a float context\n *\n * @memberof Basic:isFloat\n * @alias isFloat\n * @example\n * if( !isFloat(val) ){\n * alert('val can not be calculated with!');\n * }\n */\nexport function isFloat(floatVal){\n\treturn parseFloat(floatVal) === floatVal;\n}\n\n\n\n/**\n * @namespace Basic:isNaN\n */\n\n/**\n * Returns if an expression is NaN or not.\n * This method employs two different approaches:\n * By default it really checks if the expression is the _value_ NaN or not, this being a valid JS-value for something.\n * In JS this gets checked by comparing an expression with itself on identity, since NaN is the only value not being\n * identical to itself. If you set checkForIdentity to false, this method will use the standard JS-isNaN, which\n * inspects the expression, tries to cast or parse a number from it and returns the result.\n *\n * @param {*} expression - the expression to check\n * @param {Boolean} [checkForIdentity=true] - set to false if you want to use default JS-functionality\n * @returns {Boolean} true if expression is NaN\n *\n * @memberof Basic:isNaN\n * @alias isNaN\n * @example\n * if( !isNaN(suspiciousCalculatedValue) ){\n * return suspiciousCalculatedValue * 3;\n * }\n */\nexport function isNaN(expression, checkForIdentity=true){\n\tcheckForIdentity = orDefault(checkForIdentity, true, 'bool');\n\n\tif( checkForIdentity ){\n\t\treturn expression !== expression;\n\t} else {\n\t\treturn isNaN(expression);\n\t}\n}\n\n\n\n/**\n * @namespace Basic:isString\n */\n\n/**\n * Returns if a value is a string.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a string\n *\n * @memberof Basic:isString\n * @alias isString\n * @example\n * if( isString(val) ){\n * return prefix+val;\n * }\n */\nexport function isString(value){\n\treturn isA(value, 'string');\n}\n\n\n\n/**\n * @namespace Basic:isSymbol\n */\n\n/**\n * Returns if a value is a symbol.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a symbol\n *\n * @memberof Basic:isSymbol\n * @alias isSymbol\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol\n * @example\n * if( isSymbol(val) ){\n * return val.description;\n * }\n */\nexport function isSymbol(value){\n\treturn isA(value, 'symbol');\n}\n\n\n\n/**\n * @namespace Basic:isFunction\n */\n\n/**\n * Returns if a value is a function.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a function\n *\n * @memberof Basic:isFunction\n * @alias isFunction\n * @example\n * if( isFunction(val) ){\n * val();\n * }\n */\nexport function isFunction(value){\n\treturn isA(value, 'function');\n}\n\n\n\n/**\n * @namespace Basic:isObject\n */\n\n/**\n * Returns if a value is an object.\n *\n * Hint: if you explicitly want to check for a plain object, use isPlainObject\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is an object\n *\n * @memberof Basic:isObject\n * @alias isObject\n * @see isPlainObject\n * @example\n * if( isObject(val) ){\n * val.newProperty = 'foobar';\n * }\n */\nexport function isObject(value){\n\treturn isA(value, 'object');\n}\n\n\n\n/**\n * @namespace Basic:isPlainObject\n */\n\n/**\n * Returns if a value is an object literal, so so-called \"plain object.\n * A plain object is something like \"{hello : 'world'}\".\n *\n * This might especially be helpful when dealing with JSON configs, so quickly check if\n * something might even be parsed JSON (which in most cases is a plain object in js).\n *\n * Be aware that this function cannot differentiate between constructor-based simple objects and\n * plain objects declared inline. So, if someone took on the work to instantiate a base object and assign\n * properties either in a function or a constructor, we accept that as a plain object.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value seems to be a plain object\n *\n * @memberof Basic:isPlainObject\n * @alias isPlainObject\n * @example\n * const isParameterConfigObject = isPlainObject(param);\n */\nexport function isPlainObject(value){\n\treturn isObject(value)\n\t\t&& hasValue(value)\n\t\t&& (value.constructor === Object)\n\t\t&& Object.prototype.toString.call(value) === '[object Object]'\n\t;\n}\n\n\n\n/**\n * @namespace Basic:isArray\n */\n\n/**\n * Returns if a value is an array.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is an array\n *\n * @memberof Basic:isArray\n * @alias isArray\n * @example\n * if( isArray(val) ){\n * val.push('foobar');\n * }\n */\nexport function isArray(value){\n\treturn isA(value, 'array');\n}\n\n\n\n/**\n * @namespace Basic:isDate\n */\n\n/**\n * Returns if a value is a date.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a date\n *\n * @memberof Basic:isDate\n * @alias isDate\n * @example\n * if( isDate(val) ){\n * return val.toISOString();\n * }\n */\nexport function isDate(value){\n\treturn isA(value, 'date');\n}\n\n\n\n/**\n * @namespace Basic:isError\n */\n\n/**\n * Returns if a value is an error.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is an error\n *\n * @memberof Basic:isError\n * @alias isError\n * @example\n * if( isError(val) ){\n * return val.message;\n * }\n */\nexport function isError(value){\n\treturn isA(value, 'error');\n}\n\n\n\n/**\n * @namespace Basic:isGenerator\n */\n\n/**\n * Returns if a value is a generator.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a generator\n *\n * @memberof Basic:isGenerator\n * @alias isGenerator\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator\n * @example\n * if( isGenerator(val) ){\n * return val.return(val.next().value);\n * }\n */\nexport function isGenerator(value){\n\treturn isA(value, 'generator');\n}\n\n\n\n/**\n * @namespace Basic:isIterator\n */\n\n/**\n * Returns if a value is an iterator.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is an iterator\n *\n * @memberof Basic:isIterator\n * @alias isIterator\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator\n * @example\n * if( isIterator(val) ){\n * return val.next().value;\n * }\n */\nexport function isIterator(value){\n\treturn isA(value, 'iterator');\n}\n\n\n\n/**\n * @namespace Basic:isRegExp\n */\n\n/**\n * Returns if a value is a regular expression.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a regular expression\n *\n * @memberof Basic:isRegExp\n * @alias isRegExp\n * @example\n * if( isRegExp(val) ){\n * return val.test('foobar');\n * }\n */\nexport function isRegExp(value){\n\treturn isA(value, 'regexp');\n}\n\n\n\n/**\n * @namespace Basic:isSet\n */\n\n/**\n * Returns if a value is a set.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a set\n *\n * @memberof Basic:isSet\n * @alias isSet\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set\n * @example\n * if( isSet(val) ){\n * return val.has('foobar');\n * }\n */\nexport function isSet(value){\n\treturn isA(value, 'set');\n}\n\n\n\n/**\n * @namespace Basic:isWeakSet\n */\n\n/**\n * Returns if a value is a weak set.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a weak set\n *\n * @memberof Basic:isWeakSet\n * @alias isWeakSet\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet\n * @example\n * if( isWeakSet(val) ){\n * return val.has(someSymbol);\n * }\n */\nexport function isWeakSet(value){\n\treturn isA(value, 'weakset');\n}\n\n\n\n/**\n * @namespace Basic:isMap\n */\n\n/**\n * Returns if a value is a map.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a map\n *\n * @memberof Basic:isMap\n * @alias isMap\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map\n * @example\n * if( isMap(val) ){\n * return val.get('foobar');\n * }\n */\nexport function isMap(value){\n\treturn isA(value, 'map');\n}\n\n\n\n/**\n * @namespace Basic:isWeakMap\n */\n\n/**\n * Returns if a value is a weak map.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a weak map\n *\n * @memberof Basic:isWeakMap\n * @alias isWeakMap\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap\n * @example\n * if( isWeakMap(val) ){\n * return val.get('foobar');\n * }\n */\nexport function isWeakMap(value){\n\treturn isA(value, 'weakmap');\n}\n\n\n\n/**\n * @namespace Basic:isDocument\n */\n\n/**\n * Returns if a value is an HTML document.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is an HTML document\n *\n * @memberof Basic:isDocument\n * @alias isDocument\n * @example\n * if( isDocument(val) ){\n * return val.body;\n * }\n */\nexport function isDocument(value){\n\treturn isA(value, 'htmldocument');\n}\n\n\n\n/**\n * @namespace Basic:isElement\n */\n\n/**\n * Returns if a value is an HTML element.\n * Be aware, that this explicitly means an element, not necessarily any node.\n * So text nodes, comments and such do not qualify.\n * Also keep in mind, that SVGs are also something different.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is an HTML element\n *\n * @memberof Basic:isElement\n * @alias isElement\n * @example\n * if( isElement(target) ){\n * target.classList.add('foo');\n * }\n */\nexport function isElement(value){\n\treturn isA(value, 'htmlelement');\n}\n\n\n\n/**\n * @namespace Basic:isSvg\n */\n\n/**\n * Returns if a value is an SVG element.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is an SVG element\n *\n * @memberof Basic:isSvg\n * @alias isSvg\n * @example\n * if( isSvg(target) ){\n * target.querySelectorAll('path').remove();\n * }\n */\nexport function isSvg(value){\n\treturn isA(value, 'svgelement');\n}\n\n\n\n/**\n * @namespace Basic:isCollection\n */\n\n/**\n * Returns if a value is a collection of html elements.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a collection of html elements\n *\n * @memberof Basic:isCollection\n * @alias isCollection\n * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection\n * @example\n * if( isCollection(val) ){\n * return val.item(0);\n * }\n */\nexport function isCollection(value){\n\treturn isA(value, 'htmlcollection');\n}\n\n\n\n/**\n * @namespace Basic:isNodeList\n */\n\n/**\n * Returns if a value is a node list.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a node list\n *\n * @memberof Basic:isNodeList\n * @alias isNodeList\n * @see https://developer.mozilla.org/en-US/docs/Web/API/NodeList\n * @example\n * if( isNodeList(val) ){\n * return val.item(0);\n * }\n */\nexport function isNodeList(value){\n\treturn isA(value, 'nodelist');\n}\n\n\n\n/**\n * @namespace Basic:isWindow\n */\n\n/**\n * Returns if a value is a window.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a window\n *\n * @memberof Basic:isWindow\n * @alias isWindow\n * @example\n * if( isWindow(val) ){\n * return val.location.origin;\n * }\n */\nexport function isWindow(value){\n\treturn isA(value, 'window');\n}\n\n\n\n/**\n * @namespace Basic:isUrl\n */\n\n/**\n * Returns if a value is an URL object.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a URL object\n *\n * @memberof Basic:isUrl\n * @alias isUrl\n * @example\n * if( isUrl(val) ){\n * return val.path;\n * }\n */\nexport function isUrl(value){\n return isA(value, 'url');\n}\n\n\n\n/**\n * @namespace Basic:isUrlSearchParams\n */\n\n/**\n * Returns if a value is an URLSearchParams object.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a URLSearchParams object\n *\n * @memberof Basic:isUrlSearchParams\n * @alias isUrlSearchParams\n * @example\n * if( isUrlSearchParams(val) ){\n * val.set('query', 'foobar');\n * }\n */\nexport function isUrlSearchParams(value){\n return isA(value, 'urlsearchparams');\n}\n\n\n\n/**\n * @namespace Basic:isEventTarget\n */\n\n/**\n * Returns if a value is an EventTarget, which means that it is able to dispatch and receive events.\n * This is determined via duck-typing and not via class inheritance check, since this method is not\n * about type-safety, but the question if we can use the target for events, which is simply determined\n * by three essential object methods: addEventListener, removeEventListener and dispatchEvent. All\n * objects supporting these are fine with us.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value supports event methods\n *\n * @memberof Basic:isEventTarget\n * @alias isEventTarget\n * @example\n * if( isEventTarget(target) ){\n * target.dispatchEvent(new CustomEvent('foobar'));\n * }\n */\nexport function isEventTarget(value){\n\treturn hasValue(value)\n\t\t&& isFunction(value.addEventListener)\n\t\t&& isFunction(value.removeEventListener)\n\t\t&& isFunction(value.dispatchEvent)\n\t;\n}\n\n\n\n/**\n * @namespace Basic:isSelector\n */\n\n/**\n * Returns if a value is a valid selector, usable in methods such as querySelector\n * and querySelectorAll.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a valid selector\n *\n * @memberof Basic:isSelector\n * @alias isSelector\n * @example\n * if( isSelector(selector) ){\n * document.querySelector(selector)?.style.setProperty('color', 'red');\n * }\n */\nexport function isSelector(value){\n\t// almost all values like \"null\", \"undefined\" and \"NaN\" are accepted querySelectors, numbers are not\n\tvalue = orDefault(value, 0, 'str');\n\n\tconst fragment = document.createDocumentFragment();\n\n\ttry {\n\t\tfragment.querySelector(value);\n\t} catch(ex){\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n\n\n/**\n * @namespace Basic:isPotentialId\n */\n\n/**\n * Determines if a given value is potentially a valid id for something, because it matches a format of given\n * prefix, postfix and id regex. \"Potential\", because we can only assume by the format, we do not actually know\n * if the id really matches anything like a database entry for example.\n *\n * @param {(String|Number)} value - the value to test, will be stringified\n * @param {?String} [prefix=''] - a prefix for the id\n * @param {?String} [idRex='[1-9][0-9]*'] - the regex string to use to identify the id part of the value\n * @param {?String} [postfix=''] - a postfix for the id\n * @param {?Boolean} [maskFixes=true] - usually, prefixes are not treated as regexes and are automatically masked, if you'd like to define complex pre- and postfixes using regexes, set this to false\n * @returns {String|Boolean} if value is potential id according to format, the id is returned as a string (still usable as a truthy value), otherwise the return value is false\n *\n * @memberof Basic:isPotentialId\n * @alias isPotentialId\n * @example\n * if( isPotentialId(id, 'test_(', '[0-9]+', ')') ){\n * createJsonRequest(`/backend/${id}`).then(() => { alert('done'); });\n * }\n */\nexport function isPotentialId(value, prefix='', idRex='[1-9][0-9]*', postfix='', maskFixes=true){\n\tvalue = `${value}`;\n\tprefix = orDefault(prefix, '', 'str');\n\tidRex = orDefault(idRex, '[1-9][0-9]*', 'str');\n\tpostfix = orDefault(postfix, '', 'str');\n\tmaskFixes = orDefault(maskFixes, true, 'bool');\n\n\tconst mask = str => `${str}`.replace(/([\\-\\[\\]\\/{}()*+?.\\\\^$|])/g, \"\\\\$&\");\n\n\tlet rex;\n\tif( maskFixes ){\n\t\trex = new RegExp(`^${mask(prefix)}(${idRex})${mask(postfix)}$`);\n\t} else {\n\t\trex = new RegExp(`^${prefix}(${idRex})${postfix}$`);\n\t}\n\n\tconst matches = rex.exec(value);\n\treturn hasValue(matches) ? matches[1] : false;\n}\n\n\n\n/**\n * @namespace Basic:min\n */\n\n/**\n * Checks if a value is larger than a minimum and returns\n * the value or the lower bound respectively.\n *\n * Accepts all values comparable with >.\n *\n * @param {*} value - the value to check\n * @param {*} minValue - the lower bound\n * @returns {*} value or minValue\n *\n * @memberof Basic:min\n * @alias min\n * @example\n * let croppedVal = min(value, 0);\n */\nexport function min(value, minValue){\n\treturn (value < minValue) ? minValue : value;\n}\n\n\n\n/**\n * @namespace Basic:max\n */\n\n/**\n * Checks if a value is smaller than a maximum and returns\n * the value or the upper bound respectively.\n *\n * Accepts all values comparable with <.\n *\n * @param {*} value - the value to check\n * @param {*} maxValue - the upper bound\n * @returns {*} value or maxValue\n *\n * @memberof Basic:max\n * @alias max\n * @example\n * let croppedVal = max(value, 100);\n */\nexport function max(value, maxValue){\n\treturn (value > maxValue) ? maxValue : value;\n}\n\n\n\n/**\n * @namespace Basic:minMax\n */\n\n/**\n * Checks if a value is within bounds of a minimum and maximum and returns\n * the value or the upper or lower bound respectively.\n *\n * Accepts all values comparable with > and <.\n *\n * @param {*} minValue - the lower bound\n * @param {*} value - the value to check\n * @param {*} maxValue - the upper bound\n * @throws error if minValue is not smaller than maxValue\n * @returns {*} value, minValue or maxValue\n *\n * @memberof Basic:minMax\n * @alias minMax\n * @example\n * let croppedVal = minMax(-100, value, 100);\n */\nexport function minMax(minValue, value, maxValue){\n\tconst __methodName__ = 'minMax';\n\n\tassert(minValue <= maxValue, `${MODULE_NAME}:${__methodName__} | minValue can not be larger than maxValue`);\n\n\treturn min(max(value, maxValue), minValue);\n}\n\n\n\n/**\n * @namespace Basic:round\n */\n\n/**\n * Rounds a number to a defined precision.\n *\n * Precision 0 rounds to full number.\n *\n * @param {Number} number - the number to round\n * @param {?Number} [precision=0] - the number of digits after the floating point to round to\n * @returns {Number} rounded number\n *\n * @memberof Basic:round\n * @alias round\n * @example\n * let roundedValue = round(666.66);\n * => 667\n * let roundedValue = round(0.5555555, 3);\n * => 0.556\n */\nexport function round(number, precision=0){\n\tnumber = parseFloat(number);\n\tprecision = min(orDefault(precision, 0, 'int'), 0);\n\n\tconst power = Math.pow(10, precision);\n\n\treturn Math.round(parseFloat(number) * power) / power;\n}\n\n\n\n/**\n * @namespace Basic:Deferred\n */\n\n/**\n * @typedef Deferred\n * @type {Object}\n *\n * @property {Promise} promise - the wrapped promise\n * @property {Function} resolve - resolves the wrapped promise with given value\n * @property {Function} reject - rejects the wrapped promise with given error\n * @property {Function} then - defines a success handler for the wrapped promise and returns its result\n * @property {Function} catch - defines an error handler for the wrapped promise and returns its result\n * @property {Function} finally - defines a \"settled\" handler for the wrapped promise and returns its result\n * @property {String} status - holds the current resolution status, can either be \"pending\", \"fulfilled\" or \"rejected\"\n * @property {Function} isSettled - returns true, if the Deferred is either \"fulfilled\" or \"rejected\"\n * @property {?*} [provision=null] - may contain (a) provisional value(s) to use for a newly instantiated Deferred, before it has resolved to the actual value(s)\n *\n * @memberof Basic\n */\n\n/**\n * Class that wraps a Promise, to allow resolving and rejecting outside the\n * Promise's function scope. This allows for decoupled handling of states and\n * handling promises as references in a distributed context, like a class, where\n * a Deferred might then represent an async state.\n *\n * Deferreds also provide accessible status information, normal Promises do not have.\n * Accessing the \"status\" property returns the current status, being either \"pending\",\n * \"fulfilled\" or \"rejected\". You may also check if the Deferred has been settled via\n * \"isSettled()\". If you want to provide a preliminary result, available before the\n * promise has settled, you may set this result as a payload using the \"provision\" property.\n *\n * This follows ideas by jQuery and Q Promises:\n * - https://api.jquery.com/jQuery.Deferred/\n * - https://github.com/kriskowal/q/wiki/Coming-from-jQuery#deferreds-promises-resolvers\n *\n * Keep in mind, that Promises might need a polyfill such as core-js.\n *\n * For details, see class documentation below.\n *\n * @memberof Basic:Deferred\n * @name Deferred\n * @see Basic.Deferred\n * @example\n * const doStuff = new Deferred();\n * doStuff.provision = 'provisional value';\n * doStuff\n * .then(value => { alert(`yeah, ready with \"${value}\"!`); })\n * .catch(error => { console.error(error); })\n * .finally(() => { console.info('has been settled'); })\n * ;\n * if( foobar === 42 ){\n * doStuff.resolve(42);\n * } else {\n * doStuff.reject(new Error('not 42!'));\n * }\n * console.info(doStuff.status);\n */\nexport class Deferred {\n\n\tconstructor(){\n\t\tconst\n\t\t\tSTATUS_PENDING = 'pending',\n\t\t\tSTATUS_FULFILLED = 'fulfilled',\n\t\t\tSTATUS_REJECTED = 'rejected'\n\t\t;\n\t\tthis.resolve = null;\n\t\tthis.reject = null;\n\t\tthis.provision = null;\n\t\tthis.status = STATUS_PENDING;\n\t\tthis.isSettled = () => [STATUS_FULFILLED, STATUS_REJECTED].includes(this.status);\n\t\tthis.promise = new Promise((resolve, reject) => {\n\t\t\tthis.resolve = resolution => {\n\t\t\t\tthis.status = STATUS_FULFILLED;\n\t\t\t\tresolve(resolution);\n\t\t\t};\n\t\t\tthis.reject = rejection => {\n\t\t\t\tthis.status = STATUS_REJECTED;\n\t\t\t\treject(rejection);\n\t\t\t};\n\t\t});\n\t}\n\n\tthen(f){\n\t\treturn this.promise.then(f);\n\t}\n\n\tcatch(f){\n\t\treturn this.promise.catch(f);\n\t}\n\n\tfinally(f){\n\t\treturn this.promise.finally(f);\n\t}\n\n}\n\n\n\n/**\n * @namespace Basic:Observable\n */\n\n/**\n * @typedef Observable\n * @type {Object}\n *\n * @property {Function} getValue - returns the current value\n * @property {Function} setValue - sets a new value, which will subsequently trigger all subscriptions\n * @property {Function} subscribe - register a given function to be executed on any value change, the subscription receives the new and the old value on each execution, returns the subscription value, which can later be used to unsubscribe again\n * @property {Function} unsubscribe - removes a given subscription again, use subscription value returned by subscribe here\n *\n * @memberof Basic\n */\n\n/**\n * A class offering the bare minimum feature set to observe a value and subscribe to future value changes.\n * No automatic magic going on here, this simply follows a basic subscription pattern, where each subscription is\n * a function, being called with a newly set value. This closely resembles the kind of observables knockout is using.\n *\n * For details, see class documentation below.\n *\n * @memberof Basic:Observable\n * @name Observable\n * @see Basic.Observable\n * @example\n * const status = new Observable('ok');\n * const subscription = status.subscribe(s => {\n * console.log(`status changed to: ${s}`);\n * });\n * status.setValue('oh noez');\n * status.unsubscribe(subscription);\n */\nexport class Observable {\n\n\t#__className__ = 'Observable';\n\t#value;\n\t#subscriptions;\n\n\tconstructor(initialValue){\n\t\tthis.#value = initialValue;\n\t\tthis.#subscriptions = [];\n\t}\n\n\tgetValue(){\n\t\treturn this.#value;\n\t}\n\n\tsetValue(newValue, force=false){\n\t\tconst\n\t\t\toldValue = this.#value,\n\t\t\tisNewValue = oldValue !== newValue\n\t\t;\n\t\tthis.#value = newValue;\n\t\tif( isNewValue || force ){\n\t\t\tthis.#subscriptions.forEach(s => s(newValue, oldValue));\n\t\t}\n\t}\n\n\tsubscribe(subscription){\n\t\tconst __methodName__ = 'subscribe';\n\t\tassert(isFunction(subscription), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | subscription must be function`);\n\t\tif( this.#subscriptions.indexOf(subscription) < 0 ){\n\t\t\tthis.#subscriptions = [...this.#subscriptions, subscription];\n\t\t}\n\t\treturn subscription;\n\t}\n\n\tunsubscribe(subscription){\n\t\tthis.#subscriptions = this.#subscriptions.filter(s => s !== subscription);\n\t}\n\n\ttoString(){\n\t\treturn `${this.#value}`;\n\t}\n\n}\n"]} \ No newline at end of file +{"version":3,"file":"basic.js","names":["MODULE_NAME","log","warn","assert","condition","message","orDefault","Error","attempt","closure","isFunction","ex","hasValue","res","Array","from","arguments","forEach","value","size","target","countStringCharacters","values","length","getType","Object","isEmpty","emptyValues","undefined","obj","isArray","__additionalEmptyValues__","concat","Set","includes","hasMembers","memberNames","verbose","memberName","info","expression","defaultValue","caster","additionalEmptyValues","toLowerCase","parseInt","parseFloat","deepType","prototype","toString","call","slice","test","match","isA","type","isBoolean","isNumber","isBigInt","isInt","intVal","isFloat","floatVal","isNaN","checkForIdentity","isString","isSymbol","isObject","isPlainObject","constructor","isDate","isError","isGenerator","isIterator","isRegExp","isSet","isWeakSet","isMap","isWeakMap","isDocument","isElement","isSvg","isCollection","isNodeList","isWindow","isUrl","isUrlSearchParams","isEventTarget","addEventListener","removeEventListener","dispatchEvent","isSelector","fragment","document","createDocumentFragment","querySelector","isPotentialId","prefix","idRex","postfix","maskFixes","mask","str","replace","rex","RegExp","matches","exec","min","minValue","max","maxValue","minMax","round","number","precision","power","Math","pow","Deferred","STATUS_FULFILLED","STATUS_REJECTED","this","resolve","reject","provision","status","isSettled","promise","Promise","resolution","rejection","then","f","catch","finally","Observable","__className__","subscriptions","initialValue","getValue","setValue","newValue","force","oldValue","isNewValue","s","subscribe","subscription","indexOf","unsubscribe","filter"],"sources":["basic.js"],"mappings":";;;AAQA,MAAMA,YAAc,eAMZC,IAAKC,SAAW,sBA0BjB,SAASC,OAAOC,EAAWC,GACjC,IAAKD,EAEJ,MADAC,EAAUC,UAAUD,EAAS,qCAAsC,OAC7D,IAAIE,MAAMF,EAElB,QA0BO,SAASG,QAAQC,GACvBN,OAAOO,WAAWD,GAAU,GAAGT,gDAE/B,IACCS,GACD,CAAE,MAAME,GACP,OAAO,CACR,CAEA,OAAO,CACR,QAuBO,SAASC,WACf,IAAIC,GAAM,EAMV,OAJAC,MAAMC,KAAKC,WAAWC,SAAQC,IAC7BL,IAAQ,MAAEK,CAAyC,IAG7CL,CACR,QA+CO,SAASM,KAAKC,EAAQC,GAAsB,GAClD,GAAIX,WAAWU,GAAQE,QAAU,OAAOR,MAAMC,KAAKK,EAAOE,UAAUC,OAEpE,IAAIV,EACJ,OAAQW,QAAQJ,IACf,IAAK,QACJP,EAAMO,EAAOG,OACd,MAEA,IAAK,MACL,IAAK,MACJV,EAAMO,EAAOD,KACd,MAEA,IAAK,WACJN,EAAMC,MAAMC,KAAKK,GAAQG,OAC1B,MAEA,IAAK,SAEJV,EAAMQ,EAAwB,IAAID,GAAQG,OAASH,EAAOG,OAC3D,MAEA,IAAK,SACJV,EAAMY,OAAOH,OAAOF,GAAQG,OAC7B,MAEA,QACCV,EAAM,KAIR,OAAOA,CACR,QA2BO,SAASa,UACf,IACCb,GAAM,EACNc,EAAc,MAACC,EAAW,KAAM,GAAI,GAoBrC,OAjBAd,MAAMC,KAAKC,WAAWC,SAAQY,IACzBC,QAAQD,GAAKE,6BAChBJ,EAAcA,EAAYK,OAAOH,EAAIE,2BACtC,IAEDJ,EAAcb,MAAMC,KAAK,IAAIkB,IAAIN,IAEjCb,MAAMC,KAAKC,WAAWC,SAAQY,IACzBhB,IAAQiB,QAAQD,GAAKE,6BACxBlB,EAAMc,EAAYO,SAASL,GAEtBhB,IACJA,EAAqB,IAAdM,KAAKU,IAEd,IAGMhB,CACR,QAyBO,SAASsB,WAAWN,EAAKO,EAAaC,GAAQ,GACpDD,EAAc9B,UAAU8B,EAAa,GAAI,OACzCC,EAAU/B,UAAU+B,GAAS,EAAO,QAEpC,IAAIxB,GAAM,EAYV,OAVAuB,EAAYnB,SAAQqB,IACd1B,SAASiB,EAAI,GAAGS,QAChBD,GACHpC,MAAMsC,KAAK,GAAGvC,2CAA2CsC,KAG1DzB,GAAM,EACP,IAGMA,CACR,QA0BO,SAASP,UAAUkC,EAAYC,EAAcC,EAAO,KAAMC,EAAsB,MAsCtF,OApCCA,EADG/B,SAAS+B,GACY,GAAGX,OAAOW,GAEV,GAGrB/B,SAAS8B,IAEVhC,WAAWgC,IACR,CACH,MAAO,SACP,MAAO,UACP,OAAQ,UACR,QACA,MAAO,SACNR,SAAS,GAAGQ,EAAOE,kBAErBF,EAAS,GAAGA,IAASE,cAEjB,CAAC,MAAO,UAAUV,SAASQ,GAC9BA,EAAS,SAASxB,GAAQ,MAAO,GAAGA,GAAS,EACnC,CAAC,MAAO,WAAWgB,SAASQ,GACtCA,EAAS,SAASxB,GAAQ,OAAO2B,SAAS3B,EAAO,GAAK,EAC5C,CAAC,OAAQ,WAAWgB,SAASQ,GACvCA,EAAS,SAASxB,GAAQ,QAASA,CAAO,EACrB,UAAXwB,EACVA,EAAS,SAASxB,GAAQ,OAAO4B,WAAW5B,EAAQ,EAC1C,CAAC,MAAO,SAASgB,SAASQ,KACpCA,EAAS,SAASxB,GAAQ,MAAO,GAAGc,OAAOd,EAAQ,IAEzCR,WAAWgC,KACtBA,EAAS,SAASxB,GAAQ,OAAOA,CAAO,GAGzCwB,EAAS,SAASxB,GAAQ,OAAOA,CAAO,GAGpCN,SAAS4B,IAAgBG,EAAsBT,SAASM,GACrDC,EAEAC,EAAOF,EAEhB,QAoDO,SAAShB,QAAQN,GACvB,IAAKN,SAASM,GAAS,MAAO,GAAGA,IAAQ0B,cAEzC,MAAMG,EAAWtB,OAAOuB,UAAUC,SAASC,KAAKhC,GAAOiC,MAAM,GAAG,GAAGP,cAEnE,MAAiB,sBAAbG,EAA0C,WAC7B,aAAbA,EAAiC,eACpB,YAAbA,GACA,kBAAkBK,KAAKL,GADS,cAEhC,iBAAiBK,KAAKL,GAAmB,aACzC,eAAeK,KAAKL,GAAmB,WAEpCA,EAASM,MAAM,wJACnBN,EACmB,iBAAV7B,GAAyC,mBAAVA,EAAyB,gBAAkBA,CAEvF,QAsBO,SAASoC,IAAIpC,EAAOqC,GAC1B,MACC,CACC,YACA,OACA,UACA,SACA,SACA,SACA,SACA,WACA,SACA,QACA,OACA,QACA,YACA,WACA,SACA,MACA,UACA,MACA,UACA,eACA,cACA,aACA,iBACA,WACA,SACA,MACA,mBACCrB,SAAS,GAAGqB,IAAOX,eAEdpB,QAAQN,KAAW,GAAGqC,IAAOX,eAEpC1C,KAAK,GAAGF,sBAAsBuD,gCACvB,EAET,QAqBO,SAASC,UAAUtC,GACzB,OAAOoC,IAAIpC,EAAO,UACnB,QA0BO,SAASuC,SAASvC,GACxB,OAAOoC,IAAIpC,EAAO,SACnB,QAqBO,SAASwC,SAASxC,GACxB,OAAOoC,IAAIpC,EAAO,SACnB,QAuBO,SAASyC,MAAMC,GACrB,OAAOf,SAASe,EAAQ,MAAQA,CACjC,QAwBO,SAASC,QAAQC,GACvB,OAAOhB,WAAWgB,KAAcA,CACjC,QA2BO,SAASC,MAAMvB,EAAYwB,GAAiB,GAGlD,OAFAA,EAAmB1D,UAAU0D,GAAkB,EAAM,SAG7CxB,GAAeA,EAEfuB,MAAMvB,EAEf,QAqBO,SAASyB,SAAS/C,GACxB,OAAOoC,IAAIpC,EAAO,SACnB,QAsBO,SAASgD,SAAShD,GACxB,OAAOoC,IAAIpC,EAAO,SACnB,QAqBO,SAASR,WAAWQ,GAC1B,OAAOoC,IAAIpC,EAAO,WACnB,QAwBO,SAASiD,SAASjD,GACxB,OAAOoC,IAAIpC,EAAO,SACnB,QA2BO,SAASkD,cAAclD,GAC7B,OAAOiD,SAASjD,IACZN,SAASM,IACRA,EAAMmD,cAAgB5C,QACmB,oBAA1CA,OAAOuB,UAAUC,SAASC,KAAKhC,EAEpC,QAqBO,SAASY,QAAQZ,GACvB,OAAOoC,IAAIpC,EAAO,QACnB,QAqBO,SAASoD,OAAOpD,GACtB,OAAOoC,IAAIpC,EAAO,OACnB,QAqBO,SAASqD,QAAQrD,GACvB,OAAOoC,IAAIpC,EAAO,QACnB,QAsBO,SAASsD,YAAYtD,GAC3B,OAAOoC,IAAIpC,EAAO,YACnB,QAsBO,SAASuD,WAAWvD,GAC1B,OAAOoC,IAAIpC,EAAO,WACnB,QAqBO,SAASwD,SAASxD,GACxB,OAAOoC,IAAIpC,EAAO,SACnB,QAsBO,SAASyD,MAAMzD,GACrB,OAAOoC,IAAIpC,EAAO,MACnB,QAsBO,SAAS0D,UAAU1D,GACzB,OAAOoC,IAAIpC,EAAO,UACnB,QAsBO,SAAS2D,MAAM3D,GACrB,OAAOoC,IAAIpC,EAAO,MACnB,QAsBO,SAAS4D,UAAU5D,GACzB,OAAOoC,IAAIpC,EAAO,UACnB,QAqBO,SAAS6D,WAAW7D,GAC1B,OAAOoC,IAAIpC,EAAO,eACnB,QAwBO,SAAS8D,UAAU9D,GACzB,OAAOoC,IAAIpC,EAAO,cACnB,QAqBO,SAAS+D,MAAM/D,GACrB,OAAOoC,IAAIpC,EAAO,aACnB,QAsBO,SAASgE,aAAahE,GAC5B,OAAOoC,IAAIpC,EAAO,iBACnB,QAsBO,SAASiE,WAAWjE,GAC1B,OAAOoC,IAAIpC,EAAO,WACnB,QAqBO,SAASkE,SAASlE,GACxB,OAAOoC,IAAIpC,EAAO,SACnB,QAqBO,SAASmE,MAAMnE,GAClB,OAAOoC,IAAIpC,EAAO,MACtB,QAqBO,SAASoE,kBAAkBpE,GAC9B,OAAOoC,IAAIpC,EAAO,kBACtB,QAyBO,SAASqE,cAAcrE,GAC7B,OAAON,SAASM,IACZR,WAAWQ,EAAMsE,mBACjB9E,WAAWQ,EAAMuE,sBACjB/E,WAAWQ,EAAMwE,cAEtB,QAsBO,SAASC,WAAWzE,GAE1BA,EAAQZ,UAAUY,EAAO,EAAG,OAE5B,MAAM0E,EAAWC,SAASC,yBAE1B,IACCF,EAASG,cAAc7E,EACxB,CAAE,MAAMP,GACP,OAAO,CACR,CAEA,OAAO,CACR,QA2BO,SAASqF,cAAc9E,EAAO+E,EAAO,GAAIC,EAAM,cAAeC,EAAQ,GAAIC,GAAU,GAC1FlF,EAAQ,GAAGA,IACX+E,EAAS3F,UAAU2F,EAAQ,GAAI,OAC/BC,EAAQ5F,UAAU4F,EAAO,cAAe,OACxCC,EAAU7F,UAAU6F,EAAS,GAAI,OAGjC,MAAME,EAAOC,GAAO,GAAGA,IAAMC,QAAQ,6BAA8B,QAEnE,IAAIC,EAEHA,GANDJ,EAAY9F,UAAU8F,GAAW,EAAM,SAMhC,IAAIK,OAAO,IAAIJ,EAAKJ,MAAWC,KAASG,EAAKF,OAE7C,IAAIM,OAAO,IAAIR,KAAUC,KAASC,MAGzC,MAAMO,EAAUF,EAAIG,KAAKzF,GACzB,QAAON,SAAS8F,IAAWA,EAAQ,EACpC,QAuBO,SAASE,IAAI1F,EAAO2F,GAC1B,OAAQ3F,EAAQ2F,EAAYA,EAAW3F,CACxC,QAuBO,SAAS4F,IAAI5F,EAAO6F,GAC1B,OAAQ7F,EAAQ6F,EAAYA,EAAW7F,CACxC,QAyBO,SAAS8F,OAAOH,EAAU3F,EAAO6F,GAKvC,OAFA5G,OAAO0G,GAAYE,EAAU,GAAG/G,iEAEzB4G,IAAIE,IAAI5F,EAAO6F,GAAWF,EAClC,QAyBO,SAASI,MAAMC,EAAQC,EAAU,GACvCD,EAASpE,WAAWoE,GACpBC,EAAYP,IAAItG,UAAU6G,EAAW,EAAG,OAAQ,GAEhD,MAAMC,EAAQC,KAAKC,IAAI,GAAIH,GAE3B,OAAOE,KAAKJ,MAAMnE,WAAWoE,GAAUE,GAASA,CACjD,QA+DO,MAAMG,SAEZ,WAAAlD,GACC,MAECmD,EAAmB,YACnBC,EAAkB,WAEnBC,KAAKC,QAAU,KACfD,KAAKE,OAAS,KACdF,KAAKG,UAAY,KACjBH,KAAKI,OAPa,UAQlBJ,KAAKK,UAAY,IAAM,CAACP,EAAkBC,GAAiBvF,SAASwF,KAAKI,QACzEJ,KAAKM,QAAU,IAAIC,SAAQ,CAACN,EAASC,KACpCF,KAAKC,QAAUO,IACdR,KAAKI,OAASN,EACdG,EAAQO,EAAW,EAEpBR,KAAKE,OAASO,IACbT,KAAKI,OAASL,EACdG,EAAOO,EAAU,CACjB,GAEH,CAEA,IAAAC,CAAKC,GACJ,OAAOX,KAAKM,QAAQI,KAAKC,EAC1B,CAEA,MAAMA,GACL,OAAOX,KAAKM,QAAQM,MAAMD,EAC3B,CAEA,QAAQA,GACP,OAAOX,KAAKM,QAAQO,QAAQF,EAC7B,SAwCM,MAAMG,WAEZC,GAAiB,aACjBvH,GACAwH,GAEA,WAAArE,CAAYsE,GACXjB,MAAKxG,EAASyH,EACdjB,MAAKgB,EAAiB,EACvB,CAEA,QAAAE,GACC,OAAOlB,MAAKxG,CACb,CAEA,QAAA2H,CAASC,EAAUC,GAAM,GACxB,MACCC,EAAWtB,MAAKxG,EAChB+H,EAAaD,IAAaF,EAE3BpB,MAAKxG,EAAS4H,GACVG,GAAcF,IACjBrB,MAAKgB,EAAezH,SAAQiI,GAAKA,EAAEJ,EAAUE,IAE/C,CAEA,SAAAG,CAAUC,GAMT,OAJAjJ,OAAOO,WAAW0I,GAAe,GAAGpJ,eAAe0H,MAAKe,+CACpDf,MAAKgB,EAAeW,QAAQD,GAAgB,IAC/C1B,MAAKgB,EAAiB,IAAIhB,MAAKgB,EAAgBU,IAEzCA,CACR,CAEA,WAAAE,CAAYF,GACX1B,MAAKgB,EAAiBhB,MAAKgB,EAAea,QAAOL,GAAKA,IAAME,GAC7D,CAEA,QAAAnG,GACC,MAAO,GAAGyE,MAAKxG,GAChB","ignoreList":[],"sourcesContent":["/*!\n * Module Basic\n */\n\n/**\n * @namespace Basic\n */\n\nconst MODULE_NAME = 'Basic';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {log, warn} from './logging.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Basic:assert\n */\n\n/**\n * Classical assert method. If condition is falsy, throw assert exception.\n *\n * @param {Boolean} condition - defines if an assertion is successful\n * @param {?String} [message='assert exception: assertion failed'] - to display if assertion fails\n * @throws assert exception\n *\n * @memberof Basic:assert\n * @alias assert\n * @example\n * function set(name, value){\n * assert(name.length > 0);\n * assert(isPlainObject(value), 'error: value must be plain object');\n * ...\n * }\n */\nexport function assert(condition, message){\n\tif( !condition ){\n\t\tmessage = orDefault(message, 'assert exception: assertion failed', 'str');\n\t\tthrow new Error(message);\n\t}\n}\n\n\n\n/**\n * @namespace Basic:attempt\n */\n\n/**\n * Attempt to compute contents of closure and catch all occurring exceptions.\n * The boolean result tells you if the operation was successful or not.\n *\n * This is most helpful, when used to test value conversions or other atomic/singluar operations, where it\n * just is important if something isolated works or not.\n *\n * Do not encapsulate complex code in the closure and mind recursively occurring exceptions!\n *\n * @param {Function} closure - the code to test\n * @throws error if closure is not a function\n * @returns {Boolean} true if no exception occurred\n *\n * @memberof Basic:attempt\n * @alias attempt\n * @example\n * if( !attempt(function(){ foobar(); }) ){ console.log('foobar cannot be executed!'); }\n */\nexport function attempt(closure){\n\tassert(isFunction(closure), `${MODULE_NAME}:attempt | closure is no function`);\n\n\ttry {\n\t\tclosure();\n\t} catch(ex){\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n\n\n/**\n * @namespace Basic:hasValue\n */\n\n/**\n * Check if variable(s) is set, by being neither undefined nor null.\n *\n * @param {...*} [...] - add any number of variables you wish to check\n * @returns {Boolean} variable(s) is/are set\n *\n * @memberof Basic:hasValue\n * @alias hasValue\n * @example\n * function set(name, value){\n * if( hasValue(name, value) ){\n * ...\n * }\n * }\n */\nexport function hasValue(){\n\tlet res = true;\n\n\tArray.from(arguments).forEach(value => {\n\t\tres &&= ((value !== undefined) && (value !== null));\n\t});\n\n\treturn res;\n}\n\n\n\n/**\n * @namespace Basic:size\n */\n\n/**\n * Determine the (value) size of a collection.\n *\n * A collection is an object with countable values:\n * - Arrays return their length\n * - Sets and Maps return their size\n * - Strings return their (character) length\n * - Iterators return the length of their value list\n * - Objects return the length of their value list\n * - any object implementing .values() returns the length of the returned value list\n *\n * @param {Object|Array|Set|Map|String|Iterable} target - a collection to determine the (value) size of\n * @param {?Boolean} [countStringCharacters=true] - if we want to determine the length of a string, we'd normally like to count actual characters, but length normally returns the technical length counting more than one for unicode chars, set this to \"false\" to use technical length instead of characters\n * @returns {Number|null} the size of the collection or null if no size could be determined\n *\n * @memberof Basic:size\n * @alias size\n * @example\n * size('日本国💩👻');\n * => 5\n * size('日本国💩👻', false);\n * => 7\n * size({a : 1, b : new Date(), c : [1, 2, 3]});\n * => 3\n * size(['test', 'test', 'test']);\n * => 3\n * size(new Set(['test1', 'test2', 'test3']));\n * => 3\n * size(new Set(['test1', 'test2', 'test3']).values());\n * => 3\n * size(new Map([[1, 1], [new Date(), new Date()], ['foo', 'bar']]));\n * => 3\n * size(new Map([[1, 1], [new Date(), new Date()], ['foo', 'bar']]).values());\n * => 3\n * size(null);\n * => null\n * size(undefined);\n * => null\n */\nexport function size(target, countStringCharacters=true){\n\tif( isFunction(target?.values) ) return Array.from(target.values()).length;\n\n\tlet res;\n\tswitch( getType(target) ){\n\t\tcase 'array':\n\t\t\tres = target.length;\n\t\tbreak;\n\n\t\tcase 'set':\n\t\tcase 'map':\n\t\t\tres = target.size;\n\t\tbreak;\n\n\t\tcase 'iterator':\n\t\t\tres = Array.from(target).length;\n\t\tbreak;\n\n\t\tcase 'string':\n\t\t\t// see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length#description\n\t\t\tres = countStringCharacters ? [...target].length : target.length;\n\t\tbreak;\n\n\t\tcase 'object':\n\t\t\tres = Object.values(target).length;\n\t\tbreak;\n\n\t\tdefault:\n\t\t\tres = null;\n\t\tbreak;\n\t}\n\n\treturn res;\n}\n\n\n\n/**\n * @namespace Basic:isEmpty\n */\n\n/**\n * Check if variable(s) contain non-empty value\n * (not undefined, null, '', 0, [], {} or an empty Set/Map).\n *\n * You can supply additional non-empty values by providing an object having the key \"__additionalEmptyValues__\" as\n * any single parameter. Multiple occurrences will be merged.\n *\n * @param {...*} [...] - add any number of variables you wish to check\n * @returns {Boolean} variable(s) is/are empty\n *\n * @memberof Basic:isEmpty\n * @alias isEmpty\n * @example\n * function set(name, value){\n * if( isEmpty(fooBar) || isEmpty({'__additionalEmptyValues__' : [false, '0']}, someArray, someSet, someString, value) ){\n * ...\n * }\n * }\n */\nexport function isEmpty(){\n\tlet\n\t\tres = true,\n\t\temptyValues = [undefined, null, '', 0]\n\t;\n\n\tArray.from(arguments).forEach(obj => {\n\t\tif( isArray(obj?.__additionalEmptyValues__) ){\n\t\t\temptyValues = emptyValues.concat(obj.__additionalEmptyValues__);\n\t\t}\n\t});\n\temptyValues = Array.from(new Set(emptyValues));\n\n\tArray.from(arguments).forEach(obj => {\n\t\tif( res && !isArray(obj?.__additionalEmptyValues__) ){\n\t\t\tres = emptyValues.includes(obj);\n\n\t\t\tif( !res ){\n\t\t\t\tres = (size(obj) === 0);\n\t\t\t}\n\t\t}\n\t});\n\n\treturn res;\n}\n\n\n\n/**\n * @namespace Basic:hasMembers\n */\n\n/**\n * \"Validates\" an object in a very basic way by checking if all given members are present and are not nullish.\n *\n * @param {Object} obj - the object to check\n * @param {String[]} memberNames - the names of the members to check\n * @param {Boolean} [verbose=false] - defines if method should output missing members to console\n * @returns {Boolean} all memberNames present and not nullish\n *\n * @memberof Basic:hasMembers\n * @alias hasMembers\n * @example\n * function pat(kitten){\n * if( hasMembers(kitten, ['fluff', 'meow', 'scratch']) ){\n * ...\n * }\n * }\n */\nexport function hasMembers(obj, memberNames, verbose=false){\n\tmemberNames = orDefault(memberNames, [], 'arr');\n\tverbose = orDefault(verbose, false, 'bool');\n\n\tlet res = true;\n\n\tmemberNames.forEach(memberName => {\n\t\tif( !hasValue(obj[`${memberName}`]) ){\n\t\t\tif( verbose ){\n\t\t\t\tlog().info(`${MODULE_NAME}:hasMembers | missing member ${memberName}`);\n\t\t\t}\n\n\t\t\tres = false;\n\t\t}\n\t});\n\n\treturn res;\n}\n\n\n\n/**\n * @namespace Basic:orDefault\n */\n\n/**\n * If an expression returns a non-value (undefined or null), use the default value instead.\n * Define a caster name, to force expression result/value into certain data type.\n *\n * @param {*} expression - the expression to evaluate\n * @param {*} defaultValue - the default value to use if the expression is considered empty\n * @param {?(String|Function)} [caster=null] - either a default caster by name ('str', 'string', 'int', 'integer', 'bool', 'boolean', 'float', 'arr', 'array') or a function getting the value and returning the transformed value\n * @param {?Array} [additionalEmptyValues=null] - if set, provides a list of additional values to be considered empty, apart from undefined and null\n * @returns {*} expression of defaultValue\n *\n * @memberof Basic:orDefault\n * @alias orDefault\n * @example\n * function set(name, value){\n * name = orDefault(name, 'kittens!', 'string', ['', 'none']);\n * value = orDefault(value, 42, 'int');\n * }\n */\nexport function orDefault(expression, defaultValue, caster=null, additionalEmptyValues=null){\n\tif( hasValue(additionalEmptyValues) ){\n\t\tadditionalEmptyValues = [].concat(additionalEmptyValues);\n\t} else {\n\t\tadditionalEmptyValues = [];\n\t}\n\n\tif( hasValue(caster) ){\n\t\tif(\n\t\t\t!isFunction(caster)\n\t\t\t&& ([\n\t\t\t\t'str', 'string',\n\t\t\t\t'int', 'integer',\n\t\t\t\t'bool', 'boolean',\n\t\t\t\t'float',\n\t\t\t\t'arr', 'array'\n\t\t\t].includes(`${caster.toLowerCase()}`))\n\t\t){\n\t\t\tcaster = `${caster}`.toLowerCase();\n\n\t\t\tif( ['str', 'string'].includes(caster) ){\n\t\t\t\tcaster = function(value){ return `${value}`; };\n\t\t\t} else if( ['int', 'integer'].includes(caster) ){\n\t\t\t\tcaster = function(value){ return parseInt(value, 10); };\n\t\t\t} else if( ['bool', 'boolean'].includes(caster) ){\n\t\t\t\tcaster = function(value){ return !!value; };\n\t\t\t} else if( caster === 'float' ){\n\t\t\t\tcaster = function(value){ return parseFloat(value); };\n\t\t\t} else if( ['arr', 'array'].includes(caster) ){\n\t\t\t\tcaster = function(value){ return [].concat(value); };\n\t\t\t}\n\t\t} else if( !isFunction(caster) ){\n\t\t\tcaster = function(value){ return value; };\n\t\t}\n\t} else {\n\t\tcaster = function(value){ return value; };\n\t}\n\n\tif( !hasValue(expression) || (additionalEmptyValues.includes(expression)) ){\n\t\treturn defaultValue;\n\t} else {\n\t\treturn caster(expression);\n\t}\n}\n\n\n\n/**\n * @namespace Basic:getType\n */\n\n/**\n * Prod-ready type detection for values, expanding on flawed typeof functionality, roughly following\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof, but expanding on\n * useful frontend types like \"htmldocument\", \"htmlelement\", \"htmlcollection\" and \"nodelist\"\n *\n * Types:\n * - \"undefined\"\n * - \"null\"\n * - \"boolean\"\n * - \"number\"\n * - \"bigint\"\n * - \"string\"\n * - \"symbol\"\n * - \"function\"\n * - \"object\"\n * - \"array\"\n * - \"date\"\n * - \"error\"\n * - \"generator\"\n * - \"iterator\"\n * - \"regexp\"\n * - \"set\"\n * - \"weakset\"\n * - \"map\"\n * - \"weakmap\"\n * - \"htmldocument\"\n * - \"htmlelement\"\n * - \"svgelement\"\n * - \"htmlcollection\"\n * - \"nodelist\"\n * - \"window\"\n * - \"url\"\n * - \"urlsearchparams\"\n *\n * @param {*} [value] - variable to check the type of\n * @returns {String} the value type in lower case\n *\n * @memberof Basic:getType\n * @alias getType\n * @example\n * if( getType(cb) === 'function' ){\n * ...\n * }\n */\nexport function getType(value) {\n\tif( !hasValue(value) ) return `${value}`.toLowerCase();\n\n\tconst deepType = Object.prototype.toString.call(value).slice(8,-1).toLowerCase();\n\n\tif( deepType === 'generatorfunction' ) return 'function';\n\tif( deepType === 'document' ) return 'htmldocument';\n\tif( deepType === 'element' ) return 'htmlelement';\n\tif( /^html.*element$/.test(deepType) ) return 'htmlelement';\n\tif( /^svg.*element$/.test(deepType) ) return 'svgelement';\n\tif( /^.*iterator$/.test(deepType) ) return 'iterator';\n\n\treturn deepType.match(/^(array|bigint|date|error|function|generator|regexp|symbol|set|weakset|map|weakmap|htmldocument|htmlcollection|nodelist|window|url|urlsearchparams)$/)\n\t\t? deepType\n\t\t: ((typeof value === 'object') || (typeof value === 'function')) ? 'object' : typeof value\n\t;\n}\n\n\n\n/**\n * @namespace Basic:isA\n */\n\n/**\n * Short form of \"getType\"-method with a more compact syntax.\n * Can identify all types listed in getType.\n *\n * @param {*} value - variable to check the type of\n * @param {String} type - the name of the type to check for, has to be a standard JS-type, is case insensitive\n * @returns {Boolean} target has type\n *\n * @memberof Basic:isA\n * @alias isA\n * @see getType\n * @example\n * let stringBool = (isA(test, 'boolean') && test) ? 'true' : 'false';\n */\nexport function isA(value, type){\n\tif(\n\t\t[\n\t\t\t'undefined',\n\t\t\t'null',\n\t\t\t'boolean',\n\t\t\t'number',\n\t\t\t'bigint',\n\t\t\t'string',\n\t\t\t'symbol',\n\t\t\t'function',\n\t\t\t'object',\n\t\t\t'array',\n\t\t\t'date',\n\t\t\t'error',\n\t\t\t'generator',\n\t\t\t'iterator',\n\t\t\t'regexp',\n\t\t\t'set',\n\t\t\t'weakset',\n\t\t\t'map',\n\t\t\t'weakmap',\n\t\t\t'htmldocument',\n\t\t\t'htmlelement',\n\t\t\t'svgelement',\n\t\t\t'htmlcollection',\n\t\t\t'nodelist',\n\t\t\t'window',\n\t\t\t'url',\n\t\t\t'urlsearchparams'\n\t\t].includes(`${type}`.toLowerCase())\n\t){\n\t\treturn getType(value) === `${type}`.toLowerCase();\n\t} else {\n\t\twarn(`${MODULE_NAME}:isA | \"${type}\" is not a recognized type`);\n\t\treturn false;\n\t}\n}\n\n\n\n/**\n * @namespace Basic:isBoolean\n */\n\n/**\n * Returns if a value is a boolean value.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a boolean\n *\n * @memberof Basic:isBoolean\n * @alias isBoolean\n * @example\n * if( isBoolean(val) ){\n * console.log('val must be either true or false');\n * }\n */\nexport function isBoolean(value){\n\treturn isA(value, 'boolean');\n}\n\n\n\n/**\n * @namespace Basic:isNumber\n */\n\n/**\n * Returns if a value is a number.\n *\n * Hint: to check numbers in more detail, use isInt, isFloat and isNaN\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a number\n *\n * @memberof Basic:isNumber\n * @alias isNumber\n * @see isInt\n * @see isFloat\n * @see isNaN\n * @example\n * if( isNumber(val) ){\n * result = val * 5;\n * }\n */\nexport function isNumber(value){\n\treturn isA(value, 'number');\n}\n\n\n\n/**\n * @namespace Basic:isBigInt\n */\n\n/**\n * Returns if a value is a BigInt value.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a BigInt\n *\n * @memberof Basic:isBigInt\n * @alias isBigInt\n * @example\n * if( isBigInt(val) ){\n * console.log('this is a really huge number!');\n * }\n */\nexport function isBigInt(value){\n\treturn isA(value, 'bigint');\n}\n\n\n\n/**\n * @namespace Basic:isInt\n */\n\n/**\n * Returns if a value is truly a real integer value and not just an int-parsable value for example.\n * Since JS only knows the data type \"number\" all numbers are usable as floats by default, but not the\n * other way round.\n *\n * @param {*} intVal - the value the check\n * @returns {Boolean} true if intVal is a true integer value\n *\n * @memberof Basic:isInt\n * @alias isInt\n * @example\n * if( !isInt(val) ){\n * val = parseInt(val, 10);\n * }\n */\nexport function isInt(intVal){\n\treturn parseInt(intVal, 10) === intVal;\n}\n\n\n\n/**\n * @namespace Basic:isFloat\n */\n\n/**\n * Returns if a value is a numeric value, usable as a float number in any calculation.\n * Any number that fulfills isInt, is also considered a valid float, which lies in JS's\n * nature of not differentiating ints and floats by putting them both into a \"number\"-type.\n * So ints are always floats, but not necessarily the other way round.\n *\n * @param {*} floatVal - the value to check\n * @returns {Boolean} true if floatVal is usable in a float context\n *\n * @memberof Basic:isFloat\n * @alias isFloat\n * @example\n * if( !isFloat(val) ){\n * alert('val can not be calculated with!');\n * }\n */\nexport function isFloat(floatVal){\n\treturn parseFloat(floatVal) === floatVal;\n}\n\n\n\n/**\n * @namespace Basic:isNaN\n */\n\n/**\n * Returns if an expression is NaN or not.\n * This method employs two different approaches:\n * By default it really checks if the expression is the _value_ NaN or not, this being a valid JS-value for something.\n * In JS this gets checked by comparing an expression with itself on identity, since NaN is the only value not being\n * identical to itself. If you set checkForIdentity to false, this method will use the standard JS-isNaN, which\n * inspects the expression, tries to cast or parse a number from it and returns the result.\n *\n * @param {*} expression - the expression to check\n * @param {Boolean} [checkForIdentity=true] - set to false if you want to use default JS-functionality\n * @returns {Boolean} true if expression is NaN\n *\n * @memberof Basic:isNaN\n * @alias isNaN\n * @example\n * if( !isNaN(suspiciousCalculatedValue) ){\n * return suspiciousCalculatedValue * 3;\n * }\n */\nexport function isNaN(expression, checkForIdentity=true){\n\tcheckForIdentity = orDefault(checkForIdentity, true, 'bool');\n\n\tif( checkForIdentity ){\n\t\treturn expression !== expression;\n\t} else {\n\t\treturn isNaN(expression);\n\t}\n}\n\n\n\n/**\n * @namespace Basic:isString\n */\n\n/**\n * Returns if a value is a string.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a string\n *\n * @memberof Basic:isString\n * @alias isString\n * @example\n * if( isString(val) ){\n * return prefix+val;\n * }\n */\nexport function isString(value){\n\treturn isA(value, 'string');\n}\n\n\n\n/**\n * @namespace Basic:isSymbol\n */\n\n/**\n * Returns if a value is a symbol.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a symbol\n *\n * @memberof Basic:isSymbol\n * @alias isSymbol\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol\n * @example\n * if( isSymbol(val) ){\n * return val.description;\n * }\n */\nexport function isSymbol(value){\n\treturn isA(value, 'symbol');\n}\n\n\n\n/**\n * @namespace Basic:isFunction\n */\n\n/**\n * Returns if a value is a function.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a function\n *\n * @memberof Basic:isFunction\n * @alias isFunction\n * @example\n * if( isFunction(val) ){\n * val();\n * }\n */\nexport function isFunction(value){\n\treturn isA(value, 'function');\n}\n\n\n\n/**\n * @namespace Basic:isObject\n */\n\n/**\n * Returns if a value is an object.\n *\n * Hint: if you explicitly want to check for a plain object, use isPlainObject\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is an object\n *\n * @memberof Basic:isObject\n * @alias isObject\n * @see isPlainObject\n * @example\n * if( isObject(val) ){\n * val.newProperty = 'foobar';\n * }\n */\nexport function isObject(value){\n\treturn isA(value, 'object');\n}\n\n\n\n/**\n * @namespace Basic:isPlainObject\n */\n\n/**\n * Returns if a value is an object literal, so so-called \"plain object.\n * A plain object is something like \"{hello : 'world'}\".\n *\n * This might especially be helpful when dealing with JSON configs, so quickly check if\n * something might even be parsed JSON (which in most cases is a plain object in js).\n *\n * Be aware that this function cannot differentiate between constructor-based simple objects and\n * plain objects declared inline. So, if someone took on the work to instantiate a base object and assign\n * properties either in a function or a constructor, we accept that as a plain object.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value seems to be a plain object\n *\n * @memberof Basic:isPlainObject\n * @alias isPlainObject\n * @example\n * const isParameterConfigObject = isPlainObject(param);\n */\nexport function isPlainObject(value){\n\treturn isObject(value)\n\t\t&& hasValue(value)\n\t\t&& (value.constructor === Object)\n\t\t&& Object.prototype.toString.call(value) === '[object Object]'\n\t;\n}\n\n\n\n/**\n * @namespace Basic:isArray\n */\n\n/**\n * Returns if a value is an array.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is an array\n *\n * @memberof Basic:isArray\n * @alias isArray\n * @example\n * if( isArray(val) ){\n * val.push('foobar');\n * }\n */\nexport function isArray(value){\n\treturn isA(value, 'array');\n}\n\n\n\n/**\n * @namespace Basic:isDate\n */\n\n/**\n * Returns if a value is a date.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a date\n *\n * @memberof Basic:isDate\n * @alias isDate\n * @example\n * if( isDate(val) ){\n * return val.toISOString();\n * }\n */\nexport function isDate(value){\n\treturn isA(value, 'date');\n}\n\n\n\n/**\n * @namespace Basic:isError\n */\n\n/**\n * Returns if a value is an error.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is an error\n *\n * @memberof Basic:isError\n * @alias isError\n * @example\n * if( isError(val) ){\n * return val.message;\n * }\n */\nexport function isError(value){\n\treturn isA(value, 'error');\n}\n\n\n\n/**\n * @namespace Basic:isGenerator\n */\n\n/**\n * Returns if a value is a generator.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a generator\n *\n * @memberof Basic:isGenerator\n * @alias isGenerator\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator\n * @example\n * if( isGenerator(val) ){\n * return val.return(val.next().value);\n * }\n */\nexport function isGenerator(value){\n\treturn isA(value, 'generator');\n}\n\n\n\n/**\n * @namespace Basic:isIterator\n */\n\n/**\n * Returns if a value is an iterator.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is an iterator\n *\n * @memberof Basic:isIterator\n * @alias isIterator\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator\n * @example\n * if( isIterator(val) ){\n * return val.next().value;\n * }\n */\nexport function isIterator(value){\n\treturn isA(value, 'iterator');\n}\n\n\n\n/**\n * @namespace Basic:isRegExp\n */\n\n/**\n * Returns if a value is a regular expression.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a regular expression\n *\n * @memberof Basic:isRegExp\n * @alias isRegExp\n * @example\n * if( isRegExp(val) ){\n * return val.test('foobar');\n * }\n */\nexport function isRegExp(value){\n\treturn isA(value, 'regexp');\n}\n\n\n\n/**\n * @namespace Basic:isSet\n */\n\n/**\n * Returns if a value is a set.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a set\n *\n * @memberof Basic:isSet\n * @alias isSet\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set\n * @example\n * if( isSet(val) ){\n * return val.has('foobar');\n * }\n */\nexport function isSet(value){\n\treturn isA(value, 'set');\n}\n\n\n\n/**\n * @namespace Basic:isWeakSet\n */\n\n/**\n * Returns if a value is a weak set.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a weak set\n *\n * @memberof Basic:isWeakSet\n * @alias isWeakSet\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet\n * @example\n * if( isWeakSet(val) ){\n * return val.has(someSymbol);\n * }\n */\nexport function isWeakSet(value){\n\treturn isA(value, 'weakset');\n}\n\n\n\n/**\n * @namespace Basic:isMap\n */\n\n/**\n * Returns if a value is a map.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a map\n *\n * @memberof Basic:isMap\n * @alias isMap\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map\n * @example\n * if( isMap(val) ){\n * return val.get('foobar');\n * }\n */\nexport function isMap(value){\n\treturn isA(value, 'map');\n}\n\n\n\n/**\n * @namespace Basic:isWeakMap\n */\n\n/**\n * Returns if a value is a weak map.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a weak map\n *\n * @memberof Basic:isWeakMap\n * @alias isWeakMap\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap\n * @example\n * if( isWeakMap(val) ){\n * return val.get('foobar');\n * }\n */\nexport function isWeakMap(value){\n\treturn isA(value, 'weakmap');\n}\n\n\n\n/**\n * @namespace Basic:isDocument\n */\n\n/**\n * Returns if a value is an HTML document.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is an HTML document\n *\n * @memberof Basic:isDocument\n * @alias isDocument\n * @example\n * if( isDocument(val) ){\n * return val.body;\n * }\n */\nexport function isDocument(value){\n\treturn isA(value, 'htmldocument');\n}\n\n\n\n/**\n * @namespace Basic:isElement\n */\n\n/**\n * Returns if a value is an HTML element.\n * Be aware, that this explicitly means an element, not necessarily any node.\n * So text nodes, comments and such do not qualify.\n * Also keep in mind, that SVGs are also something different.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is an HTML element\n *\n * @memberof Basic:isElement\n * @alias isElement\n * @example\n * if( isElement(target) ){\n * target.classList.add('foo');\n * }\n */\nexport function isElement(value){\n\treturn isA(value, 'htmlelement');\n}\n\n\n\n/**\n * @namespace Basic:isSvg\n */\n\n/**\n * Returns if a value is an SVG element.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is an SVG element\n *\n * @memberof Basic:isSvg\n * @alias isSvg\n * @example\n * if( isSvg(target) ){\n * target.querySelectorAll('path').remove();\n * }\n */\nexport function isSvg(value){\n\treturn isA(value, 'svgelement');\n}\n\n\n\n/**\n * @namespace Basic:isCollection\n */\n\n/**\n * Returns if a value is a collection of html elements.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a collection of html elements\n *\n * @memberof Basic:isCollection\n * @alias isCollection\n * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection\n * @example\n * if( isCollection(val) ){\n * return val.item(0);\n * }\n */\nexport function isCollection(value){\n\treturn isA(value, 'htmlcollection');\n}\n\n\n\n/**\n * @namespace Basic:isNodeList\n */\n\n/**\n * Returns if a value is a node list.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a node list\n *\n * @memberof Basic:isNodeList\n * @alias isNodeList\n * @see https://developer.mozilla.org/en-US/docs/Web/API/NodeList\n * @example\n * if( isNodeList(val) ){\n * return val.item(0);\n * }\n */\nexport function isNodeList(value){\n\treturn isA(value, 'nodelist');\n}\n\n\n\n/**\n * @namespace Basic:isWindow\n */\n\n/**\n * Returns if a value is a window.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a window\n *\n * @memberof Basic:isWindow\n * @alias isWindow\n * @example\n * if( isWindow(val) ){\n * return val.location.origin;\n * }\n */\nexport function isWindow(value){\n\treturn isA(value, 'window');\n}\n\n\n\n/**\n * @namespace Basic:isUrl\n */\n\n/**\n * Returns if a value is an URL object.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a URL object\n *\n * @memberof Basic:isUrl\n * @alias isUrl\n * @example\n * if( isUrl(val) ){\n * return val.path;\n * }\n */\nexport function isUrl(value){\n return isA(value, 'url');\n}\n\n\n\n/**\n * @namespace Basic:isUrlSearchParams\n */\n\n/**\n * Returns if a value is an URLSearchParams object.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a URLSearchParams object\n *\n * @memberof Basic:isUrlSearchParams\n * @alias isUrlSearchParams\n * @example\n * if( isUrlSearchParams(val) ){\n * val.set('query', 'foobar');\n * }\n */\nexport function isUrlSearchParams(value){\n return isA(value, 'urlsearchparams');\n}\n\n\n\n/**\n * @namespace Basic:isEventTarget\n */\n\n/**\n * Returns if a value is an EventTarget, which means that it is able to dispatch and receive events.\n * This is determined via duck-typing and not via class inheritance check, since this method is not\n * about type-safety, but the question if we can use the target for events, which is simply determined\n * by three essential object methods: addEventListener, removeEventListener and dispatchEvent. All\n * objects supporting these are fine with us.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value supports event methods\n *\n * @memberof Basic:isEventTarget\n * @alias isEventTarget\n * @example\n * if( isEventTarget(target) ){\n * target.dispatchEvent(new CustomEvent('foobar'));\n * }\n */\nexport function isEventTarget(value){\n\treturn hasValue(value)\n\t\t&& isFunction(value.addEventListener)\n\t\t&& isFunction(value.removeEventListener)\n\t\t&& isFunction(value.dispatchEvent)\n\t;\n}\n\n\n\n/**\n * @namespace Basic:isSelector\n */\n\n/**\n * Returns if a value is a valid selector, usable in methods such as querySelector\n * and querySelectorAll.\n *\n * @param {*} value - the value to check\n * @returns {Boolean} true if value is a valid selector\n *\n * @memberof Basic:isSelector\n * @alias isSelector\n * @example\n * if( isSelector(selector) ){\n * document.querySelector(selector)?.style.setProperty('color', 'red');\n * }\n */\nexport function isSelector(value){\n\t// almost all values like \"null\", \"undefined\" and \"NaN\" are accepted querySelectors, numbers are not\n\tvalue = orDefault(value, 0, 'str');\n\n\tconst fragment = document.createDocumentFragment();\n\n\ttry {\n\t\tfragment.querySelector(value);\n\t} catch(ex){\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n\n\n/**\n * @namespace Basic:isPotentialId\n */\n\n/**\n * Determines if a given value is potentially a valid id for something, because it matches a format of given\n * prefix, postfix and id regex. \"Potential\", because we can only assume by the format, we do not actually know\n * if the id really matches anything like a database entry for example.\n *\n * @param {(String|Number)} value - the value to test, will be stringified\n * @param {?String} [prefix=''] - a prefix for the id\n * @param {?String} [idRex='[1-9][0-9]*'] - the regex string to use to identify the id part of the value\n * @param {?String} [postfix=''] - a postfix for the id\n * @param {?Boolean} [maskFixes=true] - usually, prefixes are not treated as regexes and are automatically masked, if you'd like to define complex pre- and postfixes using regexes, set this to false\n * @returns {String|Boolean} if value is potential id according to format, the id is returned as a string (still usable as a truthy value), otherwise the return value is false\n *\n * @memberof Basic:isPotentialId\n * @alias isPotentialId\n * @example\n * if( isPotentialId(id, 'test_(', '[0-9]+', ')') ){\n * createJsonRequest(`/backend/${id}`).then(() => { alert('done'); });\n * }\n */\nexport function isPotentialId(value, prefix='', idRex='[1-9][0-9]*', postfix='', maskFixes=true){\n\tvalue = `${value}`;\n\tprefix = orDefault(prefix, '', 'str');\n\tidRex = orDefault(idRex, '[1-9][0-9]*', 'str');\n\tpostfix = orDefault(postfix, '', 'str');\n\tmaskFixes = orDefault(maskFixes, true, 'bool');\n\n\tconst mask = str => `${str}`.replace(/([\\-\\[\\]\\/{}()*+?.\\\\^$|])/g, \"\\\\$&\");\n\n\tlet rex;\n\tif( maskFixes ){\n\t\trex = new RegExp(`^${mask(prefix)}(${idRex})${mask(postfix)}$`);\n\t} else {\n\t\trex = new RegExp(`^${prefix}(${idRex})${postfix}$`);\n\t}\n\n\tconst matches = rex.exec(value);\n\treturn hasValue(matches) ? matches[1] : false;\n}\n\n\n\n/**\n * @namespace Basic:min\n */\n\n/**\n * Checks if a value is larger than a minimum and returns\n * the value or the lower bound respectively.\n *\n * Accepts all values comparable with >.\n *\n * @param {*} value - the value to check\n * @param {*} minValue - the lower bound\n * @returns {*} value or minValue\n *\n * @memberof Basic:min\n * @alias min\n * @example\n * let croppedVal = min(value, 0);\n */\nexport function min(value, minValue){\n\treturn (value < minValue) ? minValue : value;\n}\n\n\n\n/**\n * @namespace Basic:max\n */\n\n/**\n * Checks if a value is smaller than a maximum and returns\n * the value or the upper bound respectively.\n *\n * Accepts all values comparable with <.\n *\n * @param {*} value - the value to check\n * @param {*} maxValue - the upper bound\n * @returns {*} value or maxValue\n *\n * @memberof Basic:max\n * @alias max\n * @example\n * let croppedVal = max(value, 100);\n */\nexport function max(value, maxValue){\n\treturn (value > maxValue) ? maxValue : value;\n}\n\n\n\n/**\n * @namespace Basic:minMax\n */\n\n/**\n * Checks if a value is within bounds of a minimum and maximum and returns\n * the value or the upper or lower bound respectively.\n *\n * Accepts all values comparable with > and <.\n *\n * @param {*} minValue - the lower bound\n * @param {*} value - the value to check\n * @param {*} maxValue - the upper bound\n * @throws error if minValue is not smaller than maxValue\n * @returns {*} value, minValue or maxValue\n *\n * @memberof Basic:minMax\n * @alias minMax\n * @example\n * let croppedVal = minMax(-100, value, 100);\n */\nexport function minMax(minValue, value, maxValue){\n\tconst __methodName__ = 'minMax';\n\n\tassert(minValue <= maxValue, `${MODULE_NAME}:${__methodName__} | minValue can not be larger than maxValue`);\n\n\treturn min(max(value, maxValue), minValue);\n}\n\n\n\n/**\n * @namespace Basic:round\n */\n\n/**\n * Rounds a number to a defined precision.\n *\n * Precision 0 rounds to full number.\n *\n * @param {Number} number - the number to round\n * @param {?Number} [precision=0] - the number of digits after the floating point to round to\n * @returns {Number} rounded number\n *\n * @memberof Basic:round\n * @alias round\n * @example\n * let roundedValue = round(666.66);\n * => 667\n * let roundedValue = round(0.5555555, 3);\n * => 0.556\n */\nexport function round(number, precision=0){\n\tnumber = parseFloat(number);\n\tprecision = min(orDefault(precision, 0, 'int'), 0);\n\n\tconst power = Math.pow(10, precision);\n\n\treturn Math.round(parseFloat(number) * power) / power;\n}\n\n\n\n/**\n * @namespace Basic:Deferred\n */\n\n/**\n * @typedef Deferred\n * @type {Object}\n *\n * @property {Promise} promise - the wrapped promise\n * @property {Function} resolve - resolves the wrapped promise with given value\n * @property {Function} reject - rejects the wrapped promise with given error\n * @property {Function} then - defines a success handler for the wrapped promise and returns its result\n * @property {Function} catch - defines an error handler for the wrapped promise and returns its result\n * @property {Function} finally - defines a \"settled\" handler for the wrapped promise and returns its result\n * @property {String} status - holds the current resolution status, can either be \"pending\", \"fulfilled\" or \"rejected\"\n * @property {Function} isSettled - returns true, if the Deferred is either \"fulfilled\" or \"rejected\"\n * @property {?*} [provision=null] - may contain (a) provisional value(s) to use for a newly instantiated Deferred, before it has resolved to the actual value(s)\n *\n * @memberof Basic\n */\n\n/**\n * Class that wraps a Promise, to allow resolving and rejecting outside the\n * Promise's function scope. This allows for decoupled handling of states and\n * handling promises as references in a distributed context, like a class, where\n * a Deferred might then represent an async state.\n *\n * Deferreds also provide accessible status information, normal Promises do not have.\n * Accessing the \"status\" property returns the current status, being either \"pending\",\n * \"fulfilled\" or \"rejected\". You may also check if the Deferred has been settled via\n * \"isSettled()\". If you want to provide a preliminary result, available before the\n * promise has settled, you may set this result as a payload using the \"provision\" property.\n *\n * This follows ideas by jQuery and Q Promises:\n * - https://api.jquery.com/jQuery.Deferred/\n * - https://github.com/kriskowal/q/wiki/Coming-from-jQuery#deferreds-promises-resolvers\n *\n * Keep in mind, that Promises might need a polyfill such as core-js.\n *\n * For details, see class documentation below.\n *\n * @memberof Basic:Deferred\n * @name Deferred\n * @see Basic.Deferred\n * @example\n * const doStuff = new Deferred();\n * doStuff.provision = 'provisional value';\n * doStuff\n * .then(value => { alert(`yeah, ready with \"${value}\"!`); })\n * .catch(error => { console.error(error); })\n * .finally(() => { console.info('has been settled'); })\n * ;\n * if( foobar === 42 ){\n * doStuff.resolve(42);\n * } else {\n * doStuff.reject(new Error('not 42!'));\n * }\n * console.info(doStuff.status);\n */\nexport class Deferred {\n\n\tconstructor(){\n\t\tconst\n\t\t\tSTATUS_PENDING = 'pending',\n\t\t\tSTATUS_FULFILLED = 'fulfilled',\n\t\t\tSTATUS_REJECTED = 'rejected'\n\t\t;\n\t\tthis.resolve = null;\n\t\tthis.reject = null;\n\t\tthis.provision = null;\n\t\tthis.status = STATUS_PENDING;\n\t\tthis.isSettled = () => [STATUS_FULFILLED, STATUS_REJECTED].includes(this.status);\n\t\tthis.promise = new Promise((resolve, reject) => {\n\t\t\tthis.resolve = resolution => {\n\t\t\t\tthis.status = STATUS_FULFILLED;\n\t\t\t\tresolve(resolution);\n\t\t\t};\n\t\t\tthis.reject = rejection => {\n\t\t\t\tthis.status = STATUS_REJECTED;\n\t\t\t\treject(rejection);\n\t\t\t};\n\t\t});\n\t}\n\n\tthen(f){\n\t\treturn this.promise.then(f);\n\t}\n\n\tcatch(f){\n\t\treturn this.promise.catch(f);\n\t}\n\n\tfinally(f){\n\t\treturn this.promise.finally(f);\n\t}\n\n}\n\n\n\n/**\n * @namespace Basic:Observable\n */\n\n/**\n * @typedef Observable\n * @type {Object}\n *\n * @property {Function} getValue - returns the current value\n * @property {Function} setValue - sets a new value, which will subsequently trigger all subscriptions\n * @property {Function} subscribe - register a given function to be executed on any value change, the subscription receives the new and the old value on each execution, returns the subscription value, which can later be used to unsubscribe again\n * @property {Function} unsubscribe - removes a given subscription again, use subscription value returned by subscribe here\n *\n * @memberof Basic\n */\n\n/**\n * A class offering the bare minimum feature set to observe a value and subscribe to future value changes.\n * No automatic magic going on here, this simply follows a basic subscription pattern, where each subscription is\n * a function, being called with a newly set value. This closely resembles the kind of observables knockout is using.\n *\n * For details, see class documentation below.\n *\n * @memberof Basic:Observable\n * @name Observable\n * @see Basic.Observable\n * @example\n * const status = new Observable('ok');\n * const subscription = status.subscribe(s => {\n * console.log(`status changed to: ${s}`);\n * });\n * status.setValue('oh noez');\n * status.unsubscribe(subscription);\n */\nexport class Observable {\n\n\t#__className__ = 'Observable';\n\t#value;\n\t#subscriptions;\n\n\tconstructor(initialValue){\n\t\tthis.#value = initialValue;\n\t\tthis.#subscriptions = [];\n\t}\n\n\tgetValue(){\n\t\treturn this.#value;\n\t}\n\n\tsetValue(newValue, force=false){\n\t\tconst\n\t\t\toldValue = this.#value,\n\t\t\tisNewValue = oldValue !== newValue\n\t\t;\n\t\tthis.#value = newValue;\n\t\tif( isNewValue || force ){\n\t\t\tthis.#subscriptions.forEach(s => s(newValue, oldValue));\n\t\t}\n\t}\n\n\tsubscribe(subscription){\n\t\tconst __methodName__ = 'subscribe';\n\t\tassert(isFunction(subscription), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | subscription must be function`);\n\t\tif( this.#subscriptions.indexOf(subscription) < 0 ){\n\t\t\tthis.#subscriptions = [...this.#subscriptions, subscription];\n\t\t}\n\t\treturn subscription;\n\t}\n\n\tunsubscribe(subscription){\n\t\tthis.#subscriptions = this.#subscriptions.filter(s => s !== subscription);\n\t}\n\n\ttoString(){\n\t\treturn `${this.#value}`;\n\t}\n\n}\n"]} \ No newline at end of file diff --git a/dist/context.js b/dist/context.js index c7ea7996..b667d0b9 100644 --- a/dist/context.js +++ b/dist/context.js @@ -1,5 +1,5 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Context diff --git a/dist/context.js.map b/dist/context.js.map index 28e2070b..c788b60a 100644 --- a/dist/context.js.map +++ b/dist/context.js.map @@ -1 +1 @@ -{"version":3,"file":"context.js","names":["MODULE_NAME","hasValue","isFunction","isArray","orDefault","Observable","throttle","reschedule","INTERACTION_TYPE_DETECTION","touchHappening","touchEndingTimer","touchStartHandler","CURRENT_INTERACTION_TYPE","getValue","setValue","touchEndHandler","blurHandler","mouseMoveHandler","browserSupportsHistoryManipulation","window","history","pushState","replaceState","contextHasHighDpi","matchMedia","matches","getBrowserScrollbarWidth","sandbox","document","createElement","style","visibility","opacity","pointerEvents","overflow","position","top","right","left","height","scrollbarEnforcer","width","appendChild","body","scrollbarWidth","offsetWidth","removeChild","detectInteractionType","returnObservable","navigator","maxTouchPoints","addEventListener","detectAppleDevice","additionalTest","family","exec","userAgent","deviceType","Array","length","platform","getBrowserLanguage","fallbackLanguage","language","languages","browserLanguages","from","forEach","browserLanguagePropertyKey","browserLanguage","languageParts","split","toLowerCase","trim","country","toUpperCase","getLocale","element","documentElement","locale","code","isFallback","langAttr","getAttribute","localeParts","getBrowserLocale"],"sources":["context.js"],"mappings":"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","sourcesContent":["/*!\n * Module Context\n */\n\n/**\n * @namespace Context\n */\n\nconst MODULE_NAME = 'Context';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {hasValue, isFunction, isArray, orDefault, Observable} from './basic.js';\nimport {throttle} from './functions.js';\nimport {reschedule} from './timers.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst INTERACTION_TYPE_DETECTION = {\n\ttouchHappening : false,\n\ttouchEndingTimer : null,\n\ttouchStartHandler(){\n\t\tINTERACTION_TYPE_DETECTION.touchHappening = true;\n\t\tif( CURRENT_INTERACTION_TYPE.getValue() !== 'touch' ){\n\t\t\tCURRENT_INTERACTION_TYPE.setValue('touch');\n\t\t}\n\t},\n\ttouchEndHandler(){\n\t\tINTERACTION_TYPE_DETECTION.touchEndingTimer = reschedule(INTERACTION_TYPE_DETECTION.touchEndingTimer, 1032, () => {\n\t\t\tINTERACTION_TYPE_DETECTION.touchHappening = false;\n\t\t});\n\t},\n\tblurHandler(){\n\t\tINTERACTION_TYPE_DETECTION.touchEndingTimer = reschedule(INTERACTION_TYPE_DETECTION.touchEndingTimer, 1032, () => {\n\t\t\tINTERACTION_TYPE_DETECTION.touchHappening = false;\n\t\t});\n\t},\n\tmouseMoveHandler : throttle(1000, function(){\n\t\tif( (CURRENT_INTERACTION_TYPE.getValue('pointer')) && !INTERACTION_TYPE_DETECTION.touchHappening ){\n\t\t\tCURRENT_INTERACTION_TYPE.setValue('pointer');\n\t\t}\n\t})\n};\n\nexport let CURRENT_INTERACTION_TYPE;\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Context:browserSupportsHistoryManipulation\n */\n\n/**\n * Detects if the browser supports history manipulation, by checking the most common\n * methods for presence in the history-object.\n *\n * @returns {Boolean} true if browser seems to support history manipulation\n *\n * @memberof Context:browserSupportsHistoryManipulation\n * @alias browserSupportsHistoryManipulation\n * @example\n * if( browserSupportsHistoryManipulation() ){\n * window.history.replaceState(null, 'test', '/test');\n * }\n */\nexport function browserSupportsHistoryManipulation(){\n\treturn hasValue(window.history)\n\t\t&& isFunction(window.history.pushState)\n\t\t&& isFunction(window.history.replaceState)\n\t;\n}\n\n\n\n/**\n * @namespace Context:contextHasHighDpi\n */\n\n/**\n * Checks if the context would benefit from high DPI graphics.\n *\n * @returns {Boolean} true if device has high DPI, false if not or browser does not support media queries\n *\n * @memberof Context:contextHasHighDpi\n * @alias contextHasHighDpi\n * @example\n * if( contextHasHighDpi() ){\n * document.querySelectorAll('img').forEach(img => {\n * img.setAttribute('src', img.getAttribute('src').replace('.jpg', '@2x.jpg'));\n * });\n * }\n */\nexport function contextHasHighDpi(){\n\tif( window.matchMedia ){\n\t\treturn window.matchMedia(\n\t\t\t'only screen and (-webkit-min-device-pixel-ratio: 1.5),'\n\t\t\t+'only screen and (-o-min-device-pixel-ratio: 3/2),'\n\t\t\t+'only screen and (min--moz-device-pixel-ratio: 1.5),'\n\t\t\t+'only screen and (min-device-pixel-ratio: 1.5),'\n\t\t\t+'only screen and (min-resolution: 144dpi),'\n\t\t\t+'only screen and (min-resolution: 1.5dppx)'\n\t\t).matches;\n\t} else {\n\t\treturn false;\n\t}\n}\n\n\n\n/**\n * @namespace Context:getBrowserScrollbarWidth\n */\n\n/**\n * Returns the current context's scrollbar width. Returns 0 if scrollbar is over content.\n * There are edge cases in which we might want to calculate positions in respect to the\n * actual width of the scrollbar. For example when working with elements with a 100vw width.\n *\n * This method temporarily inserts three elements into the body while forcing the body to\n * actually show scrollbars, measuring the difference between 100vw and 100% on the body and\n * returns the result.\n *\n * @returns {Number} the width of the body scrollbar in pixels\n *\n * @memberof Context:getBrowserScrollbarWidth\n * @alias getBrowserScrollbarWidth\n * @example\n * foobarElement.style.width = `calc(100vw - ${getBrowserScrollbarWidth()}px)`;\n */\nexport function getBrowserScrollbarWidth(){\n\tconst sandbox = document.createElement('div');\n\tsandbox.style.visibility = 'hidden';\n\tsandbox.style.opacity = '0';\n\tsandbox.style.pointerEvents = 'none';\n\tsandbox.style.overflow = 'scroll';\n\tsandbox.style.position = 'fixed';\n\tsandbox.style.top = '0';\n\tsandbox.style.right = '0';\n\tsandbox.style.left = '0';\n\t// firefox needs container to be at least 30px high to display scrollbar\n\tsandbox.style.height = '50px';\n\n\tconst scrollbarEnforcer = document.createElement('div');\n\tscrollbarEnforcer.style.width = '100%';\n\tscrollbarEnforcer.style.height = '100px';\n\n\tsandbox.appendChild(scrollbarEnforcer);\n\tdocument.body.appendChild(sandbox);\n\n\tconst scrollbarWidth = sandbox.offsetWidth - scrollbarEnforcer.offsetWidth;\n\n\tdocument.body.removeChild(sandbox);\n\n\treturn scrollbarWidth;\n}\n\n\n\n/**\n * @namespace Context:detectInteractionType\n */\n\n/**\n * Try to figure out the current type of interaction between the user and the document.\n * This is determined by the input device and is currently limited to either \"pointer\" or \"touch\".\n *\n * On call the function returns an educated guess about the fact what interaction type might be more\n * probable based on browser features and sets up event listeners to update Context module's CURRENT_INTERACTION_TYPE\n * observable (to which you may subscribe to be informed about updates), when interaction type should change while\n * the page is being interacted with. In case a touch occurs we determine touch interaction and\n * on mousemove we determine pointer interaction. If you use this observable to set up a class on your document for\n * example you can even relatively safely handle dual devices like a surface book.\n *\n * Hint: because touch devices also emit a single mousemove after touchend with a single touch we have to block\n * mousemove detection for 1s after the last touchend. Therefore, it takes up to 1s after the last touch event until\n * we are able to detect the change to a pointer device.\n *\n * @param {?Boolean} [returnObservable=false] - if set to true, the call returns Context module's CURRENT_INTERACTION_TYPE observable\n * @returns {String|Basic.Observable} interaction type string \"pointer\" or \"touch\", or the CURRENT_INTERACTION_TYPE observable\n *\n * @memberof Context:detectInteractionType\n * @alias detectInteractionType\n * @example\n * let interactionTypeGuess = detectInteractionType();\n * detectInteractionType(true).subscribe(function(type){\n * document.body.classList.toggle('touch', type === 'touch');\n * });\n */\n\nexport function detectInteractionType(returnObservable=false){\n\treturnObservable = orDefault(returnObservable, false, 'bool');\n\n\tif( !hasValue(CURRENT_INTERACTION_TYPE) ){\n\t\tCURRENT_INTERACTION_TYPE = new Observable('');\n\t\tif( ('ontouchstart' in document) && ('ontouchend' in document) && (window.navigator.maxTouchPoints > 0) ){\n\t\t\tCURRENT_INTERACTION_TYPE.setValue('touch');\n\t\t} else {\n\t\t\tCURRENT_INTERACTION_TYPE.setValue('pointer');\n\t\t}\n\n\t\tdocument.addEventListener('touchstart', INTERACTION_TYPE_DETECTION.touchStartHandler);\n\t\tdocument.addEventListener('touchend', INTERACTION_TYPE_DETECTION.touchEndHandler);\n\t\twindow.addEventListener('blur', INTERACTION_TYPE_DETECTION.blurHandler);\n\t\tdocument.addEventListener('mousemove', INTERACTION_TYPE_DETECTION.mouseMoveHandler);\n\t}\n\n\treturn returnObservable ? CURRENT_INTERACTION_TYPE : CURRENT_INTERACTION_TYPE.getValue();\n}\n\n\n\n/**\n * @namespace Context:detectAppleDevice\n */\n\n/**\n * Try to determine if the execution context is an Apple device and if so: which type.\n *\n * We use an escalating test starting with the user agent and then, as a fallback, checking the platform value\n * to determine the general device class (iPhone, iPad ,iPod ,Macintosh). If we get a Macintosh, we double check\n * if the device might be a falsely reporting iPad with iPadOS13+.\n *\n * You can hook up additional tests by providing an \"additionalTest\" function as a function parameter,\n * that function takes the evaluated device type at the end of the function and expects a new device type to be\n * returned. Using this, you can tap into the process and handle edge cases yourself.\n *\n * @param {?Function} [additionalTest=null] - if set, is executed after determining the device type, takes the current device type as parameter and is expected to return a new one; use this to add edge case tests to overwrite the result in certain conditions\n * @returns {String} \"ipad\", \"iphone\", \"ipod\" or \"mac\"\n *\n * @memberof Context:detectAppleDevice\n * @alias detectAppleDevice\n * @example\n * const IS_IOS_DEVICE = ['iphone', 'ipod', 'ipad'].includes(detectAppleDevice());\n */\nexport function detectAppleDevice(additionalTest=null){\n\tlet\n\t\tfamily = /iPhone|iPad|iPod|Macintosh/.exec(window.navigator.userAgent),\n\t\tdeviceType = null\n\t;\n\n\tif( Array.isArray(family) && (family.length > 0) ){\n\t\tfamily = family[0];\n\t} else {\n\t\tfamily = /^(iPhone|iPad|iPod|Mac)/.exec(window.navigator.platform);\n\n\t\tif( Array.isArray(family) && (family.length > 0) ){\n\t\t\tfamily = family[0];\n\n\t\t\tif( family === 'Mac' ){\n\t\t\t\tfamily = 'Macintosh';\n\t\t\t}\n\t\t} else {\n\t\t\tfamily = null;\n\t\t}\n\t}\n\n\tif( hasValue(family) ){\n\t\t// If User-Agent reports Macintosh double check this against touch points, since the device might\n\t\t// be a disguised iPad with i(Pad)Os13+\n\t\tif(\n\t\t\t(family === 'Macintosh')\n\t\t\t&& (window.navigator.maxTouchPoints > 1)\n\t\t){\n\t\t\tfamily = 'iPad';\n\t\t}\n\n\t\tswitch( family ) {\n\t\t\tcase 'iPad':\n\t\t\t\tdeviceType = 'ipad';\n\t\t\tbreak;\n\t\t\tcase 'iPhone':\n\t\t\t\tdeviceType = 'iphone';\n\t\t\tbreak;\n\t\t\tcase 'iPod':\n\t\t\t\tdeviceType = 'ipod';\n\t\t\tbreak;\n\t\t\tcase 'Macintosh':\n\t\t\t\tdeviceType = 'mac';\n\t\t\tbreak;\n\t\t}\n\n\t\tif( isFunction(additionalTest) ){\n\t\t\tdeviceType = additionalTest(deviceType);\n\t\t}\n\t}\n\n\treturn deviceType;\n}\n\n\n\n/**\n * @namespace Context:getBrowserLanguage\n */\n\n/**\n * Evaluates all available browser languages and tries to return the preferred one.\n *\n * Since browsers could not agree on a uniform way to return language values yet, the returned language\n * will always be \"lowercaselanguage-UPPERCASECOUNTRY\" or just \"lowercaselanguage\", if we have no country.\n *\n * @param {?String} [fallbackLanguage=null] - fallback value to return if no language could be evaluated\n * @returns {String|null} the preferred browser language if available, null if no language can be detected and no fallback has been defined\n *\n * @memberof Context:getBrowserLanguage\n * @alias getBrowserLanguage\n * @see getBrowserLocale\n * @example\n * getBrowserLanguage()\n * => \"en\"\n */\nexport function getBrowserLanguage(fallbackLanguage=null){\n\tlet language = null;\n\n\tif( hasValue(window.navigator.languages) ){\n\t\tconst browserLanguages = Array.from(window.navigator.languages);\n\t\tif( isArray(browserLanguages) && (browserLanguages.length > 0) ){\n\t\t\tlanguage = `${browserLanguages[0]}`;\n\t\t}\n\t}\n\n\tif( !hasValue(language) ){\n\t\t['language', 'browserLanguage', 'userLanguage', 'systemLanguage'].forEach(browserLanguagePropertyKey => {\n\t\t\tif( !hasValue(language) ){\n\t\t\t\tconst browserLanguage = window.navigator[browserLanguagePropertyKey];\n\t\t\t\tlanguage = hasValue(browserLanguage) ? `${browserLanguage}` : null;\n\t\t\t}\n\t\t});\n\t}\n\n\tif( !hasValue(language) && hasValue(fallbackLanguage) ){\n\t\tlanguage = `${fallbackLanguage}`;\n\t}\n\n\tconst languageParts = language.split('-');\n\tlanguage = languageParts[0].toLowerCase().trim();\n\tconst country = languageParts?.[1]?.toUpperCase()?.trim();\n\tlanguage = hasValue(country) ? `${language}-${country}` : language;\n\n\treturn language;\n}\n\n\n\n/**\n * @namespace Context:getLocale\n */\n\n/**\n * Evaluates the document's locale by having a look at the HTML element's lang-attribute.\n *\n * Since browsers could not agree on a uniform way to return locale values yet, the returned \"code\" will always be\n * \"lowercaselanguage-UPPERCASECOUNTRY\" (or just \"lowercaselanguage\", if we have no country), regardless of how the\n * browser returns the value, while \"country\" and \"language\" will always be lower case.\n *\n * @param {?HTMLElement} [element=document.documentElement] - the element holding the lang-attribute to evaluate\n * @param {?String} [fallbackLanguage=null] - if defined, a fallback lang value if element holds no lang information\n * @returns {Object} the locale as an object, having the lang value as \"code\", the split-up parts in \"country\" and \"language\" (if available) and \"isFallback\" to tell us if the fallback had to be used\n *\n * @memberof Context:getLocale\n * @alias getLocale\n * @see getBrowserLocale\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang\n * @example\n * getLocale()\n * => {\n * code : 'en-GB',\n * country : 'gb',\n * language : 'en',\n * isFallback : false\n * }\n * getLocale(document.querySelector('p'), 'en-US')\n * => {\n * code : 'en-US',\n * country : 'us',\n * language : 'en',\n * isFallback : true\n * }\n */\nexport function getLocale(element=null, fallbackLanguage=null){\n\t// document.documentElement not as function default to prevent errors in document-less context on import\n\telement = orDefault(element, document.documentElement);\n\n\tconst locale = {\n\t\tcode : null,\n\t\tcountry : null,\n\t\tlanguage : null,\n\t\tisFallback : false\n\t};\n\n\tlet langAttr = isFunction(element.getAttribute) ? element.getAttribute('lang') : null;\n\tif( !hasValue(langAttr) && hasValue(fallbackLanguage) ){\n\t\tlangAttr = `${fallbackLanguage}`;\n\t\tlocale.isFallback = true;\n\t}\n\n\tif( hasValue(langAttr) ){\n\t\tconst localeParts = `${langAttr}`.split('-');\n\t\tlocale.country = localeParts?.[1]?.toLowerCase()?.trim();\n\t\tlocale.language = localeParts[0].toLowerCase().trim();\n\t\tlocale.code = hasValue(locale.country) ? `${locale.language}-${locale.country.toUpperCase()}` : locale.language;\n\t}\n\n\treturn locale;\n}\n\n\n\n/**\n * @namespace Context:getBrowserLocale\n */\n\n/**\n * Evaluates the browser's locale by having a look at the preferred browser language, as reported by `getBrowserLanguage`.\n *\n * Since browsers could not agree on a uniform way to return locale values yet, the returned \"code\" will always be\n * \"lowercaselanguage-UPPERCASECOUNTRY\" (or just \"lowercaselanguage\", if we have no country), regardless of how the\n * browser returns the value, while \"country\" and \"language\" will always be lower case.\n *\n * @param {?String} [fallbackLanguage=null] - if defined, a fallback lang value if browser reports no preferred language\n * @returns {Object} the locale as an object, having the in \"country\" and \"language\" (if available) and \"isFallback\" to tell us if the fallback had to be used\n *\n * @memberof Context:getBrowserLocale\n * @alias getBrowserLocale\n * @see getBrowserLanguage\n * @example\n * getBrowserLocale()\n * => {\n * code : 'en-GB',\n * country : 'gb',\n * language : 'en',\n * isFallback : false\n * }\n * getBrowserLocale('en-US')\n * => {\n * code : 'en-US',\n * country : 'us',\n * language : 'en',\n * isFallback : true\n * }\n */\nexport function getBrowserLocale(fallbackLanguage=null){\n\treturn getLocale({getAttribute(){ return getBrowserLanguage(fallbackLanguage); }}, fallbackLanguage);\n}\n"]} \ No newline at end of file +{"version":3,"file":"context.js","names":["MODULE_NAME","hasValue","isFunction","isArray","orDefault","Observable","throttle","reschedule","INTERACTION_TYPE_DETECTION","touchHappening","touchEndingTimer","touchStartHandler","CURRENT_INTERACTION_TYPE","getValue","setValue","touchEndHandler","blurHandler","mouseMoveHandler","browserSupportsHistoryManipulation","window","history","pushState","replaceState","contextHasHighDpi","matchMedia","matches","getBrowserScrollbarWidth","sandbox","document","createElement","style","visibility","opacity","pointerEvents","overflow","position","top","right","left","height","scrollbarEnforcer","width","appendChild","body","scrollbarWidth","offsetWidth","removeChild","detectInteractionType","returnObservable","navigator","maxTouchPoints","addEventListener","detectAppleDevice","additionalTest","family","exec","userAgent","deviceType","Array","length","platform","getBrowserLanguage","fallbackLanguage","language","languages","browserLanguages","from","forEach","browserLanguagePropertyKey","browserLanguage","languageParts","split","toLowerCase","trim","country","toUpperCase","getLocale","element","documentElement","locale","code","isFallback","langAttr","getAttribute","localeParts","getBrowserLocale"],"sources":["context.js"],"mappings":"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","ignoreList":[],"sourcesContent":["/*!\n * Module Context\n */\n\n/**\n * @namespace Context\n */\n\nconst MODULE_NAME = 'Context';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {hasValue, isFunction, isArray, orDefault, Observable} from './basic.js';\nimport {throttle} from './functions.js';\nimport {reschedule} from './timers.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst INTERACTION_TYPE_DETECTION = {\n\ttouchHappening : false,\n\ttouchEndingTimer : null,\n\ttouchStartHandler(){\n\t\tINTERACTION_TYPE_DETECTION.touchHappening = true;\n\t\tif( CURRENT_INTERACTION_TYPE.getValue() !== 'touch' ){\n\t\t\tCURRENT_INTERACTION_TYPE.setValue('touch');\n\t\t}\n\t},\n\ttouchEndHandler(){\n\t\tINTERACTION_TYPE_DETECTION.touchEndingTimer = reschedule(INTERACTION_TYPE_DETECTION.touchEndingTimer, 1032, () => {\n\t\t\tINTERACTION_TYPE_DETECTION.touchHappening = false;\n\t\t});\n\t},\n\tblurHandler(){\n\t\tINTERACTION_TYPE_DETECTION.touchEndingTimer = reschedule(INTERACTION_TYPE_DETECTION.touchEndingTimer, 1032, () => {\n\t\t\tINTERACTION_TYPE_DETECTION.touchHappening = false;\n\t\t});\n\t},\n\tmouseMoveHandler : throttle(1000, function(){\n\t\tif( (CURRENT_INTERACTION_TYPE.getValue('pointer')) && !INTERACTION_TYPE_DETECTION.touchHappening ){\n\t\t\tCURRENT_INTERACTION_TYPE.setValue('pointer');\n\t\t}\n\t})\n};\n\nexport let CURRENT_INTERACTION_TYPE;\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Context:browserSupportsHistoryManipulation\n */\n\n/**\n * Detects if the browser supports history manipulation, by checking the most common\n * methods for presence in the history-object.\n *\n * @returns {Boolean} true if browser seems to support history manipulation\n *\n * @memberof Context:browserSupportsHistoryManipulation\n * @alias browserSupportsHistoryManipulation\n * @example\n * if( browserSupportsHistoryManipulation() ){\n * window.history.replaceState(null, 'test', '/test');\n * }\n */\nexport function browserSupportsHistoryManipulation(){\n\treturn hasValue(window.history)\n\t\t&& isFunction(window.history.pushState)\n\t\t&& isFunction(window.history.replaceState)\n\t;\n}\n\n\n\n/**\n * @namespace Context:contextHasHighDpi\n */\n\n/**\n * Checks if the context would benefit from high DPI graphics.\n *\n * @returns {Boolean} true if device has high DPI, false if not or browser does not support media queries\n *\n * @memberof Context:contextHasHighDpi\n * @alias contextHasHighDpi\n * @example\n * if( contextHasHighDpi() ){\n * document.querySelectorAll('img').forEach(img => {\n * img.setAttribute('src', img.getAttribute('src').replace('.jpg', '@2x.jpg'));\n * });\n * }\n */\nexport function contextHasHighDpi(){\n\tif( window.matchMedia ){\n\t\treturn window.matchMedia(\n\t\t\t'only screen and (-webkit-min-device-pixel-ratio: 1.5),'\n\t\t\t+'only screen and (-o-min-device-pixel-ratio: 3/2),'\n\t\t\t+'only screen and (min--moz-device-pixel-ratio: 1.5),'\n\t\t\t+'only screen and (min-device-pixel-ratio: 1.5),'\n\t\t\t+'only screen and (min-resolution: 144dpi),'\n\t\t\t+'only screen and (min-resolution: 1.5dppx)'\n\t\t).matches;\n\t} else {\n\t\treturn false;\n\t}\n}\n\n\n\n/**\n * @namespace Context:getBrowserScrollbarWidth\n */\n\n/**\n * Returns the current context's scrollbar width. Returns 0 if scrollbar is over content.\n * There are edge cases in which we might want to calculate positions in respect to the\n * actual width of the scrollbar. For example when working with elements with a 100vw width.\n *\n * This method temporarily inserts three elements into the body while forcing the body to\n * actually show scrollbars, measuring the difference between 100vw and 100% on the body and\n * returns the result.\n *\n * @returns {Number} the width of the body scrollbar in pixels\n *\n * @memberof Context:getBrowserScrollbarWidth\n * @alias getBrowserScrollbarWidth\n * @example\n * foobarElement.style.width = `calc(100vw - ${getBrowserScrollbarWidth()}px)`;\n */\nexport function getBrowserScrollbarWidth(){\n\tconst sandbox = document.createElement('div');\n\tsandbox.style.visibility = 'hidden';\n\tsandbox.style.opacity = '0';\n\tsandbox.style.pointerEvents = 'none';\n\tsandbox.style.overflow = 'scroll';\n\tsandbox.style.position = 'fixed';\n\tsandbox.style.top = '0';\n\tsandbox.style.right = '0';\n\tsandbox.style.left = '0';\n\t// firefox needs container to be at least 30px high to display scrollbar\n\tsandbox.style.height = '50px';\n\n\tconst scrollbarEnforcer = document.createElement('div');\n\tscrollbarEnforcer.style.width = '100%';\n\tscrollbarEnforcer.style.height = '100px';\n\n\tsandbox.appendChild(scrollbarEnforcer);\n\tdocument.body.appendChild(sandbox);\n\n\tconst scrollbarWidth = sandbox.offsetWidth - scrollbarEnforcer.offsetWidth;\n\n\tdocument.body.removeChild(sandbox);\n\n\treturn scrollbarWidth;\n}\n\n\n\n/**\n * @namespace Context:detectInteractionType\n */\n\n/**\n * Try to figure out the current type of interaction between the user and the document.\n * This is determined by the input device and is currently limited to either \"pointer\" or \"touch\".\n *\n * On call the function returns an educated guess about the fact what interaction type might be more\n * probable based on browser features and sets up event listeners to update Context module's CURRENT_INTERACTION_TYPE\n * observable (to which you may subscribe to be informed about updates), when interaction type should change while\n * the page is being interacted with. In case a touch occurs we determine touch interaction and\n * on mousemove we determine pointer interaction. If you use this observable to set up a class on your document for\n * example you can even relatively safely handle dual devices like a surface book.\n *\n * Hint: because touch devices also emit a single mousemove after touchend with a single touch we have to block\n * mousemove detection for 1s after the last touchend. Therefore, it takes up to 1s after the last touch event until\n * we are able to detect the change to a pointer device.\n *\n * @param {?Boolean} [returnObservable=false] - if set to true, the call returns Context module's CURRENT_INTERACTION_TYPE observable\n * @returns {String|Basic.Observable} interaction type string \"pointer\" or \"touch\", or the CURRENT_INTERACTION_TYPE observable\n *\n * @memberof Context:detectInteractionType\n * @alias detectInteractionType\n * @example\n * let interactionTypeGuess = detectInteractionType();\n * detectInteractionType(true).subscribe(function(type){\n * document.body.classList.toggle('touch', type === 'touch');\n * });\n */\n\nexport function detectInteractionType(returnObservable=false){\n\treturnObservable = orDefault(returnObservable, false, 'bool');\n\n\tif( !hasValue(CURRENT_INTERACTION_TYPE) ){\n\t\tCURRENT_INTERACTION_TYPE = new Observable('');\n\t\tif( ('ontouchstart' in document) && ('ontouchend' in document) && (window.navigator.maxTouchPoints > 0) ){\n\t\t\tCURRENT_INTERACTION_TYPE.setValue('touch');\n\t\t} else {\n\t\t\tCURRENT_INTERACTION_TYPE.setValue('pointer');\n\t\t}\n\n\t\tdocument.addEventListener('touchstart', INTERACTION_TYPE_DETECTION.touchStartHandler);\n\t\tdocument.addEventListener('touchend', INTERACTION_TYPE_DETECTION.touchEndHandler);\n\t\twindow.addEventListener('blur', INTERACTION_TYPE_DETECTION.blurHandler);\n\t\tdocument.addEventListener('mousemove', INTERACTION_TYPE_DETECTION.mouseMoveHandler);\n\t}\n\n\treturn returnObservable ? CURRENT_INTERACTION_TYPE : CURRENT_INTERACTION_TYPE.getValue();\n}\n\n\n\n/**\n * @namespace Context:detectAppleDevice\n */\n\n/**\n * Try to determine if the execution context is an Apple device and if so: which type.\n *\n * We use an escalating test starting with the user agent and then, as a fallback, checking the platform value\n * to determine the general device class (iPhone, iPad ,iPod ,Macintosh). If we get a Macintosh, we double check\n * if the device might be a falsely reporting iPad with iPadOS13+.\n *\n * You can hook up additional tests by providing an \"additionalTest\" function as a function parameter,\n * that function takes the evaluated device type at the end of the function and expects a new device type to be\n * returned. Using this, you can tap into the process and handle edge cases yourself.\n *\n * @param {?Function} [additionalTest=null] - if set, is executed after determining the device type, takes the current device type as parameter and is expected to return a new one; use this to add edge case tests to overwrite the result in certain conditions\n * @returns {String} \"ipad\", \"iphone\", \"ipod\" or \"mac\"\n *\n * @memberof Context:detectAppleDevice\n * @alias detectAppleDevice\n * @example\n * const IS_IOS_DEVICE = ['iphone', 'ipod', 'ipad'].includes(detectAppleDevice());\n */\nexport function detectAppleDevice(additionalTest=null){\n\tlet\n\t\tfamily = /iPhone|iPad|iPod|Macintosh/.exec(window.navigator.userAgent),\n\t\tdeviceType = null\n\t;\n\n\tif( Array.isArray(family) && (family.length > 0) ){\n\t\tfamily = family[0];\n\t} else {\n\t\tfamily = /^(iPhone|iPad|iPod|Mac)/.exec(window.navigator.platform);\n\n\t\tif( Array.isArray(family) && (family.length > 0) ){\n\t\t\tfamily = family[0];\n\n\t\t\tif( family === 'Mac' ){\n\t\t\t\tfamily = 'Macintosh';\n\t\t\t}\n\t\t} else {\n\t\t\tfamily = null;\n\t\t}\n\t}\n\n\tif( hasValue(family) ){\n\t\t// If User-Agent reports Macintosh double check this against touch points, since the device might\n\t\t// be a disguised iPad with i(Pad)Os13+\n\t\tif(\n\t\t\t(family === 'Macintosh')\n\t\t\t&& (window.navigator.maxTouchPoints > 1)\n\t\t){\n\t\t\tfamily = 'iPad';\n\t\t}\n\n\t\tswitch( family ) {\n\t\t\tcase 'iPad':\n\t\t\t\tdeviceType = 'ipad';\n\t\t\tbreak;\n\t\t\tcase 'iPhone':\n\t\t\t\tdeviceType = 'iphone';\n\t\t\tbreak;\n\t\t\tcase 'iPod':\n\t\t\t\tdeviceType = 'ipod';\n\t\t\tbreak;\n\t\t\tcase 'Macintosh':\n\t\t\t\tdeviceType = 'mac';\n\t\t\tbreak;\n\t\t}\n\n\t\tif( isFunction(additionalTest) ){\n\t\t\tdeviceType = additionalTest(deviceType);\n\t\t}\n\t}\n\n\treturn deviceType;\n}\n\n\n\n/**\n * @namespace Context:getBrowserLanguage\n */\n\n/**\n * Evaluates all available browser languages and tries to return the preferred one.\n *\n * Since browsers could not agree on a uniform way to return language values yet, the returned language\n * will always be \"lowercaselanguage-UPPERCASECOUNTRY\" or just \"lowercaselanguage\", if we have no country.\n *\n * @param {?String} [fallbackLanguage=null] - fallback value to return if no language could be evaluated\n * @returns {String|null} the preferred browser language if available, null if no language can be detected and no fallback has been defined\n *\n * @memberof Context:getBrowserLanguage\n * @alias getBrowserLanguage\n * @see getBrowserLocale\n * @example\n * getBrowserLanguage()\n * => \"en\"\n */\nexport function getBrowserLanguage(fallbackLanguage=null){\n\tlet language = null;\n\n\tif( hasValue(window.navigator.languages) ){\n\t\tconst browserLanguages = Array.from(window.navigator.languages);\n\t\tif( isArray(browserLanguages) && (browserLanguages.length > 0) ){\n\t\t\tlanguage = `${browserLanguages[0]}`;\n\t\t}\n\t}\n\n\tif( !hasValue(language) ){\n\t\t['language', 'browserLanguage', 'userLanguage', 'systemLanguage'].forEach(browserLanguagePropertyKey => {\n\t\t\tif( !hasValue(language) ){\n\t\t\t\tconst browserLanguage = window.navigator[browserLanguagePropertyKey];\n\t\t\t\tlanguage = hasValue(browserLanguage) ? `${browserLanguage}` : null;\n\t\t\t}\n\t\t});\n\t}\n\n\tif( !hasValue(language) && hasValue(fallbackLanguage) ){\n\t\tlanguage = `${fallbackLanguage}`;\n\t}\n\n\tconst languageParts = language.split('-');\n\tlanguage = languageParts[0].toLowerCase().trim();\n\tconst country = languageParts?.[1]?.toUpperCase()?.trim();\n\tlanguage = hasValue(country) ? `${language}-${country}` : language;\n\n\treturn language;\n}\n\n\n\n/**\n * @namespace Context:getLocale\n */\n\n/**\n * Evaluates the document's locale by having a look at the HTML element's lang-attribute.\n *\n * Since browsers could not agree on a uniform way to return locale values yet, the returned \"code\" will always be\n * \"lowercaselanguage-UPPERCASECOUNTRY\" (or just \"lowercaselanguage\", if we have no country), regardless of how the\n * browser returns the value, while \"country\" and \"language\" will always be lower case.\n *\n * @param {?HTMLElement} [element=document.documentElement] - the element holding the lang-attribute to evaluate\n * @param {?String} [fallbackLanguage=null] - if defined, a fallback lang value if element holds no lang information\n * @returns {Object} the locale as an object, having the lang value as \"code\", the split-up parts in \"country\" and \"language\" (if available) and \"isFallback\" to tell us if the fallback had to be used\n *\n * @memberof Context:getLocale\n * @alias getLocale\n * @see getBrowserLocale\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang\n * @example\n * getLocale()\n * => {\n * code : 'en-GB',\n * country : 'gb',\n * language : 'en',\n * isFallback : false\n * }\n * getLocale(document.querySelector('p'), 'en-US')\n * => {\n * code : 'en-US',\n * country : 'us',\n * language : 'en',\n * isFallback : true\n * }\n */\nexport function getLocale(element=null, fallbackLanguage=null){\n\t// document.documentElement not as function default to prevent errors in document-less context on import\n\telement = orDefault(element, document.documentElement);\n\n\tconst locale = {\n\t\tcode : null,\n\t\tcountry : null,\n\t\tlanguage : null,\n\t\tisFallback : false\n\t};\n\n\tlet langAttr = isFunction(element.getAttribute) ? element.getAttribute('lang') : null;\n\tif( !hasValue(langAttr) && hasValue(fallbackLanguage) ){\n\t\tlangAttr = `${fallbackLanguage}`;\n\t\tlocale.isFallback = true;\n\t}\n\n\tif( hasValue(langAttr) ){\n\t\tconst localeParts = `${langAttr}`.split('-');\n\t\tlocale.country = localeParts?.[1]?.toLowerCase()?.trim();\n\t\tlocale.language = localeParts[0].toLowerCase().trim();\n\t\tlocale.code = hasValue(locale.country) ? `${locale.language}-${locale.country.toUpperCase()}` : locale.language;\n\t}\n\n\treturn locale;\n}\n\n\n\n/**\n * @namespace Context:getBrowserLocale\n */\n\n/**\n * Evaluates the browser's locale by having a look at the preferred browser language, as reported by `getBrowserLanguage`.\n *\n * Since browsers could not agree on a uniform way to return locale values yet, the returned \"code\" will always be\n * \"lowercaselanguage-UPPERCASECOUNTRY\" (or just \"lowercaselanguage\", if we have no country), regardless of how the\n * browser returns the value, while \"country\" and \"language\" will always be lower case.\n *\n * @param {?String} [fallbackLanguage=null] - if defined, a fallback lang value if browser reports no preferred language\n * @returns {Object} the locale as an object, having the in \"country\" and \"language\" (if available) and \"isFallback\" to tell us if the fallback had to be used\n *\n * @memberof Context:getBrowserLocale\n * @alias getBrowserLocale\n * @see getBrowserLanguage\n * @example\n * getBrowserLocale()\n * => {\n * code : 'en-GB',\n * country : 'gb',\n * language : 'en',\n * isFallback : false\n * }\n * getBrowserLocale('en-US')\n * => {\n * code : 'en-US',\n * country : 'us',\n * language : 'en',\n * isFallback : true\n * }\n */\nexport function getBrowserLocale(fallbackLanguage=null){\n\treturn getLocale({getAttribute(){ return getBrowserLanguage(fallbackLanguage); }}, fallbackLanguage);\n}\n"]} \ No newline at end of file diff --git a/dist/conversion.js b/dist/conversion.js index ea4945fe..9a079cd5 100644 --- a/dist/conversion.js +++ b/dist/conversion.js @@ -1,5 +1,5 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Conversion diff --git a/dist/conversion.js.map b/dist/conversion.js.map index c84a68a3..db0861ca 100644 --- a/dist/conversion.js.map +++ b/dist/conversion.js.map @@ -1 +1 @@ -{"version":3,"file":"conversion.js","names":["MODULE_NAME","isInt","isArray","orDefault","pad","trim","UPPER_CHARS","LOWER_CHARS","NUMBERS","BASE_ALPHABETS","slice","BASE64_ALPHABET","buildAlphabet","__methodName__","baseOrAlphabet","useChunks","alphabet","Error","baseAlphabetKey","Object","keys","sort","Number","split","forEach","char","concat","Array","from","Set","a","b","aBase64Index","indexOf","bBase64Index","join","length","calculateNeededPages","base","availablePages","Math","floor","neededPages","charPoolSize","combinations","buildPageMap","pageMap","remainder","quotient","i","ceil","push","buildCharMap","pagedAlphabet","min","pagedBase","charMap","stringToBase64","value","btoa","String","fromCodePoint","TextEncoder","encode","replaceAll","base64ToString","res","TextDecoder","decode","Uint8Array","atob","codePointAt","ex","base10toBaseX","baseXValue","baseXToBase10","reverse","base10Value","pow","toBaseX","useCharacterMap","chunkSize","valueIsNumber","valueIsNegativeNumber","abs","includes","base64Value","chunks","chunkAlphabet","chunkSeparator","chunkStart","chunk","decodedValue","fromBaseX","startsWith","endsWith","inverseCharMap","fromEntries","entries","map","key","tokensByLength","tokenFound","token"],"sources":["conversion.js"],"mappings":";;;AAQA,MAAMA,YAAc,oBAMZC,MAAOC,QAASC,cAAgB,oBAChCC,IAAKC,SAAW,eAMxB,MACCC,YAAc,6BACdC,YAAc,6BACdC,QAAU,aACVC,eAAiB,CAChB,GAAO,GAAGH,cAAcC,cAAcC,YACtC,GAAO,GAAGA,UAAUF,cAAcC,eAClC,GAAO,GAAGC,UAAUF,cACpB,GAAOA,YACP,GAAO,GAAGE,UAAUF,YAAYI,MAAM,EAAG,KACzC,GAAOF,QACP,EAAMA,QAAQE,MAAM,EAAG,GACvB,EAAMF,QAAQE,MAAM,EAAG,IAExBC,gBAAkBF,eAAe,IAkBlC,SAASG,cAAcC,EAAe,gBAAiBC,EAAe,GAAIC,GAAU,GAGnF,IAAIC,EAEJ,GAJAF,EAAiBX,UAAUW,EAAgB,IAIvCb,MAAMa,GAAiB,CAC1B,GAAKA,EAAiB,GAAOA,EAAiB,GAC7C,MAAM,IAAIG,MAAM,GAAGjB,eAAea,yDAGnC,GAAIE,GAAcD,EAAiB,EAClC,MAAM,IAAIG,MAAM,GAAGjB,eAAea,kDAGnC,IAAK,IAAIK,KAAmBC,OAAOC,KAAKX,gBAAgBY,OACvD,GAAIC,OAAOJ,IAAoBJ,EAAgB,CAC9CE,EAAWP,eAAeS,GAAiBR,MAAM,EAAGI,GACpD,KACD,CAEF,MACCE,EAAW,GAENd,QAAQY,KACZA,EAAiB,GAAGA,IAAiBS,MAAM,KAG5CT,EAAeU,SAAQC,IACtBT,EAAWA,EAASU,OAAO,GAAGD,IAAOF,MAAM,IAAI,IAGhDP,EAAWW,MAAMC,KAAK,IAAIC,IAAIb,IAC9BA,EAASK,MAAK,CAACS,EAAGC,KACjB,MACCC,EAAerB,gBAAgBsB,QAAQH,GACvCI,EAAevB,gBAAgBsB,QAAQF,GAGxC,OAAKC,EAAe,GAAOE,EAAe,EACjCJ,IAAMC,EAAK,EAAMD,EAAIC,GAAM,EAAI,EAC7BC,EAAe,EAClB,EACGE,EAAe,GACjB,EAEAF,IAAiBE,EAAgB,EAAMF,EAAeE,GAAiB,EAAI,CACpF,IAGDlB,EAAWA,EAASmB,KAAK,IAG1B,GAAKnB,EAASoB,OAAS,GAAOpB,EAASoB,OAAS,GAC/C,MAAM,IAAInB,MAAM,GAAGjB,eAAea,+DAGnC,GAAIE,GAAcC,EAASoB,OAAS,EACnC,MAAM,IAAInB,MAAM,GAAGjB,eAAea,yDAGnC,OAAOG,CACR,CAUA,SAASqB,qBAAqBC,GAC7B,MAAMC,EAAiBC,KAAKC,MAAMH,EAAO,GACzC,IACCI,EAAc,EACdC,EAAeL,EACfM,EAAeD,EAGhB,KAAOC,EAAe,IACrBF,IACIA,GAAeH,GAClBI,IAEDC,GAAgBF,EAAc,GAAKC,EAGpC,OAAOD,CACR,CAWA,SAASG,aAAa7B,GACrB,MACCsB,EAAOtB,EAASoB,OAChBM,EAAcL,qBAAqBC,GACnCC,EAAiBC,KAAKC,MAAMH,EAAO,GACnCQ,EAAU,CAAC,IAGZ,IAAIC,EAAWC,EACf,IAAK,IAAIC,EAAI,EAAGA,GAAKP,EAAaO,IACjCF,EAAYE,EAAIV,EAChBS,EAAWR,KAAKU,KAAKD,EAAIV,GACzBO,EAAQK,KAAK/C,IAAI,GAAIY,EAAU+B,EAAY,EAAMA,EAAY,EAAMR,EAAiB,GAAKS,IAG1F,OAAOF,CACR,CAWA,SAASM,aAAaN,EAAS9B,GAC9B,MACCsB,EAAOtB,EAASoB,OAChBM,EAAcL,qBAAqBC,GACnCC,EAAiBC,KAAKC,MAAMH,EAAO,GACnCe,EAAgBrC,EAASN,MAAM8B,KAAKc,IAAIZ,EAAaH,IACrDgB,EAAYF,EAAcjB,OAC1BoB,EAAU,CAAC,EAGZ,IAAIT,EAAWC,EACf,IAAK,IAAIC,KAAKtC,gBAAgBY,MAAM,IACnCwB,EAAYE,EAAIM,EAChBP,EAAWR,KAAKC,MAAMQ,EAAIM,GAC1BC,EAAQ7C,gBAAgBsC,IAAM,GAAGH,EAAQE,KAAYK,EAAcN,KAGpE,OAAOS,CACR,CAWA,SAASC,eAAeC,GACvB,OAAOC,KAAKC,OAAOC,kBAAkB,IAAKC,aAAeC,OAAO,GAAGL,OAAYM,WAAW,IAAK,GAChG,CAaA,SAASC,eAAeP,EAAO7C,EAAe,kBAC7C,IAAIqD,EAAM,KAEV,IACCA,GAAM,IAAKC,aAAeC,OAAOC,WAAWzC,KAAK0C,KAAK,GAAGZ,MAAUjC,GAAQA,EAAK8C,YAAY,KAG7F,CAFE,MAAMC,GACP,MAAM,IAAIvD,MAAM,GAAGjB,eAAea,sBAAmC6C,KACtE,CAEA,OAAOQ,CACR,CAWA,SAASO,cAAcf,EAAO1C,GAC7B,MAAMsB,EAAOtB,EAASoB,OACtB,IAGCW,EAFA2B,EAAa,GACb1B,EAAWU,EAIZ,GAAiB,IAAbV,EACH,KAAoB,IAAbA,GACND,EAAYC,EAAWV,EACvBU,EAAWR,KAAKC,MAAMO,EAAWV,GACjCoC,EAAa,GAAG1D,EAAS+B,KAAa2B,SAGvCA,EAAa,GAAG1D,EAAS,KAG1B,OAAO0D,CACR,CAWA,SAASC,cAAcjB,EAAO1C,GAC7B0C,EAAQ,GAAGA,IAAQnC,MAAM,IAAIqD,UAAUzC,KAAK,IAE5C,MAAMG,EAAOtB,EAASoB,OACtB,IAAIyC,EAAc,EAElB,IAAK,IAAI5B,EAAI,EAAGA,EAAIS,EAAMtB,OAAQa,IACjC4B,GAAerC,KAAKsC,IAAIxC,EAAMW,GAAKjC,EAASiB,QAAQyB,EAAMT,IAG3D,OAAO4B,CACR,QA0FO,SAASE,QAAQrB,EAAO5C,EAAe,GAAIkE,GAAgB,EAAOjE,GAAU,EAAOkE,EAAU,GACnG,MAAMpE,EAAiB,UAGtBqE,EAAgBjF,MAAMyD,GACtByB,EAAwBD,GAAkBxB,EAAQ,EAGnDA,EAAQwB,EAAgB,GAAG1C,KAAK4C,IAAI1B,KAAW,GAAGA,IAClDsB,EAAkB7E,UAAU6E,GAAiB,EAAO,QACpDjE,EAAYZ,UAAUY,GAAW,EAAO,QACxCkE,EAAY9E,UAAU8E,EAAW,GAAI,OAErC,MAAMjE,EAAWJ,cAAcC,EAAgBC,EAAgBC,GAC/D,GAAIC,EAASqE,SAAS,MAAQrE,EAASqE,SAAS,KAC/C,MAAM,IAAIpE,MAAM,GAAGjB,eAAea,qDAGnC,IACCyE,EAAc,GACdT,EAAc,EACdH,EAAa,GAGd,GAAIM,EAAiB,CAEpB,GADAM,EAAc7B,eAAeC,GACN,KAAnB5C,EAAwB,OAAOwE,EAEnC,MAEC9B,EAAUJ,aADAP,aAAa7B,GACSA,GAGjC,IAAK,IAAIS,KAAQ6D,EAChBZ,GAAclB,EAAQ/B,EAExB,KAAO,CAEL6D,EADGJ,EACWT,cAAcf,EAAO/C,iBAErB8C,eAAeC,GAG9B,MACC6B,EAAS,GACTC,EAAgBzE,EAAYC,EAASN,MAAM,GAAKM,EAChDyE,EAAiB1E,EAAYC,EAAS,GAAK,GAG5C,GAAID,EAAW,CACd,IAAI2E,EAAa,EACjB,KAAOA,EAAaJ,EAAYlD,QAC/BmD,EAAOpC,KAAKmC,EAAY5E,MAAMgF,EAAYA,EAAaT,IACvDS,GAAcT,CAEhB,MACCM,EAAOpC,KAAKmC,GAGb,IAAK,IAAIK,KAASJ,EAAQ,CAGzB,GAFAV,EAAcF,cAAcgB,EAAOhF,kBAE9BI,GAAiC,KAAnBD,EAAwB,CAC1C4D,GAAcG,EACd,KACD,CAEAH,GAAc,GAAGe,IAAiBhB,cAAcI,EAAaW,IAC9D,CAEuB,KAAnBC,IACHf,EAAaA,EAAWhE,MAAM,GAEhC,CAEAgE,EAAa,GAAGS,EAAwB,IAAM,KAAKT,IACnD,MAAMkB,EAAe,GAAGC,UAAUnB,EAAY5D,EAAgBkE,EAAiBjE,EAAWmE,KAC1F,GAAIU,IAAiB,GAAGT,EAAwB,IAAM,KAAKzB,IAC1D,MAAM,IAAIzC,MACT,GAAGjB,eAAea,sCAAmD6D,wBAC/ChB,WAAekC,+NAMvC,OAAOlB,CACR,QAqDO,SAASmB,UAAUnC,EAAO5C,EAAe,GAAIkE,GAAgB,EAAOjE,GAAU,EAAOmE,GAAc,GACzG,MAAMrE,EAAiB,YAEvBqE,IAAkBA,GACdjF,MAAMyD,IACL,GAAGA,IAAQoC,WAAW,MAAQ,GAAGpC,IAAQqC,SAAS,KAEvDrC,EAAQ,GAAGA,IACPwB,IACHxB,EAAQrD,KAAKqD,EAAO,CAAC,IAAK,OAE3B,MAAMyB,EAAwBD,GAAiBxB,EAAMoC,WAAW,KAQhE,GAPIX,IACHzB,EAAQA,EAAMhD,MAAM,IAGrBsE,EAAkB7E,UAAU6E,GAAiB,EAAO,QACpDjE,EAAYZ,UAAUY,GAAW,EAAO,QAGnB,KAAnBD,IACGkE,IACAjE,IACAmE,EACH,OAAOjB,eAAeP,EAAO7C,GAE/B,MAAMG,EAAWJ,cAAcC,EAAgBC,EAAgBC,GAC/D,GAAIC,EAASqE,SAAS,MAAQrE,EAASqE,SAAS,KAC/C,MAAM,IAAIpE,MAAM,GAAGjB,eAAea,qDAGnC,IAGC+E,EAFAN,EAAc,GACdT,EAAc,EAIf,GAAIG,EAAiB,CACpB,MAECxB,EAAUJ,aADAP,aAAa7B,GACSA,GAChCgF,EAAiB7E,OAAO8E,YACvB9E,OACC+E,QAAQ1C,GACR2C,KAAI,EAAEC,EAAK1C,KAAW,CAACA,EAAO0C,MAEhCC,EAAiBlF,OAAOC,KAAK4E,GAAgB3E,MAAK,CAACS,EAAGC,IAC7CD,EAAEM,SAAWL,EAAEK,OAAU,EAAMN,EAAEM,OAASL,EAAEK,QAAW,EAAI,IAIrE,IAAIkE,GAAa,EACjB,KAAiB,KAAV5C,GAAc,CACpB,IAAK,IAAI6C,KAASF,EAEjB,GADAC,GAAa,EACT5C,EAAMoC,WAAWS,GAAQ,CAC5BD,GAAa,EACbhB,GAAeU,EAAeO,GAC9B7C,EAAQA,EAAMhD,MAAM6F,EAAMnE,QAC1B,KACD,CAGD,IAAKkE,EACJ,MAAM,IAAIrF,MACT,GAAGjB,eAAea,kCAA+C6C,0CAGpE,CAOA,OALAkC,EAAe3B,eAAeqB,EAAazE,GACvCsE,IACHS,EAAe,IAAIA,KAGbA,CACR,CAAO,CACNA,EAAe,GAEf,MACCJ,EAAgBzE,EAAYC,EAASN,MAAM,GAAKM,EAChDyE,EAAiB1E,EAAYC,EAAS,GAAK,GAC3CuE,EAASxE,EAAY2C,EAAMnC,MAAMkE,GAAkB,CAAC/B,GAGrD,IAAK,IAAIiC,KAASJ,EACjBV,EAAcF,cAAcgB,EAAOH,GAE/BN,EACHU,GAAgB,GAAGf,IAEnBS,GAAeb,cAAcI,EAAalE,iBAkB5C,MAdqB,KAAjBiF,IACHA,EAAe3B,eAAeqB,EAAazE,GACvCsE,IACHS,EAAe,IAAIA,OAIhB7E,GAAamE,IACjBU,EAAetE,OAAOsE,GAClBT,GAA0BS,GAAgB,IAC7CA,GAAgBA,IAIXA,CACR,CACD","sourcesContent":["/*!\n * Module Conversion\n */\n\n/**\n * @namespace Conversion\n */\n\nconst MODULE_NAME = 'Conversion';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {isInt, isArray, orDefault} from './basic.js';\nimport {pad, trim} from './strings.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst\n\tUPPER_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',\n\tLOWER_CHARS = 'abcdefghijklmnopqrstuvwxyz',\n\tNUMBERS = '0123456789',\n\tBASE_ALPHABETS = {\n\t\t'64' : `${UPPER_CHARS}${LOWER_CHARS}${NUMBERS}+/`,\n\t\t'63' : `${NUMBERS}${UPPER_CHARS}${LOWER_CHARS}_`,\n\t\t'36' : `${NUMBERS}${UPPER_CHARS}`,\n\t\t'26' : UPPER_CHARS,\n\t\t'16' : `${NUMBERS}${UPPER_CHARS.slice(0, 6)}`,\n\t\t'10' : NUMBERS,\n\t\t'8' : NUMBERS.slice(0, 8),\n\t\t'2' : NUMBERS.slice(0, 2)\n\t},\n\tBASE64_ALPHABET = BASE_ALPHABETS['64']\n;\n\n\n\n//###[ HELPERS ]########################################################################################################\n\n/**\n * Builds an alphabet string, based on an integer, an alphabet string or an array of strings containing the alphabet's\n * chars. An integer uses BASE_ALPHABETS to select a base alphabet to slice the alphabet from. The first base alphabet\n * having enough chars is going be used. The configurations of the base alphabets are according to current base\n * practices.\n *\n * Characters in custom alphabets are sorted according to base64 definition, with additional chars appended at the end,\n * sorted ascending based on char value.\n *\n * @private\n */\nfunction buildAlphabet(__methodName__='buildAlphabet', baseOrAlphabet=64, useChunks=false){\n\tbaseOrAlphabet = orDefault(baseOrAlphabet, 64);\n\n\tlet alphabet;\n\n\tif( isInt(baseOrAlphabet) ){\n\t\tif( (baseOrAlphabet < 2) || (baseOrAlphabet > 64) ){\n\t\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | base not usable, smaller than 2 or larger than 64`);\n\t\t}\n\n\t\tif( useChunks && (baseOrAlphabet < 3) ){\n\t\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | base not usable for chunks, smaller than 3`);\n\t\t}\n\n\t\tfor( let baseAlphabetKey of Object.keys(BASE_ALPHABETS).sort() ){\n\t\t\tif( Number(baseAlphabetKey) >= baseOrAlphabet ){\n\t\t\t\talphabet = BASE_ALPHABETS[baseAlphabetKey].slice(0, baseOrAlphabet);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} else {\n\t\talphabet = [];\n\n\t\tif( !isArray(baseOrAlphabet) ){\n\t\t\tbaseOrAlphabet = `${baseOrAlphabet}`.split('');\n\t\t}\n\n\t\tbaseOrAlphabet.forEach(char => {\n\t\t\talphabet = alphabet.concat(`${char}`.split(''));\n\t\t});\n\n\t\talphabet = Array.from(new Set(alphabet));\n\t\talphabet.sort((a, b) => {\n\t\t\tconst\n\t\t\t\taBase64Index = BASE64_ALPHABET.indexOf(a),\n\t\t\t\tbBase64Index = BASE64_ALPHABET.indexOf(b)\n\t\t\t;\n\n\t\t\tif( (aBase64Index < 0) && (bBase64Index < 0) ){\n\t\t\t\treturn (a === b) ? 0 : ((a < b) ? -1 : 1);\n\t\t\t} else if( aBase64Index < 0 ){\n\t\t\t\treturn 1;\n\t\t\t} else if( bBase64Index < 0 ){\n\t\t\t\treturn -1;\n\t\t\t} else {\n\t\t\t\treturn (aBase64Index === bBase64Index) ? 0 : ((aBase64Index < bBase64Index) ? -1 : 1);\n\t\t\t}\n\t\t});\n\n\t\talphabet = alphabet.join('');\n\t}\n\n\tif( (alphabet.length < 2) || (alphabet.length > 64) ){\n\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | alphabet not usable, must have between two and 64 chars`);\n\t}\n\n\tif( useChunks && (alphabet.length < 3) ){\n\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | alphabet not usable for chunks, less than 3 chars`);\n\t}\n\n\treturn alphabet;\n}\n\n\n\n/**\n * Calculates how many character mapping pages/page characters we need for a specific alphabet,\n * defined by its length/base.\n *\n * @private\n */\nfunction calculateNeededPages(base){\n\tconst availablePages = Math.floor(base / 2);\n\tlet\n\t\tneededPages = 0,\n\t\tcharPoolSize = base,\n\t\tcombinations = charPoolSize\n\t;\n\n\twhile( combinations < 64 ){\n\t\tneededPages++;\n\t\tif( neededPages <= availablePages ){\n\t\t\tcharPoolSize--;\n\t\t}\n\t\tcombinations = (neededPages + 1) * charPoolSize;\n\t}\n\n\treturn neededPages;\n}\n\n\n\n/**\n * Returns an array of value prefixes used to map characters to different code pages, in cases where we need to encode\n * a base64 character above the base of our target alphabet, which means, that we have to repeat character usage, but\n * with a page prefix to multiply the value set by reducing the base alphabet for that purpose.\n *\n * @private\n */\nfunction buildPageMap(alphabet){\n\tconst\n\t\tbase = alphabet.length,\n\t\tneededPages = calculateNeededPages(base),\n\t\tavailablePages = Math.floor(base / 2),\n\t\tpageMap = ['']\n\t;\n\n\tlet remainder, quotient;\n\tfor( let i = 1; i <= neededPages; i++ ){\n\t\tremainder = i % availablePages;\n\t\tquotient = Math.ceil(i / availablePages);\n\t\tpageMap.push(pad('', alphabet[(remainder > 0) ? (remainder - 1) : (availablePages - 1)], quotient));\n\t}\n\n\treturn pageMap;\n}\n\n\n\n/**\n * Returns a dictionary, mapping each base64 character to one or more characters of the target alphabet.\n * In cases, where the character to encode is beyond the target alphabet, page prefixes are prepended to\n * cover all characters by increasing length.\n *\n * @private\n */\nfunction buildCharMap(pageMap, alphabet){\n\tconst\n\t\tbase = alphabet.length,\n\t\tneededPages = calculateNeededPages(base),\n\t\tavailablePages = Math.floor(base / 2),\n\t\tpagedAlphabet = alphabet.slice(Math.min(neededPages, availablePages)),\n\t\tpagedBase = pagedAlphabet.length,\n\t\tcharMap = {}\n\t;\n\n\tlet remainder, quotient;\n\tfor( let i in BASE64_ALPHABET.split('') ){\n\t\tremainder = i % pagedBase;\n\t\tquotient = Math.floor(i / pagedBase);\n\t\tcharMap[BASE64_ALPHABET[i]] = `${pageMap[quotient]}${pagedAlphabet[remainder]}`\n\t}\n\n\treturn charMap;\n}\n\n\n\n/**\n * Converts a string to base64, while handling unicode characters correctly.\n * Be advised, that the result needs to be decoded with base64ToString() again, since\n * we also need to correctly handle unicode on the way back.\n *\n * @private\n */\nfunction stringToBase64(value){\n\treturn btoa(String.fromCodePoint(...((new TextEncoder()).encode(`${value}`)))).replaceAll('=', '');\n}\n\n\n\n/**\n * Decodes a base64-encoded string to its original value.\n * Be advised, that the base64 value has to be encoded using stringToBase64(), since unicode characters need\n * special handling during en/decoding.\n *\n * This function will fail with an error, if the given value is not actually decodable with base64.\n *\n * @private\n */\nfunction base64ToString(value, __methodName__='base64ToString'){\n\tlet res = null;\n\n\ttry {\n\t\tres = (new TextDecoder()).decode(Uint8Array.from(atob(`${value}`), char => char.codePointAt(0)))\n\t} catch(ex){\n\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | cannot decode \"${value}\"`);\n\t}\n\n\treturn res;\n}\n\n\n\n/**\n * Converts a decimal/base10 value to a different base numerically.\n * Be aware that this needs the value to be a safe integer.\n * This function does not deal with negative numbers by itself.\n *\n * @private\n */\nfunction base10toBaseX(value, alphabet){\n\tconst base = alphabet.length;\n\tlet\n\t\tbaseXValue = '',\n\t\tquotient = value,\n\t\tremainder\n\t;\n\n\tif( quotient !== 0){\n\t\twhile( quotient !== 0 ){\n\t\t\tremainder = quotient % base;\n\t\t\tquotient = Math.floor(quotient / base);\n\t\t\tbaseXValue = `${alphabet[remainder]}${baseXValue}`;\n\t\t}\n\t} else {\n\t\tbaseXValue = `${alphabet[0]}`;\n\t}\n\n\treturn baseXValue;\n}\n\n\n\n/**\n * Converts a value, based on a defined alphabet, to its decimal/base10 representation.\n * Be aware that this needs the result to be a safe integer.\n * This function does not deal with negative numbers by itself.\n *\n * @private\n */\nfunction baseXToBase10(value, alphabet){\n\tvalue = `${value}`.split('').reverse().join('');\n\n\tconst base = alphabet.length;\n\tlet base10Value = 0;\n\n\tfor( let i = 0; i < value.length; i++ ){\n\t\tbase10Value += Math.pow(base, i) * alphabet.indexOf(value[i]);\n\t}\n\n\treturn base10Value;\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Conversion:toBaseX\n */\n\n/**\n * This function converts a value to a representation in a defined base between 2 and 64.\n * So this covers common use cases like binary, octal, hexadecimal, alphabetical, alphanumeric and of course base64.\n *\n * The result of this function is always either a decimal number or a string, just as the input value. All numbers\n * apart from decimal ones are returned as strings without prefix. So, decimal 5 will be the number 5, but the binary\n * version will be the string \"101\". Positive and negative decimal integers are valid numbers here, but this\n * implementation does not support floats (multiply and divide if needed). Only numerical bases above 36 contain\n * lower case characters, so decimal 255 is \"FF\" in base 16 and not \"ff\".\n *\n * This function is unicode safe, by using byte conversion\n * (see: https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem).\n * Be aware, that this also means, that results of `btoa/atob()` and `toBaseX/fromBaseX()` are _not_ interchangeable,\n * since they work with different values internally.\n *\n * There are three approaches to changing the base of a value in JavaScript:\n *\n * 1. Either you are taking the numerical/mathematical road, treating a value as a number in its alphabet being\n * interpreted as a number, where each character, counting from the back is the base to the power of the\n * character index. This is the approach you'd expect, when, for instance, you'd want to convert the decimal number 5\n * to binary 101. The downside of this approach is, that the relatively small max safe integer in JavaScript makes\n * converting large numbers, such as longer strings, impossible.\n *\n * 2. Therefore, the second approach takes the numeric approach, but combines it with chunking, splitting the value into\n * pieces, which are, by themselves, safely convertible. The downside is, that we need an extra character to delimit\n * chunks in the result, since values have non-uniform lengths. This means, that this does not work with the basic\n * binary base, and we need at least 3 alphabet characters.\n *\n * 3. The last approach uses the native base64 string encoding with `btoa()` as a safe translation layer, mapping the\n * resulting string to the target base, using a generated (and possibly paged) character map. This way treats all\n * values as strings and is not compatible to numerical conversion anymore, but uses the same characters. The result\n * of this approach can encode every string of every length without structural tricks, but has the longest results.\n *\n * This function is capable of all three approaches, which are equally safe for unicode values. The numerical\n * approach is the default. If you want to encode large numbers or strings longer than ~6 characters, select\n * a different approach using the `useCharacterMap` or `useChunks` parameters. Character mapping has preference, while\n * chunks have no effect in character mapping.\n *\n * Each encoding process ends with a self-test, checking if the result is actually decodable using\n * `fromBaseX()`, using the same settings again. This ensures, that every result is valid and retrievable in the future,\n * preventing any undiscovered errors, which would make it impossible to work with the original value again.\n *\n * You may define the base as an integer between 2 and 64 or as a custom alphabet in the same range. Integer based\n * alphabets are generated using defined base alphabets, which are sliced if necessary. Custom alphabets are\n * automatically sorted to match base64 are far as possible, pushing additional characters to the end, which are then\n * sorted ascending by character value.\n *\n * \"{\" and \"}\" are the only forbidden characters in a custom alphabet, since we need these to mark number values in\n * `fromBaseX()`.\n *\n * Numerical conversion keeps negative numbers negative and marks the result with a preceding \"-\".\n *\n * Hint: if you want to genrate codes to be presented to the user, see `Random:randomUserCode`.\n *\n * @param {Number|String} value - value to be encoded\n * @param {?Number|String|Array} [baseOrAlphabet=64] - either the numerical base to convert to (64, 36, ...) or the alphabet of characters to use in encoding; numerical bases must be between 2 and 64 (if the result is chunked, we need a base 3)\n * @param {?Boolean} [useCharacterMap=true] - set to true, to use a character map, based on btoa(), instead of numerical conversion\n * @param {?Boolean} [useChunks=false] - set to true, to add chunking to the numerical approach, converting the value in groups separated by a delimiter, which is the first letter of the base's alphabet\n * @param {?Number} [chunkSize=6] - define a different chunks size; only change this, if 6 seems too big in your context, going higher is not advisable\n * @throws error if baseOrAlphabet is not usable\n * @throws error if result is not decodable again using the same settings\n * @returns {String} the encoded value\n *\n * @memberof Conversion:toBaseX\n * @alias toBaseX\n * @see fromBaseX\n * @see https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem\n * @see Random:randomUserCode\n * @example\n * toBaseX('foobar')\n * => 'Zm9vYmFy'\n * toBaseX(-5, 2)\n * => '-101'\n * toBaseX(42, 'abcdefghij')\n * => 'ec'\n * toBaseX('too-long-for-number-conversion', 36, true)\n * => 'U70R0DCN0F0DS04T0BQ040R0GCN0N0JSNA03TZ0J01S0K0N0KQOA0HRN0R0C'\n * toBaseX('too-long-for-number-conversion', 16, false, true)\n * => 'D3EF5D81F026D9DFDA970BBF17222402A47D5AD650CF6C2FE2102A494BCBDD0A2864C'\n */\nexport function toBaseX(value, baseOrAlphabet=64, useCharacterMap=false, useChunks=false, chunkSize=6){\n\tconst __methodName__ = 'toBaseX';\n\n\tconst\n\t\tvalueIsNumber = isInt(value),\n\t\tvalueIsNegativeNumber = valueIsNumber && (value < 0)\n\t;\n\n\tvalue = valueIsNumber ? `${Math.abs(value)}` : `${value}`;\n\tuseCharacterMap = orDefault(useCharacterMap, false, 'bool');\n\tuseChunks = orDefault(useChunks, false, 'bool');\n\tchunkSize = orDefault(chunkSize, 10, 'int');\n\n\tconst alphabet = buildAlphabet(__methodName__, baseOrAlphabet, useChunks);\n\tif( alphabet.includes('{') || alphabet.includes('}') ){\n\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | invalid alphabet, must not contain \"{\" or \"}\"`)\n\t}\n\n\tlet\n\t\tbase64Value = '',\n\t\tbase10Value = 0,\n\t\tbaseXValue = ''\n\t;\n\n\tif( useCharacterMap ){\n\t\tbase64Value = stringToBase64(value);\n\t\tif( baseOrAlphabet === 64 ) return base64Value;\n\n\t\tconst\n\t\t\tpageMap = buildPageMap(alphabet),\n\t\t\tcharMap = buildCharMap(pageMap, alphabet)\n\t\t;\n\n\t\tfor( let char of base64Value ){\n\t\t\tbaseXValue += charMap[char];\n\t\t}\n\t} else {\n\t\tif( valueIsNumber ){\n\t\t\tbase64Value = base10toBaseX(value, BASE64_ALPHABET);\n\t\t} else {\n\t\t\tbase64Value = stringToBase64(value);\n\t\t}\n\n\t\tconst\n\t\t\tchunks = [],\n\t\t\tchunkAlphabet = useChunks ? alphabet.slice(1) : alphabet,\n\t\t\tchunkSeparator = useChunks ? alphabet[0] : ''\n\t\t;\n\n\t\tif( useChunks ){\n\t\t\tlet chunkStart = 0;\n\t\t\twhile( chunkStart < base64Value.length ){\n\t\t\t\tchunks.push(base64Value.slice(chunkStart, chunkStart + chunkSize));\n\t\t\t\tchunkStart += chunkSize;\n\t\t\t}\n\t\t} else {\n\t\t\tchunks.push(base64Value);\n\t\t}\n\n\t\tfor( let chunk of chunks ){\n\t\t\tbase10Value = baseXToBase10(chunk, BASE64_ALPHABET);\n\n\t\t\tif( !useChunks && (baseOrAlphabet === 10) ){\n\t\t\t\tbaseXValue += base10Value;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tbaseXValue += `${chunkSeparator}${base10toBaseX(base10Value, chunkAlphabet)}`;\n\t\t}\n\n\t\tif( chunkSeparator !== '' ){\n\t\t\tbaseXValue = baseXValue.slice(1);\n\t\t}\n\t}\n\n\tbaseXValue = `${valueIsNegativeNumber ? '-' : ''}${baseXValue}`;\n\tconst decodedValue = `${fromBaseX(baseXValue, baseOrAlphabet, useCharacterMap, useChunks, valueIsNumber)}`;\n\tif( decodedValue !== `${valueIsNegativeNumber ? '-' : ''}${value}` ){\n\t\tthrow new Error(\n\t\t\t`${MODULE_NAME}:${__methodName__} | critical error, encoded value \"${baseXValue}\" `\n\t\t\t+`not decodable to \"${value}\", is \"${decodedValue}\" instead; `\n\t\t\t+`if this looks \"cut off\", this may be a problem with JS max safe integer size `\n\t\t\t+`(safe value length for number-based conversion is just ~8 chars), `\n\t\t\t+`try using character mapping or chunks to circumvent this problem`\n\t\t);\n\t}\n\treturn baseXValue;\n}\n\n\n\n/**\n * @namespace Conversion:fromBaseX\n */\n\n/**\n * This function converts a based representation back to its original number or string value.\n * This is the mirror function to `toBaseX()` and expects a value encoded with that function. See that function\n * for implementation details, modes and restrictions.\n *\n * The result of this function is always either a decimal number or a string, just as the input value. All numbers\n * apart from decimal ones are returned as strings without prefix. So, decimal 5 will be the number 5, but the binary\n * version will be the string \"101\".\n *\n * You may define the base as an integer between 2 and 64 or as a custom alphabet in the same range. Integer based\n * alphabets are generated using defined base alphabets, which are sliced if necessary. Custom alphabets are\n * automatically sorted to match base64 are far as possible, pushing additional characters to the end, which are then\n * sorted ascending by character value.\n *\n * \"{\" and \"}\" are the only forbidden characters in a custom alphabet, since we need these to mark number values in\n * `fromBaseX()`.\n *\n * Numerical conversion keeps negative numbers negative and marks the result with a preceding \"-\".\n *\n * @param {Number|String} value - value to be decoded\n * @param {?Number|String|Array} [baseOrAlphabet=64] - either the numerical base to convert to (64, 36, ...) or the alphabet of characters to use in encoding; numerical bases must be between 2 and 64 (if the result is chunked, we need a base 3)\n * @param {?Boolean} [useCharacterMap=true] - set to true, to use a character map, based on btoa(), instead of numerical conversion\n * @param {?Boolean} [useChunks=false] - set to true, to add chunking to the numerical approach, converting the value in groups separated by a delimiter, which is the first letter of the base's alphabet\n * @param {?Boolean} [valueIsNumber=false] - if true, the given value is treated as a number for numerical conversion; this is necessary, since numbers such as binaries are defined as strings and are therefore not auto-detectable\n * @throws error if baseOrAlphabet is not usable\n * @throws error character mapped decoding fails, due to missing token/unmatched alphabet\n * @returns {String} the decoded value\n *\n * @memberof Conversion:fromBaseX\n * @alias fromBaseX\n * @see toBaseX\n * @example\n * fromBaseX('Zm9vYmFy')\n * => 'foobar'\n * fromBaseX('16W33YPUS', 36)\n * => 'äす'\n * fromBaseX('{-3C3}', 13)\n * => -666\n * fromBaseX('q', 64, false, false, true)\n * => 42\n * fromBaseX('U70R0DCN0F0DS04T0BQ040R0GCN0N0JSNA03TZ0J01S0K0N0KQOA0HRN0R0C', 36, true)\n * => 'too-long-for-number-conversion'\n * fromBaseX('D3EF5D81F026D9DFDA970BBF17222402A47D5AD650CF6C2FE2102A494BCBDD0A2864C', 16, false, true)\n * => 'too-long-for-number-conversion'\n */\nexport function fromBaseX(value, baseOrAlphabet=64, useCharacterMap=false, useChunks=false, valueIsNumber=false){\n\tconst __methodName__ = 'fromBaseX';\n\n\tvalueIsNumber = !!valueIsNumber\n\t\t|| isInt(value)\n\t\t|| (`${value}`.startsWith('{') && `${value}`.endsWith('}'))\n\t;\n\tvalue = `${value}`;\n\tif( valueIsNumber ){\n\t\tvalue = trim(value, ['{', '}']);\n\t}\n\tconst valueIsNegativeNumber = valueIsNumber && value.startsWith('-');\n\tif( valueIsNegativeNumber ){\n\t\tvalue = value.slice(1);\n\t}\n\n\tuseCharacterMap = orDefault(useCharacterMap, false, 'bool');\n\tuseChunks = orDefault(useChunks, false, 'bool');\n\n\tif(\n\t\t(baseOrAlphabet === 64)\n\t\t&& !useCharacterMap\n\t\t&& !useChunks\n\t\t&& !valueIsNumber\n\t) return base64ToString(value, __methodName__);\n\n\tconst alphabet = buildAlphabet(__methodName__, baseOrAlphabet, useChunks);\n\tif( alphabet.includes('{') || alphabet.includes('}') ){\n\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | invalid alphabet, must not contain \"{\" or \"}\"`)\n\t}\n\n\tlet\n\t\tbase64Value = '',\n\t\tbase10Value = 0,\n\t\tdecodedValue\n\t;\n\n\tif( useCharacterMap ){\n\t\tconst\n\t\t\tpageMap = buildPageMap(alphabet),\n\t\t\tcharMap = buildCharMap(pageMap, alphabet),\n\t\t\tinverseCharMap = Object.fromEntries(\n\t\t\t\tObject\n\t\t\t\t.entries(charMap)\n\t\t\t\t.map(([key, value]) => [value, key])\n\t\t\t),\n\t\t\ttokensByLength = Object.keys(inverseCharMap).sort((a, b) => {\n\t\t\t\treturn (a.length === b.length) ? 0 : ((a.length > b.length) ? -1 : 1);\n\t\t\t})\n\t\t;\n\n\t\tlet tokenFound = false;\n\t\twhile( value !== '' ){\n\t\t\tfor( let token of tokensByLength ){\n\t\t\t\ttokenFound = false;\n\t\t\t\tif( value.startsWith(token) ){\n\t\t\t\t\ttokenFound = true;\n\t\t\t\t\tbase64Value += inverseCharMap[token];\n\t\t\t\t\tvalue = value.slice(token.length);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif( !tokenFound ){\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${MODULE_NAME}:${__methodName__} | unknown token at start of \"${value}\", likely due to non-matching alphabet`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tdecodedValue = base64ToString(base64Value, __methodName__);\n\t\tif( valueIsNegativeNumber ){\n\t\t\tdecodedValue = `-${decodedValue}`;\n\t\t}\n\n\t\treturn decodedValue;\n\t} else {\n\t\tdecodedValue = '';\n\n\t\tconst\n\t\t\tchunkAlphabet = useChunks ? alphabet.slice(1) : alphabet,\n\t\t\tchunkSeparator = useChunks ? alphabet[0] : '',\n\t\t\tchunks = useChunks ? value.split(chunkSeparator) : [value]\n\t\t;\n\n\t\tfor( let chunk of chunks ){\n\t\t\tbase10Value = baseXToBase10(chunk, chunkAlphabet);\n\n\t\t\tif( valueIsNumber ){\n\t\t\t\tdecodedValue += `${base10Value}`;\n\t\t\t} else {\n\t\t\t\tbase64Value += base10toBaseX(base10Value, BASE64_ALPHABET);\n\t\t\t}\n\t\t}\n\n\t\tif( decodedValue === '' ){\n\t\t\tdecodedValue = base64ToString(base64Value, __methodName__)\n\t\t\tif( valueIsNegativeNumber ){\n\t\t\t\tdecodedValue = `-${decodedValue}`;\n\t\t\t}\n\t\t}\n\n\t\tif( !useChunks && valueIsNumber ){\n\t\t\tdecodedValue = Number(decodedValue);\n\t\t\tif( valueIsNegativeNumber && (decodedValue >= 0) ){\n\t\t\t\tdecodedValue = -decodedValue;\n\t\t\t}\n\t\t}\n\n\t\treturn decodedValue;\n\t}\n}\n"]} \ No newline at end of file +{"version":3,"file":"conversion.js","names":["MODULE_NAME","isInt","isArray","orDefault","pad","trim","UPPER_CHARS","LOWER_CHARS","NUMBERS","BASE_ALPHABETS","slice","BASE64_ALPHABET","buildAlphabet","__methodName__","baseOrAlphabet","useChunks","alphabet","Error","baseAlphabetKey","Object","keys","sort","Number","split","forEach","char","concat","Array","from","Set","a","b","aBase64Index","indexOf","bBase64Index","join","length","calculateNeededPages","base","availablePages","Math","floor","neededPages","charPoolSize","combinations","buildPageMap","pageMap","remainder","quotient","i","ceil","push","buildCharMap","pagedAlphabet","min","pagedBase","charMap","stringToBase64","value","btoa","String","fromCodePoint","TextEncoder","encode","replaceAll","base64ToString","res","TextDecoder","decode","Uint8Array","atob","codePointAt","ex","base10toBaseX","baseXValue","baseXToBase10","reverse","base10Value","pow","toBaseX","useCharacterMap","chunkSize","valueIsNumber","valueIsNegativeNumber","abs","includes","base64Value","chunks","chunkAlphabet","chunkSeparator","chunkStart","chunk","decodedValue","fromBaseX","startsWith","endsWith","inverseCharMap","fromEntries","entries","map","key","tokensByLength","tokenFound","token"],"sources":["conversion.js"],"mappings":"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","ignoreList":[],"sourcesContent":["/*!\n * Module Conversion\n */\n\n/**\n * @namespace Conversion\n */\n\nconst MODULE_NAME = 'Conversion';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {isInt, isArray, orDefault} from './basic.js';\nimport {pad, trim} from './strings.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst\n\tUPPER_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',\n\tLOWER_CHARS = 'abcdefghijklmnopqrstuvwxyz',\n\tNUMBERS = '0123456789',\n\tBASE_ALPHABETS = {\n\t\t'64' : `${UPPER_CHARS}${LOWER_CHARS}${NUMBERS}+/`,\n\t\t'63' : `${NUMBERS}${UPPER_CHARS}${LOWER_CHARS}_`,\n\t\t'36' : `${NUMBERS}${UPPER_CHARS}`,\n\t\t'26' : UPPER_CHARS,\n\t\t'16' : `${NUMBERS}${UPPER_CHARS.slice(0, 6)}`,\n\t\t'10' : NUMBERS,\n\t\t'8' : NUMBERS.slice(0, 8),\n\t\t'2' : NUMBERS.slice(0, 2)\n\t},\n\tBASE64_ALPHABET = BASE_ALPHABETS['64']\n;\n\n\n\n//###[ HELPERS ]########################################################################################################\n\n/**\n * Builds an alphabet string, based on an integer, an alphabet string or an array of strings containing the alphabet's\n * chars. An integer uses BASE_ALPHABETS to select a base alphabet to slice the alphabet from. The first base alphabet\n * having enough chars is going be used. The configurations of the base alphabets are according to current base\n * practices.\n *\n * Characters in custom alphabets are sorted according to base64 definition, with additional chars appended at the end,\n * sorted ascending based on char value.\n *\n * @private\n */\nfunction buildAlphabet(__methodName__='buildAlphabet', baseOrAlphabet=64, useChunks=false){\n\tbaseOrAlphabet = orDefault(baseOrAlphabet, 64);\n\n\tlet alphabet;\n\n\tif( isInt(baseOrAlphabet) ){\n\t\tif( (baseOrAlphabet < 2) || (baseOrAlphabet > 64) ){\n\t\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | base not usable, smaller than 2 or larger than 64`);\n\t\t}\n\n\t\tif( useChunks && (baseOrAlphabet < 3) ){\n\t\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | base not usable for chunks, smaller than 3`);\n\t\t}\n\n\t\tfor( let baseAlphabetKey of Object.keys(BASE_ALPHABETS).sort() ){\n\t\t\tif( Number(baseAlphabetKey) >= baseOrAlphabet ){\n\t\t\t\talphabet = BASE_ALPHABETS[baseAlphabetKey].slice(0, baseOrAlphabet);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} else {\n\t\talphabet = [];\n\n\t\tif( !isArray(baseOrAlphabet) ){\n\t\t\tbaseOrAlphabet = `${baseOrAlphabet}`.split('');\n\t\t}\n\n\t\tbaseOrAlphabet.forEach(char => {\n\t\t\talphabet = alphabet.concat(`${char}`.split(''));\n\t\t});\n\n\t\talphabet = Array.from(new Set(alphabet));\n\t\talphabet.sort((a, b) => {\n\t\t\tconst\n\t\t\t\taBase64Index = BASE64_ALPHABET.indexOf(a),\n\t\t\t\tbBase64Index = BASE64_ALPHABET.indexOf(b)\n\t\t\t;\n\n\t\t\tif( (aBase64Index < 0) && (bBase64Index < 0) ){\n\t\t\t\treturn (a === b) ? 0 : ((a < b) ? -1 : 1);\n\t\t\t} else if( aBase64Index < 0 ){\n\t\t\t\treturn 1;\n\t\t\t} else if( bBase64Index < 0 ){\n\t\t\t\treturn -1;\n\t\t\t} else {\n\t\t\t\treturn (aBase64Index === bBase64Index) ? 0 : ((aBase64Index < bBase64Index) ? -1 : 1);\n\t\t\t}\n\t\t});\n\n\t\talphabet = alphabet.join('');\n\t}\n\n\tif( (alphabet.length < 2) || (alphabet.length > 64) ){\n\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | alphabet not usable, must have between two and 64 chars`);\n\t}\n\n\tif( useChunks && (alphabet.length < 3) ){\n\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | alphabet not usable for chunks, less than 3 chars`);\n\t}\n\n\treturn alphabet;\n}\n\n\n\n/**\n * Calculates how many character mapping pages/page characters we need for a specific alphabet,\n * defined by its length/base.\n *\n * @private\n */\nfunction calculateNeededPages(base){\n\tconst availablePages = Math.floor(base / 2);\n\tlet\n\t\tneededPages = 0,\n\t\tcharPoolSize = base,\n\t\tcombinations = charPoolSize\n\t;\n\n\twhile( combinations < 64 ){\n\t\tneededPages++;\n\t\tif( neededPages <= availablePages ){\n\t\t\tcharPoolSize--;\n\t\t}\n\t\tcombinations = (neededPages + 1) * charPoolSize;\n\t}\n\n\treturn neededPages;\n}\n\n\n\n/**\n * Returns an array of value prefixes used to map characters to different code pages, in cases where we need to encode\n * a base64 character above the base of our target alphabet, which means, that we have to repeat character usage, but\n * with a page prefix to multiply the value set by reducing the base alphabet for that purpose.\n *\n * @private\n */\nfunction buildPageMap(alphabet){\n\tconst\n\t\tbase = alphabet.length,\n\t\tneededPages = calculateNeededPages(base),\n\t\tavailablePages = Math.floor(base / 2),\n\t\tpageMap = ['']\n\t;\n\n\tlet remainder, quotient;\n\tfor( let i = 1; i <= neededPages; i++ ){\n\t\tremainder = i % availablePages;\n\t\tquotient = Math.ceil(i / availablePages);\n\t\tpageMap.push(pad('', alphabet[(remainder > 0) ? (remainder - 1) : (availablePages - 1)], quotient));\n\t}\n\n\treturn pageMap;\n}\n\n\n\n/**\n * Returns a dictionary, mapping each base64 character to one or more characters of the target alphabet.\n * In cases, where the character to encode is beyond the target alphabet, page prefixes are prepended to\n * cover all characters by increasing length.\n *\n * @private\n */\nfunction buildCharMap(pageMap, alphabet){\n\tconst\n\t\tbase = alphabet.length,\n\t\tneededPages = calculateNeededPages(base),\n\t\tavailablePages = Math.floor(base / 2),\n\t\tpagedAlphabet = alphabet.slice(Math.min(neededPages, availablePages)),\n\t\tpagedBase = pagedAlphabet.length,\n\t\tcharMap = {}\n\t;\n\n\tlet remainder, quotient;\n\tfor( let i in BASE64_ALPHABET.split('') ){\n\t\tremainder = i % pagedBase;\n\t\tquotient = Math.floor(i / pagedBase);\n\t\tcharMap[BASE64_ALPHABET[i]] = `${pageMap[quotient]}${pagedAlphabet[remainder]}`\n\t}\n\n\treturn charMap;\n}\n\n\n\n/**\n * Converts a string to base64, while handling unicode characters correctly.\n * Be advised, that the result needs to be decoded with base64ToString() again, since\n * we also need to correctly handle unicode on the way back.\n *\n * @private\n */\nfunction stringToBase64(value){\n\treturn btoa(String.fromCodePoint(...((new TextEncoder()).encode(`${value}`)))).replaceAll('=', '');\n}\n\n\n\n/**\n * Decodes a base64-encoded string to its original value.\n * Be advised, that the base64 value has to be encoded using stringToBase64(), since unicode characters need\n * special handling during en/decoding.\n *\n * This function will fail with an error, if the given value is not actually decodable with base64.\n *\n * @private\n */\nfunction base64ToString(value, __methodName__='base64ToString'){\n\tlet res = null;\n\n\ttry {\n\t\tres = (new TextDecoder()).decode(Uint8Array.from(atob(`${value}`), char => char.codePointAt(0)))\n\t} catch(ex){\n\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | cannot decode \"${value}\"`);\n\t}\n\n\treturn res;\n}\n\n\n\n/**\n * Converts a decimal/base10 value to a different base numerically.\n * Be aware that this needs the value to be a safe integer.\n * This function does not deal with negative numbers by itself.\n *\n * @private\n */\nfunction base10toBaseX(value, alphabet){\n\tconst base = alphabet.length;\n\tlet\n\t\tbaseXValue = '',\n\t\tquotient = value,\n\t\tremainder\n\t;\n\n\tif( quotient !== 0){\n\t\twhile( quotient !== 0 ){\n\t\t\tremainder = quotient % base;\n\t\t\tquotient = Math.floor(quotient / base);\n\t\t\tbaseXValue = `${alphabet[remainder]}${baseXValue}`;\n\t\t}\n\t} else {\n\t\tbaseXValue = `${alphabet[0]}`;\n\t}\n\n\treturn baseXValue;\n}\n\n\n\n/**\n * Converts a value, based on a defined alphabet, to its decimal/base10 representation.\n * Be aware that this needs the result to be a safe integer.\n * This function does not deal with negative numbers by itself.\n *\n * @private\n */\nfunction baseXToBase10(value, alphabet){\n\tvalue = `${value}`.split('').reverse().join('');\n\n\tconst base = alphabet.length;\n\tlet base10Value = 0;\n\n\tfor( let i = 0; i < value.length; i++ ){\n\t\tbase10Value += Math.pow(base, i) * alphabet.indexOf(value[i]);\n\t}\n\n\treturn base10Value;\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Conversion:toBaseX\n */\n\n/**\n * This function converts a value to a representation in a defined base between 2 and 64.\n * So this covers common use cases like binary, octal, hexadecimal, alphabetical, alphanumeric and of course base64.\n *\n * The result of this function is always either a decimal number or a string, just as the input value. All numbers\n * apart from decimal ones are returned as strings without prefix. So, decimal 5 will be the number 5, but the binary\n * version will be the string \"101\". Positive and negative decimal integers are valid numbers here, but this\n * implementation does not support floats (multiply and divide if needed). Only numerical bases above 36 contain\n * lower case characters, so decimal 255 is \"FF\" in base 16 and not \"ff\".\n *\n * This function is unicode safe, by using byte conversion\n * (see: https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem).\n * Be aware, that this also means, that results of `btoa/atob()` and `toBaseX/fromBaseX()` are _not_ interchangeable,\n * since they work with different values internally.\n *\n * There are three approaches to changing the base of a value in JavaScript:\n *\n * 1. Either you are taking the numerical/mathematical road, treating a value as a number in its alphabet being\n * interpreted as a number, where each character, counting from the back is the base to the power of the\n * character index. This is the approach you'd expect, when, for instance, you'd want to convert the decimal number 5\n * to binary 101. The downside of this approach is, that the relatively small max safe integer in JavaScript makes\n * converting large numbers, such as longer strings, impossible.\n *\n * 2. Therefore, the second approach takes the numeric approach, but combines it with chunking, splitting the value into\n * pieces, which are, by themselves, safely convertible. The downside is, that we need an extra character to delimit\n * chunks in the result, since values have non-uniform lengths. This means, that this does not work with the basic\n * binary base, and we need at least 3 alphabet characters.\n *\n * 3. The last approach uses the native base64 string encoding with `btoa()` as a safe translation layer, mapping the\n * resulting string to the target base, using a generated (and possibly paged) character map. This way treats all\n * values as strings and is not compatible to numerical conversion anymore, but uses the same characters. The result\n * of this approach can encode every string of every length without structural tricks, but has the longest results.\n *\n * This function is capable of all three approaches, which are equally safe for unicode values. The numerical\n * approach is the default. If you want to encode large numbers or strings longer than ~6 characters, select\n * a different approach using the `useCharacterMap` or `useChunks` parameters. Character mapping has preference, while\n * chunks have no effect in character mapping.\n *\n * Each encoding process ends with a self-test, checking if the result is actually decodable using\n * `fromBaseX()`, using the same settings again. This ensures, that every result is valid and retrievable in the future,\n * preventing any undiscovered errors, which would make it impossible to work with the original value again.\n *\n * You may define the base as an integer between 2 and 64 or as a custom alphabet in the same range. Integer based\n * alphabets are generated using defined base alphabets, which are sliced if necessary. Custom alphabets are\n * automatically sorted to match base64 are far as possible, pushing additional characters to the end, which are then\n * sorted ascending by character value.\n *\n * \"{\" and \"}\" are the only forbidden characters in a custom alphabet, since we need these to mark number values in\n * `fromBaseX()`.\n *\n * Numerical conversion keeps negative numbers negative and marks the result with a preceding \"-\".\n *\n * Hint: if you want to genrate codes to be presented to the user, see `Random:randomUserCode`.\n *\n * @param {Number|String} value - value to be encoded\n * @param {?Number|String|Array} [baseOrAlphabet=64] - either the numerical base to convert to (64, 36, ...) or the alphabet of characters to use in encoding; numerical bases must be between 2 and 64 (if the result is chunked, we need a base 3)\n * @param {?Boolean} [useCharacterMap=true] - set to true, to use a character map, based on btoa(), instead of numerical conversion\n * @param {?Boolean} [useChunks=false] - set to true, to add chunking to the numerical approach, converting the value in groups separated by a delimiter, which is the first letter of the base's alphabet\n * @param {?Number} [chunkSize=6] - define a different chunks size; only change this, if 6 seems too big in your context, going higher is not advisable\n * @throws error if baseOrAlphabet is not usable\n * @throws error if result is not decodable again using the same settings\n * @returns {String} the encoded value\n *\n * @memberof Conversion:toBaseX\n * @alias toBaseX\n * @see fromBaseX\n * @see https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem\n * @see Random:randomUserCode\n * @example\n * toBaseX('foobar')\n * => 'Zm9vYmFy'\n * toBaseX(-5, 2)\n * => '-101'\n * toBaseX(42, 'abcdefghij')\n * => 'ec'\n * toBaseX('too-long-for-number-conversion', 36, true)\n * => 'U70R0DCN0F0DS04T0BQ040R0GCN0N0JSNA03TZ0J01S0K0N0KQOA0HRN0R0C'\n * toBaseX('too-long-for-number-conversion', 16, false, true)\n * => 'D3EF5D81F026D9DFDA970BBF17222402A47D5AD650CF6C2FE2102A494BCBDD0A2864C'\n */\nexport function toBaseX(value, baseOrAlphabet=64, useCharacterMap=false, useChunks=false, chunkSize=6){\n\tconst __methodName__ = 'toBaseX';\n\n\tconst\n\t\tvalueIsNumber = isInt(value),\n\t\tvalueIsNegativeNumber = valueIsNumber && (value < 0)\n\t;\n\n\tvalue = valueIsNumber ? `${Math.abs(value)}` : `${value}`;\n\tuseCharacterMap = orDefault(useCharacterMap, false, 'bool');\n\tuseChunks = orDefault(useChunks, false, 'bool');\n\tchunkSize = orDefault(chunkSize, 10, 'int');\n\n\tconst alphabet = buildAlphabet(__methodName__, baseOrAlphabet, useChunks);\n\tif( alphabet.includes('{') || alphabet.includes('}') ){\n\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | invalid alphabet, must not contain \"{\" or \"}\"`)\n\t}\n\n\tlet\n\t\tbase64Value = '',\n\t\tbase10Value = 0,\n\t\tbaseXValue = ''\n\t;\n\n\tif( useCharacterMap ){\n\t\tbase64Value = stringToBase64(value);\n\t\tif( baseOrAlphabet === 64 ) return base64Value;\n\n\t\tconst\n\t\t\tpageMap = buildPageMap(alphabet),\n\t\t\tcharMap = buildCharMap(pageMap, alphabet)\n\t\t;\n\n\t\tfor( let char of base64Value ){\n\t\t\tbaseXValue += charMap[char];\n\t\t}\n\t} else {\n\t\tif( valueIsNumber ){\n\t\t\tbase64Value = base10toBaseX(value, BASE64_ALPHABET);\n\t\t} else {\n\t\t\tbase64Value = stringToBase64(value);\n\t\t}\n\n\t\tconst\n\t\t\tchunks = [],\n\t\t\tchunkAlphabet = useChunks ? alphabet.slice(1) : alphabet,\n\t\t\tchunkSeparator = useChunks ? alphabet[0] : ''\n\t\t;\n\n\t\tif( useChunks ){\n\t\t\tlet chunkStart = 0;\n\t\t\twhile( chunkStart < base64Value.length ){\n\t\t\t\tchunks.push(base64Value.slice(chunkStart, chunkStart + chunkSize));\n\t\t\t\tchunkStart += chunkSize;\n\t\t\t}\n\t\t} else {\n\t\t\tchunks.push(base64Value);\n\t\t}\n\n\t\tfor( let chunk of chunks ){\n\t\t\tbase10Value = baseXToBase10(chunk, BASE64_ALPHABET);\n\n\t\t\tif( !useChunks && (baseOrAlphabet === 10) ){\n\t\t\t\tbaseXValue += base10Value;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tbaseXValue += `${chunkSeparator}${base10toBaseX(base10Value, chunkAlphabet)}`;\n\t\t}\n\n\t\tif( chunkSeparator !== '' ){\n\t\t\tbaseXValue = baseXValue.slice(1);\n\t\t}\n\t}\n\n\tbaseXValue = `${valueIsNegativeNumber ? '-' : ''}${baseXValue}`;\n\tconst decodedValue = `${fromBaseX(baseXValue, baseOrAlphabet, useCharacterMap, useChunks, valueIsNumber)}`;\n\tif( decodedValue !== `${valueIsNegativeNumber ? '-' : ''}${value}` ){\n\t\tthrow new Error(\n\t\t\t`${MODULE_NAME}:${__methodName__} | critical error, encoded value \"${baseXValue}\" `\n\t\t\t+`not decodable to \"${value}\", is \"${decodedValue}\" instead; `\n\t\t\t+`if this looks \"cut off\", this may be a problem with JS max safe integer size `\n\t\t\t+`(safe value length for number-based conversion is just ~8 chars), `\n\t\t\t+`try using character mapping or chunks to circumvent this problem`\n\t\t);\n\t}\n\treturn baseXValue;\n}\n\n\n\n/**\n * @namespace Conversion:fromBaseX\n */\n\n/**\n * This function converts a based representation back to its original number or string value.\n * This is the mirror function to `toBaseX()` and expects a value encoded with that function. See that function\n * for implementation details, modes and restrictions.\n *\n * The result of this function is always either a decimal number or a string, just as the input value. All numbers\n * apart from decimal ones are returned as strings without prefix. So, decimal 5 will be the number 5, but the binary\n * version will be the string \"101\".\n *\n * You may define the base as an integer between 2 and 64 or as a custom alphabet in the same range. Integer based\n * alphabets are generated using defined base alphabets, which are sliced if necessary. Custom alphabets are\n * automatically sorted to match base64 are far as possible, pushing additional characters to the end, which are then\n * sorted ascending by character value.\n *\n * \"{\" and \"}\" are the only forbidden characters in a custom alphabet, since we need these to mark number values in\n * `fromBaseX()`.\n *\n * Numerical conversion keeps negative numbers negative and marks the result with a preceding \"-\".\n *\n * @param {Number|String} value - value to be decoded\n * @param {?Number|String|Array} [baseOrAlphabet=64] - either the numerical base to convert to (64, 36, ...) or the alphabet of characters to use in encoding; numerical bases must be between 2 and 64 (if the result is chunked, we need a base 3)\n * @param {?Boolean} [useCharacterMap=true] - set to true, to use a character map, based on btoa(), instead of numerical conversion\n * @param {?Boolean} [useChunks=false] - set to true, to add chunking to the numerical approach, converting the value in groups separated by a delimiter, which is the first letter of the base's alphabet\n * @param {?Boolean} [valueIsNumber=false] - if true, the given value is treated as a number for numerical conversion; this is necessary, since numbers such as binaries are defined as strings and are therefore not auto-detectable\n * @throws error if baseOrAlphabet is not usable\n * @throws error character mapped decoding fails, due to missing token/unmatched alphabet\n * @returns {String} the decoded value\n *\n * @memberof Conversion:fromBaseX\n * @alias fromBaseX\n * @see toBaseX\n * @example\n * fromBaseX('Zm9vYmFy')\n * => 'foobar'\n * fromBaseX('16W33YPUS', 36)\n * => 'äす'\n * fromBaseX('{-3C3}', 13)\n * => -666\n * fromBaseX('q', 64, false, false, true)\n * => 42\n * fromBaseX('U70R0DCN0F0DS04T0BQ040R0GCN0N0JSNA03TZ0J01S0K0N0KQOA0HRN0R0C', 36, true)\n * => 'too-long-for-number-conversion'\n * fromBaseX('D3EF5D81F026D9DFDA970BBF17222402A47D5AD650CF6C2FE2102A494BCBDD0A2864C', 16, false, true)\n * => 'too-long-for-number-conversion'\n */\nexport function fromBaseX(value, baseOrAlphabet=64, useCharacterMap=false, useChunks=false, valueIsNumber=false){\n\tconst __methodName__ = 'fromBaseX';\n\n\tvalueIsNumber = !!valueIsNumber\n\t\t|| isInt(value)\n\t\t|| (`${value}`.startsWith('{') && `${value}`.endsWith('}'))\n\t;\n\tvalue = `${value}`;\n\tif( valueIsNumber ){\n\t\tvalue = trim(value, ['{', '}']);\n\t}\n\tconst valueIsNegativeNumber = valueIsNumber && value.startsWith('-');\n\tif( valueIsNegativeNumber ){\n\t\tvalue = value.slice(1);\n\t}\n\n\tuseCharacterMap = orDefault(useCharacterMap, false, 'bool');\n\tuseChunks = orDefault(useChunks, false, 'bool');\n\n\tif(\n\t\t(baseOrAlphabet === 64)\n\t\t&& !useCharacterMap\n\t\t&& !useChunks\n\t\t&& !valueIsNumber\n\t) return base64ToString(value, __methodName__);\n\n\tconst alphabet = buildAlphabet(__methodName__, baseOrAlphabet, useChunks);\n\tif( alphabet.includes('{') || alphabet.includes('}') ){\n\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | invalid alphabet, must not contain \"{\" or \"}\"`)\n\t}\n\n\tlet\n\t\tbase64Value = '',\n\t\tbase10Value = 0,\n\t\tdecodedValue\n\t;\n\n\tif( useCharacterMap ){\n\t\tconst\n\t\t\tpageMap = buildPageMap(alphabet),\n\t\t\tcharMap = buildCharMap(pageMap, alphabet),\n\t\t\tinverseCharMap = Object.fromEntries(\n\t\t\t\tObject\n\t\t\t\t.entries(charMap)\n\t\t\t\t.map(([key, value]) => [value, key])\n\t\t\t),\n\t\t\ttokensByLength = Object.keys(inverseCharMap).sort((a, b) => {\n\t\t\t\treturn (a.length === b.length) ? 0 : ((a.length > b.length) ? -1 : 1);\n\t\t\t})\n\t\t;\n\n\t\tlet tokenFound = false;\n\t\twhile( value !== '' ){\n\t\t\tfor( let token of tokensByLength ){\n\t\t\t\ttokenFound = false;\n\t\t\t\tif( value.startsWith(token) ){\n\t\t\t\t\ttokenFound = true;\n\t\t\t\t\tbase64Value += inverseCharMap[token];\n\t\t\t\t\tvalue = value.slice(token.length);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif( !tokenFound ){\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${MODULE_NAME}:${__methodName__} | unknown token at start of \"${value}\", likely due to non-matching alphabet`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tdecodedValue = base64ToString(base64Value, __methodName__);\n\t\tif( valueIsNegativeNumber ){\n\t\t\tdecodedValue = `-${decodedValue}`;\n\t\t}\n\n\t\treturn decodedValue;\n\t} else {\n\t\tdecodedValue = '';\n\n\t\tconst\n\t\t\tchunkAlphabet = useChunks ? alphabet.slice(1) : alphabet,\n\t\t\tchunkSeparator = useChunks ? alphabet[0] : '',\n\t\t\tchunks = useChunks ? value.split(chunkSeparator) : [value]\n\t\t;\n\n\t\tfor( let chunk of chunks ){\n\t\t\tbase10Value = baseXToBase10(chunk, chunkAlphabet);\n\n\t\t\tif( valueIsNumber ){\n\t\t\t\tdecodedValue += `${base10Value}`;\n\t\t\t} else {\n\t\t\t\tbase64Value += base10toBaseX(base10Value, BASE64_ALPHABET);\n\t\t\t}\n\t\t}\n\n\t\tif( decodedValue === '' ){\n\t\t\tdecodedValue = base64ToString(base64Value, __methodName__)\n\t\t\tif( valueIsNegativeNumber ){\n\t\t\t\tdecodedValue = `-${decodedValue}`;\n\t\t\t}\n\t\t}\n\n\t\tif( !useChunks && valueIsNumber ){\n\t\t\tdecodedValue = Number(decodedValue);\n\t\t\tif( valueIsNegativeNumber && (decodedValue >= 0) ){\n\t\t\t\tdecodedValue = -decodedValue;\n\t\t\t}\n\t\t}\n\n\t\treturn decodedValue;\n\t}\n}\n"]} \ No newline at end of file diff --git a/dist/cookies.js b/dist/cookies.js index b8ff5aa1..7af05ef8 100644 --- a/dist/cookies.js +++ b/dist/cookies.js @@ -1,8 +1,8 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Cookies */ -const MODULE_NAME="Cookies";import{assert,isDate,orDefault,hasValue}from"./basic.js";import{warn}from"./logging.js";function encodeCookieValue(e){return encodeURIComponent(e).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,decodeURIComponent)}function decodeCookieValue(e){return'"'===e[0]&&(e=e.slice(1,-1)),e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent)}function encodeCookieName(e){return encodeURIComponent(`${e}`).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape)}function decodeCookieName(e){return decodeURIComponent(e)}function normalizeCookieOptions(e){e=orDefault(e,{});const o={};for(let t in e)o[t.toLowerCase()]=e[t];return hasValue((e=o).expires)?(isDate(e.expires)||(e.expires=new Date(Date.now()+24*Math.round(parseFloat(e.expires))*60*60*1e3)),e.expires=e.expires.toUTCString()):e.expires=null,e["max-age"]=orDefault(e["max-age"],null,"int"),e.path=orDefault(e.path,"/","str"),"auto"===e.path&&(e.path=""),e.domain=orDefault(e.domain,null,"str"),e.httponly=orDefault(e.httponly,!1,"bool"),e.samesite=orDefault(e.samesite,"lax","str").toLowerCase(),["strict","lax","none"].includes(e.samesite)||console.warn(`Cookies:setCookie | unknown samesite mode "${e.samesite}"`),e.secure=orDefault(e.secure,"none"===e.samesite,"bool"),e}export function getCookie(e){const o=hasValue(e)?new Set([].concat(e).map((e=>e.trim()))):new Set,t=new Set;let n=0===o.size?{}:null;if(!hasValue(document.cookie))return n;const i=document.cookie.split(";");for(let e in i)try{const a=i[e].trim().split("="),r=decodeCookieName(a[0]).trim(),s=decodeCookieValue(a.slice(1).join("="));if(""!==r&&(o.has(r)||0===o.size)&&(null===n&&(n={}),n[r]=s,t.add(r),t.size===o.size&&0!==o.size))break}catch(o){warn(`Cookies:getCookie | decoding cookie "${i[e]}" failed with "${o}"`)}return 1===o.size?n?.[e]??null:n}export function getCookies(e){return e=[],Array.from(arguments).forEach((o=>{e=e.concat(o)})),getCookie(e)}export function setCookie(e,o,t){assert(hasValue(e)&&""!==e,"Cookies:setCookie | no usable name"),e=`${e}`.trim(),o=hasValue(o)?encodeCookieValue(orDefault(o,"","str")):null,t=normalizeCookieOptions(t);let n="";for(let e in t){const o=t[e];hasValue(o)&&!1!==o&&(n+=`; ${e}`,!0!==o&&(n+=`=${o.split(";")[0]}`))}return hasValue(o)?document.cookie=`${encodeCookieName(e)}=${o}${n}`:removeCookie(e,t),getCookie(e)}export function removeCookie(e,o){return assert(hasValue(e)&&""!==e,"Cookies:removeCookie | no usable name"),(o=normalizeCookieOptions(o)).expires=-1,null===setCookie(e,"",o)} +const MODULE_NAME="Cookies";import{assert,isDate,orDefault,hasValue}from"./basic.js";import{warn}from"./logging.js";function encodeCookieValue(e){return encodeURIComponent(e).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,decodeURIComponent)}function decodeCookieValue(e){return'"'===e[0]&&(e=e.slice(1,-1)),e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent)}function encodeCookieName(e){return encodeURIComponent(`${e}`).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape)}function decodeCookieName(e){return decodeURIComponent(e)}function normalizeCookieOptions(e){e=orDefault(e,{});const o={};for(let t in e)o[t.toLowerCase()]=e[t];return hasValue((e=o).expires)?(isDate(e.expires)||(e.expires=new Date(Date.now()+24*Math.round(parseFloat(e.expires))*60*60*1e3)),e.expires=e.expires.toUTCString()):e.expires=null,e["max-age"]=orDefault(e["max-age"],null,"int"),e.path=orDefault(e.path,"/","str"),"auto"===e.path&&(e.path=""),e.domain=orDefault(e.domain,null,"str"),e.httponly=orDefault(e.httponly,!1,"bool"),e.samesite=orDefault(e.samesite,"lax","str").toLowerCase(),["strict","lax","none"].includes(e.samesite)||console.warn(`${MODULE_NAME}:setCookie | unknown samesite mode "${e.samesite}"`),e.secure=orDefault(e.secure,"none"===e.samesite,"bool"),e}export function getCookie(e){const o=hasValue(e)?new Set([].concat(e).map((e=>e.trim()))):new Set,t=new Set;let n=0===o.size?{}:null;if(!hasValue(document.cookie))return n;const i=document.cookie.split(";");for(let e in i)try{const a=i[e].trim().split("="),r=decodeCookieName(a[0]).trim(),s=decodeCookieValue(a.slice(1).join("="));if(""!==r&&(o.has(r)||0===o.size)&&(null===n&&(n={}),n[r]=s,t.add(r),t.size===o.size&&0!==o.size))break}catch(o){warn(`${MODULE_NAME}:getCookie | decoding cookie "${i[e]}" failed with "${o}"`)}return 1===o.size?n?.[e]??null:n}export function getCookies(e){return e=[],Array.from(arguments).forEach((o=>{e=e.concat(o)})),getCookie(e)}export function setCookie(e,o,t){assert(hasValue(e)&&""!==e,`${MODULE_NAME}:setCookie | no usable name`),e=`${e}`.trim(),o=hasValue(o)?encodeCookieValue(orDefault(o,"","str")):null,t=normalizeCookieOptions(t);let n="";for(let e in t){const o=t[e];hasValue(o)&&!1!==o&&(n+=`; ${e}`,!0!==o&&(n+=`=${o.split(";")[0]}`))}return hasValue(o)?document.cookie=`${encodeCookieName(e)}=${o}${n}`:removeCookie(e,t),getCookie(e)}export function removeCookie(e,o){return assert(hasValue(e)&&""!==e,`${MODULE_NAME}:removeCookie | no usable name`),(o=normalizeCookieOptions(o)).expires=-1,null===setCookie(e,"",o)} //# sourceMappingURL=cookies.js.map diff --git a/dist/cookies.js.map b/dist/cookies.js.map index 66ddbf83..a3fb8ea4 100644 --- a/dist/cookies.js.map +++ b/dist/cookies.js.map @@ -1 +1 @@ -{"version":3,"file":"cookies.js","names":["MODULE_NAME","assert","isDate","orDefault","hasValue","warn","encodeCookieValue","value","encodeURIComponent","replace","decodeURIComponent","decodeCookieValue","slice","encodeCookieName","name","escape","decodeCookieName","normalizeCookieOptions","options","normalizedOptions","optionsProp","toLowerCase","expires","Date","now","Math","round","parseFloat","toUTCString","path","domain","httponly","samesite","includes","console","secure","getCookie","names","Set","concat","map","n","trim","foundNames","res","size","document","cookie","cookies","split","i","cookieParts","cookieName","cookieValue","join","has","add","ex","getCookies","Array","from","arguments","forEach","argument","setCookie","cookieOptions","option","removeCookie"],"sources":["cookies.js"],"mappings":"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","sourcesContent":["/*!\n * Module Cookies\n */\n\n/**\n * @namespace Cookies\n */\n\nconst MODULE_NAME = 'Cookies';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {assert, isDate, orDefault, hasValue} from './basic.js';\nimport {warn} from './logging.js';\n\n\n\n//###[ HELPERS ]########################################################################################################\n\n/*\n * Encodes a string to be stored in a cookie.\n *\n * @private\n */\nfunction encodeCookieValue(value){\n\treturn encodeURIComponent(value).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g, decodeURIComponent);\n}\n\n\n\n/*\n * Decodes a cookie value to be used as a string in JavaScript.\n *\n * @private\n */\nfunction decodeCookieValue(value){\n\tif( value[0] === '\"' ){\n\t\tvalue = value.slice(1, -1);\n\t}\n\treturn value.replace(/(%[\\dA-F]{2})+/gi, decodeURIComponent);\n}\n\n\n\n/*\n * Makes sure a cookie name conforms to the cookie name rules and translates special chars to % representations.\n *\n * @private\n */\nfunction encodeCookieName(name){\n\treturn encodeURIComponent(`${name}`)\n\t\t.replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent)\n\t\t// using escape, because encodeURIComponent, indeed, does _not_ encode brackets\n\t\t.replace(/[()]/g, escape)\n\t;\n}\n\n\n\n/*\n * Decodes a cookie name, set prior with encodeCookieName to a standard JavaScript string again.\n *\n * @private\n */\nfunction decodeCookieName(name){\n\treturn decodeURIComponent(name);\n}\n\n\n\n/**\n * @typedef CookieOptions\n * @type {Object}\n *\n * @property {?Date|Number} [expires=null] - expiry time of the cookie, either a Date object or time in days\n * @property {?Number} [max-age=null] - max age of the cookie in seconds\n * @property {?String} [path='/'] - the cookie path, setting this to \"auto\" or an empty string defines auto-mode, which targets the current site path, which usually is the default, but we use '/' to set a cookie for while site, this being the common use-case\n * @property {?Boolean} [secure=false] - define if the cookie should only be transmitted via https (see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies)\n * @property {?Boolean} [httponly=false] - define this, if cookie should only be sent to servers and not be accessible to javascript (see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies)\n * @property {?String} [samesite=null] - define if this cookie should be included in cross-site requests, may be either \"strict\" (will only ever transmit same-site), \"lax\" (usual browser default, transmits same-site and top-level GET) or \"none\" (no restrictions, will always be sent)\n *\n * @memberof Cookies\n */\n\n/*\n * Makes sure, that supplied cookie options are in a usable form for setting a cookie.\n *\n * @private\n */\nfunction normalizeCookieOptions(options){\n\toptions = orDefault(options, {});\n\n\tconst normalizedOptions = {};\n\tfor( let optionsProp in options ){\n\t\tnormalizedOptions[optionsProp.toLowerCase()] = options[optionsProp];\n\t}\n\toptions = normalizedOptions;\n\n\tif( hasValue(options.expires) ){\n\t\tif( !isDate(options.expires) ){\n\t\t\toptions.expires = new Date(Date.now() + (Math.round(parseFloat(options.expires)) * 24 * 60 * 60 * 1000));\n\t\t}\n\t\toptions.expires = options.expires.toUTCString();\n\t} else {\n\t\toptions.expires = null;\n\t}\n\n\toptions['max-age'] = orDefault(options['max-age'], null, 'int');\n\n\toptions.path = orDefault(options.path, '/', 'str');\n\tif( options.path === 'auto' ){\n\t\toptions.path = '';\n\t}\n\n\toptions.domain = orDefault(options.domain, null, 'str');\n\n\toptions.httponly = orDefault(options.httponly, false, 'bool');\n\n\toptions.samesite = orDefault(options.samesite, 'lax', 'str').toLowerCase();\n\tif( !['strict', 'lax', 'none'].includes(options.samesite) ){\n\t\tconsole.warn(`${MODULE_NAME}:setCookie | unknown samesite mode \"${options.samesite}\"`);\n\t}\n\n\toptions.secure = orDefault(options.secure, options.samesite === 'none', 'bool');\n\n\treturn options;\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Cookies:getCookie\n */\n\n/**\n * Retrieves a decoded cookie value by name. Automatically decodes the value (assumes, that, if encoded, url/percent\n * encoding has been used).\n *\n * @param {?String|Array} [name] - the name of the cookie (or several names), if empty, all available cookies are returned\n * @returns {String|Object|null} decoded value of the cookie, null, if no such cookie available or a dictionary of found cookies if all or a list are being returned (if a list is requested and non are found, an empty object is returned)\n *\n * @memberof Cookies:getCookie\n * @alias getCookie\n * @see getCookies\n * @see setCookie\n * @see removeCookie\n * @example\n * getCookie('foobar')\n * => 'value'\n * getCookie(['foobar', 'boofar'])\n * => {foobar : 'value', boofar : 'value'}\n * getCookie()\n * => all available cookies\n */\nexport function getCookie(name){\n\tconst\n\t\tnames = hasValue(name) ? new Set([].concat(name).map(n => n.trim())) : new Set(),\n\t\tfoundNames = new Set()\n\t;\n\n\tlet res = (names.size === 0) ? {} : null;\n\tif( !hasValue(document.cookie) ) return res;\n\n\tconst cookies = document.cookie.split(';');\n\tfor( let i in cookies ){\n\t\ttry {\n\t\t\tconst\n\t\t\t\tcookie = cookies[i].trim(),\n\t\t\t\tcookieParts = cookie.split('='),\n\t\t\t\tcookieName = decodeCookieName(cookieParts[0]).trim(),\n\t\t\t\tcookieValue = decodeCookieValue(cookieParts.slice(1).join('='))\n\t\t\t;\n\n\t\t\tif( (cookieName !== '') && (names.has(cookieName) || (names.size === 0)) ){\n\t\t\t\tif( res === null ){\n\t\t\t\t\tres = {};\n\t\t\t\t}\n\n\t\t\t\tres[cookieName] = cookieValue;\n\t\t\t\tfoundNames.add(cookieName);\n\n\t\t\t\tif( (foundNames.size === names.size) && (names.size !== 0) ){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch(ex){\n\t\t\twarn(`${MODULE_NAME}:getCookie | decoding cookie \"${cookies[i]}\" failed with \"${ex}\"`)\n\t\t}\n\t}\n\n\tif( names.size === 1 ){\n\t\treturn res?.[name] ?? null;\n\t} else {\n\t\treturn res;\n\t}\n}\n\n\n\n/**\n * @namespace Cookies:getCookies\n */\n\n/**\n * Retrieve decoded cookie values by name. If no name is provided, all available cookie are being returned.\n * Automatically decodes the values (assumes, that, if encoded, url/percent encoding has been used).\n *\n * You can provide names as an array or as comma-separated parameters.\n *\n * @param {?String|Array} [names] - the names of the cookies, if empty or not set, all available cookies are returned\n * @returns {Object} dictionary of named decoded values of the cookies, will be empty if none of the cookies were available\n *\n * @memberof Cookies:getCookies\n * @alias getCookies\n * @see getCookie\n * @see setCookie\n * @see removeCookie\n * @example\n * getCookies(['foobar', 'boofar'])\n * => {foobar : 'value', boofar : 'value'}\n * getCookies('foobar', 'boofar')\n * => {foobar : 'value', boofar : 'value'}\n * getCookie()\n * => all available cookies\n */\nexport function getCookies(names){\n\tnames = [];\n\tArray.from(arguments).forEach(argument => {\n\t\tnames = names.concat(argument);\n\t});\n\n\treturn getCookie(names);\n}\n\n\n\n/**\n * @namespace Cookies:setCookie\n */\n\n/**\n * Set a cookie value (if possible) by name. Value will automatically be encoded.\n *\n * If you set a cookie to a nullish value, the method will try to remove the cookie with the given options.\n *\n * @param {String} name - the name of the cookie to set\n * @param {?String} [value] - the value of the cookie to set\n * @param {?Cookies.CookieOptions} [options] - the cookie options to apply\n * @returns {String|null} returns the set cookie value if available after setting or null if cookie not available (which would also mean, that setting the cookie did not work, or, in case of removal, that the removal worked)\n *\n * @memberof Cookies:setCookie\n * @alias setCookie\n * @see getCookie\n * @see getCookies\n * @see removeCookie\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie#write_a_new_cookie\n * @example\n * setCookie('mykittencookie', 'meow meow', {expires : 7, path : '/kittens', secure : true, samesite : 'strict'});\n */\nexport function setCookie(name, value, options){\n\tassert(hasValue(name) && (name !== ''), `${MODULE_NAME}:setCookie | no usable name`);\n\n\tname = `${name}`.trim();\n\tvalue = hasValue(value) ? encodeCookieValue(orDefault(value, '', 'str')) : null;\n\toptions = normalizeCookieOptions(options);\n\n\tlet cookieOptions = '';\n\tfor( let optionsProp in options ){\n\t\tconst option = options[optionsProp];\n\n\t\tif( !hasValue(option) || (option === false) ) continue;\n\n\t\tcookieOptions += `; ${optionsProp}`;\n\n\t\tif( option === true ) continue;\n\n\t\t// if the value itself contains a semicolon, according to RFC 6265 section 5.2,\n\t\t// we use everything that comes before the semicolon as the value and drop the rest\n\t\tcookieOptions += `=${option.split(';')[0]}`;\n\t}\n\n\tif( hasValue(value) ){\n\t\tdocument.cookie = `${encodeCookieName(name)}=${value}${cookieOptions}`;\n\t} else {\n\t\tremoveCookie(name, options);\n\t}\n\n\treturn getCookie(name);\n}\n\n\n\n/**\n * @namespace Cookies:removeCookie\n */\n\n/**\n * Removes a cookie (if possible) by name.\n *\n * @param {String} name - the name of the cookie to remove\n * @param {?Cookies.CookieOptions} [options] - the cookie options to apply (needed for different paths/domains for example)\n * @returns {Boolean} true if cookie is not available anymore after removal, if this is false, cookie removal failed or another cookie of the same name is still available\n *\n * @memberof Cookies:removeCookie\n * @alias removeCookie\n * @see getCookie\n * @see getCookies\n * @see setCookie\n * @example\n * removeCookie('mykittencookie', {path : '/kittens'});\n */\nexport function removeCookie(name, options){\n\tassert(hasValue(name) && (name !== ''), `${MODULE_NAME}:removeCookie | no usable name`);\n\n\toptions = normalizeCookieOptions(options);\n\toptions.expires = -1;\n\n\treturn (setCookie(name, '', options) === null);\n}\n"]} \ No newline at end of file +{"version":3,"file":"cookies.js","names":["MODULE_NAME","assert","isDate","orDefault","hasValue","warn","encodeCookieValue","value","encodeURIComponent","replace","decodeURIComponent","decodeCookieValue","slice","encodeCookieName","name","escape","decodeCookieName","normalizeCookieOptions","options","normalizedOptions","optionsProp","toLowerCase","expires","Date","now","Math","round","parseFloat","toUTCString","path","domain","httponly","samesite","includes","console","secure","getCookie","names","Set","concat","map","n","trim","foundNames","res","size","document","cookie","cookies","split","i","cookieParts","cookieName","cookieValue","join","has","add","ex","getCookies","Array","from","arguments","forEach","argument","setCookie","cookieOptions","option","removeCookie"],"sources":["cookies.js"],"mappings":";;;AAQA,MAAMA,YAAc,iBAMZC,OAAQC,OAAQC,UAAWC,aAAe,oBAC1CC,SAAW,eAWnB,SAASC,kBAAkBC,GAC1B,OAAOC,mBAAmBD,GAAOE,QAAQ,2CAA4CC,mBACtF,CASA,SAASC,kBAAkBJ,GAI1B,MAHiB,MAAbA,EAAM,KACTA,EAAQA,EAAMK,MAAM,GAAI,IAElBL,EAAME,QAAQ,mBAAoBC,mBAC1C,CASA,SAASG,iBAAiBC,GACzB,OAAON,mBAAmB,GAAGM,KAC3BL,QAAQ,uBAAwBC,oBAEhCD,QAAQ,QAASM,OAEpB,CASA,SAASC,iBAAiBF,GACzB,OAAOJ,mBAAmBI,EAC3B,CAuBA,SAASG,uBAAuBC,GAC/BA,EAAUf,UAAUe,EAAS,CAAC,GAE9B,MAAMC,EAAoB,CAAC,EAC3B,IAAK,IAAIC,KAAeF,EACvBC,EAAkBC,EAAYC,eAAiBH,EAAQE,GA+BxD,OA3BIhB,UAFJc,EAAUC,GAEWG,UACfpB,OAAOgB,EAAQI,WACnBJ,EAAQI,QAAU,IAAIC,KAAKA,KAAKC,MAAmD,GAA1CC,KAAKC,MAAMC,WAAWT,EAAQI,UAAiB,GAAK,GAAK,MAEnGJ,EAAQI,QAAUJ,EAAQI,QAAQM,eAElCV,EAAQI,QAAU,KAGnBJ,EAAQ,WAAaf,UAAUe,EAAQ,WAAY,KAAM,OAEzDA,EAAQW,KAAO1B,UAAUe,EAAQW,KAAM,IAAK,OACvB,SAAjBX,EAAQW,OACXX,EAAQW,KAAO,IAGhBX,EAAQY,OAAS3B,UAAUe,EAAQY,OAAQ,KAAM,OAEjDZ,EAAQa,SAAW5B,UAAUe,EAAQa,UAAU,EAAO,QAEtDb,EAAQc,SAAW7B,UAAUe,EAAQc,SAAU,MAAO,OAAOX,cACxD,CAAC,SAAU,MAAO,QAAQY,SAASf,EAAQc,WAC/CE,QAAQ7B,KAAK,GAAGL,kDAAkDkB,EAAQc,aAG3Ed,EAAQiB,OAAShC,UAAUe,EAAQiB,OAA6B,SAArBjB,EAAQc,SAAqB,QAEjEd,CACR,QA8BO,SAASkB,UAAUtB,GACzB,MACCuB,EAAQjC,SAASU,GAAQ,IAAIwB,IAAI,GAAGC,OAAOzB,GAAM0B,KAAIC,GAAKA,EAAEC,UAAW,IAAIJ,IAC3EK,EAAa,IAAIL,IAGlB,IAAIM,EAAsB,IAAfP,EAAMQ,KAAc,CAAC,EAAI,KACpC,IAAKzC,SAAS0C,SAASC,QAAU,OAAOH,EAExC,MAAMI,EAAUF,SAASC,OAAOE,MAAM,KACtC,IAAK,IAAIC,KAAKF,EACb,IACC,MAECG,EADSH,EAAQE,GAAGR,OACCO,MAAM,KAC3BG,EAAapC,iBAAiBmC,EAAY,IAAIT,OAC9CW,EAAc1C,kBAAkBwC,EAAYvC,MAAM,GAAG0C,KAAK,MAG3D,GAAoB,KAAfF,IAAuBf,EAAMkB,IAAIH,IAA+B,IAAff,EAAMQ,QAC/C,OAARD,IACHA,EAAM,CAAC,GAGRA,EAAIQ,GAAcC,EAClBV,EAAWa,IAAIJ,GAEVT,EAAWE,OAASR,EAAMQ,MAAyB,IAAfR,EAAMQ,MAC9C,KAGH,CAAE,MAAMY,GACPpD,KAAK,GAAGL,4CAA4CgD,EAAQE,oBAAoBO,KACjF,CAGD,OAAmB,IAAfpB,EAAMQ,KACFD,IAAM9B,IAAS,KAEf8B,CAET,QA8BO,SAASc,WAAWrB,GAM1B,OALAA,EAAQ,GACRsB,MAAMC,KAAKC,WAAWC,SAAQC,IAC7B1B,EAAQA,EAAME,OAAOwB,EAAS,IAGxB3B,UAAUC,EAClB,QA2BO,SAAS2B,UAAUlD,EAAMP,EAAOW,GACtCjB,OAAOG,SAASU,IAAmB,KAATA,EAAc,GAAGd,0CAE3Cc,EAAO,GAAGA,IAAO4B,OACjBnC,EAAQH,SAASG,GAASD,kBAAkBH,UAAUI,EAAO,GAAI,QAAU,KAC3EW,EAAUD,uBAAuBC,GAEjC,IAAI+C,EAAgB,GACpB,IAAK,IAAI7C,KAAeF,EAAS,CAChC,MAAMgD,EAAShD,EAAQE,GAElBhB,SAAS8D,KAAuB,IAAXA,IAE1BD,GAAiB,KAAK7C,KAEP,IAAX8C,IAIJD,GAAiB,IAAIC,EAAOjB,MAAM,KAAK,MACxC,CAQA,OANI7C,SAASG,GACZuC,SAASC,OAAS,GAAGlC,iBAAiBC,MAASP,IAAQ0D,IAEvDE,aAAarD,EAAMI,GAGbkB,UAAUtB,EAClB,QAuBO,SAASqD,aAAarD,EAAMI,GAMlC,OALAjB,OAAOG,SAASU,IAAmB,KAATA,EAAc,GAAGd,8CAE3CkB,EAAUD,uBAAuBC,IACzBI,SAAW,EAEsB,OAAjC0C,UAAUlD,EAAM,GAAII,EAC7B","ignoreList":[],"sourcesContent":["/*!\n * Module Cookies\n */\n\n/**\n * @namespace Cookies\n */\n\nconst MODULE_NAME = 'Cookies';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {assert, isDate, orDefault, hasValue} from './basic.js';\nimport {warn} from './logging.js';\n\n\n\n//###[ HELPERS ]########################################################################################################\n\n/*\n * Encodes a string to be stored in a cookie.\n *\n * @private\n */\nfunction encodeCookieValue(value){\n\treturn encodeURIComponent(value).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g, decodeURIComponent);\n}\n\n\n\n/*\n * Decodes a cookie value to be used as a string in JavaScript.\n *\n * @private\n */\nfunction decodeCookieValue(value){\n\tif( value[0] === '\"' ){\n\t\tvalue = value.slice(1, -1);\n\t}\n\treturn value.replace(/(%[\\dA-F]{2})+/gi, decodeURIComponent);\n}\n\n\n\n/*\n * Makes sure a cookie name conforms to the cookie name rules and translates special chars to % representations.\n *\n * @private\n */\nfunction encodeCookieName(name){\n\treturn encodeURIComponent(`${name}`)\n\t\t.replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent)\n\t\t// using escape, because encodeURIComponent, indeed, does _not_ encode brackets\n\t\t.replace(/[()]/g, escape)\n\t;\n}\n\n\n\n/*\n * Decodes a cookie name, set prior with encodeCookieName to a standard JavaScript string again.\n *\n * @private\n */\nfunction decodeCookieName(name){\n\treturn decodeURIComponent(name);\n}\n\n\n\n/**\n * @typedef CookieOptions\n * @type {Object}\n *\n * @property {?Date|Number} [expires=null] - expiry time of the cookie, either a Date object or time in days\n * @property {?Number} [max-age=null] - max age of the cookie in seconds\n * @property {?String} [path='/'] - the cookie path, setting this to \"auto\" or an empty string defines auto-mode, which targets the current site path, which usually is the default, but we use '/' to set a cookie for while site, this being the common use-case\n * @property {?Boolean} [secure=false] - define if the cookie should only be transmitted via https (see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies)\n * @property {?Boolean} [httponly=false] - define this, if cookie should only be sent to servers and not be accessible to javascript (see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies)\n * @property {?String} [samesite=null] - define if this cookie should be included in cross-site requests, may be either \"strict\" (will only ever transmit same-site), \"lax\" (usual browser default, transmits same-site and top-level GET) or \"none\" (no restrictions, will always be sent)\n *\n * @memberof Cookies\n */\n\n/*\n * Makes sure, that supplied cookie options are in a usable form for setting a cookie.\n *\n * @private\n */\nfunction normalizeCookieOptions(options){\n\toptions = orDefault(options, {});\n\n\tconst normalizedOptions = {};\n\tfor( let optionsProp in options ){\n\t\tnormalizedOptions[optionsProp.toLowerCase()] = options[optionsProp];\n\t}\n\toptions = normalizedOptions;\n\n\tif( hasValue(options.expires) ){\n\t\tif( !isDate(options.expires) ){\n\t\t\toptions.expires = new Date(Date.now() + (Math.round(parseFloat(options.expires)) * 24 * 60 * 60 * 1000));\n\t\t}\n\t\toptions.expires = options.expires.toUTCString();\n\t} else {\n\t\toptions.expires = null;\n\t}\n\n\toptions['max-age'] = orDefault(options['max-age'], null, 'int');\n\n\toptions.path = orDefault(options.path, '/', 'str');\n\tif( options.path === 'auto' ){\n\t\toptions.path = '';\n\t}\n\n\toptions.domain = orDefault(options.domain, null, 'str');\n\n\toptions.httponly = orDefault(options.httponly, false, 'bool');\n\n\toptions.samesite = orDefault(options.samesite, 'lax', 'str').toLowerCase();\n\tif( !['strict', 'lax', 'none'].includes(options.samesite) ){\n\t\tconsole.warn(`${MODULE_NAME}:setCookie | unknown samesite mode \"${options.samesite}\"`);\n\t}\n\n\toptions.secure = orDefault(options.secure, options.samesite === 'none', 'bool');\n\n\treturn options;\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Cookies:getCookie\n */\n\n/**\n * Retrieves a decoded cookie value by name. Automatically decodes the value (assumes, that, if encoded, url/percent\n * encoding has been used).\n *\n * @param {?String|Array} [name] - the name of the cookie (or several names), if empty, all available cookies are returned\n * @returns {String|Object|null} decoded value of the cookie, null, if no such cookie available or a dictionary of found cookies if all or a list are being returned (if a list is requested and non are found, an empty object is returned)\n *\n * @memberof Cookies:getCookie\n * @alias getCookie\n * @see getCookies\n * @see setCookie\n * @see removeCookie\n * @example\n * getCookie('foobar')\n * => 'value'\n * getCookie(['foobar', 'boofar'])\n * => {foobar : 'value', boofar : 'value'}\n * getCookie()\n * => all available cookies\n */\nexport function getCookie(name){\n\tconst\n\t\tnames = hasValue(name) ? new Set([].concat(name).map(n => n.trim())) : new Set(),\n\t\tfoundNames = new Set()\n\t;\n\n\tlet res = (names.size === 0) ? {} : null;\n\tif( !hasValue(document.cookie) ) return res;\n\n\tconst cookies = document.cookie.split(';');\n\tfor( let i in cookies ){\n\t\ttry {\n\t\t\tconst\n\t\t\t\tcookie = cookies[i].trim(),\n\t\t\t\tcookieParts = cookie.split('='),\n\t\t\t\tcookieName = decodeCookieName(cookieParts[0]).trim(),\n\t\t\t\tcookieValue = decodeCookieValue(cookieParts.slice(1).join('='))\n\t\t\t;\n\n\t\t\tif( (cookieName !== '') && (names.has(cookieName) || (names.size === 0)) ){\n\t\t\t\tif( res === null ){\n\t\t\t\t\tres = {};\n\t\t\t\t}\n\n\t\t\t\tres[cookieName] = cookieValue;\n\t\t\t\tfoundNames.add(cookieName);\n\n\t\t\t\tif( (foundNames.size === names.size) && (names.size !== 0) ){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch(ex){\n\t\t\twarn(`${MODULE_NAME}:getCookie | decoding cookie \"${cookies[i]}\" failed with \"${ex}\"`)\n\t\t}\n\t}\n\n\tif( names.size === 1 ){\n\t\treturn res?.[name] ?? null;\n\t} else {\n\t\treturn res;\n\t}\n}\n\n\n\n/**\n * @namespace Cookies:getCookies\n */\n\n/**\n * Retrieve decoded cookie values by name. If no name is provided, all available cookie are being returned.\n * Automatically decodes the values (assumes, that, if encoded, url/percent encoding has been used).\n *\n * You can provide names as an array or as comma-separated parameters.\n *\n * @param {?String|Array} [names] - the names of the cookies, if empty or not set, all available cookies are returned\n * @returns {Object} dictionary of named decoded values of the cookies, will be empty if none of the cookies were available\n *\n * @memberof Cookies:getCookies\n * @alias getCookies\n * @see getCookie\n * @see setCookie\n * @see removeCookie\n * @example\n * getCookies(['foobar', 'boofar'])\n * => {foobar : 'value', boofar : 'value'}\n * getCookies('foobar', 'boofar')\n * => {foobar : 'value', boofar : 'value'}\n * getCookie()\n * => all available cookies\n */\nexport function getCookies(names){\n\tnames = [];\n\tArray.from(arguments).forEach(argument => {\n\t\tnames = names.concat(argument);\n\t});\n\n\treturn getCookie(names);\n}\n\n\n\n/**\n * @namespace Cookies:setCookie\n */\n\n/**\n * Set a cookie value (if possible) by name. Value will automatically be encoded.\n *\n * If you set a cookie to a nullish value, the method will try to remove the cookie with the given options.\n *\n * @param {String} name - the name of the cookie to set\n * @param {?String} [value] - the value of the cookie to set\n * @param {?Cookies.CookieOptions} [options] - the cookie options to apply\n * @returns {String|null} returns the set cookie value if available after setting or null if cookie not available (which would also mean, that setting the cookie did not work, or, in case of removal, that the removal worked)\n *\n * @memberof Cookies:setCookie\n * @alias setCookie\n * @see getCookie\n * @see getCookies\n * @see removeCookie\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie#write_a_new_cookie\n * @example\n * setCookie('mykittencookie', 'meow meow', {expires : 7, path : '/kittens', secure : true, samesite : 'strict'});\n */\nexport function setCookie(name, value, options){\n\tassert(hasValue(name) && (name !== ''), `${MODULE_NAME}:setCookie | no usable name`);\n\n\tname = `${name}`.trim();\n\tvalue = hasValue(value) ? encodeCookieValue(orDefault(value, '', 'str')) : null;\n\toptions = normalizeCookieOptions(options);\n\n\tlet cookieOptions = '';\n\tfor( let optionsProp in options ){\n\t\tconst option = options[optionsProp];\n\n\t\tif( !hasValue(option) || (option === false) ) continue;\n\n\t\tcookieOptions += `; ${optionsProp}`;\n\n\t\tif( option === true ) continue;\n\n\t\t// if the value itself contains a semicolon, according to RFC 6265 section 5.2,\n\t\t// we use everything that comes before the semicolon as the value and drop the rest\n\t\tcookieOptions += `=${option.split(';')[0]}`;\n\t}\n\n\tif( hasValue(value) ){\n\t\tdocument.cookie = `${encodeCookieName(name)}=${value}${cookieOptions}`;\n\t} else {\n\t\tremoveCookie(name, options);\n\t}\n\n\treturn getCookie(name);\n}\n\n\n\n/**\n * @namespace Cookies:removeCookie\n */\n\n/**\n * Removes a cookie (if possible) by name.\n *\n * @param {String} name - the name of the cookie to remove\n * @param {?Cookies.CookieOptions} [options] - the cookie options to apply (needed for different paths/domains for example)\n * @returns {Boolean} true if cookie is not available anymore after removal, if this is false, cookie removal failed or another cookie of the same name is still available\n *\n * @memberof Cookies:removeCookie\n * @alias removeCookie\n * @see getCookie\n * @see getCookies\n * @see setCookie\n * @example\n * removeCookie('mykittencookie', {path : '/kittens'});\n */\nexport function removeCookie(name, options){\n\tassert(hasValue(name) && (name !== ''), `${MODULE_NAME}:removeCookie | no usable name`);\n\n\toptions = normalizeCookieOptions(options);\n\toptions.expires = -1;\n\n\treturn (setCookie(name, '', options) === null);\n}\n"]} \ No newline at end of file diff --git a/dist/css.js b/dist/css.js index 4bbaa3fe..fca93c63 100644 --- a/dist/css.js +++ b/dist/css.js @@ -1,5 +1,5 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module CSS diff --git a/dist/css.js.map b/dist/css.js.map index d30e1dcc..9491cb4e 100644 --- a/dist/css.js.map +++ b/dist/css.js.map @@ -1 +1 @@ -{"version":3,"file":"css.js","names":["MODULE_NAME","assert","isNumber","orDefault","isPlainObject","isElement","hasValue","isNaN","maskForRegEx","applyStyles","element","styles","crossBrowser","returnCssStyleDeclaration","__methodName__","vendorPrefixes","Object","entries","forEach","cssKey","cssValue","vendorPrefix","replace","style","setProperty","removeProperty","cssValueToNumber","value","parseFloat","cssUrlValueToUrl","urlValue","baseUrl","baseUrlSubstitution","urlValueRex","RegExp","matches","match","exec","push","length","remByPx","px","initial","getPropertyValue","document","querySelector","remVal"],"sources":["css.js"],"mappings":";;;AAQA,MAAMA,YAAc,aAMZC,OAAQC,SAAUC,UAAWC,cAAeC,UAAWC,SAAUC,UAAY,oBAC7EC,iBAAmB,sBA6CpB,SAASC,YAAYC,EAASC,EAAQC,GAAa,EAAOC,GAA0B,GAC1F,MAAMC,EAAiB,cAEvBF,EAAeT,UAAUS,GAAc,EAAO,QAC9CC,EAA4BV,UAAUU,GAA2B,EAAO,QAExEZ,OAAOI,UAAUK,GAAU,OAAkBI,sCAC7Cb,OAAOG,cAAcO,GAAS,OAAkBG,qCAEhD,MAAMC,EAAiB,CAAC,WAAY,QAAS,OAAQ,MAAO,WA+B5D,OA7BIH,GACHI,OAAOC,QAAQ,IAAIN,IAASO,SAAQ,EAAEC,EAAQC,MAC7CL,EAAeG,SAAQG,IAErBV,EAAOU,EAAaF,GADP,eAAXA,EAC4BC,EAASE,QAAQ,YAAa,GAAGD,cAEjCD,CAC/B,GACC,IAIJJ,OAAOC,QAAQ,IAAIN,IAASO,SAAQ,EAAEC,EAAQC,MACzClB,SAASkB,IAA2B,IAAbA,GAC1BT,EAAOQ,GAAU,GAAGC,MACpBV,EAAQa,MAAMC,YAAYL,EAAQR,EAAOQ,KAC9Bb,SAASc,IAQpBT,EAAOQ,GAAU,GAAGC,IACpBV,EAAQa,MAAMC,YAAYL,EAAQR,EAAOQ,MARzCJ,EAAeG,SAAQG,WACfV,EAAOU,EAAaF,GAC3BT,EAAQa,MAAME,eAAeJ,EAAaF,EAAO,WAE3CR,EAAOQ,GACdT,EAAQa,MAAME,eAAeN,GAI9B,IAGMN,EAA4BH,EAAQa,MAAQZ,CACpD,QAsBO,SAASe,iBAAiBC,GAChC,OAAOC,WAAWzB,UAAUwB,EAAO,GAAI,OACxC,QA0BO,SAASE,iBAAiBC,EAAUC,EAAQ,KAAMC,EAAoB,MAC5EF,EAAW3B,UAAU2B,EAAU,GAAI,OACnCC,EAAU5B,UAAU4B,EAAS,KAAM,OACnCC,EAAsB7B,UAAU6B,EAAqB,KAAM,OAE3D,MACCC,EAAc,IAAIC,OAAO,2DAA4D,OACrFC,EAAU,GAGX,IAAIC,EACJ,KAAgD,QAAxCA,EAAQH,EAAYI,KAAKP,KAChCM,EAAQA,EAAM,GACV9B,SAASyB,EAASC,KACrBI,EAAQA,EAAMd,QAAQ,IAAIY,OAAO,IAAI1B,aAAauB,MAAaC,IAEhEG,EAAQG,KAAKF,GAGd,OAAuB,IAAnBD,EAAQI,OACJJ,EAAQ,GACLA,EAAQI,OAAS,EACpBJ,EAEA,IAET,QAiCO,SAASK,QAAQC,EAAIC,EAAQ,QAInC,GAHAD,EAAKf,iBAAiBe,GACtBC,EAAUvC,UAAUuC,EAAS,QAEzBrC,UAAUqC,GACbA,EAAUhB,iBAAiBgB,EAAQnB,MAAMoB,iBAAiB,kBACpD,CACN,MAAMhB,EAAQD,iBAAiBgB,GAC/B,GAAInC,MAAMoB,GAAQ,CACjB,MAAMjB,EAAUkC,SAASC,cAAcH,GACvCzC,OAAOK,SAASI,GAAU,kDAC1BgC,EAAUhB,iBAAiBhB,EAAQa,MAAMoB,iBAAiB,aAC3D,MACCD,EAAUf,CAEZ,CAEA,MAAMmB,EAASL,EAAKC,EAEpB,OAAiB,IAAZA,GAAmBnC,MAAMuC,GAGtB,KAFA,GAAGA,MAIZ","sourcesContent":["/*!\n * Module CSS\n */\n\n/**\n * @namespace CSS\n */\n\nconst MODULE_NAME = 'CSS';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {assert, isNumber, orDefault, isPlainObject, isElement, hasValue, isNaN} from './basic.js';\nimport {maskForRegEx} from './strings.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace CSS:applyStyles\n */\n\n/**\n * Applies CSS definitions to an HTMLElement, by providing a plain object of property-value-pairs.\n * Properties may be written as default CSS kebab-case properties such as \"margin-left\" or as JS\n * camel-cased versions such as \"marginLeft\".\n *\n * Providing a real JS number without a unit will be treated as a pixel value, so defining \"'line-height' : 0\" will\n * actually result in a 1px line-height. To actually set a unit-less value, just set the value as a string:\n * \"'line-height' : '0'\".\n *\n * Generally all CSS values are usually strings (this is also the way JS handles this),\n * treating plain numbers as pixels is just a convenience feature, since pixels are most likely to be\n * calculated values, where it is bothersome and error-prone to add the \"px\" all the time.\n *\n * To remove a property, just set the value to a nullish value. Deleting a property also tries to remove all\n * vendor prefixed variants.\n *\n * This function uses CSSStyleDeclaration.setProperty instead of direct style assignments. This means, that the\n * browser itself decides which value to apply, based on the support of the property. This means, the style object\n * will not be polluted with vendor stuff the browser does not support, but this also means, that all non-standard\n * properties might be refused. If you really need to set something out of spec, use direct style assignment instead.\n *\n * @param {HTMLElement} element - the element to apply the styles to, use null or undefined as value to remove a prop\n * @param {Object} styles - the styles to apply, provided as a plain object, defining property-value-pairs\n * @param {?Boolean} [crossBrowser=false] - set this to true, to automatically generate vendor-prefixed versions of all provided properties\n * @param {?Boolean} [returnCssStyleDeclaration=false] - set this to true, return the CSSStyleDeclaration of the element after the style application, rather than the plain object\n * @throws error if element is not an HTMLElement\n * @throws error if styles is not a plain object\n * @returns {Object|CSSStyleDeclaration} the applied/active styles\n *\n * @memberof CSS:applyStyles\n * @alias applyStyles\n * @example\n * applyStyles(document.body, {backgroundColor : red, transition : 'all 200ms'}, true);\n * applyStyles(document.querySelector('main'), {'font-family' : 'serif'}, false, true);\n */\nexport function applyStyles(element, styles, crossBrowser=false, returnCssStyleDeclaration=false){\n\tconst __methodName__ = 'applyStyles';\n\n\tcrossBrowser = orDefault(crossBrowser, false, 'bool');\n\treturnCssStyleDeclaration = orDefault(returnCssStyleDeclaration, false, 'bool');\n\n\tassert(isElement(element), `${MODULE_NAME}:${__methodName__} | element is not an html element`);\n\tassert(isPlainObject(styles), `${MODULE_NAME}:${__methodName__} | styles must be a plain object`);\n\n\tconst vendorPrefixes = ['-webkit-', '-moz-', '-ms-', '-o-', '-khtml-'];\n\n\tif( crossBrowser ){\n\t\tObject.entries({...styles}).forEach(([cssKey, cssValue]) => {\n\t\t\tvendorPrefixes.forEach(vendorPrefix => {\n\t\t\t\tif(cssKey === 'transition'){\n\t\t\t\t\tstyles[vendorPrefix+cssKey] = cssValue.replace('transform', `${vendorPrefix}transform`);\n\t\t\t\t} else {\n\t\t\t\t\tstyles[vendorPrefix+cssKey] = cssValue;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\tObject.entries({...styles}).forEach(([cssKey, cssValue]) => {\n\t\tif( isNumber(cssValue) && (cssValue !== 0) ){\n\t\t\tstyles[cssKey] = `${cssValue}px`;\n\t\t\telement.style.setProperty(cssKey, styles[cssKey]);\n\t\t} else if( !hasValue(cssValue) ){\n\t\t\tvendorPrefixes.forEach(vendorPrefix => {\n\t\t\t\tdelete styles[vendorPrefix+cssKey];\n\t\t\t\telement.style.removeProperty(vendorPrefix+cssKey);\n\t\t\t});\n\t\t\tdelete styles[cssKey];\n\t\t\telement.style.removeProperty(cssKey);\n\t\t} else {\n\t\t\tstyles[cssKey] = `${cssValue}`;\n\t\t\telement.style.setProperty(cssKey, styles[cssKey]);\n\t\t}\n\t});\n\n\treturn returnCssStyleDeclaration ? element.style : styles;\n}\n\n\n\n/**\n * @namespace CSS:cssValueToNumber\n */\n\n/**\n * Converts a CSS-value to a number without unit. If the base number is an integer the result will also\n * be an integer, float values will also be converted correctly.\n *\n * @param {String} value - the css-value to convert\n * @returns {Number|NaN} true number representation of the given value or NaN if the value is not parsable\n *\n * @memberof CSS:cssValueToNumber\n * @alias cssValueToNumber\n * @example\n * document.querySelector('main').style.setProperty('width', '99vh');\n * cssValueToNumber(document.querySelector('main').style.getPropertyValue('width'));\n * => 99\n */\nexport function cssValueToNumber(value){\n\treturn parseFloat(orDefault(value, '', 'str'));\n}\n\n\n\n/**\n * @namespace CSS:cssUrlValueToUrl\n */\n\n/**\n * Converts a CSS-URL-value (\"url('/foo/bar/baz.jpg')\") to a plain URL usable in requests or src-attributes.\n *\n * @param {String} urlValue - the URL-value from CSS\n * @param {?String} [baseUrl=null] - if you want to transform the URL by substituting the start of the path or URL with something fitting for your context, define what to replace here\n * @param {?String} [baseUrlSubstitution=null] - if you want to transform the URL by substituting the start of the path or URL with something fitting for your context, define what to replace the baseUrl with here\n * @returns {String|Array|null} the extracted URL (or list of URLs if value contained several) with substitutions (if defined) or null if no URL-values were found\n *\n * @memberof CSS:cssUrlValueToUrl\n * @alias cssUrlValueToUrl\n * @example\n * cssUrlValueToUrl('url(\"https://foobar.com/test.jpg\")', 'https://foobar.com', '..');\n * => '../test.jpg'\n * cssUrlValueToUrl(`url(/foo/bar),\n * url('https://google.de') url(\"test.jpg\"),url(omg.svg)\n * url(http://lol.com)`)\n * => ['/foo/bar', 'https://google.com', 'test.jpg', 'omg.svg', 'http://lol.com']\n */\nexport function cssUrlValueToUrl(urlValue, baseUrl=null, baseUrlSubstitution=null){\n\turlValue = orDefault(urlValue, '', 'str');\n\tbaseUrl = orDefault(baseUrl, null, 'str');\n\tbaseUrlSubstitution = orDefault(baseUrlSubstitution, null, 'str');\n\n\tconst\n\t\turlValueRex = new RegExp('(?:^|\\\\s|,)url\\\\((?:\\'|\")?([^\\'\"\\\\n\\\\r\\\\t]+)(?:\\'|\")?\\\\)', 'gmi'),\n\t\tmatches = []\n\t;\n\n\tlet match;\n\twhile( (match = urlValueRex.exec(urlValue)) !== null ){\n\t\tmatch = match[1];\n\t\tif( hasValue(baseUrl, baseUrlSubstitution) ){\n\t\t\tmatch = match.replace(new RegExp(`^${maskForRegEx(baseUrl)}`), baseUrlSubstitution);\n\t\t}\n\t\tmatches.push(match);\n\t}\n\n\tif( matches.length === 1 ){\n\t\treturn matches[0];\n\t} else if( matches.length > 1 ){\n\t\treturn matches;\n\t} else {\n\t\treturn null;\n\t}\n}\n\n\n\n/**\n * @namespace CSS:remByPx\n */\n\n/**\n * Calculates a rem value based on a given px value.\n * As a default this method takes the font-size (supposedly being in px) of the html-container.\n * You can overwrite this behaviour by setting initial to a number to use as a base px value or\n * to a string, which then defines a new selector for an element to get the initial font-size from.\n * You can also provide an HTMLElement directly, but keep in mind that the element's font size definition\n * has to be in pixels, to make this work.\n *\n * In most cases you will have to define the initial value via a constant or a selector to a container\n * with non-changing font-size, since you can never be sure which relative font-size applies atm, even on first\n * call, after dom ready, since responsive definitions might already be active, returning a viewport-specific\n * size.\n *\n * @param {Number} px - the pixel value to convert to rem\n * @param {?(Number|String|HTMLElement)} [initial='html'] - either a pixel value to use as a conversion base, a selector for an element to get the initial font-size from or the element itself; keep in mind, that the element's font-size definition has to be in px\n * @throws error if given selector in initial does not return an element\n * @returns {String|null} the rem value string to use in a css definition or null if the value could not be calculated\n *\n * @memberof CSS:remByPx\n * @alias remByPx\n * @example\n * remByPx(20, 16);\n * => '1.25rem'\n * remByPx('100px', 'p.has-base-fontsize');\n */\nexport function remByPx(px, initial='html'){\n\tpx = cssValueToNumber(px);\n\tinitial = orDefault(initial, 'html');\n\n\tif( isElement(initial) ){\n\t\tinitial = cssValueToNumber(initial.style.getPropertyValue('font-size'));\n\t} else {\n\t\tconst value = cssValueToNumber(initial);\n\t\tif( isNaN(value) ){\n\t\t\tconst element = document.querySelector(initial);\n\t\t\tassert(hasValue(element), `${MODULE_NAME}:remByPx | selector does not return element`);\n\t\t\tinitial = cssValueToNumber(element.style.getPropertyValue('font-size'));\n\t\t} else {\n\t\t\tinitial = value;\n\t\t}\n\t}\n\n\tconst remVal = px / initial;\n\n\tif( (initial !== 0) && !isNaN(remVal) ){\n\t\treturn `${remVal}rem`;\n\t} else {\n\t\treturn null;\n\t}\n}\n"]} \ No newline at end of file +{"version":3,"file":"css.js","names":["MODULE_NAME","assert","isNumber","orDefault","isPlainObject","isElement","hasValue","isNaN","maskForRegEx","applyStyles","element","styles","crossBrowser","returnCssStyleDeclaration","__methodName__","vendorPrefixes","Object","entries","forEach","cssKey","cssValue","vendorPrefix","replace","style","setProperty","removeProperty","cssValueToNumber","value","parseFloat","cssUrlValueToUrl","urlValue","baseUrl","baseUrlSubstitution","urlValueRex","RegExp","matches","match","exec","push","length","remByPx","px","initial","getPropertyValue","document","querySelector","remVal"],"sources":["css.js"],"mappings":";;;AAQA,MAAMA,YAAc,aAMZC,OAAQC,SAAUC,UAAWC,cAAeC,UAAWC,SAAUC,UAAY,oBAC7EC,iBAAmB,sBA6CpB,SAASC,YAAYC,EAASC,EAAQC,GAAa,EAAOC,GAA0B,GAC1F,MAAMC,EAAiB,cAEvBF,EAAeT,UAAUS,GAAc,EAAO,QAC9CC,EAA4BV,UAAUU,GAA2B,EAAO,QAExEZ,OAAOI,UAAUK,GAAU,OAAkBI,sCAC7Cb,OAAOG,cAAcO,GAAS,OAAkBG,qCAEhD,MAAMC,EAAiB,CAAC,WAAY,QAAS,OAAQ,MAAO,WA+B5D,OA7BIH,GACHI,OAAOC,QAAQ,IAAIN,IAASO,SAAQ,EAAEC,EAAQC,MAC7CL,EAAeG,SAAQG,IAErBV,EAAOU,EAAaF,GADP,eAAXA,EAC4BC,EAASE,QAAQ,YAAa,GAAGD,cAEjCD,CAC/B,GACC,IAIJJ,OAAOC,QAAQ,IAAIN,IAASO,SAAQ,EAAEC,EAAQC,MACzClB,SAASkB,IAA2B,IAAbA,GAC1BT,EAAOQ,GAAU,GAAGC,MACpBV,EAAQa,MAAMC,YAAYL,EAAQR,EAAOQ,KAC9Bb,SAASc,IAQpBT,EAAOQ,GAAU,GAAGC,IACpBV,EAAQa,MAAMC,YAAYL,EAAQR,EAAOQ,MARzCJ,EAAeG,SAAQG,WACfV,EAAOU,EAAaF,GAC3BT,EAAQa,MAAME,eAAeJ,EAAaF,EAAO,WAE3CR,EAAOQ,GACdT,EAAQa,MAAME,eAAeN,GAI9B,IAGMN,EAA4BH,EAAQa,MAAQZ,CACpD,QAsBO,SAASe,iBAAiBC,GAChC,OAAOC,WAAWzB,UAAUwB,EAAO,GAAI,OACxC,QA0BO,SAASE,iBAAiBC,EAAUC,EAAQ,KAAMC,EAAoB,MAC5EF,EAAW3B,UAAU2B,EAAU,GAAI,OACnCC,EAAU5B,UAAU4B,EAAS,KAAM,OACnCC,EAAsB7B,UAAU6B,EAAqB,KAAM,OAE3D,MACCC,EAAc,IAAIC,OAAO,2DAA4D,OACrFC,EAAU,GAGX,IAAIC,EACJ,KAAgD,QAAxCA,EAAQH,EAAYI,KAAKP,KAChCM,EAAQA,EAAM,GACV9B,SAASyB,EAASC,KACrBI,EAAQA,EAAMd,QAAQ,IAAIY,OAAO,IAAI1B,aAAauB,MAAaC,IAEhEG,EAAQG,KAAKF,GAGd,OAAuB,IAAnBD,EAAQI,OACJJ,EAAQ,GACLA,EAAQI,OAAS,EACpBJ,EAEA,IAET,QAiCO,SAASK,QAAQC,EAAIC,EAAQ,QAInC,GAHAD,EAAKf,iBAAiBe,GACtBC,EAAUvC,UAAUuC,EAAS,QAEzBrC,UAAUqC,GACbA,EAAUhB,iBAAiBgB,EAAQnB,MAAMoB,iBAAiB,kBACpD,CACN,MAAMhB,EAAQD,iBAAiBgB,GAC/B,GAAInC,MAAMoB,GAAQ,CACjB,MAAMjB,EAAUkC,SAASC,cAAcH,GACvCzC,OAAOK,SAASI,GAAU,kDAC1BgC,EAAUhB,iBAAiBhB,EAAQa,MAAMoB,iBAAiB,aAC3D,MACCD,EAAUf,CAEZ,CAEA,MAAMmB,EAASL,EAAKC,EAEpB,OAAiB,IAAZA,GAAmBnC,MAAMuC,GAGtB,KAFA,GAAGA,MAIZ","ignoreList":[],"sourcesContent":["/*!\n * Module CSS\n */\n\n/**\n * @namespace CSS\n */\n\nconst MODULE_NAME = 'CSS';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {assert, isNumber, orDefault, isPlainObject, isElement, hasValue, isNaN} from './basic.js';\nimport {maskForRegEx} from './strings.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace CSS:applyStyles\n */\n\n/**\n * Applies CSS definitions to an HTMLElement, by providing a plain object of property-value-pairs.\n * Properties may be written as default CSS kebab-case properties such as \"margin-left\" or as JS\n * camel-cased versions such as \"marginLeft\".\n *\n * Providing a real JS number without a unit will be treated as a pixel value, so defining \"'line-height' : 0\" will\n * actually result in a 1px line-height. To actually set a unit-less value, just set the value as a string:\n * \"'line-height' : '0'\".\n *\n * Generally all CSS values are usually strings (this is also the way JS handles this),\n * treating plain numbers as pixels is just a convenience feature, since pixels are most likely to be\n * calculated values, where it is bothersome and error-prone to add the \"px\" all the time.\n *\n * To remove a property, just set the value to a nullish value. Deleting a property also tries to remove all\n * vendor prefixed variants.\n *\n * This function uses CSSStyleDeclaration.setProperty instead of direct style assignments. This means, that the\n * browser itself decides which value to apply, based on the support of the property. This means, the style object\n * will not be polluted with vendor stuff the browser does not support, but this also means, that all non-standard\n * properties might be refused. If you really need to set something out of spec, use direct style assignment instead.\n *\n * @param {HTMLElement} element - the element to apply the styles to, use null or undefined as value to remove a prop\n * @param {Object} styles - the styles to apply, provided as a plain object, defining property-value-pairs\n * @param {?Boolean} [crossBrowser=false] - set this to true, to automatically generate vendor-prefixed versions of all provided properties\n * @param {?Boolean} [returnCssStyleDeclaration=false] - set this to true, return the CSSStyleDeclaration of the element after the style application, rather than the plain object\n * @throws error if element is not an HTMLElement\n * @throws error if styles is not a plain object\n * @returns {Object|CSSStyleDeclaration} the applied/active styles\n *\n * @memberof CSS:applyStyles\n * @alias applyStyles\n * @example\n * applyStyles(document.body, {backgroundColor : red, transition : 'all 200ms'}, true);\n * applyStyles(document.querySelector('main'), {'font-family' : 'serif'}, false, true);\n */\nexport function applyStyles(element, styles, crossBrowser=false, returnCssStyleDeclaration=false){\n\tconst __methodName__ = 'applyStyles';\n\n\tcrossBrowser = orDefault(crossBrowser, false, 'bool');\n\treturnCssStyleDeclaration = orDefault(returnCssStyleDeclaration, false, 'bool');\n\n\tassert(isElement(element), `${MODULE_NAME}:${__methodName__} | element is not an html element`);\n\tassert(isPlainObject(styles), `${MODULE_NAME}:${__methodName__} | styles must be a plain object`);\n\n\tconst vendorPrefixes = ['-webkit-', '-moz-', '-ms-', '-o-', '-khtml-'];\n\n\tif( crossBrowser ){\n\t\tObject.entries({...styles}).forEach(([cssKey, cssValue]) => {\n\t\t\tvendorPrefixes.forEach(vendorPrefix => {\n\t\t\t\tif(cssKey === 'transition'){\n\t\t\t\t\tstyles[vendorPrefix+cssKey] = cssValue.replace('transform', `${vendorPrefix}transform`);\n\t\t\t\t} else {\n\t\t\t\t\tstyles[vendorPrefix+cssKey] = cssValue;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\tObject.entries({...styles}).forEach(([cssKey, cssValue]) => {\n\t\tif( isNumber(cssValue) && (cssValue !== 0) ){\n\t\t\tstyles[cssKey] = `${cssValue}px`;\n\t\t\telement.style.setProperty(cssKey, styles[cssKey]);\n\t\t} else if( !hasValue(cssValue) ){\n\t\t\tvendorPrefixes.forEach(vendorPrefix => {\n\t\t\t\tdelete styles[vendorPrefix+cssKey];\n\t\t\t\telement.style.removeProperty(vendorPrefix+cssKey);\n\t\t\t});\n\t\t\tdelete styles[cssKey];\n\t\t\telement.style.removeProperty(cssKey);\n\t\t} else {\n\t\t\tstyles[cssKey] = `${cssValue}`;\n\t\t\telement.style.setProperty(cssKey, styles[cssKey]);\n\t\t}\n\t});\n\n\treturn returnCssStyleDeclaration ? element.style : styles;\n}\n\n\n\n/**\n * @namespace CSS:cssValueToNumber\n */\n\n/**\n * Converts a CSS-value to a number without unit. If the base number is an integer the result will also\n * be an integer, float values will also be converted correctly.\n *\n * @param {String} value - the css-value to convert\n * @returns {Number|NaN} true number representation of the given value or NaN if the value is not parsable\n *\n * @memberof CSS:cssValueToNumber\n * @alias cssValueToNumber\n * @example\n * document.querySelector('main').style.setProperty('width', '99vh');\n * cssValueToNumber(document.querySelector('main').style.getPropertyValue('width'));\n * => 99\n */\nexport function cssValueToNumber(value){\n\treturn parseFloat(orDefault(value, '', 'str'));\n}\n\n\n\n/**\n * @namespace CSS:cssUrlValueToUrl\n */\n\n/**\n * Converts a CSS-URL-value (\"url('/foo/bar/baz.jpg')\") to a plain URL usable in requests or src-attributes.\n *\n * @param {String} urlValue - the URL-value from CSS\n * @param {?String} [baseUrl=null] - if you want to transform the URL by substituting the start of the path or URL with something fitting for your context, define what to replace here\n * @param {?String} [baseUrlSubstitution=null] - if you want to transform the URL by substituting the start of the path or URL with something fitting for your context, define what to replace the baseUrl with here\n * @returns {String|Array|null} the extracted URL (or list of URLs if value contained several) with substitutions (if defined) or null if no URL-values were found\n *\n * @memberof CSS:cssUrlValueToUrl\n * @alias cssUrlValueToUrl\n * @example\n * cssUrlValueToUrl('url(\"https://foobar.com/test.jpg\")', 'https://foobar.com', '..');\n * => '../test.jpg'\n * cssUrlValueToUrl(`url(/foo/bar),\n * url('https://google.de') url(\"test.jpg\"),url(omg.svg)\n * url(http://lol.com)`)\n * => ['/foo/bar', 'https://google.com', 'test.jpg', 'omg.svg', 'http://lol.com']\n */\nexport function cssUrlValueToUrl(urlValue, baseUrl=null, baseUrlSubstitution=null){\n\turlValue = orDefault(urlValue, '', 'str');\n\tbaseUrl = orDefault(baseUrl, null, 'str');\n\tbaseUrlSubstitution = orDefault(baseUrlSubstitution, null, 'str');\n\n\tconst\n\t\turlValueRex = new RegExp('(?:^|\\\\s|,)url\\\\((?:\\'|\")?([^\\'\"\\\\n\\\\r\\\\t]+)(?:\\'|\")?\\\\)', 'gmi'),\n\t\tmatches = []\n\t;\n\n\tlet match;\n\twhile( (match = urlValueRex.exec(urlValue)) !== null ){\n\t\tmatch = match[1];\n\t\tif( hasValue(baseUrl, baseUrlSubstitution) ){\n\t\t\tmatch = match.replace(new RegExp(`^${maskForRegEx(baseUrl)}`), baseUrlSubstitution);\n\t\t}\n\t\tmatches.push(match);\n\t}\n\n\tif( matches.length === 1 ){\n\t\treturn matches[0];\n\t} else if( matches.length > 1 ){\n\t\treturn matches;\n\t} else {\n\t\treturn null;\n\t}\n}\n\n\n\n/**\n * @namespace CSS:remByPx\n */\n\n/**\n * Calculates a rem value based on a given px value.\n * As a default this method takes the font-size (supposedly being in px) of the html-container.\n * You can overwrite this behaviour by setting initial to a number to use as a base px value or\n * to a string, which then defines a new selector for an element to get the initial font-size from.\n * You can also provide an HTMLElement directly, but keep in mind that the element's font size definition\n * has to be in pixels, to make this work.\n *\n * In most cases you will have to define the initial value via a constant or a selector to a container\n * with non-changing font-size, since you can never be sure which relative font-size applies atm, even on first\n * call, after dom ready, since responsive definitions might already be active, returning a viewport-specific\n * size.\n *\n * @param {Number} px - the pixel value to convert to rem\n * @param {?(Number|String|HTMLElement)} [initial='html'] - either a pixel value to use as a conversion base, a selector for an element to get the initial font-size from or the element itself; keep in mind, that the element's font-size definition has to be in px\n * @throws error if given selector in initial does not return an element\n * @returns {String|null} the rem value string to use in a css definition or null if the value could not be calculated\n *\n * @memberof CSS:remByPx\n * @alias remByPx\n * @example\n * remByPx(20, 16);\n * => '1.25rem'\n * remByPx('100px', 'p.has-base-fontsize');\n */\nexport function remByPx(px, initial='html'){\n\tpx = cssValueToNumber(px);\n\tinitial = orDefault(initial, 'html');\n\n\tif( isElement(initial) ){\n\t\tinitial = cssValueToNumber(initial.style.getPropertyValue('font-size'));\n\t} else {\n\t\tconst value = cssValueToNumber(initial);\n\t\tif( isNaN(value) ){\n\t\t\tconst element = document.querySelector(initial);\n\t\t\tassert(hasValue(element), `${MODULE_NAME}:remByPx | selector does not return element`);\n\t\t\tinitial = cssValueToNumber(element.style.getPropertyValue('font-size'));\n\t\t} else {\n\t\t\tinitial = value;\n\t\t}\n\t}\n\n\tconst remVal = px / initial;\n\n\tif( (initial !== 0) && !isNaN(remVal) ){\n\t\treturn `${remVal}rem`;\n\t} else {\n\t\treturn null;\n\t}\n}\n"]} \ No newline at end of file diff --git a/dist/dates.js b/dist/dates.js index f9a82426..4f891542 100644 --- a/dist/dates.js +++ b/dist/dates.js @@ -1,5 +1,5 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Dates diff --git a/dist/dates.js.map b/dist/dates.js.map index 9a50b4de..3ed32fd3 100644 --- a/dist/dates.js.map +++ b/dist/dates.js.map @@ -1 +1 @@ -{"version":3,"file":"dates.js","names":["MODULE_NAME","hasValue","assert","orDefault","isArray","isDate","isString","isNumber","isInt","isNaN","isObject","isPlainObject","isFunction","pad","DATE_PART_SETTERS_AND_GETTERS","local","year","setter","getter","month","date","hours","minutes","seconds","milliseconds","utc","format","definition","locale","type","options","timeZone","settersAndGetters","predefinedStyles","includes","timezone","offset","getTimezoneOffset","Math","floor","abs","tokenMap","Map","set","slice","replaceAll","formattedDate","forEach","value","token","formatterOptions","dateStyle","timeStyle","concat","Intl","DateTimeFormat","SaneDate","__className__","invalidDateMessage","paramInvalidOrOutOfRangeMessage","constructor","initialValueOrYear","definedIndividualDateParts","hasDefinedIndividualDateParts","Object","values","filter","part","length","this","getVanillaDate","parseIsoString","parseInt","Date","toISOString","toIsoString","getISOString","getIsoString","getTime","createDatePartGettersAndSetters","entries","_","propertyConfig","enumerable","defineProperty","get","tryDatePartChange","getWeekDay","startingWith","asName","weekdays","day","getUTCDay","getDay","indexOf","getTimezone","padWithZero","getIsoDateString","getIsoTimeString","withTimezone","withSeparator","compareTo","initialValueOrSaneDate","withMilliseconds","saneDate","dateCompareGetters","timeCompareGetters","millisecondsCompareGetter","ownValue","compareValue","comparator","compareGetters","compareGetter","isBefore","isAfter","isSame","move","amount","parts","partDict","keys","join","forward","__methodName__","amountMustBePositiveMessage","backward","getDelta","largestUnit","relative","delta","negativeDelta","days","partName","clone","clonedSaneDate","digitCount","isoString","timezoneOffset","isoStringParts","split","isoStringDateParts","isoStringTimezoneParts","offsetFactor","isoStringTimezoneTimeParts","isoStringTimeParts","isoStringSecondsParts","ex","Error","newDate","allDatePartGetters","map","methods","sideEffect","datePartGetter"],"sources":["dates.js"],"mappings":"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","sourcesContent":["/*!\n * Module Dates\n */\n\n/**\n * @namespace Dates\n */\n\nconst MODULE_NAME = 'Dates';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {\n\thasValue,\n\tassert,\n\torDefault,\n\tisArray,\n\tisDate,\n\tisString,\n\tisNumber,\n\tisInt,\n\tisNaN,\n\tisObject,\n\tisPlainObject,\n\tisFunction\n} from './basic.js';\n\nimport {pad} from './strings.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst DATE_PART_SETTERS_AND_GETTERS = {\n\tlocal : {\n\t\tyear : {\n\t\t\tsetter : 'setFullYear',\n\t\t\tgetter : 'getFullYear'\n\t\t},\n\t\tmonth : {\n\t\t\tsetter : 'setMonth',\n\t\t\tgetter : 'getMonth',\n\t\t},\n\t\tdate : {\n\t\t\tsetter : 'setDate',\n\t\t\tgetter : 'getDate',\n\t\t},\n\t\thours : {\n\t\t\tsetter : 'setHours',\n\t\t\tgetter : 'getHours',\n\t\t},\n\t\tminutes : {\n\t\t\tsetter : 'setMinutes',\n\t\t\tgetter : 'getMinutes',\n\t\t},\n\t\tseconds : {\n\t\t\tsetter : 'setSeconds',\n\t\t\tgetter : 'getSeconds',\n\t\t},\n\t\tmilliseconds : {\n\t\t\tsetter : 'setMilliseconds',\n\t\t\tgetter : 'getMilliseconds',\n\t\t},\n\t},\n\tutc : {\n\t\tyear : {\n\t\t\tsetter : 'setUTCFullYear',\n\t\t\tgetter : 'getUTCFullYear',\n\t\t},\n\t\tmonth : {\n\t\t\tsetter : 'setUTCMonth',\n\t\t\tgetter : 'getUTCMonth',\n\t\t},\n\t\tdate : {\n\t\t\tsetter : 'setUTCDate',\n\t\t\tgetter : 'getUTCDate',\n\t\t},\n\t\thours : {\n\t\t\tsetter : 'setUTCHours',\n\t\t\tgetter : 'getUTCHours',\n\t\t},\n\t\tminutes : {\n\t\t\tsetter : 'setUTCMinutes',\n\t\t\tgetter : 'getUTCMinutes',\n\t\t},\n\t\tseconds : {\n\t\t\tsetter : 'setUTCSeconds',\n\t\t\tgetter : 'getUTCSeconds',\n\t\t},\n\t\tmilliseconds : {\n\t\t\tsetter : 'setUTCMilliseconds',\n\t\t\tgetter : 'getUTCMilliseconds',\n\t\t},\n\t}\n};\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Dates:format\n */\n\n/**\n * Returns a formatted string, describing the date in a verbose, non-technical way.\n *\n * Under the hood, this uses Intl.DateTimeFormat, which is widely supported and conveniently to use\n * for most widely used locales.\n *\n * \"definition\" may be a format shortcut for \"dateStyle\" (and \"timeStyle\" if type is \"datetime\") or a format string,\n * for a custom format, using these tokens:\n *\n * YY 18 two-digit year;\n * YYYY 2018 four-digit year;\n * M 1-12 the month, beginning at 1;\n * MM 01-12 the month, 2-digits;\n * D 1-31 the day of the month;\n * DD 01-31 the day of the month, 2-digits;\n * H 0-23 the hour;\n * HH 00-23 the hour, 2-digits;\n * h 1-12 the hour, 12-hour clock;\n * hh 01-12 the hour, 12-hour clock, 2-digits;\n * m 0-59 the minute;\n * mm 00-59 the minute, 2-digits;\n * s 0-59 the second;\n * ss 00-59 the second, 2-digits;\n * SSS 000-999 the millisecond, 3-digits;\n * Z +05:00 the offset from UTC, ±HH:mm;\n * ZZ +0500 the offset from UTC, ±HHmm;\n * A AM PM;\n * a am pm;\n *\n * Using these, you could create your own ISO string like this:\n * \"YYYY-MM-DDTHH:mm:ss.SSSZ\"\n *\n * If you use \"full\", \"long\", \"medium\" or \"short\" instead, you'll use the DateTimeFormatters built-in, preset\n * format styles for localized dates, based on the given locale(s).\n *\n * @param {Date} date - the date to format\n * @param {?String} [definition='long'] - either a preset style to quickly define a format style, by setting shortcuts for dateStyle and timeStyle (if type is \"datetime\"), set to \"none\" or nullish value to skip quick format; alternatively, define this as a format string to use a custom format\n * @param {?String|Array} [locale='en-US'] - locale to use for date format and text generation, use array to define fallback; always falls back to en-US if nothing else works\n * @param {?String} [type='datetime'] - set to 'datetime', 'date' or 'time' to define which parts should be rendered\n * @param {?Object} [options=null] - options to pass to the Intl.DateTimeFormat constructor, is applied last, so should override anything predefined, if key is reset\n * @returns {String} - the formatted date/time string\n *\n * @memberof Dates:format\n * @alias format\n * @variation Dates\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#style_shortcuts\n * @example\n * format(new Date(), 'de-DE', 'long', 'datetime', {timeZone : 'UTC'})\n * => '12. Dezember 2023 um 02:00:00 UTC'\n * format(new Date(), 'YYYY-MM-DDTHH:mm:ss.SSSZ')\n * => '2023-12-12T02:00:00'\n */\nexport function format(date, definition='long', locale='en-US', type='datetime', options=null){\n\tconst\n\t\tutc = (options?.timeZone === 'UTC'),\n\t\tsettersAndGetters = utc\n\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t,\n\t\tpredefinedStyles = ['full', 'long', 'medium', 'short', 'none']\n\t;\n\n\tif( hasValue(definition) && !predefinedStyles.includes(definition) ){\n\t\tlet timezone = '';\n\t\tconst offset = date.getTimezoneOffset();\n\t\tif( !utc && (offset !== 0) ){\n\t\t\tconst\n\t\t\t\thours = pad(Math.floor(Math.abs(offset) / 60), '0', 2),\n\t\t\t\tminutes = pad(Math.abs(offset) - (hours * 60), '0', 2)\n\t\t\t;\n\t\t\ttimezone = `${(offset < 0) ? '+' : '-'}${hours}:${minutes}`;\n\t\t}\n\n\t\tconst tokenMap = new Map();\n\t\ttokenMap.set('YYYY', `${date[settersAndGetters.year.getter]()}`);\n\t\ttokenMap.set('YY', `${date[settersAndGetters.year.getter]()}`.slice(-2));\n\t\ttokenMap.set('MM', pad(`${date[settersAndGetters.month.getter]() + 1}`, '0', 2));\n\t\ttokenMap.set('M', `${date[settersAndGetters.month.getter]() + 1}`);\n\t\ttokenMap.set('DD', pad(`${date[settersAndGetters.date.getter]()}`, '0', 2));\n\t\ttokenMap.set('D', `${date[settersAndGetters.date.getter]()}`);\n\t\ttokenMap.set('HH', pad(`${date[settersAndGetters.hours.getter]()}`, '0', 2));\n\t\ttokenMap.set('H', `${date[settersAndGetters.hours.getter]()}`);\n\t\ttokenMap.set('hh', pad(`${\n\t\t\t(date[settersAndGetters.hours.getter]() === 0)\n\t\t\t? 12\n\t\t\t: (\n\t\t\t\t(date[settersAndGetters.hours.getter]() > 12)\n\t\t\t\t? date[settersAndGetters.hours.getter]() - 12\n\t\t\t\t: date[settersAndGetters.hours.getter]()\n\t\t\t)\n\t\t}`, '0', 2));\n\t\ttokenMap.set('h', `${\n\t\t\t(date[settersAndGetters.hours.getter]() === 0)\n\t\t\t? 12\n\t\t\t: (\n\t\t\t\t(date[settersAndGetters.hours.getter]() > 12)\n\t\t\t\t? date[settersAndGetters.hours.getter]() - 12\n\t\t\t\t: date[settersAndGetters.hours.getter]()\n\t\t\t)\n\t\t}`);\n\t\ttokenMap.set('mm', pad(`${date[settersAndGetters.minutes.getter]()}`, '0', 2));\n\t\ttokenMap.set('m', `${date[settersAndGetters.minutes.getter]()}`);\n\t\ttokenMap.set('ss', pad(`${date[settersAndGetters.seconds.getter]()}`, '0', 2));\n\t\ttokenMap.set('s', `${date[settersAndGetters.seconds.getter]()}`);\n\t\ttokenMap.set('SSS', pad(`${date[settersAndGetters.milliseconds.getter]()}`, '0', 3));\n\t\ttokenMap.set('ZZ', timezone.replaceAll(':', ''));\n\t\ttokenMap.set('Z', timezone);\n\t\ttokenMap.set('A', `${(date[settersAndGetters.hours.getter]() >= 12) ? 'PM' : 'AM'}`);\n\t\ttokenMap.set('a', `${(date[settersAndGetters.hours.getter]() >= 12) ? 'pm' : 'am'}`);\n\n\t\tlet formattedDate = definition;\n\t\ttokenMap.forEach((value, token) => {\n\t\t\tformattedDate = formattedDate.replaceAll(token, value);\n\t\t});\n\n\t\treturn formattedDate;\n\t} else {\n\t\tlet formatterOptions = {};\n\n\t\tif( predefinedStyles.includes(definition) ){\n\t\t\tif( ['datetime', 'date'].includes(type) ){\n\t\t\t\tformatterOptions.dateStyle = definition;\n\t\t\t}\n\t\t\tif( ['datetime', 'time'].includes(type) ){\n\t\t\t\tformatterOptions.timeStyle = definition;\n\t\t\t}\n\t\t}\n\n\t\tlocale = orDefault(locale, 'en-US');\n\t\tif(\n\t\t\t(!isArray(locale) && (locale !== 'en-US'))\n\t\t\t|| (isArray(locale) && !locale.includes('en-US'))\n\t\t){\n\t\t\tlocale = [].concat(locale).concat('en-US');\n\t\t}\n\n\t\tformatterOptions = {\n\t\t\t...formatterOptions,\n\t\t\t...(options ?? {})\n\t\t};\n\n\t\treturn Intl.DateTimeFormat(locale, formatterOptions).format(date);\n\t}\n\n}\n\n\n\n/**\n * @namespace Dates:SaneDate\n **/\n\n/**\n * SaneDate is a reimplementation of JavaScript date objects, trying to iron out all the small fails\n * which make you want to pull your hair while keeping the cool stuff in a streamlined manner.\n *\n * SaneDates operate between the years 0 and 9999.\n * If you create a new SaneDate, it starts off in local mode, always working and returning local information, but\n * you may activate UTC mode by defining `.utc = true;`.\n *\n * Parsing an ISO string creates a local SaneDate if no timezone is defined, if you define \"Z\" or an offset, the\n * given string is interpreted as UTC info, so \"2012-12-12T12:00:00\" will set all parts as local information,\n * meaning, that the UTC representation may differ according to your timezone, while \"2012-12-12T12:00:00Z\" will\n * set all parts as UTC information, meaning that this is exactly what you get as the UTC representation, but your local\n * info will differ according to your timezone. \"2012-12-12T12:00:00+02:00\" on the other hand, will create UTC\n * information, with a negative offset of two hours, since this says: this datetime is two hours in the UTC future,\n * so the resulting UTC info will be at 10 o'clock, while your local info will behave according to your timezone in\n * regard to that info.\n *\n * The relevant date parts of a SaneDate, which are also available as attributes to get and set are:\n * \"year\", \"month\", \"date\" (not day!), \"hours\", \"minutes\", \"seconds\" and \"milliseconds\".\n *\n * Additionally, set UTC mode, using the \"utc\" property.\n *\n * SaneDates are very exception-happy and won't allow anything, that changes or produces a date in an unexpected\n * manner. All automagic behaviour of JS dates is an error here, so setting a month to 13 and expecting a year jump\n * will not work. Dates are very sensitive information and often used for contractual stuff, so anything coming out\n * differently than you defined it in the first place is very problematic. Every change to any single property triggers\n * a check, if any side effects occurred at all and if the change exactly results in the exact info being represented.\n * Any side effect or misrepresentation results in an exception, since something happened we did not expect or define.\n *\n * Months and week days are not zero based in SaneDates but begin with 1. Week days are not an attribute\n * (and not settable), but accessible via .getWeekDay().\n *\n * This whole implementation is heavily built around iso strings, so building a date with one and getting one\n * to transfer should be forgiving, easy and robust. Something like '1-2-3 4:5:6.7' is a usable iso string\n * for SaneDate, but getIsoString() will return correctly formatted '0001-02-03T04:05:06.700'.\n *\n * See class documentation below for details.\n *\n * @memberof Dates:SaneDate\n * @name SaneDate\n *\n * @see SaneDate\n * @example\n * let date = new SaneDate('1-2-3 4:5:6.7');\n * date = new SaneDate('2016-4-7');\n * date = new SaneDate('2016-04-07 13:37:00');\n * date = new SaneDate(2016, 4, 7);\n * date = new SaneDate(2016, 4, 7, 13, 37, 0, 999);\n * date.year = 2000;\n * date.forward('hours', 42);\n */\nclass SaneDate {\n\n\t#__className__ = 'SaneDate';\n\t#invalidDateMessage = 'invalid date, please check parameters - SaneDate only accepts values that result in a valid date, where the given value is reflected exactly (e.g.: setting hours to 25 will not work)';\n\t#paramInvalidOrOutOfRangeMessage = 'invalid or out of range';\n\t#date = null;\n\t#utc = false;\n\n\t/**\n\t * Creates a new SaneDate, either based on Date.now(), a given initial value or given date parts.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object} [initialValueOrYear=null] - something, that can be used to construct an initial value, this may be a vanilla Date, a SaneDate, a parsable string, a unix timestamp or an object implementing a method toISOString/toIsoString/getISOString/getIsoString; if this is a number, it will be treated as the year, if any other parameter is set as well; if nullish and all other parameters are not set either, the initial value is Date.now()\n\t * @param {?Number} [month=null] - month between 1 and 12, to set in initial value\n\t * @param {?Number} [date=null] - date between 1 and 31, to set in initial value\n\t * @param {?Number} [hours=null] - hours between 0 and 23, to set in initial value\n\t * @param {?Number} [minutes=null] - minutes between 0 and 59, to set in initial value\n\t * @param {?Number} [seconds=null] - seconds between 0 and 59, to set in initial value\n\t * @param {?Number} [milliseconds=null] - milliseconds between 0 and 999, to set in initial value\n\t * @throws error if created date is invalid\n\t */\n\tconstructor(initialValueOrYear=null, month=null, date=null, hours=null, minutes=null, seconds=null, milliseconds=null){\n\t\tconst __methodName__ = 'constructor';\n\n\t\tlet year = null;\n\t\tconst definedIndividualDateParts = {year, month, date, hours, minutes, seconds, milliseconds};\n\t\tlet hasDefinedIndividualDateParts = Object.values(definedIndividualDateParts).filter(part => isNumber(part)).length >= 1;\n\n\t\tif( initialValueOrYear instanceof SaneDate ){\n\t\t\tthis.#date = initialValueOrYear.getVanillaDate();\n\t\t} else if( isDate(initialValueOrYear) ){\n\t\t\tthis.#date = initialValueOrYear;\n\t\t} else if( isString(initialValueOrYear) ){\n\t\t\tthis.#date = this.#parseIsoString(initialValueOrYear);\n\t\t} else if( isNumber(initialValueOrYear) ){\n\t\t\tif( hasDefinedIndividualDateParts ){\n\t\t\t\tyear = parseInt(initialValueOrYear, 10);\n\t\t\t\tdefinedIndividualDateParts.year = year;\n\t\t\t} else {\n\t\t\t\tthis.#date = new Date(initialValueOrYear);\n\t\t\t}\n\t\t} else if(\n\t\t\tisObject(initialValueOrYear)\n\t\t\t&& (\n\t\t\t\tisFunction(initialValueOrYear.toISOString)\n\t\t\t\t|| isFunction(initialValueOrYear.toIsoString)\n\t\t\t\t|| isFunction(initialValueOrYear.getISOString)\n\t\t\t\t|| isFunction(initialValueOrYear.getIsoString)\n\t\t\t)\n\t\t){\n\t\t\tthis.#date = this.#parseIsoString(\n\t\t\t\tinitialValueOrYear.toISOString?.()\n\t\t\t\t?? initialValueOrYear.toIsoString?.()\n\t\t\t\t?? initialValueOrYear.getISOString?.()\n\t\t\t\t?? initialValueOrYear.getIsoString?.()\n\t\t\t);\n\t\t}\n\n\t\tif( !isDate(this.#date) ){\n\t\t\tthis.#date = hasDefinedIndividualDateParts ? new Date('1970-01-01T00:00:00.0') : new Date();\n\t\t}\n\n\t\tassert(\n\t\t\t!isNaN(this.#date.getTime()),\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#invalidDateMessage}`\n\t\t);\n\n\t\tthis.#createDatePartGettersAndSetters();\n\n\t\tif( hasDefinedIndividualDateParts ){\n\t\t\tObject.entries(definedIndividualDateParts)\n\t\t\t\t.filter(([_, value]) => isNumber(value))\n\t\t\t\t.forEach(([part, value]) => {\n\t\t\t\t\tthis[part] = value;\n\t\t\t\t})\n\t\t\t;\n\t\t}\n\t}\n\n\n\n\t/**\n\t * Creates getters and setters to leisurely access and change date properties by using property assignments\n\t * instead of method calls. This method provides most of the public interface of every SaneDate object.\n\t *\n\t * @private\n\t */\n\t#createDatePartGettersAndSetters(){\n\t\tconst propertyConfig = {\n\t\t\tenumerable : true\n\t\t};\n\n\t\t/**\n\t\t * @name SaneDate#utc\n\t\t * @property {Boolean} - defines if the date should behave as a UTC date instead of a local date (which is the default)\n\t\t */\n\t\tObject.defineProperty(this, 'utc', {\n\t\t\t...propertyConfig,\n\t\t\tset(utc){\n\t\t\t\tthis.#utc = !!utc;\n\t\t\t},\n\t\t\tget(){\n\t\t\t\treturn this.#utc;\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#year\n\t\t * @property {Number} - the date's year in the range of 0 to 9999\n\t\t */\n\t\tObject.defineProperty(this, 'year', {\n\t\t\t...propertyConfig,\n\t\t\tset(year){\n\t\t\t\tconst __methodName__ = 'set year';\n\n\t\t\t\tyear = parseInt(year, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(year)\n\t\t\t\t\t&& (year >= 0 && year <= 9999),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | year ${this.#paramInvalidOrOutOfRangeMessage} (0...9999)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('year', year);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.year.getter]();\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#month\n\t\t * @property {Number} - the date's month in the range of 1 to 12\n\t\t */\n\t\tObject.defineProperty(this, 'month', {\n\t\t\t...propertyConfig,\n\t\t\tset(month){\n\t\t\t\tconst __methodName__ = 'set month';\n\n\t\t\t\tmonth = parseInt(month, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(month)\n\t\t\t\t\t&& (month >= 1 && month <= 12),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | month ${this.#paramInvalidOrOutOfRangeMessage} (1...12)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('month', month - 1);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.month.getter]() + 1;\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#date\n\t\t * @property {Number} - the date's day of the month in the range of 1 to 31\n\t\t */\n\t\tObject.defineProperty(this, 'date', {\n\t\t\t...propertyConfig,\n\t\t\tset(date){\n\t\t\t\tconst __methodName__ = 'set date';\n\n\t\t\t\tdate = parseInt(date, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(date)\n\t\t\t\t\t&& (date >= 1 && date <= 31),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | date ${this.#paramInvalidOrOutOfRangeMessage} (1...31)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('date', date);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.date.getter]();\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#hours\n\t\t * @property {Number} - the date's hours in the range of 0 to 23\n\t\t */\n\t\tObject.defineProperty(this, 'hours',{\n\t\t\tset(hours){\n\t\t\t\tconst __methodName__ = 'set hours';\n\n\t\t\t\thours = parseInt(hours, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(hours)\n\t\t\t\t\t&& (hours >= 0 && hours <= 23),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | hours ${this.#paramInvalidOrOutOfRangeMessage} (0...23)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('hours', hours);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.hours.getter]();\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#minutes\n\t\t * @property {Number} - the date's minutes in the range of 0 to 59\n\t\t */\n\t\tObject.defineProperty(this, 'minutes', {\n\t\t\tset(minutes){\n\t\t\t\tconst __methodName__ = 'set hours';\n\n\t\t\t\tminutes = parseInt(minutes, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(minutes)\n\t\t\t\t\t&& (minutes >= 0 && minutes <= 59),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | minutes ${this.#paramInvalidOrOutOfRangeMessage} (0...59)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('minutes', minutes);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.minutes.getter]();\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#seconds\n\t\t * @property {Number} - the date's seconds in the range of 0 to 59\n\t\t */\n\t\tObject.defineProperty(this, 'seconds', {\n\t\t\tset(seconds){\n\t\t\t\tconst __methodName__ = 'set seconds';\n\n\t\t\t\tseconds = parseInt(seconds, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(seconds)\n\t\t\t\t\t&& (seconds >= 0 && seconds <= 59),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | seconds ${this.#paramInvalidOrOutOfRangeMessage} (0...59)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('seconds', seconds);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.seconds.getter]();\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#milliseconds\n\t\t * @property {Number} - the date's milliseconds in the range of 0 to 999\n\t\t */\n\t\tObject.defineProperty(this, 'milliseconds', {\n\t\t\tset(milliseconds){\n\t\t\t\tconst __methodName__ = 'set milliseconds';\n\n\t\t\t\tmilliseconds = parseInt(milliseconds, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(milliseconds)\n\t\t\t\t\t&& (milliseconds >= 0 && milliseconds <= 999),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | milliseconds ${this.#paramInvalidOrOutOfRangeMessage} (0...999)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('milliseconds', milliseconds);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.milliseconds.getter]();\n\t\t\t}\n\t\t});\n\t}\n\n\n\n\t/**\n\t * Returns the current day of the week as a number between 1 and 7 or an english day name.\n\t * This method counts days the European way, starting with monday, but you can change this\n\t * behaviour using the first parameter (if your week starts with sunday or friday for example).\n\t *\n\t * @param {?String} [startingWith='monday'] - set to the english day, which is the first day of the week (monday, tuesday, wednesday, thursday, friday, saturday, sunday)\n\t * @param {?Boolean} [asName=false] - set to true, if you'd like the method to return english day names instead of an index\n\t * @returns {Number|String} weekday index between 1 and 7 or english name of the day\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * if( d.getWeekDay() == 5 ){\n\t * alert(`Thank god it's ${d.getWeekday(null, true)}!`);\n\t * }\n\t */\n\tgetWeekDay(startingWith='monday', asName=false){\n\t\tconst __methodName__ = 'getWeekDay';\n\n\t\tconst weekdays = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];\n\t\tstartingWith = orDefault(startingWith, weekdays[1], 'str');\n\t\tassert(\n\t\t\tweekdays.includes(startingWith),\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | unknown weekday \"${startingWith}\"`\n\t\t);\n\n\t\tlet day = this.#utc ? this.#date.getUTCDay() : this.#date.getDay();\n\t\tif( asName ) return weekdays[day];\n\n\t\tconst offset = day - weekdays.indexOf(startingWith);\n\t\tif( offset < 0 ){\n\t\t\tday = 7 + offset;\n\t\t} else {\n\t\t\tday = offset;\n\t\t}\n\n\t\treturn day + 1;\n\t}\n\n\n\n\t/**\n\t * Returns the date's current timezone, like it would occur in an ISO-string (\"Z\", \"+06:00\", \"-02:30\").\n\t *\n\t * If you need the raw offset, use the vanilla date's getTimezoneOffset() method.\n\t *\n\t * @returns {String} - the timezone string\n\t *\n\t * @example\n\t * const d = new SaneDate()\n\t * d.getTimezone()\n\t * => \"+09:30\"\n\t */\n\tgetTimezone(){\n\t\tif( this.#utc ) return 'Z';\n\n\t\tconst offset = this.#date.getTimezoneOffset();\n\n\t\tif( offset === 0 ){\n\t\t\treturn 'Z';\n\t\t} else {\n\t\t\tconst\n\t\t\t\thours = this.#padWithZero(Math.floor(Math.abs(offset) / 60), 2),\n\t\t\t\tminutes = this.#padWithZero(Math.abs(offset) - (hours * 60), 2)\n\t\t\t;\n\t\t\treturn `${(offset < 0) ? '+' : '-'}${hours}:${minutes}`;\n\t\t}\n\t}\n\n\n\n\t/**\n\t * Returns the representation of the date's current date parts (year, month, day) as an ISO-string.\n\t *\n\t * A difference to the vanilla implementation is, that this method respects UTC mode and does not always\n\t * coerce the date to UTC automatically. So, this will return a local ISO representation if not in UTC mode\n\t * and the UTC representation in UTC mode.\n\t *\n\t * @returns {String} date ISO-string of the format \"2016-04-07\"\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * thatDatePicker.setValue(d.getIsoDateString());\n\t */\n\tgetIsoDateString(){\n\t\tconst\n\t\t\tyear = this.#padWithZero(this.year, 4),\n\t\t\tmonth = this.#padWithZero(this.month, 2),\n\t\t\tdate = this.#padWithZero(this.date, 2)\n\t\t;\n\n\t\treturn `${year}-${month}-${date}`;\n\t}\n\n\n\n\t/**\n\t * Returns the representation of the date's current time parts (hours, minutes, seconds, milliseconds) as an\n\t * ISO-string.\n\t *\n\t * A difference to the vanilla implementation is, that this method respects UTC mode and does not always\n\t * coerce the date to UTC automatically. So, this will return a local ISO representation (optionally with\n\t * timezone information in relation to UTC) if not in UTC mode and the UTC representation in UTC mode.\n\t *\n\t * @param {?Boolean} [withTimezone=true] - defines if the ISO string should end with timezone information, such as \"Z\" or \"+02:00\"\n\t * @returns {String} time ISO-string of the format \"12:59:00.123Z\"\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * thatDatePicker.setValue(`2023-12-12T${d.getIsoTimeString()}`);\n\t */\n\tgetIsoTimeString(withTimezone=true){\n\t\twithTimezone = orDefault(withTimezone, true, 'bool');\n\n\t\tconst\n\t\t\thours = this.#padWithZero(this.hours, 2),\n\t\t\tminutes = this.#padWithZero(this.minutes, 2),\n\t\t\tseconds = this.#padWithZero(this.seconds, 2),\n\t\t\tmilliseconds = this.#padWithZero(this.milliseconds, 3),\n\t\t\ttimezone = this.getTimezone()\n\t\t;\n\n\t\treturn `${hours}:${minutes}:${seconds}${(milliseconds > 0) ? '.'+milliseconds : ''}${withTimezone ? timezone : ''}`;\n\t}\n\n\n\n\t/**\n\t * Returns the date as an ISO-string.\n\t *\n\t * A difference to the vanilla implementation is, that this method respects UTC mode and does not always\n\t * coerce the date to UTC automatically. So, this will return a local ISO representation (optionally with\n\t * timezone information in relation to UTC) if not in UTC mode and the UTC representation in UTC mode.\n\t *\n\t * @param {?Boolean} [withSeparator=true] - defines if date and time should be separated with a \"T\"\n\t * @param {?Boolean} [withTimezone=true] - defines if the ISO string should end with timezone information, such as \"Z\" or \"+02:00\"\n\t * @returns {String} ISO-string of the format \"2016-04-07T13:37:00.222Z\"\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * thatDateTimePicker.setValue(d.getIsoString());\n\t */\n\tgetIsoString(withSeparator=true, withTimezone=true){\n\t\twithSeparator = orDefault(withSeparator, true, 'bool');\n\n\t\treturn `${this.getIsoDateString()}${withSeparator ? 'T' : ' '}${this.getIsoTimeString(withTimezone)}`;\n\t}\n\n\n\n\t/**\n\t * Returns a formatted string, describing the current date in a verbose, human-readable, non-technical way.\n\t *\n\t * \"definition\" may be a format shortcut for \"dateStyle\" (and \"timeStyle\" if type is \"datetime\") or a format string,\n\t * for a custom format, using these tokens:\n\t *\n\t * YY 18 two-digit year;\n\t * YYYY 2018 four-digit year;\n\t * M 1-12 the month, beginning at 1;\n\t * MM 01-12 the month, 2-digits;\n\t * D 1-31 the day of the month;\n\t * DD 01-31 the day of the month, 2-digits;\n\t * H 0-23 the hour;\n\t * HH 00-23 the hour, 2-digits;\n\t * h 1-12 the hour, 12-hour clock;\n\t * hh 01-12 the hour, 12-hour clock, 2-digits;\n\t * m 0-59 the minute;\n\t * mm 00-59 the minute, 2-digits;\n\t * s 0-59 the second;\n\t * ss 00-59 the second, 2-digits;\n\t * SSS 000-999 the millisecond, 3-digits;\n\t * Z +05:00 the offset from UTC, ±HH:mm;\n\t * ZZ +0500 the offset from UTC, ±HHmm;\n\t * A AM PM;\n\t * a am pm;\n\t *\n\t * Using these, you could create your own ISO string like this:\n\t * \"YYYY-MM-DDTHH:mm:ss.SSSZ\"\n\t *\n\t * If you use \"full\", \"long\", \"medium\" or \"short\" instead, you'll use the DateTimeFormatters built-in, preset\n\t * format styles for localized dates, based on the given locale(s).\n\t *\n\t * @param {?String} [definition='long'] - either a preset style to quickly define a format style, by setting shortcuts for dateStyle and timeStyle (if type is \"datetime\"), set to \"none\" or nullish value to skip quick format; alternatively, define this as a format string to use a custom format\n\t * @param {?String|Array} [locale='en-US'] - locale to use for date format and text generation, use array to define fallback; always falls back to en-US if nothing else works\n\t * @param {?String} [type='datetime'] - set to 'datetime', 'date' or 'time' to define which parts should be rendered\n\t * @param {?Object} [options=null] - options to pass to the Intl.DateTimeFormat constructor, is applied last, so should override anything predefined, if key is reset\n\t * @returns {String} - the formatted date/time string\n\t *\n\t * @see format(Dates)\n\t * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat\n\t * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#style_shortcuts\n\t * @example\n\t * const d = new SaneDate();\n\t * d.format('de-DE', 'long', 'datetime', {timeZone : 'UTC'})\n\t * => '12. Dezember 2023 um 02:00:00 UTC'\n\t * d.format('YYYY-MM-DDTHH:mm:ss.SSSZ')\n\t * => '2023-12-12T02:00:00'\n\t */\n\tformat(definition='long', locale='en-US', type='datetime', options=null){\n\t\toptions = orDefault(options, {});\n\n\t\tif( !hasValue(options.timeZone) && this.#utc ){\n\t\t\toptions.timeZone = 'UTC';\n\t\t}\n\n\t\treturn format(this.#date, definition, locale, type, options);\n\t}\n\n\n\n\t/**\n\t * Return the current original JavaScript date object wrapped by SaneDate.\n\t * Use this to do special things.\n\t *\n\t * @returns {Date} the original JavaScript date object\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * const timezoneOffset = d.getVanillaDate().getTimezoneOffset();\n\t */\n\tgetVanillaDate(){\n\t\treturn this.#date;\n\t}\n\n\n\n\t/**\n\t * Compares the date to another date in terms of placement on the time axis.\n\t *\n\t * Returns a classical comparator value (-1/0/1), being -1 if the date is earlier than the parameter.\n\t * Normally checks date and time. Set type to \"date\" to only check date.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object|SaneDate} initialValueOrSaneDate - anything compatible to the SaneDate constructor or a SaneDate instance\n\t * @param {?String} [type='datetime'] - either \"datetime\" or \"date\", telling the method if time should be considered\n\t * @param {?Boolean} [withMilliseconds=true] - tells the method if milliseconds should be considered if type is \"datetime\"\n\t * @throws error if compare date is not usable\n\t * @returns {Number} -1 if this date is smaller/earlier, 0 if identical, 1 if this date is bigger/later\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * if( d.compareTo('2016-04-07', 'date') === 0 ){\n\t * alert('congratulations, that\\'s the same date!');\n\t * }\n\t */\n\tcompareTo(initialValueOrSaneDate, type='datetime', withMilliseconds=true){\n\t\ttype = orDefault(type, 'datetime', 'string');\n\t\twithMilliseconds = orDefault(withMilliseconds, true, 'bool');\n\n\t\tconst\n\t\t\tsaneDate = new SaneDate(initialValueOrSaneDate),\n\t\t\tdateCompareGetters = [\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.year.getter,\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.month.getter,\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.date.getter,\n\t\t\t],\n\t\t\ttimeCompareGetters = [\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.hours.getter,\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.minutes.getter,\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.seconds.getter,\n\t\t\t],\n\t\t\tmillisecondsCompareGetter = DATE_PART_SETTERS_AND_GETTERS.utc.milliseconds.getter\n\t\t;\n\n\t\tlet compareGetters = [].concat(dateCompareGetters);\n\t\tif( type === 'datetime' ){\n\t\t\tcompareGetters = compareGetters.concat(timeCompareGetters);\n\t\t\tif( withMilliseconds ){\n\t\t\t\tcompareGetters = compareGetters.concat(millisecondsCompareGetter);\n\t\t\t}\n\t\t}\n\n\t\tlet ownValue, compareValue, comparator;\n\t\tfor( const compareGetter of compareGetters ){\n\t\t\townValue = this.#date[compareGetter]();\n\t\t\tcompareValue = saneDate.getVanillaDate()[compareGetter]();\n\t\t\tcomparator = (ownValue < compareValue)\n\t\t\t\t? -1\n\t\t\t\t: ((ownValue > compareValue) ? 1 : 0)\n\t\t\t;\n\n\t\t\tif( comparator !== 0 ){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn comparator;\n\t}\n\n\n\n\t/**\n\t * Returns if the SaneDate is earlier on the time axis than the comparison value.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object|SaneDate} initialValueOrSaneDate - anything compatible to the SaneDate constructor or a SaneDate instance\n\t * @param {?String} [type='datetime'] - either \"datetime\" or \"date\", telling the method if time should be considered\n\t * @param {?Boolean} [withMilliseconds=true] - tells the method if milliseconds should be considered if type is \"datetime\"\n\t * @throws error if compare date is not usable\n\t * @returns {Boolean} true if SaneDate is earlier than compare value\n\t *\n\t * @example\n\t * const now = new SaneDate();\n\t * const theFuture = now.clone().forward({days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5});\n\t * now.isBefore(theFuture)\n\t * => true\n\t * theFuture.isBefore(now)\n\t * => false\n\t */\n\tisBefore(initialValueOrSaneDate, type='datetime', withMilliseconds=true){\n\t\treturn this.compareTo(initialValueOrSaneDate, type, withMilliseconds) === -1;\n\t}\n\n\n\n\t/**\n\t * Returns if the SaneDate is later on the time axis than the comparison value.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object|SaneDate} initialValueOrSaneDate - anything compatible to the SaneDate constructor or a SaneDate instance\n\t * @param {?String} [type='datetime'] - either \"datetime\" or \"date\", telling the method if time should be considered\n\t * @param {?Boolean} [withMilliseconds=true] - tells the method if milliseconds should be considered if type is \"datetime\"\n\t * @throws error if compare date is not usable\n\t * @returns {Boolean} true if SaneDate is later than compare value\n\t *\n\t * @example\n\t * const now = new SaneDate();\n\t * const theFuture = now.clone().forward({days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5});\n\t * now.isAfter(theFuture)\n\t * => false\n\t * theFuture.isAfter(now)\n\t * => true\n\t */\n\tisAfter(initialValueOrSaneDate, type='datetime', withMilliseconds=true){\n\t\treturn this.compareTo(initialValueOrSaneDate, type, withMilliseconds) === 1;\n\t}\n\n\n\n\t/**\n\t * Returns if the SaneDate is at the same time as comparison value.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object|SaneDate} initialValueOrSaneDate - anything compatible to the SaneDate constructor or a SaneDate instance\n\t * @param {?String} [type='datetime'] - either \"datetime\" or \"date\", telling the method if time should be considered\n\t * @param {?Boolean} [withMilliseconds=true] - tells the method if milliseconds should be considered if type is \"datetime\"\n\t * @throws error if compare date is not usable\n\t * @returns {Boolean} true if SaneDate is at the same time as compare value\n\t *\n\t * @example\n\t * const now = new SaneDate();\n\t * const theFuture = now.clone();\n\t * now.isSame(theFuture)\n\t * => true\n\t * theFuture.forward({days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5});\n\t * theFuture.isSame(now)\n\t * => false\n\t */\n\tisSame(initialValueOrSaneDate, type='datetime', withMilliseconds=true){\n\t\treturn this.compareTo(initialValueOrSaneDate, type, withMilliseconds) === 0;\n\t}\n\n\n\n\t/**\n\t * Move the date a defined offset to the past or the future.\n\t *\n\t * @param {String|Object} part - the name of the date part to change, one of \"years\", \"months\", \"days\", \"hours\", \"minutes\", \"seconds\" and \"milliseconds\" or a dictionary of part/amount pairs ({hours : -1, seconds : 30})\n\t * @param {?Number} [amount=0] - negative or positive integer defining the offset from the current date\n\t * @throws error on invalid part name\n\t * @returns {SaneDate} the SaneDate instance\n\t *\n\t * @example\n\t * let d = new SaneDate();\n\t * d = d.move('years', 10).move('milliseconds', -1);\n\t */\n\tmove(part, amount=0){\n\t\tconst __methodName__ = 'move;'\n\n\t\tamount = orDefault(amount, 0, 'int');\n\n\t\tconst\n\t\t\tsettersAndGetters = DATE_PART_SETTERS_AND_GETTERS.utc,\n\t\t\tparts = ['years', 'months', 'days', 'hours', 'minutes', 'seconds', 'milliseconds']\n\t\t;\n\t\tlet partDict = {};\n\n\t\tif( !isPlainObject(part) ){\n\t\t\tpartDict[part] = amount;\n\t\t} else {\n\t\t\tpartDict = part;\n\t\t}\n\n\t\tObject.keys(partDict).forEach(part => {\n\t\t\tassert(\n\t\t\t\tparts.includes(part),\n\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | part must be one of ${parts.join(', ')}, is \"${part}\"`\n\t\t\t);\n\t\t});\n\n\t\tObject.entries(partDict).forEach(([part, amount]) => {\n\t\t\tswitch( part ){\n\t\t\t\tcase 'years':\n\t\t\t\t\tthis.#date[settersAndGetters.year.setter](this.#date[settersAndGetters.year.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'months':\n\t\t\t\t\tthis.#date[settersAndGetters.month.setter](this.#date[settersAndGetters.month.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'days':\n\t\t\t\t\tthis.#date[settersAndGetters.date.setter](this.#date[settersAndGetters.date.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'hours':\n\t\t\t\t\tthis.#date[settersAndGetters.hours.setter](this.#date[settersAndGetters.hours.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'minutes':\n\t\t\t\t\tthis.#date[settersAndGetters.minutes.setter](this.#date[settersAndGetters.minutes.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'seconds':\n\t\t\t\t\tthis.#date[settersAndGetters.seconds.setter](this.#date[settersAndGetters.seconds.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'milliseconds':\n\t\t\t\t\tthis.#date[settersAndGetters.milliseconds.setter](this.#date[settersAndGetters.milliseconds.getter]() + amount);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Moves the date's time forward a certain offset.\n\t *\n\t * @param {String|Object} part - the name of the date part to change, one of \"years\", \"months\", \"days\", \"hours\", \"minutes\", \"seconds\" and \"milliseconds\" or a dictionary of part/amount pairs ({hours : 1, seconds : 30})\n\t * @param {?Number} [amount=0] - integer defining the positive offset from the current date, negative value is treated as an error\n\t * @throws error on invalid part name or negative amount\n\t * @returns {SaneDate} the SaneDate instance\n\t *\n\t * @example\n\t * let d = new SaneDate();\n\t * d = d.forward('hours', 8);\n\t */\n\tforward(part, amount=0){\n\t\tconst\n\t\t\t__methodName__ = 'forward',\n\t\t\tamountMustBePositiveMessage = 'amount must be >= 0'\n\t\t;\n\n\t\tpart = `${part}`;\n\t\tamount = orDefault(amount, 0, 'int');\n\n\t\tlet partDict = {};\n\t\tif( !isPlainObject(part) ){\n\t\t\tassert(\n\t\t\t\tamount >= 0,\n\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${amountMustBePositiveMessage}`\n\t\t\t);\n\t\t\tpartDict[part] = amount;\n\t\t} else {\n\t\t\tpartDict = part;\n\t\t\tObject.entries(partDict).forEach(([part, amount]) => {\n\t\t\t\tamount = parseInt(amount, 10);\n\t\t\t\tassert(\n\t\t\t\t\tamount >= 0,\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${amountMustBePositiveMessage}`\n\t\t\t\t);\n\t\t\t\tpartDict[part] = amount;\n\t\t\t});\n\t\t}\n\n\t\treturn this.move(partDict);\n\t}\n\n\n\n\t/**\n\t * Moves the date's time backward a certain offset.\n\t *\n\t * @param {String|Object} part - the name of the date part to change, one of \"years\", \"months\", \"days\", \"hours\", \"minutes\", \"seconds\" and \"milliseconds\" or a dictionary of part/amount pairs ({hours : 1, seconds : 30})\n\t * @param {?Number} [amount=0] - integer defining the negative offset from the current date, negative value is treated as an error\n\t * @throws error on invalid part name or negative amount\n\t * @returns {SaneDate} the SaneDate instance\n\t *\n\t * @example\n\t * let d = new SaneDate();\n\t * d = d.backward('years', 1000);\n\t */\n\tbackward(part, amount=0){\n\t\tconst\n\t\t\t__methodName__ = 'backward',\n\t\t\tamountMustBePositiveMessage = 'amount must be >= 0'\n\t\t;\n\n\t\tpart = `${part}`;\n\t\tamount = orDefault(amount, 0, 'int');\n\n\t\tlet partDict = {};\n\t\tif( !isPlainObject(part) ){\n\t\t\tassert(\n\t\t\t\tamount >= 0,\n\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${amountMustBePositiveMessage}`\n\t\t\t);\n\t\t\tpartDict[part] = (amount === 0) ? 0 : -amount;\n\t\t} else {\n\t\t\tpartDict = part;\n\t\t\tObject.entries(partDict).forEach(([part, amount]) => {\n\t\t\t\tassert(\n\t\t\t\t\tamount >= 0,\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${amountMustBePositiveMessage}`\n\t\t\t\t);\n\t\t\t\tpartDict[part] = (amount === 0) ? 0 : -amount;\n\t\t\t});\n\t\t}\n\n\t\treturn this.move(partDict);\n\t}\n\n\n\n\t/**\n\t * Calculates a time delta between the SaneDate and a comparison value.\n\t *\n\t * The result is a plain object with the delta's units up to the defined \"largestUnit\". All values are integers.\n\t * The largest unit is days, since above neither months nor years are calculable via a fixed divisor and therefore\n\t * useless (since month vary from 28 to 31 days and years vary between 365 and 366 days, so both are not a fixed\n\t * unit).\n\t *\n\t * By default, the order does not matter and only the absolute value is used, but you can change this\n\t * through the parameter \"relative\", which by setting this to true, will include \"-\", if the comparison value\n\t * is in the future.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object|SaneDate} initialValueOrSaneDate - anything compatible to the SaneDate constructor or a SaneDate instance\n\t * @param {?String} [largestUnit='days'] - the largest time unit to differentiate in the result\n\t * @param {?Boolean} [relative=false] - if true, returns negative values if first parameter is later than this date (this adheres to the order defined by compareTo)\n\t * @throws error on unknown largestUnit or incompatible comparison value\n\t * @returns {Object} time delta object in the format {days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5} (keys depending on largestUnit)\n\t *\n\t * @example\n\t * const now = new SaneDate();\n\t * const theFuture = now.clone().forward({days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5});\n\t * now.getDelta(theFuture)\n\t * => {days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5}\n\t * now.getDelta(theFuture, 'hours', true)\n\t * => {hours : -26, minutes : -3, seconds : -4, milliseconds : -5}\n\t */\n\tgetDelta(initialValueOrSaneDate, largestUnit='days', relative=false){\n\t\tconst __methodName__ = 'getDelta';\n\n\t\tconst saneDate = new SaneDate(initialValueOrSaneDate);\n\t\tlargestUnit = orDefault(largestUnit, 'days', 'string');\n\t\tassert(\n\t\t\t['days', 'hours', 'minutes', 'seconds', 'milliseconds'].includes(largestUnit),\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | unknown largest unit`\n\t\t);\n\t\trelative = orDefault(relative, false, 'bool');\n\n\t\tconst parts = {};\n\t\tlet delta = relative\n\t\t\t? (this.#date.getTime() - saneDate.#date.getTime())\n\t\t\t: Math.abs(this.#date.getTime() - saneDate.#date.getTime())\n\t\t;\n\t\tconst negativeDelta = delta < 0;\n\t\tdelta = Math.abs(delta);\n\n\t\tif( largestUnit === 'days' ){\n\t\t\tparts.days = Math.floor(delta / 1000 / 60 / 60 / 24);\n\t\t\tdelta -= parts.days * 1000 * 60 * 60 * 24;\n\t\t\tlargestUnit = 'hours';\n\t\t}\n\n\t\tif( largestUnit === 'hours' ){\n\t\t\tparts.hours = Math.floor(delta / 1000 / 60 / 60);\n\t\t\tdelta -= parts.hours * 1000 * 60 * 60;\n\t\t\tlargestUnit = 'minutes';\n\t\t}\n\n\t\tif( largestUnit === 'minutes' ){\n\t\t\tparts.minutes = Math.floor(delta / 1000 / 60);\n\t\t\tdelta -= parts.minutes * 1000 * 60;\n\t\t\tlargestUnit = 'seconds';\n\t\t}\n\n\t\tif( largestUnit === 'seconds' ){\n\t\t\tparts.seconds = Math.floor(delta / 1000);\n\t\t\tdelta -= parts.seconds * 1000;\n\t\t\tlargestUnit = 'milliseconds';\n\t\t}\n\n\t\tif( largestUnit === 'milliseconds' ){\n\t\t\tparts.milliseconds = delta;\n\t\t}\n\n\t\tif( negativeDelta ){\n\t\t\tfor( const partName in parts ){\n\t\t\t\tparts[partName] = (parts[partName] === 0) ? 0 : -parts[partName];\n\t\t\t}\n\t\t}\n\n\t\treturn parts;\n\t}\n\n\n\n\t/**\n\t * Returns a copy of the current SaneDate.\n\t * Might be very handy for creating dates based on another with an offset for example.\n\t * Keeps UTC mode.\n\t *\n\t * @returns {SaneDate} copy of current SaneDate instance\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * const theFuture = d.clone().forward('hours', 8);\n\t **/\n\tclone(){\n\t\tconst clonedSaneDate = new SaneDate(new Date(this.getVanillaDate().getTime()));\n\t\tclonedSaneDate.utc = this.#utc;\n\t\treturn clonedSaneDate;\n\t}\n\n\n\n\t/**\n\t * Adds leading zeroes to values, which are not yet of a defined expected length.\n\t *\n\t * @param {*} value - the value to pad\n\t * @param {?Number} [digitCount=2] - the number of digits, the result has to have at least\n\t * @returns {String} the padded value, will always be cast to a string\n\t *\n\t * @private\n\t * @example\n\t * this.#padWithZero(1, 4)\n\t * => '0001'\n\t */\n\t#padWithZero(value, digitCount=2){\n\t\treturn pad(value, '0', digitCount);\n\t}\n\n\n\n\t/**\n\t * Tries to parse an ISO string (or at least, something resembling an ISO string) into a date.\n\t *\n\t * The basic idea of this method is, that it is supposed to be fairly forgiving, as long as the info is there,\n\t * even in a little wonky notation, this should result in a successfully created SaneDate.\n\t *\n\t * @param {String} isoString - something resembling an ISO string, that we can create a date from\n\t * @throws error if isoString is not usable\n\t * @returns {Date} the date create from the given ISO string\n\t *\n\t * @private\n\t * @example\n\t * this.#parseIsoString('2018-02-28T13:37:00')\n\t * this.#parseIsoString('1-2-3 4:5:6.7')\n\t */\n\t#parseIsoString(isoString){\n\t\tconst\n\t\t\t__methodName__ = '#parseIsoString',\n\t\t\tunparsableIsoStringMessage = 'ISO string not parsable'\n\t\t;\n\n\t\tisoString = `${isoString}`;\n\n\t\tlet\n\t\t\tyear = 1970,\n\t\t\tmonth = 1,\n\t\t\tdate = 1,\n\t\t\thours = 0,\n\t\t\tminutes = 0,\n\t\t\tseconds = 0,\n\t\t\tmilliseconds = 0,\n\t\t\ttimezoneOffset = 0,\n\t\t\tutc = false\n\t\t;\n\n\t\tlet isoStringParts = isoString.split('T');\n\t\tif( isoStringParts.length === 1 ){\n\t\t\tisoStringParts = isoStringParts[0].split(' ');\n\t\t}\n\n\n\t\t// date parts\n\n\t\tconst isoStringDateParts = isoStringParts[0].split('-');\n\t\tyear = isoStringDateParts[0];\n\t\tif( isoStringDateParts.length >= 2 ){\n\t\t\tmonth = isoStringDateParts[1];\n\t\t}\n\t\tif( isoStringDateParts.length >= 3 ){\n\t\t\tdate = isoStringDateParts[2];\n\t\t}\n\n\n\t\t// time parts\n\n\t\tif( isoStringParts.length >= 2 ){\n\t\t\t// timezone\n\n\t\t\tlet\tisoStringTimezoneParts = isoStringParts[1].split('Z');\n\t\t\tif( isoStringTimezoneParts.length >= 2 ){\n\t\t\t\tutc = true;\n\t\t\t} else {\n\t\t\t\tlet offsetFactor = 0;\n\t\t\t\tif( isoStringTimezoneParts[0].includes('+') ){\n\t\t\t\t\toffsetFactor = -1;\n\t\t\t\t\tisoStringTimezoneParts = isoStringTimezoneParts[0].split('+');\n\t\t\t\t} else if( isoStringTimezoneParts[0].includes('-') ){\n\t\t\t\t\toffsetFactor = 1;\n\t\t\t\t\tisoStringTimezoneParts = isoStringTimezoneParts[0].split('-');\n\t\t\t\t}\n\n\t\t\t\tif( isoStringTimezoneParts.length >= 2 ){\n\t\t\t\t\tconst isoStringTimezoneTimeParts = isoStringTimezoneParts[1].split(':');\n\n\t\t\t\t\tif( isoStringTimezoneTimeParts.length >= 2 ){\n\t\t\t\t\t\ttimezoneOffset += parseInt(isoStringTimezoneTimeParts[0], 10) * 60;\n\t\t\t\t\t\ttimezoneOffset += parseInt(isoStringTimezoneTimeParts[1], 10);\n\t\t\t\t\t} else if( isoStringTimezoneTimeParts[0].length >= 3 ){\n\t\t\t\t\t\ttimezoneOffset += parseInt(isoStringTimezoneTimeParts[0].slice(0, 2), 10) * 60;\n\t\t\t\t\t\ttimezoneOffset += parseInt(isoStringTimezoneTimeParts[1].slice(2), 10);\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttimezoneOffset += parseInt(isoStringTimezoneTimeParts[0], 10) * 60;\n\t\t\t\t\t}\n\t\t\t\t\ttimezoneOffset *= offsetFactor;\n\n\t\t\t\t\tassert(\n\t\t\t\t\t\t!isNaN(timezoneOffset),\n\t\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | invalid timezone \"${isoStringTimezoneParts[1]}\"`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\t// hours and minutes\n\t\t\tconst isoStringTimeParts = isoStringTimezoneParts[0].split(':');\n\t\t\thours = isoStringTimeParts[0];\n\t\t\tif( isoStringTimeParts.length >= 2 ){\n\t\t\t\tminutes = isoStringTimeParts[1];\n\t\t\t}\n\n\n\t\t\t// seconds and milliseconds\n\n\t\t\tif( isoStringTimeParts.length >= 3 ){\n\t\t\t\tconst isoStringSecondsParts = isoStringTimeParts[2].split('.');\n\n\t\t\t\tseconds = isoStringSecondsParts[0];\n\n\t\t\t\tif( isoStringSecondsParts.length >= 2 ){\n\t\t\t\t\tmilliseconds = isoStringSecondsParts[1];\n\n\t\t\t\t\tif( milliseconds.length > 3 ){\n\t\t\t\t\t\tmilliseconds = milliseconds.slice(0, 3);\n\t\t\t\t\t} else if( milliseconds.length === 2 ){\n\t\t\t\t\t\tmilliseconds = `${parseInt(milliseconds, 10) * 10}`;\n\t\t\t\t\t} else if( milliseconds.length === 1 ){\n\t\t\t\t\t\tmilliseconds = `${parseInt(milliseconds, 10) * 100}`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\n\t\t// date construction\n\n\t\tconst saneDate = new SaneDate();\n\t\tsaneDate.utc = utc || (timezoneOffset !== 0);\n\t\ttry {\n\t\t\tsaneDate.year = year;\n\t\t\tsaneDate.month = month;\n\t\t\tsaneDate.date = date;\n\t\t\tsaneDate.hours = hours;\n\t\t\tsaneDate.minutes = minutes;\n\t\t\tsaneDate.seconds = seconds;\n\t\t\tsaneDate.milliseconds = milliseconds;\n\t\t} catch(ex){\n\t\t\tthrow Error(`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${unparsableIsoStringMessage} \"${isoString}\"`);\n\t\t}\n\t\tsaneDate.move('minutes', timezoneOffset);\n\n\t\treturn saneDate.getVanillaDate();\n\t}\n\n\n\n\t/**\n\t * Tries to change a part of the date and makes sure, that this change does not trigger automagic and only\n\t * leads to exactly the change, we wanted to do and nothing else.\n\t *\n\t * @param {String} part - the date part to change, one of: year, month, date, hours, minutes, seconds or milliseconds\n\t * @param {Number} value - the new value to set\n\t * @returns {SaneDate} the SaneDate instance\n\t *\n\t * @private\n\t */\n\t#tryDatePartChange(part, value){\n\t\tconst __methodName__ = '#tryDatePartChange';\n\n\t\tconst\n\t\t\tnewDate = this.clone().getVanillaDate(),\n\t\t\tsettersAndGetters = this.#utc\n\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t,\n\t\t\tallDatePartGetters = Object.values(settersAndGetters).map(methods => methods.getter)\n\t\t;\n\n\t\tnewDate[settersAndGetters[part].setter](value);\n\n\t\tlet sideEffect = false;\n\t\tfor( const datePartGetter of allDatePartGetters ){\n\t\t\tif( datePartGetter !== settersAndGetters[part].getter){\n\t\t\t\tsideEffect ||= this.#date[datePartGetter]() !== newDate[datePartGetter]();\n\t\t\t}\n\n\t\t\tif( sideEffect ){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tassert(\n\t\t\t(newDate[settersAndGetters[part].getter]() === value) && !sideEffect,\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | date part change \"${part} = ${value}\" is invalid or has side effects`\n\t\t);\n\n\t\tthis.#date = newDate;\n\n\t\treturn this;\n\t}\n\n}\n\nexport {SaneDate};\n"]} \ No newline at end of file +{"version":3,"file":"dates.js","names":["MODULE_NAME","hasValue","assert","orDefault","isArray","isDate","isString","isNumber","isInt","isNaN","isObject","isPlainObject","isFunction","pad","DATE_PART_SETTERS_AND_GETTERS","local","year","setter","getter","month","date","hours","minutes","seconds","milliseconds","utc","format","definition","locale","type","options","timeZone","settersAndGetters","predefinedStyles","includes","timezone","offset","getTimezoneOffset","Math","floor","abs","tokenMap","Map","set","slice","replaceAll","formattedDate","forEach","value","token","formatterOptions","dateStyle","timeStyle","concat","Intl","DateTimeFormat","SaneDate","__className__","invalidDateMessage","paramInvalidOrOutOfRangeMessage","constructor","initialValueOrYear","definedIndividualDateParts","hasDefinedIndividualDateParts","Object","values","filter","part","length","this","getVanillaDate","parseIsoString","parseInt","Date","toISOString","toIsoString","getISOString","getIsoString","getTime","createDatePartGettersAndSetters","entries","_","propertyConfig","enumerable","defineProperty","get","tryDatePartChange","getWeekDay","startingWith","asName","weekdays","day","getUTCDay","getDay","indexOf","getTimezone","padWithZero","getIsoDateString","getIsoTimeString","withTimezone","withSeparator","compareTo","initialValueOrSaneDate","withMilliseconds","saneDate","dateCompareGetters","timeCompareGetters","millisecondsCompareGetter","ownValue","compareValue","comparator","compareGetters","compareGetter","isBefore","isAfter","isSame","move","amount","parts","partDict","keys","join","forward","__methodName__","amountMustBePositiveMessage","backward","getDelta","largestUnit","relative","delta","negativeDelta","days","partName","clone","clonedSaneDate","digitCount","isoString","timezoneOffset","isoStringParts","split","isoStringDateParts","isoStringTimezoneParts","offsetFactor","isoStringTimezoneTimeParts","isoStringTimeParts","isoStringSecondsParts","ex","Error","newDate","allDatePartGetters","map","methods","sideEffect","datePartGetter"],"sources":["dates.js"],"mappings":"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","ignoreList":[],"sourcesContent":["/*!\n * Module Dates\n */\n\n/**\n * @namespace Dates\n */\n\nconst MODULE_NAME = 'Dates';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {\n\thasValue,\n\tassert,\n\torDefault,\n\tisArray,\n\tisDate,\n\tisString,\n\tisNumber,\n\tisInt,\n\tisNaN,\n\tisObject,\n\tisPlainObject,\n\tisFunction\n} from './basic.js';\n\nimport {pad} from './strings.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst DATE_PART_SETTERS_AND_GETTERS = {\n\tlocal : {\n\t\tyear : {\n\t\t\tsetter : 'setFullYear',\n\t\t\tgetter : 'getFullYear'\n\t\t},\n\t\tmonth : {\n\t\t\tsetter : 'setMonth',\n\t\t\tgetter : 'getMonth',\n\t\t},\n\t\tdate : {\n\t\t\tsetter : 'setDate',\n\t\t\tgetter : 'getDate',\n\t\t},\n\t\thours : {\n\t\t\tsetter : 'setHours',\n\t\t\tgetter : 'getHours',\n\t\t},\n\t\tminutes : {\n\t\t\tsetter : 'setMinutes',\n\t\t\tgetter : 'getMinutes',\n\t\t},\n\t\tseconds : {\n\t\t\tsetter : 'setSeconds',\n\t\t\tgetter : 'getSeconds',\n\t\t},\n\t\tmilliseconds : {\n\t\t\tsetter : 'setMilliseconds',\n\t\t\tgetter : 'getMilliseconds',\n\t\t},\n\t},\n\tutc : {\n\t\tyear : {\n\t\t\tsetter : 'setUTCFullYear',\n\t\t\tgetter : 'getUTCFullYear',\n\t\t},\n\t\tmonth : {\n\t\t\tsetter : 'setUTCMonth',\n\t\t\tgetter : 'getUTCMonth',\n\t\t},\n\t\tdate : {\n\t\t\tsetter : 'setUTCDate',\n\t\t\tgetter : 'getUTCDate',\n\t\t},\n\t\thours : {\n\t\t\tsetter : 'setUTCHours',\n\t\t\tgetter : 'getUTCHours',\n\t\t},\n\t\tminutes : {\n\t\t\tsetter : 'setUTCMinutes',\n\t\t\tgetter : 'getUTCMinutes',\n\t\t},\n\t\tseconds : {\n\t\t\tsetter : 'setUTCSeconds',\n\t\t\tgetter : 'getUTCSeconds',\n\t\t},\n\t\tmilliseconds : {\n\t\t\tsetter : 'setUTCMilliseconds',\n\t\t\tgetter : 'getUTCMilliseconds',\n\t\t},\n\t}\n};\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Dates:format\n */\n\n/**\n * Returns a formatted string, describing the date in a verbose, non-technical way.\n *\n * Under the hood, this uses Intl.DateTimeFormat, which is widely supported and conveniently to use\n * for most widely used locales.\n *\n * \"definition\" may be a format shortcut for \"dateStyle\" (and \"timeStyle\" if type is \"datetime\") or a format string,\n * for a custom format, using these tokens:\n *\n * YY 18 two-digit year;\n * YYYY 2018 four-digit year;\n * M 1-12 the month, beginning at 1;\n * MM 01-12 the month, 2-digits;\n * D 1-31 the day of the month;\n * DD 01-31 the day of the month, 2-digits;\n * H 0-23 the hour;\n * HH 00-23 the hour, 2-digits;\n * h 1-12 the hour, 12-hour clock;\n * hh 01-12 the hour, 12-hour clock, 2-digits;\n * m 0-59 the minute;\n * mm 00-59 the minute, 2-digits;\n * s 0-59 the second;\n * ss 00-59 the second, 2-digits;\n * SSS 000-999 the millisecond, 3-digits;\n * Z +05:00 the offset from UTC, ±HH:mm;\n * ZZ +0500 the offset from UTC, ±HHmm;\n * A AM PM;\n * a am pm;\n *\n * Using these, you could create your own ISO string like this:\n * \"YYYY-MM-DDTHH:mm:ss.SSSZ\"\n *\n * If you use \"full\", \"long\", \"medium\" or \"short\" instead, you'll use the DateTimeFormatters built-in, preset\n * format styles for localized dates, based on the given locale(s).\n *\n * @param {Date} date - the date to format\n * @param {?String} [definition='long'] - either a preset style to quickly define a format style, by setting shortcuts for dateStyle and timeStyle (if type is \"datetime\"), set to \"none\" or nullish value to skip quick format; alternatively, define this as a format string to use a custom format\n * @param {?String|Array} [locale='en-US'] - locale to use for date format and text generation, use array to define fallback; always falls back to en-US if nothing else works\n * @param {?String} [type='datetime'] - set to 'datetime', 'date' or 'time' to define which parts should be rendered\n * @param {?Object} [options=null] - options to pass to the Intl.DateTimeFormat constructor, is applied last, so should override anything predefined, if key is reset\n * @returns {String} - the formatted date/time string\n *\n * @memberof Dates:format\n * @alias format\n * @variation Dates\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#style_shortcuts\n * @example\n * format(new Date(), 'de-DE', 'long', 'datetime', {timeZone : 'UTC'})\n * => '12. Dezember 2023 um 02:00:00 UTC'\n * format(new Date(), 'YYYY-MM-DDTHH:mm:ss.SSSZ')\n * => '2023-12-12T02:00:00'\n */\nexport function format(date, definition='long', locale='en-US', type='datetime', options=null){\n\tconst\n\t\tutc = (options?.timeZone === 'UTC'),\n\t\tsettersAndGetters = utc\n\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t,\n\t\tpredefinedStyles = ['full', 'long', 'medium', 'short', 'none']\n\t;\n\n\tif( hasValue(definition) && !predefinedStyles.includes(definition) ){\n\t\tlet timezone = '';\n\t\tconst offset = date.getTimezoneOffset();\n\t\tif( !utc && (offset !== 0) ){\n\t\t\tconst\n\t\t\t\thours = pad(Math.floor(Math.abs(offset) / 60), '0', 2),\n\t\t\t\tminutes = pad(Math.abs(offset) - (hours * 60), '0', 2)\n\t\t\t;\n\t\t\ttimezone = `${(offset < 0) ? '+' : '-'}${hours}:${minutes}`;\n\t\t}\n\n\t\tconst tokenMap = new Map();\n\t\ttokenMap.set('YYYY', `${date[settersAndGetters.year.getter]()}`);\n\t\ttokenMap.set('YY', `${date[settersAndGetters.year.getter]()}`.slice(-2));\n\t\ttokenMap.set('MM', pad(`${date[settersAndGetters.month.getter]() + 1}`, '0', 2));\n\t\ttokenMap.set('M', `${date[settersAndGetters.month.getter]() + 1}`);\n\t\ttokenMap.set('DD', pad(`${date[settersAndGetters.date.getter]()}`, '0', 2));\n\t\ttokenMap.set('D', `${date[settersAndGetters.date.getter]()}`);\n\t\ttokenMap.set('HH', pad(`${date[settersAndGetters.hours.getter]()}`, '0', 2));\n\t\ttokenMap.set('H', `${date[settersAndGetters.hours.getter]()}`);\n\t\ttokenMap.set('hh', pad(`${\n\t\t\t(date[settersAndGetters.hours.getter]() === 0)\n\t\t\t? 12\n\t\t\t: (\n\t\t\t\t(date[settersAndGetters.hours.getter]() > 12)\n\t\t\t\t? date[settersAndGetters.hours.getter]() - 12\n\t\t\t\t: date[settersAndGetters.hours.getter]()\n\t\t\t)\n\t\t}`, '0', 2));\n\t\ttokenMap.set('h', `${\n\t\t\t(date[settersAndGetters.hours.getter]() === 0)\n\t\t\t? 12\n\t\t\t: (\n\t\t\t\t(date[settersAndGetters.hours.getter]() > 12)\n\t\t\t\t? date[settersAndGetters.hours.getter]() - 12\n\t\t\t\t: date[settersAndGetters.hours.getter]()\n\t\t\t)\n\t\t}`);\n\t\ttokenMap.set('mm', pad(`${date[settersAndGetters.minutes.getter]()}`, '0', 2));\n\t\ttokenMap.set('m', `${date[settersAndGetters.minutes.getter]()}`);\n\t\ttokenMap.set('ss', pad(`${date[settersAndGetters.seconds.getter]()}`, '0', 2));\n\t\ttokenMap.set('s', `${date[settersAndGetters.seconds.getter]()}`);\n\t\ttokenMap.set('SSS', pad(`${date[settersAndGetters.milliseconds.getter]()}`, '0', 3));\n\t\ttokenMap.set('ZZ', timezone.replaceAll(':', ''));\n\t\ttokenMap.set('Z', timezone);\n\t\ttokenMap.set('A', `${(date[settersAndGetters.hours.getter]() >= 12) ? 'PM' : 'AM'}`);\n\t\ttokenMap.set('a', `${(date[settersAndGetters.hours.getter]() >= 12) ? 'pm' : 'am'}`);\n\n\t\tlet formattedDate = definition;\n\t\ttokenMap.forEach((value, token) => {\n\t\t\tformattedDate = formattedDate.replaceAll(token, value);\n\t\t});\n\n\t\treturn formattedDate;\n\t} else {\n\t\tlet formatterOptions = {};\n\n\t\tif( predefinedStyles.includes(definition) ){\n\t\t\tif( ['datetime', 'date'].includes(type) ){\n\t\t\t\tformatterOptions.dateStyle = definition;\n\t\t\t}\n\t\t\tif( ['datetime', 'time'].includes(type) ){\n\t\t\t\tformatterOptions.timeStyle = definition;\n\t\t\t}\n\t\t}\n\n\t\tlocale = orDefault(locale, 'en-US');\n\t\tif(\n\t\t\t(!isArray(locale) && (locale !== 'en-US'))\n\t\t\t|| (isArray(locale) && !locale.includes('en-US'))\n\t\t){\n\t\t\tlocale = [].concat(locale).concat('en-US');\n\t\t}\n\n\t\tformatterOptions = {\n\t\t\t...formatterOptions,\n\t\t\t...(options ?? {})\n\t\t};\n\n\t\treturn Intl.DateTimeFormat(locale, formatterOptions).format(date);\n\t}\n\n}\n\n\n\n/**\n * @namespace Dates:SaneDate\n **/\n\n/**\n * SaneDate is a reimplementation of JavaScript date objects, trying to iron out all the small fails\n * which make you want to pull your hair while keeping the cool stuff in a streamlined manner.\n *\n * SaneDates operate between the years 0 and 9999.\n * If you create a new SaneDate, it starts off in local mode, always working and returning local information, but\n * you may activate UTC mode by defining `.utc = true;`.\n *\n * Parsing an ISO string creates a local SaneDate if no timezone is defined, if you define \"Z\" or an offset, the\n * given string is interpreted as UTC info, so \"2012-12-12T12:00:00\" will set all parts as local information,\n * meaning, that the UTC representation may differ according to your timezone, while \"2012-12-12T12:00:00Z\" will\n * set all parts as UTC information, meaning that this is exactly what you get as the UTC representation, but your local\n * info will differ according to your timezone. \"2012-12-12T12:00:00+02:00\" on the other hand, will create UTC\n * information, with a negative offset of two hours, since this says: this datetime is two hours in the UTC future,\n * so the resulting UTC info will be at 10 o'clock, while your local info will behave according to your timezone in\n * regard to that info.\n *\n * The relevant date parts of a SaneDate, which are also available as attributes to get and set are:\n * \"year\", \"month\", \"date\" (not day!), \"hours\", \"minutes\", \"seconds\" and \"milliseconds\".\n *\n * Additionally, set UTC mode, using the \"utc\" property.\n *\n * SaneDates are very exception-happy and won't allow anything, that changes or produces a date in an unexpected\n * manner. All automagic behaviour of JS dates is an error here, so setting a month to 13 and expecting a year jump\n * will not work. Dates are very sensitive information and often used for contractual stuff, so anything coming out\n * differently than you defined it in the first place is very problematic. Every change to any single property triggers\n * a check, if any side effects occurred at all and if the change exactly results in the exact info being represented.\n * Any side effect or misrepresentation results in an exception, since something happened we did not expect or define.\n *\n * Months and week days are not zero based in SaneDates but begin with 1. Week days are not an attribute\n * (and not settable), but accessible via .getWeekDay().\n *\n * This whole implementation is heavily built around iso strings, so building a date with one and getting one\n * to transfer should be forgiving, easy and robust. Something like '1-2-3 4:5:6.7' is a usable iso string\n * for SaneDate, but getIsoString() will return correctly formatted '0001-02-03T04:05:06.700'.\n *\n * See class documentation below for details.\n *\n * @memberof Dates:SaneDate\n * @name SaneDate\n *\n * @see SaneDate\n * @example\n * let date = new SaneDate('1-2-3 4:5:6.7');\n * date = new SaneDate('2016-4-7');\n * date = new SaneDate('2016-04-07 13:37:00');\n * date = new SaneDate(2016, 4, 7);\n * date = new SaneDate(2016, 4, 7, 13, 37, 0, 999);\n * date.year = 2000;\n * date.forward('hours', 42);\n */\nclass SaneDate {\n\n\t#__className__ = 'SaneDate';\n\t#invalidDateMessage = 'invalid date, please check parameters - SaneDate only accepts values that result in a valid date, where the given value is reflected exactly (e.g.: setting hours to 25 will not work)';\n\t#paramInvalidOrOutOfRangeMessage = 'invalid or out of range';\n\t#date = null;\n\t#utc = false;\n\n\t/**\n\t * Creates a new SaneDate, either based on Date.now(), a given initial value or given date parts.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object} [initialValueOrYear=null] - something, that can be used to construct an initial value, this may be a vanilla Date, a SaneDate, a parsable string, a unix timestamp or an object implementing a method toISOString/toIsoString/getISOString/getIsoString; if this is a number, it will be treated as the year, if any other parameter is set as well; if nullish and all other parameters are not set either, the initial value is Date.now()\n\t * @param {?Number} [month=null] - month between 1 and 12, to set in initial value\n\t * @param {?Number} [date=null] - date between 1 and 31, to set in initial value\n\t * @param {?Number} [hours=null] - hours between 0 and 23, to set in initial value\n\t * @param {?Number} [minutes=null] - minutes between 0 and 59, to set in initial value\n\t * @param {?Number} [seconds=null] - seconds between 0 and 59, to set in initial value\n\t * @param {?Number} [milliseconds=null] - milliseconds between 0 and 999, to set in initial value\n\t * @throws error if created date is invalid\n\t */\n\tconstructor(initialValueOrYear=null, month=null, date=null, hours=null, minutes=null, seconds=null, milliseconds=null){\n\t\tconst __methodName__ = 'constructor';\n\n\t\tlet year = null;\n\t\tconst definedIndividualDateParts = {year, month, date, hours, minutes, seconds, milliseconds};\n\t\tlet hasDefinedIndividualDateParts = Object.values(definedIndividualDateParts).filter(part => isNumber(part)).length >= 1;\n\n\t\tif( initialValueOrYear instanceof SaneDate ){\n\t\t\tthis.#date = initialValueOrYear.getVanillaDate();\n\t\t} else if( isDate(initialValueOrYear) ){\n\t\t\tthis.#date = initialValueOrYear;\n\t\t} else if( isString(initialValueOrYear) ){\n\t\t\tthis.#date = this.#parseIsoString(initialValueOrYear);\n\t\t} else if( isNumber(initialValueOrYear) ){\n\t\t\tif( hasDefinedIndividualDateParts ){\n\t\t\t\tyear = parseInt(initialValueOrYear, 10);\n\t\t\t\tdefinedIndividualDateParts.year = year;\n\t\t\t} else {\n\t\t\t\tthis.#date = new Date(initialValueOrYear);\n\t\t\t}\n\t\t} else if(\n\t\t\tisObject(initialValueOrYear)\n\t\t\t&& (\n\t\t\t\tisFunction(initialValueOrYear.toISOString)\n\t\t\t\t|| isFunction(initialValueOrYear.toIsoString)\n\t\t\t\t|| isFunction(initialValueOrYear.getISOString)\n\t\t\t\t|| isFunction(initialValueOrYear.getIsoString)\n\t\t\t)\n\t\t){\n\t\t\tthis.#date = this.#parseIsoString(\n\t\t\t\tinitialValueOrYear.toISOString?.()\n\t\t\t\t?? initialValueOrYear.toIsoString?.()\n\t\t\t\t?? initialValueOrYear.getISOString?.()\n\t\t\t\t?? initialValueOrYear.getIsoString?.()\n\t\t\t);\n\t\t}\n\n\t\tif( !isDate(this.#date) ){\n\t\t\tthis.#date = hasDefinedIndividualDateParts ? new Date('1970-01-01T00:00:00.0') : new Date();\n\t\t}\n\n\t\tassert(\n\t\t\t!isNaN(this.#date.getTime()),\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#invalidDateMessage}`\n\t\t);\n\n\t\tthis.#createDatePartGettersAndSetters();\n\n\t\tif( hasDefinedIndividualDateParts ){\n\t\t\tObject.entries(definedIndividualDateParts)\n\t\t\t\t.filter(([_, value]) => isNumber(value))\n\t\t\t\t.forEach(([part, value]) => {\n\t\t\t\t\tthis[part] = value;\n\t\t\t\t})\n\t\t\t;\n\t\t}\n\t}\n\n\n\n\t/**\n\t * Creates getters and setters to leisurely access and change date properties by using property assignments\n\t * instead of method calls. This method provides most of the public interface of every SaneDate object.\n\t *\n\t * @private\n\t */\n\t#createDatePartGettersAndSetters(){\n\t\tconst propertyConfig = {\n\t\t\tenumerable : true\n\t\t};\n\n\t\t/**\n\t\t * @name SaneDate#utc\n\t\t * @property {Boolean} - defines if the date should behave as a UTC date instead of a local date (which is the default)\n\t\t */\n\t\tObject.defineProperty(this, 'utc', {\n\t\t\t...propertyConfig,\n\t\t\tset(utc){\n\t\t\t\tthis.#utc = !!utc;\n\t\t\t},\n\t\t\tget(){\n\t\t\t\treturn this.#utc;\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#year\n\t\t * @property {Number} - the date's year in the range of 0 to 9999\n\t\t */\n\t\tObject.defineProperty(this, 'year', {\n\t\t\t...propertyConfig,\n\t\t\tset(year){\n\t\t\t\tconst __methodName__ = 'set year';\n\n\t\t\t\tyear = parseInt(year, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(year)\n\t\t\t\t\t&& (year >= 0 && year <= 9999),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | year ${this.#paramInvalidOrOutOfRangeMessage} (0...9999)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('year', year);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.year.getter]();\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#month\n\t\t * @property {Number} - the date's month in the range of 1 to 12\n\t\t */\n\t\tObject.defineProperty(this, 'month', {\n\t\t\t...propertyConfig,\n\t\t\tset(month){\n\t\t\t\tconst __methodName__ = 'set month';\n\n\t\t\t\tmonth = parseInt(month, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(month)\n\t\t\t\t\t&& (month >= 1 && month <= 12),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | month ${this.#paramInvalidOrOutOfRangeMessage} (1...12)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('month', month - 1);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.month.getter]() + 1;\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#date\n\t\t * @property {Number} - the date's day of the month in the range of 1 to 31\n\t\t */\n\t\tObject.defineProperty(this, 'date', {\n\t\t\t...propertyConfig,\n\t\t\tset(date){\n\t\t\t\tconst __methodName__ = 'set date';\n\n\t\t\t\tdate = parseInt(date, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(date)\n\t\t\t\t\t&& (date >= 1 && date <= 31),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | date ${this.#paramInvalidOrOutOfRangeMessage} (1...31)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('date', date);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.date.getter]();\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#hours\n\t\t * @property {Number} - the date's hours in the range of 0 to 23\n\t\t */\n\t\tObject.defineProperty(this, 'hours',{\n\t\t\tset(hours){\n\t\t\t\tconst __methodName__ = 'set hours';\n\n\t\t\t\thours = parseInt(hours, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(hours)\n\t\t\t\t\t&& (hours >= 0 && hours <= 23),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | hours ${this.#paramInvalidOrOutOfRangeMessage} (0...23)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('hours', hours);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.hours.getter]();\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#minutes\n\t\t * @property {Number} - the date's minutes in the range of 0 to 59\n\t\t */\n\t\tObject.defineProperty(this, 'minutes', {\n\t\t\tset(minutes){\n\t\t\t\tconst __methodName__ = 'set hours';\n\n\t\t\t\tminutes = parseInt(minutes, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(minutes)\n\t\t\t\t\t&& (minutes >= 0 && minutes <= 59),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | minutes ${this.#paramInvalidOrOutOfRangeMessage} (0...59)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('minutes', minutes);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.minutes.getter]();\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#seconds\n\t\t * @property {Number} - the date's seconds in the range of 0 to 59\n\t\t */\n\t\tObject.defineProperty(this, 'seconds', {\n\t\t\tset(seconds){\n\t\t\t\tconst __methodName__ = 'set seconds';\n\n\t\t\t\tseconds = parseInt(seconds, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(seconds)\n\t\t\t\t\t&& (seconds >= 0 && seconds <= 59),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | seconds ${this.#paramInvalidOrOutOfRangeMessage} (0...59)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('seconds', seconds);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.seconds.getter]();\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#milliseconds\n\t\t * @property {Number} - the date's milliseconds in the range of 0 to 999\n\t\t */\n\t\tObject.defineProperty(this, 'milliseconds', {\n\t\t\tset(milliseconds){\n\t\t\t\tconst __methodName__ = 'set milliseconds';\n\n\t\t\t\tmilliseconds = parseInt(milliseconds, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(milliseconds)\n\t\t\t\t\t&& (milliseconds >= 0 && milliseconds <= 999),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | milliseconds ${this.#paramInvalidOrOutOfRangeMessage} (0...999)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('milliseconds', milliseconds);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.milliseconds.getter]();\n\t\t\t}\n\t\t});\n\t}\n\n\n\n\t/**\n\t * Returns the current day of the week as a number between 1 and 7 or an english day name.\n\t * This method counts days the European way, starting with monday, but you can change this\n\t * behaviour using the first parameter (if your week starts with sunday or friday for example).\n\t *\n\t * @param {?String} [startingWith='monday'] - set to the english day, which is the first day of the week (monday, tuesday, wednesday, thursday, friday, saturday, sunday)\n\t * @param {?Boolean} [asName=false] - set to true, if you'd like the method to return english day names instead of an index\n\t * @returns {Number|String} weekday index between 1 and 7 or english name of the day\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * if( d.getWeekDay() == 5 ){\n\t * alert(`Thank god it's ${d.getWeekday(null, true)}!`);\n\t * }\n\t */\n\tgetWeekDay(startingWith='monday', asName=false){\n\t\tconst __methodName__ = 'getWeekDay';\n\n\t\tconst weekdays = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];\n\t\tstartingWith = orDefault(startingWith, weekdays[1], 'str');\n\t\tassert(\n\t\t\tweekdays.includes(startingWith),\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | unknown weekday \"${startingWith}\"`\n\t\t);\n\n\t\tlet day = this.#utc ? this.#date.getUTCDay() : this.#date.getDay();\n\t\tif( asName ) return weekdays[day];\n\n\t\tconst offset = day - weekdays.indexOf(startingWith);\n\t\tif( offset < 0 ){\n\t\t\tday = 7 + offset;\n\t\t} else {\n\t\t\tday = offset;\n\t\t}\n\n\t\treturn day + 1;\n\t}\n\n\n\n\t/**\n\t * Returns the date's current timezone, like it would occur in an ISO-string (\"Z\", \"+06:00\", \"-02:30\").\n\t *\n\t * If you need the raw offset, use the vanilla date's getTimezoneOffset() method.\n\t *\n\t * @returns {String} - the timezone string\n\t *\n\t * @example\n\t * const d = new SaneDate()\n\t * d.getTimezone()\n\t * => \"+09:30\"\n\t */\n\tgetTimezone(){\n\t\tif( this.#utc ) return 'Z';\n\n\t\tconst offset = this.#date.getTimezoneOffset();\n\n\t\tif( offset === 0 ){\n\t\t\treturn 'Z';\n\t\t} else {\n\t\t\tconst\n\t\t\t\thours = this.#padWithZero(Math.floor(Math.abs(offset) / 60), 2),\n\t\t\t\tminutes = this.#padWithZero(Math.abs(offset) - (hours * 60), 2)\n\t\t\t;\n\t\t\treturn `${(offset < 0) ? '+' : '-'}${hours}:${minutes}`;\n\t\t}\n\t}\n\n\n\n\t/**\n\t * Returns the representation of the date's current date parts (year, month, day) as an ISO-string.\n\t *\n\t * A difference to the vanilla implementation is, that this method respects UTC mode and does not always\n\t * coerce the date to UTC automatically. So, this will return a local ISO representation if not in UTC mode\n\t * and the UTC representation in UTC mode.\n\t *\n\t * @returns {String} date ISO-string of the format \"2016-04-07\"\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * thatDatePicker.setValue(d.getIsoDateString());\n\t */\n\tgetIsoDateString(){\n\t\tconst\n\t\t\tyear = this.#padWithZero(this.year, 4),\n\t\t\tmonth = this.#padWithZero(this.month, 2),\n\t\t\tdate = this.#padWithZero(this.date, 2)\n\t\t;\n\n\t\treturn `${year}-${month}-${date}`;\n\t}\n\n\n\n\t/**\n\t * Returns the representation of the date's current time parts (hours, minutes, seconds, milliseconds) as an\n\t * ISO-string.\n\t *\n\t * A difference to the vanilla implementation is, that this method respects UTC mode and does not always\n\t * coerce the date to UTC automatically. So, this will return a local ISO representation (optionally with\n\t * timezone information in relation to UTC) if not in UTC mode and the UTC representation in UTC mode.\n\t *\n\t * @param {?Boolean} [withTimezone=true] - defines if the ISO string should end with timezone information, such as \"Z\" or \"+02:00\"\n\t * @returns {String} time ISO-string of the format \"12:59:00.123Z\"\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * thatDatePicker.setValue(`2023-12-12T${d.getIsoTimeString()}`);\n\t */\n\tgetIsoTimeString(withTimezone=true){\n\t\twithTimezone = orDefault(withTimezone, true, 'bool');\n\n\t\tconst\n\t\t\thours = this.#padWithZero(this.hours, 2),\n\t\t\tminutes = this.#padWithZero(this.minutes, 2),\n\t\t\tseconds = this.#padWithZero(this.seconds, 2),\n\t\t\tmilliseconds = this.#padWithZero(this.milliseconds, 3),\n\t\t\ttimezone = this.getTimezone()\n\t\t;\n\n\t\treturn `${hours}:${minutes}:${seconds}${(milliseconds > 0) ? '.'+milliseconds : ''}${withTimezone ? timezone : ''}`;\n\t}\n\n\n\n\t/**\n\t * Returns the date as an ISO-string.\n\t *\n\t * A difference to the vanilla implementation is, that this method respects UTC mode and does not always\n\t * coerce the date to UTC automatically. So, this will return a local ISO representation (optionally with\n\t * timezone information in relation to UTC) if not in UTC mode and the UTC representation in UTC mode.\n\t *\n\t * @param {?Boolean} [withSeparator=true] - defines if date and time should be separated with a \"T\"\n\t * @param {?Boolean} [withTimezone=true] - defines if the ISO string should end with timezone information, such as \"Z\" or \"+02:00\"\n\t * @returns {String} ISO-string of the format \"2016-04-07T13:37:00.222Z\"\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * thatDateTimePicker.setValue(d.getIsoString());\n\t */\n\tgetIsoString(withSeparator=true, withTimezone=true){\n\t\twithSeparator = orDefault(withSeparator, true, 'bool');\n\n\t\treturn `${this.getIsoDateString()}${withSeparator ? 'T' : ' '}${this.getIsoTimeString(withTimezone)}`;\n\t}\n\n\n\n\t/**\n\t * Returns a formatted string, describing the current date in a verbose, human-readable, non-technical way.\n\t *\n\t * \"definition\" may be a format shortcut for \"dateStyle\" (and \"timeStyle\" if type is \"datetime\") or a format string,\n\t * for a custom format, using these tokens:\n\t *\n\t * YY 18 two-digit year;\n\t * YYYY 2018 four-digit year;\n\t * M 1-12 the month, beginning at 1;\n\t * MM 01-12 the month, 2-digits;\n\t * D 1-31 the day of the month;\n\t * DD 01-31 the day of the month, 2-digits;\n\t * H 0-23 the hour;\n\t * HH 00-23 the hour, 2-digits;\n\t * h 1-12 the hour, 12-hour clock;\n\t * hh 01-12 the hour, 12-hour clock, 2-digits;\n\t * m 0-59 the minute;\n\t * mm 00-59 the minute, 2-digits;\n\t * s 0-59 the second;\n\t * ss 00-59 the second, 2-digits;\n\t * SSS 000-999 the millisecond, 3-digits;\n\t * Z +05:00 the offset from UTC, ±HH:mm;\n\t * ZZ +0500 the offset from UTC, ±HHmm;\n\t * A AM PM;\n\t * a am pm;\n\t *\n\t * Using these, you could create your own ISO string like this:\n\t * \"YYYY-MM-DDTHH:mm:ss.SSSZ\"\n\t *\n\t * If you use \"full\", \"long\", \"medium\" or \"short\" instead, you'll use the DateTimeFormatters built-in, preset\n\t * format styles for localized dates, based on the given locale(s).\n\t *\n\t * @param {?String} [definition='long'] - either a preset style to quickly define a format style, by setting shortcuts for dateStyle and timeStyle (if type is \"datetime\"), set to \"none\" or nullish value to skip quick format; alternatively, define this as a format string to use a custom format\n\t * @param {?String|Array} [locale='en-US'] - locale to use for date format and text generation, use array to define fallback; always falls back to en-US if nothing else works\n\t * @param {?String} [type='datetime'] - set to 'datetime', 'date' or 'time' to define which parts should be rendered\n\t * @param {?Object} [options=null] - options to pass to the Intl.DateTimeFormat constructor, is applied last, so should override anything predefined, if key is reset\n\t * @returns {String} - the formatted date/time string\n\t *\n\t * @see format(Dates)\n\t * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat\n\t * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#style_shortcuts\n\t * @example\n\t * const d = new SaneDate();\n\t * d.format('de-DE', 'long', 'datetime', {timeZone : 'UTC'})\n\t * => '12. Dezember 2023 um 02:00:00 UTC'\n\t * d.format('YYYY-MM-DDTHH:mm:ss.SSSZ')\n\t * => '2023-12-12T02:00:00'\n\t */\n\tformat(definition='long', locale='en-US', type='datetime', options=null){\n\t\toptions = orDefault(options, {});\n\n\t\tif( !hasValue(options.timeZone) && this.#utc ){\n\t\t\toptions.timeZone = 'UTC';\n\t\t}\n\n\t\treturn format(this.#date, definition, locale, type, options);\n\t}\n\n\n\n\t/**\n\t * Return the current original JavaScript date object wrapped by SaneDate.\n\t * Use this to do special things.\n\t *\n\t * @returns {Date} the original JavaScript date object\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * const timezoneOffset = d.getVanillaDate().getTimezoneOffset();\n\t */\n\tgetVanillaDate(){\n\t\treturn this.#date;\n\t}\n\n\n\n\t/**\n\t * Compares the date to another date in terms of placement on the time axis.\n\t *\n\t * Returns a classical comparator value (-1/0/1), being -1 if the date is earlier than the parameter.\n\t * Normally checks date and time. Set type to \"date\" to only check date.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object|SaneDate} initialValueOrSaneDate - anything compatible to the SaneDate constructor or a SaneDate instance\n\t * @param {?String} [type='datetime'] - either \"datetime\" or \"date\", telling the method if time should be considered\n\t * @param {?Boolean} [withMilliseconds=true] - tells the method if milliseconds should be considered if type is \"datetime\"\n\t * @throws error if compare date is not usable\n\t * @returns {Number} -1 if this date is smaller/earlier, 0 if identical, 1 if this date is bigger/later\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * if( d.compareTo('2016-04-07', 'date') === 0 ){\n\t * alert('congratulations, that\\'s the same date!');\n\t * }\n\t */\n\tcompareTo(initialValueOrSaneDate, type='datetime', withMilliseconds=true){\n\t\ttype = orDefault(type, 'datetime', 'string');\n\t\twithMilliseconds = orDefault(withMilliseconds, true, 'bool');\n\n\t\tconst\n\t\t\tsaneDate = new SaneDate(initialValueOrSaneDate),\n\t\t\tdateCompareGetters = [\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.year.getter,\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.month.getter,\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.date.getter,\n\t\t\t],\n\t\t\ttimeCompareGetters = [\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.hours.getter,\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.minutes.getter,\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.seconds.getter,\n\t\t\t],\n\t\t\tmillisecondsCompareGetter = DATE_PART_SETTERS_AND_GETTERS.utc.milliseconds.getter\n\t\t;\n\n\t\tlet compareGetters = [].concat(dateCompareGetters);\n\t\tif( type === 'datetime' ){\n\t\t\tcompareGetters = compareGetters.concat(timeCompareGetters);\n\t\t\tif( withMilliseconds ){\n\t\t\t\tcompareGetters = compareGetters.concat(millisecondsCompareGetter);\n\t\t\t}\n\t\t}\n\n\t\tlet ownValue, compareValue, comparator;\n\t\tfor( const compareGetter of compareGetters ){\n\t\t\townValue = this.#date[compareGetter]();\n\t\t\tcompareValue = saneDate.getVanillaDate()[compareGetter]();\n\t\t\tcomparator = (ownValue < compareValue)\n\t\t\t\t? -1\n\t\t\t\t: ((ownValue > compareValue) ? 1 : 0)\n\t\t\t;\n\n\t\t\tif( comparator !== 0 ){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn comparator;\n\t}\n\n\n\n\t/**\n\t * Returns if the SaneDate is earlier on the time axis than the comparison value.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object|SaneDate} initialValueOrSaneDate - anything compatible to the SaneDate constructor or a SaneDate instance\n\t * @param {?String} [type='datetime'] - either \"datetime\" or \"date\", telling the method if time should be considered\n\t * @param {?Boolean} [withMilliseconds=true] - tells the method if milliseconds should be considered if type is \"datetime\"\n\t * @throws error if compare date is not usable\n\t * @returns {Boolean} true if SaneDate is earlier than compare value\n\t *\n\t * @example\n\t * const now = new SaneDate();\n\t * const theFuture = now.clone().forward({days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5});\n\t * now.isBefore(theFuture)\n\t * => true\n\t * theFuture.isBefore(now)\n\t * => false\n\t */\n\tisBefore(initialValueOrSaneDate, type='datetime', withMilliseconds=true){\n\t\treturn this.compareTo(initialValueOrSaneDate, type, withMilliseconds) === -1;\n\t}\n\n\n\n\t/**\n\t * Returns if the SaneDate is later on the time axis than the comparison value.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object|SaneDate} initialValueOrSaneDate - anything compatible to the SaneDate constructor or a SaneDate instance\n\t * @param {?String} [type='datetime'] - either \"datetime\" or \"date\", telling the method if time should be considered\n\t * @param {?Boolean} [withMilliseconds=true] - tells the method if milliseconds should be considered if type is \"datetime\"\n\t * @throws error if compare date is not usable\n\t * @returns {Boolean} true if SaneDate is later than compare value\n\t *\n\t * @example\n\t * const now = new SaneDate();\n\t * const theFuture = now.clone().forward({days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5});\n\t * now.isAfter(theFuture)\n\t * => false\n\t * theFuture.isAfter(now)\n\t * => true\n\t */\n\tisAfter(initialValueOrSaneDate, type='datetime', withMilliseconds=true){\n\t\treturn this.compareTo(initialValueOrSaneDate, type, withMilliseconds) === 1;\n\t}\n\n\n\n\t/**\n\t * Returns if the SaneDate is at the same time as comparison value.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object|SaneDate} initialValueOrSaneDate - anything compatible to the SaneDate constructor or a SaneDate instance\n\t * @param {?String} [type='datetime'] - either \"datetime\" or \"date\", telling the method if time should be considered\n\t * @param {?Boolean} [withMilliseconds=true] - tells the method if milliseconds should be considered if type is \"datetime\"\n\t * @throws error if compare date is not usable\n\t * @returns {Boolean} true if SaneDate is at the same time as compare value\n\t *\n\t * @example\n\t * const now = new SaneDate();\n\t * const theFuture = now.clone();\n\t * now.isSame(theFuture)\n\t * => true\n\t * theFuture.forward({days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5});\n\t * theFuture.isSame(now)\n\t * => false\n\t */\n\tisSame(initialValueOrSaneDate, type='datetime', withMilliseconds=true){\n\t\treturn this.compareTo(initialValueOrSaneDate, type, withMilliseconds) === 0;\n\t}\n\n\n\n\t/**\n\t * Move the date a defined offset to the past or the future.\n\t *\n\t * @param {String|Object} part - the name of the date part to change, one of \"years\", \"months\", \"days\", \"hours\", \"minutes\", \"seconds\" and \"milliseconds\" or a dictionary of part/amount pairs ({hours : -1, seconds : 30})\n\t * @param {?Number} [amount=0] - negative or positive integer defining the offset from the current date\n\t * @throws error on invalid part name\n\t * @returns {SaneDate} the SaneDate instance\n\t *\n\t * @example\n\t * let d = new SaneDate();\n\t * d = d.move('years', 10).move('milliseconds', -1);\n\t */\n\tmove(part, amount=0){\n\t\tconst __methodName__ = 'move;'\n\n\t\tamount = orDefault(amount, 0, 'int');\n\n\t\tconst\n\t\t\tsettersAndGetters = DATE_PART_SETTERS_AND_GETTERS.utc,\n\t\t\tparts = ['years', 'months', 'days', 'hours', 'minutes', 'seconds', 'milliseconds']\n\t\t;\n\t\tlet partDict = {};\n\n\t\tif( !isPlainObject(part) ){\n\t\t\tpartDict[part] = amount;\n\t\t} else {\n\t\t\tpartDict = part;\n\t\t}\n\n\t\tObject.keys(partDict).forEach(part => {\n\t\t\tassert(\n\t\t\t\tparts.includes(part),\n\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | part must be one of ${parts.join(', ')}, is \"${part}\"`\n\t\t\t);\n\t\t});\n\n\t\tObject.entries(partDict).forEach(([part, amount]) => {\n\t\t\tswitch( part ){\n\t\t\t\tcase 'years':\n\t\t\t\t\tthis.#date[settersAndGetters.year.setter](this.#date[settersAndGetters.year.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'months':\n\t\t\t\t\tthis.#date[settersAndGetters.month.setter](this.#date[settersAndGetters.month.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'days':\n\t\t\t\t\tthis.#date[settersAndGetters.date.setter](this.#date[settersAndGetters.date.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'hours':\n\t\t\t\t\tthis.#date[settersAndGetters.hours.setter](this.#date[settersAndGetters.hours.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'minutes':\n\t\t\t\t\tthis.#date[settersAndGetters.minutes.setter](this.#date[settersAndGetters.minutes.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'seconds':\n\t\t\t\t\tthis.#date[settersAndGetters.seconds.setter](this.#date[settersAndGetters.seconds.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'milliseconds':\n\t\t\t\t\tthis.#date[settersAndGetters.milliseconds.setter](this.#date[settersAndGetters.milliseconds.getter]() + amount);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Moves the date's time forward a certain offset.\n\t *\n\t * @param {String|Object} part - the name of the date part to change, one of \"years\", \"months\", \"days\", \"hours\", \"minutes\", \"seconds\" and \"milliseconds\" or a dictionary of part/amount pairs ({hours : 1, seconds : 30})\n\t * @param {?Number} [amount=0] - integer defining the positive offset from the current date, negative value is treated as an error\n\t * @throws error on invalid part name or negative amount\n\t * @returns {SaneDate} the SaneDate instance\n\t *\n\t * @example\n\t * let d = new SaneDate();\n\t * d = d.forward('hours', 8);\n\t */\n\tforward(part, amount=0){\n\t\tconst\n\t\t\t__methodName__ = 'forward',\n\t\t\tamountMustBePositiveMessage = 'amount must be >= 0'\n\t\t;\n\n\t\tpart = `${part}`;\n\t\tamount = orDefault(amount, 0, 'int');\n\n\t\tlet partDict = {};\n\t\tif( !isPlainObject(part) ){\n\t\t\tassert(\n\t\t\t\tamount >= 0,\n\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${amountMustBePositiveMessage}`\n\t\t\t);\n\t\t\tpartDict[part] = amount;\n\t\t} else {\n\t\t\tpartDict = part;\n\t\t\tObject.entries(partDict).forEach(([part, amount]) => {\n\t\t\t\tamount = parseInt(amount, 10);\n\t\t\t\tassert(\n\t\t\t\t\tamount >= 0,\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${amountMustBePositiveMessage}`\n\t\t\t\t);\n\t\t\t\tpartDict[part] = amount;\n\t\t\t});\n\t\t}\n\n\t\treturn this.move(partDict);\n\t}\n\n\n\n\t/**\n\t * Moves the date's time backward a certain offset.\n\t *\n\t * @param {String|Object} part - the name of the date part to change, one of \"years\", \"months\", \"days\", \"hours\", \"minutes\", \"seconds\" and \"milliseconds\" or a dictionary of part/amount pairs ({hours : 1, seconds : 30})\n\t * @param {?Number} [amount=0] - integer defining the negative offset from the current date, negative value is treated as an error\n\t * @throws error on invalid part name or negative amount\n\t * @returns {SaneDate} the SaneDate instance\n\t *\n\t * @example\n\t * let d = new SaneDate();\n\t * d = d.backward('years', 1000);\n\t */\n\tbackward(part, amount=0){\n\t\tconst\n\t\t\t__methodName__ = 'backward',\n\t\t\tamountMustBePositiveMessage = 'amount must be >= 0'\n\t\t;\n\n\t\tpart = `${part}`;\n\t\tamount = orDefault(amount, 0, 'int');\n\n\t\tlet partDict = {};\n\t\tif( !isPlainObject(part) ){\n\t\t\tassert(\n\t\t\t\tamount >= 0,\n\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${amountMustBePositiveMessage}`\n\t\t\t);\n\t\t\tpartDict[part] = (amount === 0) ? 0 : -amount;\n\t\t} else {\n\t\t\tpartDict = part;\n\t\t\tObject.entries(partDict).forEach(([part, amount]) => {\n\t\t\t\tassert(\n\t\t\t\t\tamount >= 0,\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${amountMustBePositiveMessage}`\n\t\t\t\t);\n\t\t\t\tpartDict[part] = (amount === 0) ? 0 : -amount;\n\t\t\t});\n\t\t}\n\n\t\treturn this.move(partDict);\n\t}\n\n\n\n\t/**\n\t * Calculates a time delta between the SaneDate and a comparison value.\n\t *\n\t * The result is a plain object with the delta's units up to the defined \"largestUnit\". All values are integers.\n\t * The largest unit is days, since above neither months nor years are calculable via a fixed divisor and therefore\n\t * useless (since month vary from 28 to 31 days and years vary between 365 and 366 days, so both are not a fixed\n\t * unit).\n\t *\n\t * By default, the order does not matter and only the absolute value is used, but you can change this\n\t * through the parameter \"relative\", which by setting this to true, will include \"-\", if the comparison value\n\t * is in the future.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object|SaneDate} initialValueOrSaneDate - anything compatible to the SaneDate constructor or a SaneDate instance\n\t * @param {?String} [largestUnit='days'] - the largest time unit to differentiate in the result\n\t * @param {?Boolean} [relative=false] - if true, returns negative values if first parameter is later than this date (this adheres to the order defined by compareTo)\n\t * @throws error on unknown largestUnit or incompatible comparison value\n\t * @returns {Object} time delta object in the format {days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5} (keys depending on largestUnit)\n\t *\n\t * @example\n\t * const now = new SaneDate();\n\t * const theFuture = now.clone().forward({days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5});\n\t * now.getDelta(theFuture)\n\t * => {days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5}\n\t * now.getDelta(theFuture, 'hours', true)\n\t * => {hours : -26, minutes : -3, seconds : -4, milliseconds : -5}\n\t */\n\tgetDelta(initialValueOrSaneDate, largestUnit='days', relative=false){\n\t\tconst __methodName__ = 'getDelta';\n\n\t\tconst saneDate = new SaneDate(initialValueOrSaneDate);\n\t\tlargestUnit = orDefault(largestUnit, 'days', 'string');\n\t\tassert(\n\t\t\t['days', 'hours', 'minutes', 'seconds', 'milliseconds'].includes(largestUnit),\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | unknown largest unit`\n\t\t);\n\t\trelative = orDefault(relative, false, 'bool');\n\n\t\tconst parts = {};\n\t\tlet delta = relative\n\t\t\t? (this.#date.getTime() - saneDate.#date.getTime())\n\t\t\t: Math.abs(this.#date.getTime() - saneDate.#date.getTime())\n\t\t;\n\t\tconst negativeDelta = delta < 0;\n\t\tdelta = Math.abs(delta);\n\n\t\tif( largestUnit === 'days' ){\n\t\t\tparts.days = Math.floor(delta / 1000 / 60 / 60 / 24);\n\t\t\tdelta -= parts.days * 1000 * 60 * 60 * 24;\n\t\t\tlargestUnit = 'hours';\n\t\t}\n\n\t\tif( largestUnit === 'hours' ){\n\t\t\tparts.hours = Math.floor(delta / 1000 / 60 / 60);\n\t\t\tdelta -= parts.hours * 1000 * 60 * 60;\n\t\t\tlargestUnit = 'minutes';\n\t\t}\n\n\t\tif( largestUnit === 'minutes' ){\n\t\t\tparts.minutes = Math.floor(delta / 1000 / 60);\n\t\t\tdelta -= parts.minutes * 1000 * 60;\n\t\t\tlargestUnit = 'seconds';\n\t\t}\n\n\t\tif( largestUnit === 'seconds' ){\n\t\t\tparts.seconds = Math.floor(delta / 1000);\n\t\t\tdelta -= parts.seconds * 1000;\n\t\t\tlargestUnit = 'milliseconds';\n\t\t}\n\n\t\tif( largestUnit === 'milliseconds' ){\n\t\t\tparts.milliseconds = delta;\n\t\t}\n\n\t\tif( negativeDelta ){\n\t\t\tfor( const partName in parts ){\n\t\t\t\tparts[partName] = (parts[partName] === 0) ? 0 : -parts[partName];\n\t\t\t}\n\t\t}\n\n\t\treturn parts;\n\t}\n\n\n\n\t/**\n\t * Returns a copy of the current SaneDate.\n\t * Might be very handy for creating dates based on another with an offset for example.\n\t * Keeps UTC mode.\n\t *\n\t * @returns {SaneDate} copy of current SaneDate instance\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * const theFuture = d.clone().forward('hours', 8);\n\t **/\n\tclone(){\n\t\tconst clonedSaneDate = new SaneDate(new Date(this.getVanillaDate().getTime()));\n\t\tclonedSaneDate.utc = this.#utc;\n\t\treturn clonedSaneDate;\n\t}\n\n\n\n\t/**\n\t * Adds leading zeroes to values, which are not yet of a defined expected length.\n\t *\n\t * @param {*} value - the value to pad\n\t * @param {?Number} [digitCount=2] - the number of digits, the result has to have at least\n\t * @returns {String} the padded value, will always be cast to a string\n\t *\n\t * @private\n\t * @example\n\t * this.#padWithZero(1, 4)\n\t * => '0001'\n\t */\n\t#padWithZero(value, digitCount=2){\n\t\treturn pad(value, '0', digitCount);\n\t}\n\n\n\n\t/**\n\t * Tries to parse an ISO string (or at least, something resembling an ISO string) into a date.\n\t *\n\t * The basic idea of this method is, that it is supposed to be fairly forgiving, as long as the info is there,\n\t * even in a little wonky notation, this should result in a successfully created SaneDate.\n\t *\n\t * @param {String} isoString - something resembling an ISO string, that we can create a date from\n\t * @throws error if isoString is not usable\n\t * @returns {Date} the date create from the given ISO string\n\t *\n\t * @private\n\t * @example\n\t * this.#parseIsoString('2018-02-28T13:37:00')\n\t * this.#parseIsoString('1-2-3 4:5:6.7')\n\t */\n\t#parseIsoString(isoString){\n\t\tconst\n\t\t\t__methodName__ = '#parseIsoString',\n\t\t\tunparsableIsoStringMessage = 'ISO string not parsable'\n\t\t;\n\n\t\tisoString = `${isoString}`;\n\n\t\tlet\n\t\t\tyear = 1970,\n\t\t\tmonth = 1,\n\t\t\tdate = 1,\n\t\t\thours = 0,\n\t\t\tminutes = 0,\n\t\t\tseconds = 0,\n\t\t\tmilliseconds = 0,\n\t\t\ttimezoneOffset = 0,\n\t\t\tutc = false\n\t\t;\n\n\t\tlet isoStringParts = isoString.split('T');\n\t\tif( isoStringParts.length === 1 ){\n\t\t\tisoStringParts = isoStringParts[0].split(' ');\n\t\t}\n\n\n\t\t// date parts\n\n\t\tconst isoStringDateParts = isoStringParts[0].split('-');\n\t\tyear = isoStringDateParts[0];\n\t\tif( isoStringDateParts.length >= 2 ){\n\t\t\tmonth = isoStringDateParts[1];\n\t\t}\n\t\tif( isoStringDateParts.length >= 3 ){\n\t\t\tdate = isoStringDateParts[2];\n\t\t}\n\n\n\t\t// time parts\n\n\t\tif( isoStringParts.length >= 2 ){\n\t\t\t// timezone\n\n\t\t\tlet\tisoStringTimezoneParts = isoStringParts[1].split('Z');\n\t\t\tif( isoStringTimezoneParts.length >= 2 ){\n\t\t\t\tutc = true;\n\t\t\t} else {\n\t\t\t\tlet offsetFactor = 0;\n\t\t\t\tif( isoStringTimezoneParts[0].includes('+') ){\n\t\t\t\t\toffsetFactor = -1;\n\t\t\t\t\tisoStringTimezoneParts = isoStringTimezoneParts[0].split('+');\n\t\t\t\t} else if( isoStringTimezoneParts[0].includes('-') ){\n\t\t\t\t\toffsetFactor = 1;\n\t\t\t\t\tisoStringTimezoneParts = isoStringTimezoneParts[0].split('-');\n\t\t\t\t}\n\n\t\t\t\tif( isoStringTimezoneParts.length >= 2 ){\n\t\t\t\t\tconst isoStringTimezoneTimeParts = isoStringTimezoneParts[1].split(':');\n\n\t\t\t\t\tif( isoStringTimezoneTimeParts.length >= 2 ){\n\t\t\t\t\t\ttimezoneOffset += parseInt(isoStringTimezoneTimeParts[0], 10) * 60;\n\t\t\t\t\t\ttimezoneOffset += parseInt(isoStringTimezoneTimeParts[1], 10);\n\t\t\t\t\t} else if( isoStringTimezoneTimeParts[0].length >= 3 ){\n\t\t\t\t\t\ttimezoneOffset += parseInt(isoStringTimezoneTimeParts[0].slice(0, 2), 10) * 60;\n\t\t\t\t\t\ttimezoneOffset += parseInt(isoStringTimezoneTimeParts[1].slice(2), 10);\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttimezoneOffset += parseInt(isoStringTimezoneTimeParts[0], 10) * 60;\n\t\t\t\t\t}\n\t\t\t\t\ttimezoneOffset *= offsetFactor;\n\n\t\t\t\t\tassert(\n\t\t\t\t\t\t!isNaN(timezoneOffset),\n\t\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | invalid timezone \"${isoStringTimezoneParts[1]}\"`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\t// hours and minutes\n\t\t\tconst isoStringTimeParts = isoStringTimezoneParts[0].split(':');\n\t\t\thours = isoStringTimeParts[0];\n\t\t\tif( isoStringTimeParts.length >= 2 ){\n\t\t\t\tminutes = isoStringTimeParts[1];\n\t\t\t}\n\n\n\t\t\t// seconds and milliseconds\n\n\t\t\tif( isoStringTimeParts.length >= 3 ){\n\t\t\t\tconst isoStringSecondsParts = isoStringTimeParts[2].split('.');\n\n\t\t\t\tseconds = isoStringSecondsParts[0];\n\n\t\t\t\tif( isoStringSecondsParts.length >= 2 ){\n\t\t\t\t\tmilliseconds = isoStringSecondsParts[1];\n\n\t\t\t\t\tif( milliseconds.length > 3 ){\n\t\t\t\t\t\tmilliseconds = milliseconds.slice(0, 3);\n\t\t\t\t\t} else if( milliseconds.length === 2 ){\n\t\t\t\t\t\tmilliseconds = `${parseInt(milliseconds, 10) * 10}`;\n\t\t\t\t\t} else if( milliseconds.length === 1 ){\n\t\t\t\t\t\tmilliseconds = `${parseInt(milliseconds, 10) * 100}`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\n\t\t// date construction\n\n\t\tconst saneDate = new SaneDate();\n\t\tsaneDate.utc = utc || (timezoneOffset !== 0);\n\t\ttry {\n\t\t\tsaneDate.year = year;\n\t\t\tsaneDate.month = month;\n\t\t\tsaneDate.date = date;\n\t\t\tsaneDate.hours = hours;\n\t\t\tsaneDate.minutes = minutes;\n\t\t\tsaneDate.seconds = seconds;\n\t\t\tsaneDate.milliseconds = milliseconds;\n\t\t} catch(ex){\n\t\t\tthrow Error(`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${unparsableIsoStringMessage} \"${isoString}\"`);\n\t\t}\n\t\tsaneDate.move('minutes', timezoneOffset);\n\n\t\treturn saneDate.getVanillaDate();\n\t}\n\n\n\n\t/**\n\t * Tries to change a part of the date and makes sure, that this change does not trigger automagic and only\n\t * leads to exactly the change, we wanted to do and nothing else.\n\t *\n\t * @param {String} part - the date part to change, one of: year, month, date, hours, minutes, seconds or milliseconds\n\t * @param {Number} value - the new value to set\n\t * @returns {SaneDate} the SaneDate instance\n\t *\n\t * @private\n\t */\n\t#tryDatePartChange(part, value){\n\t\tconst __methodName__ = '#tryDatePartChange';\n\n\t\tconst\n\t\t\tnewDate = this.clone().getVanillaDate(),\n\t\t\tsettersAndGetters = this.#utc\n\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t,\n\t\t\tallDatePartGetters = Object.values(settersAndGetters).map(methods => methods.getter)\n\t\t;\n\n\t\tnewDate[settersAndGetters[part].setter](value);\n\n\t\tlet sideEffect = false;\n\t\tfor( const datePartGetter of allDatePartGetters ){\n\t\t\tif( datePartGetter !== settersAndGetters[part].getter){\n\t\t\t\tsideEffect ||= this.#date[datePartGetter]() !== newDate[datePartGetter]();\n\t\t\t}\n\n\t\t\tif( sideEffect ){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tassert(\n\t\t\t(newDate[settersAndGetters[part].getter]() === value) && !sideEffect,\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | date part change \"${part} = ${value}\" is invalid or has side effects`\n\t\t);\n\n\t\tthis.#date = newDate;\n\n\t\treturn this;\n\t}\n\n}\n\nexport {SaneDate};\n"]} \ No newline at end of file diff --git a/dist/elements.js b/dist/elements.js index 67eb4362..9c56701d 100644 --- a/dist/elements.js +++ b/dist/elements.js @@ -1,8 +1,8 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Elements */ -const MODULE_NAME="Elements";import{orDefault,isString,isFunction,isPlainObject,isSelector,isElement,hasValue,assert,size,Deferred}from"./basic.js";import{randomUuid}from"./random.js";import{clone}from"./objects.js";import{onDomReady}from"./events.js";import{applyStyles}from"./css.js";const NOT_AN_HTMLELEMENT_ERROR="given node/target is not an HTMLElement";let BROWSER_HAS_CSS_SCOPE_SUPPORT;try{document.querySelector(":scope *")}catch(e){BROWSER_HAS_CSS_SCOPE_SUPPORT=!1}export function createNode(e,t=null,n=null){e=orDefault(e,"span","str").trim(),t=isPlainObject(t)?t:null,n=orDefault(n,null,"str");const s=document.createElement("div");/^<[^\/][^<>]*>/.test(e)&&/<\/[^<>\/]+>$/.test(e)?s.innerHTML=e:s.appendChild(document.createElement(e));const r=s.firstChild;if(s.removeChild(r),hasValue(t))for(let e in t)r.setAttribute(e,`${t[e]}`);return hasValue(n)&&(r.textContent=n),r}export function insertNode(e,t,n="beforeend"){switch(assert(isElement(e),`Elements.insertNode | ${NOT_AN_HTMLELEMENT_ERROR}`),isElement(t)||(t=createNode(`${t}`)),n){case"beforebegin":case"before":n="beforebegin";break;case"afterend":case"after":n="afterend";break;case"afterbegin":case"prepend":n="afterbegin";break;default:n="beforeend"}return e.insertAdjacentElement(n,t),t}export function replaceNode(e,t){const n="replaceNode";return assert(isElement(e),`Elements.${n} | ${NOT_AN_HTMLELEMENT_ERROR}`),isElement(t)||(t=createNode(`${t}`)),assert(isElement(e.parentNode),`Elements.${n} | given target does not have a parent)`),insertNode(e,t,"after"),e.parentNode.removeChild(e),t}export function defineNode(e,t,n=null){const s="defineNode";assert(isElement(e),`Elements:${s} | ${NOT_AN_HTMLELEMENT_ERROR}`),assert(isPlainObject(t),`Elements:${s} | definitions is not a plain object`);const r="<-";return isElement(n)&&Array.from(n.attributes).forEach((e=>{(t[e.name]===r||!hasValue(t[e.name])&&(t["data*"]===r&&e.name.startsWith("data-")||t["on*"]===r&&e.name.startsWith("on")))&&(t[e.name]=e.value),(t[`+${e.name}`]===r||!hasValue(t[`+${e.name}`])&&(t["+data*"]===r&&e.name.startsWith("data-")||t["+on*"]===r&&e.name.startsWith("on")))&&(hasValue(t[`+${e.name}`])&&t[`+${e.name}`]!==r||(t[`+${e.name}`]=""),t[`+${e.name}`]+=e.value)})),delete t["data*"],delete t["+data*"],delete t["on*"],delete t["+on*"],Object.keys(t).forEach((e=>{t[e]===r&&delete t[e]})),Object.keys(t).sort().reverse().forEach((n=>{const s=t[n],r=n.startsWith("+");r&&(n=n.slice(1)),n.endsWith("*")&&(n=n.slice(0,-1)),"class"===n?(r||e.setAttribute("class",""),[].concat(s).forEach((t=>{`${t}`.split(" ").forEach((t=>{e.classList.add(`${t.trim()}`)}))}))):"style"===n?(r||e.setAttribute("style",""),[].concat(s).forEach((t=>{if(!isPlainObject(t)){const e=`${t}`.split(";"),n={};e.forEach((e=>{let[t,s]=e.split(":");t=t.trim(),hasValue(s)&&(s=s.trim(),s=s.endsWith(";")?s.slice(0,-1):s,n[t]=s)})),t=n}hasValue(t)&&applyStyles(e,t)}))):r?e.setAttribute(n,`${e.getAttribute(n)??""}${s}`):e.setAttribute(n,`${s}`)})),e}export function getTextContent(e,t=!1){if(t=orDefault(t,!1,"bool"),isString(e)&&(e=createNode(e)),assert(isElement(e),"Elements:getTextContent | target is neither node nor markup"),t){let t="";return e.childNodes.forEach((e=>{3===e.nodeType&&(t+=e.textContent)})),t}return e.textContent}export function isInDom(e){return assert(isElement(e),`Elements:isInDom | ${NOT_AN_HTMLELEMENT_ERROR}`),isFunction(document.contains)?document.contains(e):document.body.contains(e)}export function getData(e,t=null){t=orDefault(t,null,"arr"),assert(isElement(e),`Elements:getData | ${NOT_AN_HTMLELEMENT_ERROR}`);let n={};return hasValue(t)?t.forEach((t=>{let s=e.getAttribute(`data-${t}`);if(hasValue(s))try{n[t]=JSON.parse(s)}catch(e){n[t]=s}})):Array.from(e.attributes).forEach((e=>{if(e.name.startsWith("data-")){const t=e.name.replace(/^data-/,"");try{n[t]=JSON.parse(e.value)}catch(s){n[t]=e.value}}})),0===size(n)?n=null:1===t?.length&&(n=n[t[0]]??null),n}export function setData(e,t,n=null){const s="setData";assert(isElement(e),`Elements:${s} | ${NOT_AN_HTMLELEMENT_ERROR}`);let r=null;hasValue(n)&&(r=`${t}`,t={[r]:n}),assert(isPlainObject(t),`Elements:${s} | dataSet is not a plain object`);const a={};return Object.entries(t).forEach((([t,n])=>{if(isFunction(n)&&(n=n()),void 0!==n){let s,r;try{s=JSON.stringify(n),r=JSON.parse(s)}catch(e){s=`${n}`,r=s}s=s.replace(/^['"]/,"").replace(/['"]$/,"").trim(),""!==s?(a[t]=r,e.setAttribute(`data-${t}`,s)):e.hasAttribute(`data-${t}`)&&(a[t]=void 0,e.removeAttribute(`data-${t}`))}else e.hasAttribute(`data-${t}`)&&(a[t]=void 0,e.removeAttribute(`data-${t}`))})),hasValue(r)?r in a?a[r]:null:size(a)>0?a:null}export function removeData(e,t=null){t=orDefault(t,null,"arr"),assert(isElement(e),`Elements:removeData | ${NOT_AN_HTMLELEMENT_ERROR}`);let n=getData(e,t);return hasValue(n)?setData(e,1===t?.length?{[t[0]]:void 0}:Object.keys(n).reduce(((e,t)=>(e[t]=void 0,e)),{})):n=null,n}export function find(e,t="*",n=!1){const s=/:scope(?![\w-])/gi;if(assert(isElement(e),`Elements:find | ${NOT_AN_HTMLELEMENT_ERROR}`),t=orDefault(t,"*","str").trim(),s.test(t)||(t=`:scope ${t}`),n=orDefault(n,!1,"bool"),BROWSER_HAS_CSS_SCOPE_SUPPORT)return n?e.querySelector(t):Array.from(e.querySelectorAll(t));{const r=`find-scope-${randomUuid()}`;t=t.replace(s,`[${r}]`),e.setAttribute(r,"");const a=n?e.querySelector(t):Array.from(e.querySelectorAll(t));return e.removeAttribute(r),a}}export function findOne(e,t="*"){return find(e,t,!0)}export function findTextNodes(e,t=null,n=!1){t=isFunction(t)?t:()=>!0,n=orDefault(n,!1,"bool"),assert(isElement(e),`Elements:findTextNodes | ${NOT_AN_HTMLELEMENT_ERROR}`);const s=e=>3===e.nodeType&&""!==e.textContent.trim()&&!!t(e),r=e=>s(e)?[].concat(e):Array.from(e.childNodes).reduce(((e,t)=>s(t)?e.concat(t):n?e:e.concat(r(t))),[]);return r(e)}export function prime(e,t,n=null,s="primed"){const r="prime";n=orDefault(n,{}),s=orDefault(s,"primed","str"),assert(isElement(e),`Elements:${r} | ${NOT_AN_HTMLELEMENT_ERROR}`),assert(isFunction(t),`Elements:${r} | init is not a function`);const a=new Deferred;return!0!==getData(e,s)?(setData(e,s,!0),onDomReady((()=>{const n=t(e);hasValue(n)&&isFunction(n.then)&&isFunction(n.catch)?n.then((e=>{a.resolve(e)})).catch((e=>{a.reject(e)})):a.resolve(n),setData(e,`${s}-ready`,!0)}))):a.resolve(void 0),a.then((()=>{hasValue(n.remove)&&[].concat(n.remove).forEach((t=>{`${t}`.split(" ").forEach((t=>{e.classList.remove(t.trim())}))})),hasValue(n.add)&&[].concat(n.add).forEach((t=>{`${t}`.split(" ").forEach((t=>{e.classList.add(t.trim())}))})),setData(e,`${s}-resolved`,!0)})),a}export function measureHiddenDimensions(e,t="outer",n=null,s=null){const r="measureHidden",a={offset:{width:"offsetWidth",height:"offsetHeight"},outer:{width:"offsetWidth",height:"offsetHeight"},client:{width:"clientWidth",height:"clientHeight"},inner:{width:"clientWidth",height:"clientHeight"},scroll:{width:"scrollWidth",height:"scrollHeight"}};t=a[orDefault(t,"outer","str")]??a.outer,s=orDefault(s,document.body),assert(isElement(e),`Elements:${r} | ${NOT_AN_HTMLELEMENT_ERROR}`),assert(isElement(s),`Elements:${r} | context is no an htmlelement`);const o=createNode("div",{id:`sandbox-${randomUuid()}`,class:"sandbox",style:"display:block; opacity:0; visibility:hidden; pointer-events:none; position:absolute; top:-10000px; left:-10000px;"}),i=clone(e);s.appendChild(o),o.appendChild(i);const l=isSelector(n)?i.querySelector(n):i,c=l?.[t.width]??0,d=l?.[t.height]??0,u={width:c,height:d,toString:()=>`${c}x${d}`};return s.removeChild(o),u} +const MODULE_NAME="Elements";import{orDefault,isString,isFunction,isPlainObject,isSelector,isElement,hasValue,assert,size,Deferred}from"./basic.js";import{randomUuid}from"./random.js";import{clone}from"./objects.js";import{onDomReady}from"./events.js";import{applyStyles}from"./css.js";const NOT_AN_HTMLELEMENT_ERROR="given node/target is not an HTMLElement";let BROWSER_HAS_CSS_SCOPE_SUPPORT;try{document.querySelector(":scope *")}catch(e){BROWSER_HAS_CSS_SCOPE_SUPPORT=!1}export function createNode(e,t=null,n=null){e=orDefault(e,"span","str").trim(),t=isPlainObject(t)?t:null,n=orDefault(n,null,"str");const r=document.createElement("div");/^<[^\/][^<>]*>/.test(e)&&/<\/[^<>\/]+>$/.test(e)?r.innerHTML=e:r.appendChild(document.createElement(e));const a=r.firstChild;if(r.removeChild(a),hasValue(t))for(let e in t)a.setAttribute(e,`${t[e]}`);return hasValue(n)&&(a.textContent=n),a}export function insertNode(e,t,n="beforeend"){switch(assert(isElement(e),`${MODULE_NAME}.insertNode | ${NOT_AN_HTMLELEMENT_ERROR}`),isElement(t)||(t=createNode(`${t}`)),n){case"beforebegin":case"before":n="beforebegin";break;case"afterend":case"after":n="afterend";break;case"afterbegin":case"prepend":n="afterbegin";break;default:n="beforeend"}return e.insertAdjacentElement(n,t),t}export function replaceNode(e,t){const n="replaceNode";return assert(isElement(e),`${MODULE_NAME}.${n} | ${NOT_AN_HTMLELEMENT_ERROR}`),isElement(t)||(t=createNode(`${t}`)),assert(isElement(e.parentNode),`${MODULE_NAME}.${n} | given target does not have a parent)`),insertNode(e,t,"after"),e.parentNode.removeChild(e),t}export function defineNode(e,t,n=null){const r="defineNode";assert(isElement(e),`${MODULE_NAME}:${r} | ${NOT_AN_HTMLELEMENT_ERROR}`),assert(isPlainObject(t),`${MODULE_NAME}:${r} | definitions is not a plain object`);const a="<-";return isElement(n)&&Array.from(n.attributes).forEach((e=>{(t[e.name]===a||!hasValue(t[e.name])&&(t["data*"]===a&&e.name.startsWith("data-")||t["on*"]===a&&e.name.startsWith("on")))&&(t[e.name]=e.value),(t[`+${e.name}`]===a||!hasValue(t[`+${e.name}`])&&(t["+data*"]===a&&e.name.startsWith("data-")||t["+on*"]===a&&e.name.startsWith("on")))&&(hasValue(t[`+${e.name}`])&&t[`+${e.name}`]!==a||(t[`+${e.name}`]=""),t[`+${e.name}`]+=e.value)})),delete t["data*"],delete t["+data*"],delete t["on*"],delete t["+on*"],Object.keys(t).forEach((e=>{t[e]===a&&delete t[e]})),Object.keys(t).sort().reverse().forEach((n=>{const r=t[n],a=n.startsWith("+");a&&(n=n.slice(1)),n.endsWith("*")&&(n=n.slice(0,-1)),"class"===n?(a||e.setAttribute("class",""),[].concat(r).forEach((t=>{`${t}`.split(" ").forEach((t=>{e.classList.add(`${t.trim()}`)}))}))):"style"===n?(a||e.setAttribute("style",""),[].concat(r).forEach((t=>{if(!isPlainObject(t)){const e=`${t}`.split(";"),n={};e.forEach((e=>{let[t,r]=e.split(":");t=t.trim(),hasValue(r)&&(r=r.trim(),r=r.endsWith(";")?r.slice(0,-1):r,n[t]=r)})),t=n}hasValue(t)&&applyStyles(e,t)}))):a?e.setAttribute(n,`${e.getAttribute(n)??""}${r}`):e.setAttribute(n,`${r}`)})),e}export function getTextContent(e,t=!1){if(t=orDefault(t,!1,"bool"),isString(e)&&(e=createNode(e)),assert(isElement(e),`${MODULE_NAME}:getTextContent | target is neither node nor markup`),t){let t="";return e.childNodes.forEach((e=>{3===e.nodeType&&(t+=e.textContent)})),t}return e.textContent}export function isInDom(e){return assert(isElement(e),`${MODULE_NAME}:isInDom | ${NOT_AN_HTMLELEMENT_ERROR}`),isFunction(document.contains)?document.contains(e):document.body.contains(e)}export function getData(e,t=null){t=orDefault(t,null,"arr"),assert(isElement(e),`${MODULE_NAME}:getData | ${NOT_AN_HTMLELEMENT_ERROR}`);let n={};return hasValue(t)?t.forEach((t=>{let r=e.getAttribute(`data-${t}`);if(hasValue(r))try{n[t]=JSON.parse(r)}catch(e){n[t]=r}})):Array.from(e.attributes).forEach((e=>{if(e.name.startsWith("data-")){const t=e.name.replace(/^data-/,"");try{n[t]=JSON.parse(e.value)}catch(r){n[t]=e.value}}})),0===size(n)?n=null:1===t?.length&&(n=n[t[0]]??null),n}export function setData(e,t,n=null){const r="setData";assert(isElement(e),`${MODULE_NAME}:${r} | ${NOT_AN_HTMLELEMENT_ERROR}`);let a=null;hasValue(n)&&(a=`${t}`,t={[a]:n}),assert(isPlainObject(t),`${MODULE_NAME}:${r} | dataSet is not a plain object`);const s={};return Object.entries(t).forEach((([t,n])=>{if(isFunction(n)&&(n=n()),void 0!==n){let r,a;try{r=JSON.stringify(n),a=JSON.parse(r)}catch(e){r=`${n}`,a=r}r=r.replace(/^['"]/,"").replace(/['"]$/,"").trim(),""!==r?(s[t]=a,e.setAttribute(`data-${t}`,r)):e.hasAttribute(`data-${t}`)&&(s[t]=void 0,e.removeAttribute(`data-${t}`))}else e.hasAttribute(`data-${t}`)&&(s[t]=void 0,e.removeAttribute(`data-${t}`))})),hasValue(a)?a in s?s[a]:null:size(s)>0?s:null}export function removeData(e,t=null){t=orDefault(t,null,"arr"),assert(isElement(e),`${MODULE_NAME}:removeData | ${NOT_AN_HTMLELEMENT_ERROR}`);let n=getData(e,t);return hasValue(n)?setData(e,1===t?.length?{[t[0]]:void 0}:Object.keys(n).reduce(((e,t)=>(e[t]=void 0,e)),{})):n=null,n}export function find(e,t="*",n=!1){const r=/:scope(?![\w-])/gi;if(assert(isElement(e),`${MODULE_NAME}:find | ${NOT_AN_HTMLELEMENT_ERROR}`),t=orDefault(t,"*","str").trim(),r.test(t)||(t=`:scope ${t}`),n=orDefault(n,!1,"bool"),BROWSER_HAS_CSS_SCOPE_SUPPORT)return n?e.querySelector(t):Array.from(e.querySelectorAll(t));{const a=`find-scope-${randomUuid()}`;t=t.replace(r,`[${a}]`),e.setAttribute(a,"");const s=n?e.querySelector(t):Array.from(e.querySelectorAll(t));return e.removeAttribute(a),s}}export function findOne(e,t="*"){return find(e,t,!0)}export function findTextNodes(e,t=null,n=!1){t=isFunction(t)?t:()=>!0,n=orDefault(n,!1,"bool"),assert(isElement(e),`${MODULE_NAME}:findTextNodes | ${NOT_AN_HTMLELEMENT_ERROR}`);const r=e=>3===e.nodeType&&""!==e.textContent.trim()&&!!t(e),a=e=>r(e)?[].concat(e):Array.from(e.childNodes).reduce(((e,t)=>r(t)?e.concat(t):n?e:e.concat(a(t))),[]);return a(e)}export function prime(e,t,n=null,r="primed"){const a="prime";n=orDefault(n,{}),r=orDefault(r,"primed","str"),assert(isElement(e),`${MODULE_NAME}:${a} | ${NOT_AN_HTMLELEMENT_ERROR}`),assert(isFunction(t),`${MODULE_NAME}:${a} | init is not a function`);const s=new Deferred;return!0!==getData(e,r)?(setData(e,r,!0),onDomReady((()=>{const n=t(e);hasValue(n)&&isFunction(n.then)&&isFunction(n.catch)?n.then((e=>{s.resolve(e)})).catch((e=>{s.reject(e)})):s.resolve(n),setData(e,`${r}-ready`,!0)}))):s.resolve(void 0),s.then((()=>{hasValue(n.remove)&&[].concat(n.remove).forEach((t=>{`${t}`.split(" ").forEach((t=>{e.classList.remove(t.trim())}))})),hasValue(n.add)&&[].concat(n.add).forEach((t=>{`${t}`.split(" ").forEach((t=>{e.classList.add(t.trim())}))})),setData(e,`${r}-resolved`,!0)})),s}export function measureHiddenDimensions(e,t="outer",n=null,r=null){const a="measureHidden",s={offset:{width:"offsetWidth",height:"offsetHeight"},outer:{width:"offsetWidth",height:"offsetHeight"},client:{width:"clientWidth",height:"clientHeight"},inner:{width:"clientWidth",height:"clientHeight"},scroll:{width:"scrollWidth",height:"scrollHeight"}};t=s[orDefault(t,"outer","str")]??s.outer,r=orDefault(r,document.body),assert(isElement(e),`${MODULE_NAME}:${a} | ${NOT_AN_HTMLELEMENT_ERROR}`),assert(isElement(r),`${MODULE_NAME}:${a} | context is no an htmlelement`);const o=createNode("div",{id:`sandbox-${randomUuid()}`,class:"sandbox",style:"display:block; opacity:0; visibility:hidden; pointer-events:none; position:absolute; top:-10000px; left:-10000px;"}),i=clone(e);r.appendChild(o),o.appendChild(i);const l=isSelector(n)?i.querySelector(n):i,c=l?.[t.width]??0,d=l?.[t.height]??0,u={width:c,height:d,toString:()=>`${c}x${d}`};return r.removeChild(o),u} //# sourceMappingURL=elements.js.map diff --git a/dist/elements.js.map b/dist/elements.js.map index 47ddef11..eaf17d1c 100644 --- a/dist/elements.js.map +++ b/dist/elements.js.map @@ -1 +1 @@ -{"version":3,"file":"elements.js","names":["MODULE_NAME","orDefault","isString","isFunction","isPlainObject","isSelector","isElement","hasValue","assert","size","Deferred","randomUuid","clone","onDomReady","applyStyles","NOT_AN_HTMLELEMENT_ERROR","BROWSER_HAS_CSS_SCOPE_SUPPORT","document","querySelector","ex","createNode","tag","attributes","content","trim","outerNode","createElement","test","innerHTML","appendChild","node","firstChild","removeChild","attribute","setAttribute","textContent","insertNode","target","position","insertAdjacentElement","replaceNode","__methodName__","parentNode","defineNode","definition","boilerplateNode","inheritValue","Array","from","forEach","name","startsWith","value","Object","keys","sort","reverse","addValue","slice","endsWith","concat","split","classList","add","rules","valueObj","rule","key","prop","getAttribute","getTextContent","onlyFirstLevel","childNodes","nodeType","isInDom","contains","body","getData","properties","data","property","attributeValue","JSON","parse","replace","length","setData","dataSet","singleValue","singleKey","appliedValues","entries","undefined","stringifiedValue","getValue","stringify","hasAttribute","removeAttribute","removeData","reduce","removalDataSet","find","selector","onlyOne","scopeRex","querySelectorAll","fallbackScopeAttribute","found","findOne","findTextNodes","filter","isValidTextNode","extractTextNodes","textNodes","childNode","prime","init","classChanges","markerAttributesName","deferred","initResult","then","catch","resolution","resolve","error","reject","remove","removeClass","addClass","measureHiddenDimensions","method","context","methods","offset","width","height","outer","client","inner","scroll","sandbox","id","class","style","measureClone","dimensions","toString"],"sources":["elements.js"],"mappings":"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","sourcesContent":["/*!\n * Module Elements\n */\n\n/**\n * @namespace Elements\n */\n\nconst MODULE_NAME = 'Elements';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {\n\torDefault,\n\tisString,\n\tisFunction,\n\tisPlainObject,\n\tisSelector,\n\tisElement,\n\thasValue,\n\tassert,\n\tsize,\n\tDeferred\n} from './basic.js';\nimport {randomUuid} from './random.js';\nimport {clone} from './objects.js';\nimport {onDomReady} from './events.js';\nimport {applyStyles} from './css.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst NOT_AN_HTMLELEMENT_ERROR = 'given node/target is not an HTMLElement';\nlet BROWSER_HAS_CSS_SCOPE_SUPPORT;\ntry {\n\tdocument.querySelector(':scope *');\n} catch(ex){\n\tBROWSER_HAS_CSS_SCOPE_SUPPORT = false;\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Elements:createNode\n */\n\n/**\n * Creates an element on the fly programmatically, based on provided name, attributes and content or markup,\n * without inserting it into the DOM.\n *\n * If you provide markup as \"tag\", make sure that there is one single root element, this method returns exactly one\n * element, not a NodeList. Also be sure to _not_ just pass HTML source from an unsecure source, since this\n * method does not deal with potential security risks.\n *\n * One thing about dynamically creating script tags with this: if you want the script is javascript and you want to\n * actually execute the script upon adding it to the dom, you cannot provide the complete tag as a source string,\n * since scripts created with innerHTML will not execute.\n * (see: https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML#security_considerations)\n * Instead, just provide the tag name and define attributes and source via the parameters instead.\n *\n * @param {?String} [tag='span'] - tag of the element to create or markup for root element\n * @param {?Object} [attributes=null] - tag attributes as key/value-pairs, will also be added to provided markup\n * @param {?String} [content=null] - content to insert into the element as textContent, be aware, that this will replace other content in provided markup\n * @returns {HTMLElement} the created DOM-node\n *\n * @memberof Elements:createNode\n * @alias createNode\n * @example\n * document.body.appendChild(\n * createNode('div', {id : 'content', style : 'display:none;'}, 'loading...')\n * );\n * document.body.appendChild(\n * createNode('
loading...
')\n * );\n * document.body.appendChild(\n * createNode('script', {type : 'text/javascript'}, 'alert(\"Hello World\");');\n * );\n */\nexport function createNode(tag, attributes=null, content=null){\n\ttag = orDefault(tag, 'span', 'str').trim();\n\tattributes = isPlainObject(attributes) ? attributes : null;\n\tcontent = orDefault(content, null, 'str');\n\n\t// using anything more generic like template results in non-standard nodes like\n\t// `);\n\t\t\t\t\tif( dataId !== null ){\n\t\t\t\t\t\telement.setAttribute('data-id', `${dataId}`);\n\t\t\t\t\t}\n\n\t\t\t\t\tif( hasValue(insertTarget) ){\n\t\t\t\t\t\tconst\n\t\t\t\t\t\t\ttarget = insertTarget.element ?? insertTarget,\n\t\t\t\t\t\t\tposition = insertTarget.position ?? null\n\t\t\t\t\t\t;\n\n\t\t\t\t\t\tif( position === null ){\n\t\t\t\t\t\t\tinsertNode(target, element);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tinsertNode(target, element, position);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tres.resolve(\n\t\t\t\t\t\t(resolveTo === 'element')\n\t\t\t\t\t\t\t? element\n\t\t\t\t\t\t\t: (\n\t\t\t\t\t\t\t\t(resolveTo === 'raw')\n\t\t\t\t\t\t\t\t? JSON.stringify(json)\n\t\t\t\t\t\t\t\t: json\n\t\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t})\n\t\t\t\t.catch(error => {\n\t\t\t\t\tres.reject(error);\n\t\t\t\t})\n\t\t\t;\n\n\t\t\treturn res;\n\t\t}\n\t};\n}\n\n\n\n/**\n * @namespace Requests:RestfulJsonClient\n */\n\n/**\n * @typedef RestfulJsonClientConfig\n * @type {Object}\n *\n * @property {URL} url - the current request URL, build from baseUrl and path\n * @property {Object} options - the current options with which requests are been created, build from baseOptions and options, see createFetchRequest for details\n * @property {URLSearchParams} params - the current URL params\n * @property {Object} data - the current payload to be sent with requests like POST and PUT\n *\n * @memberof Requests\n * @see createFetchRequest\n */\n\n/**\n * This class provides a dedicated client for restful operations against an API via JSON payloads and responses.\n *\n * Internally this implementation uses createJsonRequest to actually request stuff, while this class\n * is a wrapper, providing central configuration, such as a base URL and options like credentials,\n * as well as standard methods for HTTP verbs and setup things like setting headers.\n *\n * See class documentation below for details.\n *\n * @memberof Requests:RestfulJsonClient\n * @name RestfulJsonClient\n *\n * @see RestfulJsonClient\n * @see createJsonRequest\n * @see Requests.FetchRequest\n * @example\n * const client = new RestfulJsonClient('https://jsonplaceholder.typicode.com', {credentials : 'include'});\n * const postJson = await client\n * .path('/posts')\n * \t .params({\n * \t ids : [1, 2],\n * \t q : 'lorem'\n * \t })\n * \t .data({\n * \t title : 'foo',\n * \t body : 'bar',\n * \t userId : 1,\n * \t })\n * \t .post()\n * ;\n */\nclass RestfulJsonClient {\n\n\t#__className__ = 'RestfulJsonClient';\n\t#invalidRequestMethodMessage = 'invalid request method';\n\t#dataValidationMessage = 'data must be plain object';\n\t#baseUrl = null;\n\t#baseOptions = null;\n\t#useNative = false;\n\t#strict = true;\n\t#config = null;\n\n\t/**\n\t * Creates a new RestfulJsonClient\n\t *\n\t * @param {?String} [baseUrl=window.location.origin] - the base URL for all queries, based on which final request URLs will be built, adding the paths, may be absolute or relative to current origin\n\t * @param {?Object} [baseOptions=null] - the base request options, can be expanded later via options() (see createFetchRequests for details)\n\t * @param {?Boolean|String} [useNative=false] - determines if the native Fetch implementation of the browser should be used, true forces usage, \"auto\" uses it only if available\n\t * @param {?Boolean} [strict=true] - if true, enforces \"application/json\" as accept header as well as response mime type, if false, accept header is not set and different mime type only results in warning\n\t *\n\t * @see createJsonRequest\n * @see Requests.FetchRequest\n\t */\n\tconstructor(baseUrl=null, baseOptions=null, useNative=false, strict=true){\n\t\tthis.#baseUrl = orDefault(baseUrl, window.location.origin, 'str');\n\t\tthis.#baseOptions = isPlainObject(baseOptions) ? baseOptions : {};\n\t\tthis.#useNative = orDefault(useNative, false, 'bool');\n\t\tthis.#strict = orDefault(strict, true, 'bool');\n\n\t\tif( !this.#baseUrl.startsWith('//') && this.#baseUrl.startsWith('/') ){\n\t\t\tthis.#baseUrl = `${window.location.origin}${this.#baseUrl}`;\n\t\t}\n\n\t\tthis.#config = {\n\t\t\turl : new URL('', this.#baseUrl),\n\t\t\toptions : {},\n\t\t\tparams : new URLSearchParams(),\n\t\t\tdata : {},\n\t\t};\n\t}\n\n\n\n\t/**\n\t * Sets the current request path, which will be concatenated to baseUrl.\n\t *\n\t * @param {String} path - the current path to request from baseUrl\n\t * @returns {RestfulJsonClient}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/food')).path('/pizzas').get();\n\t */\n\tpath(path){\n\t\tpath = `${path}`.replaceAll(/^\\/+/g, '');\n\n\t\tthis.#config.url = new URL(path, this.#baseUrl);\n\n\t\treturn this;\n\t}\n\n\n\t/**\n\t * Sets the current request options, which will be merged with baseOptions.\n\t *\n\t * @param {?Object} options - plain options object to merge with baseOptions to define current request options (see createFetchRequest for details and defaults); if nullish, baseOptions will be used\n\t * @throws error if given options are not a plain object\n\t * @returns {RestfulJsonClient}\n\t *\n\t * @see createJsonRequest\n\t * @see Requests.FetchRequest\n\t * @example\n\t * (new RestfulJsonClient('/run-forrest-run')).options({timeout : 1});\n\t */\n\toptions(options){\n\t\tconst __methodName__ = 'options';\n\n\t\tif( hasValue(options) ){\n\t\t\tassert(isPlainObject(options), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | options must be plain object`);\n\t\t\tthis.#config.options = options;\n\t\t} else {\n\t\t\tthis.#config.options = {};\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\t/**\n\t * Sets a header for all subsequent requests.\n\t * Use a nullish value to unset a header.\n\t *\n\t * @param {String} key - the header to set for all following requests\n\t * @param {?String} value - the header's value; a nullish value will remove the header again\n\t * @returns {RestfulJsonClient}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/run-forrest-run')).header('X-Test', 42).header('X-Test', null);\n\t */\n\theader(key, value){\n\t\tkey = `${key}`;\n\n\t\tif( !isPlainObject(this.#config.options.headers) ){\n\t\t\tthis.#config.options.headers = {};\n\t\t}\n\n\t\tif( hasValue(value) ){\n\t\t\tthis.#config.options.headers[key] = `${value}`;\n\t\t} else {\n\t\t\tdelete this.#config.options.headers[key];\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Sets query parameters to be added to the request URL.\n\t *\n\t * @param {?*} params - query parameters to set on the current URL, this parameter takes all regular definitions for URLSearchParams constructor, as well as flat plain objects, which may also have arrays as values; if nullish, parameters are emptied\n\t * @returns {RestfulJsonClient}\n\t *\n\t * @see https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/URLSearchParams\n\t * @example\n\t * (new RestfulJsonClient('/food/search')).params({q : 'delicious pizza'}).get();\n\t */\n\tparams(params){\n\t\tif( hasValue(params) ){\n\t\t\tthis.#config.params = new URLSearchParams(isPlainObject(params) ? this.#toFlatEntries(params) : params);\n\t\t} else {\n\t\t\tthis.#config.params = new URLSearchParams();\n\t\t}\n\n\t\tthis.#config.url.search = this.#config.params.toString();\n\n\t\treturn this;\n\t}\n\n\n\n /**\n * Sets a query parameter to be added to the request URL.\n * Use a nullish value to unset a parameter.\n *\n * @param {String} key - the parameter name to set\n * @param {?String} value - the parameter's value; a nullish value will remove the param again\n * @param {?Boolean} [append=false] - if true, the parameter is appended instead of overwritten\n * @returns {RestfulJsonClient}\n *\n * @example\n * (new RestfulJsonClient('/food/search')).param('q', 'delicious pizza').get();\n */\n\tparam(key, value, append=false){\n key = `${key}`;\n\t\tappend = orDefault(append, false, 'bool');\n\n if( hasValue(value) ){\n\t\t\tif( append ){\n this.#config.params.append(key, `${value}`);\n\t\t\t} else {\n this.#config.params.set(key, `${value}`);\n\t\t\t}\n } else {\n delete this.#config.params.delete(key);\n }\n\n this.#config.url.search = this.#config.params.toString();\n\n return this;\n\t}\n\n\n\n\t/**\n\t * Sets data payload for POST, PUT and PATCH requests.\n\t *\n\t * @param {?Object} data - data payload to send with the next POST, PUT or PATCH request, this parameter will set a permanent payload; for one-off payloads, use the verb method's data parameter; if nullish, data will be emptied\n\t * @throws error if given data is not a plain object\n\t * @returns {RestfulJsonClient}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/food/order')).data({pizza : 'diavolo'}).post();\n\t */\n\tdata(data){\n\t\tconst __methodName__ = 'data';\n\n\t\tif( hasValue(data) ){\n\t\t\tassert(isPlainObject(data), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#dataValidationMessage}`);\n\t\t\tthis.#config.data = data;\n\t\t} else {\n\t\t\tthis.#config.data = {};\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Queries the current URL with GET.\n\t *\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns {Basic.Deferred}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/food/')).path('pizza').get();\n\t */\n\tget(){\n\t\treturn this.#executeRequest('GET');\n\t}\n\n\n\n\t/**\n\t * Queries the current URL with POST using defined payload/data.\n\t *\n\t * @param {?Object} [data=null] - one-off data to use in this request, will replace any central data defined before and will only be valid for this request\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns {Basic.Deferred}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/food/order')).post({pizza : 'diavolo'});\n\t */\n\tpost(data=null){\n\t\treturn this.#executeRequestWithPayload('POST', data);\n\t}\n\n\n\n\t/**\n\t * Queries the current URL with PUT using defined payload/data.\n\t *\n\t * @param {?Object} [data=null] - one-off data to use in this request, will replace any central data defined before and will only be valid for this request\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns {Basic.Deferred}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/food/deliver')).put({pizza : 'diavolo'});\n\t */\n\tput(data=null){\n\t\treturn this.#executeRequestWithPayload('PUT', data);\n\t}\n\n\n\n\t/**\n\t * Queries the current URL with PATCH using defined payload/data.\n\t *\n\t * @param {?Object} [data=null] - one-off data to use in this request, will replace any central data defined before and will only be valid for this request\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns {Basic.Deferred}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/software')).data({version : 2}).patch();\n\t */\n\tpatch(data=null){\n\t\treturn this.#executeRequestWithPayload('PATCH', data);\n\t}\n\n\n\n\t/**\n\t * Queries the current URL with DELETE.\n\t *\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns {Basic.Deferred}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/')).data({command : 'rm -rf'}).delete();\n\t */\n\tdelete(){\n\t\treturn this.#executeRequest('DELETE');\n\t}\n\n\n\n\t/**\n\t * Returns the current config.\n\t *\n\t * baseUrl is retrievable from the url property (via origin).\n\t * Options are the merged result of baseOptions and currently set option values.\n\t *\n\t * Changes to this object, will not reflect in the client config directly, use the client's methods to\n\t * alter config values.\n\t *\n\t * @returns {RestfulJsonClientConfig} a clone of the current config\n\t *\n\t * @example\n\t * client.getConfig().url.toString()\n\t * => https://pizza.com\n\t */\n\tgetConfig(){\n\t\treturn merge(this.#config, {options : merge(this.#baseOptions, this.#config.options)});\n\t}\n\n\n\n\t/**\n\t * Creates and executes an HTTP request without a payload, such as GET and DELETE.\n\t * Uses current config from class to construct request.\n\t *\n\t * @param {String} method - either GET or DELETE\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns Basic.Deferred\n\t *\n\t * @example\n\t * this.#executeRequest('GET');\n\t */\n\t#executeRequest(method){\n\t\tconst __methodName__ = '#executeRequest';\n\n\t\tmethod = method.toUpperCase();\n\t\tassert(\n\t\t\t['GET', 'DELETE'].includes(method),\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#invalidRequestMethodMessage} \"${method}\"`\n\t\t);\n\n\t\tconst options = merge(this.#baseOptions, this.#config.options, {method});\n\t\treturn createJsonRequest(this.#config.url, options, this.#useNative, this.#strict).execute();\n\t}\n\n\n\n\t/**\n\t * Creates and executes an HTTP request with a payload, such as POST and PUT.\n\t * Uses current config from class to construct request.\n\t *\n\t * @param {String} method - either POST, PUT or PATCH\n\t * @param {?Object} [data=null] - the data to send to the request URL as payload\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns Basic.Deferred\n\t *\n\t * @example\n\t * this.#executeRequestWithPayload('POST', {foo : 'bar'});\n\t */\n\t#executeRequestWithPayload(method, data=null){\n\t\tconst __methodName__ = '#executeRequestWithPayload';\n\n\t\tmethod = method.toUpperCase();\n\t\tassert(\n\t\t\t['POST', 'PUT', 'PATCH'].includes(method),\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#invalidRequestMethodMessage} \"${method}\"`\n\t\t);\n\t\tif( hasValue(data) ){\n\t\t\tassert(isPlainObject(data), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#dataValidationMessage}`);\n\t\t}\n\n\t\tconst contentTypeHeader = 'Content-Type';\n\t\tthis.header(contentTypeHeader, 'application/json; charset=UTF-8');\n\t\tconst\n\t\t\tbody = JSON.stringify(data ?? this.#config.data),\n\t\t\toptions = merge(this.#baseOptions, this.#config.options, {method, body})\n\t\t;\n\t\treturn createJsonRequest(this.#config.url, options, this.#useNative, this.#strict)\n\t\t\t.execute()\n\t\t\t.finally(() => {\n\t\t\t\tthis.header(contentTypeHeader, null);\n\t\t\t})\n\t\t;\n\t}\n\n\n\n\t/**\n\t * Transforms a dictionary to an entries array, but handles list values, such as arrays and sets, specially, by\n\t * iterating them and creating a new entry for each list value, thereby producing a notation, which is compatible\n\t * to URLSearchParams, based on an object with a readable notation.\n\t *\n\t * @param {Object} obj - the object to transform into a flattened array of entries\n\t * @returns {Array>} flat array of entries\n\t *\n\t * @private\n\t * @see https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams\n\t */\n\t#toFlatEntries(obj){\n\t\tconst\n\t\t\tentries = Object.entries(obj),\n\t\t\tflattenedEntries = []\n\t\t;\n\n\t\tfor(const entryIndex in entries ){\n\t\t\tconst\n\t\t\t\tentryKey = entries[entryIndex][0],\n\t\t\t\tentryVal = entries[entryIndex][1],\n\t\t\t\tentryValType = getType(entryVal)\n\t\t\t;\n\n\t\t\tif( ['array', 'set'].includes(entryValType) ){\n\t\t\t\tArray.from(entryVal).forEach(val => {\n\t\t\t\t\tflattenedEntries.push([entryKey, `${val}`]);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tflattenedEntries.push([entryKey, `${entryVal}`]);\n\t\t\t}\n\t\t}\n\n\t\treturn flattenedEntries;\n\t}\n\n}\n\nexport {RestfulJsonClient};\n\n\n\n/**\n * @namespace Requests:createJsRequest\n */\n\n/**\n * @typedef JsFetchResponse\n * @type {HTMLElement|String}\n *\n * @memberof Requests\n */\n\n/**\n * @typedef JsFetchRequestExecuteFunction\n * @type {Function}\n *\n * @param {?String} [resolveTo='element'] - defines what the response should resolve to, may either be \"element\", \"raw\" or \"sourced-element\" (which is the special case to insert a script with a src instead of doing a real request)\n * @param {?HTMLElement|Object} [insertTarget=null] - defines if the retrieved value should be inserted as a dom element and if so where; if this is an element, the value gets appended into that as a script tag, otherwise the properties below apply\n * @param {?HTMLElement} [insertTarget.element] - target element in relation to which the resolved value should be inserted into the dom\n * @param {?String} [insertTarget.position] - defines where, in relation to the target element, the resolved value will be inserted, see insertNode for more details\n * @param {?String} [dataId=null] - if you need an identifier, to find inserted elements again after they are inserted into dom, you can define an id here, which will be set as the \"data-id\" attribute on the created node\n * @param {?Boolean} [resolveSourcedOnInsert=false] - normally sourced elements resolve on load to work with the request as far as possible, but if you want to ignore the request after insertion, you may set this parameter to \"true\", resulting in immediate resolution after insertion\n * @returns {Basic.Deferred}\n *\n * @memberof Requests\n * @see insertNode\n */\n\n/**\n * @typedef JsFetchRequest\n * @type {Object}\n *\n * @property {String} url - the request URL\n * @property {Object} options - the options with which the request has been created\n * @property {String} options.method - the request method\n * @property {?Object} options.headers - the set headers for the request\n * @property {?String} options.credentials - the credentials setting for the request\n * @property {?String} options.body - the provided request body of the request\n * @property {?Number} [options.timeout=10000] - milliseconds until the request fails due to a timeout\n * @property {Requests.JsFetchRequestExecuteFunction} execute - call this to execute the request\n *\n * @memberof Requests\n */\n\n/**\n * This method creates a special version of a FetchRequest specifically designed to retrieve JavaScript.\n *\n * Usually you'll want to retrieve JavaScript to include it into a page to execute the script on the page\n * currently open, so the default mode of this method is to resolve to a directly usable script tag, you may\n * insert into the DOM wherever you please. However, you may also specify to retrieve the raw JavaScript source.\n *\n * Be aware that requesting JavaScript from an unsecure source is a very big security risk. Do not load and execute\n * source from a source you do not fully trust!\n *\n * If you plan on inserting the result into DOM anyway you'll like the fact that this is also directly possible, by\n * defining an insert target. In case you decide to insert the result directly, the default is an inline script, but\n * you may also choose to insert a sourced script tag, loading a script on insertion and executing in asynchronously\n * in turn. This is not strictly a programmatic \"request\" anymore, but very handy. If you are inserting a sourced\n * script, the Deferred resolves on load by default (and rejects on error), thereby keeping the general idea of\n * working with a request. But you may also define a parameter on execute to force resolve immediately on insert.\n *\n * BTW: Inserting does not automatically change the resolve value, those are separate concerns.\n *\n * @param {String} url - the complete URL to query\n * @param {?Object} [options=null] - the request options (see: createFetchRequests for details)\n * @param {?Boolean|String} [useNative=false] - determines if the native Fetch implementation of the browser should be used, true forces usage, \"auto\" uses it only if available\n * @param {?Boolean} [strict=true] - if true, enforces \"application/javascript\" as accept header as well as response mime type, if false, accept header is not set and different mime type only results in warning\n * @throws error in strict mode if response content type is not \"application/javascript\"\n * @returns {Requests.JsFetchRequest} use this via the \"execute\" method, which resolves to a FetchResponse or rejects with error in case of a technical request error (request is not completable)\n *\n * @memberof Requests:createJsRequest\n * @alias createJsRequest\n * @see createFetchRequest\n * @example\n * createJsRequest('/js/test.js')\n * .execute()\n * .then(jsElement => { document.body.appendChild(jsElement); })\n * ;\n * createJsRequest('/js/test.js')\n * .execute(null, injectTarget, 'request-2')\n * .then(jsElement => { alert(`has been injected: \"${jsElement.textContent}\"`); })\n * ;\n * createJsRequest('/js/test.js')\n * .execute('raw', {element : injectTarget, position : 'beforebegin'})\n * .then(rawJs => { alert(`has been injected: \"${rawJs}\"`); })\n * ;\n * createJsRequest('/js/test.js')\n * .execute('sourced-element', {element : injectTarget, position : 'prepend'}, 'request-4')\n * .then(jsElement => { alert(`has been injected: \"${jsElement.getAttribute('data-id')}\"`); })\n * ;\n */\nexport function createJsRequest(url, options=null, useNative=false, strict=true){\n\tconst\n\t\t__methodName__ = 'createJsRequest',\n\t\tcontentType = 'application/javascript'\n\t;\n\n\tif( strict ){\n\t\tif( !hasValue(options) ){\n\t\t\toptions = {};\n\t\t}\n\n\t\tif( !hasValue(options.headers) ){\n\t\t\toptions.headers = {};\n\t\t}\n\n\t\toptions.headers['Accept'] = contentType;\n\t}\n\n\treturn {\n\t\turl,\n\t\toptions,\n\t\texecute(resolveTo='element', insertTarget=null, dataId=null, resolveSourcedOnInsert=false){\n\t\t\tconst\n\t\t\t\tsourceElementValue = 'sourced-element',\n\t\t\t\tres = new Deferred(),\n\t\t\t\tfInsertAndResolve = (element, js='') => {\n\t\t\t\t\tif( dataId !== null ){\n\t\t\t\t\t\telement.setAttribute('data-id', `${dataId}`);\n\t\t\t\t\t}\n\n\t\t\t\t\tif( hasValue(insertTarget) ){\n\t\t\t\t\t\tconst\n\t\t\t\t\t\t\ttarget = insertTarget.element ?? insertTarget,\n\t\t\t\t\t\t\tposition = insertTarget.position ?? null\n\t\t\t\t\t\t;\n\n\t\t\t\t\t\tif( !resolveSourcedOnInsert ){\n\t\t\t\t\t\t\telement.onload = () => { res.resolve((resolveTo === 'raw') ? js : element); };\n\t\t\t\t\t\t\telement.onerror = error => { res.reject(error); };\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( position === null ){\n\t\t\t\t\t\t\tinsertNode(target, element);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tinsertNode(target, element, position);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(\n\t\t\t\t\t\t(resolveTo !== sourceElementValue)\n\t\t\t\t\t\t|| ((resolveTo === sourceElementValue) && resolveSourcedOnInsert)\n\t\t\t\t\t){\n\t\t\t\t\t\tres.resolve((resolveTo === 'raw') ? js : element);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t;\n\n\t\t\tif( resolveTo === sourceElementValue ){\n\t\t\t\tfInsertAndResolve(createNode('script', {src : url}));\n\t\t\t} else {\n\t\t\t\tcreateFetchRequest(url, options, useNative).execute()\n\t\t\t\t\t.then(response => {\n\t\t\t\t\t\tconst responseContentType = (\n\t\t\t\t\t\t\tresponse.headers.get('content-type') ?? response.headers.get('Content-Type') ?? ''\n\t\t\t\t\t\t).split(';')[0].trim();\n\n\t\t\t\t\t\tif( responseContentType !== contentType ){\n\t\t\t\t\t\t\tconst message = `${MODULE_NAME}:${__methodName__} | content-type \"${responseContentType}\" is not valid for JavaScript, expecting \"application/javascript\"`;\n\t\t\t\t\t\t\tif( strict ){\n\t\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\twarn(message);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn response.text();\n\t\t\t\t\t})\n\t\t\t\t\t.then(js => {\n\t\t\t\t\t\tfInsertAndResolve(createNode('script', null, js), js);\n\t\t\t\t\t})\n\t\t\t\t\t.catch(error => {\n\t\t\t\t\t\tres.reject(error);\n\t\t\t\t\t})\n\t\t\t\t;\n\t\t\t}\n\n\t\t\treturn res;\n\t\t}\n\t};\n}\n\n\n\n/**\n * @namespace Requests:createCssRequest\n */\n\n/**\n * @typedef CssFetchResponse\n * @type {HTMLElement|String}\n *\n * @memberof Requests\n */\n\n/**\n * @typedef CssFetchRequestExecuteFunction\n * @type {Function}\n *\n * @param {?String} [resolveTo='element'] - defines what the response should resolve to, may either be \"element\", \"raw\" or \"sourced-element\" (which is the special case to insert a link with a href instead of doing a real request)\n * @param {?HTMLElement|Object} [insertTarget=null] - defines if the retrieved value should be inserted as a dom element and if so where; if this is an element, the value gets appended into that as a style/link tag, otherwise the properties below apply\n * @param {?HTMLElement} [insertTarget.element] - target element in relation to which the resolved value should be inserted into the dom\n * @param {?String} [insertTarget.position] - defines where, in relation to the target element, the resolved value will be inserted, see insertNode for more details\n * @param {?String} [dataId=null] - if you need an identifier, to find inserted elements again after they are inserted into dom, you can define an id here, which will be set as the \"data-id\" attribute on the created node\n * @param {?String} [media='all'] - define the style's media attribute here to target the output device(s), could be \"screen\" or \"print\" for example\n * @param {?Boolean} [resolveSourcedOnInsert=false] - normally sourced elements resolve on load to work with the request as far as possible, but if you want to ignore the request after insertion, you may set this parameter to \"true\", resulting in immediate resolution after insertion\n * @returns {Basic.Deferred}\n *\n * @memberof Requests\n * @see insertNode\n */\n\n/**\n * @typedef CssFetchRequest\n * @type {Object}\n *\n * @property {String} url - the request URL\n * @property {Object} options - the options with which the request has been created\n * @property {String} options.method - the request method\n * @property {?Object} options.headers - the set headers for the request\n * @property {?String} options.credentials - the credentials setting for the request\n * @property {?String} options.body - the provided request body of the request\n * @property {?Number} [options.timeout=10000] - milliseconds until the request fails due to a timeout\n * @property {Requests.CssFetchRequestExecuteFunction} execute - call this to execute the request\n *\n * @memberof Requests\n */\n\n/**\n * This method creates a special version of a FetchRequest specifically designed to retrieve Cascading Stylesheets.\n *\n * Usually you'll want to retrieve CSS to include it into a page and thereby style something on the page\n * currently open, so the default mode of this method is to resolve to a directly usable style tag, you may\n * insert into the DOM wherever you please. However, you may also specify to retrieve the raw CSS source.\n *\n * If you plan on inserting the result into DOM anyway you'll like the fact that this is also directly possible, by\n * defining an insert target. In case you decide to insert the result directly, the default is an inline style, but\n * you may also choose to insert a sourced link tag, loading a stylesheet on insertion and adding the included styles\n * on load. This is not strictly a programmatic \"request\" anymore, but very handy. If you are inserting a sourced\n * link, the Deferred resolves on load by default (and rejects on error), thereby keeping the general idea of\n * working with a request. But you may also define a parameter on execute to force resolve immediately on insert.\n *\n * BTW: Inserting does not automatically change the resolve value, those are separate concerns.\n *\n * @param {String} url - the complete URL to query\n * @param {?Object} [options=null] - the request options (see: createFetchRequests for details)\n * @param {?Boolean|String} [useNative=false] - determines if the native Fetch implementation of the browser should be used, true forces usage, \"auto\" uses it only if available\n * @param {?Boolean} [strict=true] - if true, enforces \"text/css\" as accept header as well as response mime type, if false, accept header is not set and different mime type only results in warning\n * @throws error in strict mode if response content type is not \"text/css\"\n * @returns {Requests.CssFetchRequest} use this via the \"execute\" method, which resolves to a FetchResponse or rejects with error in case of a technical request error (request is not completable)\n *\n * @memberof Requests:createCssRequest\n * @alias createCssRequest\n * @see createFetchRequest\n * @example\n * createCssRequest('/css/test.css')\n * .execute()\n * .then(cssElement => { document.head.appendChild(cssElement); })\n * ;\n * createCssRequest('/css/test.css')\n * .execute(null, injectTarget, 'request-2')\n * .then(cssElement => { alert(`has been injected: \"${cssElement.textContent}\"`); })\n * ;\n * createCssRequest('/css/test.css')\n * .execute('raw', {element : injectTarget, position : 'beforebegin'}, 'request-3', 'screen')\n * .then(rawCss => { alert(`has been injected: \"${rawCss}\"`); })\n * ;\n * createCssRequest('/css/test.css')\n * .execute('sourced-element', {element : injectTarget, position : 'prepend'}, 'request-4', 'screen')\n * .then(cssElement => { alert(`has been injected: \"${cssElement.getAttribute('data-id')+}\"`); })\n * ;\n */\nexport function createCssRequest(url, options=null, useNative=false, strict=true){\n\tconst\n\t\t__methodName__ = 'createCssRequest',\n\t\tcontentType = 'text/css'\n\t;\n\n\n\tif( strict ){\n\t\tif( !hasValue(options) ){\n\t\t\toptions = {};\n\t\t}\n\n\t\tif( !hasValue(options.headers) ){\n\t\t\toptions.headers = {};\n\t\t}\n\n\t\toptions.headers['Accept'] = contentType;\n\t}\n\n\treturn {\n\t\turl,\n\t\toptions,\n\t\texecute(resolveTo='element', insertTarget=null, dataId=null, media='all', resolveSourcedOnInsert=false){\n\t\t\tconst\n\t\t\t\tsourceElementValue = 'sourced-element',\n\t\t\t\tres = new Deferred(),\n\t\t\t\tfInsertAndResolve = (element, css='') => {\n\t\t\t\t\tif( dataId !== null ){\n\t\t\t\t\t\telement.setAttribute('data-id', `${dataId}`);\n\t\t\t\t\t}\n\n\t\t\t\t\tif( hasValue(insertTarget) ){\n\t\t\t\t\t\tconst\n\t\t\t\t\t\t\ttarget = insertTarget.element ?? insertTarget,\n\t\t\t\t\t\t\tposition = insertTarget.position ?? null\n\t\t\t\t\t\t;\n\n\t\t\t\t\t\tif( !resolveSourcedOnInsert ){\n\t\t\t\t\t\t\telement.onload = () => { res.resolve((resolveTo === 'raw') ? css : element); };\n\t\t\t\t\t\t\telement.onerror = error => { res.reject(error); };\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( position === null ){\n\t\t\t\t\t\t\tinsertNode(target, element);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tinsertNode(target, element, position);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(\n\t\t\t\t\t\t(resolveTo !== sourceElementValue)\n\t\t\t\t\t\t|| ((resolveTo === sourceElementValue) && resolveSourcedOnInsert)\n\t\t\t\t\t){\n\t\t\t\t\t\tres.resolve((resolveTo === 'raw') ? css : element);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t;\n\n\t\t\tif( resolveTo === sourceElementValue ){\n\t\t\t\tconst linkAttrs = {href : url, rel : 'stylesheet'};\n\t\t\t\tif( media !== 'all' ){\n\t\t\t\t\tlinkAttrs.media = media;\n\t\t\t\t}\n\t\t\t\tfInsertAndResolve(createNode('link', linkAttrs));\n\t\t\t} else {\n\t\t\t\tcreateFetchRequest(url, options, useNative).execute()\n\t\t\t\t\t.then(response => {\n\t\t\t\t\t\tconst responseContentType = (\n\t\t\t\t\t\t\tresponse.headers.get('content-type') ?? response.headers.get('Content-Type') ?? ''\n\t\t\t\t\t\t).split(';')[0].trim();\n\n\t\t\t\t\t\tif( responseContentType !== contentType ){\n\t\t\t\t\t\t\tconst message = `${MODULE_NAME}:${__methodName__} | content-type \"${responseContentType}\" is not valid for CSS, expecting \"text/css\"`;\n\t\t\t\t\t\t\tif( strict ){\n\t\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\twarn(message);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn response.text();\n\t\t\t\t\t})\n\t\t\t\t\t.then(css => {\n\t\t\t\t\t\tfInsertAndResolve(createNode('style', (media !== 'all') ? {media} : null, css), css);\n\t\t\t\t\t})\n\t\t\t\t\t.catch(error => {\n\t\t\t\t\t\tres.reject(error);\n\t\t\t\t\t})\n\t\t\t\t;\n\t\t\t}\n\n\t\t\treturn res;\n\t\t}\n\t};\n}\n\n\n\n/**\n * @namespace Requests:createHtmlRequest\n */\n\n/**\n * @typedef HtmlFetchResponse\n * @type {HTMLElement|Array|String}\n *\n * @memberof Requests\n */\n\n/**\n * @typedef HtmlFetchRequestExecuteFunction\n * @type {Function}\n *\n * @param {?String} [resolveTo='element'] - defines what the response should resolve to, may either be \"element\" or \"raw\"\n * @param {?HTMLElement|Object} [insertTarget=null] - defines if the retrieved value should be inserted as a dom element and if so where; if this is an element, the value gets appended into that as (a) node(s), otherwise the properties below apply\n * @param {?HTMLElement} [insertTarget.element] - target element in relation to which the resolved value should be inserted into the dom\n * @param {?String} [insertTarget.position] - defines where, in relation to the target element, the resolved value will be inserted, see insertNode for more details\n * @param {?String} [dataId=null] - if you need an identifier, to find inserted elements again after they are inserted into dom, you can define an id here, which will be set as the \"data-id\" attribute on the created node(s)\n * @param {?String} [selector=null] - if you'd like to preselect something from the result, you may define a regular query selector to find matching elements in the result\n * @param {?Boolean} [selectAll=false] - usually, if a selector is defined, we select a single element, if you need to select a list, set this to true\n * @returns {Basic.Deferred}\n *\n * @memberof Requests\n * @see insertNode\n */\n\n/**\n * @typedef HtmlFetchRequest\n * @type {Object}\n *\n * @property {String} url - the request URL\n * @property {Object} options - the options with which the request has been created\n * @property {String} options.method - the request method\n * @property {?Object} options.headers - the set headers for the request\n * @property {?String} options.credentials - the credentials setting for the request\n * @property {?String} options.body - the provided request body of the request\n * @property {?Number} [options.timeout=10000] - milliseconds until the request fails due to a timeout\n * @property {Requests.HtmlFetchRequestExecuteFunction} execute - call this to execute the request\n *\n * @memberof Requests\n */\n\n/**\n * This method creates a special version of a FetchRequest specifically designed to retrieve HTML content.\n *\n * Usually you'll want to retrieve HTML to include it into a page or extract information from it, so the default mode\n * of this method is to resolve to a node, you may insert into the DOM wherever you please or use stuff like a\n * querySelector on. However, you may also specify to retrieve the raw HTML source.\n *\n * Be aware, that requesting and parsing HTML from an unsecure source comes with a high risk. If you cannot fully\n * trust the source, request the HTML raw and use something like dom purify before using the result.\n *\n * If you plan on inserting the result into DOM anyway you'll like the fact that this is also directly possible, by\n * defining an insert target.\n *\n * BTW: Inserting does not automatically change the resolve value, those are separate concerns.\n *\n * @param {String} url - the complete URL to query\n * @param {?Object} [options=null] - the request options (see: createFetchRequests for details)\n * @param {?Boolean|String} [useNative=false] - determines if the native Fetch implementation of the browser should be used, true forces usage, \"auto\" uses it only if available\n * @param {?Boolean} [strict=true] - if true, enforces \"text/html\" as accept header as well as response mime type, if false, accept header is not set and different mime type only results in warning\n * @throws error in strict mode if response content type is not \"text/html\"\n * @returns {Requests.HtmlFetchRequest} use this via the \"execute\" method, which resolves to a FetchResponse or rejects with error in case of a technical request error (request is not completable)\n *\n * @memberof Requests:createHtmlRequest\n * @alias createHtmlRequest\n * @see createFetchRequest\n * @example\n * createHtmlRequest('/html/test.html')\n * .execute()\n * .then(htmlElement => { document.body.appendChild(htmlElement); })\n * ;\n * createHtmlRequest('/html/test.html')\n * .execute('raw', null, 'request-1')\n * .then(rawHtml => { alert(`document has been loaded: \"${rawHtml}\"`); })\n * ;\n * createHtmlRequest('/html/test.html')\n * .execute(null, injectTarget, 'request-3', 'body > main > h1')\n * .then(htmlElement => { alert(`has been injected: \"${htmlElement.outerHTML}\"`); })\n * ;\n * createHtmlRequest('/files/html/requests-test-1.html')\n * .execute('raw', {element : injectTarget, position : 'beforebegin'}, 'request-4', 'h1 ~ p', true)\n * .then(rawHtml => { alert(`has been injected: \"${rawHtml}\"`); })\n * ;\n * createHtmlRequest('/files/html/requests-test-2.html')\n * .execute('element', {element : injectTarget, position : 'prepend'}, 'request-5', 'p', true)\n * .then(htmlElements => { alert(`has been injected: \"${htmlElements.map(e => e.outerHTML).join('')}\"`); })\n * ;\n */\nexport function createHtmlRequest(url, options=null, useNative=false, strict=true){\n\tconst\n\t\t__methodName__ = 'createHtmlRequest',\n\t\tcontentType = 'text/html'\n\t;\n\n\tif( strict ){\n\t\tif( !hasValue(options) ){\n\t\t\toptions = {};\n\t\t}\n\n\t\tif( !hasValue(options.headers) ){\n\t\t\toptions.headers = {};\n\t\t}\n\n\t\toptions.headers['Accept'] = contentType;\n\t}\n\n\treturn {\n\t\turl,\n\t\toptions,\n\t\texecute(resolveTo='element', insertTarget=null, dataId=null, selector=null, selectAll=false){\n\t\t\tconst\n\t\t\t\tres = new Deferred(),\n\t\t\t\tfInsertAndResolve = (element, html='') => {\n\t\t\t\t\tif( hasValue(element) ){\n\t\t\t\t\t\tconst elements = [].concat(element);\n\n\t\t\t\t\t\tif( dataId !== null ){\n\t\t\t\t\t\t\telements.forEach(element => {\n\t\t\t\t\t\t\t\telement.setAttribute('data-id', `${dataId}`);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( hasValue(insertTarget) ){\n\t\t\t\t\t\t\tconst\n\t\t\t\t\t\t\t\ttarget = insertTarget.element ?? insertTarget,\n\t\t\t\t\t\t\t\tposition = insertTarget.position ?? null\n\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\tif( ['before', 'beforebegin', 'prepend', 'afterbegin'].includes(position) ){\n\t\t\t\t\t\t\t\telements.reverse();\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\telements.forEach(element => {\n\t\t\t\t\t\t\t\tif( position === null ){\n\t\t\t\t\t\t\t\t\tinsertNode(target, element);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tinsertNode(target, element, position);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tres.resolve((resolveTo === 'raw') ? html : element);\n\t\t\t\t}\n\t\t\t;\n\n\t\t\tcreateFetchRequest(url, options, useNative).execute()\n\t\t\t\t.then(response => {\n\t\t\t\t\tconst responseContentType = (\n\t\t\t\t\t\tresponse.headers.get('content-type') ?? response.headers.get('Content-Type') ?? ''\n\t\t\t\t\t).split(';')[0].trim();\n\t\t\t\t\tif( responseContentType !== contentType ){\n\t\t\t\t\t\tconst message = `${MODULE_NAME}:${__methodName__} | content-type \"${responseContentType}\" is not valid for HTML, expecting \"text/html\"`;\n\t\t\t\t\t\tif( strict ){\n\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\twarn(message);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn response.text();\n\t\t\t\t})\n\t\t\t\t.then(html => {\n\t\t\t\t\tconst\n\t\t\t\t\t\tisWholeDocument = html.includes(' {\n\t\t\t\t\t\t\t\thtml += element.outerHTML;\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tfInsertAndResolve(element, html);\n\t\t\t\t})\n\t\t\t\t.catch(error => {\n\t\t\t\t\tres.reject(error);\n\t\t\t\t})\n\t\t\t;\n\n\t\t\treturn res;\n\t\t}\n\t};\n}\n\n\n\n/**\n * @namespace Requests:visitUrl\n */\n\n/**\n * This function opens a given URL, using a dynamically created iframe, thereby opening the URL as if the user\n * him- or herself navigates to the URL using a browser window. Why should we do this you ask?\n *\n * For example: In session management, you'll sometimes have the case, that you need to trigger URLs on login or logout,\n * that construct or destruct parts of the session by creating of removing cookie or other client-storage items.\n * If that domain is part of a system running on another (sub)domain, using a usual client request for this will\n * not work, since the calling context of the request will have no access to the storage scope of that domain.\n *\n * So, to allow those domains to do their tasks, triggered from a different context, we can use this method to execute\n * those webhooks with the iframe, which natively runs in the called domains scope and therefore can do all necessary\n * domain-based storage actions.\n *\n * The big downside of this is, that we cannot really handle errors well this way. So if the URL returns a 404\n * or a 500, this will actually be treated as a resolved promise, since the iframe loaded. The only case a request\n * of this kind fails, is if the request runs into a timeout. So, for really critical actions, this way of handling\n * thing should be avoided in favour of an approach, that actually includes a postMessage implementation on the other\n * domain, to verify completion on load.\n *\n * @param {String} url - the URL to query, will be the current one if left empty\n * @param {?Number} [timeout=5000] - the timeout in ms to wait for completion of the request, before rejecting the promise\n * @param {?String} [tokenValue=null] - if the URL needs to include a token, you can provide this token here, which will replace the placeholder defined in \"tokenPlaceholder\"\n * @param {?String} [tokenPlaceholder='token'] = the placeholder in the url to replace with the tokenValue, must be surrounded with curly braces in the url (\"{token}\")\n * @returns {Basic.Deferred} resolves on load of URL (with the final URL as resolution value), rejects on timeout (with a \"timeout\" error)\n *\n * @memberof Requests:visitUrl\n * @alias visitUrl\n * @example\n * visitUrl('https://some.other.domain?token={token}', 2500, 'A38')\n * .then(() => { console.log('loaded!'); })\n * ;\n * visitUrl(\n * 'https://some.other.domain?token={session_value}',\n * 5000,\n * 'A38',\n * 'session_value'\n * )\n * .then(url => { console.log(`\"${url}\" loaded!`); })\n * .catch(error => { console.log(`${error.message} - URL did not load super fast, blimey!`); })\n * ;\n */\nexport function visitUrl(url, timeout=5000, tokenValue=null, tokenPlaceholder='token'){\n\turl = orDefault(url, '', 'str');\n\ttimeout = Math.abs(orDefault(timeout, 5000, 'int'));\n\ttokenValue = orDefault(tokenValue, null, 'str');\n\ttokenPlaceholder = orDefault(tokenPlaceholder, 'token', 'str');\n\turl = hasValue(tokenValue) ? url.replaceAll(`{${tokenPlaceholder}}`, tokenValue) : url;\n\n\tconst\n\t\tdeferred = new Deferred(),\n\t\touterNode = document.createElement('div')\n\t;\n\n\touterNode.innerHTML = `\n\t\t\n\t`.trim();\n\n\tconst\n\t\tiframe = outerNode.firstChild,\n\t\tfOnLoad = () => {\n\t\t\tiframe.removeEventListener('load', fOnLoad);\n\t\t\twindow.clearTimeout(loadTimeout);\n\t\t\t// we need to wait a bit after load before removing the iframe,\n\t\t\t// otherwise safari considers the request cancelled :(\n\t\t\twindow.setTimeout(() => {\n\t\t\t\tdocument.body.removeChild(iframe);\n\t\t\t\tdeferred.resolve(url);\n\t\t\t}, 250);\n\t\t},\n\t\tloadTimeout = window.setTimeout(() => {\n\t\t\tiframe.removeEventListener('load', fOnLoad);\n\t\t\tdocument.body.removeChild(iframe);\n\t\t\tdeferred.reject(new Error('timeout'));\n\t\t}, timeout)\n\t;\n\n\tiframe.addEventListener('load', fOnLoad);\n\tdocument.body.appendChild(iframe);\n\n\treturn deferred;\n}\n","/*!\n * Module Polyfills\n */\n\n/**\n * @namespace Polyfills\n */\n\nconst MODULE_NAME = 'Polyfills';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {assert, hasValue, isFunction, orDefault} from './basic.js';\nimport {createFetchRequest} from './requests.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Polyfills:polyfillFetch\n */\n\n/**\n * Polyfills window.fetch with a simple XMLHttpRequest-based implementation adapted from \"unfetch\", to provide\n * basic functionality with a compatible signature while keeping the source as small as possible.\n *\n * This polyfill should cover most basic use cases, but for complex cases you might need to polyfill something more\n * complete (for example Github's implementation: https://github.com/github/fetch).\n *\n * @param {?Boolean} [force=false] - if true, replaces a possibly present native implementation with the polyfill as well\n *\n * @memberof Polyfills:polyfillFetch\n * @alias polyfillFetch\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch\n * @see https://github.com/developit/unfetch\n * @example\n * polyfillFetch(true);\n */\nexport function polyfillFetch(force=false){\n\tforce = orDefault(force, false, 'bool');\n\n\tif( force || !isFunction(window.fetch) ){\n\t\twindow.fetch = function(url, options=null){\n\t\t\treturn createFetchRequest(url, options).execute();\n\t\t};\n\t}\n}\n\n\n\n/**\n * @namespace Polyfills:polyfillElementMatches\n */\n\n/**\n * Adds Element.matches support, if not already present in browser. Falls back to ms or mozilla implementations\n * if necessary.\n *\n * @throws error if Element.matches is not supported\n *\n * @memberof Polyfills:polyfillElementMatches\n * @alias polyfillElementMatches\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/matches\n * @example\n * polyfillElementMatches()\n * => makes Element.prototype.matches available, if not already present\n */\nexport function polyfillElementMatches(){\n\tconst __methodName__ = 'polyfillElementMatches';\n\n\tif( !Element.prototype.matches ){\n\t\tElement.prototype.matches = Element.prototype.msMatchesSelector\n\t\t\t?? Element.prototype.webkitMatchesSelector\n\t\t\t?? null\n\t\t;\n\t}\n\n\tassert(hasValue(Element.prototype.matches), `${MODULE_NAME}:${__methodName__} | browser does not support Element.matches`);\n}\n\n\n\n/**\n * @namespace Polyfills:polyfillCustomEvent\n */\n\n/**\n * Adds CustomEvent support, if not already present in browser. Falls back to manual implementation via\n * document.createEvent and event.initCustomEvent, if necessary.\n *\n * @memberof Polyfills:polyfillCustomEvent\n * @alias polyfillCustomEvent\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent\n * @example\n * polyfillCustomEvent()\n * => makes \"window.CustomEvent\" and \"new CustomEvent()\" available, if not already present\n */\nexport function polyfillCustomEvent(){\n\tif( isFunction(window.CustomEvent) ) return false;\n\n\tconst CustomEvent = function(event, params){\n\t\tparams = params ?? {bubbles : false, cancelable : false, detail : undefined};\n\t\tconst e = document.createEvent('CustomEvent');\n\t\te.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n\t\treturn e;\n\t};\n\tCustomEvent.prototype = window.Event.prototype;\n\n\twindow.CustomEvent = CustomEvent;\n}\n\n\n\n/**\n * @namespace Polyfills:polyfillArrayAt\n */\n\n/**\n * Adds support for Array.prototype.at, which is a fairly recent feature, compared to most other basic array\n * operations, resulting in even modern Chrome, Firefox and Safari versions not having implemented this.\n * But adding this is quite forward, it just being general array index access with possible negative index.\n *\n * @memberof Polyfills:polyfillArrayAt\n * @alias polyfillArrayAt\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at\n * @example\n * polyfillArrayAt()\n * => adds Array.prototype.at if not already defined\n */\nexport function polyfillArrayAt(){\n\tif( isFunction(Array.prototype.at) ) return false;\n\n\tObject.defineProperty(Array.prototype, 'at', {\n\t\tvalue : function(n){\n\t\t\tn = Math.trunc(n) || 0;\n\t\t\tif( n < 0 ) n += this.length;\n\t\t\tif( (n < 0) || (n >= this.length) ) return undefined;\n\t\t\treturn this[n];\n\t\t},\n\t\twritable : true,\n\t\tenumerable : false,\n\t\tconfigurable : true\n\t});\n}\n","/*!\n * Module Units\n */\n\n/**\n * @namespace Units\n */\n\nconst MODULE_NAME = 'Units';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {orDefault, assert, isNaN, isArray, round} from './basic.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const\n\tLOCAL_FLOAT_SEPARATOR = (0.1).toLocaleString().replace(/[0-9]/g, '').slice(0, 1),\n\tLOCAL_THOUSAND_SEPARATOR = (1000).toLocaleString().replace(/[0-9]/g, '').slice(0, 1)\n;\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Units:asFileSize\n */\n\n/**\n * Renders a byte number as a human-readable file size with the correct unit.\n *\n * Switch calculation base by setting useBinaryBase to true.\n * Today, file sizes are usually calculated against a decimal base of 1000, while in the\n * past, a binary base of 1024 was commonly used (and still is today by some software such as Microsoft Windows).\n * In 1998 the IEC standardized byte units to be metric in nature, which is the base assumption of this method.\n *\n * @param {Number} bytes - file size in bytes to render as string\n * @param {?String} [separator=LOCAL_FLOAT_SEPARATOR] - the character to separate the fraction in float numbers, will default to the current browser's default for local strings\n * @param {?Number} [precision=1] - the floating point precision to use for the size\n * @param {?Boolean} [useBinaryBase=false] - set to true to activate binary calculation and units\n * @returns {String} the formatted file size\n *\n * @memberof Units:asFileSize\n * @alias asFileSize\n * @see https://en.wikipedia.org/wiki/Kilobyte\n * @example\n * asFileSize(1_500_000, ',')\n * => '1,5 MB'\n * asFileSize(1024, '.', 0, true)\n * => '1 KiB'\n */\nexport function asFileSize(bytes, separator=LOCAL_FLOAT_SEPARATOR, precision=1, useBinaryBase=false){\n\tconst __methodName__ = 'asFileSize';\n\n\tbytes = parseInt(bytes, 10);\n\tassert(\n\t\t!isNaN(bytes) && (bytes >= 0),\n\t\t`${MODULE_NAME}:${__methodName__} | bytes not usable or negative`\n\t);\n\n\tseparator = orDefault(separator, LOCAL_FLOAT_SEPARATOR, 'str');\n\tprecision = orDefault(precision, 1, 'int');\n\n\tconst\n\t\tthresh = !!useBinaryBase ? 1024 : 1000,\n\t\tunits = !!useBinaryBase\n\t\t\t? ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB']\n\t\t\t: ['kB','MB','GB','TB','PB','EB','ZB','YB']\n\t;\n\n\tif( bytes < thresh ){\n\t\treturn `${bytes} B`;\n\t}\n\n\tlet unitIndex = -1;\n\tdo {\n\t\tbytes /= thresh;\n\t\tunitIndex++;\n\t} while(\n\t\t(bytes >= thresh)\n\t\t&& (unitIndex < (units.length - 1))\n\t);\n\n\tbytes = `${round(bytes, precision)}`.replace('.', separator);\n\treturn `${bytes} ${units[unitIndex]}`;\n}\n\n\n\n/**\n * @namespace Units:asCurrency\n */\n\n/**\n * Renders a number as a currency value, using native Intl.NumberFormat functionality.\n *\n * @param {Number} number - the number to use as a currency amount\n * @param {?String|Array} [locale='en-US'] - locale to use, use array to define fallback; always falls back to en-US if nothing else works\n * @param {?String} [currency='USD'] - a ISO4217 currency code, such as EUR for Euro\n * @param {?String} [currencyDisplay='symbol'] - one of \"symbol\", \"narrowSymbol\", \"code\" or \"name\", defining, how the currency should be displayed in the result\n * @returns {String} the formatted currency amount\n *\n * @memberof Units:asCurrency\n * @alias asCurrency\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat\n * @see https://en.wikipedia.org/wiki/ISO_4217#List_of_ISO_4217_currency_codes\n * @example\n * asCurrency(42.666)\n * => '42.67 $'\n * asCurrency(42.666, 'de-DE', 'EUR')\n * => '42,67 €'\n */\nexport function asCurrency(number, locale='en-US', currency='USD', currencyDisplay='symbol'){\n\tnumber = parseFloat(number);\n\n\tlocale = orDefault(locale, 'en-US');\n\tif(\n\t\t(!isArray(locale) && (locale !== 'en-US'))\n\t\t|| (isArray(locale) && !locale.includes('en-US'))\n\t){\n\t\tlocale = [].concat(locale).concat('en-US');\n\t}\n\n\tcurrency = orDefault(currency, 'USD', 'str');\n\tcurrencyDisplay = orDefault(currencyDisplay, 'symbol', 'str');\n\n\treturn new Intl.NumberFormat(\n\t\tlocale,\n\t\t{\n\t\t\tstyle : 'currency',\n\t\t\tcurrency,\n\t\t\tcurrencyDisplay,\n\t\t}\n\t).format(number);\n}\n\n\n\n/**\n * @namespace Units:asDecimal\n */\n\n/**\n * Renders a number as a decimal value, using native Intl.NumberFormat functionality.\n *\n * @param {Number} number - the number to use as a decimal amount\n * @param {?String|Array} [locale='en-US'] - locale to use, use array to define fallback; always falls back to en-US if nothing else works\n * @param {?Number} [minPrecision=2] - the minimal precision to use in decimal display\n * @param {?Number} [maxPrecision=null] - the minimal precision to use in decimal display; if nullish, will be set to minPrecision\n * @returns {String} the formatted decimal amount\n *\n * @memberof Units:asDecimal\n * @alias asDecimal\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat\n * @example\n * asDecimal(42.666)\n * => '42.67'\n * asDecimal(42.666, 'de-DE', 1)\n * => '42,7'\n */\nexport function asDecimal(number, locale='en-US', minPrecision=2, maxPrecision=null){\n\tnumber = parseFloat(number);\n\n\tlocale = orDefault(locale, 'en-US');\n\tif(\n\t\t(!isArray(locale) && (locale !== 'en-US'))\n\t\t|| (isArray(locale) && !locale.includes('en-US'))\n\t){\n\t\tlocale = [].concat(locale).concat('en-US');\n\t}\n\n\tminPrecision = orDefault(minPrecision, 2, 'int');\n\tmaxPrecision = orDefault(maxPrecision, minPrecision, 'int');\n\n\treturn new Intl.NumberFormat(\n\t\tlocale,\n\t\t{\n\t\t\tstyle : 'decimal',\n\t\t\tuseGrouping : false,\n\t\t\tminimumFractionDigits : minPrecision,\n\t\t\tmaximumFractionDigits : maxPrecision\n\t\t}\n\t).format(number);\n}\n","/*!\n * Module Dates\n */\n\n/**\n * @namespace Dates\n */\n\nconst MODULE_NAME = 'Dates';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {\n\thasValue,\n\tassert,\n\torDefault,\n\tisArray,\n\tisDate,\n\tisString,\n\tisNumber,\n\tisInt,\n\tisNaN,\n\tisObject,\n\tisPlainObject,\n\tisFunction\n} from './basic.js';\n\nimport {pad} from './strings.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst DATE_PART_SETTERS_AND_GETTERS = {\n\tlocal : {\n\t\tyear : {\n\t\t\tsetter : 'setFullYear',\n\t\t\tgetter : 'getFullYear'\n\t\t},\n\t\tmonth : {\n\t\t\tsetter : 'setMonth',\n\t\t\tgetter : 'getMonth',\n\t\t},\n\t\tdate : {\n\t\t\tsetter : 'setDate',\n\t\t\tgetter : 'getDate',\n\t\t},\n\t\thours : {\n\t\t\tsetter : 'setHours',\n\t\t\tgetter : 'getHours',\n\t\t},\n\t\tminutes : {\n\t\t\tsetter : 'setMinutes',\n\t\t\tgetter : 'getMinutes',\n\t\t},\n\t\tseconds : {\n\t\t\tsetter : 'setSeconds',\n\t\t\tgetter : 'getSeconds',\n\t\t},\n\t\tmilliseconds : {\n\t\t\tsetter : 'setMilliseconds',\n\t\t\tgetter : 'getMilliseconds',\n\t\t},\n\t},\n\tutc : {\n\t\tyear : {\n\t\t\tsetter : 'setUTCFullYear',\n\t\t\tgetter : 'getUTCFullYear',\n\t\t},\n\t\tmonth : {\n\t\t\tsetter : 'setUTCMonth',\n\t\t\tgetter : 'getUTCMonth',\n\t\t},\n\t\tdate : {\n\t\t\tsetter : 'setUTCDate',\n\t\t\tgetter : 'getUTCDate',\n\t\t},\n\t\thours : {\n\t\t\tsetter : 'setUTCHours',\n\t\t\tgetter : 'getUTCHours',\n\t\t},\n\t\tminutes : {\n\t\t\tsetter : 'setUTCMinutes',\n\t\t\tgetter : 'getUTCMinutes',\n\t\t},\n\t\tseconds : {\n\t\t\tsetter : 'setUTCSeconds',\n\t\t\tgetter : 'getUTCSeconds',\n\t\t},\n\t\tmilliseconds : {\n\t\t\tsetter : 'setUTCMilliseconds',\n\t\t\tgetter : 'getUTCMilliseconds',\n\t\t},\n\t}\n};\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Dates:format\n */\n\n/**\n * Returns a formatted string, describing the date in a verbose, non-technical way.\n *\n * Under the hood, this uses Intl.DateTimeFormat, which is widely supported and conveniently to use\n * for most widely used locales.\n *\n * \"definition\" may be a format shortcut for \"dateStyle\" (and \"timeStyle\" if type is \"datetime\") or a format string,\n * for a custom format, using these tokens:\n *\n * YY 18 two-digit year;\n * YYYY 2018 four-digit year;\n * M 1-12 the month, beginning at 1;\n * MM 01-12 the month, 2-digits;\n * D 1-31 the day of the month;\n * DD 01-31 the day of the month, 2-digits;\n * H 0-23 the hour;\n * HH 00-23 the hour, 2-digits;\n * h 1-12 the hour, 12-hour clock;\n * hh 01-12 the hour, 12-hour clock, 2-digits;\n * m 0-59 the minute;\n * mm 00-59 the minute, 2-digits;\n * s 0-59 the second;\n * ss 00-59 the second, 2-digits;\n * SSS 000-999 the millisecond, 3-digits;\n * Z +05:00 the offset from UTC, ±HH:mm;\n * ZZ +0500 the offset from UTC, ±HHmm;\n * A AM PM;\n * a am pm;\n *\n * Using these, you could create your own ISO string like this:\n * \"YYYY-MM-DDTHH:mm:ss.SSSZ\"\n *\n * If you use \"full\", \"long\", \"medium\" or \"short\" instead, you'll use the DateTimeFormatters built-in, preset\n * format styles for localized dates, based on the given locale(s).\n *\n * @param {Date} date - the date to format\n * @param {?String} [definition='long'] - either a preset style to quickly define a format style, by setting shortcuts for dateStyle and timeStyle (if type is \"datetime\"), set to \"none\" or nullish value to skip quick format; alternatively, define this as a format string to use a custom format\n * @param {?String|Array} [locale='en-US'] - locale to use for date format and text generation, use array to define fallback; always falls back to en-US if nothing else works\n * @param {?String} [type='datetime'] - set to 'datetime', 'date' or 'time' to define which parts should be rendered\n * @param {?Object} [options=null] - options to pass to the Intl.DateTimeFormat constructor, is applied last, so should override anything predefined, if key is reset\n * @returns {String} - the formatted date/time string\n *\n * @memberof Dates:format\n * @alias format\n * @variation Dates\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#style_shortcuts\n * @example\n * format(new Date(), 'de-DE', 'long', 'datetime', {timeZone : 'UTC'})\n * => '12. Dezember 2023 um 02:00:00 UTC'\n * format(new Date(), 'YYYY-MM-DDTHH:mm:ss.SSSZ')\n * => '2023-12-12T02:00:00'\n */\nexport function format(date, definition='long', locale='en-US', type='datetime', options=null){\n\tconst\n\t\tutc = (options?.timeZone === 'UTC'),\n\t\tsettersAndGetters = utc\n\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t,\n\t\tpredefinedStyles = ['full', 'long', 'medium', 'short', 'none']\n\t;\n\n\tif( hasValue(definition) && !predefinedStyles.includes(definition) ){\n\t\tlet timezone = '';\n\t\tconst offset = date.getTimezoneOffset();\n\t\tif( !utc && (offset !== 0) ){\n\t\t\tconst\n\t\t\t\thours = pad(Math.floor(Math.abs(offset) / 60), '0', 2),\n\t\t\t\tminutes = pad(Math.abs(offset) - (hours * 60), '0', 2)\n\t\t\t;\n\t\t\ttimezone = `${(offset < 0) ? '+' : '-'}${hours}:${minutes}`;\n\t\t}\n\n\t\tconst tokenMap = new Map();\n\t\ttokenMap.set('YYYY', `${date[settersAndGetters.year.getter]()}`);\n\t\ttokenMap.set('YY', `${date[settersAndGetters.year.getter]()}`.slice(-2));\n\t\ttokenMap.set('MM', pad(`${date[settersAndGetters.month.getter]() + 1}`, '0', 2));\n\t\ttokenMap.set('M', `${date[settersAndGetters.month.getter]() + 1}`);\n\t\ttokenMap.set('DD', pad(`${date[settersAndGetters.date.getter]()}`, '0', 2));\n\t\ttokenMap.set('D', `${date[settersAndGetters.date.getter]()}`);\n\t\ttokenMap.set('HH', pad(`${date[settersAndGetters.hours.getter]()}`, '0', 2));\n\t\ttokenMap.set('H', `${date[settersAndGetters.hours.getter]()}`);\n\t\ttokenMap.set('hh', pad(`${\n\t\t\t(date[settersAndGetters.hours.getter]() === 0)\n\t\t\t? 12\n\t\t\t: (\n\t\t\t\t(date[settersAndGetters.hours.getter]() > 12)\n\t\t\t\t? date[settersAndGetters.hours.getter]() - 12\n\t\t\t\t: date[settersAndGetters.hours.getter]()\n\t\t\t)\n\t\t}`, '0', 2));\n\t\ttokenMap.set('h', `${\n\t\t\t(date[settersAndGetters.hours.getter]() === 0)\n\t\t\t? 12\n\t\t\t: (\n\t\t\t\t(date[settersAndGetters.hours.getter]() > 12)\n\t\t\t\t? date[settersAndGetters.hours.getter]() - 12\n\t\t\t\t: date[settersAndGetters.hours.getter]()\n\t\t\t)\n\t\t}`);\n\t\ttokenMap.set('mm', pad(`${date[settersAndGetters.minutes.getter]()}`, '0', 2));\n\t\ttokenMap.set('m', `${date[settersAndGetters.minutes.getter]()}`);\n\t\ttokenMap.set('ss', pad(`${date[settersAndGetters.seconds.getter]()}`, '0', 2));\n\t\ttokenMap.set('s', `${date[settersAndGetters.seconds.getter]()}`);\n\t\ttokenMap.set('SSS', pad(`${date[settersAndGetters.milliseconds.getter]()}`, '0', 3));\n\t\ttokenMap.set('ZZ', timezone.replaceAll(':', ''));\n\t\ttokenMap.set('Z', timezone);\n\t\ttokenMap.set('A', `${(date[settersAndGetters.hours.getter]() >= 12) ? 'PM' : 'AM'}`);\n\t\ttokenMap.set('a', `${(date[settersAndGetters.hours.getter]() >= 12) ? 'pm' : 'am'}`);\n\n\t\tlet formattedDate = definition;\n\t\ttokenMap.forEach((value, token) => {\n\t\t\tformattedDate = formattedDate.replaceAll(token, value);\n\t\t});\n\n\t\treturn formattedDate;\n\t} else {\n\t\tlet formatterOptions = {};\n\n\t\tif( predefinedStyles.includes(definition) ){\n\t\t\tif( ['datetime', 'date'].includes(type) ){\n\t\t\t\tformatterOptions.dateStyle = definition;\n\t\t\t}\n\t\t\tif( ['datetime', 'time'].includes(type) ){\n\t\t\t\tformatterOptions.timeStyle = definition;\n\t\t\t}\n\t\t}\n\n\t\tlocale = orDefault(locale, 'en-US');\n\t\tif(\n\t\t\t(!isArray(locale) && (locale !== 'en-US'))\n\t\t\t|| (isArray(locale) && !locale.includes('en-US'))\n\t\t){\n\t\t\tlocale = [].concat(locale).concat('en-US');\n\t\t}\n\n\t\tformatterOptions = {\n\t\t\t...formatterOptions,\n\t\t\t...(options ?? {})\n\t\t};\n\n\t\treturn Intl.DateTimeFormat(locale, formatterOptions).format(date);\n\t}\n\n}\n\n\n\n/**\n * @namespace Dates:SaneDate\n **/\n\n/**\n * SaneDate is a reimplementation of JavaScript date objects, trying to iron out all the small fails\n * which make you want to pull your hair while keeping the cool stuff in a streamlined manner.\n *\n * SaneDates operate between the years 0 and 9999.\n * If you create a new SaneDate, it starts off in local mode, always working and returning local information, but\n * you may activate UTC mode by defining `.utc = true;`.\n *\n * Parsing an ISO string creates a local SaneDate if no timezone is defined, if you define \"Z\" or an offset, the\n * given string is interpreted as UTC info, so \"2012-12-12T12:00:00\" will set all parts as local information,\n * meaning, that the UTC representation may differ according to your timezone, while \"2012-12-12T12:00:00Z\" will\n * set all parts as UTC information, meaning that this is exactly what you get as the UTC representation, but your local\n * info will differ according to your timezone. \"2012-12-12T12:00:00+02:00\" on the other hand, will create UTC\n * information, with a negative offset of two hours, since this says: this datetime is two hours in the UTC future,\n * so the resulting UTC info will be at 10 o'clock, while your local info will behave according to your timezone in\n * regard to that info.\n *\n * The relevant date parts of a SaneDate, which are also available as attributes to get and set are:\n * \"year\", \"month\", \"date\" (not day!), \"hours\", \"minutes\", \"seconds\" and \"milliseconds\".\n *\n * Additionally, set UTC mode, using the \"utc\" property.\n *\n * SaneDates are very exception-happy and won't allow anything, that changes or produces a date in an unexpected\n * manner. All automagic behaviour of JS dates is an error here, so setting a month to 13 and expecting a year jump\n * will not work. Dates are very sensitive information and often used for contractual stuff, so anything coming out\n * differently than you defined it in the first place is very problematic. Every change to any single property triggers\n * a check, if any side effects occurred at all and if the change exactly results in the exact info being represented.\n * Any side effect or misrepresentation results in an exception, since something happened we did not expect or define.\n *\n * Months and week days are not zero based in SaneDates but begin with 1. Week days are not an attribute\n * (and not settable), but accessible via .getWeekDay().\n *\n * This whole implementation is heavily built around iso strings, so building a date with one and getting one\n * to transfer should be forgiving, easy and robust. Something like '1-2-3 4:5:6.7' is a usable iso string\n * for SaneDate, but getIsoString() will return correctly formatted '0001-02-03T04:05:06.700'.\n *\n * See class documentation below for details.\n *\n * @memberof Dates:SaneDate\n * @name SaneDate\n *\n * @see SaneDate\n * @example\n * let date = new SaneDate('1-2-3 4:5:6.7');\n * date = new SaneDate('2016-4-7');\n * date = new SaneDate('2016-04-07 13:37:00');\n * date = new SaneDate(2016, 4, 7);\n * date = new SaneDate(2016, 4, 7, 13, 37, 0, 999);\n * date.year = 2000;\n * date.forward('hours', 42);\n */\nclass SaneDate {\n\n\t#__className__ = 'SaneDate';\n\t#invalidDateMessage = 'invalid date, please check parameters - SaneDate only accepts values that result in a valid date, where the given value is reflected exactly (e.g.: setting hours to 25 will not work)';\n\t#paramInvalidOrOutOfRangeMessage = 'invalid or out of range';\n\t#date = null;\n\t#utc = false;\n\n\t/**\n\t * Creates a new SaneDate, either based on Date.now(), a given initial value or given date parts.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object} [initialValueOrYear=null] - something, that can be used to construct an initial value, this may be a vanilla Date, a SaneDate, a parsable string, a unix timestamp or an object implementing a method toISOString/toIsoString/getISOString/getIsoString; if this is a number, it will be treated as the year, if any other parameter is set as well; if nullish and all other parameters are not set either, the initial value is Date.now()\n\t * @param {?Number} [month=null] - month between 1 and 12, to set in initial value\n\t * @param {?Number} [date=null] - date between 1 and 31, to set in initial value\n\t * @param {?Number} [hours=null] - hours between 0 and 23, to set in initial value\n\t * @param {?Number} [minutes=null] - minutes between 0 and 59, to set in initial value\n\t * @param {?Number} [seconds=null] - seconds between 0 and 59, to set in initial value\n\t * @param {?Number} [milliseconds=null] - milliseconds between 0 and 999, to set in initial value\n\t * @throws error if created date is invalid\n\t */\n\tconstructor(initialValueOrYear=null, month=null, date=null, hours=null, minutes=null, seconds=null, milliseconds=null){\n\t\tconst __methodName__ = 'constructor';\n\n\t\tlet year = null;\n\t\tconst definedIndividualDateParts = {year, month, date, hours, minutes, seconds, milliseconds};\n\t\tlet hasDefinedIndividualDateParts = Object.values(definedIndividualDateParts).filter(part => isNumber(part)).length >= 1;\n\n\t\tif( initialValueOrYear instanceof SaneDate ){\n\t\t\tthis.#date = initialValueOrYear.getVanillaDate();\n\t\t} else if( isDate(initialValueOrYear) ){\n\t\t\tthis.#date = initialValueOrYear;\n\t\t} else if( isString(initialValueOrYear) ){\n\t\t\tthis.#date = this.#parseIsoString(initialValueOrYear);\n\t\t} else if( isNumber(initialValueOrYear) ){\n\t\t\tif( hasDefinedIndividualDateParts ){\n\t\t\t\tyear = parseInt(initialValueOrYear, 10);\n\t\t\t\tdefinedIndividualDateParts.year = year;\n\t\t\t} else {\n\t\t\t\tthis.#date = new Date(initialValueOrYear);\n\t\t\t}\n\t\t} else if(\n\t\t\tisObject(initialValueOrYear)\n\t\t\t&& (\n\t\t\t\tisFunction(initialValueOrYear.toISOString)\n\t\t\t\t|| isFunction(initialValueOrYear.toIsoString)\n\t\t\t\t|| isFunction(initialValueOrYear.getISOString)\n\t\t\t\t|| isFunction(initialValueOrYear.getIsoString)\n\t\t\t)\n\t\t){\n\t\t\tthis.#date = this.#parseIsoString(\n\t\t\t\tinitialValueOrYear.toISOString?.()\n\t\t\t\t?? initialValueOrYear.toIsoString?.()\n\t\t\t\t?? initialValueOrYear.getISOString?.()\n\t\t\t\t?? initialValueOrYear.getIsoString?.()\n\t\t\t);\n\t\t}\n\n\t\tif( !isDate(this.#date) ){\n\t\t\tthis.#date = hasDefinedIndividualDateParts ? new Date('1970-01-01T00:00:00.0') : new Date();\n\t\t}\n\n\t\tassert(\n\t\t\t!isNaN(this.#date.getTime()),\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#invalidDateMessage}`\n\t\t);\n\n\t\tthis.#createDatePartGettersAndSetters();\n\n\t\tif( hasDefinedIndividualDateParts ){\n\t\t\tObject.entries(definedIndividualDateParts)\n\t\t\t\t.filter(([_, value]) => isNumber(value))\n\t\t\t\t.forEach(([part, value]) => {\n\t\t\t\t\tthis[part] = value;\n\t\t\t\t})\n\t\t\t;\n\t\t}\n\t}\n\n\n\n\t/**\n\t * Creates getters and setters to leisurely access and change date properties by using property assignments\n\t * instead of method calls. This method provides most of the public interface of every SaneDate object.\n\t *\n\t * @private\n\t */\n\t#createDatePartGettersAndSetters(){\n\t\tconst propertyConfig = {\n\t\t\tenumerable : true\n\t\t};\n\n\t\t/**\n\t\t * @name SaneDate#utc\n\t\t * @property {Boolean} - defines if the date should behave as a UTC date instead of a local date (which is the default)\n\t\t */\n\t\tObject.defineProperty(this, 'utc', {\n\t\t\t...propertyConfig,\n\t\t\tset(utc){\n\t\t\t\tthis.#utc = !!utc;\n\t\t\t},\n\t\t\tget(){\n\t\t\t\treturn this.#utc;\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#year\n\t\t * @property {Number} - the date's year in the range of 0 to 9999\n\t\t */\n\t\tObject.defineProperty(this, 'year', {\n\t\t\t...propertyConfig,\n\t\t\tset(year){\n\t\t\t\tconst __methodName__ = 'set year';\n\n\t\t\t\tyear = parseInt(year, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(year)\n\t\t\t\t\t&& (year >= 0 && year <= 9999),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | year ${this.#paramInvalidOrOutOfRangeMessage} (0...9999)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('year', year);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.year.getter]();\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#month\n\t\t * @property {Number} - the date's month in the range of 1 to 12\n\t\t */\n\t\tObject.defineProperty(this, 'month', {\n\t\t\t...propertyConfig,\n\t\t\tset(month){\n\t\t\t\tconst __methodName__ = 'set month';\n\n\t\t\t\tmonth = parseInt(month, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(month)\n\t\t\t\t\t&& (month >= 1 && month <= 12),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | month ${this.#paramInvalidOrOutOfRangeMessage} (1...12)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('month', month - 1);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.month.getter]() + 1;\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#date\n\t\t * @property {Number} - the date's day of the month in the range of 1 to 31\n\t\t */\n\t\tObject.defineProperty(this, 'date', {\n\t\t\t...propertyConfig,\n\t\t\tset(date){\n\t\t\t\tconst __methodName__ = 'set date';\n\n\t\t\t\tdate = parseInt(date, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(date)\n\t\t\t\t\t&& (date >= 1 && date <= 31),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | date ${this.#paramInvalidOrOutOfRangeMessage} (1...31)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('date', date);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.date.getter]();\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#hours\n\t\t * @property {Number} - the date's hours in the range of 0 to 23\n\t\t */\n\t\tObject.defineProperty(this, 'hours',{\n\t\t\tset(hours){\n\t\t\t\tconst __methodName__ = 'set hours';\n\n\t\t\t\thours = parseInt(hours, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(hours)\n\t\t\t\t\t&& (hours >= 0 && hours <= 23),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | hours ${this.#paramInvalidOrOutOfRangeMessage} (0...23)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('hours', hours);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.hours.getter]();\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#minutes\n\t\t * @property {Number} - the date's minutes in the range of 0 to 59\n\t\t */\n\t\tObject.defineProperty(this, 'minutes', {\n\t\t\tset(minutes){\n\t\t\t\tconst __methodName__ = 'set hours';\n\n\t\t\t\tminutes = parseInt(minutes, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(minutes)\n\t\t\t\t\t&& (minutes >= 0 && minutes <= 59),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | minutes ${this.#paramInvalidOrOutOfRangeMessage} (0...59)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('minutes', minutes);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.minutes.getter]();\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#seconds\n\t\t * @property {Number} - the date's seconds in the range of 0 to 59\n\t\t */\n\t\tObject.defineProperty(this, 'seconds', {\n\t\t\tset(seconds){\n\t\t\t\tconst __methodName__ = 'set seconds';\n\n\t\t\t\tseconds = parseInt(seconds, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(seconds)\n\t\t\t\t\t&& (seconds >= 0 && seconds <= 59),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | seconds ${this.#paramInvalidOrOutOfRangeMessage} (0...59)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('seconds', seconds);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.seconds.getter]();\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * @name SaneDate#milliseconds\n\t\t * @property {Number} - the date's milliseconds in the range of 0 to 999\n\t\t */\n\t\tObject.defineProperty(this, 'milliseconds', {\n\t\t\tset(milliseconds){\n\t\t\t\tconst __methodName__ = 'set milliseconds';\n\n\t\t\t\tmilliseconds = parseInt(milliseconds, 10);\n\t\t\t\tassert(\n\t\t\t\t\tisInt(milliseconds)\n\t\t\t\t\t&& (milliseconds >= 0 && milliseconds <= 999),\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | milliseconds ${this.#paramInvalidOrOutOfRangeMessage} (0...999)`\n\t\t\t\t);\n\n\t\t\t\tthis.#tryDatePartChange('milliseconds', milliseconds);\n\t\t\t},\n\t\t\tget(){\n\t\t\t\tconst settersAndGetters = this.#utc\n\t\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t\t;\n\t\t\t\treturn this.#date[settersAndGetters.milliseconds.getter]();\n\t\t\t}\n\t\t});\n\t}\n\n\n\n\t/**\n\t * Returns the current day of the week as a number between 1 and 7 or an english day name.\n\t * This method counts days the European way, starting with monday, but you can change this\n\t * behaviour using the first parameter (if your week starts with sunday or friday for example).\n\t *\n\t * @param {?String} [startingWith='monday'] - set to the english day, which is the first day of the week (monday, tuesday, wednesday, thursday, friday, saturday, sunday)\n\t * @param {?Boolean} [asName=false] - set to true, if you'd like the method to return english day names instead of an index\n\t * @returns {Number|String} weekday index between 1 and 7 or english name of the day\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * if( d.getWeekDay() == 5 ){\n\t * alert(`Thank god it's ${d.getWeekday(null, true)}!`);\n\t * }\n\t */\n\tgetWeekDay(startingWith='monday', asName=false){\n\t\tconst __methodName__ = 'getWeekDay';\n\n\t\tconst weekdays = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];\n\t\tstartingWith = orDefault(startingWith, weekdays[1], 'str');\n\t\tassert(\n\t\t\tweekdays.includes(startingWith),\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | unknown weekday \"${startingWith}\"`\n\t\t);\n\n\t\tlet day = this.#utc ? this.#date.getUTCDay() : this.#date.getDay();\n\t\tif( asName ) return weekdays[day];\n\n\t\tconst offset = day - weekdays.indexOf(startingWith);\n\t\tif( offset < 0 ){\n\t\t\tday = 7 + offset;\n\t\t} else {\n\t\t\tday = offset;\n\t\t}\n\n\t\treturn day + 1;\n\t}\n\n\n\n\t/**\n\t * Returns the date's current timezone, like it would occur in an ISO-string (\"Z\", \"+06:00\", \"-02:30\").\n\t *\n\t * If you need the raw offset, use the vanilla date's getTimezoneOffset() method.\n\t *\n\t * @returns {String} - the timezone string\n\t *\n\t * @example\n\t * const d = new SaneDate()\n\t * d.getTimezone()\n\t * => \"+09:30\"\n\t */\n\tgetTimezone(){\n\t\tif( this.#utc ) return 'Z';\n\n\t\tconst offset = this.#date.getTimezoneOffset();\n\n\t\tif( offset === 0 ){\n\t\t\treturn 'Z';\n\t\t} else {\n\t\t\tconst\n\t\t\t\thours = this.#padWithZero(Math.floor(Math.abs(offset) / 60), 2),\n\t\t\t\tminutes = this.#padWithZero(Math.abs(offset) - (hours * 60), 2)\n\t\t\t;\n\t\t\treturn `${(offset < 0) ? '+' : '-'}${hours}:${minutes}`;\n\t\t}\n\t}\n\n\n\n\t/**\n\t * Returns the representation of the date's current date parts (year, month, day) as an ISO-string.\n\t *\n\t * A difference to the vanilla implementation is, that this method respects UTC mode and does not always\n\t * coerce the date to UTC automatically. So, this will return a local ISO representation if not in UTC mode\n\t * and the UTC representation in UTC mode.\n\t *\n\t * @returns {String} date ISO-string of the format \"2016-04-07\"\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * thatDatePicker.setValue(d.getIsoDateString());\n\t */\n\tgetIsoDateString(){\n\t\tconst\n\t\t\tyear = this.#padWithZero(this.year, 4),\n\t\t\tmonth = this.#padWithZero(this.month, 2),\n\t\t\tdate = this.#padWithZero(this.date, 2)\n\t\t;\n\n\t\treturn `${year}-${month}-${date}`;\n\t}\n\n\n\n\t/**\n\t * Returns the representation of the date's current time parts (hours, minutes, seconds, milliseconds) as an\n\t * ISO-string.\n\t *\n\t * A difference to the vanilla implementation is, that this method respects UTC mode and does not always\n\t * coerce the date to UTC automatically. So, this will return a local ISO representation (optionally with\n\t * timezone information in relation to UTC) if not in UTC mode and the UTC representation in UTC mode.\n\t *\n\t * @param {?Boolean} [withTimezone=true] - defines if the ISO string should end with timezone information, such as \"Z\" or \"+02:00\"\n\t * @returns {String} time ISO-string of the format \"12:59:00.123Z\"\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * thatDatePicker.setValue(`2023-12-12T${d.getIsoTimeString()}`);\n\t */\n\tgetIsoTimeString(withTimezone=true){\n\t\twithTimezone = orDefault(withTimezone, true, 'bool');\n\n\t\tconst\n\t\t\thours = this.#padWithZero(this.hours, 2),\n\t\t\tminutes = this.#padWithZero(this.minutes, 2),\n\t\t\tseconds = this.#padWithZero(this.seconds, 2),\n\t\t\tmilliseconds = this.#padWithZero(this.milliseconds, 3),\n\t\t\ttimezone = this.getTimezone()\n\t\t;\n\n\t\treturn `${hours}:${minutes}:${seconds}${(milliseconds > 0) ? '.'+milliseconds : ''}${withTimezone ? timezone : ''}`;\n\t}\n\n\n\n\t/**\n\t * Returns the date as an ISO-string.\n\t *\n\t * A difference to the vanilla implementation is, that this method respects UTC mode and does not always\n\t * coerce the date to UTC automatically. So, this will return a local ISO representation (optionally with\n\t * timezone information in relation to UTC) if not in UTC mode and the UTC representation in UTC mode.\n\t *\n\t * @param {?Boolean} [withSeparator=true] - defines if date and time should be separated with a \"T\"\n\t * @param {?Boolean} [withTimezone=true] - defines if the ISO string should end with timezone information, such as \"Z\" or \"+02:00\"\n\t * @returns {String} ISO-string of the format \"2016-04-07T13:37:00.222Z\"\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * thatDateTimePicker.setValue(d.getIsoString());\n\t */\n\tgetIsoString(withSeparator=true, withTimezone=true){\n\t\twithSeparator = orDefault(withSeparator, true, 'bool');\n\n\t\treturn `${this.getIsoDateString()}${withSeparator ? 'T' : ' '}${this.getIsoTimeString(withTimezone)}`;\n\t}\n\n\n\n\t/**\n\t * Returns a formatted string, describing the current date in a verbose, human-readable, non-technical way.\n\t *\n\t * \"definition\" may be a format shortcut for \"dateStyle\" (and \"timeStyle\" if type is \"datetime\") or a format string,\n\t * for a custom format, using these tokens:\n\t *\n\t * YY 18 two-digit year;\n\t * YYYY 2018 four-digit year;\n\t * M 1-12 the month, beginning at 1;\n\t * MM 01-12 the month, 2-digits;\n\t * D 1-31 the day of the month;\n\t * DD 01-31 the day of the month, 2-digits;\n\t * H 0-23 the hour;\n\t * HH 00-23 the hour, 2-digits;\n\t * h 1-12 the hour, 12-hour clock;\n\t * hh 01-12 the hour, 12-hour clock, 2-digits;\n\t * m 0-59 the minute;\n\t * mm 00-59 the minute, 2-digits;\n\t * s 0-59 the second;\n\t * ss 00-59 the second, 2-digits;\n\t * SSS 000-999 the millisecond, 3-digits;\n\t * Z +05:00 the offset from UTC, ±HH:mm;\n\t * ZZ +0500 the offset from UTC, ±HHmm;\n\t * A AM PM;\n\t * a am pm;\n\t *\n\t * Using these, you could create your own ISO string like this:\n\t * \"YYYY-MM-DDTHH:mm:ss.SSSZ\"\n\t *\n\t * If you use \"full\", \"long\", \"medium\" or \"short\" instead, you'll use the DateTimeFormatters built-in, preset\n\t * format styles for localized dates, based on the given locale(s).\n\t *\n\t * @param {?String} [definition='long'] - either a preset style to quickly define a format style, by setting shortcuts for dateStyle and timeStyle (if type is \"datetime\"), set to \"none\" or nullish value to skip quick format; alternatively, define this as a format string to use a custom format\n\t * @param {?String|Array} [locale='en-US'] - locale to use for date format and text generation, use array to define fallback; always falls back to en-US if nothing else works\n\t * @param {?String} [type='datetime'] - set to 'datetime', 'date' or 'time' to define which parts should be rendered\n\t * @param {?Object} [options=null] - options to pass to the Intl.DateTimeFormat constructor, is applied last, so should override anything predefined, if key is reset\n\t * @returns {String} - the formatted date/time string\n\t *\n\t * @see format(Dates)\n\t * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat\n\t * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#style_shortcuts\n\t * @example\n\t * const d = new SaneDate();\n\t * d.format('de-DE', 'long', 'datetime', {timeZone : 'UTC'})\n\t * => '12. Dezember 2023 um 02:00:00 UTC'\n\t * d.format('YYYY-MM-DDTHH:mm:ss.SSSZ')\n\t * => '2023-12-12T02:00:00'\n\t */\n\tformat(definition='long', locale='en-US', type='datetime', options=null){\n\t\toptions = orDefault(options, {});\n\n\t\tif( !hasValue(options.timeZone) && this.#utc ){\n\t\t\toptions.timeZone = 'UTC';\n\t\t}\n\n\t\treturn format(this.#date, definition, locale, type, options);\n\t}\n\n\n\n\t/**\n\t * Return the current original JavaScript date object wrapped by SaneDate.\n\t * Use this to do special things.\n\t *\n\t * @returns {Date} the original JavaScript date object\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * const timezoneOffset = d.getVanillaDate().getTimezoneOffset();\n\t */\n\tgetVanillaDate(){\n\t\treturn this.#date;\n\t}\n\n\n\n\t/**\n\t * Compares the date to another date in terms of placement on the time axis.\n\t *\n\t * Returns a classical comparator value (-1/0/1), being -1 if the date is earlier than the parameter.\n\t * Normally checks date and time. Set type to \"date\" to only check date.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object|SaneDate} initialValueOrSaneDate - anything compatible to the SaneDate constructor or a SaneDate instance\n\t * @param {?String} [type='datetime'] - either \"datetime\" or \"date\", telling the method if time should be considered\n\t * @param {?Boolean} [withMilliseconds=true] - tells the method if milliseconds should be considered if type is \"datetime\"\n\t * @throws error if compare date is not usable\n\t * @returns {Number} -1 if this date is smaller/earlier, 0 if identical, 1 if this date is bigger/later\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * if( d.compareTo('2016-04-07', 'date') === 0 ){\n\t * alert('congratulations, that\\'s the same date!');\n\t * }\n\t */\n\tcompareTo(initialValueOrSaneDate, type='datetime', withMilliseconds=true){\n\t\ttype = orDefault(type, 'datetime', 'string');\n\t\twithMilliseconds = orDefault(withMilliseconds, true, 'bool');\n\n\t\tconst\n\t\t\tsaneDate = new SaneDate(initialValueOrSaneDate),\n\t\t\tdateCompareGetters = [\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.year.getter,\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.month.getter,\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.date.getter,\n\t\t\t],\n\t\t\ttimeCompareGetters = [\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.hours.getter,\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.minutes.getter,\n\t\t\t\tDATE_PART_SETTERS_AND_GETTERS.utc.seconds.getter,\n\t\t\t],\n\t\t\tmillisecondsCompareGetter = DATE_PART_SETTERS_AND_GETTERS.utc.milliseconds.getter\n\t\t;\n\n\t\tlet compareGetters = [].concat(dateCompareGetters);\n\t\tif( type === 'datetime' ){\n\t\t\tcompareGetters = compareGetters.concat(timeCompareGetters);\n\t\t\tif( withMilliseconds ){\n\t\t\t\tcompareGetters = compareGetters.concat(millisecondsCompareGetter);\n\t\t\t}\n\t\t}\n\n\t\tlet ownValue, compareValue, comparator;\n\t\tfor( const compareGetter of compareGetters ){\n\t\t\townValue = this.#date[compareGetter]();\n\t\t\tcompareValue = saneDate.getVanillaDate()[compareGetter]();\n\t\t\tcomparator = (ownValue < compareValue)\n\t\t\t\t? -1\n\t\t\t\t: ((ownValue > compareValue) ? 1 : 0)\n\t\t\t;\n\n\t\t\tif( comparator !== 0 ){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn comparator;\n\t}\n\n\n\n\t/**\n\t * Returns if the SaneDate is earlier on the time axis than the comparison value.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object|SaneDate} initialValueOrSaneDate - anything compatible to the SaneDate constructor or a SaneDate instance\n\t * @param {?String} [type='datetime'] - either \"datetime\" or \"date\", telling the method if time should be considered\n\t * @param {?Boolean} [withMilliseconds=true] - tells the method if milliseconds should be considered if type is \"datetime\"\n\t * @throws error if compare date is not usable\n\t * @returns {Boolean} true if SaneDate is earlier than compare value\n\t *\n\t * @example\n\t * const now = new SaneDate();\n\t * const theFuture = now.clone().forward({days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5});\n\t * now.isBefore(theFuture)\n\t * => true\n\t * theFuture.isBefore(now)\n\t * => false\n\t */\n\tisBefore(initialValueOrSaneDate, type='datetime', withMilliseconds=true){\n\t\treturn this.compareTo(initialValueOrSaneDate, type, withMilliseconds) === -1;\n\t}\n\n\n\n\t/**\n\t * Returns if the SaneDate is later on the time axis than the comparison value.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object|SaneDate} initialValueOrSaneDate - anything compatible to the SaneDate constructor or a SaneDate instance\n\t * @param {?String} [type='datetime'] - either \"datetime\" or \"date\", telling the method if time should be considered\n\t * @param {?Boolean} [withMilliseconds=true] - tells the method if milliseconds should be considered if type is \"datetime\"\n\t * @throws error if compare date is not usable\n\t * @returns {Boolean} true if SaneDate is later than compare value\n\t *\n\t * @example\n\t * const now = new SaneDate();\n\t * const theFuture = now.clone().forward({days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5});\n\t * now.isAfter(theFuture)\n\t * => false\n\t * theFuture.isAfter(now)\n\t * => true\n\t */\n\tisAfter(initialValueOrSaneDate, type='datetime', withMilliseconds=true){\n\t\treturn this.compareTo(initialValueOrSaneDate, type, withMilliseconds) === 1;\n\t}\n\n\n\n\t/**\n\t * Returns if the SaneDate is at the same time as comparison value.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object|SaneDate} initialValueOrSaneDate - anything compatible to the SaneDate constructor or a SaneDate instance\n\t * @param {?String} [type='datetime'] - either \"datetime\" or \"date\", telling the method if time should be considered\n\t * @param {?Boolean} [withMilliseconds=true] - tells the method if milliseconds should be considered if type is \"datetime\"\n\t * @throws error if compare date is not usable\n\t * @returns {Boolean} true if SaneDate is at the same time as compare value\n\t *\n\t * @example\n\t * const now = new SaneDate();\n\t * const theFuture = now.clone();\n\t * now.isSame(theFuture)\n\t * => true\n\t * theFuture.forward({days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5});\n\t * theFuture.isSame(now)\n\t * => false\n\t */\n\tisSame(initialValueOrSaneDate, type='datetime', withMilliseconds=true){\n\t\treturn this.compareTo(initialValueOrSaneDate, type, withMilliseconds) === 0;\n\t}\n\n\n\n\t/**\n\t * Move the date a defined offset to the past or the future.\n\t *\n\t * @param {String|Object} part - the name of the date part to change, one of \"years\", \"months\", \"days\", \"hours\", \"minutes\", \"seconds\" and \"milliseconds\" or a dictionary of part/amount pairs ({hours : -1, seconds : 30})\n\t * @param {?Number} [amount=0] - negative or positive integer defining the offset from the current date\n\t * @throws error on invalid part name\n\t * @returns {SaneDate} the SaneDate instance\n\t *\n\t * @example\n\t * let d = new SaneDate();\n\t * d = d.move('years', 10).move('milliseconds', -1);\n\t */\n\tmove(part, amount=0){\n\t\tconst __methodName__ = 'move;'\n\n\t\tamount = orDefault(amount, 0, 'int');\n\n\t\tconst\n\t\t\tsettersAndGetters = DATE_PART_SETTERS_AND_GETTERS.utc,\n\t\t\tparts = ['years', 'months', 'days', 'hours', 'minutes', 'seconds', 'milliseconds']\n\t\t;\n\t\tlet partDict = {};\n\n\t\tif( !isPlainObject(part) ){\n\t\t\tpartDict[part] = amount;\n\t\t} else {\n\t\t\tpartDict = part;\n\t\t}\n\n\t\tObject.keys(partDict).forEach(part => {\n\t\t\tassert(\n\t\t\t\tparts.includes(part),\n\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | part must be one of ${parts.join(', ')}, is \"${part}\"`\n\t\t\t);\n\t\t});\n\n\t\tObject.entries(partDict).forEach(([part, amount]) => {\n\t\t\tswitch( part ){\n\t\t\t\tcase 'years':\n\t\t\t\t\tthis.#date[settersAndGetters.year.setter](this.#date[settersAndGetters.year.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'months':\n\t\t\t\t\tthis.#date[settersAndGetters.month.setter](this.#date[settersAndGetters.month.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'days':\n\t\t\t\t\tthis.#date[settersAndGetters.date.setter](this.#date[settersAndGetters.date.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'hours':\n\t\t\t\t\tthis.#date[settersAndGetters.hours.setter](this.#date[settersAndGetters.hours.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'minutes':\n\t\t\t\t\tthis.#date[settersAndGetters.minutes.setter](this.#date[settersAndGetters.minutes.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'seconds':\n\t\t\t\t\tthis.#date[settersAndGetters.seconds.setter](this.#date[settersAndGetters.seconds.getter]() + amount);\n\t\t\t\tbreak;\n\n\t\t\t\tcase 'milliseconds':\n\t\t\t\t\tthis.#date[settersAndGetters.milliseconds.setter](this.#date[settersAndGetters.milliseconds.getter]() + amount);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Moves the date's time forward a certain offset.\n\t *\n\t * @param {String|Object} part - the name of the date part to change, one of \"years\", \"months\", \"days\", \"hours\", \"minutes\", \"seconds\" and \"milliseconds\" or a dictionary of part/amount pairs ({hours : 1, seconds : 30})\n\t * @param {?Number} [amount=0] - integer defining the positive offset from the current date, negative value is treated as an error\n\t * @throws error on invalid part name or negative amount\n\t * @returns {SaneDate} the SaneDate instance\n\t *\n\t * @example\n\t * let d = new SaneDate();\n\t * d = d.forward('hours', 8);\n\t */\n\tforward(part, amount=0){\n\t\tconst\n\t\t\t__methodName__ = 'forward',\n\t\t\tamountMustBePositiveMessage = 'amount must be >= 0'\n\t\t;\n\n\t\tpart = `${part}`;\n\t\tamount = orDefault(amount, 0, 'int');\n\n\t\tlet partDict = {};\n\t\tif( !isPlainObject(part) ){\n\t\t\tassert(\n\t\t\t\tamount >= 0,\n\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${amountMustBePositiveMessage}`\n\t\t\t);\n\t\t\tpartDict[part] = amount;\n\t\t} else {\n\t\t\tpartDict = part;\n\t\t\tObject.entries(partDict).forEach(([part, amount]) => {\n\t\t\t\tamount = parseInt(amount, 10);\n\t\t\t\tassert(\n\t\t\t\t\tamount >= 0,\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${amountMustBePositiveMessage}`\n\t\t\t\t);\n\t\t\t\tpartDict[part] = amount;\n\t\t\t});\n\t\t}\n\n\t\treturn this.move(partDict);\n\t}\n\n\n\n\t/**\n\t * Moves the date's time backward a certain offset.\n\t *\n\t * @param {String|Object} part - the name of the date part to change, one of \"years\", \"months\", \"days\", \"hours\", \"minutes\", \"seconds\" and \"milliseconds\" or a dictionary of part/amount pairs ({hours : 1, seconds : 30})\n\t * @param {?Number} [amount=0] - integer defining the negative offset from the current date, negative value is treated as an error\n\t * @throws error on invalid part name or negative amount\n\t * @returns {SaneDate} the SaneDate instance\n\t *\n\t * @example\n\t * let d = new SaneDate();\n\t * d = d.backward('years', 1000);\n\t */\n\tbackward(part, amount=0){\n\t\tconst\n\t\t\t__methodName__ = 'backward',\n\t\t\tamountMustBePositiveMessage = 'amount must be >= 0'\n\t\t;\n\n\t\tpart = `${part}`;\n\t\tamount = orDefault(amount, 0, 'int');\n\n\t\tlet partDict = {};\n\t\tif( !isPlainObject(part) ){\n\t\t\tassert(\n\t\t\t\tamount >= 0,\n\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${amountMustBePositiveMessage}`\n\t\t\t);\n\t\t\tpartDict[part] = (amount === 0) ? 0 : -amount;\n\t\t} else {\n\t\t\tpartDict = part;\n\t\t\tObject.entries(partDict).forEach(([part, amount]) => {\n\t\t\t\tassert(\n\t\t\t\t\tamount >= 0,\n\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${amountMustBePositiveMessage}`\n\t\t\t\t);\n\t\t\t\tpartDict[part] = (amount === 0) ? 0 : -amount;\n\t\t\t});\n\t\t}\n\n\t\treturn this.move(partDict);\n\t}\n\n\n\n\t/**\n\t * Calculates a time delta between the SaneDate and a comparison value.\n\t *\n\t * The result is a plain object with the delta's units up to the defined \"largestUnit\". All values are integers.\n\t * The largest unit is days, since above neither months nor years are calculable via a fixed divisor and therefore\n\t * useless (since month vary from 28 to 31 days and years vary between 365 and 366 days, so both are not a fixed\n\t * unit).\n\t *\n\t * By default, the order does not matter and only the absolute value is used, but you can change this\n\t * through the parameter \"relative\", which by setting this to true, will include \"-\", if the comparison value\n\t * is in the future.\n\t *\n\t * @param {?Date|SaneDate|String|Number|Object|SaneDate} initialValueOrSaneDate - anything compatible to the SaneDate constructor or a SaneDate instance\n\t * @param {?String} [largestUnit='days'] - the largest time unit to differentiate in the result\n\t * @param {?Boolean} [relative=false] - if true, returns negative values if first parameter is later than this date (this adheres to the order defined by compareTo)\n\t * @throws error on unknown largestUnit or incompatible comparison value\n\t * @returns {Object} time delta object in the format {days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5} (keys depending on largestUnit)\n\t *\n\t * @example\n\t * const now = new SaneDate();\n\t * const theFuture = now.clone().forward({days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5});\n\t * now.getDelta(theFuture)\n\t * => {days : 1, hours : 2, minutes : 3, seconds : 4, milliseconds : 5}\n\t * now.getDelta(theFuture, 'hours', true)\n\t * => {hours : -26, minutes : -3, seconds : -4, milliseconds : -5}\n\t */\n\tgetDelta(initialValueOrSaneDate, largestUnit='days', relative=false){\n\t\tconst __methodName__ = 'getDelta';\n\n\t\tconst saneDate = new SaneDate(initialValueOrSaneDate);\n\t\tlargestUnit = orDefault(largestUnit, 'days', 'string');\n\t\tassert(\n\t\t\t['days', 'hours', 'minutes', 'seconds', 'milliseconds'].includes(largestUnit),\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | unknown largest unit`\n\t\t);\n\t\trelative = orDefault(relative, false, 'bool');\n\n\t\tconst parts = {};\n\t\tlet delta = relative\n\t\t\t? (this.#date.getTime() - saneDate.#date.getTime())\n\t\t\t: Math.abs(this.#date.getTime() - saneDate.#date.getTime())\n\t\t;\n\t\tconst negativeDelta = delta < 0;\n\t\tdelta = Math.abs(delta);\n\n\t\tif( largestUnit === 'days' ){\n\t\t\tparts.days = Math.floor(delta / 1000 / 60 / 60 / 24);\n\t\t\tdelta -= parts.days * 1000 * 60 * 60 * 24;\n\t\t\tlargestUnit = 'hours';\n\t\t}\n\n\t\tif( largestUnit === 'hours' ){\n\t\t\tparts.hours = Math.floor(delta / 1000 / 60 / 60);\n\t\t\tdelta -= parts.hours * 1000 * 60 * 60;\n\t\t\tlargestUnit = 'minutes';\n\t\t}\n\n\t\tif( largestUnit === 'minutes' ){\n\t\t\tparts.minutes = Math.floor(delta / 1000 / 60);\n\t\t\tdelta -= parts.minutes * 1000 * 60;\n\t\t\tlargestUnit = 'seconds';\n\t\t}\n\n\t\tif( largestUnit === 'seconds' ){\n\t\t\tparts.seconds = Math.floor(delta / 1000);\n\t\t\tdelta -= parts.seconds * 1000;\n\t\t\tlargestUnit = 'milliseconds';\n\t\t}\n\n\t\tif( largestUnit === 'milliseconds' ){\n\t\t\tparts.milliseconds = delta;\n\t\t}\n\n\t\tif( negativeDelta ){\n\t\t\tfor( const partName in parts ){\n\t\t\t\tparts[partName] = (parts[partName] === 0) ? 0 : -parts[partName];\n\t\t\t}\n\t\t}\n\n\t\treturn parts;\n\t}\n\n\n\n\t/**\n\t * Returns a copy of the current SaneDate.\n\t * Might be very handy for creating dates based on another with an offset for example.\n\t * Keeps UTC mode.\n\t *\n\t * @returns {SaneDate} copy of current SaneDate instance\n\t *\n\t * @example\n\t * const d = new SaneDate();\n\t * const theFuture = d.clone().forward('hours', 8);\n\t **/\n\tclone(){\n\t\tconst clonedSaneDate = new SaneDate(new Date(this.getVanillaDate().getTime()));\n\t\tclonedSaneDate.utc = this.#utc;\n\t\treturn clonedSaneDate;\n\t}\n\n\n\n\t/**\n\t * Adds leading zeroes to values, which are not yet of a defined expected length.\n\t *\n\t * @param {*} value - the value to pad\n\t * @param {?Number} [digitCount=2] - the number of digits, the result has to have at least\n\t * @returns {String} the padded value, will always be cast to a string\n\t *\n\t * @private\n\t * @example\n\t * this.#padWithZero(1, 4)\n\t * => '0001'\n\t */\n\t#padWithZero(value, digitCount=2){\n\t\treturn pad(value, '0', digitCount);\n\t}\n\n\n\n\t/**\n\t * Tries to parse an ISO string (or at least, something resembling an ISO string) into a date.\n\t *\n\t * The basic idea of this method is, that it is supposed to be fairly forgiving, as long as the info is there,\n\t * even in a little wonky notation, this should result in a successfully created SaneDate.\n\t *\n\t * @param {String} isoString - something resembling an ISO string, that we can create a date from\n\t * @throws error if isoString is not usable\n\t * @returns {Date} the date create from the given ISO string\n\t *\n\t * @private\n\t * @example\n\t * this.#parseIsoString('2018-02-28T13:37:00')\n\t * this.#parseIsoString('1-2-3 4:5:6.7')\n\t */\n\t#parseIsoString(isoString){\n\t\tconst\n\t\t\t__methodName__ = '#parseIsoString',\n\t\t\tunparsableIsoStringMessage = 'ISO string not parsable'\n\t\t;\n\n\t\tisoString = `${isoString}`;\n\n\t\tlet\n\t\t\tyear = 1970,\n\t\t\tmonth = 1,\n\t\t\tdate = 1,\n\t\t\thours = 0,\n\t\t\tminutes = 0,\n\t\t\tseconds = 0,\n\t\t\tmilliseconds = 0,\n\t\t\ttimezoneOffset = 0,\n\t\t\tutc = false\n\t\t;\n\n\t\tlet isoStringParts = isoString.split('T');\n\t\tif( isoStringParts.length === 1 ){\n\t\t\tisoStringParts = isoStringParts[0].split(' ');\n\t\t}\n\n\n\t\t// date parts\n\n\t\tconst isoStringDateParts = isoStringParts[0].split('-');\n\t\tyear = isoStringDateParts[0];\n\t\tif( isoStringDateParts.length >= 2 ){\n\t\t\tmonth = isoStringDateParts[1];\n\t\t}\n\t\tif( isoStringDateParts.length >= 3 ){\n\t\t\tdate = isoStringDateParts[2];\n\t\t}\n\n\n\t\t// time parts\n\n\t\tif( isoStringParts.length >= 2 ){\n\t\t\t// timezone\n\n\t\t\tlet\tisoStringTimezoneParts = isoStringParts[1].split('Z');\n\t\t\tif( isoStringTimezoneParts.length >= 2 ){\n\t\t\t\tutc = true;\n\t\t\t} else {\n\t\t\t\tlet offsetFactor = 0;\n\t\t\t\tif( isoStringTimezoneParts[0].includes('+') ){\n\t\t\t\t\toffsetFactor = -1;\n\t\t\t\t\tisoStringTimezoneParts = isoStringTimezoneParts[0].split('+');\n\t\t\t\t} else if( isoStringTimezoneParts[0].includes('-') ){\n\t\t\t\t\toffsetFactor = 1;\n\t\t\t\t\tisoStringTimezoneParts = isoStringTimezoneParts[0].split('-');\n\t\t\t\t}\n\n\t\t\t\tif( isoStringTimezoneParts.length >= 2 ){\n\t\t\t\t\tconst isoStringTimezoneTimeParts = isoStringTimezoneParts[1].split(':');\n\n\t\t\t\t\tif( isoStringTimezoneTimeParts.length >= 2 ){\n\t\t\t\t\t\ttimezoneOffset += parseInt(isoStringTimezoneTimeParts[0], 10) * 60;\n\t\t\t\t\t\ttimezoneOffset += parseInt(isoStringTimezoneTimeParts[1], 10);\n\t\t\t\t\t} else if( isoStringTimezoneTimeParts[0].length >= 3 ){\n\t\t\t\t\t\ttimezoneOffset += parseInt(isoStringTimezoneTimeParts[0].slice(0, 2), 10) * 60;\n\t\t\t\t\t\ttimezoneOffset += parseInt(isoStringTimezoneTimeParts[1].slice(2), 10);\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttimezoneOffset += parseInt(isoStringTimezoneTimeParts[0], 10) * 60;\n\t\t\t\t\t}\n\t\t\t\t\ttimezoneOffset *= offsetFactor;\n\n\t\t\t\t\tassert(\n\t\t\t\t\t\t!isNaN(timezoneOffset),\n\t\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | invalid timezone \"${isoStringTimezoneParts[1]}\"`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\t// hours and minutes\n\t\t\tconst isoStringTimeParts = isoStringTimezoneParts[0].split(':');\n\t\t\thours = isoStringTimeParts[0];\n\t\t\tif( isoStringTimeParts.length >= 2 ){\n\t\t\t\tminutes = isoStringTimeParts[1];\n\t\t\t}\n\n\n\t\t\t// seconds and milliseconds\n\n\t\t\tif( isoStringTimeParts.length >= 3 ){\n\t\t\t\tconst isoStringSecondsParts = isoStringTimeParts[2].split('.');\n\n\t\t\t\tseconds = isoStringSecondsParts[0];\n\n\t\t\t\tif( isoStringSecondsParts.length >= 2 ){\n\t\t\t\t\tmilliseconds = isoStringSecondsParts[1];\n\n\t\t\t\t\tif( milliseconds.length > 3 ){\n\t\t\t\t\t\tmilliseconds = milliseconds.slice(0, 3);\n\t\t\t\t\t} else if( milliseconds.length === 2 ){\n\t\t\t\t\t\tmilliseconds = `${parseInt(milliseconds, 10) * 10}`;\n\t\t\t\t\t} else if( milliseconds.length === 1 ){\n\t\t\t\t\t\tmilliseconds = `${parseInt(milliseconds, 10) * 100}`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\n\t\t// date construction\n\n\t\tconst saneDate = new SaneDate();\n\t\tsaneDate.utc = utc || (timezoneOffset !== 0);\n\t\ttry {\n\t\t\tsaneDate.year = year;\n\t\t\tsaneDate.month = month;\n\t\t\tsaneDate.date = date;\n\t\t\tsaneDate.hours = hours;\n\t\t\tsaneDate.minutes = minutes;\n\t\t\tsaneDate.seconds = seconds;\n\t\t\tsaneDate.milliseconds = milliseconds;\n\t\t} catch(ex){\n\t\t\tthrow Error(`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${unparsableIsoStringMessage} \"${isoString}\"`);\n\t\t}\n\t\tsaneDate.move('minutes', timezoneOffset);\n\n\t\treturn saneDate.getVanillaDate();\n\t}\n\n\n\n\t/**\n\t * Tries to change a part of the date and makes sure, that this change does not trigger automagic and only\n\t * leads to exactly the change, we wanted to do and nothing else.\n\t *\n\t * @param {String} part - the date part to change, one of: year, month, date, hours, minutes, seconds or milliseconds\n\t * @param {Number} value - the new value to set\n\t * @returns {SaneDate} the SaneDate instance\n\t *\n\t * @private\n\t */\n\t#tryDatePartChange(part, value){\n\t\tconst __methodName__ = '#tryDatePartChange';\n\n\t\tconst\n\t\t\tnewDate = this.clone().getVanillaDate(),\n\t\t\tsettersAndGetters = this.#utc\n\t\t\t\t? DATE_PART_SETTERS_AND_GETTERS.utc\n\t\t\t\t: DATE_PART_SETTERS_AND_GETTERS.local\n\t\t\t,\n\t\t\tallDatePartGetters = Object.values(settersAndGetters).map(methods => methods.getter)\n\t\t;\n\n\t\tnewDate[settersAndGetters[part].setter](value);\n\n\t\tlet sideEffect = false;\n\t\tfor( const datePartGetter of allDatePartGetters ){\n\t\t\tif( datePartGetter !== settersAndGetters[part].getter){\n\t\t\t\tsideEffect ||= this.#date[datePartGetter]() !== newDate[datePartGetter]();\n\t\t\t}\n\n\t\t\tif( sideEffect ){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tassert(\n\t\t\t(newDate[settersAndGetters[part].getter]() === value) && !sideEffect,\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | date part change \"${part} = ${value}\" is invalid or has side effects`\n\t\t);\n\n\t\tthis.#date = newDate;\n\n\t\treturn this;\n\t}\n\n}\n\nexport {SaneDate};\n","/*!\n * Module Polling\n */\n\n/**\n * @namespace Polling\n */\n\nconst MODULE_NAME = 'Polling';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {orDefault, isFunction, isObject, assert, hasValue} from './basic.js';\nimport {loop, countermand} from './timers.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const POLLS = {\n\tdefaultLoop : null,\n\tactivePollCount : 0,\n\tactivePolls : {}\n};\n\nconst POLL_DEFAULT_LOOP_MS = 250;\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Polling:poll\n */\n\n/**\n * Waits for a certain program- or DOM-state before executing a certain action. Waiting is implemented via\n * a global timer (and optionally locals as well). If you need to react to a certain case, that's not\n * defined by standard events and reaction does not have to be razor sharp, this is your method.\n * Pick a name for the state/event you want to poll, define a condition closure and an action closure that\n * holds what is to be done in case the condition works out.\n * Polls end or are repeated after an execution of the action depending on the result of the action closure.\n * There can always be only one poll of a certain name, redefining it overwrites the first one.\n *\n * If you need to evaluate a poll out of the line, to trigger a sharp synchronous evaluation due to an event\n * for example, you can use the \"fire\" method of the poll object itself, which will trigger the condition and all\n * subsequent actions. You can provide a boolean parameter to this function to override manually if the result\n * should be considered changed to the last run. You can only fire polls, that are still active, you can check this\n * state easily via \"isActive\" on the poll.\n *\n * @param {String} name - name of the state or event you are waiting/polling for\n * @param {Function} fCondition - closure to define the state to wait for, returns true if state exists and false if not\n * @param {Function} fAction - closure to define action to take place if condition is fulfilled, poll removes itself if this evaluates to true, receives Boolean parameter defining if condition result has changed since last call\n * @param {?Function} [fElseAction=null] - closure to define action to take place if condition is not fulfilled, receives Boolean parameter defining if condition result has changed since last call\n * @param {?Number} [newLoopMs=250] - sets interval length from here on, resets global loop if useOwnTimer is not set, otherwise sets local interval for that poll poll\n * @param {?Boolean} [useOwnTimer=false] - has to be true to tell the poll to use an independent local timer instead of the global one, use this if you need different levels of fuzziness for you polls, performance-wise it's better to have less independent intervals running\n * @throws error in case name, fCondition or fAction are missing or unfit to use\n * @returns {Object} new poll - structure: {name, condition, action, elseAction, loop, lastPollResult, isActive, fire()}\n *\n * @memberof Polling:poll\n * @alias poll\n * @see unpoll\n * @example\n * const pollBodyHeightPermanently = poll('permanent-body-height-poll', function(){ return document.body.scrollHeight > 1000; }, function(changed){ console.log(`too high${changed ? ' as of yet' : ''}!`); }, null, 5000);\n * const pollBodyHeightAndStopIfHighEnough = poll('one-time-body-height-poll', function(){ return document.body.scrollHeight > 1000; }, function(){ console.log('high enough!'); return true; }, function(){ console.log('not high enough yet :(') }, null, true);\n */\nexport function poll(name, fCondition, fAction, fElseAction=null, newLoopMs=POLL_DEFAULT_LOOP_MS, useOwnTimer=false){\n\tname = orDefault(name, '', 'str').trim();\n\tfElseAction = isFunction(fElseAction) ? fElseAction : () => {};\n\tnewLoopMs = orDefault(newLoopMs, POLL_DEFAULT_LOOP_MS, 'int');\n\tuseOwnTimer = orDefault(useOwnTimer, false, 'bool');\n\n\tassert(name !== '', `${MODULE_NAME}:poll | name is missing`);\n\tassert(isFunction(fCondition), `${MODULE_NAME}:poll | fCondition is not a function`);\n\tassert(isFunction(fAction), `${MODULE_NAME}:poll | fAction is not a function`);\n\n\tconst newPoll = {\n\t\tname,\n\t\tcondition: fCondition,\n\t\taction : fAction,\n\t\telseAction : fElseAction,\n\t\tloop : null,\n\t\tlastPollResult : false,\n\t\tisActive : true,\n\t\tfire(changed=null){\n\t\t\tif( hasValue(POLLS.activePolls[newPoll.name]) ){\n\t\t\t\tif( newPoll.condition() ){\n\t\t\t\t\tif( newPoll.action(hasValue(changed) ? !!changed : (newPoll.lastPollResult === false)) === true ){\n\t\t\t\t\t\tif( hasValue(newPoll.loop) ){\n\t\t\t\t\t\t\tcountermand(newPoll.loop);\n\t\t\t\t\t\t\tnewPoll.loop = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnewPoll.isActive = false;\n\t\t\t\t\t\tdelete POLLS.activePolls[newPoll.name];\n\t\t\t\t\t\tPOLLS.activePollCount--;\n\t\t\t\t\t}\n\t\t\t\t\tnewPoll.lastPollResult = true;\n\t\t\t\t} else {\n\t\t\t\t\tnewPoll.elseAction(hasValue(changed) ? !!changed : (newPoll.lastPollResult === true));\n\t\t\t\t\tnewPoll.lastPollResult = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tif( useOwnTimer ){\n\t\tnewPoll.loop = loop(newLoopMs, function(){\n\t\t\tnewPoll.fire();\n\t\t});\n\t}\n\n\tif( hasValue(POLLS.activePolls[name]) ){\n\t\tunpoll(name);\n\t}\n\tPOLLS.activePolls[name] = newPoll;\n\tPOLLS.activePollCount++;\n\n\tif(\n\t\t(\n\t\t\t!hasValue(POLLS.defaultLoop)\n\t\t\t|| ((newLoopMs !== POLL_DEFAULT_LOOP_MS) && !useOwnTimer)\n\t\t)\n\t\t&& (POLLS.activePollCount > 0)\n\t){\n\t\tif( hasValue(POLLS.defaultLoop) ){\n\t\t\tcountermand(POLLS.defaultLoop);\n\t\t}\n\n\t\tPOLLS.defaultLoop = loop(newLoopMs, function(){\n\t\t\tif( POLLS.activePollCount > 0 ){\n\t\t\t\tfor( let name in POLLS.activePolls ){\n\t\t\t\t\tif( POLLS.activePolls.hasOwnProperty(name) ){\n\t\t\t\t\t\tconst poll = POLLS.activePolls[name];\n\t\t\t\t\t\tif( !hasValue(poll.loop) ){\n\t\t\t\t\t\t\tpoll.fire();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcountermand(POLLS.defaultLoop);\n\t\t\t\tPOLLS.defaultLoop = null;\n\t\t\t}\n\t\t});\n\t}\n\n\treturn newPoll;\n}\n\n\n\n/**\n * @namespace Polling:unpoll\n */\n\n/**\n * Removes an active poll.\n *\n * @param {String|Object} poll - name of the poll to be removed or the poll object itself\n * @returns {Boolean} true if poll has been removed, false if poll has not been found\n *\n * @memberof Polling:unpoll\n * @alias unpoll\n * @see poll\n * @example\n * unpoll('permanent-body-height-poll');\n * unpoll(pollBodyHeightAndStopIfHighEnough);\n */\nexport function unpoll(poll){\n\tconst name = (isObject(poll) && hasValue(poll.name)) ? `${poll.name}` : `${poll}`.trim();\n\tif( name === '' ) return false;\n\n\tpoll = POLLS.activePolls[name];\n\tif( !hasValue(poll) ) return false;\n\n\tif( hasValue(poll.loop) ){\n\t\tcountermand(poll.loop);\n\t}\n\n\tpoll.isActive = false;\n\tdelete POLLS.activePolls[poll.name];\n\tPOLLS.activePollCount--;\n\n\tif( POLLS.activePollCount <= 0 ){\n\t\tcountermand(POLLS.defaultLoop);\n\t\tPOLLS.defaultLoop = null;\n\t\tPOLLS.activePollCount = 0;\n\t}\n\n\treturn true;\n}\n","/*!\n * Module Forms\n */\n\n/**\n * @namespace Forms\n */\n\nconst MODULE_NAME = 'Forms';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {isFunction, isPlainObject, hasValue} from './basic.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Forms:formDataToObject\n */\n\n/**\n * Constructs a plain object from an existing FormData object or a given form element.\n *\n * The idea of this function is, to make working with form data easier in programmatic contexts by allowing operations\n * like optional chaining and \"in\" operators. This might especially come in handy if you need to do programmatic\n * validations.\n *\n * Additionally, this function streamlines field names, by discarding PHP-style array field name conventions like\n * \"files[]\", by removing the brackets. So, if you have a field named \"files[]\" and another field named \"files\",\n * both will just end up in one \"files\"-field, having an array as a value containing all combined values.\n *\n * Keep in mind, that the status of form fields in a form matters when retrieving FormData from a form element.\n * Disabled fields will not be included for example. Make sure to handle this before using the data.\n *\n * On Internet Explorers, this function needs a polyfill, which is not included in annex, due to its size and\n * complexity, since IEs, while supporting FormData basically, are lacking all functions to access values of an existing\n * FormData object, thereby making it impossible to iterate its values.\n *\n * @param {FormData|HTMLFormElement} formDataOrForm - either an existing FormData object or a form, from which we can retrieve formdata\n * @returns {Object} plain object, containing all form values based on the exisiting fields as key/value-pairs\n *\n * @memberof Forms:formDataToObject\n * @alias formDataToObject\n * @see objectToFormData\n * @see https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData\n * @see https://github.com/jimmywarting/FormData\n * @example\n * const formData = new FormData();\n * formData.append('secrethash', 123456789);\n * formData.append('firstname', 'Paul');\n * formData.append('lastname', 'Atreides');\n * formData.append('houses', 'Atreides');\n * formData.append('houses', 'Fremen');\n * formData.append('houses', 'Corrino');\n * formData.append('diary', new File(['Dear Diary, ...'], 'diary.txt', {type : 'text/plain', lastModified : new Date()}));\n * formData.append('instagramPage', new Blob(['...'], {type : 'text/html'}));\n * formDataToObject(formData)\n * =>\n * {\n * secrethash : '123456789',\n * \t firstname : 'Paul',\n * \t lastname : 'Atreides',\n * \t houses : ['Atreides', 'Fremen', 'Corrino'],\n * \t diary : File,\n * \t instagramPage : Blob\n * }\n */\nexport function formDataToObject(formDataOrForm){\n\tlet formData;\n\n\t// let's do duck-typing to allow polyfills\n\tif(\n\t\tisFunction(formDataOrForm.append)\n\t\t&& isFunction(formDataOrForm.getAll)\n\t\t&& isFunction(formDataOrForm.entries)\n\t){\n\t\tformData = formDataOrForm;\n\t} else {\n\t\ttry {\n\t\t\tformData = new FormData(formDataOrForm);\n\t\t} catch(ex){\n\t\t\tformData = null;\n\t\t}\n\t}\n\n\tif( !hasValue(formData) ) return null;\n\n\tconst formDataObject = {};\n\n\tArray.from(formData.entries()).forEach(([key, values]) => {\n\t\tif( key.endsWith('[]') ){\n\t\t\tkey = key.slice(0, -2);\n\t\t}\n\t\tvalues = [].concat(values);\n\n\t\tif( !hasValue(formDataObject[key]) ){\n\t\t\tformDataObject[key] = (values.length === 1) ? values[0] : values;\n\t\t} else {\n\t\t\tformDataObject[key] = [].concat(formDataObject[key], values);\n\t\t}\n\t});\n\n\treturn formDataObject;\n}\n\n\n\n/**\n * @namespace Forms:objectToFormData\n */\n\n/**\n * Constructs a FormData object, to be used in requests, from a given (plain) object, iterating its entries.\n *\n * Additionally, this function streamlines field names, by discarding PHP-style array field name conventions like\n * \"files[]\", by removing the brackets. So, if you have a field named \"files[]\" and another field named \"files\",\n * both will just end up in one \"files\"-field.\n *\n * Files and Blobs can be provided as-is (constructed programmatically of retrieved from file inputs via `.files`).\n * Alternatively (and if you manually want to define the filename), you can provide plain objects to describe a File or\n * Blob to add to the FormData:\n * - use {file : File, ?name : String} to add \"file\" as a File and optionally set \"name\" to define a filename, taking\n * precedence over what is already defined in the File object itself\n * - use {blob : Blob|String, ?name : String, ?mimeType : String} to add \"blob\" as a Blob (if this is a string, it\n * will be treated as the content of a new Blob), optionally using \"name\" as the filename (I'd recommend to set this)\n * and optionally setting the file type via the MIME type defined in \"mimeType\".\n *\n * In contrast to `formDataToObject`, this function does not need a polyfill in Internet Explorer, since it only uses\n * the FormData constructor and the `.append()` method, which are both supported.\n *\n * @param {Object} formDataObject - object to iterate, to create FormData based on its entries\n * @returns {FormData} FormData object to be used in a request\n *\n * @memberof Forms:objectToFormData\n * @alias objectToFormData\n * @see formDataToObject\n * @see https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData\n * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types\n * @example\n * const formData = objectToFormData({\n * secrethash : 123456789,\n * \t firstname : 'Paul',\n * \t lastname : 'Atreides',\n * \t houses : ['Atreides', 'Fremen', 'Corrino'],\n * \t diary : {file : new File(['Dear Diary, ...'], 'diary.txt', {type : 'text/plain', lastModified : new Date()})},\n * \t instagramPage : {blob : '...', name : 'instagram.html', mimeType : 'text/html'},\n * }).getAll('houses');\n * => ['Atreides', 'Fremen', 'Corrino']\n */\nexport function objectToFormData(formDataObject){\n\tconst formData = new FormData();\n\n\tObject.entries(formDataObject).forEach(([fieldName, fieldValue]) => {\n\t\tif( fieldName.endsWith('[]') ){\n\t\t\tfieldName = fieldName.slice(0, -2);\n\t\t}\n\n\t\t[].concat(fieldValue).forEach(fieldValue => {\n\t\t\tif( isPlainObject(fieldValue) ){\n\t\t\t\tif( hasValue(fieldValue.file) && (fieldValue.file instanceof File) ){\n\t\t\t\t\tformData.append(\n\t\t\t\t\t\tfieldName,\n\t\t\t\t\t\tfieldValue.file,\n\t\t\t\t\t\thasValue(fieldValue.name) ? `${fieldValue.name}` : undefined\n\t\t\t\t\t);\n\t\t\t\t} else if( hasValue(fieldValue.blob) ){\n\t\t\t\t\tconst blob = (fieldValue.blob instanceof Blob)\n\t\t\t\t\t\t? fieldValue.blob\n\t\t\t\t\t\t: new Blob(\n\t\t\t\t\t\t\t[`${fieldValue.blob}`],\n\t\t\t\t\t\t\thasValue(fieldValue.mimeType) ? {type : `${fieldValue.mimeType}`} : undefined\n\t\t\t\t\t\t)\n\t\t\t\t\t;\n\n\t\t\t\t\tformData.append(\n\t\t\t\t\t\tfieldName,\n\t\t\t\t\t\tblob,\n\t\t\t\t\t\thasValue(fieldValue.name) ? `${fieldValue.name}` : undefined\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tformData.append(fieldName, `${fieldValue}`);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tformData.append(fieldName, fieldValue);\n\t\t\t}\n\t\t});\n\t});\n\n\treturn formData;\n}\n","/*!\n * Module Animation\n */\n\n/**\n * @namespace Animation\n */\n\nconst MODULE_NAME = 'Animation';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {hasValue, isPlainObject, isEmpty, isNaN, isElement, orDefault, assert, Deferred} from './basic.js';\nimport {warn} from './logging.js';\nimport {pschedule, countermand, waitForRepaint} from './timers.js';\nimport {applyStyles} from './css.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst RUNNING_TRANSITIONS = new WeakMap();\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Animation:EasingFunctions\n */\n\n/**\n * A collection of all basic easing functions to be used in animations.\n * All functions here take a float parameter between 0 and 1 and return a mapped value between 0 and 1.\n *\n * Taken from: https://gist.github.com/gre/1650294\n *\n * Available functions:\n * - linear\n * - easeInQuad\n * - easeOutQuad\n * - easeInOutQuad\n * - easeInCubic\n * - easeOutCubic\n * - easeInOutCubic\n * - easeInQuart\n * - easeOutQuart\n * - easeInOutQuart\n * - easeInQuint\n * - easeOutQuint\n * - easeInOutQuint\n *\n * @memberof Animation:EasingFunctions\n * @alias EasingFunctions\n * @example\n * scrollTo(window, 1000, 0, EasingFunctions.easeInOutQuint);\n */\nexport const EasingFunctions = {\n\t// no easing, no acceleration\n\tlinear : t => t,\n\t// accelerating from zero velocity\n\teaseInQuad : t => t*t,\n\t// decelerating to zero velocity\n\teaseOutQuad : t => t*(2-t),\n\t// acceleration until halfway, then deceleration\n\teaseInOutQuad : t => t<.5 ? 2*t*t : -1+(4-2*t)*t,\n\t// accelerating from zero velocity\n\teaseInCubic : t => t*t*t,\n\t// decelerating to zero velocity\n\teaseOutCubic : t => (--t)*t*t+1,\n\t// acceleration until halfway, then deceleration\n\teaseInOutCubic : t => t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1,\n\t// accelerating from zero velocity\n\teaseInQuart : t => t*t*t*t,\n\t// decelerating to zero velocity\n\teaseOutQuart : t => 1-(--t)*t*t*t,\n\t// acceleration until halfway, then deceleration\n\teaseInOutQuart : t => t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t,\n\t// accelerating from zero velocity\n\teaseInQuint : t => t*t*t*t*t,\n\t// decelerating to zero velocity\n\teaseOutQuint : t => 1+(--t)*t*t*t*t,\n\t// acceleration until halfway, then deceleration\n\teaseInOutQuint : t => t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t\n};\n\n\n\n/**\n * @namespace Animation:transition\n */\n\n/**\n * This method offers the possibility to apply CSS transitions via classes and/or styles and wait for the transition\n * to finish, which results in the resolution of a Deferred.\n *\n * In general, this method remedies the pain of having to manage transitions manually in JS, entering precise ms for\n * timers waiting on conclusion of transitions.\n *\n * The general principle of this is the parsing of transition CSS attributes, which may contain transition\n * timings (transition and transition-duration) and looks for the longest currently running transition.\n * Values are excepted as milliseconds or seconds (int or float notation).\n *\n * Why would you do this, if there is something like the `animationend` event, you ask? Well, the problem is, that,\n * if the animation is interrupted or never finishes for any other reason, the event never fires. For that, there is\n * the `animationcancel` event, but that is not really robustly supported at the moment. So, in cases of complex\n * style changes, where we definitively want to have a callback when the animation has been (or would have been)\n * finished, this is still the safer option. But, for simple and small cases I'd strongly recommend using the native\n * `AnimationEvent` API.\n *\n * Calling this method successively on the same element replaces the currently running transition, normally\n * resulting in premature resolution of the Deferred and application of the newly provided changes.\n *\n * Be advised, that legacy browsers like IE11 and Edge <= 18 have problems connecting interrupted transitions,\n * especially when transition-durations change during animation, resulting in skipped or choppy animations. If you\n * experience this, try to keep timings stable during animation and chain animations without overlap.\n *\n * @param {Element} element - the element to transition, by applying class and/or style changes\n * @param {?Object} [classChanges=null] - plain object containing class changes to apply, add classes via the \"add\" key, remove them via the \"remove\" key (add has precedence over remove); values may be standard CSS class string notation or an array of standard CSS class notations\n * @param {?Object} [styleChanges=null] - plain object containing style changes to apply (via applyStyles)\n * @param {?Boolean} [rejectOnInterruption=false] - if a new transition is applied using this function while a previous transition is still running the Deferred would normally be resolved before continuing, set this to true to let the Deferred reject in that case (the rejection message is \"interrupted\", access the element using \"element)\n * @return {Basic.Deferred} resolves on transition completion or repeated call on the same element, with the resolution value being the element, rejects on repeated call on same element if rejectOnInterruption is true (the rejection message is \"interrupted\", access the element using \"element\")\n *\n * @memberof Animation:transition\n * @alias transition\n * @see applyStyles\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/animationend_event\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/animationcancel_event\n * @example\n * transition(element, {add : 'foobar'}).then(element => { return transition(element, {remove : 'foobar'}); }).then(() => { console.log('finished'); });\n * transition(element, null, {top : 0, left : 0, background : 'pink', transition : 'all 1500ms'}).then(() => { console.log('finished'); });\n * transition(element, {add : 'foobar'}).then(() => { console.log('finished'); }).catch(error => { console.log('cancelled'); });\n */\nexport function transition(element, classChanges=null, styleChanges=null, rejectOnInterruption=false){\n\tconst __methodName__ = 'cssTransition';\n\n\tclassChanges = orDefault(classChanges, {});\n\tstyleChanges = orDefault(styleChanges, {});\n\trejectOnInterruption = orDefault(rejectOnInterruption, false, 'bool');\n\n\tassert(isElement(element), `${MODULE_NAME}:${__methodName__} | element is not usable`);\n\tassert(isPlainObject(classChanges), `${MODULE_NAME}:${__methodName__} | classChanges is not a plain object`);\n\tassert(isPlainObject(styleChanges), `${MODULE_NAME}:${__methodName__} | styleChanges is not a plain object`);\n\n\tconst\n\t\tdeferred = new Deferred(),\n\t\trunningTransition = RUNNING_TRANSITIONS.get(element)\n\t;\n\n\tif( hasValue(runningTransition) ){\n\t\tcountermand(runningTransition.timer);\n\t\tif( !rejectOnInterruption ){\n\t\t\trunningTransition.deferred.resolve(element);\n\t\t} else {\n\t\t\tconst error = new Error('interrupted');\n\t\t\terror.element = element;\n\t\t\trunningTransition.deferred.reject(error);\n\t\t}\n\t}\n\tRUNNING_TRANSITIONS.delete(element);\n\n\tconst\n\t\ttransitionDurationProperties = [\n\t\t\t'transition-duration',\n\t\t\t'-webkit-transition-duration',\n\t\t\t'-moz-transition-duration',\n\t\t\t'-o-transition-duration'\n\t\t],\n\t\ttransitionProperties = [\n\t\t\t'transition',\n\t\t\t'-webkit-transition',\n\t\t\t'-moz-transition',\n\t\t\t'-o-transition'\n\t\t],\n\t\ttimingProperties = [\n\t\t\t...transitionDurationProperties,\n\t\t\t...transitionProperties\n\t\t],\n\t\ttransitionDefinition = {\n\t\t\tproperty : null,\n\t\t\tvalue : null\n\t\t}\n\t;\n\n\tif( !isEmpty(styleChanges) ){\n\t\tlet vendorPropertiesAdded;\n\t\t[transitionDurationProperties, transitionProperties].forEach(properties => {\n\t\t\tvendorPropertiesAdded = false;\n\t\t\tproperties.forEach(property => {\n\t\t\t\tconst transitionValue = styleChanges[property];\n\t\t\t\tif( !vendorPropertiesAdded && hasValue(transitionValue) ){\n\t\t\t\t\tvendorPropertiesAdded = true;\n\t\t\t\t\tproperties.forEach(property => {\n\t\t\t\t\t\tstyleChanges[property] = transitionValue;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tapplyStyles(element, styleChanges);\n\t}\n\n\tif( !isEmpty(classChanges?.remove) ){\n\t\t[].concat(classChanges.remove).forEach(removeClass => {\n\t\t\t`${removeClass}`.split(' ').forEach(removeClass => {\n\t\t\t\telement.classList.remove(removeClass.trim());\n\t\t\t});\n\t\t});\n\t}\n\n\tif( !isEmpty(classChanges?.add) ){\n\t\t[].concat(classChanges.add).forEach(addClass => {\n\t\t\t`${addClass}`.split(' ').forEach(addClass => {\n\t\t\t\telement.classList.add(addClass.trim());\n\t\t\t});\n\t\t});\n\t}\n\n\twaitForRepaint(() => {\n\t\tconst elementStyles = getComputedStyle(element);\n\t\ttimingProperties.forEach(timingProperty => {\n\t\t\tif( !hasValue(transitionDefinition.value) && hasValue(elementStyles[timingProperty]) ){\n\t\t\t\ttransitionDefinition.property = timingProperty;\n\t\t\t\ttransitionDefinition.value = elementStyles[timingProperty];\n\t\t\t}\n\t\t});\n\n\t\tif( !hasValue(transitionDefinition.value) ){\n\t\t\twarn(`${MODULE_NAME}:${__methodName__} | no usable transitions on element \"${element}\"`);\n\t\t\tdeferred.resolve(element);\n\t\t} else {\n\t\t\tconst\n\t\t\t\tsTimings = transitionDefinition.value.match(/(^|\\s)(\\d+(\\.\\d+)?)s(\\s|,|$)/g),\n\t\t\t\tmsTimings = transitionDefinition.value.match(/(^|\\s)(\\d+)ms(\\s|,|$)/g)\n\t\t\t;\n\t\t\tlet\tlongestTiming = 0;\n\n\t\t\t(sTimings ?? []).forEach(timing => {\n\t\t\t\ttiming = parseFloat(timing);\n\n\t\t\t\tif( !isNaN(timing) ){\n\t\t\t\t\ttiming = Math.floor(timing * 1000);\n\n\t\t\t\t\tif( timing > longestTiming ){\n\t\t\t\t\t\tlongestTiming = timing;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t(msTimings ?? []).forEach(timing => {\n\t\t\t\ttiming = parseInt(timing, 10);\n\n\t\t\t\tif( !isNaN(timing) && (timing > longestTiming) ){\n\t\t\t\t\tlongestTiming = timing;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tRUNNING_TRANSITIONS.set(element, {\n\t\t\t\tdeferred,\n\t\t\t\ttimer : pschedule(longestTiming, () => {\n\t\t\t\t\twaitForRepaint(() => {\n\t\t\t\t\t\tdeferred.resolve(element);\n\t\t\t\t\t\tRUNNING_TRANSITIONS.delete(element);\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t});\n\t\t}\n\t});\n\n\treturn deferred;\n}\n","/*!\n * Module Viewport\n */\n\n/**\n * @namespace Viewport\n */\n\nconst MODULE_NAME = 'Viewport';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {\n\thasValue,\n\torDefault,\n\tisWindow,\n\tisPlainObject,\n\tisArray,\n\tisFunction,\n\tisElement,\n\tisBoolean,\n\tisNumber,\n\tDeferred,\n\tObservable,\n\tassert,\n\tmin,\n\tminMax,\n\tround\n} from './basic.js';\nimport {isInDom} from './elements.js';\nimport {EasingFunctions} from './animation.js';\nimport {requestAnimationFrame, cancelAnimationFrame} from './timers.js';\nimport {throttle, defer} from './functions.js';\nimport {warn} from './logging.js';\nimport {fire} from './events.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst\n\tVISIBILITY_BASE_FPS = 15,\n\tDISTANCE_BASE_FPS = 4,\n\tBREAKPOINT_BASE_FPS = 4\n;\n\n\n\n//###[ HELPERS ]########################################################################################################\n\n/**\n * Returns the boundingClientRect of an HTML element. Falls back to zero-valued default rect if retrieval fails\n * (as in IE11 with an element, which is not in the DOM).\n *\n * @param {HTMLElement} element - the element of which we want to retrieve the bounding client rect\n * @returns {DOMRect} the element's bounding client rect\n *\n * @private\n */\nfunction getBoundingClientRect(element){\n\tlet boundingClientRect;\n\ttry {\n\t\tboundingClientRect = element.getBoundingClientRect();\n\t} catch(ex){\n\t\tboundingClientRect = !!window.DOMRect ?\n\t\t\tnew DOMRect(0, 0, 0, 0)\n\t\t\t: {top : 0, right : 0, bottom : 0, left : 0, width : 0, height : 0}\n\t\t;\n\t}\n\n\treturn boundingClientRect;\n}\n\n\n\n/**\n * A very simple polling-based implementation of the IntersectionObserver interface to replace a missing native\n * implementation for the VisibilityObserver. This is _not_ a polyfill, and it lacks a lot of implementation depth,\n * since it is tailored towards interoperability with VisibilityObserver.\n *\n * At its core, this implementation replaces real intersection events with stupid, brute-force, throttled polling\n * of all observed element's bounding boxes in respect to the viewport box.\n *\n * Be aware, that this is a very CPU/GPU intensive way of doing things and that using an IntersectionObserver is much\n * preferred. Only use this, if you have to support browsers like IE11 and you cannot leave out scroll animations there.\n * Also try to keep the number of observed elements to a minimum in that cases.\n *\n * @protected\n * @memberof Viewport\n * @name SimplePollingObserver\n *\n * @example\n * new SimplePollingObserver(entries => { ... , {targetFps : 60}});\n */\nclass SimplePollingObserver {\n\n\t#__className__ = 'SimplePollingObserver';\n\t#handler;\n\t#elements;\n\t#targetFps;\n\t#pollTimer;\n\n\t/**\n\t * Creates a new SimplePollingObserver, and starts observation.\n\t *\n\t * @param {Function} handler - the intersection handler function, that works with given entries\n\t * @param {Object} options - in IntersectionObserver, this would hold the threshold(s), which we do not need here, but, optionally, you may define the targetFps here, to define polling precision in detail\n\t */\n\tconstructor(handler, options){\n\t\tthis.#handler = handler;\n\t\tthis.#elements = new Set();\n\t\tthis.#targetFps = options?.targetFps ?? VISIBILITY_BASE_FPS;\n\n\t\tthis.connect();\n\t}\n\n\n\n\t/**\n\t * Starts polling elements and calls the intersection handler periodically with newly created entries.\n\t *\n\t * @returns {SimplePollingObserver} the observer instance\n\t *\n\t * @example\n\t * simplePollingObserver.connect();\n\t */\n\tconnect(){\n\t\tthis.disconnect();\n\n\t\tconst\n\t\t\tfpsMs = round(1000 / this.#targetFps),\n\t\t\tthrottledUpdate = throttle(fpsMs, () => {\n\t\t\t\tthis.#handler(Array.from(this.#elements).map(element => {\n\t\t\t\t\tconst\n\t\t\t\t\t\tboundingClientRect = getBoundingClientRect(element),\n\t\t\t\t\t\tviewportWidth = window.innerWidth,\n\t\t\t\t\t\tviewportHeight = window.innerHeight,\n\t\t\t\t\t\tupperCut = (boundingClientRect.top < 0) ? Math.abs(boundingClientRect.top) : 0,\n\t\t\t\t\t\tlowerCut = ((boundingClientRect.top + boundingClientRect.height) > viewportHeight)\n\t\t\t\t\t\t\t? (boundingClientRect.top + boundingClientRect.height) - viewportHeight\n\t\t\t\t\t\t\t: 0\n\t\t\t\t\t\t,\n\t\t\t\t\t\tvisiblePixels = minMax(\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\tboundingClientRect.height - upperCut - lowerCut,\n\t\t\t\t\t\t\tround(boundingClientRect.height)\n\t\t\t\t\t\t),\n\t\t\t\t\t\tentry = {\n\t\t\t\t\t\t\ttarget : element,\n\t\t\t\t\t\t\trootBounds : isInDom(element) ? {\n\t\t\t\t\t\t\t\ttop : 0,\n\t\t\t\t\t\t\t\tright : viewportWidth,\n\t\t\t\t\t\t\t\tbottom : viewportHeight,\n\t\t\t\t\t\t\t\tleft : 0,\n\t\t\t\t\t\t\t\twidth : viewportWidth,\n\t\t\t\t\t\t\t\theight : viewportHeight\n\t\t\t\t\t\t\t} : null,\n\t\t\t\t\t\t\tboundingClientRect : boundingClientRect,\n\t\t\t\t\t\t\tintersectionRect : {\n\t\t\t\t\t\t\t\theight : visiblePixels\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t;\n\n\t\t\t\t\tentry.intersectionRatio = visiblePixels / entry.boundingClientRect.height;\n\n\t\t\t\t\treturn entry;\n\t\t\t\t}));\n\t\t\t}).bind(this),\n\t\t\tstep = () => {\n\t\t\t\tthrottledUpdate();\n\t\t\t\tthis.#pollTimer = requestAnimationFrame(step);\n\t\t\t}\n\t\t;\n\n\t\tthis.#pollTimer = requestAnimationFrame(step);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops polling and removes all observed elements from the observer.\n\t *\n\t * @returns {SimplePollingObserver} the observer instance\n\t *\n\t * @example\n\t * simplePollingObserver.disconnect();\n\t */\n\tdisconnect(){\n\t\tcancelAnimationFrame(this.#pollTimer);\n\t\tthis.#pollTimer = null;\n\t\tthis.#elements.clear();\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Adds the element to the set of observed elements, for which entries are created, that are, in-term,\n\t * given to the intersection handler.\n\t *\n\t * @param {HTMLElement} element - the element to observe\n\t * @returns {SimplePollingObserver} the observer instance\n\t *\n\t * @example\n\t * simplePollingObserver.observe(teaserElement);\n\t */\n\tobserve(element){\n\t\tthis.#elements.add(element);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Removes the element from the set of observed elements.\n\t *\n\t * @param {HTMLElement} element - the element to unobserve\n\t * @returns {SimplePollingObserver} the observer instance\n\t *\n\t * @example\n\t * simplePollingObserver.unobserve(teaserElement);\n\t */\n\tunobserve(element){\n\t\tthis.#elements.delete(element);\n\n\t\treturn this;\n\t}\n\n}\n\n\n\n/**\n * A class to manage the visibility of an element in respect to the viewport.\n * A VisibilityState contains information such as if the element is currently (fully) inside the viewport and if so,\n * how many pixels are currently visible. There's a whole bunch of information to be found here, that aims to allow\n * for flexible usage in scenarios that require visibility-based effects.\n *\n * @protected\n * @memberof Viewport\n * @name VisibilityState\n * @example\n * (new VisibilityState(teaserElement, true)).visiblePixels(42);\n */\nclass VisibilityState {\n\n\t#__className__ = 'VisibilityState';\n\t#eventNameSpace = 'visibilitystate';\n\t#element;\n\t#inViewport = false;\n\t#fullyInViewport = false;\n\t#upperBoundInViewport = false;\n\t#lowerBoundInViewport = false;\n\t#visiblePercent = 0;\n\t#visiblePixels = 0;\n\tcalculateScrolled = false;\n\t#scrolledPercent = 0;\n\t#autoScrolledUpdateObservable = null;\n\t#autoScrolledUpdateSubscription = null;\n\tcalculateDistance = false;\n\t#distancePixels = Number.POSITIVE_INFINITY;\n\t#distanceViewports = Number.POSITIVE_INFINITY;\n\t#autoDistanceUpdateObservable = null;\n\t#autoDistanceUpdateSubscription = null;\n\tautoHandleTooLargeElements = true;\n\t#autoHandleTooLargeUpdatesObservable = null;\n\t#autoHandleTooLargeUpdatesSubscription = null;\n\t#deferredChange = null;\n\n\t/**\n\t * Creates a new VisibilityState object.\n\t *\n\t * @param {HTMLElement} element - the element being described by this state\n\t * @param {?Boolean} [calculateScrolled=false] - defines if the state should have scroll information, not available by default due to performance impact (such as scrolledPercent); scrolled information covers the question of how far the element has been scrolled through the viewport starting with the first pixel entering and ending with the last pixel leaving\n\t * @param {?Boolean} [calculateDistance=false] - defines if the state should have distance information, not available by default due to performance impact (such as distanceViewports); distance information covers the question of how far away an element currently is from the viewport\n\t * @param {?Boolean} [autoHandleTooLargeElements=true] - defines if element, which are larger/higher than the viewport, should be automatically handled, by adding additional means to update values without an interception taking place, because no edge is inside the viewport; this has a performance impact, but beware that setting this to false, will stop updates if no edge is inside the viewport\n\t */\n\tconstructor(element, calculateScrolled=false, calculateDistance=false, autoHandleTooLargeElements=true){\n\t\tthis.#element = element;\n\t\tthis.calculateScrolled = !!calculateScrolled;\n\t\tthis.calculateDistance = !!calculateDistance;\n\t\tthis.autoHandleTooLargeElements = !!autoHandleTooLargeElements;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the element currently being in the viewport or not.\n\t *\n\t * @param {?Boolean} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"enteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"leftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Boolean} true if element is currently in the viewport by any degree\n\t *\n\t * @example\n\t * state.inViewport()\n\t * => true/false\n\t * state.inViewport(true)\n\t * => true\n\t */\n\tinViewport(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#inViewport;\n\t\t\tthis.#inViewport = !!value;\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#inViewport,\n\t\t\t\t'enteredviewport', 'leftviewport'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#inViewport;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the element currently being _fully_ in the viewport or not.\n\t *\n\t * @param {?Boolean} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"fullyenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"fullyleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Boolean} true if element is currently in the viewport completely\n\t *\n\t * @example\n\t * state.fullyInViewport()\n\t * => true/false\n\t * state.fullyInViewport(true)\n\t * => true\n\t */\n\tfullyInViewport(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#fullyInViewport;\n\t\t\tthis.#fullyInViewport = !!value;\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#fullyInViewport,\n\t\t\t\t'fullyenteredviewport', 'fullyleftviewport'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#fullyInViewport;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the element's upper bound currently being in the viewport or not.\n\t *\n\t * @param {?Boolean} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"upperboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"upperboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Boolean} true if element's upper bound is currently in the viewport\n\t *\n\t * @example\n\t * state.upperBoundInViewport()\n\t * => true/false\n\t * state.upperBoundInViewport(true)\n\t * => true\n\t */\n\tupperBoundInViewport(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#upperBoundInViewport;\n\t\t\tthis.#upperBoundInViewport = !!value;\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#upperBoundInViewport,\n\t\t\t\t'upperboundenteredviewport', 'upperboundleftviewport'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#upperBoundInViewport;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the element's lower bound currently being in the viewport or not.\n\t *\n\t * @param {?Boolean} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"lowerboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Boolean} true if element's lower bound is currently in the viewport\n\t *\n\t * @example\n\t * state.lowerBoundInViewport()\n\t * => true/false\n\t * state.lowerBoundInViewport(true)\n\t * => true\n\t */\n\tlowerBoundInViewport(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#lowerBoundInViewport;\n\t\t\tthis.#lowerBoundInViewport = !!value;\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#lowerBoundInViewport,\n\t\t\t\t'lowerboundenteredviewport', 'lowerboundleftviewport'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#lowerBoundInViewport;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the percentage of the element currently being inside the viewport.\n\t *\n\t * @param {?Number} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"visiblepercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Number} the visible percentage between 0.00 and 100.00\n\t *\n\t * @example\n\t * state.visiblePercent()\n\t * => 0.00 ... 100.00\n\t * state.visiblePercent(66.6)\n\t * => 66.6\n\t */\n\tvisiblePercent(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#visiblePercent;\n\t\t\tthis.#visiblePercent = minMax(0, round(parseFloat(value), 2), 100);\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#visiblePercent,\n\t\t\t\t'visiblepercent'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#visiblePercent;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the number of vertical pixels of the element currently being inside the viewport.\n\t *\n\t * @param {?Number} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"visiblepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Number} the visible pixels between 0 and element height\n\t *\n\t * @example\n\t * state.visiblePixels()\n\t * => 0 ... element height\n\t * state.visiblePixels(66)\n\t * => 66\n\t */\n\tvisiblePixels(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#visiblePixels;\n\t\t\tthis.#visiblePixels = minMax(0, round(parseFloat(value)), round(this.#element.scrollHeight));\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#visiblePixels,\n\t\t\t\t'visiblepixels'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#visiblePixels;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the percentage the element has already been scrolled through the entirety of the\n\t * viewport, starting with the first pixel entering from below and ending with the last pixel leaving at the top.\n\t *\n\t * @param {?Number} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"scrolledpercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Number} the percentage scrolled between 0.00 and 100.00\n\t *\n\t * @example\n\t * state.scrolledPercent()\n\t * => 0.00 ... 100.00\n\t * state.scrolledPercent(66.6)\n\t * => 66.6\n\t */\n\tscrolledPercent(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#scrolledPercent;\n\t\t\tthis.#scrolledPercent = minMax(0, round(parseFloat(value), 2), 100);\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#scrolledPercent,\n\t\t\t\t'scrolledpercent'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#scrolledPercent;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the pixel distance of the element from the viewport, describing how long we still\n\t * need to scroll, until the first pixel hits the viewport bounds. This value may also be negative, if so, it\n\t * indicates distance from the top.\n\t *\n\t * @param {?Number} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"distancepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Number} the amount of pixels to scroll until the element hits the viewport bounds\n\t *\n\t * @example\n\t * state.distancePixels()\n\t * => -document height ... document height\n\t * state.distancePixels(66)\n\t * => 66\n\t */\n\tdistancePixels(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#distancePixels;\n\t\t\tthis.#distancePixels = round(parseFloat(value));\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#distancePixels,\n\t\t\t\t'distancepixels'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#distancePixels;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the distance of the element from the viewport, measured in viewport heights as a\n\t * floating point number, describing how long we still need to scroll, until the first pixel hits the viewport\n\t * bounds. This value may also be negative, if so, it indicates distance from the top.\n\t *\n\t * @param {?Number} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"distanceviewports.visibilitystate\" - {detail : viewportNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Number} the amount of viewports to scroll until the element hits the viewport bounds\n\t *\n\t * @example\n\t * state.distanceViewports()\n\t * => -document height in viewports ... document height in viewports\n\t * state.distanceViewports(6.6)\n\t * => 6.6\n\t */\n\tdistanceViewports(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#distanceViewports;\n\t\t\tthis.#distanceViewports = round(parseFloat(value), 2);\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#distanceViewports,\n\t\t\t\t'distanceviewports'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#distanceViewports;\n\t}\n\n\n\n\t/**\n\t * Starts the measurement of scrolledPercent for an element, which cannot be measured by just evaluating\n\t * interceptions (since we do not have any, if element is not intersecting a viewport edge).\n\t *\n\t * This is a feature, that should specifically be activated, since it is a CPU-intensive operation and should\n\t * only be used for elements, that really need this information.\n\t *\n\t * The range during which this updates should take place is: as long as the element is fully inside the viewport.\n\t *\n\t * @param {Basic.Observable} viewportHashObservable - observable, which changes on any change to the viewport, indicating that a new calculation is necessary\n\t * @param {Number} [targetFps=VISIBILITY_BASE_FPS] - the target amount of frames per second we are aiming for with these updates\n\t * @param {Boolean} [precisionUpdate=true] - since this operation is running a high-precision update to scrolledPercent anyway, we can also update the other properties as well, using the timer precision here, this is especially helpful for effects with positioning, that need razor-sharp in-sync information; set to false to save a few cpu-cycles\n\t * @fires CustomEvent#\"scrolledpercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"upperboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"upperboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"visiblepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"visiblepercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @see Basic.Observable\n\t * @example\n\t * state.startAutoScrolledPercentUpdates(new Observable('hash'), 30);\n\t */\n\tstartAutoScrolledPercentUpdates(viewportHashObservable, targetFps=VISIBILITY_BASE_FPS, precisionUpdate=true){\n\t\tif( this.calculateScrolled && !hasValue(this.#autoScrolledUpdateObservable) ){\n\t\t\tthis.#autoScrolledUpdateObservable = viewportHashObservable;\n\t\t\tconst fpsMs = round(1000 / targetFps);\n\t\t\tthis.#autoScrolledUpdateSubscription = this.#autoScrolledUpdateObservable.subscribe(throttle(fpsMs, () => {\n\t\t\t\tconst\n\t\t\t\t\tboundingClientRect = getBoundingClientRect(this.#element),\n\t\t\t\t\tviewportHeight = window.innerHeight\n\t\t\t\t;\n\n\t\t\t\tthis.scrolledPercent(\n\t\t\t\t\t(boundingClientRect.top - viewportHeight)\n\t\t\t\t\t/ (-boundingClientRect.height - viewportHeight) * 100\n\t\t\t\t);\n\n\t\t\t\tif( precisionUpdate ){\n\t\t\t\t\tthis.#calculatePreciseUpdate();\n\t\t\t\t}\n\t\t\t}));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops the measurement of scrolledPercent for an element.\n\t *\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @example\n\t * state.stopAutoScrolledPercentUpdates();\n\t */\n\tstopAutoScrolledPercentUpdates(){\n\t\tif( hasValue(this.#autoScrolledUpdateObservable) ){\n\t\t\tthis.#autoScrolledUpdateObservable.unsubscribe(this.#autoScrolledUpdateSubscription);\n\t\t}\n\n\t\tthis.#autoScrolledUpdateSubscription = null;\n\t\tthis.#autoScrolledUpdateObservable = null;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Starts the measurement of pixel and viewport distance for an element, which cannot be measured by just evaluating\n\t * interceptions (since we do not have any, if element is not intersecting a viewport edge, while off-screen).\n\t *\n\t * This is a feature, that should specifically be activated, since it is a CPU-intensive operation and should\n\t * only be used for elements, that really need this information.\n\t *\n\t * The range during which this updates should take place is: as long as the element is completely outside of the\n\t * viewport.\n\t *\n\t * @param {Basic.Observable} viewportHashObservable - observable, which changes on any change to the viewport, indicating that a new calculation is necessary\n\t * @param {Number} [targetFps=VISIBILITY_BASE_FPS] - the target amount of frames per second we are aiming for with these updates\n\t * @fires CustomEvent#\"distancepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"distancepercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @see Basic.Observable\n\t * @example\n\t * state.startAutoDistanceUpdates(new Observable('hash'), 30);\n\t */\n\tstartAutoDistanceUpdates(viewportHashObservable, targetFps=VISIBILITY_BASE_FPS){\n\t\tif( this.calculateDistance && !hasValue(this.#autoDistanceUpdateObservable) ){\n\t\t\tthis.#autoDistanceUpdateObservable = viewportHashObservable;\n\t\t\tconst fpsMs = round(1000 / targetFps);\n\t\t\tthis.#autoDistanceUpdateSubscription = this.#autoDistanceUpdateObservable.subscribe(throttle(fpsMs, () => {\n\t\t\t\tconst\n\t\t\t\t\tboundingClientRect = getBoundingClientRect(this.#element),\n\t\t\t\t\tviewportHeight = window.innerHeight,\n\t\t\t\t\tdistancePxToTop = boundingClientRect.top - viewportHeight,\n\t\t\t\t\tdistancePxToBottom = boundingClientRect.bottom,\n\t\t\t\t\tdistancePx = (Math.abs(distancePxToTop) < Math.abs(distancePxToBottom))\n\t\t\t\t\t\t? distancePxToTop\n\t\t\t\t\t\t: distancePxToBottom\n\t\t\t\t;\n\n\t\t\t\tthis.distancePixels(distancePx);\n\t\t\t\tthis.distanceViewports(distancePx / viewportHeight);\n\t\t\t}));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops the measurement of pixel and viewport distance for an element.\n\t *\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @example\n\t * state.stopAutoDistanceUpdates();\n\t */\n\tstopAutoDistanceUpdates(){\n\t\tif( hasValue(this.#autoDistanceUpdateObservable) ){\n\t\t\tthis.#autoDistanceUpdateObservable.unsubscribe(this.#autoDistanceUpdateSubscription);\n\t\t}\n\n\t\tthis.#autoDistanceUpdateSubscription = null;\n\t\tthis.#autoDistanceUpdateObservable = null;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Starts the measurement of properties for an element larger than the viewport itself, which are not measured,\n\t * if no intersection is taking place at the moment, because both element bounds are outside the viewport.\n\t * The is especially necessary, because very large elements also tend to need enormous amounts of thresholds to\n\t * precisely update values, which, at the end, quickly gets worse, then using a poll in that case. So, using this\n\t * feature keeps values precise and lets you define a reasonable granularity for all elements, no matter the size.\n\t *\n\t * This is a feature, that should specifically be activated, since it is a CPU-intensive operation and should\n\t * only be used for elements, that really need this information.\n\t *\n\t * The range during which this updates should take place is: the element is larger than the viewport height and\n\t * it is currently inside the viewport by any degree.\n\t *\n\t * @param {Basic.Observable} viewportHashObservable - observable, which changes on any change to the viewport, indicating that a new calculation is necessary\n\t * @param {Number} [targetFps=VISIBILITY_BASE_FPS] - the target amount of frames per second we are aiming for with these updates\n\t * @fires CustomEvent#\"upperboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"upperboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"visiblepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"visiblepercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @see Basic.Observable\n\t * @example\n\t * state.startAutoTooLargeUpdates(new Observable('hash'), 30);\n\t */\n\tstartAutoTooLargeUpdates(viewportHashObservable, targetFps=VISIBILITY_BASE_FPS){\n\t\tif( this.autoHandleTooLargeElements && !hasValue(this.#autoHandleTooLargeUpdatesObservable) ){\n\t\t\tthis.#autoHandleTooLargeUpdatesObservable = viewportHashObservable;\n\t\t\tconst fpsMs = round(1000 / targetFps);\n\t\t\tthis.#autoHandleTooLargeUpdatesSubscription = this.#autoHandleTooLargeUpdatesObservable.subscribe(throttle(fpsMs, () => {\n\t\t\t\tthis.#calculatePreciseUpdate();\n\t\t\t}));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops the measurement of properties for an element larger than the viewport itself, which are not measured,\n\t * if no intersection is taking place at the moment, because both element bounds are outside the viewport.\n\t *\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @example\n\t * state.stopAutoTooLargeUpdates();\n\t */\n\tstopAutoTooLargeUpdates(){\n\t\tif( hasValue(this.#autoHandleTooLargeUpdatesObservable) ){\n\t\t\tthis.#autoHandleTooLargeUpdatesObservable.unsubscribe(this.#autoHandleTooLargeUpdatesSubscription);\n\t\t}\n\n\t\tthis.#autoHandleTooLargeUpdatesSubscription = null;\n\t\tthis.#autoHandleTooLargeUpdatesObservable = null;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Returns a JSON snapshot of the element's current visibility state.\n\t *\n\t * @returns {Object} with active, inViewport, fullyInViewport, upperBoundInViewport, lowerBoundInViewport, visiblePercent, visiblePixels and (optionally) scrolledPercent, distancePixels and distanceViewports\n\t *\n\t * @example\n\t * state.toJson()\n\t * => {\n\t * active : true,\n\t * inViewport : true,\n\t * fullyInViewport : false,\n\t * upperBoundInViewport : true,\n\t * lowerBoundInViewport : false,\n\t * visiblePercent : 10.11,\n\t * visiblePixels : 42\n\t * }\n\t */\n\ttoJson(){\n\t\tconst info = {\n\t\t\tinViewport : this.inViewport(),\n\t\t\tfullyInViewport : this.fullyInViewport(),\n\t\t\tupperBoundInViewport : this.upperBoundInViewport(),\n\t\t\tlowerBoundInViewport : this.lowerBoundInViewport(),\n\t\t\tvisiblePercent : this.visiblePercent(),\n\t\t\tvisiblePixels : this.visiblePixels(),\n\t\t};\n\n\t\tif( this.calculateScrolled ){\n\t\t\tinfo.scrolledPercent = this.scrolledPercent()\n\t\t}\n\n\t\tif( this.calculateDistance ){\n\t\t\tinfo.distancePixels = this.distancePixels();\n\t\t\tinfo.distanceViewports = this.distanceViewports();\n\t\t}\n\n\t\treturn info;\n\t}\n\n\n\n\t/**\n\t * Triggers a named custom event of the state's element.\n\t * The primary reason for doing this, is to notify the DOM about visibility changes, that happened on the element.\n\t *\n\t * This method always constructs an eventname with a namespace attached after the event name, separated by a dot.\n\t * So, \"eventname.visibilitystate\" for example.\n\t *\n\t * @param {String} eventName - the name of the event\n\t * @param {?*} [payload=null] - payload to attach to the event's \"detail\" property\n\t * @fires CustomEvent#\"eventName.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @private\n\t * @example\n\t * this.#triggerEvent('foobar', {foo : 'bar'})\n\t * => CustomEvent('foobar.visibilitystate', {detail : {foo : 'bar'}})\n\t */\n\t#triggerEvent(eventName, payload=null){\n\t\tthis.#element.dispatchEvent(new CustomEvent(\n\t\t\t`${eventName}.${this.#eventNameSpace}`,\n\t\t\t{detail : payload ?? {}}\n\t\t));\n\n\t\tfire(\n\t\t\tthis.#element,\n\t\t\t`${eventName}.${this.#eventNameSpace}`,\n\t\t\tpayload ?? {}\n\t\t);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Triggers a general change event, notifying the dom about the fact, that something/anything has changed on\n\t * the element's visibility state.\n\t *\n\t * This event is triggered in a deferred way and not strictly synchronous to gather change events of several\n\t * changes in one event at the end of the change chain, the idea being, that changing five props only results in\n\t * one deferred change event. This means, that code, that relies on being executed synchronously at the exact moment\n\t * the change occurs, should use the precise property event instead.\n\t *\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @private\n\t * @example\n\t * this.#triggerChanged()\n\t * => CustomEvent('changed.visibilitystate')\n\t */\n\t#triggerChanged(){\n\t\tif( !hasValue(this.#deferredChange) ){\n\t\t\tthis.#deferredChange = defer(() => {\n\t\t\t\tthis.#deferredChange = null;\n\t\t\t\tthis.#triggerEvent('changed');\n\t\t\t});\n\t\t\tthis.#deferredChange();\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Triggers standardized update events for a property change.\n\t * Boolean values get specific enter and leave events, since they signify something starting and ending, while\n\t * numbers get a general change event.\n\t *\n\t * @param {Boolean|Number} oldValue - the old value, before the change\n\t * @param {Boolean|Number} newValue - the new value, after the change\n\t * @param {String} enterEventName - the event name for something starting/becoming true or the event name for number changes\n\t * @param {String} leaveEventName - the event name for something ending/becoming false; optional for number values\n\t * @fires CustomEvent#\"enterOrLeaveEventname.visibilitystate\"\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @private\n\t * @example\n\t * this.#triggerUpdateEvents(42, 66.6, 'propertyupdated');\n\t * this.#triggerUpdateEvents(true, false, 'somethingappeared', 'somethingdisappeared');\n\t */\n\t#triggerUpdateEvents(oldValue, newValue, enterEventName, leaveEventName){\n\t\tif( hasValue(newValue) ){\n\t\t\tif( isBoolean(newValue) ){\n\t\t\t\tif( newValue && !oldValue ){\n\t\t\t\t\tthis.#triggerEvent(enterEventName);\n\t\t\t\t\tthis.#triggerChanged();\n\t\t\t\t} else if( !newValue && oldValue ){\n\t\t\t\t\tthis.#triggerEvent(leaveEventName);\n\t\t\t\t\tthis.#triggerChanged();\n\t\t\t\t}\n\t\t\t} else if( isNumber(newValue) ){\n\t\t\t\tif( newValue !== oldValue ){\n\t\t\t\t\tthis.#triggerEvent(enterEventName ?? leaveEventName, newValue);\n\t\t\t\t\tthis.#triggerChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Calculates properties on-the-fly, which might not get updated precisely in certain scenarios, such as with\n\t * elements larger than the viewport itself.\n\t *\n\t * @fires CustomEvent#\"upperboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"upperboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"visiblepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"visiblepercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @private\n\t * @example\n\t * this.#calculatePreciseUpdate()\n\t */\n\t#calculatePreciseUpdate(){\n\t\tconst\n\t\t\tboundingClientRect = getBoundingClientRect(this.#element),\n\t\t\tviewportHeight = window.innerHeight,\n\t\t\tupperCut = (boundingClientRect.top < 0) ? Math.abs(boundingClientRect.top) : 0,\n\t\t\tlowerCut = ((boundingClientRect.top + boundingClientRect.height) > viewportHeight)\n\t\t\t\t? (boundingClientRect.top + boundingClientRect.height) - viewportHeight\n\t\t\t\t: 0\n\t\t;\n\n\t\tthis.upperBoundInViewport(\n\t\t\t(boundingClientRect.top >= 0)\n\t\t\t&& (boundingClientRect.top <= viewportHeight)\n\t\t);\n\n\t\tthis.lowerBoundInViewport(\n\t\t\t(boundingClientRect.bottom >= 0)\n\t\t\t&& (boundingClientRect.bottom <= viewportHeight)\n\t\t);\n\n\t\tthis.visiblePixels(boundingClientRect.height - upperCut - lowerCut);\n\n\t\tthis.visiblePercent((this.visiblePixels() / boundingClientRect.height) * 100);\n\n\t\treturn this;\n\t}\n\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Viewport:isInViewport\n */\n\n/**\n * Returns if the current element is visible in the window's viewport at the moment.\n *\n * @param {HTMLElement} element - the element to check\n * @param {?Boolean} [mustBeFullyInside=false] - defines if the element has to be fully enclosed in the viewport, default is false\n * @returns {Boolean} true if in viewport\n *\n * @memberof Viewport:isInViewport\n * @alias isInViewport\n * @example\n * if( isInViewport(document.querySelector('div.moving'), true) ){\n * ...\n * }\n */\nexport function isInViewport(element, mustBeFullyInside=false){\n\tmustBeFullyInside = orDefault(mustBeFullyInside, false, 'bool');\n\n\tif( !isInDom(element) ) return false;\n\n\tconst\n\t\tbb = element.getBoundingClientRect(),\n\t\tviewportWidth = window.innerWidth,\n\t\tviewportHeight = window.innerHeight\n\t;\n\n\tlet viewportBounds;\n\tif( mustBeFullyInside ){\n\t\tviewportBounds = {\n\t\t\ttop: 0,\n\t\t\tright : viewportWidth,\n\t\t\tbottom : viewportHeight,\n\t\t\tleft : 0\n\t\t};\n\t} else {\n\t\tviewportBounds = {\n\t\t\ttop : -(bb.bottom - bb.top) + 1,\n\t\t\tright : (viewportWidth + (bb.right - bb.left)) + 1,\n\t\t\tbottom : (viewportHeight + (bb.bottom - bb.top)) + 1,\n\t\t\tleft : -(bb.right - bb.left) + 1\n\t\t};\n\t}\n\n\treturn (\n\t\tbb.top >= viewportBounds.top &&\n\t\tbb.right <= viewportBounds.right &&\n\t\tbb.left >= viewportBounds.left &&\n\t\tbb.bottom <= viewportBounds.bottom\n\t);\n}\n\n\n\n/**\n * @namespace Viewport:scrollTo\n */\n\n/**\n * Scrolls the viewport to the element's position (first pixel at half viewport height).\n * Does not do anything if target element is already fully in viewport, unless scrollEvenIfFullyInViewport is set to\n * true. Uses getBoundingClientRect to measure viewport check, scrolls always if missing.\n *\n * If you use this function on a window, the offset is directly used as scrollTop, so this function may also be used for\n * things like back to top buttons.\n *\n * Scrolls may be cancelled by setting cancelOnUserScroll to true, but keep in mind, that this will only work\n * with mousewheels and (maybe) touchpads on modern browsers. No keyboard or scrollbar support yet.\n * The root of the problem is that a user scroll is indistinguishable from a js-triggered scroll,\n * since both trigger the scroll event and look exactly the same. So we have to use exotic\n * and specific events like mousewheel and DOMMouseScroll. So, please, use cancelOnUserScroll only\n * as a convenience option and not as a must.\n *\n * @param {HTMLElement|Window} element - the element to scroll to or the window to scroll within\n * @param {?Number} [durationMs=1000] - duration of the scrolling animation\n * @param {?Number} [offset=0] - offset from the viewport center to apply to the end position\n * @param {?String} [easing='easeInOutCubic'] - easing function to use, can be any of Animation.EasingFunctions\n * @param {?Boolean} [scrollEvenIfFullyInViewport=false] - if true, forces method to always scroll no matter the element's position\n * @param {?Boolean} [cancelOnUserScroll=false] - if true, scrolling animation will immediately be canceled on manual user scroll, return value will not resolve in that case\n * @throws error if element is not usable or if durationMs is <= 0\n * @returns {Basic.Deferred} resolves when scroll complete, rejects if scroll fails or is cancelled\n *\n * @memberof Viewport:scrollTo\n * @alias scrollTo\n * @see EasingFunctions\n * @example\n * document.querySelector('a.jumpitem').addEventListener('click', function(){ scrollTo(document.querySelector('.jumptarget'), function(){ alert('scrolled!'); }, 500, -100, true); });\n * scrollTo(document.querySelector('.jumptarget'), function(){ alert('Not triggered if user uses mousewheel.'); }, 5000, -0, false, true);\n * scrollTo(window, null, 500, 0, false, true);\n */\nexport function scrollTo(\n\telement,\n\tdurationMs=1000,\n\toffset=0,\n\teasing='easeInOutCubic',\n\tscrollEvenIfFullyInViewport=false,\n\tcancelOnUserScroll=false\n){\n\tconst __methodName__ = 'scrollTo';\n\n\tdurationMs = orDefault(durationMs, 1000, 'int');\n\toffset = orDefault(offset, 0, 'int');\n\teasing = orDefault(easing, 'easeInOutCubic', 'str');\n\tscrollEvenIfFullyInViewport = orDefault(scrollEvenIfFullyInViewport, false, 'bool');\n\tcancelOnUserScroll = orDefault(cancelOnUserScroll, false, 'bool');\n\n\tassert(isElement(element) || isWindow(element), `${MODULE_NAME}:${__methodName__} | element unusable`);\n\tassert(durationMs > 0, `${MODULE_NAME}:${__methodName__} | durationMs must be > 0`);\n\n\tif( !isFunction(EasingFunctions[easing]) ){\n\t\teasing = EasingFunctions.easeInOutCubic;\n\t} else {\n\t\teasing = EasingFunctions[easing];\n\t}\n\n\tconst\n\t\tres = new Deferred(),\n\t\telementIsWindow = (element.self === element),\n\t\telementInDom = !elementIsWindow && isInDom(element),\n\t\telementInViewport = (elementIsWindow || !elementInDom) ? false : isInViewport(element, true)\n\t;\n\n\tif( (elementInDom || elementIsWindow) && (scrollEvenIfFullyInViewport || !elementInViewport) ){\n\t\tlet start, targetY, cancelled = false;\n\t\tconst startY = window.scrollY ?? window.pageYOffset;\n\n\t\tif( elementIsWindow ){\n\t\t\ttargetY = offset;\n\t\t} else {\n\t\t\ttargetY = startY + getBoundingClientRect(element).top - round(window.innerHeight / 2) + offset;\n\t\t}\n\n\t\tconst\n\t\t\tdiff = targetY - startY,\n\t\t\tfScroll = function(timestamp){\n\t\t\t\tif( !cancelled ){\n\t\t\t\t\tif( !hasValue(start) ){\n\t\t\t\t\t\tstart = timestamp;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst\n\t\t\t\t\t\ttime = timestamp - start,\n\t\t\t\t\t\tprogress = easing(Math.min(time / durationMs, 1))\n\t\t\t\t\t;\n\n\t\t\t\t\twindow.scrollTo(0, startY + (diff * progress));\n\n\t\t\t\t\tif( (time < durationMs) && (progress < 1) ){\n\t\t\t\t\t\trequestAnimationFrame(fScroll)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tres.resolve();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t;\n\n\t\tif( cancelOnUserScroll ){\n\t\t\tconst fCancelScroll = function(){\n\t\t\t\tcancelled = true;\n\t\t\t\tres.reject(new Error('cancelled'));\n\t\t\t\twindow.removeEventListener('DOMMouseScroll', fCancelScroll);\n\t\t\t\twindow.removeEventListener('mousewheel', fCancelScroll);\n\t\t\t};\n\n\t\t\twindow.addEventListener('DOMMouseScroll', fCancelScroll);\n\t\t\twindow.addEventListener('mousewheel', fCancelScroll);\n\t\t}\n\n\t\tif( diff !== 0 ){\n\t\t\trequestAnimationFrame(fScroll);\n\t\t}\n\t}\n\n\treturn res;\n}\n\n\n\n/**\n * @namespace Viewport:VisibilityObserver\n */\n\n/**\n * @typedef ViewportInfo\n * @type Object\n *\n * @property {Number} scrollTop - scroll distance of the window/document in pixels to the upper bound of the viewport\n * @property {String} scrollDirection - either \"down\" or \"up\", depending on the last scroll movement\n * @property {String} fuzzyScrollDirection - either \"down\" or \"up\", depending on the last scroll movement; the user needs to scroll at least a small distance in the opposite direction for this to change, minimal changes will not change this\n * @property {Number} width - inner width of the window/viewport\n * @property {Number} height - inner height of the window/viewport\n * @property {Object} bounds - the viewport bound rectangle\n * @property {Number} bounds.top - upper bound of the viewport (typically 0)\n * @property {Number} bounds.right - right edge of the viewport (typically equals width)\n * @property {Number} bounds.bottom - bottom edge of the viewport (typically equals height)\n * @property {Number} bounds.left - left bound of the viewport (typically 0)\n * @property {Number} bounds.width - inner width of the window/viewport\n * @property {Number} bounds.height - inner height of the window/viewport\n *\n * @memberof Viewport\n */\n\n/**\n * A class offering extended visibility information about elements in regard to their positioning to the viewport\n * (bounds). An intersection observer is nice and concise, but if you want to build scroll-based effects or control\n * lazy loading a little bit more in detail, you are out of luck, since the intersection observer does not offer much\n * to help you in these cases.\n *\n * The VisibilityObserver offers tailor-fit information to build visibility-based effects, such as \"pixels visible\",\n * \"percent scrolled\" or \"distance in viewports\". Additionally, the VisibilityObserver handles edge-cases like\n * elements, which are bigger than the viewport itself, which results in intersections not being recognized is bounds\n * are not visible.\n *\n * This class aims to do the heavy lifting using an IntersectionObservers, to keep CPU usage down, but cover the edge\n * cases, if needed, with polling and precise calculations. Features, that are not achievable with intersections alone,\n * are very likely opt-in features.\n *\n * In case there is no native IntersectionObserver available, this implementation falls back to a SimplePollingObserver,\n * which replaces the IntersectionObserver and brute-forces the functionality with CPU-intensive polling. This should\n * be avoided if possible, but guarantees interoperability with older ES5 environments.\n *\n * This class roughly follows the interface defined by things like MutationObserver and IntersectionObserver.\n *\n * See class documentation below for details.\n *\n * @memberof Viewport:VisibilityObserver\n * @name VisibilityObserver\n *\n * @see VisibilityObserver\n * @see VisibilityState\n * @see SimplePollingObserver\n * @example\n * (new VisibilityObserver(100, 30))\n * .observe(element1, false, true)\n * .observe(element2, true, true)\n * .observe(element4, true, true)\n * .observe(element5)\n * .unobserve(element5)\n * ;\n * element1.addEventListener(\n * 'visiblepixels.visibilityobserver',\n * e => { console.log(`${e.detail} vertical pixels of element1 are visible`); }\n * );\n */\nclass VisibilityObserver {\n\n\t#__className__ = 'VisibilityObserver';\n\t#eventNameSpace = 'visibilityobserver';\n\t#htmlElementRequiredMessage = 'html element required';\n\t#states;\n\t#started = false;\n\t#initialized = false;\n\t#granularity;\n\t#targetFps;\n\t#throttledHandleScroll;\n\t#throttledHandleResize;\n\t#throttledHandleMutation;\n\t#throttledTriggerEvent;\n\t#thresholds;\n\t#observer;\n\t#refreshPoll;\n\t#documentMutationObserver;\n\t#viewportInfo;\n\t#viewportInfoReferenceScrollTop;\n\t#viewportInfoHash;\n\n\t/**\n\t * Creates a new VisibilityObserver and starts the observation of elements.\n\t *\n\t * @param {?Number} [granularity=10] - the number of intersection thresholds to use for each element (see IntersectionObserver threshold documentation) -> 2: just the outer bounds - 10: 10% steps - 100: one intersection every visible percent; make sure this number fits you needs and maybe think about using multiple observers with different granularities to cover different use cases\n\t * @param {?Number} [targetFps=VISIBILITY_BASE_FPS] - target frames per second to target with polls (be aware, that higher values put more stress on the CPU)\n\t * @param {?Boolean} [forcePollingObserver=false] - set this to true, if you want to skip usage of IntersectionObserver and, instead, just use polling all the time (this is a brute-force method putting stress on the CPU, only do this for a good reason)\n\t *\n\t * @see https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver\n\t */\n\tconstructor(granularity=10, targetFps=VISIBILITY_BASE_FPS, forcePollingObserver=false){\n\t\tthis.#states = new Map();\n\n\t\tthis.connect(granularity, targetFps, forcePollingObserver);\n\t}\n\n\n\n\t/**\n\t * Starts the observation of observed elements, which produces all visibility-related events.\n\t *\n\t * Be sure, that the observer is started before using any detail functions (these should be safe-guarded and warn\n\t * about the fact, that the observer is not connected).\n\t *\n\t * @param {?Number} [granularity=10] - the number of intersection thresholds to use for each element (see IntersectionObserver threshold documentation) -> 2: just the outer bounds - 10: 10% steps - 100: one intersection every visible percent; make sure this number fits you needs and maybe think about using multiple observers with different granularities to cover different use cases\n\t * @param {?Number} [targetFps=VISIBILITY_BASE_FPS] - target frames per second to target with polls (be aware, that higher values put more stress on the CPU)\n\t * @param {?Boolean} [forcePollingObserver=false] - set this to true, if you want to skip usage of IntersectionObserver and, instead, just use polling all the time (this is a brute-force method putting stress on the CPU, only do this for a good reason)\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @see disconnect\n\t * @example\n\t * visibilityObserver.connect(100, 50);\n\t */\n\tconnect(granularity=10, targetFps=VISIBILITY_BASE_FPS, forcePollingObserver=false){\n\t\tconst __methodName__ = 'connect';\n\n\t\tthis.disconnect();\n\n\t\tthis.#granularity = min(orDefault(granularity, 10, 'int'), 1);\n\t\tthis.#targetFps = minMax(1, orDefault(targetFps, VISIBILITY_BASE_FPS, 'int'), 120);\n\n\t\tconst fpsMs = round(1000 / targetFps);\n\t\tthis.#throttledHandleScroll = throttle(fpsMs, this.#handleScroll, true, true).bind(this);\n\t\tthis.#throttledHandleResize = throttle(fpsMs, this.#handleResize, true, true).bind(this);\n\t\tthis.#throttledHandleMutation = throttle(fpsMs, this.#handleMutation, true, true).bind(this);\n\t\tthis.#throttledTriggerEvent = throttle(fpsMs, this.#triggerEvent, true, true).bind(this);\n\n\t\tlet ObserverImplementation;\n\t\ttry {\n\t\t\tObserverImplementation = !forcePollingObserver ? IntersectionObserver : SimplePollingObserver;\n\t\t} catch(ex){\n\t\t\twarn(`${MODULE_NAME}:${this.#__className__}.${__methodName__} | IntersectionObserver not available, falling back to SimplePollingObserver`);\n\t\t\tObserverImplementation = SimplePollingObserver;\n\t\t}\n\n\t\tthis.#buildThresholds();\n\t\tthis.#observer = new ObserverImplementation(this.#handleIntersections.bind(this), {\n\t\t\tthreshold : this.#thresholds,\n\t\t\ttargetFps : this.#targetFps,\n\t\t});\n\n\t\tthis.#refreshViewportInfo();\n\t\tthis.#registerEvents();\n\n\t\tthis.#started = true;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops the observation of observed elements.\n\t *\n\t * Be sure to use this method before removing a VisibilityObserver to prevent trailing event registrations\n\t * and timers.\n\t *\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @see connect\n\t * @example\n\t * visibilityObserver.disconnect();\n\t */\n\tdisconnect(){\n\t\tthis.#unregisterEvents();\n\t\tif( hasValue(this.#observer) ){\n\t\t\tthis.#observer.disconnect();\n\t\t\tthis.#observer = null;\n\t\t}\n\t\tthis.#states.clear();\n\n\t\tthis.#started = false;\n\t\tthis.#initialized = false;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Adds an element to the set of observed elements.\n\t *\n\t * @param {HTMLElement} element - the element to observe\n\t * @param {?Boolean} [calculateScrolled=false] - defines if the element should be observed in terms of scrolled distance inside the viewport (which is not possible by watching intersections alone), setting this to true adds the property \"scrolledPercent\" to the visibility state\n\t * @param {?Boolean} [calculateDistance=false] - defines if the element should be observed in terms of distance from the viewport (which is not possible by watching intersections alone), setting this to true adds the properties \"distancePixels\" and \"distanceViewports\" to the visibility state\n\t * @param {?Boolean} [autoHandleTooLargeElements=true] - defines if elements, that are larger than the viewport should automatically be handled differently, to keep property updates consistent, if no element bounds are in the viewport (this is CPU-intensive, but normally something you'll expect, set this to false, if you are sure, that you do not need continuous updates during scrolling)\n\t * @throws error if element is not an HTML element\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @see unobserve\n\t * @example\n\t * visibilityObserver.observe(teaserElement);\n\t * visibilityObserver.observe(anotherTeaserElement, true, true);\n\t */\n\tobserve(element, calculateScrolled=false, calculateDistance=false, autoHandleTooLargeElements=true){\n\t\tif( this.#startedSafeguard() ){\n\t\t\tconst __methodName__ = 'addElement';\n\n\t\t\tassert(\n\t\t\t\tisElement(element),\n\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#htmlElementRequiredMessage}`\n\t\t\t);\n\n\t\t\tif( !isInDom(element) ){\n\t\t\t\twarn(`${MODULE_NAME}:${this.#__className__}.${__methodName__} | element not in DOM`);\n\t\t\t}\n\n\t\t\tthis.#states.set(element, new VisibilityState(\n\t\t\t\telement,\n\t\t\t\tcalculateScrolled,\n\t\t\t\tcalculateDistance,\n\t\t\t\tautoHandleTooLargeElements\n\t\t\t));\n\n\t\t\tthis.#observer.observe(element);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Removes an element from the set of observed elements.\n\t *\n\t * @param {HTMLElement} element - the element to unobserve\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @see observe\n\t * @example\n\t * visibilityObserver.unobserve(teaserElement);\n\t */\n\tunobserve(element){\n\t\tif( this.#states.has(element) ){\n\t\t\tthis.#states.delete(element);\n\t\t\tthis.#observer.unobserve(element);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Returns information about the current state of the viewport.\n\t *\n\t * This includes dimensions as well as scroll state.\n\t *\n\t * @returns {Viewport.ViewportInfo|null} the current viewport info or null if observer is not running\n\t *\n\t * @example\n\t * visibilityObserver.getViewportInfo().scrollTop;\n\t */\n\tgetViewportInfo(){\n\t\tif( this.#startedSafeguard() ){\n\t\t\treturn this.#viewportInfo;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\n\n\t/**\n\t * Returns an Observable, which changes on every update of the viewport.\n\t *\n\t * Subscribing to this value, allows you to programmatically react to every relevant viewport change.\n\t *\n\t * @returns {Basic.Observable|null} the observable or null if observer is not running\n\t *\n\t * @see Basic.Observable\n\t * @example\n\t * visibilityObserver.getViewportObservable().subscribe(() => { console.log(visibilityObserver.getViewportInfo().scrollTop); });\n\t */\n\tgetViewportObservable(){\n\t\tif( this.#startedSafeguard() ){\n\t\t\treturn this.#viewportInfoHash;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\n\n\t/**\n\t * Returns the current visibility state of an element.\n\t *\n\t * @param {HTMLElement} element - the element of which to retrieve the current visibility state\n\t * @returns {VisibilityState|null} the element's visibility state or null if observer is not running\n\t *\n\t * @example\n\t * if( visibilityObserver.getState(teaserElement).inViewport() ){ ... }\n\t */\n\tgetState(element){\n\t\tif( this.#startedSafeguard() ){\n\t\t\tif( this.#states.has(element) ){\n\t\t\t\treturn this.#states.get(element);\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\n\n\t/**\n\t * This is a guard method for public instance methods, which makes sure, that the observer is actually running,\n\t * automatically producing a warning, if this is not the case.\n\t *\n\t * @returns {Boolean} true if observer is running\n\t *\n\t * @private\n\t * @example\n\t * if( this.#startedSafeguard() ){ ... }\n\t */\n\t#startedSafeguard(){\n\t\tif( !this.#started ){\n\t\t\twarn(`${MODULE_NAME}:${this.#__className__}.${__methodName__} | not running, call connect() before`);\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\n\n\t/**\n\t * Builds InterceptionObserver thresholds based on the currently defined granularity, by dividing the range between\n\t * 0.0 and 1.0 into n + 1 equally distanced values.\n\t *\n\t * E.g.: granularity=10 -> 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0\n\t *\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#buildThresholds();\n\t */\n\t#buildThresholds(){\n\t\tconst thresholds = [];\n\n\t\tfor( let i = 0.0; i <= this.#granularity; i++ ){\n\t\t\tthresholds.push(round(i / this.#granularity, 2));\n\t\t}\n\n\t\tthis.#thresholds = thresholds;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Updates the viewport info object with the latest state, based on width, height and scrollTop.\n\t *\n\t * @param {?Boolean} [onlyScroll=false] - if true, only scrolling values are updated, which prevents some reflow-relevant calls; this is primarily used to connect \"scroll\" event to property updates, that might actually change\n\t * @fires CustomEvent#\"viewportchanged.visibilityobserver\"\n\t * @returns {Viewport.ViewportInfo} the updated viewport information\n\t *\n\t * @private\n\t * @example\n\t * this.#refreshViewportInfo(true);\n\t */\n\t#refreshViewportInfo(onlyScroll=false){\n\t\tconst\n\t\t\tviewportWidth = window.innerWidth,\n\t\t\tviewportHeight = window.innerHeight\n\t\t;\n\n\t\tif( !hasValue(this.#viewportInfo) ){\n\t\t\tthis.#viewportInfo = {\n\t\t\t\tscrollTop : window.scrollY ?? window.pageYOffset,\n\t\t\t\tscrollDirection : 'down',\n\t\t\t\tfuzzyScrollDirection : 'down',\n\t\t\t\twidth : viewportWidth,\n\t\t\t\theight : viewportHeight,\n\t\t\t\tbounds : {\n\t\t\t\t\ttop : 0,\n\t\t\t\t\tright : viewportWidth,\n\t\t\t\t\tbottom : viewportHeight,\n\t\t\t\t\tleft : 0,\n\t\t\t\t\twidth : viewportWidth,\n\t\t\t\t\theight : viewportHeight,\n\t\t\t\t}\n\t\t\t};\n\t\t\tthis.#viewportInfoReferenceScrollTop = this.#viewportInfo.scrollTop;\n\t\t\tthis.#viewportInfoHash = new Observable(\n\t\t\t\t`${this.#viewportInfo.scrollTop}${this.#viewportInfo.width}${this.#viewportInfo.height}`\n\t\t\t);\n\t\t} else {\n\t\t\tconst newScrollTop = window.scrollY ?? window.pageYOffset;\n\n\t\t\tif( newScrollTop > this.#viewportInfo.scrollTop ){\n\t\t\t\tthis.#viewportInfo.scrollDirection = 'down';\n\t\t\t} else if( newScrollTop < this.#viewportInfo.scrollTop ){\n\t\t\t\tthis.#viewportInfo.scrollDirection = 'up';\n\t\t\t}\n\n\t\t\tif( newScrollTop > (this.#viewportInfoReferenceScrollTop + 10) ){\n\t\t\t\tthis.#viewportInfo.fuzzyScrollDirection = 'down';\n\t\t\t\tthis.#viewportInfoReferenceScrollTop = newScrollTop;\n\t\t\t} else if( newScrollTop < (this.#viewportInfoReferenceScrollTop - 10) ){\n\t\t\t\tthis.#viewportInfo.fuzzyScrollDirection = 'up';\n\t\t\t\tthis.#viewportInfoReferenceScrollTop = newScrollTop;\n\t\t\t}\n\n\t\t\tthis.#viewportInfo.scrollTop = newScrollTop;\n\n\t\t\tif( !onlyScroll ){\n\t\t\t\tthis.#viewportInfo.width = viewportWidth;\n\t\t\t\tthis.#viewportInfo.height = viewportHeight;\n\t\t\t\tthis.#viewportInfo.bounds.right = viewportWidth;\n\t\t\t\tthis.#viewportInfo.bounds.bottom = viewportHeight;\n\t\t\t\tthis.#viewportInfo.bounds.width = viewportWidth;\n\t\t\t\tthis.#viewportInfo.bounds.height = viewportHeight;\n\t\t\t}\n\t\t}\n\n\t\tconst viewportInfoHash = `${this.#viewportInfo.scrollTop}${this.#viewportInfo.width}${this.#viewportInfo.height}`;\n\t\tif( viewportInfoHash !== this.#viewportInfoHash.getValue() ){\n\t\t\tthis.#viewportInfoHash.setValue(viewportInfoHash);\n\t\t\tthis.#throttledTriggerEvent('viewportchanged', this.#viewportInfo);\n\t\t}\n\n\t\treturn this.#viewportInfo;\n\t}\n\n\n\n\t/**\n\t * The event handler for scroll events, updating the viewport information.\n\t *\n\t * @fires CustomEvent#\"viewportchanged.visibilityobserver\"\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * window.addEventListener('scroll', this.#handleScroll);\n\t */\n\t#handleScroll(){\n\t\tthis.#refreshViewportInfo(true);\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * The event handler for resize events, updating the viewport information.\n\t *\n\t * @fires CustomEvent#\"viewportchanged.visibilityobserver\"\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * window.addEventListener('resize', this.#handleResize);\n\t */\n\t#handleResize(){\n\t\tthis.#refreshViewportInfo();\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * The event handler for document mutation events, updating the viewport information.\n\t *\n\t * @fires CustomEvent#\"viewportchanged.visibilityobserver\"\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * new MutationObserver(this.#handleMutation);\n\t */\n\t#handleMutation(){\n\t\tthis.#refreshViewportInfo();\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * The event handler for polling events, updating the viewport information.\n\t *\n\t * @fires CustomEvent#\"viewportchanged.visibilityobserver\"\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * const pollTimer = window.setInterval(this.#handlePoll, 100);\n\t */\n\t#handlePoll(){\n\t\tthis.#refreshViewportInfo();\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * The event handler for intersection events, updating VisibilityStates of all involved elements.\n\t *\n\t * This is the primary method for visibility logic, containing compilation, management and updates of\n\t * visibility information for all observed elements.\n\t *\n\t * @param {Array} entries - all elements with intersections currently happening\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @see https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver\n\t * @example\n\t * new IntersectionObserver(this.#handleIntersections);\n\t */\n\t#handleIntersections(entries){\n\t\tentries.forEach(entry => {\n\t\t\tif( hasValue(entry.rootBounds) ){\n\t\t\t\tconst state = this.#states.get(entry.target);\n\t\t\t\t// normally, this should not be necessary, since #states\n\t\t\t\t// observer are always set in tandem, but somehow, sometimes\n\t\t\t\t// the observer still triggers an intersection with a non-state target\n\t\t\t\t// this could be a browser but, which needs to be handled here\n\t\t\t\tif( hasValue(state) ){\n\t\t\t\t\tstate.inViewport(entry.intersectionRatio > 0);\n\t\t\t\t\tstate.fullyInViewport(entry.intersectionRatio >= 1);\n\n\t\t\t\t\tstate.upperBoundInViewport(\n\t\t\t\t\t\t(entry.boundingClientRect.top >= entry.rootBounds.top)\n\t\t\t\t\t\t&& (entry.boundingClientRect.top <= entry.rootBounds.bottom)\n\t\t\t\t\t);\n\t\t\t\t\tstate.lowerBoundInViewport(\n\t\t\t\t\t\t(entry.boundingClientRect.bottom >= entry.rootBounds.top)\n\t\t\t\t\t\t&& (entry.boundingClientRect.bottom <= entry.rootBounds.bottom)\n\t\t\t\t\t);\n\n\t\t\t\t\tstate.visiblePercent(entry.intersectionRatio * 100);\n\t\t\t\t\tstate.visiblePixels(entry.intersectionRect.height);\n\n\t\t\t\t\tif( state.calculateScrolled ){\n\t\t\t\t\t\tstate.scrolledPercent(\n\t\t\t\t\t\t\t(entry.boundingClientRect.top - entry.rootBounds.height)\n\t\t\t\t\t\t\t/ (-entry.boundingClientRect.height - entry.rootBounds.height) * 100\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif( state.fullyInViewport() ){\n\t\t\t\t\t\t\tstate.startAutoScrolledPercentUpdates(this.#viewportInfoHash, this.#targetFps);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstate.stopAutoScrolledPercentUpdates();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif( state.calculateDistance ){\n\t\t\t\t\t\tif( !state.inViewport() ){\n\t\t\t\t\t\t\tstate.startAutoDistanceUpdates(this.#viewportInfoHash, DISTANCE_BASE_FPS);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstate.stopAutoDistanceUpdates();\n\t\t\t\t\t\t\tstate.distancePixels(0);\n\t\t\t\t\t\t\tstate.distanceViewports(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(\n\t\t\t\t\t\tstate.autoHandleTooLargeElements\n\t\t\t\t\t\t&& (entry.boundingClientRect.height > entry.rootBounds.height)\n\t\t\t\t\t){\n\t\t\t\t\t\tif( state.inViewport() ){\n\t\t\t\t\t\t\tstate.startAutoTooLargeUpdates(this.#viewportInfoHash, this.#targetFps);\n\t\t\t\t\t\t\tif( state.calculateScrolled ){\n\t\t\t\t\t\t\t\tstate.startAutoScrolledPercentUpdates(this.#viewportInfoHash, this.#targetFps, false);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstate.stopAutoTooLargeUpdates();\n\t\t\t\t\t\t\tif( state.calculateScrolled ){\n\t\t\t\t\t\t\t\tstate.stopAutoScrolledPercentUpdates();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tif( !this.#initialized ){\n\t\t\tthis.#initialized = true;\n\t\t\tthis.#triggerEvent('initialized');\n\t\t}\n\n\t\tthis.#throttledTriggerEvent('updated');\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Dispatches a custom event on document.body, signifying a global viewport/visibility event or update.\n\t *\n\t * Every event is automatically namespaced with a dotted postfix.\n\t *\n\t * @param {String} eventName - the name of the event\n\t * @param {?*} [payload=null] -\n\t * @fires CustomEvent#\"eventName.visibilityobserver\"\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#triggerEvent('foobar', {foo : 'bar'});\n\t */\n\t#triggerEvent(eventName, payload=null){\n\t\tdocument.body.dispatchEvent(new CustomEvent(\n\t\t\t`${eventName}.${this.#eventNameSpace}`,\n\t\t\t{detail : payload ?? {}}\n\t\t));\n\n\t\tfire(\n\t\t\tdocument.body,\n\t\t\t`${eventName}.${this.#eventNameSpace}`,\n\t\t\tpayload ?? {}\n\t\t);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Sets up all global events, which are necessary to track viewport updates.\n\t *\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#registerEvents();\n\t */\n\t#registerEvents(){\n\t\twindow.addEventListener('scroll', this.#throttledHandleScroll);\n\t\twindow.addEventListener('resize', this.#throttledHandleResize);\n\t\tthis.#documentMutationObserver = new MutationObserver(this.#throttledHandleMutation);\n\t\tthis.#documentMutationObserver.observe(document.body, {attributes : true, childList : true, subtree : true});\n\t\tconst\n\t\t\tfpsMs = round(1000 / this.#targetFps),\n\t\t\tlazyFpsMs = round(fpsMs / 10)\n\t\t;\n\t\tthis.#refreshPoll = window.setInterval(this.#handlePoll.bind(this), lazyFpsMs);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Removes all global events, which are necessary to track viewport updates.\n\t *\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#registerEvents();\n\t */\n\t#unregisterEvents(){\n\t\twindow.clearInterval(this.#refreshPoll);\n\t\twindow.removeEventListener('scroll', this.#throttledHandleScroll);\n\t\twindow.removeEventListener('resize', this.#throttledHandleResize);\n\t\tif( hasValue(this.#documentMutationObserver) ){\n\t\t\tthis.#documentMutationObserver.disconnect();\n\t\t\tthis.#documentMutationObserver = null;\n\t\t}\n\n\t\treturn this;\n\t}\n\n}\n\nexport {VisibilityObserver};\n\n\n\n/**\n * @namespace Viewport:BreakpointObserver\n */\n\n/**\n * A class observing a defined list of breakpoints, notifying subscribers, if the breakpoint changes for whatever\n * reason (viewport resizes or device orientation changes mostly).\n *\n * See class documentation below for details.\n *\n * @memberof Viewport:BreakpointObserver\n * @name BreakpointObserver\n *\n * @see BreakpointObserver\n * @example\n * (new BreakpointObserver((to, from) => {\n * alert(`breakpoint changed from \"${from}\" to \"${to}\"`);\n * })).observe({\n * small : 0,\n * medium : 768,\n * large : 1024,\n * xlarge : 1440\n * });\n * (new BreakpointObserver())\n * .observe(\n * {small : 0},\n * ['medium', 768],\n * [\n * {large : 1024},\n * ['xlarge', 1440]\n * ]\n * )\n * .unobserve('xlarge')\n * .getCurrentBreakpoint()\n * ;\n * => 'medium'\n */\nclass BreakpointObserver {\n\n\t#__className__ = 'BreakpointObserver';\n\t#handlerMustBeFunctionMessage = 'handler must be function';\n\t#handler;\n\t#securedHandler;\n\t#breakpoints;\n\t#currentBreakpoint;\n\t#currentBreakpointReadOnly;\n\t#throttledHandleResize;\n\n\t/**\n\t * Creates a new BreakpointObserver and, optionally, sets a handler for breakpoint changes.\n\t *\n\t * @param {?Function} [handler=null] - the function to call on breakpoint change, receives two parameters: newBreakpointName, oldBreakpointName (if there is no old breakpoint, the parameter will be undefined)\n\t * @param {?Number} [targetFps=BREAKPOINT_BASE_FPS] - the max amount of updates per second we are aiming for in the observer; since breakpoints are not changing very regularly, low FPS should be alright here for most cases\n\t * @throws error if handler is set, but is not a function\n\t */\n\tconstructor(handler=null, targetFps=BREAKPOINT_BASE_FPS){\n\t\tconst __methodName__ = 'constructor';\n\n\t\tif( hasValue(handler) ){\n\t\t\tassert(isFunction(handler), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#handlerMustBeFunctionMessage}`);\n\t\t\tthis.#handler = handler;\n\t\t}\n\n\t\tthis.#securedHandler = (to, from) => {\n\t\t\tif( Object.keys(this.#breakpoints).length > 0 ){\n\t\t\t\tthis.#handler?.(to, from);\n\t\t\t}\n\t\t};\n\n\t\ttargetFps = minMax(1, orDefault(targetFps, VISIBILITY_BASE_FPS, 'int'), 120);\n\t\tconst fpsMs = round(1000 / targetFps);\n\t\tthis.#throttledHandleResize = throttle(fpsMs, this.#handleResize, true, true).bind(this);\n\n\t\tthis.connect(handler);\n\t}\n\n\n\n\t/**\n\t * (Re)starts breakpoint observation (resetting all data and states before) and, optionally, sets a new handler.\n\t *\n\t * @param {?Function} [handler=null] - the function to call on breakpoint change, receives two parameters: newBreakpointName, oldBreakpointName (if there is no old breakpoint, the parameter will be undefined)\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @see disconnect\n\t * @example\n\t * observer\n\t * .connect((to, from) => {\n\t * alert(`breakpoint changed from \"${from}\" to \"${to}\"`);\n\t * })\n\t * .observe(\n\t * ['small', 0],\n\t * ['medium', 768],\n\t * ['large', 1024]\n\t * )\n\t * ;\n\t */\n\tconnect(handler=null){\n\t\tconst __methodName__ = 'connect';\n\n\t\tthis.disconnect();\n\n\t\tif( hasValue(handler) ){\n\t\t\tassert(isFunction(handler), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#handlerMustBeFunctionMessage}`);\n\t\t\tthis.#handler = handler;\n\t\t}\n\n\t\tthis.#currentBreakpoint.subscribe(this.#securedHandler);\n\t\tthis.#currentBreakpoint.subscribe(to => { this.#currentBreakpointReadOnly.setValue(to); });\n\n\t\tthis.#registerEvents();\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops the observation of breakpoints and resets all data and states.\n\t *\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @see connect\n\t * @example\n\t * observer.disconnect().getCurrentBreakpoint();\n\t * => null\n\t */\n\tdisconnect(){\n\t\tthis.#breakpoints = {};\n\t\tthis.#currentBreakpoint = new Observable();\n\t\tthis.#currentBreakpointReadOnly = new Observable();\n\n\t\tthis.#unregisterEvents();\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Returns either the width to a breakpoint name or the name to a breakpoint width.\n\t *\n\t * @param {String|Number} breakpoint - if a number, tries to return a corresponding breakpoint name, else we'll try to find a width to the given name\n\t * @returns {String|Number|null} - either a breakpoint name, a breakpoint width or null, if nothing was found\n\t *\n\t * @example\n\t * observer.getBreakpoint('large')\n\t * => 1024\n\t * observer.getBreakpoint(1024)\n\t * => 'large'\n\t */\n\tgetBreakpoint(breakpoint){\n\t\tif( isNumber(breakpoint) ){\n\t\t\tlet name = null;\n\n\t\t\tfor( const breakpointName in this.#breakpoints ){\n\t\t\t\tif( breakpoint === this.#breakpoints[breakpointName] ){\n\t\t\t\t\tname = breakpointName;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn name;\n\t\t} else {\n\t\t\treturn this.#breakpoints[`${breakpoint}`] ?? null;\n\t\t}\n\t}\n\n\n\n\t/**\n\t * Returns the currently configured breakpoints of the observer as a dictionary.\n\t *\n\t * The return value is a copy, changing values or names in this value will not change the observer's data.\n\t *\n\t * @returns {Object} the observer's configured breakpoints\n\t */\n\tgetBreakpoints(){\n\t\treturn {...this.#breakpoints};\n\t}\n\n\n\n\t/**\n\t * Returns the current breakpoint's name.\n\t *\n\t * If you need the width, use this value in .getBreakpoint().\n\t *\n\t * @returns {String} the current breakpoint's name\n\t *\n\t * @see getBreakpoint\n\t */\n\tgetCurrentBreakpoint(){\n\t\treturn this.#currentBreakpoint.getValue();\n\t}\n\n\n\n\t/**\n\t * Returns an observable, that notifies subscribers of breakpoint changes.\n\t *\n\t * Use this, if you need more than one handler or want a little bit more flexibility.\n\t *\n\t * This observable is read-only, setting its values will not influence breakpoint evaluation in the observer.\n\t *\n\t * @returns {Basic.Observable} the breakpoint observable\n\t *\n\t * @example\n\t * observer.getCurrentBreakpointObservable().subscribe((to, from) => {\n\t * alert(`breakpoint changed from \"${from}\" to \"${to}\"`);\n\t * });\n\t */\n\tgetCurrentBreakpointObservable(){\n\t\treturn this.#currentBreakpointReadOnly;\n\t}\n\n\n\n\t/**\n\t * Adds breakpoint(s) to observe.\n\t *\n\t * @param {Object|Array|Array|Array} breakpoints - the breakpoint definition, either as a simple dictionary ({breakPointName : breakpointWidth, ...}) with 1 to n props, or as an entry array (['breakpointname', breakpointWidth]); both definitions can also be provided as a list of parameters or an array\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @see unobserve\n\t * @example\n\t * observer.observe({\n\t * small : 0,\n\t * medium : 768,\n\t * large : 1024,\n\t * xlarge : 1440\n\t * });\n\t * observer.observe(\n\t * {small : 0},\n\t * ['medium', 768],\n\t * [\n\t * {large : 1024},\n\t * ['xlarge', 1440]\n\t * ]\n\t * );\n\t */\n\tobserve(...breakpoints){\n\t\tconst additionalBreakpoints = this.#parseBreakpointList(breakpoints);\n\t\tthis.#breakpoints = {\n\t\t\t...this.#breakpoints,\n\t\t\t...additionalBreakpoints\n\t\t};\n\n\t\tthis.#refreshCurrentBreakpoint();\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Removes breakpoint(s) from observation.\n\t *\n\t * @param {Array|Object|Array|Array|Array} breakpoints - this can either be a definition, as used in observe() or just a list of breakpoint names to remove\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @see observe\n\t * @example\n\t * observer.unobserve('small', 'xlarge');\n\t * observer.unobserve(['small', 'xlarge']);\n\t * observer.unobserve({\n\t * small : 0,\n\t * xlarge : 1440\n\t * });\n\t */\n\tunobserve(...breakpoints){\n\t\tconst obsoleteBreakpoints = this.#parseBreakpointList(breakpoints, true);\n\t\tObject.keys(obsoleteBreakpoints).forEach(obsoleteBreakpointName => {\n\t\t\tdelete this.#breakpoints[obsoleteBreakpointName];\n\t\t});\n\n\t\tthis.#refreshCurrentBreakpoint();\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Takes an iterable list of breakpoint definitions and recursively parses this into a plain object of\n\t * key-value pairs, where keys are breakpoint names and values are breakpoint width integers.\n\t *\n\t * @param {Array|Array} list - the breakpoint definition lists, containing either a simple dictionaries ({breakPointName : breakpointWidth, ...}) with 1 to n props, or entry arrays (['breakpointname', breakpointWidth])\n\t * @param {Boolean} [acceptOnlyNames=false] - if true, will accept breakpoint names without widths and return these entries with a null width\n\t * @throws error if breakpoint width is not usable as an integer or width is negative\n\t * @returns {Object} dictionary of parsed breakpoints\n\t *\n\t * @private\n\t * @example\n\t * this.#parseBreakpointList([\n\t * {small : 0},\n\t * ['medium', 768],\n\t * [\n\t * {large : 1024},\n\t * ['xlarge', 1440]\n\t * ]\n\t * ])\n\t * => {\n\t * small : 0,\n\t * medium : 768,\n\t * large : 1024,\n\t * xlarge : 1440\n\t * }\n\t * this.#parseBreakpointList(['xlarge', {small : 0}, ['medium', ['large', 1024]]], true)\n\t * => {\n\t * xlarge : null,\n\t * small : 0,\n\t * medium : null,\n\t * large : 1024\n\t * }\n\t */\n\t#parseBreakpointList(list, acceptOnlyNames=false){\n\t\tconst\n\t\t\t__methodName__ = '#parseBreakpointList',\n\t\t\tunusableBreakpointMessage = 'unusable breakpoint'\n\t\t;\n\n\t\tlet breakpoints = {};\n\n\t\tArray.from(list).forEach(breakpoint => {\n\t\t\tif( isPlainObject(breakpoint) ){\n\t\t\t\tfor( const breakpointName in breakpoint ){\n\t\t\t\t\tbreakpoint[breakpointName] = parseInt(breakpoint[breakpointName], 10);\n\t\t\t\t\tassert(\n\t\t\t\t\t\t!isNaN(breakpoint[breakpointName]) && (breakpoint[breakpointName] >= 0),\n\t\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${unusableBreakpointMessage} \"${breakpointName}\"`\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tbreakpoints = {...breakpoints, ...breakpoint};\n\t\t\t} else if( isArray(breakpoint) ){\n\t\t\t\tif(\n\t\t\t\t\t(breakpoint.length === 2)\n\t\t\t\t\t&& !isPlainObject(breakpoint[0]) && !isArray(breakpoint[0])\n\t\t\t\t\t&& !isPlainObject(breakpoint[1]) && !isArray(breakpoint[1])\n\t\t\t\t){\n\t\t\t\t\tconst breakpointName = `${breakpoint[0]}`;\n\t\t\t\t\tbreakpoints[breakpointName] = parseInt(breakpoint[1], 10);\n\t\t\t\t\tassert(\n\t\t\t\t\t\t!isNaN(breakpoints[breakpointName]) && (breakpoints[breakpointName] >= 0),\n\t\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${unusableBreakpointMessage} \"${breakpointName}\"`\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tbreakpoints = {\n\t\t\t\t\t\t...breakpoints,\n\t\t\t\t\t\t...this.#parseBreakpointList(breakpoint, acceptOnlyNames)\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} else if( acceptOnlyNames ){\n\t\t\t\tbreakpoints[`${breakpoint}`] = null;\n\t\t\t}\n\t\t});\n\n\t\treturn breakpoints;\n\t}\n\n\n\n\t/**\n\t * Updates the current breakpoint value, based on the current breakpoint configuration in regard to the current\n\t * viewport width.\n\t *\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#refreshCurrentBreakpoint();\n\t */\n\t#refreshCurrentBreakpoint(){\n\t\tconst\n\t\t\tviewportWidth = window.innerWidth,\n\t\t\tbreakpoints = Object.entries(this.#breakpoints).sort((a, b) => {\n\t\t\t\treturn (a[1] === b[1])\n\t\t\t\t\t? 0\n\t\t\t\t\t: (\n\t\t\t\t\t\t(a[1] > b[1])\n\t\t\t\t\t\t? 1\n\t\t\t\t\t\t: -1\n\t\t\t\t\t)\n\t\t\t\t;\n\t\t\t})\n\t\t;\n\n\t\tlet currentBreakpoint = null;\n\t\tbreakpoints.forEach(([breakpointName, breakpointWidth]) => {\n\t\t\tif( viewportWidth >= breakpointWidth ){\n\t\t\t\tcurrentBreakpoint = breakpointName;\n\t\t\t}\n\t\t});\n\n\t\tthis.#currentBreakpoint.setValue(currentBreakpoint);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Event handler for resize events. Updates the current breakpoint if necessary.\n\t *\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * window.addEventListener('resize', this.#handleResize);\n\t */\n\t#handleResize(){\n\t\tthis.#refreshCurrentBreakpoint();\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Registers all (global) events, such as the resize event, that are needed for breakpoint observation.\n\t *\n\t * Be sure to unregister trailing handlers before destructing the observer, by using disconnect().\n\t *\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#registerEvents()\n\t */\n\t#registerEvents(){\n\t\twindow.addEventListener('resize', this.#throttledHandleResize);\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Unregisters all (global) events, such as the resize event, to prevent trailing event handlers after destruction.\n\t *\n\t * Be sure to unregister trailing handlers before destructing the observer, by using disconnect().\n\t *\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#unregisterEvents()\n\t */\n\t#unregisterEvents(){\n\t\twindow.removeEventListener('resize', this.#throttledHandleResize);\n\t\treturn this;\n\t}\n\n}\n\nexport {BreakpointObserver};\n","/*!\n * Module Urls\n */\n\n/**\n * @namespace Urls\n */\n\nconst MODULE_NAME = 'Urls';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {\n\thasValue,\n\torDefault,\n\tsize,\n\tassert,\n\tisFunction,\n\tisString,\n\tisArray,\n\tisObject,\n\tisPlainObject,\n\tisNaN,\n\tisEmpty\n} from './basic.js';\nimport {log} from './logging.js';\nimport {replace} from './strings.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const COMMON_TOP_LEVEL_DOMAINS = [\n\t'aero', 'biz', 'cat', 'com', 'coop', 'edu', 'gov', 'info', 'int', 'jobs', 'mil', 'mobi', 'museum', 'name', 'net',\n\t'org', 'travel', 'ac', 'ad', 'ae', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao', 'aq', 'ar', 'as', 'at', 'au', 'aw',\n\t'az', 'ba', 'bb', 'bd', 'be', 'bf', 'bg', 'bh', 'bi', 'bj', 'bm', 'bn', 'bo', 'br', 'bs', 'bt', 'bv', 'bw', 'by',\n\t'bz', 'ca', 'cc', 'cd', 'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'cr', 'cs', 'cu', 'cv', 'cx', 'cy',\n\t'cz', 'de', 'dj', 'dk', 'dm', 'do', 'dz', 'ec', 'ee', 'eg', 'eh', 'er', 'es', 'et', 'eu', 'fi', 'fj', 'fk', 'fm',\n\t'fo', 'fr', 'ga', 'gb', 'gd', 'ge', 'gf', 'gg', 'gh', 'gi', 'gl', 'gm', 'gn', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu',\n\t'gw', 'gy', 'hk', 'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il', 'im', 'in', 'io', 'iq', 'ir', 'is', 'it', 'je',\n\t'jm', 'jo', 'jp', 'ke', 'kg', 'kh', 'ki', 'km', 'kn', 'kp', 'kr', 'kw', 'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk',\n\t'lr', 'ls', 'lt', 'lu', 'lv', 'ly', 'ma', 'mc', 'md', 'mg', 'mh', 'mk', 'ml', 'mm', 'mn', 'mo', 'mp', 'mq', 'mr',\n\t'ms', 'mt', 'mu', 'mv', 'mw', 'mx', 'my', 'mz', 'na', 'nc', 'ne', 'nf', 'ng', 'ni', 'nl', 'no', 'np', 'nr', 'nu',\n\t'nz', 'om', 'pa', 'pe', 'pf', 'pg', 'ph', 'pk', 'pl', 'pm', 'pn', 'pr', 'ps', 'pt', 'pw', 'py', 'qa', 're', 'ro',\n\t'ru', 'rw', 'sa', 'sb', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sl', 'sm', 'sn', 'so', 'sr', 'st', 'su',\n\t'sv', 'sy', 'sz', 'tc', 'td', 'tf', 'tg', 'th', 'tj', 'tk', 'tm', 'tn', 'to', 'tp', 'tr', 'tt', 'tv', 'tw', 'tz',\n\t'ua', 'ug', 'uk', 'um', 'us', 'uy', 'uz', 'va', 'vc', 've', 'vg', 'vi', 'vn', 'vu', 'wf', 'ws', 'ye', 'yt', 'yu',\n\t'za', 'zm', 'zr', 'zw', 'local'\n];\n\nconst\n\tURISON_VALUE_FORMAT = `[^\\-0123456789 '!:(),*@$][^ '!:(),*@$]*`,\n\tURISON_VALUE_REX = new RegExp(`^${URISON_VALUE_FORMAT}$`),\n\tURISON_NEXT_VALUE_REX = new RegExp(URISON_VALUE_FORMAT, 'g')\n;\n\n\n\n//###[ HELPERS ]########################################################################################################\n\n/**\n * A parser to translate a Rison string such as `'(key1:value,key2:!t,key3:!(!f,42,!n))'` into its\n * JSON object/array representation `{key1 : 'value', key2 : true, key3 : [false, 42, null]}`. This is a helper class\n * for the public Urison class below.\n *\n * @protected\n * @memberof Urls\n * @name UrisonParser\n *\n * @see https://github.com/Nanonid/rison\n * @example\n * new UrisonParser(error => { console.error(error); });\n */\nclass UrisonParser {\n\n\t#__className__ = 'UrisonParser';\n\t#errorHandler;\n\t#string = '';\n\t#index = 0;\n\t#message = null;\n\t#bangTokens;\n\t#tokenMap;\n\n\t/**\n\t * Creates a new UrisonParser instance.\n\t *\n\t * All errors in this class result in a console error message rather than an exception. To work with occurring\n\t * errors, define an errorCallback for the constructor and throw errors from there if needed.\n\t *\n\t * @param {Function} [errorHandler=null] - function to call in case parsing fails, receives the error message and the character index as parameters\n\t */\n\tconstructor(errorHandler=null){\n\t\tconst instance = this;\n\n\t\tthis.#errorHandler = isFunction(errorHandler) ? errorHandler : null;\n\n\t\t// syntax tokens preceded with a \"!\" and the values they represent in JSON\n\t\tthis.#bangTokens = {\n\t\t\t't' : true,\n\t\t\t'f' : false,\n\t\t\t'n' : null,\n\t\t\t'(' : this.#parseArray\n\t\t};\n\n\t\t// syntax structure tokens and the procedures, that transform these tokens into json structure\n\t\tthis.#tokenMap = {\n\t\t\t'!' : function(){\n\t\t\t\tconst char = instance.#string.charAt(instance.#index++);\n\t\t\t\tif( char === '' ) return instance.#error('\"!\" at end of input');\n\n\t\t\t\tconst value = instance.#bangTokens[char];\n\t\t\t\tif( value === undefined ) return instance.#error(`unknown literal: \"!${char}\"`);\n\t\t\t\tif( isFunction(value) ) return value.call(this);\n\n\t\t\t\treturn value;\n\t\t\t},\n\n\t\t\t'(' : function(){\n\t\t\t\tconst res = {};\n\t\t\t\tlet\n\t\t\t\t\tfirst = true,\n\t\t\t\t\tchar\n\t\t\t\t;\n\n\t\t\t\twhile( (char = instance.#next()) !== ')' ){\n\t\t\t\t\tif( !first ){\n\t\t\t\t\t\tif( char !== ',' ){\n\t\t\t\t\t\t\treturn instance.#error('missing \",\"');\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if( char === ',' ){\n\t\t\t\t\t\treturn instance.#error('extra \",\"');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tinstance.#index--;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst key = instance.#readValue();\n\t\t\t\t\tif( key === undefined ) return undefined;\n\t\t\t\t\tif( instance.#next() !== ':' ) return instance.#error('missing \":\"');\n\n\t\t\t\t\tconst value = instance.#readValue();\n\t\t\t\t\tif( value === undefined ) return undefined;\n\t\t\t\t\tres[key] = value;\n\n\t\t\t\t\tfirst = false;\n\t\t\t\t}\n\n\t\t\t\treturn res;\n\t\t\t},\n\n\t\t\t\"'\" : function(){\n\t\t\t\tconst segments = [];\n\t\t\t\tlet\n\t\t\t\t\ti = instance.#index,\n\t\t\t\t\tstart = instance.#index,\n\t\t\t\t\tchar\n\t\t\t\t;\n\n\t\t\t\twhile( (char = instance.#string.charAt(i++)) !== \"'\" ){\n\t\t\t\t\tif( char === '' ) return instance.#error(`unmatched \"'\"`);\n\t\t\t\t\tif( char === '!' ){\n\t\t\t\t\t\tif( start < (i - 1) ){\n\t\t\t\t\t\t\tsegments.push(instance.#string.slice(start, i - 1));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchar = instance.#string.charAt(i++);\n\t\t\t\t\t\tif( ['!', \"'\"].includes(char) ){\n\t\t\t\t\t\t\tsegments.push(char);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn instance.#error(`invalid string escape: \"!${char}\"`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstart = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif( start < (i - 1) ){\n\t\t\t\t\tsegments.push(instance.#string.slice(start, i - 1));\n\t\t\t\t}\n\t\t\t\tinstance.#index = i;\n\n\t\t\t\treturn (segments.length === 1) ? segments[0] : segments.join('');\n\t\t\t},\n\n\t\t\t'-' : function(){\n\t\t\t\tconst\n\t\t\t\t\tstart = instance.#index - 1,\n\t\t\t\t\tnumberTypeMap = {\n\t\t\t\t\t\t'int+.' : 'frac',\n\t\t\t\t\t\t'int+e' : 'exp',\n\t\t\t\t\t\t'frac+e' : 'exp'\n\t\t\t\t\t}\n\t\t\t\t;\n\t\t\t\tlet\n\t\t\t\t\ts = instance.#string,\n\t\t\t\t\ti = instance.#index,\n\t\t\t\t\tnumberType = 'int',\n\t\t\t\t\tpermittedSigns = '-'\n\t\t\t\t;\n\n\t\t\t\tdo {\n\t\t\t\t\tconst char = s.charAt(i++);\n\t\t\t\t\tif( char === '' ) break;\n\t\t\t\t\tif( (char >= '0') && (char <= '9') ) continue;\n\t\t\t\t\tif( permittedSigns.includes(char) ){\n\t\t\t\t\t\tpermittedSigns = '';\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tnumberType = numberTypeMap[`${numberType}+${char.toLowerCase()}`];\n\t\t\t\t\tif( numberType === 'exp' ){\n\t\t\t\t\t\tpermittedSigns = '-';\n\t\t\t\t\t}\n\t\t\t\t} while( numberType !== undefined );\n\n\t\t\t\ti--;\n\t\t\t\tinstance.#index = i;\n\t\t\t\ts = s.slice(start, i);\n\t\t\t\tif( s === '-' ) return instance.#error('invalid number');\n\t\t\t\treturn Number(s);\n\t\t\t}\n\t\t};\n\n\t\t(function(tokenMap){\n\t\t\tfor( let i = 0; i <= 9; i++ ){\n\t\t\t\ttokenMap[`${i}`] = tokenMap['-'];\n\t\t\t}\n\t\t})(this.#tokenMap);\n\t}\n\n\n\n\t/**\n\t * Parses a Rison string into a JSON object.\n\t * Resets internal parsing info, like parsing index, to start new parsing process.\n\t *\n\t * @param {String} risonString - the string to parse\n\t * @returns {Object|Array|undefined} the parsed JSON object or undefined, in case parsing failed\n\t *\n\t * @example\n\t * (new UrisonParser()).parse('(key1:value,key2:!t,key3:!(!f,42,!n))')\n\t * => {key1 : 'value', key2 : true, key3 : [false, 42, null]}\n\t */\n\tparse(risonString){\n\t\tthis.#string = `${risonString}`;\n\t\tthis.#index = 0;\n\t\tthis.#message = null;\n\n\t\tlet value = this.#readValue();\n\n\t\tconst trailingChar = this.#next();\n\t\tif( !this.#message && (trailingChar !== undefined) ){\n\t\t\tlet detailMessage;\n\t\t\tif( /\\s/.test(trailingChar) ){\n\t\t\t\tdetailMessage = 'whitespace detected';\n\t\t\t} else {\n\t\t\t\tdetailMessage = `trailing char \"${trailingChar}\"`;\n\t\t\t}\n\t\t\tvalue = this.#error(`unable to parse string \"${risonString}\", ${detailMessage}`);\n\t\t}\n\n\t\tif( this.#message && this.#errorHandler ){\n\t\t\tthis.#errorHandler(this.#message, this.#index);\n\t\t}\n\n\t\treturn value;\n\t}\n\n\n\n\t/**\n\t * Parses the structure of an array. Is a helper function for #parse/#readValue.\n\t * Works with previously set internal parsing info such as string and parsing index.\n\t *\n\t * @returns {Array|undefined} the parsed array or undefined, in case parsing failed\n\t *\n\t * @private\n\t * @example\n\t * this.#parseArray()\n\t * => [true, null, 'value']\n\t */\n\t#parseArray(){\n\t\tconst res = [];\n\t\tlet char;\n\n\t\twhile( (char = this.#next()) !== ')' ){\n\t\t\tif( char === '' ) return this.#error('unmatched \"!(\"');\n\n\t\t\tif( !isEmpty(res) ){\n\t\t\t\tif( char !== ',' ){\n\t\t\t\t\treturn this.#error('missing \",\"');\n\t\t\t\t}\n\t\t\t} else if( char === ',' ){\n\t\t\t\treturn this.#error('extra \",\"');\n\t\t\t} else {\n\t\t\t\tthis.#index--;\n\t\t\t}\n\n\t\t\tconst value = this.#readValue();\n\t\t\tif( value === undefined ) return undefined;\n\t\t\tres.push(value);\n\t\t}\n\n\t\treturn res;\n\t}\n\n\n\n\t/**\n\t * Either reads the next value or key in the current parser string or triggers recursive handling of syntax tokens.\n\t * Progresses parsing to the next section so to speak.\n\t *\n\t * @returns {Object|Array|String|Number|Boolean|null|undefined} the parsed value or undefined if parsing failed\n\t *\n\t * @private\n\t * @example\n\t * this.#readValue()\n\t * => 'valueorkeyorstructure'\n\t */\n\t#readValue(){\n\t\tconst\n\t\t\tchar = this.#next(),\n\t\t\tmapper = this.#tokenMap[char]\n\t\t;\n\n\t\tif( isFunction(mapper) ) return mapper.apply(this);\n\n\t\tconst i = this.#index - 1;\n\t\tURISON_NEXT_VALUE_REX.lastIndex = i;\n\t\tconst matches = URISON_NEXT_VALUE_REX.exec(this.#string);\n\t\tif( !isEmpty(matches) ){\n\t\t\tconst id = matches[0];\n\t\t\tthis.#index = i + id.length;\n\t\t\treturn id;\n\t\t}\n\n\t\tif( hasValue(char) && (char !== '') ) return this.#error(`invalid character \"${char}\"`);\n\t\treturn this.#error('empty expression');\n\t}\n\n\n\n\t/**\n\t * Reads the next character of the currently given Rison string, increments the index\n\t * and returns the character.\n\t *\n\t * @returns {String|undefined} the next character or undefined if there is none\n\t *\n\t * @private\n\t * @example\n\t * this.#next()\n\t * => '!'\n\t */\n\t#next(){\n\t\tlet\n\t\t\ti = this.#index,\n\t\t\tchar\n\t\t;\n\n\t\tif( i >= this.#string.length ) return undefined;\n\t\tchar = this.#string.charAt(i++);\n\t\tthis.#index = i;\n\n\t\treturn char;\n\t}\n\n\n\n\t/**\n\t * Sets the error message and writes it to `console.error()` for info purposes.\n\t * This method does _not_ throw an exception, for this, please set an error handler\n\t * in the constructor and throw it externally.\n\t *\n\t * @param {String} message - the error message\n\t * @returns {undefined} is always undefined to be uniform return value for failed value parsing in case of error\n\t *\n\t * @private\n\t * @example\n\t * this.#error('oh noez')\n\t * => undefined\n\t */\n\t#error(message){\n\t\tconsole.error(`${this.#__className__} error: `, message);\n\t\tthis.#message = message;\n\t\treturn undefined;\n\t}\n\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Urls:urlHref\n */\n\n/**\n * Will return a fully qualified URL based on the given URL base string for use as a href/source-value\n * or navigation target.\n *\n * Provide a base URL or leave the URL out, to use the current URL.\n * Add GET-parameters (adding to those already present in the URL), define an anchor (or automatically get the one\n * defined in the URL).\n *\n * Provided URLs are handled with some automagic:\n * - a URL starting with \"//\" will receive the current page protocol\n * - a URL starting with a single \"/\" will be seen as relative and will be expanded to an absolute URL, based\n * on the current URL\n * - a URL starting with \"?\" will be treated as a singular query string, resulting in the query being added to the\n * current URL, replacing any present query\n * - a URL starting with \"#\" will be treated as a singular hash string, resulting in the hash being added to the\n * current URL, replacing any present hash\n * - if, after all automagic applied, the URL still does not start with a http-protocol, the current page's protocol\n * will be added\n *\n * Provided params have to be a flat plain object, with ordinal values or arrays of ordinal values on the first level.\n * Everything else will be stringified and url-encoded as is. Usually, parameters defined here add to present\n * parameters in the URL. To force-override present values, declare the param name with a \"!\" prefix\n * (`{'!presentparam' : 'new'}`).\n *\n * This method implements some quality-of-life improvements, that differ from the native result of `new URL().href`:\n * - `+`-encoding for whitespace is replaced with `%20`, while `+` will stay what it is, a verbatim URL-safe character\n * with repeating keys (`tags=1&tags=2&tags=3`)\n * - empty parameters are rendered without \"=\". So, \"?test=&foo\" will be \"?test&foo\"\n * - `path/?` will become just `path?`\n * - `path/#` will become just `path#`\n * - trailing slashes will be removed\n * - parameters will be sorted alphabetically by keys\n * (value order will be kept if possible, might change, when using markListParams)\n * - identical key/value pairs will be reduced to one occurrence, so `?q=a&q=a` will become `?q=a`\n *\n * @param {?String|URL} [url=null] - the base URL to use, if nullish current location is used\n * @param {?Object} [params=null] - plain object of GET-parameters to add to the url\n * @param {?String} [anchor=null] - anchor/hash to set, has precedence over URL hash\n * @param {?Boolean} [markListParams=false] - if true, params with more than one value will be marked with \"[]\" preceding the param name\n * @param {?Boolean} [keepEncodedUrlSafeChars=false] - if true, encoded chars, which are URL-safe, are kept encoded, instead of being returned raw\n * @throws error if url is not usable\n * @returns {String} the created URL including parameters and anchor\n *\n * @memberof Urls:urlHref\n * @alias urlHref\n * @example\n * buildUrl('https://test.com', {search : 'kittens', order : 'asc'}, 'fluffykittens');\n * => 'https://test.com?search=kittens&order=asc#fluffykittens'\n * buildUrl(null, {order : 'desc'});\n * => 'https://current.url?order=desc'\n */\nexport function urlHref(url=null, params=null, anchor=null, markListParams=false, keepEncodedUrlSafeChars=false){\n\tconst __methodName__ = 'urlHref';\n\n\turl = orDefault(url, window.location.href, 'str');\n\tparams = isPlainObject(params) ? params : null;\n\tanchor = orDefault(anchor, null, 'str');\n\tmarkListParams = orDefault(markListParams, false, 'bool');\n\n\tif( url === 'about:blank' ) return url;\n\tif( url.trim() === '' ){\n\t\turl = window.location.href;\n\t}\n\tif( url.startsWith('//') ){\n\t\turl = `${window.location.protocol}${url}`;\n\t} else if( url.startsWith('/') ){\n\t\turl = `${window.location.origin}${url}`;\n\t} else if( url.startsWith('?') ){\n\t\tconst anchorPart = !url.includes('#') ? window.location.href.split('#')[1] : null;\n\t\turl = `${window.location.href.split('?')[0]}${url}${hasValue(anchorPart) ? '#'+anchorPart : ''}`;\n\t} else if( url.startsWith('#') ){\n\t\turl = `${window.location.href.split('#')[0]}${url}`;\n\t}\n\tif( !(/^https?:\\/\\//.test(url)) ){\n\t\turl = `${window.location.protocol}//${url}`;\n\t}\n\n\tlet urlObj;\n\ttry {\n\t\turlObj = new URL(url);\n\t} catch(ex){\n\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | unusable URL \"${url}\" [${ex}]`);\n\t}\n\n\tif( hasValue(anchor) ){\n\t\turlObj.hash = anchor.startsWith('#') ? anchor : `#${anchor}`;\n\t}\n\n\tconst urlParams = urlObj.searchParams;\n\n\tif( hasValue(params) ){\n\t\tfor( let paramName in params ){\n\t\t\tlet overrideName = paramName;\n\t\t\tif( paramName.startsWith('!') ){\n\t\t\t\toverrideName = paramName.slice(1);\n\t\t\t}\n\n\t\t\tif( overrideName !== paramName ){\n\t\t\t\turlParams.delete(overrideName);\n\t\t\t}\n\n\t\t\t[].concat(params[paramName]).forEach(paramValue => {\n\t\t\t\turlParams.append(overrideName, `${paramValue}`);\n\t\t\t});\n\t\t}\n\t}\n\n\tif( markListParams ){\n\t\tfor( let k of urlParams.keys() ){\n\t\t\tconst cleanKey = k.replace(/\\[]$/, '');\n\n\t\t\tlet presentValues = [].concat(urlParams.getAll(k));\n\t\t\tif( k.endsWith('[]') ){\n\t\t\t\tpresentValues = presentValues.concat(urlParams.getAll(cleanKey));\n\t\t\t}\n\n\t\t\tif( (presentValues.length > 1) ){\n\t\t\t\turlParams.delete(k);\n\t\t\t\turlParams.delete(cleanKey);\n\t\t\t\tpresentValues.forEach(v => {\n\t\t\t\t\turlParams.append(`${cleanKey}[]`, v);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tlet\tquery = urlObj.search\n\t\t.replace(/\\+/g, '%20')\n\t\t.replace(/=&/g, '&')\n\t\t.replace(/=$/g, '')\n\t;\n\n\tif( !keepEncodedUrlSafeChars ){\n\t\tquery = query\n\t\t\t.replaceAll('%2B', '+')\n\t\t\t.replaceAll('%5B', '[')\n\t\t\t.replaceAll('%5D', ']')\n\t\t;\n\t}\n\n\tlet queryParts = query.startsWith('?') ? query.slice(1).split('&') : []\n\tif( !isEmpty(queryParts) ){\n\t\tqueryParts.sort((a, b) => {\n\t\t\tconst\n\t\t\t\taKey = a.split('=')[0],\n\t\t\t\tbKey = b.split('=')[0]\n\t\t\t;\n\t\t\treturn (aKey < bKey) ? -1 : ((aKey > bKey) ? 1 : 0 );\n\t\t});\n\t\tqueryParts = queryParts.filter((part, index) => {\n\t\t\tif( index >= 1 ){\n\t\t\t\treturn queryParts.indexOf(part) === index;\n\t\t\t} else {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t});\n\t\tquery = `?${queryParts.join('&')}`;\n\t}\n\n\tlet finalUrl;\n\tif( !isEmpty(query) ){\n\t\tfinalUrl = `${urlObj.href.split('?')[0]}${query}${urlObj.hash}`.replace('/?', '?');\n\t} else if( !isEmpty(urlObj.hash) && isEmpty(query) ){\n\t\tfinalUrl = `${urlObj.href.split('#')[0]}${urlObj.hash}`.replace('/#', '#');\n\t} else {\n\t\tfinalUrl = urlObj.href.replace(/\\/$/, '');\n\t}\n\n\treturn keepEncodedUrlSafeChars ? finalUrl : replace(\n\t\tfinalUrl,\n\t\t['%2C', '%3A', '%40', '%24', '%2F', '%2B'],\n\t\t[',', ':', '@', '$', '/', '+']\n\t);\n}\n\n\n\n/**\n * @namespace Urls:urlParameter\n */\n\n/**\n * Searches for and returns parameters embedded in the provided url containing a query string\n * (make sure all values are url encoded).\n *\n * You may also just provide the query string.\n *\n * Returns a single parameter's value if a parameter name is given, otherwise returns dictionary with all parameters\n * as keys and the associated parameter value.\n *\n * If a parameter has more than one value the values are returned as an array, whether being requested by name\n * or in the dictionary containing all params.\n *\n * If a parameter is set, but has no defined value (name present, but no = before next param)\n * the value is returned as boolean true.\n *\n * @param {?String|URL} [url=null] - the url containing the parameter string, will use current URL if nullish\n * @param {?String} [parameter=null] - the name of the parameter to extract\n * @throws error if given url is not usable\n * @returns {null|true|String|Array|Object} null in case the parameter doesn't exist, true in case it exists but has no value, a string in case the parameter has one value, or an array of values, or a dictionary object of all available parameters with corresponding values\n *\n * @memberof Urls:urlParameter\n * @alias urlParameter\n * @see urlHref\n * @example\n * const hasKittens = urlParameter('//foobar.com/bar?has_kittens', 'has_kittens');\n * => true\n * const hasDoggies = urlParameter('has_doggies=yes&has_doggies', 'has_doggies');\n * => ['yes', true]\n * const allTheData = urlParameter('?foo=foo&bar=bar&bar=barbar&bar');\n * => {foo : 'foo', bar : ['bar', 'barbar', true]}\n */\nexport function urlParameter(url=null, parameter=null){\n\turl = urlHref(url, null, null, false, true);\n\tparameter = orDefault(parameter, null, 'str');\n\n\tconst\n\t\tsearchParams = new URL(url).searchParams,\n\t\tfMapParameterValue = parameterValue => ((parameterValue === '') ? true : parameterValue)\n\t;\n\n\tif( hasValue(parameter) ){\n\t\tconst parameterValues = searchParams.getAll(parameter);\n\t\tif( parameterValues.length === 0 ){\n\t\t\treturn null;\n\t\t} else if( parameterValues.length === 1 ){\n\t\t\treturn fMapParameterValue(parameterValues[0]);\n\t\t} else {\n\t\t\treturn Array.from(new Set(parameterValues.map(fMapParameterValue)));\n\t\t}\n\t} else {\n\t\tconst parameters = {};\n\t\tArray.from(searchParams.keys()).forEach(parameterName => {\n\t\t\tconst parameterValues = searchParams.getAll(parameterName);\n\t\t\tif( parameterValues.length > 0 ){\n\t\t\t\tparameters[parameterName] =\n\t\t\t\t\t(parameterValues.length === 1)\n\t\t\t\t\t? fMapParameterValue(parameterValues[0])\n\t\t\t\t\t: Array.from(new Set(parameterValues.map(fMapParameterValue)))\n\t\t\t\t;\n\t\t\t}\n\t\t});\n\t\treturn (size(parameters) > 0) ? parameters : null;\n\t}\n}\n\n\n\n/**\n * @namespace Urls:urlParameters\n */\n\n/**\n * Searches for and returns parameters embedded in provided url with a parameter string.\n *\n * Semantic shortcut version of urlParameter without any given parameter.\n *\n * @param {?String|URL} [url=null] - the url containing the parameter string, will use current URL if nullish\n * @throws error if given url is not usable\n * @returns {Object|null} dictionary object of all parameters or null if url has no parameters\n *\n * @memberof Urls:urlParameters\n * @alias urlParameters\n * @see urlParameter\n * @example\n * const allParams = urlParameters('http://www.foobar.com?foo=foo&bar=bar&bar=barbar&bar');\n * => {foo : 'foo', bar : ['bar', 'barbar', true]}\n */\nexport function urlParameters(url=null){\n\treturn urlParameter(url);\n}\n\n\n\n/**\n * @namespace Urls:urlAnchor\n */\n\n/**\n * Returns the currently set URL-Anchor on given URL.\n *\n * Theoretically, this function also works with any other string containing a hash (as long as there is \"#\" included),\n * since this implementation does not lean on \"new URL()\", but is a simple string operation.\n *\n * In comparison to \"location.hash\", this function actually decodes the hash automatically.\n *\n * @param {?String|URL} [url=null] - the url, in which to search for a hash, uses current url if nullish\n * @param {?Boolean} [withCaret=false] - defines if the returned anchor value should contain leading \"#\"\n * @throws error if given url is not usable\n * @returns {String|null} current anchor value or null if no anchor was found\n *\n * @memberof Urls:urlAnchor\n * @alias urlAnchor\n * @example\n * const anchorWithoutCaret = urlAnchor('https://foobar.com#test');\n * => 'test'\n * const hrefAnchorWithCaret = urlAnchor(linkElement.getAttribute('href'), true);\n * => '#test'\n * const decodedAnchorFromLocation = urlAnchor(window.location.hash);\n */\nexport function urlAnchor(url=null, withCaret=false){\n\turl = urlHref(url);\n\twithCaret = orDefault(withCaret, false, 'bool');\n\n\tconst urlParts = url.split('#');\n\n\tlet anchor = (urlParts.length > 1) ? decodeURIComponent(urlParts[1].trim()) : null;\n\tif( anchor === '' ){\n\t\tanchor = null;\n\t}\n\tif( withCaret && hasValue(anchor) ){\n\t\tanchor = `#${anchor}`;\n\t}\n\n\treturn anchor;\n}\n\n\n\n/**\n * @namespace Urls:addNextParameter\n */\n\n/**\n * Adds a \"next\"-parameter to a given URL. If there is already a parameter of that name, it will be replaced.\n *\n * A \"next\"-parameter is usually used to relay a second URL, which should be redirected to after something happens,\n * such as a login or another (possibly automatic) action.\n *\n * @param {?String} [url=''] - the URL to add the next parameter to, if left empty, will be \"\", which is synonymous with the current URL\n * @param {?String} [next=''] - the next URL to add as parameter to the given URL (will automatically be URL-encoded)\n * @param {?String} [paramName='next'] - the name of the next parameter\n * @param {?Boolean} [assertSameBaseDomain=false] - if true, url and next must have the same base domain (ignoring subdomains), to prevent injections\n * @param {?Array} [additionalTopLevelDomains=null] - this function uses a list of common TLDs (if assertSameBaseDomain is true), if yours is missing, you may provide it, using this parameter\n * @throws error if url or next are not usable URLs\n * @throws error if assertBaseDomain is true an the base domains of url and next differ\n * @returns {String} the transformed URL with the added next parameter\n *\n * @memberof Urls:addNextParameter\n * @alias addNextParameter\n * @see urlHref\n * @example\n * addNextParameter('https://foobar.com', 'https://foo.bar', 'redirect');\n * => 'https://foobar.com?redirect=https%3A%2F%2Ffoo.bar'\n * addNextParameter('https://foobar.com?next=https%3A%2F%2Ffoo.bar', 'https://kittens.com');\n * => 'https://foobar.com?next=https%3A%2F%2Fkittens.com'\n */\nexport function addNextParameter(url, next, paramName='next', assertSameBaseDomain=false, additionalTopLevelDomains=null){\n\tconst __methodName__ = 'addNextParameter';\n\n\turl = urlHref(url);\n\tnext = urlHref(next);\n\tparamName = orDefault(paramName, 'next', 'str');\n\tassertSameBaseDomain = orDefault(assertSameBaseDomain, true, 'bool');\n\n\tif( assertSameBaseDomain ){\n\t\tassert(\n\t\t\tevaluateBaseDomain(new URL(url).hostname, additionalTopLevelDomains) === evaluateBaseDomain(new URL(next).hostname, additionalTopLevelDomains),\n\t\t\t`${MODULE_NAME}:${__methodName__} | different base domains in url and next`\n\t\t);\n\t}\n\n\tconst params = new URL(url).searchParams;\n\tif( params.has(paramName) ){\n\t\tlog().info(`${MODULE_NAME}:${__methodName__} | replaced \"${paramName}\" value \"${params.get(paramName)}\" with \"${next}\"`);\n\t}\n\n\treturn urlHref(url, {[`!${paramName}`] : next});\n}\n\n\n\n/**\n * @namespace Urls:addCacheBuster\n */\n\n/**\n * Adds a cache busting parameter to a given URL. If there is already a parameter of that name, it will be replaced.\n * This prevents legacy browsers from caching requests by changing the request URL dynamically, based on current time.\n *\n * @param {?String|URL} [url=null] - the URL to add the cache busting parameter to, if nullish, the current URL will be used\n * @param {?String} [paramName='_'] - the name of the cache busting parameter\n * @throws error if url is not a usable URL\n * @returns {String} the transformed URL with the added cache busting parameter\n *\n * @memberof Urls:addCacheBuster\n * @alias addCacheBuster\n * @see urlHref\n * @example\n * addCacheBuster('https://foobar.com');\n * => 'https://foobar.com?_=1648121948009'\n * addCacheBuster('https://foobar.com?next=https%3A%2F%2Ffoo.bar', 'nocache');\n * => 'https://foobar.com?next=https%3A%2F%2Ffoo.bar&nocache=1648121948009'\n */\nexport function addCacheBuster(url=null, paramName='_'){\n\tconst __methodName__ = 'addCacheBuster';\n\n\turl = urlHref(url);\n\n\tconst\n\t\tparams = new URL(url).searchParams,\n\t\tbuster = Date.now()\n\t;\n\n\tif( params.has(paramName) ){\n\t\tlog().info(`${MODULE_NAME}:${__methodName__} | replaced \"${paramName}\" value \"${params.get(paramName)}\" with \"${buster}\"`);\n\t}\n\n\treturn urlHref(url, {[`!${paramName}`] : buster})\n}\n\n\n\n/**\n * @namespace Urls:evaluateBaseDomain\n */\n\n/**\n * Walks a domain string (e.g. foobar.barfoo.co.uk) backwards, separated by dots, skips over all top level\n * domains it finds and includes the first non-TLD value to retrieve the base domain without any subdomains\n * (e.g. barfoo.co.uk).\n *\n * This is not completely fool-proof in case of very exotic TLDs, but quite robust in most cases.\n *\n * This method is particularly helpful if you want to set a domain cookie while being on a subdomain.\n *\n * @param {String} domain - the domain string (hostname), which should be evaluated; you may also provide a full, parsable URL, from which to extract the hostname\n * @param {?Array} [additionalTopLevelDomains=null] - this function uses a list of common TLDs, if yours is missing, you may provide it, using this parameter\n * @returns {String} the evaluated base domain string\n *\n * @memberof Urls:evaluateBaseDomain\n * @alias evaluateBaseDomain\n * @example\n * evaluateBaseDomain('foobar.barfoo.co.uk');\n * => 'barfoo.co.uk'\n * evaluateBaseDomain('https://foobar.barfoo.co.uk/?foo=bar');\n * => 'barfoo.co.uk'\n */\nexport function evaluateBaseDomain(domain, additionalTopLevelDomains=null){\n\tdomain = orDefault(domain, window.location.hostname, 'str');\n\tadditionalTopLevelDomains = orDefault(additionalTopLevelDomains, null, 'arr');\n\n\tlet url;\n\ttry {\n\t\turl = new URL(domain);\n\t} catch(error){\n\t\turl = null;\n\t}\n\tif( hasValue(url) ){\n\t\tdomain = url.hostname;\n\t}\n\n\tconst\n\t\ttopLevelDomains = new Set([\n\t\t\t...COMMON_TOP_LEVEL_DOMAINS,\n\t\t\t...(hasValue(additionalTopLevelDomains) ? additionalTopLevelDomains.map(tld => `${tld}`) : [])\n\t\t]),\n\t\tdomainParts = domain.split('.').reverse()\n\t;\n\n\tlet baseDomain = domain;\n\n\tif( domainParts.length > 2 ){\n\t\tlet i;\n\n\t\tfor( i = 0; i < domainParts.length; i++ ){\n\t\t\tif( !topLevelDomains.has(domainParts[i]) ){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tbaseDomain = domainParts.slice(0, i + 1).reverse().join('.');\n\t}\n\n\treturn baseDomain;\n}\n\n\n\n/**\n * @namespace Urls:Urison\n */\n\n/**\n * A class, which (re)implements the \"Rison\" standard of en- and decoding JSON structures to and from URL-safe strings,\n * which can be used as parameter or hash values, while staying readable and avoiding characters, which are not meant\n * to be used inside a URL.\n *\n * This is a renamed reimplementation of ES5 Rison, which has not gotten an update for years and should be fully\n * compatible with other available parsers for that standard.\n *\n * The basic idea is this:\n * We have some kind of complex data structure we want to serialize to a URL, to represent a current search and filter\n * setup for example. This structure should also be retrievable easily after a reload, to be able to use that config\n * as a starting point again for the page's search and filter widgets. A big plus here would be readability, which,\n * for instance, gets lost, if we just were to url-encode JSON as-is.\n *\n * This class provides the means to en- and decode JSON structures for usage in URLs. Additionally, it provides methods\n * to explicitly work with objects and array, for the en- and decoding process, removing the necessity to include\n * brackets into the result, making the string even leaner.\n *\n * See class documentation below for details.\n *\n * @memberof Urls:Urison\n * @name Urison\n *\n * @see Urison\n * @see https://github.com/Nanonid/rison\n * @example\n * (new Urison()).encode({key1 : 'value', key2 : true, key3 : [false, 42, null]})\n * => '(key1:value,key2:!t,key3:!(!f,42,!n))'\n * (new Urison()).decode('(key1:value,key2:!t,key3:!(!f,42,!n))')\n * => {key1 : 'value', key2 : true, key3 : [false, 42, null]}\n * (new Urison()).encodeObject({key1 : 'value', key2 : true, key3 : [false, 42, null]})\n * => 'key1:value,key2:!t,key3:!(!f,42,!n)'\n * (new Urison()).decodeObject('key1:value,key2:!t,key3:!(!f,42,!n)')\n * => {key1 : 'value', key2 : true, key3 : [false, 42, null]}\n * (new Urison()).encodeArray([false, 42, null])\n * => '!f,42,!n'\n * (new Urison()).decodeArray('!f,42,!n')\n * => [false, 42, null]\n */\nclass Urison {\n\n\t#__className__ = 'Urison';\n\t#autoEscape;\n\t#autoUnescape;\n\t#encoders;\n\t#parser;\n\n\t/**\n\t * Creates a new Urison en- and decoder.\n\t *\n\t * @param {Boolean} [autoEscape=true] - if true, all keys and values are automatically uri-encoded and decoded if necessary, set this to false to keep values as is\n\t */\n\tconstructor(autoEscape=true){\n\t\tconst instance = this;\n\n\t\tautoEscape = orDefault(autoEscape, true, 'bool');\n\t\tthis.#autoEscape = autoEscape ? this.escape : val => val;\n\t\tthis.#autoUnescape = autoEscape ? decodeURIComponent : val => val;\n\n\t\t// procedure map, defining how data types are string-represented in Rison\n\t\tthis.#encoders = {\n\t\t\tarray(value){\n\t\t\t\tconst res = [];\n\n\t\t\t\tfor( let v of value ){\n\t\t\t\t\tconst encodedValue = instance.encode(v);\n\t\t\t\t\tif( isString(encodedValue) ){\n\t\t\t\t\t\tres.push(encodedValue);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn `!(${res.join(',')})`;\n\t\t\t},\n\n\t\t\tboolean(value){\n\t\t\t\treturn !!value ? '!t' : '!f';\n\t\t\t},\n\n\t\t\tnull(){\n\t\t\t\treturn '!n';\n\t\t\t},\n\n\t\t\tnumber(value){\n\t\t\t\tif( !isFinite(value) ) return '!n';\n\t\t\t\treturn `${value}`.replace(/\\+/, '');\n\t\t\t},\n\n\t\t\tobject(value){\n\t\t\t\tif( hasValue(value) ){\n\t\t\t\t\tif( isArray(value) ){\n\t\t\t\t\t\treturn this.array(value);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst keys = Object.keys(value);\n\t\t\t\t\tkeys.sort();\n\n\t\t\t\t\tconst res = [];\n\t\t\t\t\tfor( let key of keys ){\n\t\t\t\t\t\tconst v = instance.encode(value[key]);\n\t\t\t\t\t\tif( isString(v) ){\n\t\t\t\t\t\t\tconst k = isNaN(parseInt(key, 10)) ? this.string(key) : this.number(key);\n\t\t\t\t\t\t\tres.push(`${k}:${v}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn `(${res.join(',')})`;\n\t\t\t\t}\n\n\t\t\t\treturn '!n';\n\t\t\t},\n\n\t\t\tstring(value){\n\t\t\t\tif( value === '' ) return \"''\";\n\t\t\t\tif( URISON_VALUE_REX.test(value) ) return value;\n\n\t\t\t\tvalue = value.replace(/(['!])/g, function(_, quotedChar){\n\t\t\t\t\treturn `!${quotedChar}`;\n\t\t\t\t});\n\n\t\t\t\treturn `'${value}'`;\n\t\t\t}\n\t\t};\n\n\t\tthis.#parser = (new UrisonParser((error, index) => {\n\t\t\tthrow Error(`decoding error [${error}] at string index ${index}`);\n\t\t}));\n\t}\n\n\n\n\t/**\n\t * Encodes a JSON value to a Rison string.\n\t *\n\t * @param {Array|Object|String|Number|Boolean|null} value - the value to encode\n\t * @throws error if encoding fails or value is not usable JSON\n\t * @returns {String|undefined} the encoded Rison string or undefined if value cannot be encoded\n\t *\n\t * @example\n\t * (new Urison()).encode({key1 : 'value', key2 : true, key3 : [false, 42, null]})\n\t * => '(key1:value,key2:!t,key3:!(!f,42,!n))'\n\t */\n\tencode(value){\n\t\tconst __methodName__ = 'encode';\n\n\t\tif( isFunction(value?.toJson) ){\n\t\t\tvalue = value.toJson();\n\t\t}\n\n\t\tif( isFunction(value?.toJSON) ){\n\t\t\tvalue = value.toJSON();\n\t\t}\n\n\t\tconst encoder = this.#encoders[typeof value];\n\t\tif( !isFunction(encoder) ){\n\t\t\tthrow new Error(`${this.#__className__}.${__methodName__} | invalid data type`);\n\t\t}\n\n\t\tlet res;\n\t\ttry {\n\t\t\tres = encoder.call(this.#encoders, value);\n\t\t} catch(ex){\n\t\t\tthrow new Error(`${this.#__className__}.${__methodName__} | encoding error [${ex}]`);\n\t\t}\n\n\t\treturn this.#autoEscape(this.#autoUnescape(res));\n\t}\n\n\n\n\t/**\n\t * Encodes a JSON value to a Rison string.\n\t *\n\t * @param {Object} value - the object to encode\n\t * @returns {String|undefined} the encoded Rison string or undefined if value cannot be encoded\n\t * @throws error if value is not an object\n\t *\n\t * @example\n\t * (new Urison()).encodeObject({key1 : 'value', key2 : true, key3 : [false, 42, null]})\n\t * => 'key1:value,key2:!t,key3:!(!f,42,!n)'\n\t */\n\tencodeObject(value){\n\t\tconst __methodName__ = 'encodeObject';\n\n\t\tif( !isObject(value) ){\n\t\t\tthrow new Error(`${this.#__className__}.${__methodName__} | value is not an object`);\n\t\t}\n\n\t\tconst res = this.#encoders.object(value);\n\t\treturn this.#autoEscape(this.#autoUnescape(res.substring(1, res.length - 1)));\n\t}\n\n\n\n\t/**\n\t * Encodes a JSON array to a Rison string.\n\t *\n\t * @param {Array} value - the array to encode\n\t * @returns {String|undefined} the encoded Rison string or undefined if value cannot be encoded\n\t * @throws error if value is not an array\n\t *\n\t * @example\n\t * (new Urison()).encodeArray([false, 42, null])\n\t * => '!f,42,!n'\n\t */\n\tencodeArray(value){\n\t\tconst __methodName__ = 'encodeArray';\n\n\t\tif( !isArray(value) ){\n\t\t\tthrow new Error(`${this.#__className__}.${__methodName__} | value is not an array`);\n\t\t}\n\n\t\tconst res = this.#encoders.array(value);\n\t\treturn this.#autoEscape(this.#autoUnescape(res.substring(2, res.length - 1)));\n\t}\n\n\n\n\t/**\n\t * Decodes a Rison string to a JSON value.\n\t *\n\t * @param {String} risonString - the Rison string to decode\n\t * @returns {Object|Array|String|Number|Boolean|null} the decoded JSON value\n\t * @throws error if decoding fails\n\t *\n\t * @example\n\t * (new Urison()).decode('(key1:value,key2:!t,key3:!(!f,42,!n))')\n\t * => {key1 : 'value', key2 : true, key3 : [false, 42, null]}\n\t */\n\tdecode(risonString){\n\t\treturn this.#parser.parse(this.#autoUnescape(risonString));\n\t}\n\n\n\n\t/**\n\t * Decodes a shortened Rison object string to a JSON object.\n\t *\n\t * @param {String} risonString - the Rison object string to decode\n\t * @returns {Object} the decoded JSON object\n\t * @throws error if decoding fails\n\t *\n\t * @example\n\t * (new Urison()).decodeObject('key1:value,key2:!t,key3:!(!f,42,!n)')\n\t * => {key1 : 'value', key2 : true, key3 : [false, 42, null]}\n\t */\n\tdecodeObject(risonString){\n\t\treturn this.decode(`(${risonString})`);\n\t}\n\n\n\n\t/**\n\t * Decodes a shortened Rison array string to a JSON array.\n\t *\n\t * @param {String} risonString - the Rison array string to decode\n\t * @returns {Array} the decoded JSON array\n\t * @throws error if decoding fails\n\t *\n\t * @example\n\t * (new Urison()).decodeArray('!f,42,!n')\n\t * => [false, 42, null]\n\t */\n\tdecodeArray(risonString){\n\t\treturn this.decode(`!(${risonString})`);\n\t}\n\n\n\n\t/**\n\t * URI-Escapes a value, if necessary, according to the rules of Rison, which is a little bit\n\t * more lax than native uri encoding (allows [,:@$/+]).\n\t *\n\t * This method has one difference to the reference implementation:\n\t * We do _not_ encode whitespace as \"+\", but as \"%20\". This is done, because \"+\"-encoding is not\n\t * compatible with `decodeURIComponent` and makes working with URL-encoded values manually painful.\n\t * So here, \"+\" is just a normal, allowed URL-safe character and whitespace becomes \"%20\".\n\t * Since `encode_uri` was never automatically applied in Rison, this should not break anything.\n\t *\n\t * @param {String} value - the value to escape problematic chars in\n\t * @returns {String} uri-encoded string\n\t *\n\t * @example\n\t * (new Urison()).escape('abc,:@')\n\t * => 'abc%2C%3A%40'\n\t */\n\tescape(value){\n\t\tvalue = `${value}`;\n\n\t\tif( /^[\\-A-Za-z0-9~!*()_.',:@$\\/+]*$/.test(value) ) return value;\n\n\t\treturn replace(\n\t\t\tencodeURIComponent(value),\n\t\t\t['%2C', '%3A', '%40', '%24', '%2F', '%2B'],\n\t\t\t[',', ':', '@', '$', '/', '+']\n\t\t);\n\t}\n\n}\n\nexport {Urison};\n","/*!\n * Module Navigation\n */\n\n/**\n * @namespace Navigation\n */\n\nconst MODULE_NAME = 'Navigation';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {warn} from './logging.js';\nimport {hasValue, orDefault, isPlainObject, isArray, isWindow, isFunction, assert} from './basic.js';\nimport {createNode} from './elements.js';\nimport {browserSupportsHistoryManipulation} from './context.js';\nimport {urlHref} from './urls.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const HISTORY = {\n\tcurrent : {\n\t\tstate : null,\n\t\ttitle : '',\n\t\t...getHostAndPathname()\n\t},\n\tpopState : {\n\t\tlistening : false,\n\t\tcallbacks : [],\n\t\thandler(e){\n\t\t\tconst historyNew = {\n\t\t\t\tstate : e.state,\n\t\t\t\ttitle : e.title,\n\t\t\t\t...getHostAndPathname()\n\t\t\t};\n\n\t\t\tHISTORY.popState.callbacks.forEach(cb => {\n\t\t\t\tcb.stateful(e, historyNew);\n\t\t\t});\n\n\t\t\tHISTORY.current = historyNew;\n\t\t}\n\t}\n};\n\n\n\n//###[ HELPERS ]########################################################################################################\n\nfunction getHostAndPathname(){\n\tconst hostAndPathname = {\n\t\thost : undefined,\n\t\tpathname : undefined\n\t};\n\n\ttry {\n\t\thostAndPathname.host = window.location.host;\n\t\thostAndPathname.pathname = window.location.pathname;\n\t} catch(ex){\n\t\thostAndPathname.host = undefined;\n\t\thostAndPathname.pathname = undefined;\n\t}\n\n\treturn hostAndPathname;\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Navigation:redirect\n */\n\n/**\n * Everything you need to do basic navigation without history API.\n *\n * Provide a URL to navigate to or leave the URL out, to use the current full URL. See `urlHref` for details.\n *\n * Add GET-parameters (adding to those already present in the URL), define an anchor (or automatically get the one\n * defined in the URL), set a target to define a window to navigate to (or open a new one) and even\n * define POST-parameters to navigate while providing POST-data.\n *\n * Provided params have to be a flat plain object, with ordinal values or arrays of ordinal values on the first level.\n * Everything else will be stringified and url-encoded as is. Usually, parameters defined here add to present\n * parameters in the URL. To force-override present values, declare the param name with a \"!\" prefix\n * (`{'!presentparam' : 'new'}`).\n *\n * If you define POST-params to navigate to a URL providing POST-data we internally build a custom form element,\n * with type \"post\", filled with hidden fields adding the form data, which we submit to navigate to the action, which\n * contains our url. Even the target carries over.\n *\n * If you define a target window and therefore open a new tab/window this function adds \"noopener,noreferrer\"\n * automatically if the origins do not match to increase security. If you need the opener, have a look at\n * \"openWindow\", which gives you more manual control in that regard.\n *\n * If you define a target and open an external URL, repeated calls to the same target will open multiple windows\n * due to the security settings.\n *\n * @param {?String|URL} [url=null] - the location to load, if null current location is reloaded/used\n * @param {?Object} [params=null] - plain object of GET-parameters to add to the url\n * @param {?String} [anchor=null] - anchor/hash to set for called url, has precedence over URL hash\n * @param {?String} [target=null] - name of the window to perform the redirect to/in, use \"_blank\" to open a new window/tab\n * @param {?Object} [postParams=null] - plain object of postParameters to send with the redirect, solved with a hidden form\n * @param {?Boolean} [markListParams=false] - if true, params with more than one value will be marked with \"[]\" preceding the param name\n * @throws error if url is not usable\n *\n * @memberof Navigation:redirect\n * @alias redirect\n * @see Urls.urlHref\n * @example\n * redirect('https://test.com', {search : 'kittens', order : 'asc'}, 'fluffykittens');\n * redirect(null, {order : 'desc'});\n */\nexport function redirect(url=null, params=null, anchor=null, target=null, postParams=null, markListParams=false){\n\turl = urlHref(url, params, anchor, markListParams);\n\ttarget = orDefault(target, null, 'str');\n\tpostParams = isPlainObject(postParams) ? postParams : null;\n\n\n\tif( hasValue(postParams) ){\n\t\tconst formAttributes = {method : 'post', action : url, 'data-ajax' : 'false'};\n\t\tif( hasValue(target) ){\n\t\t\tformAttributes.target = target;\n\t\t}\n\n\t\tconst redirectForm = createNode('form', formAttributes);\n\t\tfor( let paramName in postParams ){\n\t\t\tif( isArray(postParams[paramName]) ){\n\t\t\t\tpostParams[paramName].forEach(val => {\n\t\t\t\t\tredirectForm.appendChild(createNode(\n\t\t\t\t\t\t'input',\n\t\t\t\t\t\t{type : 'hidden', name : `${paramName}[]`, value : `${val}`}\n\t\t\t\t\t));\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tredirectForm.appendChild(createNode(\n\t\t\t\t\t'input',\n\t\t\t\t\t{type : 'hidden', name : paramName, value : `${postParams[paramName]}`}\n\t\t\t\t));\n\t\t\t}\n\t\t}\n\n\t\tdocument.body.appendChild(redirectForm);\n\t\tredirectForm.submit();\n\t\tdocument.body.removeChild(redirectForm);\n\t} else if( hasValue(target) ){\n\t\tconst parsedUrl = new URL(url);\n\n\t\tif( parsedUrl.origin !== window.location.origin ){\n\t\t\t// we have to jump through hoops here, since adding security features to window.open\n\t\t\t// forces popup windows in some browsers and although we can set opener via the created\n\t\t\t// window, we cannot reliably set the referrer that way\n\t\t\tconst eLink = document.createElement('a');\n\t\t\teLink.href = url;\n\t\t\teLink.target = target;\n\t\t\teLink.rel = 'noopener noreferrer';\n\t\t\tdocument.body.appendChild(eLink);\n\t\t\teLink.click();\n\t\t\teLink.parentNode.removeChild(eLink);\n\t\t} else {\n\t\t\twindow.open(url, target);\n\t\t}\n\t} else {\n\t\twindow.location.assign(url);\n\t}\n}\n\n\n\n/**\n * @namespace Navigation:openTab\n */\n\n/**\n * Opens a sub-window for the current window as _blank, which should result in a new tab in most browsers.\n *\n * This method is just a shortcut for \"redirect\" with a set target and reasonable parameters.\n *\n * By using \"redirect\", this method also automatically takes care of adding \"noopener,noreferrer\" to external\n * links, which are determined by not having the same origin as the current location. For more manual control\n * over such parameters, have a look at \"openWindow\" instead.\n *\n * @param {?String} [url] - the location to load, if null current location is reloaded/used\n * @param {?Object} [params=null] - plain object of GET-parameters to add to the url, adds to existing ones in the URL and overwrites existing ones with same name\n * @param {?String} [anchor=null] - anchor/hash to set for called url, has precedence over URL hash\n * @param {?Object} [postParams=null] - plain object of postParameters to send with the redirect, solved with a hidden form\n *\n * @memberof Navigation:openTab\n * @alias openTab\n * @see redirect\n * @example\n * openTab('/misc/faq.html');\n */\nexport function openTab(url, params=null, anchor=null, postParams=null){\n\tredirect(url, params, anchor, '_blank', postParams);\n}\n\n\n\n/**\n * @namespace Navigation:openWindow\n */\n\n/**\n * Opens a sub-window for the current window or another defined parent window.\n * Be aware that most browsers open new windows as a tab by default, have a look at the \"tryAsPopup\"-parameter\n * if you need to open a new standalone window and your configuration results in new tabs instead.\n *\n * For window options (in this implementation, we consider \"name\" to be an option as well), see:\n * https://developer.mozilla.org/en-US/docs/Web/API/Window/open#window_features\n *\n * Keep in mind to set \"noopener\" and/or \"noreferrer\" for external URLs in options, to improve security and privacy.\n * Hint for older MS browsers: if you set these security options, these will most likely open the URL in a popup\n * window. If you want to circumvent this, you'll have to drop the \"noreferrer\" and settle for \"noopener\", by\n * setting opener to null on the returned window like this: `openWindow('url').opener = null;`\n *\n * @param {?String|URL} [url=null] - the URL to load in the new window, if nullish, the current URL is used\n * @param {?Object} [options=null] - parameters for the new window according to the definitions of window.open & \"name\" for the window name\n * @param {?Window} [parentWindow=null] - parent window for the new window, current if not defined\n * @param {?Boolean} [tryAsPopup=false] - defines if it should be tried to force a real new window instead of a tab\n * @throws error if url is not usable\n * @returns {Window} the newly opened window/tab\n *\n * @memberof Navigation:openWindow\n * @alias openWindow\n * @see Urls.urlHref\n * @example\n * openWindow('/img/gallery.html');\n * openWindow('http://www.kittens.com', {name : 'kitten_popup'}, parent);\n */\nexport function openWindow(url=null, options=null, parentWindow=null, tryAsPopup=false){\n\turl = urlHref(url);\n\toptions = isPlainObject(options) ? options : null;\n\tparentWindow = isWindow(parentWindow) ? parentWindow : window;\n\ttryAsPopup = orDefault(tryAsPopup, false, 'bool');\n\n\tlet\twindowName = '';\n\tconst optionArray = [];\n\n\tif( hasValue(options) ){\n\t\tfor( let prop in options ){\n\t\t\tif( prop === 'name' ){\n\t\t\t\twindowName = options[prop];\n\t\t\t}\n\n\t\t\tif( (prop !== 'name') || tryAsPopup ){\n\t\t\t\tif( [true, 1, 'yes'].includes(options[prop]) ){\n\t\t\t\t\toptionArray.push(`${prop}`);\n\t\t\t\t} else {\n\t\t\t\t\toptionArray.push(`${prop}=${options[prop]}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn parentWindow.open(url, windowName, optionArray.join(','));\n}\n\n\n\n/**\n * @namespace Navigation:reload\n */\n\n/**\n * Reloads the current window-location. Differentiates between cached and cache-refreshing reload.\n * Hint: the forcedReload param in window.location.reload is deprecated and not supported anymore in all browsers,\n * so, in order to do a cache busting reload we have to use a trick, by using a POST-reload, since POST never\n * gets cached. If, for some reason, you cannot POST to a URL, I also provided a second, less effective fallback,\n * using \"replace\".\n *\n * Hint: depending on your browser a cached reload may keep the current scrolling position in the document, while\n * the uncached variants won't\n *\n * @param {?Boolean} [cached=true] - should we use the cache on reload?\n * @param {?Boolean} [postUsable=true] - if set to false, we try to replace URL instead of POSTing to it\n *\n * @memberof Navigation:reload\n * @alias reload\n * @example\n * // with cache\n * reload();\n * // without cache via POST\n * reload(false);\n * // without cache via \"replace\"\n * reload(false, false);\n */\nexport function reload(cached=true, postUsable=true){\n\tcached = orDefault(cached, true, 'bool');\n\tpostUsable = orDefault(postUsable, true, 'bool');\n\n\tif( !cached && postUsable ){\n\t\tconst form = document.createElement('form');\n\t\tform.method = 'post';\n\t\tform.action = window.location.href;\n\t\tdocument.body.appendChild(form);\n\t\tform.submit();\n\t\tdocument.body.removeChild(form);\n\t} else if( !cached && !postUsable ){\n\t\twindow.location.replace(window.location.href);\n\t} else {\n\t\twindow.location.reload();\n\t}\n}\n\n\n\n/**\n * @namespace Navigation:changeCurrentUrl\n */\n\n/**\n * Changes the current URL by using the history API (this means, we can only change to a path on the same origin).\n * Be aware that this replaces the current URL in the history _without_ any normal navigation or reload.\n * This method only works if the history API is supported by the browser, otherwise no navigation will occur\n * (but a warning will be shown in console).\n * For more details on the history API see:\n * https://developer.mozilla.org/en-US/docs/Web/API/History\n *\n * @param {?String|URL} [url=null] - a url to change the current address to on the same origin, will use current URL if nullish\n * @param {?Boolean} [usePushState=false] - push new state instead of replacing current\n * @param {?*} [state=null] - a serializable object to append to the history state (gets retrieved on popState-event)\n * @param {?String} [title=null] - a name/title for the new state (as of yet, only Safari uses this, other browser will return undefined)\n * @throws error if state is not serializable by browser\n *\n * @memberof Navigation:changeCurrentUrl\n * @alias changeCurrentUrl\n * @see onHistoryChange\n * @see Urls.urlHref\n * @example\n * changeCurrentUrl('/article/important-stuff', false, {id : 666});\n */\nexport function changeCurrentUrl(url=null, usePushState=false, state=null, title=null){\n\turl = urlHref(url);\n\tusePushState = orDefault(usePushState, false, 'bool');\n\ttitle = orDefault(title, '', 'str');\n\n\tif ( browserSupportsHistoryManipulation() ) {\n\t\tif( usePushState ){\n\t\t\twindow.history.pushState(state, title, url);\n\t\t} else {\n\t\t\twindow.history.replaceState(state, title, url);\n\t\t}\n\n\t\tHISTORY.current = {\n\t\t\tstate,\n\t\t\ttitle,\n\t\t\thost : window.location.host,\n\t\t\tpath : window.location.pathname\n\t\t};\n\t} else {\n\t\twarn(`${MODULE_NAME}:changeCurrentUrl | this browser does not support history api, skipping`);\n\t}\n}\n\n\n\n/**\n * @namespace Navigation:onHistoryChange\n */\n\n/**\n * Registers an onpopstate event if history API is available (does nothing and warns if not available).\n * Takes a callback, which is provided with states as plain objects like: {state, title, host, path}.\n * Hint: do not rely on title, since that property may only be supported by browsers like Safari,\n * serialize everything important into state and use title as orientation only.\n *\n * In case of a regular binding all callbacks get the current state, so the state that is being changed to, but\n * if you set \"usePreviousState\" to true and prior navigation was done with \"changeCurrentUrl\", all callbacks\n * get two states: \"from\" and \"to\". With this you can define rules an behaviour depending on the state you are\n * coming from. Keep in mind: this only works if you use \"changeCurrentUrl\" for navigation in tandem with this method.\n *\n * @param {Function} callback - function to execute on popstate\n * @param {?Boolean} [clearOld=false] - defines if old handlers should be removed before setting new one\n * @param {?Boolean} [usePreviousState=false] - defines if callbacks should be provided with previous state as well (in that case, changeCurrentUrl must have been used for prior navigation)\n * @throws error if callback is no function\n *\n * @memberof Navigation:onHistoryChange\n * @alias onHistoryChange\n * @see changeCurrentUrl\n * @see offHistoryChange\n * @example\n * onHistoryChange(function(){ alert('Hey, don\\'t do this!'); }, true);\n */\nexport function onHistoryChange(callback, clearOld=false, usePreviousState=false){\n\tconst __methodName__ = 'onHistoryChange';\n\n\tclearOld = orDefault(clearOld, false, 'bool');\n\tusePreviousState = orDefault(usePreviousState, false, 'bool');\n\n\tassert(isFunction(callback), `${MODULE_NAME}:${__methodName__} | callback is no function`);\n\n\tif ( browserSupportsHistoryManipulation() ) {\n\t\tif( clearOld ){\n\t\t\tHISTORY.popState.callbacks = [];\n\t\t}\n\n\t\tconst statefulCallback = function(e, historyNew){\n\t\t\tif( usePreviousState ){\n\t\t\t\tcallback(HISTORY.current, historyNew);\n\t\t\t} else {\n\t\t\t\tcallback(historyNew);\n\t\t\t}\n\t\t};\n\n\t\tHISTORY.popState.callbacks.push({\n\t\t\toriginal : callback,\n\t\t\tstateful : statefulCallback\n\t\t});\n\n\t\tif( !HISTORY.popState.listening ){\n\t\t\tHISTORY.popState.listening = true;\n\n\t\t\twindow.addEventListener('popstate',\tHISTORY.popState.handler);\n\t\t}\n\t} else {\n\t\twarn(`${MODULE_NAME}:${__methodName__} | this browser does not support history api, skipping`);\n\t}\n}\n\n\n\n/**\n * @namespace Navigation:offHistoryChange\n */\n\n/**\n * Removes registered history change handlers, that have been created with \"onHistoryChange\".\n * If a callback is provided, that callback is removed from callbacks, if the function is called\n * without parameters all callbacks are removed and the event listener for the callbacks is removed.\n *\n * @param {?Function} [callback=true] - reference to the callback to be removed, if missing all callbacks are removed\n * @throws error if callback is no function\n * @return {Boolean} true if callback(s) are/were removed, false if nothing was done\n *\n * @memberof Navigation:offHistoryChange\n * @alias offHistoryChange\n * @see changeCurrentUrl\n * @see onHistoryChange\n * @example\n * offHistoryChange(thatOneCallback);\n * offHistoryChange();\n */\nexport function offHistoryChange(callback=null){\n\tconst __methodName__ = 'offHistoryChange';\n\n\tif( hasValue(callback) ){\n\t\tassert(isFunction(callback), `${MODULE_NAME}:${__methodName__} | callback is not a function`);\n\n\t\tconst oldCallbackCount = HISTORY.popState.callbacks.length;\n\t\tHISTORY.popState.callbacks = HISTORY.popState.callbacks.reduce((cbs, cb) => {\n\t\t\tif( cb.original !== callback ){\n\t\t\t\tcbs.push(cb);\n\t\t\t}\n\n\t\t\treturn cbs;\n\t\t}, []);\n\t\tconst newCallbackCount = HISTORY.popState.callbacks.length;\n\n\t\tif( newCallbackCount === 0 ){\n\t\t\twindow.removeEventListener('popstate', HISTORY.popState.handler);\n\t\t\tHISTORY.popState.listening = false;\n\t\t}\n\n\t\treturn oldCallbackCount > newCallbackCount;\n\t} else {\n\t\tHISTORY.popState.callbacks = [];\n\t\twindow.removeEventListener('popstate', HISTORY.popState.handler);\n\t\tHISTORY.popState.listening = false;\n\n\t\treturn true;\n\t}\n}\n","/*!\n * Module Cookies\n */\n\n/**\n * @namespace Cookies\n */\n\nconst MODULE_NAME = 'Cookies';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {assert, isDate, orDefault, hasValue} from './basic.js';\nimport {warn} from './logging.js';\n\n\n\n//###[ HELPERS ]########################################################################################################\n\n/*\n * Encodes a string to be stored in a cookie.\n *\n * @private\n */\nfunction encodeCookieValue(value){\n\treturn encodeURIComponent(value).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g, decodeURIComponent);\n}\n\n\n\n/*\n * Decodes a cookie value to be used as a string in JavaScript.\n *\n * @private\n */\nfunction decodeCookieValue(value){\n\tif( value[0] === '\"' ){\n\t\tvalue = value.slice(1, -1);\n\t}\n\treturn value.replace(/(%[\\dA-F]{2})+/gi, decodeURIComponent);\n}\n\n\n\n/*\n * Makes sure a cookie name conforms to the cookie name rules and translates special chars to % representations.\n *\n * @private\n */\nfunction encodeCookieName(name){\n\treturn encodeURIComponent(`${name}`)\n\t\t.replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent)\n\t\t// using escape, because encodeURIComponent, indeed, does _not_ encode brackets\n\t\t.replace(/[()]/g, escape)\n\t;\n}\n\n\n\n/*\n * Decodes a cookie name, set prior with encodeCookieName to a standard JavaScript string again.\n *\n * @private\n */\nfunction decodeCookieName(name){\n\treturn decodeURIComponent(name);\n}\n\n\n\n/**\n * @typedef CookieOptions\n * @type {Object}\n *\n * @property {?Date|Number} [expires=null] - expiry time of the cookie, either a Date object or time in days\n * @property {?Number} [max-age=null] - max age of the cookie in seconds\n * @property {?String} [path='/'] - the cookie path, setting this to \"auto\" or an empty string defines auto-mode, which targets the current site path, which usually is the default, but we use '/' to set a cookie for while site, this being the common use-case\n * @property {?Boolean} [secure=false] - define if the cookie should only be transmitted via https (see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies)\n * @property {?Boolean} [httponly=false] - define this, if cookie should only be sent to servers and not be accessible to javascript (see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies)\n * @property {?String} [samesite=null] - define if this cookie should be included in cross-site requests, may be either \"strict\" (will only ever transmit same-site), \"lax\" (usual browser default, transmits same-site and top-level GET) or \"none\" (no restrictions, will always be sent)\n *\n * @memberof Cookies\n */\n\n/*\n * Makes sure, that supplied cookie options are in a usable form for setting a cookie.\n *\n * @private\n */\nfunction normalizeCookieOptions(options){\n\toptions = orDefault(options, {});\n\n\tconst normalizedOptions = {};\n\tfor( let optionsProp in options ){\n\t\tnormalizedOptions[optionsProp.toLowerCase()] = options[optionsProp];\n\t}\n\toptions = normalizedOptions;\n\n\tif( hasValue(options.expires) ){\n\t\tif( !isDate(options.expires) ){\n\t\t\toptions.expires = new Date(Date.now() + (Math.round(parseFloat(options.expires)) * 24 * 60 * 60 * 1000));\n\t\t}\n\t\toptions.expires = options.expires.toUTCString();\n\t} else {\n\t\toptions.expires = null;\n\t}\n\n\toptions['max-age'] = orDefault(options['max-age'], null, 'int');\n\n\toptions.path = orDefault(options.path, '/', 'str');\n\tif( options.path === 'auto' ){\n\t\toptions.path = '';\n\t}\n\n\toptions.domain = orDefault(options.domain, null, 'str');\n\n\toptions.httponly = orDefault(options.httponly, false, 'bool');\n\n\toptions.samesite = orDefault(options.samesite, 'lax', 'str').toLowerCase();\n\tif( !['strict', 'lax', 'none'].includes(options.samesite) ){\n\t\tconsole.warn(`${MODULE_NAME}:setCookie | unknown samesite mode \"${options.samesite}\"`);\n\t}\n\n\toptions.secure = orDefault(options.secure, options.samesite === 'none', 'bool');\n\n\treturn options;\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Cookies:getCookie\n */\n\n/**\n * Retrieves a decoded cookie value by name. Automatically decodes the value (assumes, that, if encoded, url/percent\n * encoding has been used).\n *\n * @param {?String|Array} [name] - the name of the cookie (or several names), if empty, all available cookies are returned\n * @returns {String|Object|null} decoded value of the cookie, null, if no such cookie available or a dictionary of found cookies if all or a list are being returned (if a list is requested and non are found, an empty object is returned)\n *\n * @memberof Cookies:getCookie\n * @alias getCookie\n * @see getCookies\n * @see setCookie\n * @see removeCookie\n * @example\n * getCookie('foobar')\n * => 'value'\n * getCookie(['foobar', 'boofar'])\n * => {foobar : 'value', boofar : 'value'}\n * getCookie()\n * => all available cookies\n */\nexport function getCookie(name){\n\tconst\n\t\tnames = hasValue(name) ? new Set([].concat(name).map(n => n.trim())) : new Set(),\n\t\tfoundNames = new Set()\n\t;\n\n\tlet res = (names.size === 0) ? {} : null;\n\tif( !hasValue(document.cookie) ) return res;\n\n\tconst cookies = document.cookie.split(';');\n\tfor( let i in cookies ){\n\t\ttry {\n\t\t\tconst\n\t\t\t\tcookie = cookies[i].trim(),\n\t\t\t\tcookieParts = cookie.split('='),\n\t\t\t\tcookieName = decodeCookieName(cookieParts[0]).trim(),\n\t\t\t\tcookieValue = decodeCookieValue(cookieParts.slice(1).join('='))\n\t\t\t;\n\n\t\t\tif( (cookieName !== '') && (names.has(cookieName) || (names.size === 0)) ){\n\t\t\t\tif( res === null ){\n\t\t\t\t\tres = {};\n\t\t\t\t}\n\n\t\t\t\tres[cookieName] = cookieValue;\n\t\t\t\tfoundNames.add(cookieName);\n\n\t\t\t\tif( (foundNames.size === names.size) && (names.size !== 0) ){\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch(ex){\n\t\t\twarn(`${MODULE_NAME}:getCookie | decoding cookie \"${cookies[i]}\" failed with \"${ex}\"`)\n\t\t}\n\t}\n\n\tif( names.size === 1 ){\n\t\treturn res?.[name] ?? null;\n\t} else {\n\t\treturn res;\n\t}\n}\n\n\n\n/**\n * @namespace Cookies:getCookies\n */\n\n/**\n * Retrieve decoded cookie values by name. If no name is provided, all available cookie are being returned.\n * Automatically decodes the values (assumes, that, if encoded, url/percent encoding has been used).\n *\n * You can provide names as an array or as comma-separated parameters.\n *\n * @param {?String|Array} [names] - the names of the cookies, if empty or not set, all available cookies are returned\n * @returns {Object} dictionary of named decoded values of the cookies, will be empty if none of the cookies were available\n *\n * @memberof Cookies:getCookies\n * @alias getCookies\n * @see getCookie\n * @see setCookie\n * @see removeCookie\n * @example\n * getCookies(['foobar', 'boofar'])\n * => {foobar : 'value', boofar : 'value'}\n * getCookies('foobar', 'boofar')\n * => {foobar : 'value', boofar : 'value'}\n * getCookie()\n * => all available cookies\n */\nexport function getCookies(names){\n\tnames = [];\n\tArray.from(arguments).forEach(argument => {\n\t\tnames = names.concat(argument);\n\t});\n\n\treturn getCookie(names);\n}\n\n\n\n/**\n * @namespace Cookies:setCookie\n */\n\n/**\n * Set a cookie value (if possible) by name. Value will automatically be encoded.\n *\n * If you set a cookie to a nullish value, the method will try to remove the cookie with the given options.\n *\n * @param {String} name - the name of the cookie to set\n * @param {?String} [value] - the value of the cookie to set\n * @param {?Cookies.CookieOptions} [options] - the cookie options to apply\n * @returns {String|null} returns the set cookie value if available after setting or null if cookie not available (which would also mean, that setting the cookie did not work, or, in case of removal, that the removal worked)\n *\n * @memberof Cookies:setCookie\n * @alias setCookie\n * @see getCookie\n * @see getCookies\n * @see removeCookie\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie#write_a_new_cookie\n * @example\n * setCookie('mykittencookie', 'meow meow', {expires : 7, path : '/kittens', secure : true, samesite : 'strict'});\n */\nexport function setCookie(name, value, options){\n\tassert(hasValue(name) && (name !== ''), `${MODULE_NAME}:setCookie | no usable name`);\n\n\tname = `${name}`.trim();\n\tvalue = hasValue(value) ? encodeCookieValue(orDefault(value, '', 'str')) : null;\n\toptions = normalizeCookieOptions(options);\n\n\tlet cookieOptions = '';\n\tfor( let optionsProp in options ){\n\t\tconst option = options[optionsProp];\n\n\t\tif( !hasValue(option) || (option === false) ) continue;\n\n\t\tcookieOptions += `; ${optionsProp}`;\n\n\t\tif( option === true ) continue;\n\n\t\t// if the value itself contains a semicolon, according to RFC 6265 section 5.2,\n\t\t// we use everything that comes before the semicolon as the value and drop the rest\n\t\tcookieOptions += `=${option.split(';')[0]}`;\n\t}\n\n\tif( hasValue(value) ){\n\t\tdocument.cookie = `${encodeCookieName(name)}=${value}${cookieOptions}`;\n\t} else {\n\t\tremoveCookie(name, options);\n\t}\n\n\treturn getCookie(name);\n}\n\n\n\n/**\n * @namespace Cookies:removeCookie\n */\n\n/**\n * Removes a cookie (if possible) by name.\n *\n * @param {String} name - the name of the cookie to remove\n * @param {?Cookies.CookieOptions} [options] - the cookie options to apply (needed for different paths/domains for example)\n * @returns {Boolean} true if cookie is not available anymore after removal, if this is false, cookie removal failed or another cookie of the same name is still available\n *\n * @memberof Cookies:removeCookie\n * @alias removeCookie\n * @see getCookie\n * @see getCookies\n * @see setCookie\n * @example\n * removeCookie('mykittencookie', {path : '/kittens'});\n */\nexport function removeCookie(name, options){\n\tassert(hasValue(name) && (name !== ''), `${MODULE_NAME}:removeCookie | no usable name`);\n\n\toptions = normalizeCookieOptions(options);\n\toptions.expires = -1;\n\n\treturn (setCookie(name, '', options) === null);\n}\n","/*!\n * Module Images\n */\n\n/**\n * @namespace Images\n */\n\nconst MODULE_NAME = 'Images';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {orDefault, isArray, isPlainObject, assert, isEmpty, isElement, hasValue, Deferred} from './basic.js';\nimport {waitForRepaint} from './timers.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst PRELOADED_IMAGES = {\n\tunnamed : [],\n\tnamed : {}\n};\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Images:preload\n */\n\n/**\n * Preloads images by URL, so that subsequent usages are served from browser cache.\n * Images can be preloaded anonymously or with a given name. So you can either just use the url again,\n * or, to be super-sure, call the method again, with just the image name to get the preloaded image itself.\n *\n * The function returns a Deferred, which resolves, after the images have loaded, with either an array of preloaded\n * images or a single image, if only one has been defined. The Deferred contains all images newly created for\n * preloading on the provision property before the Deferred resolves.\n *\n * @param {(String|String[]|Object.)} images - a URL, an array of URLs or a plain object containing named URLs. In case the string is an already used name, the image object from the named preloaded images cache is returned.\n * @returns {Basic.Deferred|Image} either a Deferred, resolving after images are preloaded, or a requested cached image\n *\n * @memberof Images:preload\n * @alias preload\n * @example\n * preload([url1, url2, url3]).then(images => { alert(`loaded ${images.length} images`); });\n * const provisionalImage preload({name1 : url1, name2 : url2}}).provision.name1;\n * const preloadedImage = preload('name1');\n */\nexport function preload(images){\n\tconst\n\t\tpreloadedImages = [],\n\t\tdeferred = new Deferred()\n\t;\n\tlet newImages;\n\n\tif( !isPlainObject(images) && !isArray(images) ){\n\t\timages = `${images}`;\n\n\t\tif( hasValue(PRELOADED_IMAGES.named[images]) ){\n\t\t\treturn PRELOADED_IMAGES.named[images];\n\t\t} else {\n\t\t\timages = [images];\n\t\t}\n\t}\n\n\tif( isPlainObject(images) ){\n\t\tnewImages = {};\n\n\t\tObject.entries(images).forEach(([key, value]) => {\n\t\t\tkey = `${key}`;\n\t\t\tvalue = `${value}`;\n\n\t\t\tif( !hasValue(PRELOADED_IMAGES.named[key]) ){\n\t\t\t\tnewImages[key] = new Image();\n\t\t\t\tnewImages[key].src = value;\n\t\t\t\tpreloadedImages.push(newImages[key]);\n\t\t\t}\n\t\t});\n\n\t\tPRELOADED_IMAGES.named = {...PRELOADED_IMAGES.named, ...newImages};\n\t} else if( isArray(images) ){\n\t\tnewImages = [];\n\n\t\timages.forEach(value => {\n\t\t\tconst newImage = new Image();\n\t\t\tnewImage.src = `${value}`;\n\t\t\tnewImages.push(newImage);\n\t\t\tpreloadedImages.push(newImage);\n\t\t});\n\n\t\tPRELOADED_IMAGES.unnamed = Array.from(new Set(PRELOADED_IMAGES.unnamed.concat(newImages)));\n\t}\n\n\tdeferred.provision = (isArray(newImages) && (newImages.length === 1)) ? newImages[0] : newImages;\n\tloaded(preloadedImages)\n\t\t.then(deferred.resolve)\n\t\t.catch(deferred.reject)\n\t;\n\n\treturn deferred;\n}\n\n\n\n/**\n * @namespace Images:loaded\n */\n\n/**\n * Fixes problems with image \"load\" events and fires the event even in case the image is already loaded or served from\n * browser cache. So repeated calls to this method on the same loaded image will actually work.\n *\n * Also supports imgs inside picture elements, while automatically handling the polyfills respimage and picturefill if\n * present in window. Make sure to apply this method to the img _inside_ the picture and _not_ on the picture itself!\n *\n * Define \"dimensionsNeeded\" if your definition of \"loaded\" includes, that the loaded image should already have usable\n * image dimensions for layouting. Use this, if you need to do calculations based on image dimensions after load.\n * Dimensions are determined using the images \"naturalWidth\".\n *\n * The function returns a Deferred, which resolves, after the images have loaded, with either an array of loaded\n * images or a single image, if only one has been defined. The Deferred contains all initially given images on the\n * provision property before the Deferred resolves.\n *\n * @param {Image|Array} images - an image or an array of images\n * @param {?Boolean} [dimensionsNeeded=false] - tells the check if we expect the loaded image to have readable dimensions\n * @returns {Basic.Deferred} a Deferred, resolving after all given images have loaded\n *\n * @memberof Images:loaded\n * @alias loaded\n * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalWidth\n * @example\n * loaded(image).then(image => { image.classList.remove('hidden'); });\n * loaded([image1, image2, image3]).then(images => { alert(`all ${images.length} images have loaded`); })\n */\nexport function loaded(images, dimensionsNeeded=false){\n\tconst __methodName__ = 'loaded';\n\n\timages = orDefault(images, [], 'arr').filter(image => {\n\t\treturn Object.prototype.toString.call(image).slice(8, -1).toLowerCase() === 'htmlimageelement';\n\t});\n\tdimensionsNeeded = orDefault(dimensionsNeeded, false, 'bool');\n\n\tfunction onLoad(e){\n\t\tconst image = e.currentTarget;\n\t\tif( !dimensionsNeeded || (dimensionsNeeded && (image.naturalWidth > 0)) ){\n\t\t\tloadCount--;\n\t\t\tif( loadCount <= 0 ){\n\t\t\t\timages.map(image => {\n\t\t\t\t\timage.removeEventListener('load', onLoad);\n\t\t\t\t\timage.removeEventListener('error', onError);\n\t\t\t\t});\n\t\t\t\tloaderImages.map(image => {\n\t\t\t\t\timage.removeEventListener('load', onLoad);\n\t\t\t\t\timage.removeEventListener('error', onError);\n\t\t\t\t});\n\t\t\t\tdeferred.resolve((images.length === 1) ? images[0] : images);\n\t\t\t}\n\t\t} else {\n\t\t\twaitForRepaint(() => { onLoad(e); });\n\t\t}\n\t}\n\n\tfunction onError(error){\n\t\timages.map(image => {\n\t\t\timage.removeEventListener('load', onLoad);\n\t\t\timage.removeEventListener('error', onError);\n\t\t});\n\t\tloaderImages.map(image => {\n\t\t\timage.removeEventListener('load', onLoad);\n\t\t\timage.removeEventListener('error', onError);\n\t\t});\n\t\tdeferred.reject(error);\n\t}\n\n\tconst\n\t\tdeferred = new Deferred(),\n\t\tloaderImages = []\n\t;\n\tlet loadCount = images.length;\n\n\tdeferred.provision = (images.length === 1) ? images[0] : images;\n\timages.forEach(image => {\n\t\timage.removeEventListener('load', onLoad);\n\t\timage.addEventListener('load', onLoad);\n\t\timage.removeEventListener('error', onError);\n\t\timage.addEventListener('error', onError);\n\n\t\tconst\n\t\t\tsrc = image.src,\n\t\t\tparent = image.parentNode,\n\t\t\tisPicture = isElement(image.parentNode) ? (parent.nodeName.toLowerCase() === 'picture') : false\n\t\t;\n\n\t\tassert(!isEmpty(src), `${MODULE_NAME}:${__methodName__} | image has no src`);\n\n\t\tif( isPicture || !!image.complete ){\n\t\t\tlet img;\n\n\t\t\tif( isPicture ){\n\t\t\t\tif( window.respimage ){\n\t\t\t\t\twindow.respimage({elements : [parent]});\n\t\t\t\t\timg = parent.querySelector('img');\n\t\t\t\t} else if( window.picturefill ){\n\t\t\t\t\twindow.picturefill({elements : [parent]});\n\t\t\t\t\timg = parent.querySelector('img');\n\t\t\t\t} else {\n\t\t\t\t\timg = image;\n\t\t\t\t}\n\n\t\t\t\tif( !!img.complete ){\n\t\t\t\t\timg = new Image();\n\t\t\t\t\timg.addEventListener('load', onLoad);\n\t\t\t\t\timg.addEventListener('error', onError);\n\t\t\t\t\timg.src = src;\n\t\t\t\t\tloaderImages.push(img);\n\t\t\t\t} else {\n\t\t\t\t\timg.removeEventListener('load', onLoad);\n\t\t\t\t\timg.addEventListener('load', onLoad);\n\t\t\t\t\timg.removeEventListener('error', onError);\n\t\t\t\t\timg.addEventListener('error', onError);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\timg = new Image();\n\t\t\t\timg.addEventListener('load', onLoad);\n\t\t\t\timg.addEventListener('error', onError);\n\t\t\t\timg.src = src;\n\t\t\t\tloaderImages.push(img);\n\t\t\t}\n\t\t}\n\t});\n\n\treturn deferred;\n}\n","/*!\n * Module Fonts\n */\n\n/**\n * @namespace Fonts\n */\n\nconst MODULE_NAME = 'Fonts';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {hasValue, orDefault, Deferred} from './basic.js';\nimport {createNode} from './elements.js';\nimport {applyStyles} from './css.js';\nimport {loop, countermand} from './timers.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Fonts:waitForWebfonts\n */\n\n/**\n * Waits for a list of webfonts to load. This includes the fact, that the font is ready to display and renders in the\n * browser's rendering engine and not just a completed request or a loaded resource.\n *\n * Also works for fonts, that have already been loaded.\n *\n * @param {String|String[]} fonts - the CSS-names of the fonts to wait for\n * @param {?String} [fallbackFontName=sans-serif] - the system font which the page falls back on if the webfont is not loaded\n * @param {?Number} [timeout=5000] - timeout in ms after which the call fails and the return value rejects\n * @returns {Basic.Deferred|String>} a Deferred, that resolves once all webfonts are available and rejects when the timeout is reached\n *\n * @memberof Fonts:waitForWebfonts\n * @alias waitForWebfonts\n * @example\n * waitForWebfonts(['purr-regular', 'scratch-light'], 'helvetica, sans-serif')\n * .then(fonts => {\n * document.body.classList.add('webfonts-loaded');\n * alert(`${fonts.length} webfonts ready to render`);\n * })\n * .catch(error => {\n * if( error.message === 'timeout' ){\n * document.body.classList.add('webfonts-timeout');\n * }\n * })\n * ;\n */\nexport function waitForWebfonts(fonts, fallbackFontName='sans-serif', timeout=5000){\n\tfonts = orDefault(fonts, [], 'arr').map(font => `${font}`);\n\tfallbackFontName = orDefault(fallbackFontName, 'sans-serif', 'string');\n\ttimeout = orDefault(timeout, 5000, 'int');\n\n\tconst\n\t\tdeferred = new Deferred(),\n\t\tstart = Date.now(),\n\t\tfDimsAreIdentical = (dims1, dims2) => ((dims1.width === dims2.width) && (dims1.height === dims2.height))\n\t;\n\tlet\tloadedFonts = 0;\n\n\tfonts.forEach(font => {\n\t\tlet node = createNode('span', null, 'giItT1WQy@!-/#');\n\t\tapplyStyles(node, {\n\t\t\t'position' : 'absolute',\n\t\t\t'visibility' : 'hidden',\n\t\t\t'left' : '-10000px',\n\t\t\t'top' : '-10000px',\n\t\t\t'font-size' : '300px',\n\t\t\t'font-family' : fallbackFontName,\n\t\t\t'font-variant' : 'normal',\n\t\t\t'font-style' : 'normal',\n\t\t\t'font-weight' : 'normal',\n\t\t\t'letter-spacing' : '0',\n\t\t\t'white-space' : 'pre',\n\t\t\t'line-height' : 1\n\t\t});\n\t\tdocument.body.appendChild(node);\n\n\t\tconst systemFontDims = {\n\t\t\twidth : node.offsetWidth,\n\t\t\theight : node.offsetHeight\n\t\t};\n\t\tapplyStyles(node, {'font-family' : `${font}, ${fallbackFontName}`});\n\n\t\tlet fontLoadedCheckTimer = null;\n\t\tconst fCheckFont = () => {\n\t\t\tif( (Date.now() - start) >= timeout ){\n\t\t\t\tcountermand(fontLoadedCheckTimer);\n\t\t\t\tif( hasValue(node) ){\n\t\t\t\t\tdocument.body.removeChild(node);\n\t\t\t\t\tnode = null;\n\t\t\t\t}\n\t\t\t\tdeferred.reject(new Error('timeout'));\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif(\n\t\t\t\thasValue(node)\n\t\t\t\t&& !fDimsAreIdentical({width : node.offsetWidth, height : node.offsetHeight}, systemFontDims)\n\t\t\t){\n\t\t\t\tcountermand(fontLoadedCheckTimer);\n\t\t\t\tdocument.body.removeChild(node);\n\t\t\t\tnode = null;\n\t\t\t\tloadedFonts++;\n\t\t\t}\n\n\t\t\tif( loadedFonts >= fonts.length ){\n\t\t\t\tdeferred.resolve((fonts.length === 1) ? fonts[0] : fonts);\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\t\tif( !fCheckFont() ){\n\t\t\tfontLoadedCheckTimer = loop(100, fCheckFont);\n\t\t}\n\t});\n\n\treturn deferred;\n}\n","/*!\n * Module Interaction\n */\n\n/**\n * @namespace Interaction\n */\n\nconst MODULE_NAME = 'Interaction';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {assert, isFunction, isElement, orDefault, hasValue, Deferred} from './basic.js';\nimport {findTextNodes} from './elements.js';\nimport {applyStyles} from './css.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const TAPPABLE_ELEMENTS_SELECTOR = 'a, button, .button, input[type=button], input[type=submit]';\nconst NOT_AN_HTMLELEMENT_ERROR = 'given node/target is not an HTMLElement';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Interaction:createSelection\n */\n\n/**\n * Programmatically create a text selection inside a node, possibly reaching across several child nodes,\n * but virtually only working with the raw text content. Can also be used to create a selection in text\n * inputs for example.\n *\n * Be aware that the endOffset is neither the length to select nor the last index, but the offset starting\n * from the last character in the node counting backwards (like a reverse startOffset). The reason for this wonkyness\n * is the fact that we have to implement three different ways of creating selections in this function, this\n * notation being the most compatible one. We assume the default use case for this method is to select all content\n * of a node with the possibility to skip one or two unwanted characters on each side of the content.\n *\n * Hint: You cannot create a selection spanning normal inline text into an input, ending there. To create a selection in\n * a text input, please target that element specifically or make sure the selection spans the whole input.\n * Furthermore, on mobile/iOS devices creation of selection ranges might only be possible in text inputs.\n *\n * @param {HTMLElement} node - the element to create a selection inside\n * @param {?Number} [startOffset=0] - characters to leave out at the beginning of the text content\n * @param {?Number} [endOffset=0] - characters to leave out at the end of the text content\n * @return {String} the selected text\n *\n * @memberof Interaction:createSelection\n * @alias createSelection\n * @see removeSelections\n * @example\n * const selectedText = createSelection(copytextElement, 12, 6);\n */\nexport function createSelection(node, startOffset=0, endOffset=0){\n\tconst __methodName__ = 'createSelection';\n\n\tstartOffset = orDefault(startOffset, 0, 'int');\n\tendOffset = orDefault(endOffset, 0, 'int');\n\n\tassert(isElement(node), `${MODULE_NAME}:${__methodName__} | ${NOT_AN_HTMLELEMENT_ERROR}`);\n\n\tlet\tselectionText, range, selection, rangeText;\n\n\tif( hasValue(node.selectionStart, node.selectionEnd) ){\n\t\tnode.focus();\n\t\tnode.select();\n\t\trangeText = node.value;\n\t\tnode.selectionStart = startOffset;\n\t\tnode.selectionEnd = rangeText.length - endOffset;\n\t\tselectionText = rangeText.substring(node.selectionStart, node.selectionEnd);\n\t} else if( isFunction(window.getSelection) ){\n\t\trange = document.createRange();\n\t\trange.selectNodeContents(node);\n\n\t\tif( hasValue(startOffset) || hasValue(endOffset) ){\n\t\t\tconst textNodes = findTextNodes(node);\n\t\t\tif( textNodes.length > 0 ){\n\t\t\t\tlet\n\t\t\t\t\tstartNodeIndex = 0,\n\t\t\t\t\tstartNode = textNodes[startNodeIndex],\n\t\t\t\t\tendNodeIndex = textNodes.length - 1,\n\t\t\t\t\tendNode = textNodes[endNodeIndex]\n\t\t\t\t;\n\n\t\t\t\tif( hasValue(startOffset) ){\n\t\t\t\t\tlet\n\t\t\t\t\t\tremainingStartOffset = startOffset,\n\t\t\t\t\t\tstartOffsetNodeFound = (remainingStartOffset <= startNode.length)\n\t\t\t\t\t;\n\n\t\t\t\t\twhile( !startOffsetNodeFound && hasValue(startNode) ){\n\t\t\t\t\t\tstartNodeIndex++;\n\t\t\t\t\t\tif( hasValue(textNodes[startNodeIndex]) ){\n\t\t\t\t\t\t\tremainingStartOffset -= startNode.length;\n\t\t\t\t\t\t\tstartNode = textNodes[startNodeIndex];\n\t\t\t\t\t\t\tstartOffsetNodeFound = (remainingStartOffset <= startNode.length);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tremainingStartOffset = startNode.length;\n\t\t\t\t\t\t\tstartOffsetNodeFound = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\trange.setStart(startNode, remainingStartOffset);\n\t\t\t\t}\n\n\t\t\t\tif( hasValue(endOffset) ){\n\t\t\t\t\tlet\n\t\t\t\t\t\tremainingEndOffset = endOffset,\n\t\t\t\t\t\tendOffsetNodeFound = (remainingEndOffset <= endNode.length)\n\t\t\t\t\t;\n\n\t\t\t\t\twhile( !endOffsetNodeFound && hasValue(endNode) ){\n\t\t\t\t\t\tendNodeIndex--;\n\t\t\t\t\t\tif( hasValue(textNodes[endNodeIndex]) ){\n\t\t\t\t\t\t\tremainingEndOffset -= endNode.length;\n\t\t\t\t\t\t\tendNode = textNodes[endNodeIndex];\n\t\t\t\t\t\t\tendOffsetNodeFound = (remainingEndOffset <= endNode.length);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tremainingEndOffset = endNode.length;\n\t\t\t\t\t\t\tendOffsetNodeFound = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\trange.setEnd(endNode, endNode.length - remainingEndOffset);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tselection = window.getSelection();\n\t\tselection.removeAllRanges();\n\t\tselection.addRange(range);\n\t\tselectionText = range.toString();\n\t} else if( isFunction(document.body.createTextRange) ){\n\t\trange = document.body.createTextRange();\n\t\trange.moveToElementText(node);\n\n\t\tif( hasValue(startOffset) ){\n\t\t\trange.moveStart('character', startOffset);\n\t\t}\n\n\t\tif( hasValue(endOffset) ){\n\t\t\trange.moveEnd('character', -endOffset);\n\t\t}\n\n\t\trange.select();\n\n\t\tselectionText = range.text;\n\t}\n\n\treturn selectionText;\n}\n\n\n\n/**\n * @namespace Interaction:removeSelections\n */\n\n/**\n * Removes all text selections from the current window if possible.\n * Certain mobile devices like iOS devices might block this behaviour actively.\n *\n * @memberof Interaction:removeSelections\n * @alias removeSelections\n * @see createSelection\n * @example\n * removeSelections();\n */\nexport function removeSelections(){\n\tif( isFunction(window.getSelection) ){\n\t\twindow.getSelection().removeAllRanges();\n\t} else if( isFunction(document.getSelection) ){\n\t\tdocument.getSelection().removeAllRanges();\n\t}\n\n\tif( hasValue(document.selection) ){\n\t\tdocument.selection.empty();\n\t}\n}\n\n\n\n/**\n * @namespace Interaction:disableSelection\n */\n\n/**\n * Disables the possibility to create a selection in an element.\n *\n * @param {HTMLElement} node - the element to disable user selection for\n * @return {HTMLElement} the node with disabled selection\n *\n * @memberof Interaction:disableSelection\n * @alias disableSelection\n * @see enableSelection\n * @example\n * disableSelection(widget);\n */\nexport function disableSelection(node){\n\tconst __methodName__ = 'disableSelection';\n\n\tassert(isElement(node), `${MODULE_NAME}:${__methodName__} | ${NOT_AN_HTMLELEMENT_ERROR}`);\n\n\tnode.onselectstart = () => false;\n\tnode.unselectable = 'on';\n\tapplyStyles(node, {'user-select' : 'none'}, true);\n\tapplyStyles(node, {'-webkit-touch-callout' : 'none'});\n\n\treturn node;\n}\n\n\n\n/**\n * @namespace Interaction:enableSelection\n */\n\n/**\n * (Re)enables the possibility to create a selection in an element. Most likely after having been disabled\n * using `disableSelection`.\n *\n * @param {HTMLElement} node - the element to (re)enable user selection for\n * @return {HTMLElement} the node with (re)enabled selection\n *\n * @memberof Interaction:enableSelection\n * @alias enableSelection\n * @see disableSelection\n * @example\n * enableSelection(widget);\n */\nexport function enableSelection(node){\n\tconst __methodName__ = 'disableSelection';\n\n\tassert(isElement(node), `${MODULE_NAME}:${__methodName__} | ${NOT_AN_HTMLELEMENT_ERROR}`);\n\n\tnode.onselectstart = undefined;\n\tnode.unselectable = 'off';\n\tapplyStyles(node, {'user-select' : null}, true);\n\tapplyStyles(node, {'-webkit-touch-callout' : null});\n\n\treturn node;\n}\n\n\n\n/**\n * @namespace Interaction:obfuscatePrivateMailToLink\n */\n\n/**\n * Augment a link element to hold an obfuscated private mailto link, to be able to contact people\n * via their own mail address, without the need to openly write the address into the DOM permanently,\n * in a way crawlers could identify easily.\n *\n * The method takes all parts of the address as (hopefully) unidentifiable parameters and then applies them internally,\n * to build an email string with mailto protocol dynamically on mouse or focus interaction in the link's href,\n * offering normal link functionality from here on. If the interaction ends, the href is removed again immediately,\n * so the link is only and exclusively readable and complete during user interaction.\n *\n * You may set the link text yourself or set `setAsContent` to true, to let the function fill the link text with\n * the completed address. Be aware, that this, although still being obfuscated, lowers the level of security for this\n * solution.\n *\n * Although most parameters are technically optional, this function still expects `beforeAt` and `afterAtWithoutTld` to\n * be filled. While these parts are strictly necessary here: I'd always suggest to use all parts, since, the more\n * of an address is written together, the easier the address can be parsed.\n *\n * @param {HTMLElement} link - the link to augment, has to be a node where we can set a \"href\" attribute\n * @param {?Boolean} [setAsContent=false] - define if the address should be used as link text (still uses string obfuscation, but weaker against bot with JS execution)\n * @param {?String} [tld=''] - the top level domain to use\n * @param {?String} [afterAtWithoutTld=''] - the address part after the @ but before the tld\n * @param {?String} [beforeAt=''] - the address part before the @\n * @param {?String} [subject=''] - the subject the mail should have, if you want to preset this\n * @param {?String} [body=''] - the body text the mail should have initially, if you want to preset this\n * @param {?String} [ccTld=''] - the top level domain to use for the cc address\n * @param {?String} [ccAfterAtWithoutTld=''] - the address part after the @ but before the tld for the cc address\n * @param {?String} [ccBeforeAt=''] - the address part before the @ for the cc address\n * @throws error if beforeAt or afterAtWithoutTld are empty\n * @return {HTMLElement} the augmented link\n *\n * @memberof Interaction:obfuscatePrivateMailToLink\n * @alias obfuscatePrivateMailToLink\n * @example\n * obfuscatePrivateMailToLink(document.querySelector('a'), true, 'de', 'gmail', 'recipient', 'Hello there!', 'How are you these days?');\n */\nexport function obfuscatePrivateMailToLink(\n\tlink,\n\tsetAsContent=false,\n\ttld='',\n\tafterAtWithoutTld='',\n\tbeforeAt='',\n\tsubject='',\n\tbody='',\n\tccTld='',\n\tccAfterAtWithoutTld='',\n\tccBeforeAt=''\n){\n\tconst __methodName__ = 'obfuscatePrivateMailToLink';\n\n\tsetAsContent = orDefault(setAsContent, false, 'bool');\n\tsubject = orDefault(subject, '', 'str');\n\tbody = orDefault(body, '', 'str');\n\tbeforeAt = orDefault(beforeAt, '', 'str');\n\tafterAtWithoutTld = orDefault(afterAtWithoutTld, '', 'str');\n\ttld = orDefault(tld, '', 'str');\n\tccBeforeAt = orDefault(ccBeforeAt, '', 'str');\n\tccAfterAtWithoutTld = orDefault(ccAfterAtWithoutTld, '', 'str');\n\tccTld = orDefault(ccTld, '', 'str');\n\n\tassert((beforeAt !== '') && (afterAtWithoutTld !== ''), `${MODULE_NAME}:${__methodName__} | basic mail parts missing`);\n\n\tif( tld !== '' ){\n\t\ttld = `.${tld}`;\n\t}\n\n\tif( ccTld !== '' ){\n\t\tccTld = `.${ccTld}`;\n\t}\n\n\tlet optionParams = new URLSearchParams();\n\tif( subject !== '' ){\n\t\toptionParams.set('subject', subject);\n\t}\n\tif( body !== '' ){\n\t\toptionParams.set('body', body);\n\t}\n\tif( (ccBeforeAt !== '') && (ccAfterAtWithoutTld !== '') ){\n\t\toptionParams.set('cc', `${ccBeforeAt}@${ccAfterAtWithoutTld}${ccTld}`);\n\t}\n\toptionParams = optionParams.toString();\n\tif( optionParams !== '' ){\n\t\toptionParams = `?${optionParams.replaceAll('+', '%20')}`;\n\t}\n\n\tlet interactionCount = 0;\n\tconst fAddLinkUrl = () => {\n\t\tinteractionCount++;\n\t\tlink.setAttribute('href', `mailto:${beforeAt}@${afterAtWithoutTld}${tld}${optionParams}`);\n\t};\n\tlink.addEventListener('mouseenter', fAddLinkUrl);\n\tlink.addEventListener('focusin', fAddLinkUrl);\n\tconst fRemoveLinkUrl = () => {\n\t\tinteractionCount--;\n\t\tif( interactionCount <= 0 ){\n\t\t\tlink.setAttribute('href', '');\n\t\t}\n\t};\n\tlink.addEventListener('mouseleave', fRemoveLinkUrl);\n\tlink.addEventListener('focusout', fRemoveLinkUrl);\n\n\tif( setAsContent ){\n\t\tlink.innerHTML = (`${beforeAt}@${afterAtWithoutTld}${tld}`).replace(/(\\w{1})/g, '$1‌');\n\t}\n\n\treturn link;\n}\n\n\n\n/**\n * @namespace Interaction:obfuscatePrivateTelLink\n */\n\n/**\n * Augment a link element to hold an obfuscated private tel link, to be able to contact people\n * via their own phone number, without the need to openly write the number into the DOM permanently,\n * in a way crawlers could identify easily.\n *\n * The method takes all parts of the number as (hopefully) unidentifiable parameters and then applies them internally,\n * to build a number string with tel protocol dynamically on mouse or focus interaction in the link's href,\n * offering normal link functionality from here on. If the interaction ends, the href is removed again immediately,\n * so the link is only and exclusively readable and complete during user interaction.\n *\n * You may set the link text yourself or set `setAsContent` to true, to let the function fill the link text with\n * the completed address. Be aware, that this, although still being obfuscated, lowers the level of security for this\n * solution.\n *\n * Although most parameters are technically optional, this function still expects `secondTelPart` or `firstTelPart` to\n * be filled. While only one part is strictly necessary here: I'd always suggest to use all parts, since, the more\n * of a number is written together, the easier the number can be parsed.\n *\n * @param {HTMLElement} link - the link to augment, has to be a node where we can set a \"href\" attribute\n * @param {?Boolean} [setAsContent=false] - define if the number should be used as link text, being formatted according to DIN 5008 (still uses string obfuscation, but weaker against bot with JS execution)\n * @param {?Number|String} [secondTelPart=''] - second half of the main number +49 04 123(4-56)<-this; add a dash to signify where a base number ends and the personal part starts\n * @param {?Number|String} [firstTelPart=''] - first half of the main number +49 04 (123)<-this 4-56\n * @param {?Number|String} [regionPart=''] - the local part of the number after the country part e.g. +49(04)<-this 1234-56\n * @param {?Number|String} [countryPart=''] - the country identifier with or without + this->(+49) 04 1234-56 (do not prefix with a local 0!)\n * @throws error if `secondTelPart` and `firstTelPart` are empty\n * @return {HTMLElement} the augmented link\n *\n * @memberof Interaction:obfuscatePrivateTelLink\n * @alias obfuscatePrivateTelLink\n * @example\n * obfuscatePrivateTelLink(document.querySelector('a'), true, 123, 439, 40, '+49');\n */\nexport function obfuscatePrivateTelLink(\n\tlink,\n\tsetAsContent=false,\n\tsecondTelPart='',\n\tfirstTelPart='',\n\tregionPart='',\n\tcountryPart=''\n){\n\tconst __methodName__ = 'obfuscatePrivateTelLink';\n\n\tsetAsContent = orDefault(setAsContent, false, 'bool');\n\tsecondTelPart = orDefault(secondTelPart, '', 'str').replace(/[^0-9\\-]/g, '');\n\tfirstTelPart = orDefault(firstTelPart, '', 'str').replace(/[^0-9\\-]/g, '');\n\tregionPart = orDefault(regionPart, '', 'str').replace(/[^0-9]/g, '');\n\tcountryPart = orDefault(countryPart, '', 'str').replace(/[^0-9]/g, '');\n\n\tassert((firstTelPart !== '') || (secondTelPart !== ''), `${MODULE_NAME}:${__methodName__} | basic tel parts missing`);\n\n\tlet interactionCount = 0;\n\tconst fAddLinkUrl = () => {\n\t\tinteractionCount++;\n\t\tlink.setAttribute('href', `tel:+${countryPart}${regionPart}${firstTelPart.replace(/-/g, '')}${secondTelPart.replace(/-/g, '')}`);\n\t};\n\tlink.addEventListener('mouseenter', fAddLinkUrl);\n\tlink.addEventListener('focusin', fAddLinkUrl);\n\tconst fRemoveLinkUrl = () => {\n\t\tinteractionCount--;\n\t\tif( interactionCount <= 0 ){\n\t\t\tlink.setAttribute('href', '');\n\t\t}\n\t};\n\tlink.addEventListener('mouseleave', fRemoveLinkUrl);\n\tlink.addEventListener('focusout', fRemoveLinkUrl);\n\n\tif( setAsContent ){\n\t\tlink.innerHTML = (`+${countryPart} ${regionPart} ${firstTelPart}${secondTelPart}`).replace(/(\\w{1})/g, '$1‌');\n\t}\n}\n\n\n\n/**\n * @namespace Interaction:setTappedState\n */\n\n/**\n * Sets a \"tapped\" state on an element (via a CSS class), which removes itself again after a short time.\n *\n * The sole reason for doing this, is to be able to apply styling to a tap/click action across devices without\n * trailing styles, which would result by using something like `:focus`.\n *\n * @param {HTMLElement} element - the link to augment, has to be a node where we can set a \"href\" attribute\n * @param {?String} [tappedClass='tapped'] - the CSS class to set on the element to signify the \"tapped\" state\n * @param {?Number} [tappedDuration=200] - the duration in milliseconds, the \"tapped\" state should last\n * @throws error if element is not an HTMLElement\n * @return {Basic.Deferred} resolves with the element, when the tapped state ends\n *\n * @memberof Interaction:setTappedState\n * @alias setTappedState\n * @example\n * setTappedState(link);\n * setTappedState(link, 'clicked', 500);\n */\nexport function setTappedState(element, tappedClass='tapped', tappedDuration=200){\n\tconst __methodName__ = 'setTappedState';\n\n\ttappedClass = orDefault(tappedClass, 'tapped', 'str');\n\ttappedDuration = orDefault(tappedDuration, 200, 'int');\n\n\tassert(isElement(element), `${MODULE_NAME}:${__methodName__} | ${NOT_AN_HTMLELEMENT_ERROR}`);\n\n\tconst deferred = new Deferred();\n\n\telement.classList.add(tappedClass);\n\twindow.setTimeout(() =>{\n\t\telement.classList.remove(tappedClass);\n\t\telement.blur();\n\t\tdeferred.resolve(element);\n\t}, tappedDuration);\n\n\treturn deferred;\n}\n\n\n\n/**\n * @namespace Interaction:setupAutoTappedStates\n */\n\n/**\n * This function registers a global event handler on the document body, to automatically add \"tapped\" states (as a CSS\n * class) to \"tappable\" elements on \"tap\".\n *\n * What is a \"tap\" you ask? Well, it's either a pointer click or a finger touch or anything resembling these actions\n * on your current device.\n *\n * The idea behind that is this: usually, on pointer devices, we have a `:hover` state to signify user interaction\n * with an element, while on touch devices, we only know that an interaction took place after a user touched an element\n * with his/her finger, \"tapped\" it so to speak. Styling a touch with CSS would only be possible via `:focus`, which\n * has the problems, that focus has a different meaning on pointer devices and the focus state does not end\n * automatically, resulting in trailing visual states.\n *\n * So, what we do instead, is that we just generally observe taps (via \"click\" event, which works across devices as\n * expected) and set a class on the element, for a short time, which removes itself automatically again, to be able\n * to define a visual state or a short animation for that class. So, for example, let's say the function has been\n * executed. After that, you can define something like `a.tapped { color: orange; }`, which would result in orange\n * coloring for a short time, after clicking/touching the element. Combine this with `:hover`, `:focus` definitions\n * in CSS to define a complete effect setup.\n *\n * @param {?HTMLElement} [element=document.body] - the element to use as delegation parent for events, should contain the tappable elements you'd like to target\n * @param {?String} [tappableElementsSelector='a, button, .button, input[type=button], input[type=submit]'] - selector to identify a tappable element by in a delegated event handler\n * @param {?String|Array} [tapEvents='click'] - the DOM event(s) to register for taps\n * @param {?String} [tappedClass='tapped'] - the CSS class to set on the element to signify the \"tapped\" state\n * @param {?Number} [tappedDuration=200] - the duration in milliseconds, the \"tapped\" state should last\n * @throws error if element is not an HTMLElement\n *\n * @memberof Interaction:setupAutoTappedStates\n * @alias setupAutoTappedStates\n * @example\n * setupAutoTappedStates();\n * setupAutoTappedStates(document.body, 'a, button', 'customevent');\n */\nexport function setupAutoTappedStates(\n\telement=null,\n\ttappableElementsSelector=TAPPABLE_ELEMENTS_SELECTOR,\n\ttapEvents='click',\n\ttappedClass='tapped',\n\ttappedDuration=200\n){\n\tconst __methodName__ = 'setupAutoTappedStates';\n\n\t// document.body not in function default to prevent errors on import in document-less contexts\n\telement = orDefault(element, document.body);\n\ttappableElementsSelector = orDefault(tappableElementsSelector, TAPPABLE_ELEMENTS_SELECTOR, 'str');\n\ttapEvents = orDefault(tapEvents, 'click', 'str');\n\ttapEvents = [].concat(tapEvents);\n\n\tassert(isElement(element), `${MODULE_NAME}:${__methodName__} | ${NOT_AN_HTMLELEMENT_ERROR}`);\n\n\ttapEvents.forEach(tapEvent => {\n\t\telement.addEventListener(tapEvent, e => {\n\t\t\tif(\n\t\t\t\thasValue(e.target?.matches)\n\t\t\t\t&& e.target.matches(tappableElementsSelector)\n\t\t\t){\n\t\t\t\tsetTappedState(e.target, tappedClass, tappedDuration);\n\t\t\t}\n\t\t});\n\t});\n}\n","import * as _polyfills from './polyfills.js';\nexport const polyfills = _polyfills;\n\nimport * as _logging from './logging.js';\nexport const logging = _logging;\n\nimport * as _basic from './basic.js';\nexport const basic = _basic;\n\nimport * as _strings from './strings.js';\nexport const strings = _strings;\n\nimport * as _arrays from './arrays.js';\nexport const arrays = _arrays;\n\nimport * as _objects from './objects.js';\nexport const objects = _objects;\n\nimport * as _conversion from './conversion.js';\nexport const conversion = _conversion;\n\nimport * as _random from './random.js';\nexport const random = _random;\n\nimport * as _timers from './timers.js';\nexport const timers = _timers;\n\nimport * as _functions from './functions.js';\nexport const functions = _functions;\n\nimport * as _units from './units.js';\nexport const units = _units;\n\nimport * as _dates from './dates.js';\nexport const dates = _dates;\n\nimport * as _events from './events.js';\nexport const events = _events;\n\nimport * as _context from './context.js';\nexport const context = _context;\n\nimport * as _polling from './polling.js';\nexport const polling = _polling;\n\nimport * as _elements from './elements.js';\nexport const elements = _elements;\n\nimport * as _forms from './forms.js';\nexport const forms = _forms;\n\nimport * as _animation from './animation.js';\nexport const animation = _animation;\n\nimport * as _viewport from './viewport.js';\nexport const viewport = _viewport;\n\nimport * as _urls from './urls.js';\nexport const urls = _urls;\n\nimport * as _navigation from './navigation.js';\nexport const navigation = _navigation;\n\nimport * as _requests from './requests.js';\nexport const requests = _requests;\n\nimport * as _cookies from './cookies.js';\nexport const cookies = _cookies;\n\nimport * as _css from './css.js';\nexport const css = _css;\n\nimport * as _images from './images.js';\nexport const images = _images;\n\nimport * as _fonts from './fonts.js';\nexport const fonts = _fonts;\n\nimport * as _interaction from './interaction.js';\nexport const interaction = _interaction;\n"],"names":["check","it","Math","global","globalThis","window","self","this","Function","fails","exec","error","descriptors","require$$0","Object","defineProperty","get","functionBindNative","test","bind","hasOwnProperty","NATIVE_BIND","call","prototype","functionCall","apply","arguments","$propertyIsEnumerable","propertyIsEnumerable","getOwnPropertyDescriptor","NASHORN_BUG","objectPropertyIsEnumerable","f","V","descriptor","enumerable","match","version","createPropertyDescriptor","bitmap","value","configurable","writable","FunctionPrototype","uncurryThisWithBind","functionUncurryThis","fn","uncurryThis","toString","stringSlice","slice","classofRaw","require$$1","classof","require$$2","$Object","split","indexedObject","isNullOrUndefined","$TypeError","TypeError","requireObjectCoercible","IndexedObject","toIndexedObject","documentAll","document","all","isCallable","undefined","argument","isObject","getBuiltIn","namespace","method","length","objectIsPrototypeOf","isPrototypeOf","engineUserAgent","navigator","String","userAgent","process","Deno","versions","v8","engineV8Version","V8_VERSION","$String","symbolConstructorDetection","getOwnPropertySymbols","symbol","Symbol","sham","useSymbolAsUid","iterator","isSymbol","require$$3","$Symbol","tryToString","aCallable","getMethod","P","func","defineGlobalProperty","key","SHARED","store","sharedStoreModule","exports","push","mode","copyright","license","source","shared","toObject","hasOwnProperty_1","hasOwn","id","postfix","random","uid","NATIVE_SYMBOL","require$$4","USE_SYMBOL_AS_UID","require$$5","WellKnownSymbolsStore","createWellKnownSymbol","withoutSetter","wellKnownSymbol","name","ordinaryToPrimitive","input","pref","val","valueOf","TO_PRIMITIVE","toPrimitive","result","exoticToPrim","toPropertyKey","EXISTS","createElement","documentCreateElement","ie8DomDefine","a","DESCRIPTORS","propertyIsEnumerableModule","require$$6","IE8_DOM_DEFINE","require$$7","$getOwnPropertyDescriptor","objectGetOwnPropertyDescriptor","O","v8PrototypeDefineBug","anObject","V8_PROTOTYPE_DEFINE_BUG","$defineProperty","ENUMERABLE","CONFIGURABLE","WRITABLE","objectDefineProperty","Attributes","current","definePropertyModule","createNonEnumerableProperty","object","getDescriptor","functionName","PROPER","functionToString","inspectSource","set","has","WeakMap","weakMapBasicDetection","keys","sharedKey","hiddenKeys","NATIVE_WEAK_MAP","OBJECT_ALREADY_INITIALIZED","state","metadata","facade","STATE","internalState","enforce","getterFor","TYPE","type","CONFIGURABLE_FUNCTION_NAME","enforceInternalState","getInternalState","replace","join","CONFIGURABLE_LENGTH","TEMPLATE","makeBuiltIn","makeBuiltInModule","options","getter","setter","arity","constructor","defineBuiltIn","simple","unsafe","nonConfigurable","nonWritable","ceil","floor","mathTrunc","trunc","x","n","toIntegerOrInfinity","number","max","min","toAbsoluteIndex","index","integer","toLength","len","lengthOfArrayLike","obj","createMethod","IS_INCLUDES","$this","el","fromIndex","arrayIncludes","includes","indexOf","objectKeysInternal","names","i","enumBugKeys","internalObjectKeys","concat","objectGetOwnPropertyNames","getOwnPropertyNames","objectGetOwnPropertySymbols","getOwnPropertyNamesModule","getOwnPropertySymbolsModule","ownKeys","getOwnPropertyDescriptorModule","copyConstructorProperties","target","exceptions","replacement","isForced","feature","detection","data","normalize","POLYFILL","NATIVE","string","toLowerCase","isForced_1","_export","targetProperty","sourceProperty","TARGET","GLOBAL","STATIC","stat","dontCallGetSet","forced","isArray","Array","createProperty","toStringTagSupport","TO_STRING_TAG_SUPPORT","TO_STRING_TAG","CORRECT_ARGUMENTS","tag","tryGet","callee","noop","construct","constructorRegExp","INCORRECT_TO_STRING","isConstructorModern","isConstructorLegacy","isConstructor","called","SPECIES","$Array","arraySpeciesConstructor","originalArray","C","arraySpeciesCreate","arrayMethodHasSpeciesSupport","METHOD_NAME","array","foo","Boolean","$","doesNotExceedSafeInteger","require$$8","require$$9","require$$11","IS_CONCAT_SPREADABLE","require$$10","IS_CONCAT_SPREADABLE_SUPPORT","isConcatSpreadable","spreadable","proto","arg","k","E","A","$location","defer","channel","port","engineIsNode","isPossiblePrototype","uncurryThisAccessor","aPossiblePrototype","objectSetPrototypeOf","setPrototypeOf","CORRECT_SETTER","__proto__","setToStringTag","TAG","defineBuiltInAccessor","setSpecies","CONSTRUCTOR_NAME","Constructor","anInstance","Prototype","aConstructor","speciesConstructor","defaultConstructor","S","functionApply","Reflect","functionUncurryThisClause","functionBindContext","that","html","arraySlice","validateArgumentsLength","passed","required","engineIsIos","IS_IOS","IS_NODE","setImmediate","clear","clearImmediate","Dispatch","MessageChannel","counter","queue","ONREADYSTATECHANGE","location","run","runner","eventListener","event","globalPostMessageDefer","postMessage","protocol","host","handler","args","nextTick","now","port2","port1","onmessage","addEventListener","importScripts","appendChild","removeChild","setTimeout","task","safeGetBuiltIn","Queue","head","tail","Queue$2","add","item","entry","next","notify","toggle","node","promise","then","engineIsIosPebble","Pebble","engineIsWebosWebkit","macrotask","IS_IOS_PEBBLE","IS_WEBOS_WEBKIT","MutationObserver","WebKitMutationObserver","Promise","microtask","flush","parent","domain","exit","enter","resolve","createTextNode","observe","characterData","microtask_1","perform","promiseNativeConstructor","engineIsDeno","engineIsBrowser","NativePromiseConstructor","IS_BROWSER","IS_DENO","NativePromiseConstructor$4","SUBCLASSING","NATIVE_PROMISE_REJECTION_EVENT","PromiseRejectionEvent","FORCED_PROMISE_CONSTRUCTOR","PROMISE_CONSTRUCTOR_SOURCE","GLOBAL_CORE_JS_PROMISE","FakePromise","promiseConstructorDetection","CONSTRUCTOR","REJECTION_EVENT","PromiseCapability","reject","$$resolve","$$reject","newPromiseCapability","Internal","OwnPromiseCapability","nativeThen","require$$12","require$$13","require$$14","require$$15","hostReportErrors","b","console","require$$17","require$$18","InternalStateModule","require$$19","require$$20","newPromiseCapabilityModule","require$$22","PROMISE","require$$21","NATIVE_PROMISE_SUBCLASSING","getInternalPromiseState","setInternalState","NativePromisePrototype","PromiseConstructor","PromisePrototype","newGenericPromiseCapability","DISPATCH_EVENT","createEvent","dispatchEvent","UNHANDLED_REJECTION","isThenable","callReaction","reaction","exited","ok","fail","rejection","onHandleUnhandled","isReject","notified","reactions","onUnhandled","reason","initEvent","isUnhandled","emit","unwrap","internalReject","done","internalResolve","wrapper","executor","onFulfilled","onRejected","PromiseWrapper","wrap","setSpecies$3","iterators","Iterators","ITERATOR","ArrayPrototype","isArrayIteratorMethod","getIteratorMethod","getIterator","usingIterator","iteratorMethod","iteratorClose","kind","innerResult","innerError","Result","stopped","ResultPrototype","iterate","iterable","unboundFunction","iterFn","step","AS_ENTRIES","IS_RECORD","IS_ITERATOR","INTERRUPTED","stop","condition","callFn","SAFE_CLOSING","iteratorWithReturn","return","from","checkCorrectnessOfIteration","SKIP_CLOSING","ITERATION_SUPPORT","promiseStaticsIncorrectIteration","capability","$promiseResolve","values","remaining","alreadyCalled","real","catch","race","r","capabilityReject","promiseResolve","promiseCapability","IS_MAP","IS_FILTER","IS_SOME","IS_EVERY","IS_FIND_INDEX","IS_FILTER_REJECT","NO_HOLES","callbackfn","specificCreate","boundFunction","create","arrayIteration","forEach","map","filter","some","every","find","findIndex","filterReject","$filter","callWithSafeIterationClosing","ENTRIES","arrayFrom","arrayLike","IS_CONSTRUCTOR","argumentsLength","mapfn","mapping","objectKeys","objectDefineProperties","defineProperties","Properties","props","activeXDocument","definePropertiesModule","PROTOTYPE","SCRIPT","IE_PROTO","EmptyConstructor","scriptTag","content","LT","NullProtoObjectViaActiveX","write","close","temp","parentWindow","NullProtoObject","ActiveXObject","iframeDocument","iframe","JS","style","display","src","contentWindow","open","F","objectCreate","UNSCOPABLES","addToUnscopables","$includes","addToUnscopables$1","IteratorPrototype","PrototypeOfArrayIteratorPrototype","arrayIterator","correctPrototypeGetter","getPrototypeOf","CORRECT_PROTOTYPE_GETTER","ObjectPrototype","objectGetPrototypeOf","BUGGY_SAFARI_ITERATORS","NEW_ITERATOR_PROTOTYPE","iteratorsCore","returnThis","iteratorCreateConstructor","IteratorConstructor","NAME","ENUMERABLE_NEXT","createIteratorConstructor","PROPER_FUNCTION_NAME","KEYS","VALUES","iteratorDefine","Iterable","DEFAULT","IS_SET","FORCED","CurrentIteratorPrototype","methods","KEY","getIterationMethod","KIND","defaultIterator","IterablePrototype","INCORRECT_VALUES_NAME","nativeIterator","anyNativeIterator","entries","createIterResultObject","defineIterator","ARRAY_ITERATOR","es_array_iterator","iterated","Arguments","nativeSlice","HAS_SPECIES_SUPPORT","start","end","fin","IE_BUG","TO_ENTRIES","IE_WORKAROUND","objectToArray","$values","finally","onFinally","isFunction","e","inheritIfRequired","dummy","Wrapper","NewTarget","NewTargetPrototype","MATCH","isRegexp","isRegExp","regexpFlags","hasIndices","ignoreCase","multiline","dotAll","unicode","unicodeSets","sticky","regExpFlags","RegExpPrototype","RegExp","regexpGetFlags","R","flags","$RegExp","UNSUPPORTED_Y","re","lastIndex","MISSED_STICKY","regexpStickyHelpers","BROKEN_CARET","regexpUnsupportedDotAll","regexpUnsupportedNcg","groups","getRegExpFlags","stickyHelpers","proxyAccessor","Target","Source","require$$16","UNSUPPORTED_DOT_ALL","UNSUPPORTED_NCG","NativeRegExp","SyntaxError","charAt","stringIndexOf","IS_NCG","re1","re2","CORRECT_NEW","BASE_FORCED","RegExpWrapper","pattern","rawFlags","handled","thisIsRegExp","patternIsRegExp","flagsAreUndefined","rawPattern","chr","named","brackets","ncg","groupid","groupname","handleNCG","raw","handleDotAll","setSpecies$2","nativeReplace","nativeExec","patchedExec","UPDATES_LAST_INDEX_WRONG","NPCG_INCLUDED","reCopy","group","str","charsAdded","strCopy","regexpExec","$toString","TO_STRING","nativeToString","NOT_GENERIC","INCORRECT_NAME","$getOwnPropertyNames","windowNames","objectGetOwnPropertyNamesExternal","getWindowNames","arrayBufferNonExtensible","ArrayBuffer","buffer","isExtensible","ARRAY_BUFFER_NON_EXTENSIBLE","$isExtensible","objectIsExtensible","freezing","preventExtensions","getOwnPropertyNamesExternalModule","FREEZING","REQUIRED","METADATA","setMetadata","objectID","weakData","meta","internalMetadataModule","enable","splice","fastKey","getWeakData","onFreeze","InternalMetadataModule","collection","common","IS_WEAK","ADDER","NativeConstructor","NativePrototype","exported","fixMethod","uncurriedNativeMethod","getConstructor","instance","HASNT_CHAINING","THROWS_ON_PRIMITIVES","ACCEPT_ITERABLES","BUGGY_ZERO","$instance","setStrong","defineBuiltIns","internalStateGetterFor","collectionStrong","first","last","size","define","previous","getEntry","removed","delete","prev","ITERATOR_NAME","getInternalCollectionState","getInternalIteratorState","init","notARegexp","correctIsRegexpLogic","regexp","error1","error2","notARegExp","correctIsRegExpLogic","searchString","charCodeAt","CONVERT_TO_STRING","pos","second","position","stringMultibyte","codeAt","STRING_ITERATOR","point","fixRegexpWellKnownSymbolLogic","SHAM","SYMBOL","DELEGATES_TO_SYMBOL","DELEGATES_TO_EXEC","execCalled","nativeRegExpMethod","nativeMethod","arg2","forceStringMethod","$exec","advanceStringIndex","regexpExecAbstract","regExpExec","nativeMatch","maybeCallNative","matcher","rx","res","fullUnicode","matchStr","SUBSTITUTION_SYMBOLS","SUBSTITUTION_SYMBOLS_NO_NAMED","getSubstitution","matched","captures","namedCaptures","tailPos","m","symbols","ch","capture","fixRegExpWellKnownSymbolLogic","REPLACE","REPLACE_KEEPS_$0","REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE","fixRegExpWellKnownSymbolLogic$2","_","UNSAFE_SUBSTITUTE","searchValue","replaceValue","replacer","functionalReplace","results","accumulatedResult","nextSourcePosition","j","replacerArgs","uncaughtFrozenStore","frozen","UncaughtFrozenStore","findUncaughtFrozen","InternalWeakMap","collectionWeak","isFrozen","isSealed","freeze","seal","IS_IE11","$WeakMap","WeakMapPrototype","nativeSet","nativeDelete","nativeHas","nativeGet","frozenArray","arrayIntegrityLevel","domIterables","CSSRuleList","CSSStyleDeclaration","CSSValueList","ClientRectList","DOMRectList","DOMStringList","DOMTokenList","DataTransferItemList","FileList","HTMLAllCollection","HTMLCollection","HTMLFormElement","HTMLSelectElement","MediaList","MimeTypeArray","NamedNodeMap","NodeList","PaintRequestList","Plugin","PluginArray","SVGLengthList","SVGNumberList","SVGPathSegList","SVGPointList","SVGStringList","SVGTransformList","SourceBufferList","StyleSheetList","TextTrackCueList","TextTrackList","TouchList","classList","DOMTokenListPrototype","domTokenListPrototype","arrayMethodIsStrict","$forEach","arrayForEach","DOMIterables","handlePrototype","CollectionPrototype","COLLECTION_NAME","handlePrototype$1","ArrayIteratorMethods","ArrayValues","whitespaces","ltrim","rtrim","stringTrim","trim","$trim","forcedStringTrimMethod","LOG_LEVELS","XLOG_CONTEXT_COUNTS","LOG_LEVEL","TRY_TO_LOG_TO_PARENT","LOG_CHAINABLE_OBJECT","__documentation_for_chainable_object_of_log_execution__","setLogLevel","level","log","tryToLogToParent","setting","assert","genericConsoleMethodWrapperFactory","count","dir","dirxml","dirXml","err","_toConsumableArray","groupCollapsed","groupEnd","info","profile","profileEnd","table","time","timeEnd","timeLog","timeStamp","trace","warn","genericConsoleMethodWrapper","_window$console","logLevel","_len","_key","ex","_window$console2","_window$console3","_window$console4","context","message","Error","stack","MODULE_NAME","orDefault","hasValue","countStringCharacters","getType","isEmpty","emptyValues","__additionalEmptyValues__","Set","hasMembers","memberNames","verbose","memberName","expression","defaultValue","caster","additionalEmptyValues","parseInt","parseFloat","deepType","_typeof","isA","isBoolean","isNumber","isInt","intVal","isNaN","checkForIdentity","isString","isPlainObject","isDate","isSet","isMap","isElement","isWindow","isEventTarget","removeEventListener","isSelector","fragment","createDocumentFragment","querySelector","minValue","maxValue","minMax","round","precision","power","pow","Deferred","_createClass","_this","_classCallCheck","STATUS_FULFILLED","STATUS_REJECTED","provision","status","isSettled","resolution","_className__","_value","_subscriptions","Observable","initialValue","_classPrivateFieldInitSpec","_classPrivateFieldSet","_classPrivateFieldGet","newValue","force","oldValue","isNewValue","s","subscription","closure","floatVal","prefix","idRex","maskFixes","mask","matches","$entries","nativeKeys","sameValue","is","y","SEARCH","nativeSearch","searcher","previousLastIndex","CORRECT_IS_REGEXP_LOGIC","startsWith","search","$$d","replaceAll","searchLength","advanceBy","endOfLastMatch","urlConstructorDetection","url","URL","params","searchParams","params2","URLSearchParams","pathname","sort","href","username","hash","$assign","assign","objectAssign","B","alphabet","T","maxInt","regexNonASCII","regexSeparators","OVERFLOW_ERROR","$RangeError","RangeError","fromCharCode","digitToBasic","digit","adapt","delta","numPoints","firstTime","baseMinusTMin","base","encode","output","extra","ucs2decode","currentValue","inputLength","bias","basicLength","handledCPCount","handledCPCountPlusOne","q","t","qMinusT","baseMinusT","comparefn","element","middle","left","right","llength","rlength","lindex","rindex","arraySort","USE_NATIVE_URL","require$$23","require$$24","require$$25","require$$26","require$$27","require$$29","require$$28","URL_SEARCH_PARAMS","URL_SEARCH_PARAMS_ITERATOR","getInternalParamsState","nativeFetch","NativeRequest","Headers","RequestPrototype","HeadersPrototype","decodeURIComponent","encodeURIComponent","shift","plus","sequences","percentSequence","bytes","percentDecode","sequence","deserialize","replacements","serialize","URLSearchParamsIterator","URLSearchParamsState","parseObject","parseQuery","bindURL","update","entryIterator","entryNext","query","attribute","attributes","updateURL","URLSearchParamsConstructor","URLSearchParamsPrototype","defineBuiltIns$1","append","$value","getAll","found","callback","headersHas","headersSet","wrapRequestOptions","headers","body","fetch","RequestConstructor","Request","EOF","toASCII","label","encoded","labels","URLSearchParamsModule","getState","getInternalURLState","getInternalSearchParamsState","NativeURL","numberToString","pop","unshift","INVALID_SCHEME","INVALID_HOST","INVALID_PORT","ALPHA","ALPHANUMERIC","DIGIT","HEX_START","OCT","DEC","HEX","FORBIDDEN_HOST_CODE_POINT","FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT","LEADING_C0_CONTROL_OR_SPACE","TRAILING_C0_CONTROL_OR_SPACE","TAB_AND_NEW_LINE","serializeHost","compress","ignore0","ipv6","maxIndex","maxLength","currStart","currLength","findLongestZeroSequence","C0ControlPercentEncodeSet","fragmentPercentEncodeSet","pathPercentEncodeSet","userinfoPercentEncodeSet","percentEncode","code","specialSchemes","ftp","file","http","https","ws","wss","isWindowsDriveLetter","normalized","startsWithWindowsDriveLetter","third","isSingleDot","segment","SCHEME_START","SCHEME","NO_SCHEME","SPECIAL_RELATIVE_OR_AUTHORITY","PATH_OR_AUTHORITY","RELATIVE","RELATIVE_SLASH","SPECIAL_AUTHORITY_SLASHES","SPECIAL_AUTHORITY_IGNORE_SLASHES","AUTHORITY","HOST","HOSTNAME","PORT","FILE","FILE_SLASH","FILE_HOST","PATH_START","PATH","CANNOT_BE_A_BASE_URL_PATH","QUERY","FRAGMENT","URLState","isBase","baseState","failure","urlString","parse","stateOverride","codePoints","bufferCodePoints","pointer","seenAt","seenBracket","seenPasswordToken","scheme","password","path","cannotBeABaseURL","isSpecial","includesCredentials","codePoint","encodedCodePoints","parseHost","shortenPath","numbersSeen","ipv4Piece","swaps","swap","address","pieceIndex","parseIPv6","partsLength","numbers","part","radix","ipv4","parts","parseIPv4","cannotHaveUsernamePasswordPort","pathSize","setHref","getOrigin","URLConstructor","origin","getProtocol","setProtocol","getUsername","setUsername","getPassword","setPassword","getHost","setHost","getHostname","setHostname","hostname","getPort","setPort","getPathname","setPathname","getSearch","setSearch","getSearchParams","getHash","setHash","URLPrototype","accessorDescriptor","nativeCreateObjectURL","createObjectURL","nativeRevokeObjectURL","revokeObjectURL","$$b","toJSON","nativeGetPrototypeOf","clone","_Array$from$","_Array$from$2","deep","seenReferences","seenCopies","targetType","arrayCopy","setCopy","WeakSet","mapCopy","Map","urlCopy","urlSearchParamsCopy","objectCopy","prop","childNodes","outerNode","innerHTML","outerHTML","firstChild","Date","getTime","cloneNode","merge","extensions","extension","deletePropertyOrThrow","firefox","engineFfVersion","engineIsIeOrEdge","webkit","engineWebkitVersion","internalSort","FF","IE_OR_EDGE","V8","WEBKIT","nativeSort","FAILS_ON_UNDEFINED","FAILS_ON_NULL","STRICT_METHOD","STABLE_SORT","v","itemsLength","items","arrayLength","getSortCompare","FUNCTION_NAME_EXISTS","nameRE","MDN_POLYFILL_BUG","endsWith","endPosition","thisNumberValue","NUMBER","NativeNumber","NumberPrototype","toNumber","maxCode","digits","NaN","NumberWrapper","primValue","toNumeric","Number","arrayBufferBasicDetection","DataView","NATIVE_ARRAY_BUFFER","Int8Array","Int8ArrayPrototype","Uint8ClampedArray","Uint8ClampedArrayPrototype","TypedArray","TypedArrayPrototype","TYPED_ARRAY_TAG","TYPED_ARRAY_CONSTRUCTOR","NATIVE_ARRAY_BUFFER_VIEWS","opera","TYPED_ARRAY_TAG_REQUIRED","TypedArrayConstructorsList","Uint8Array","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigIntArrayConstructorsList","BigInt64Array","BigUint64Array","getTypedArrayConstructor","isTypedArray","klass","arrayBufferViewCore","aTypedArray","aTypedArrayConstructor","exportTypedArrayMethod","property","ARRAY","TypedArrayConstructor","exportTypedArrayStaticMethod","isView","typedArrayConstructorsRequireWrappers","toIndex","sign","abs","EPSILON","INVERSE_EPSILON","floatRound","FLOAT_EPSILON","FLOAT_MAX_VALUE","FLOAT_MIN_VALUE","absolute","roundTiesToEven","Infinity","mathFround","fround","LN2","ieee754","pack","mantissaLength","exponent","mantissa","c","exponentLength","eMax","eBias","rt","unpack","nBits","arrayFill","endPos","IEEE754","ARRAY_BUFFER","DATA_VIEW","WRONG_INDEX","getInternalArrayBufferState","getInternalDataViewState","NativeArrayBuffer","$ArrayBuffer","ArrayBufferPrototype","$DataView","DataViewPrototype","fill","reverse","packIEEE754","unpackIEEE754","packInt8","packInt16","packInt32","unpackInt32","packFloat32","packFloat64","addGetter","view","isLittleEndian","intIndex","boolIsLittleEndian","byteLength","byteOffset","conversion","INCORRECT_ARRAY_BUFFER_NAME","testView","$setInt8","setInt8","getInt8","setUint8","detached","bufferState","bufferLength","offset","getUint8","getInt16","getUint16","getInt32","getUint32","getFloat32","getFloat64","setInt16","setUint16","setInt32","setUint32","setFloat32","setFloat64","arrayBuffer","isIntegralNumber","isInteger","isFinite","toPositiveInteger","toOffset","BYTES","toBigInt","prim","BigInt","isBigIntArray","typedArrayFrom","thisIsBigIntArray","arrayFromConstructorAndList","list","$length","TYPED_ARRAYS_CONSTRUCTORS_REQUIRES_WRAPPERS","ArrayBufferViewCore","ArrayBufferModule","toUint8Clamped","require$$30","require$$32","require$$31","nativeDefineProperty","nativeGetOwnPropertyDescriptor","BYTES_PER_ELEMENT","WRONG_LENGTH","isArrayBuffer","isTypedArrayIndex","wrappedGetOwnPropertyDescriptor","wrappedDefineProperty","typedArrayConstructorModule","CLAMPED","GETTER","SETTER","NativeTypedArrayConstructor","TypedArrayConstructorPrototype","addElement","typedArrayOffset","$len","arrayCopyWithin","copyWithin","to","inc","u$ArrayCopyWithin","exportTypedArrayMethod$m","$every","$fill","actualValue","typedArraySpeciesConstructor","fromSpeciesAndList","$find","predicate","$findIndex","searchElement","$indexOf","ArrayIterators","arrayValues","arrayKeys","arrayEntries","GENERIC","ITERATOR_IS_VALUES","typedArrayValues","$join","separator","$lastIndexOf","lastIndexOf","NEGATIVE_ZERO","arrayLastIndexOf","$map","REDUCE_EMPTY","IS_RIGHT","memo","arrayReduce","$reduce","$reduceRight","$set","WORKS_WITH_OBJECTS_AND_GENERIC_ON_TYPED_ARRAYS","TO_OBJECT_BUG","exportTypedArrayMethod$5","$some","ACCEPT_INCORRECT_ARGUMENTS","mod","expected","exportTypedArrayMethod$2","begin","beginIndex","$toLocaleString","toLocaleString","TO_LOCALE_STRING_BUG","Uint8ArrayPrototype","arrayToString","IS_NOT_ARRAY_METHOD","nativeJoin","SLUGIFY_LATINMAP","subject","tmp","searchTerm","pad","paddingCharacter","expectedLength","difference","characters","char","slugify","text","additionalMap","_ref","_additionalMap$char","maskForRegEx","glue","strings","template","_len2","_key2","idx","explicit","implicit","fResolve","formatters","int","float","format","literal","ref","formatter","formatterArg","keyParts","formatterParts","formatterName","fLookup","escape","textContent","suffix","fromEntries","codePointAt","$fromCodePoint","fromCodePoint","elements","SPLIT_WORKS_WITH_OVERWRITTEN_EXEC","originalExec","BUGGY","SPLIT","nativeSplit","internalSplit","limit","splitter","unicodeMatching","lim","p","z","UPPER_CHARS","LOWER_CHARS","NUMBERS","BASE_ALPHABETS","BASE64_ALPHABET","buildAlphabet","__methodName__","baseOrAlphabet","useChunks","_step","_iterator","_createForOfIteratorHelper","baseAlphabetKey","aBase64Index","bBase64Index","calculateNeededPages","availablePages","neededPages","charPoolSize","combinations","buildPageMap","remainder","quotient","pageMap","buildCharMap","pagedAlphabet","pagedBase","charMap","stringToBase64","btoa","TextEncoder","base64ToString","TextDecoder","decode","atob","base10toBaseX","baseXValue","baseXToBase10","base10Value","toBaseX","useCharacterMap","chunkSize","valueIsNumber","valueIsNegativeNumber","base64Value","_step2","_iterator2","chunks","chunkAlphabet","chunkSeparator","chunkStart","_i","_chunks","decodedValue","fromBaseX","inverseCharMap","_ref2","_slicedToArray","tokensByLength","tokenFound","_step3","_iterator3","token","_step4","_iterator4","RANDOM_UUIDS_USED_SINCE_RELOAD","DEFAULT_USER_CODE_ALPHABET","randomNumber","ceiling","randomUuid","withDashes","uuid","collisions","_window$crypto","_window$msCrypto","crypto","getRandomValues","msCrypto","_window$crypto2","_window$msCrypto2","_window$crypto$getRan","_window$crypto3","_window$crypto3$getRa","_window$msCrypto3","_window$msCrypto3$get","minLength","randomValue","reduce","sum","toISOString","removeFrom","fromList","rest","reducedArray","cannotBeEmptyMessage","generateChars","factor","range","diff","schedule","ms","oldTimer","countermand","pschedule","precise","waitStart","waitMilliSecs","fAdjustWait","reschedule","timer","loop","oldLoop","setInterval","isInterval","clearInterval","clearTimeout","requestAnimationFrame","_ref3","_window$requestAnimat","raf","webkitRequestAnimationFrame","mozRequestAnimationFrame","msRequestAnimationFrame","cancelAnimationFrame","_ref4","_ref5","_window$requestAnimat2","_window$cancelAnimati","caf","mozCancelAnimationFrame","waitForRepaint","ids","outer","inner","throttle","hasLeadingExecution","hasTrailingExecution","frameHasStarted","callsInFrame","delay","_arguments2","_this3","CURRENT_INTERACTION_TYPE","debounceTimer","_arguments","_this2","defaults","argNamesString","argNames","argName","applicableArgs","argIndex","kwargs","argNameIndex","INTERACTION_TYPE_DETECTION","touchHappening","touchEndingTimer","touchStartHandler","getValue","setValue","touchEndHandler","blurHandler","mouseMoveHandler","browserSupportsHistoryManipulation","history","pushState","replaceState","detectInteractionType","returnObservable","maxTouchPoints","getBrowserLanguage","_languageParts$","fallbackLanguage","language","languages","browserLanguages","browserLanguagePropertyKey","browserLanguage","languageParts","country","toUpperCase","getLocale","locale","isFallback","langAttr","documentElement","getAttribute","_localeParts$","localeParts","matchMedia","additionalTest","family","deviceType","platform","sandbox","visibility","opacity","pointerEvents","overflow","top","height","scrollbarEnforcer","width","scrollbarWidth","offsetWidth","EVENT_MAP","POST_MESSAGE_MAP","DEFAULT_NAMESPACE","SWIPE_DIRECTIONS","SWIPE_HANDLERS","SWIPE_TOUCH","startX","startY","endX","endY","EVENT_OPTION_SUPPORT","once","passive","signal","prepareEventMethodBaseParams","methodName","targets","events","handlerIsOptional","targetsAreEventTargets","delegatedTargetsAreSelectorsAndHaveAncestor","targetIndex","ancestor","normalizedEvents","normalizedEventIndex","prepareEventMethodAdditionalTargetInfo","prevTarget","nextTarget","hasDelegation","isDelegation","prepareEventMethodEventInfo","eventName","defaultNamespace","defaultEvent","eventParts","gatherTargetEvents","delegation","targetEvents","gatheredTargetEvents","nameSpaceScope","delegations","ns","ev","cleanUpEventMap","desertedTargets","targetNamespace","targetEvent","targetScope","handlerCount","handlers","delegationHandlerCount","desertedTarget","createDelegatedHandler","_e$target","delegationSelector","syntheticTarget","createHandlerRemover","_targetEvents$namespa","ignoreInvalidScope","handlerScope","removedHandlers","existingHandler","removedHandler","action","createSelfRemovingHandler","removeHandlers","removedCount","_targetEvents$namespa2","delegationScope","removeLocatedHandler","pauseHandlers","paused","pausedCount","_targetEvents$namespa3","pausedHandlers","pausedHandler","pauseLocatedHandlers","createSyntheticEvent","payload","bubbles","cancelable","EventConstructor","eventOptions","_objectSpread","CustomEvent","detail","syntheticTargetElements","querySelectorAll","resolvePostMessageTarget","_target","windowPostMessageHandler","_e$data","currentTarget","targetPostMessages","__AVA_ENV__","messageType","_targetPostMessages$m","on","_prepareEventMethodBa","removers","_prepareEventMethodAd","_defineProperty","_prepareEventMethodEv","remover","managedHandler","nonPauseAwareAction","createPauseAwareAction","eventListenerOptions","supportedOptions","option","compileEventListenerOptions","off","tryNativeRemoval","_prepareEventMethodBa2","_prepareEventMethodAd2","_prepareEventMethodEv2","removeDelegatedHandlers","pause","_prepareEventMethodBa3","_prepareEventMethodAd3","_prepareEventMethodEv3","pauseDelegatedHandlers","fire","_prepareEventMethodBa4","fireCount","_prepareEventMethodAd4","_prepareEventMethodEv4","syntheticEvent","onDomReady","readyState","wrappedCallback","offPostMessage","handlerCountBefore","h","handlerCountAfter","removePostMessageHandlers","_prepareEventMethodBa5","emitCount","_prepareEventMethodAd5","_prepareEventMethodEv5","offCount","contains","direction","eventNameSpace","_prepareEventMethodBa7","swipeHandler","_SWIPE_HANDLERS$get","dimensionFactor","hasToBeTouchDevice","_prepareEventMethodBa6","originalHandler","startOrEnd","changedTouches","screenX","screenY","updateSwipeTouch","offsetHeight","applyStyles","styles","crossBrowser","returnCssStyleDeclaration","vendorPrefixes","cssKey","cssValue","vendorPrefix","setProperty","removeProperty","cssValueToNumber","BROWSER_HAS_CSS_SCOPE_SUPPORT","urlValue","baseUrl","baseUrlSubstitution","urlValueRex","px","initial","getPropertyValue","remVal","NOT_AN_HTMLELEMENT_ERROR","createNode","setAttribute","insertNode","insertAdjacentElement","isInDom","getData","_properties","properties","attributeValue","JSON","_data$properties$","setData","dataSet","singleValue","singleKey","appliedValues","stringifiedValue","stringify","hasAttribute","removeAttribute","selector","onlyOne","scopeRex","fallbackScopeAttribute","findTextNodes","onlyFirstLevel","isValidTextNode","nodeType","extractTextNodes","textNodes","childNode","definition","boilerplateNode","inheritValue","addValue","rules","valueObj","rule","_rule$split2","_node$getAttribute","_methods$orDefault","_target$method$width","_target$method$height","client","scroll","class","measureClone","dimensions","classChanges","markerAttributesName","deferred","initResult","remove","removeClass","addClass","_properties2","removalDataSet","parentNode","createFetchRequest","_window$__ANNEX_USE_N","useNative","timeout","__ANNEX_USE_NATIVE_FETCH__","execute","_options$body","request","XMLHttpRequest","headerKeys","headerEntries","response","statusText","responseURL","responseText","json","blob","Blob","ontimeout","onload","getAllResponseHeaders","onerror","withCredentials","credentials","setRequestHeader","send","timeoutTimer","abortController","AbortController","abort","createJsonRequest","strict","contentType","resolveTo","insertTarget","dataId","_response$headers$get","responseContentType","_insertTarget$element","_insertTarget$positio","_invalidRequestMethodMessage","_dataValidationMessage","_baseUrl","_baseOptions","_useNative","_strict","_config","_RestfulJsonClient_brand","RestfulJsonClient","baseOptions","_classPrivateMethodInitSpec","_assertClassBrand","_toFlatEntries","_executeRequest","_executeRequestWithPayload","contentTypeHeader","header","flattenedEntries","_loop","entryKey","entryIndex","entryVal","entryValType","media","resolveSourcedOnInsert","sourceElementValue","fInsertAndResolve","css","_insertTarget$element3","_insertTarget$positio3","linkAttrs","rel","_response$headers$get3","selectAll","_response$headers$get4","_element","isWholeDocument","isDocument","fragmentNode","DOMParser","parseFromString","children","_insertTarget$element4","_insertTarget$positio4","js","_insertTarget$element2","_insertTarget$positio2","_response$headers$get2","tokenValue","tokenPlaceholder","fOnLoad","loadTimeout","at","_params","initCustomEvent","Event","_Element$prototype$ms","Element","msMatchesSelector","webkitMatchesSelector","LOCAL_FLOAT_SEPARATOR","LOCAL_THOUSAND_SEPARATOR","currency","currencyDisplay","Intl","NumberFormat","minPrecision","maxPrecision","useGrouping","minimumFractionDigits","maximumFractionDigits","useBinaryBase","thresh","units","unitIndex","DATE_PART_SETTERS_AND_GETTERS","local","year","month","date","hours","minutes","seconds","milliseconds","utc","timeZone","settersAndGetters","predefinedStyles","timezone","getTimezoneOffset","tokenMap","formattedDate","formatterOptions","dateStyle","timeStyle","DateTimeFormat","_invalidDateMessage","_paramInvalidOrOutOfRangeMessage","_date","_utc","_SaneDate_brand","SaneDate","initialValueOrYear","definedIndividualDateParts","hasDefinedIndividualDateParts","getVanillaDate","_parseIsoString","toIsoString","getISOString","getIsoString","_initialValueOrYear$t","_initialValueOrYear$t2","_initialValueOrYear$t3","_initialValueOrYear$g","_initialValueOrYear$g2","_createDatePartGettersAndSetters","_ref6","startingWith","asName","weekdays","day","getUTCDay","getDay","_padWithZero","withTimezone","getTimezone","withSeparator","getIsoDateString","getIsoTimeString","initialValueOrSaneDate","withMilliseconds","ownValue","compareValue","comparator","saneDate","dateCompareGetters","timeCompareGetters","millisecondsCompareGetter","compareGetters","compareGetter","compareTo","amount","partDict","_ref7","_ref8","amountMustBePositiveMessage","_ref9","_ref10","move","_this4","_ref11","_ref12","largestUnit","relative","negativeDelta","days","partName","clonedSaneDate","propertyConfig","_tryDatePartChange","isoString","timezoneOffset","isoStringParts","isoStringDateParts","isoStringTimezoneParts","offsetFactor","isoStringTimezoneTimeParts","isoStringTimeParts","isoStringSecondsParts","newDate","allDatePartGetters","sideEffect","datePartGetter","_SaneDate","POLLS","defaultLoop","activePollCount","activePolls","unpoll","poll","isActive","fCondition","fAction","fElseAction","newLoopMs","useOwnTimer","newPoll","elseAction","lastPollResult","changed","formDataOrForm","formData","FormData","formDataObject","fieldName","fieldValue","File","mimeType","RUNNING_TRANSITIONS","EasingFunctions","linear","easeInQuad","easeOutQuad","easeInOutQuad","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","_classChanges","_classChanges2","styleChanges","rejectOnInterruption","runningTransition","vendorPropertiesAdded","transitionDurationProperties","transitionProperties","timingProperties","transitionDefinition","transitionValue","elementStyles","getComputedStyle","timingProperty","sTimings","msTimings","longestTiming","timing","VISIBILITY_BASE_FPS","getBoundingClientRect","boundingClientRect","DOMRect","bottom","_handler","_elements","_targetFps","_pollTimer","SimplePollingObserver","_options$targetFps","targetFps","connect","disconnect","throttledUpdate","viewportWidth","innerWidth","viewportHeight","innerHeight","upperCut","lowerCut","visiblePixels","rootBounds","intersectionRect","intersectionRatio","_className__2","_eventNameSpace","_inViewport","_fullyInViewport","_upperBoundInViewport","_lowerBoundInViewport","_visiblePercent","_visiblePixels","_scrolledPercent","_autoScrolledUpdateObservable","_autoScrolledUpdateSubscription","_distancePixels","_distanceViewports","_autoDistanceUpdateObservable","_autoDistanceUpdateSubscription","_autoHandleTooLargeUpdatesObservable","_autoHandleTooLargeUpdatesSubscription","_deferredChange","_VisibilityState_brand","VisibilityState","calculateScrolled","calculateDistance","autoHandleTooLargeElements","POSITIVE_INFINITY","_triggerUpdateEvents","scrollHeight","viewportHashObservable","precisionUpdate","fpsMs","subscribe","scrolledPercent","_calculatePreciseUpdate","unsubscribe","distancePxToTop","distancePxToBottom","distancePx","distancePixels","distanceViewports","inViewport","fullyInViewport","upperBoundInViewport","lowerBoundInViewport","visiblePercent","_triggerEvent","_triggerChanged","_this8","enterEventName","leaveEventName","isInViewport","mustBeFullyInside","viewportBounds","bb","_className__3","_eventNameSpace2","_htmlElementRequiredMessage","_states","_started","_initialized","_granularity","_targetFps2","_throttledHandleScroll","_throttledHandleResize","_throttledHandleMutation","_throttledTriggerEvent","_thresholds","_observer","_refreshPoll","_documentMutationObserver","_viewportInfo","_viewportInfoReferenceScrollTop","_viewportInfoHash","_VisibilityObserver_brand","VisibilityObserver","granularity","forcePollingObserver","ObserverImplementation","_handleScroll","_handleResize","_handleMutation","_triggerEvent2","IntersectionObserver","_buildThresholds","_handleIntersections","threshold","_refreshViewportInfo","_registerEvents","_unregisterEvents","_startedSafeguard","unobserve","thresholds","onlyScroll","_window$scrollY3","newScrollTop","scrollY","pageYOffset","scrollTop","scrollDirection","fuzzyScrollDirection","bounds","_window$scrollY2","viewportInfoHash","_handlePoll","_this9","startAutoScrolledPercentUpdates","stopAutoScrolledPercentUpdates","stopAutoDistanceUpdates","startAutoDistanceUpdates","startAutoTooLargeUpdates","stopAutoTooLargeUpdates","childList","subtree","lazyFpsMs","_className__4","_handlerMustBeFunctionMessage","_handler2","_securedHandler","_breakpoints","_currentBreakpoint","_currentBreakpointReadOnly","_throttledHandleResize2","_BreakpointObserver_brand","BreakpointObserver","_this5","_classPrivateFieldGet2","_handleResize2","_this6","_registerEvents2","_unregisterEvents2","breakpoint","breakpointName","_classPrivateFieldGet3","breakpoints","additionalBreakpoints","_parseBreakpointList","_refreshCurrentBreakpoint","_this7","obsoleteBreakpoints","obsoleteBreakpointName","_this10","acceptOnlyNames","unusableBreakpointMessage","currentBreakpoint","breakpointWidth","durationMs","easing","scrollEvenIfFullyInViewport","cancelOnUserScroll","elementIsWindow","elementInDom","elementInViewport","_window$scrollY","cancelled","fCancelScroll","fScroll","timestamp","progress","scrollTo","COMMON_TOP_LEVEL_DOMAINS","URISON_VALUE_FORMAT","URISON_VALUE_REX","URISON_NEXT_VALUE_REX","_errorHandler","_string","_index","_message","_bangTokens","_tokenMap","_UrisonParser_brand","UrisonParser","errorHandler","_parseArray","_instance$index","_instance$index2","_error","_next","_instance$index3","_readValue","segments","numberTypeMap","numberType","permittedSigns","risonString","detailMessage","trailingChar","_this$index","mapper","urlHref","urlObj","anchor","markListParams","keepEncodedUrlSafeChars","anchorPart","urlParams","overrideName","paramName","paramValue","_loop2","cleanKey","presentValues","finalUrl","queryParts","aKey","bKey","urlParameter","parameter","fMapParameterValue","parameterValue","parameterValues","parameters","parameterName","evaluateBaseDomain","additionalTopLevelDomains","topLevelDomains","tld","domainParts","baseDomain","_autoEscape","_autoUnescape","_encoders","_parser","Urison","autoEscape","encodedValue","boolean","null","_keys","quotedChar","_value2","toJson","encoder","substring","buster","assertSameBaseDomain","withCaret","urlParts","HISTORY","title","getHostAndPathname","popState","listening","callbacks","historyNew","cb","stateful","hostAndPathname","redirect","postParams","formAttributes","redirectForm","submit","eLink","click","usePushState","oldCallbackCount","cbs","original","newCallbackCount","clearOld","usePreviousState","tryAsPopup","windowName","optionArray","cached","postUsable","form","reload","decodeCookieName","normalizeCookieOptions","normalizedOptions","optionsProp","expires","toUTCString","httponly","samesite","secure","getCookie","foundNames","cookie","_res$name","_res","cookies","cookieParts","cookieName","cookieValue","setCookie","encodeCookieValue","cookieOptions","encodeCookieName","removeCookie","PRELOADED_IMAGES","unnamed","loaded","images","dimensionsNeeded","onLoad","image","naturalWidth","loadCount","onError","loaderImages","img","isPicture","nodeName","complete","respimage","picturefill","Image","newImages","preloadedImages","newImage","fonts","fallbackFontName","font","loadedFonts","systemFontDims","fontLoadedCheckTimer","fCheckFont","dims1","dims2","TAPPABLE_ELEMENTS_SELECTOR","setTappedState","tappedClass","tappedDuration","blur","selectionText","selection","rangeText","startOffset","endOffset","selectionStart","selectionEnd","focus","select","getSelection","createRange","selectNodeContents","startNodeIndex","startNode","endNodeIndex","endNode","remainingStartOffset","startOffsetNodeFound","setStart","remainingEndOffset","endOffsetNodeFound","setEnd","removeAllRanges","addRange","createTextRange","moveToElementText","moveStart","moveEnd","onselectstart","unselectable","link","setAsContent","afterAtWithoutTld","beforeAt","ccTld","ccAfterAtWithoutTld","ccBeforeAt","optionParams","interactionCount","fAddLinkUrl","fRemoveLinkUrl","secondTelPart","firstTelPart","regionPart","countryPart","empty","tappableElementsSelector","tapEvents","tapEvent","polyfills","_polyfills","logging","_logging","basic","_basic","_strings","arrays","_arrays","objects","_objects","_conversion","_random","timers","_timers","functions","_functions","_units","dates","_dates","_events","_context","polling","_polling","forms","_forms","animation","_animation","viewport","_viewport","urls","_urls","navigation","_navigation","requests","_requests","_cookies","_css","_images","_fonts","interaction","_interaction"],"mappings":"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IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC/G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAC5G,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAC3G,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAC/G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,270,271,272,273,274]} \ No newline at end of file diff --git a/dist/events.js b/dist/events.js index 78246bc2..8e01f84f 100644 --- a/dist/events.js +++ b/dist/events.js @@ -1,8 +1,8 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Events */ -const MODULE_NAME="Events";import{assert,isFunction,isString,isArray,isBoolean,isObject,isWindow,isEventTarget,isPlainObject,isElement,orDefault,hasValue,isEmpty,isSelector}from"./basic.js";import{slugify,replace}from"./strings.js";import{removeFrom}from"./arrays.js";import{detectInteractionType}from"./context.js";import{warn}from"./logging.js";export const EVENT_MAP=new Map,POST_MESSAGE_MAP=new Map;const DEFAULT_NAMESPACE="__default",SWIPE_DIRECTIONS=["up","right","down","left"],SWIPE_HANDLERS=new WeakMap,SWIPE_TOUCH={startX:0,startY:0,endX:0,endY:0},EVENT_OPTION_SUPPORT={capture:!1,once:!1,passive:!1,signal:!1};try{const e={get capture(){return EVENT_OPTION_SUPPORT.capture=!0,!1},get once(){return EVENT_OPTION_SUPPORT.once=!0,!1},get passive(){return EVENT_OPTION_SUPPORT.passive=!0,!1},get signal(){return EVENT_OPTION_SUPPORT.signal=!0,!1}};window.addEventListener("test",null,e),window.removeEventListener("test",null,e)}catch(t){}function prepareEventMethodBaseParams(e,t,n,a,s=!1){t=orDefault(t,[],"arr"),assert(t.length>0,`Events:${e} | no targets provided`),n=orDefault(n,[],"arr"),assert(n.length>0,`Events:${e} | no events provided`),s&&!hasValue(a)||assert(isFunction(a),`Events:${e} | handler is not a function`);let r=!0,o=!0;t.forEach(((e,n)=>{if(isString(e)){const a=n>0?t[n-1]:null;o&&=isSelector(e)&&isEventTarget(a)}else r&&=isEventTarget(e)})),assert(r,`Events:${e} | not all targets are event targets`),assert(o,`Events:${e} | not all delegated targets are a selector or have an ancestor`);const l=n.map((e=>e.replace(".__default",".-default-ns"))).map((e=>replace(e,["xxyxxx-","-xxyxx"],""))).map((e=>slugify(e,{_:"xxyxx-underscore-xxyxx",".":"xxyxx-dot-xxyxx","*":"xxyxx-star-xxyxx",":":"xxyxx-colon-xxyxx"}))).map((e=>replace(e,["xxyxx-underscore-xxyxx","xxyxx-dot-xxyxx","xxyxx-star-xxyxx","xxyxx-colon-xxyxx"],["_",".","*",":"]))).map((e=>e.replace(".-default-ns",".__default")));for(const t in l)l[t]!==n[t]&&warn(`Events:${e} | invalid event name "${n[t]}" has been normalized to "${l[t]}", please check event handling`);return{targets:t,events:n=l,handler:a}}function prepareEventMethodAdditionalTargetInfo(e,t,n){const a=n-1>=0?t[n-1]:null,s=n{const t=s[e];!hasValue(t[n])||hasValue(a)&&!hasValue(t[n].delegations[a])||(hasValue(r[e])||(r[e]=new Set([])),r[e].add(n))}));else{const e=s[t];hasValue(e)&&(r[t]=new Set([]),Object.keys(s[t]).forEach((n=>{hasValue(a)&&!hasValue(e[n].delegations[a])||r[t].add(n)})))}else Object.keys(s).forEach((e=>{r[e]=new Set([]),Object.keys(s[e]).forEach((t=>{hasValue(a)&&!hasValue(s[e][t].delegations[a])||r[e].add(t)}))}));return r}function cleanUpEventMap(e){e=hasValue(e)?new Set([].concat(e)):null;const t=[];EVENT_MAP.forEach(((n,a)=>{hasValue(e)&&!e.has(a)||(Object.keys(n).forEach((e=>{Object.keys(n[e]).forEach((t=>{const a=n[e][t];let s=a.handlers.length;Object.keys(a.delegations).forEach((e=>{const t=a.delegations[e].handlers.length;s+=t,0===t&&delete a.delegations[e]})),0===s&&delete n[e][t]})),0===Object.keys(n[e]).length&&delete n[e]})),0===Object.keys(n).length&&t.push(a))})),t.forEach((e=>{EVENT_MAP.delete(e)}))}function createDelegatedHandler(e,t){return function(n){const a=`${e}`;(hasValue(n.target?.matches)?n.target.matches(a):isEventTarget(n.syntheticTarget)||isArray(n.syntheticTarget)&&isSelector(n.syntheticTarget[1])?isEventTarget(n.syntheticTarget)?n.syntheticTarget.matches(a):n.syntheticTarget[1]===a:null)&&t(n)}}function createHandlerRemover(e,t,n,a,s=null,r=!1){const o="createHandlerRemover";let l=EVENT_MAP.get(e)?.[t]?.[n];if(hasValue(s)&&(assert(isSelector(s),`Events:${o} | invalid delegation "${s}"`),l=l.delegations[`${s}`]),r){if(!isPlainObject(l))return()=>{}}else assert(isPlainObject(l),`Events:${o} | invalid handlerScope`);return function(){const t=l.handlers.filter((e=>e.handler===a));l.handlers=removeFrom(l.handlers,t),t.forEach((t=>{e.removeEventListener(n,t.action)})),cleanUpEventMap(e)}}function createSelfRemovingHandler(e,t,n,a,s=null){return function(r){a(r),createHandlerRemover(e,t,n,a,s,!0)()}}function removeLocatedHandler(e,t,n,a,s=null){const r="removeLocatedHandler",o=EVENT_MAP.get(e)?.[t]?.[n];let l;if(assert(isPlainObject(o),`Events:${r} | invalid targetScope`),hasValue(s)){const e=o.delegations[`${s}`];assert(isPlainObject(e),`Events:${r} | invalid delegation "${s}"`),l=e}else l=o;const c=l.handlers.filter((e=>!hasValue(a)||a===e.handler));return l.handlers=removeFrom(l.handlers,c),c.forEach((t=>{e.removeEventListener(n,t.action),e.removeEventListener(n,t.action,{capture:!0})})),c.length}function removeHandlers(e,t=null,n=null,a=null,s=null){const r=gatherTargetEvents(e,t,n,s);let o=0;return Object.keys(r).forEach((t=>{Array.from(r[t]).forEach((n=>{o+=removeLocatedHandler(e,t,n,a,s)}))})),o}function removeDelegatedHandlers(e,t,n=null,a=null,s=null){return removeHandlers(e,n,a,s,t)}function pauseLocatedHandlers(e,t,n,a,s=null,r=!0){const o="pauseLocatedHandlers",l=EVENT_MAP.get(e)?.[t]?.[n];let c;if(assert(isPlainObject(l),`Events:${o} | invalid targetScope`),hasValue(s)){const e=l.delegations[`${s}`];assert(isPlainObject(e),`Events:${o} | invalid delegation "${s}"`),c=e}else c=l;const i=c.handlers.filter((e=>!hasValue(a)||a===e.handler));return i.forEach((e=>{e.paused=!!r})),i.length}function pauseHandlers(e,t=null,n=null,a=null,s=null,r=!0){const o=gatherTargetEvents(e,t,n,s);let l=0;return Object.keys(o).forEach((t=>{Array.from(o[t]).forEach((n=>{l+=pauseLocatedHandlers(e,t,n,a,s,r)}))})),l}function pauseDelegatedHandlers(e,t,n=null,a=null,s=null,r=!0){return pauseHandlers(e,n,a,s,t,r)}function createPauseAwareAction(e,t){return function(n){e.paused||t(n)}}function compileEventListenerOptions(e){if(isBoolean(e))return e;if(!isObject(e))return null;const t={};return Object.keys(EVENT_OPTION_SUPPORT).forEach((n=>{EVENT_OPTION_SUPPORT[n]&&hasValue(e[n])&&(t[n]=e[n])})),!(0!==Object.keys(t).length||!e.capture)||t}function createSyntheticEvent(e,t=null,n=null,a=null,s=null,r=null,o=null,l=null){let c;return e=`${e}`,a=orDefault(a,!1,"bool"),s=orDefault(s,a,"bool"),l=isPlainObject(l)?l:{},isFunction(o)?(hasValue(n)&&warn(`Events:createSyntheticEvent | can't add payload to event "${o.name}", skipping`),c=new o(e,{bubbles:a,cancelable:s,...l})):c=hasValue(n)?new CustomEvent(e,{detail:n,bubbles:a,cancelable:s,...l}):new CustomEvent(e,{bubbles:a,cancelable:s,...l}),hasValue(t)&&(c.namespace=`${t}`),isEventTarget(r)?(c.syntheticTarget=r,c.syntheticTargetElements=[r]):isArray(r)&&isEventTarget(r[0])&&isSelector(r[1])&&(c.syntheticTarget=r,Object.defineProperty(c,"syntheticTargetElements",{get:()=>Array.from(r[0].querySelectorAll(`${r[1]}`))})),c}function updateSwipeTouch(e){const t=["touchstart","mousedown"].includes(e.type)?"start":"end";["touchstart","touchend"].includes(e.type)?(SWIPE_TOUCH[`${t}X`]=e.changedTouches[0].screenX,SWIPE_TOUCH[`${t}Y`]=e.changedTouches[0].screenY):(SWIPE_TOUCH[`${t}X`]=e.screenX,SWIPE_TOUCH[`${t}Y`]=e.screenY)}function resolvePostMessageTarget(e,t){return e=isWindow(e)?e:isWindow(e?.contentWindow)?e.contentWindow:null,assert(hasValue(e),`Events:${t} | no usable target`),e}function windowPostMessageHandler(e){const t=e.currentTarget,n=POST_MESSAGE_MAP.get(t),a=isEmpty(e.origin)?window.__AVA_ENV__?window.location.href:null:e.origin,s=e.data?.type;if(hasValue(n)){(hasValue(s)?[s]:Object.keys(n)).forEach((t=>{(n[t]??[]).forEach((t=>{"*"!==t.origin&&t.origin!==a||t.handler(e)}))}))}}function removePostMessageHandlers(e,t,n=null,a=null){if(hasValue(e[t])){const s=e[t].length;hasValue(n)||hasValue(a)?hasValue(n)&&!hasValue(a)?e[t]=e[t].filter((e=>e.origin!==n)):!hasValue(n)&&hasValue(a)?e[t]=e[t].filter((e=>e.handler!==a)):hasValue(n,a)&&(e[t]=e[t].filter((e=>e.origin!==n&&e.handler!==a))):e[t]=[];const r=e[t].length;return 0===e[t].length&&delete e[t],s-r}return 0}export function on(e,t,n,a=null,s=!1){({targets:e,events:t,handler:n}=prepareEventMethodBaseParams("on",e,t,n)),s=!!s||!!a?.once,delete a?.once;const r=[];return e.forEach(((o,l)=>{const{prevTarget:c,hasDelegation:i,isDelegation:u}=prepareEventMethodAdditionalTargetInfo("on",e,l);let d=EVENT_MAP.get(o);u?d=EVENT_MAP.get(c):hasValue(d)||(EVENT_MAP.set(o,{__default:{}}),d=EVENT_MAP.get(o)),i||t.forEach((e=>{const{event:t,namespace:l}=prepareEventMethodEventInfo(e,"__default");hasValue(d[l])||(d[l]={}),hasValue(d[l][t])||(d[l][t]={target:u?c:o,handlers:[],delegations:{}});const i=d[l][t];let E,h,g;u?(hasValue(i.delegations[o])||(i.delegations[o]={handlers:[]}),E=i.delegations[o],h=createDelegatedHandler(o,s?createSelfRemovingHandler(i.target,l,t,n,o):n),g=createHandlerRemover(i.target,l,t,n,o)):(E=i,h=s?createSelfRemovingHandler(i.target,l,t,n):n,g=createHandlerRemover(i.target,l,t,n));const f={handler:n,remover:g,paused:!1};f.action=createPauseAwareAction(f,h),E.handlers=E.handlers.concat(f);const v=compileEventListenerOptions(a);hasValue(v)?i.target.addEventListener(t,f.action,v):i.target.addEventListener(t,f.action),r.push(g)}))})),r.length>1?function(){r.forEach((e=>e()))}:r.length>0?r[0]:null}export function once(e,t,n,a=null){return on(e,t,n,a,!0)}export function off(e,t,n=null,a=!0){const s="off";({targets:e,events:t,handler:n}=prepareEventMethodBaseParams(s,e,t,n,!0)),a=orDefault(a,!0,"bool");let r=0;return e.forEach(((o,l)=>{const{prevTarget:c,hasDelegation:i,isDelegation:u}=prepareEventMethodAdditionalTargetInfo(s,e,l);if(!i){const e=u?EVENT_MAP.get(c):EVENT_MAP.get(o);t.forEach((t=>{const{event:l,namespace:i}=prepareEventMethodEventInfo(t);hasValue(e)?(r+=u?removeDelegatedHandlers(c,o,i,l,n):removeHandlers(o,i,l,n),cleanUpEventMap(u?c:o)):a&&(hasValue(n)?((u?c:o).removeEventListener(t,n),(u?c:o).removeEventListener(t,n,{capture:!0})):warn(`Events:${s} | native fallback event removal for "${t}" not possible, handler is missing`))}))}})),r}export function pause(e,t,n=null,a=!0){const s="pause";({targets:e,events:t,handler:n}=prepareEventMethodBaseParams(s,e,t,n,!0));let r=0;return e.forEach(((o,l)=>{const{prevTarget:c,hasDelegation:i,isDelegation:u}=prepareEventMethodAdditionalTargetInfo(s,e,l);if(!i){const e=u?EVENT_MAP.get(c):EVENT_MAP.get(o);hasValue(e)&&t.forEach((e=>{const{event:t,namespace:s}=prepareEventMethodEventInfo(e);r+=u?pauseDelegatedHandlers(c,o,s,t,n,a):pauseHandlers(o,s,t,n,null,a)}))}})),r}export function resume(e,t,n=null){return pause(e,t,n,!1)}export function fire(e,t,n=null){const a="fire";({targets:e,events:t}=prepareEventMethodBaseParams(a,e,t,null,!0));let s=0;return e.forEach(((r,o)=>{const{prevTarget:l,hasDelegation:c,isDelegation:i}=prepareEventMethodAdditionalTargetInfo(a,e,o);if(!c){const e=i?EVENT_MAP.get(l):EVENT_MAP.get(r);hasValue(e)&&t.forEach((t=>{const{event:a,namespace:o}=prepareEventMethodEventInfo(t);let c;c=i?gatherTargetEvents(l,o,a,r):gatherTargetEvents(r,o,a),Object.keys(c).forEach((t=>{Array.from(c[t]).forEach((a=>{const o=i?e[t][a].delegations[r]:e[t][a],c=createSyntheticEvent(a,t,n,!1,!1,i?[l,r]:r);o.handlers.forEach((e=>{e.action(c),s++}))}))}))}))}})),s}export function emit(e,t,n=null,a=null,s=null){const r="emit";({targets:e,events:t}=prepareEventMethodBaseParams(r,e,t,null,!0));let o=0;return e.forEach(((l,c)=>{const{prevTarget:i,hasDelegation:u,isDelegation:d}=prepareEventMethodAdditionalTargetInfo(r,e,c);u||t.forEach((e=>{const{event:t,namespace:c}=prepareEventMethodEventInfo(e);assert(hasValue(t),`Events:${r} | missing event name`),d?Array.from(i.querySelectorAll(l)).forEach((e=>{e.dispatchEvent(createSyntheticEvent(t,c,n,!0,!0,null,a,s)),o++})):(l.dispatchEvent(createSyntheticEvent(t,c,n,!0,!0,null,a,s)),o++)}))})),o}export function offDetachedElements(e){0===(e=orDefault(e,[],"arr")).length&&(e=Array.from(EVENT_MAP.keys()));let t=0;return e.forEach((e=>{isElement(e)&&!document.body.contains(e)&&EVENT_MAP.has(e)&&(t++,off(e,"*"))})),t}export function onSwipe(e,t,n,a=.2,s=!0,r="annex-swipe"){const o="onSwipe";t=orDefault(t,"","str"),a=orDefault(a,.2,"float"),s=orDefault(s,!0,"bool"),r=orDefault(r,"annex-swipe","str"),assert(SWIPE_DIRECTIONS.includes(t),`Events:${o} | unknown direction "${t}"`);let l=[`touchstart.${r}-${t}`,`touchend.${r}-${t}`];s||(l.push(`mousedown.${r}-${t}`),l.push(`mouseup.${r}-${t}`)),({targets:e,events:l,handler:n}=prepareEventMethodBaseParams(o,e,l,n));const c=n;n=s&&"touch"!==detectInteractionType()?()=>{}:c;const i=SWIPE_HANDLERS.get(c)??(e=>{if(updateSwipeTouch(e),["touchend","mouseup"].includes(e.type)){const r=e.currentTarget.offsetWidth,o=e.currentTarget.offsetHeight;s&&"touch"!==detectInteractionType()||!("up"===t&&SWIPE_TOUCH.startY>SWIPE_TOUCH.endY+o*a||"right"===t&&SWIPE_TOUCH.startXSWIPE_TOUCH.endX+r*a)||n(e)}});return SWIPE_HANDLERS.set(c,i),on(e,l,i)}export function offSwipe(e,t=null,n=null,a="annex-swipe"){const s="offSwipe";t=orDefault(t,"","str"),a=orDefault(a,"annex-swipe","str"),assert(SWIPE_DIRECTIONS.concat("").includes(t),`Events:${s} | unknown direction "${t}"`);let r=0;return(""===t?SWIPE_DIRECTIONS:[t]).forEach((t=>{let o=[`touchstart.${a}-${t}`,`touchend.${a}-${t}`,`mousedown.${a}-${t}`,`mouseup.${a}-${t}`];if(({targets:e,events:o,handler:n}=prepareEventMethodBaseParams(s,e,o,n,!0)),hasValue(n)){const t=SWIPE_HANDLERS.get(n);hasValue(t)&&(r+=off(e,o,t))}else r+=off(e,o)})),r}export function onDomReady(e){if("loading"!==document.readyState)e();else{const t=()=>{document.removeEventListener("DOMContentLoaded",t),e()};document.addEventListener("DOMContentLoaded",t)}}export function onPostMessage(e,t,n,a){const s="onPostMessage";e=resolvePostMessageTarget(e,s),t=orDefault(t,"*","str"),n=`${n}`,assert(isFunction(a),`Events:${s} | handler is not a function`),hasValue(POST_MESSAGE_MAP.get(e))||(POST_MESSAGE_MAP.set(e,{}),e.addEventListener("message",windowPostMessageHandler));const r=POST_MESSAGE_MAP.get(e);return hasValue(r[n])||(r[n]=[]),r[n].push({handler:a,origin:t}),()=>{offPostMessage(e,t,n,a)}}export function offPostMessage(e,t=null,n=null,a=null,s=!0){const r="offPostMessage";e=resolvePostMessageTarget(e,r),t=orDefault(t,null,"str"),n=orDefault(n,null,"str"),s=orDefault(s,!0,"bool"),hasValue(a)&&assert(isFunction(a),`Events:${r} | handler is not a function`);let o=0;const l=POST_MESSAGE_MAP.get(e);if(hasValue(l)){(hasValue(n)?[n]:Object.keys(l)).forEach((e=>{o+=removePostMessageHandlers(l,e,t,a)})),0===Object.keys(l).length&&POST_MESSAGE_MAP.delete(e)}else s&&(hasValue(a)?e.removeEventListener("message",a):warn(`Events:${r} | native fallback event removal for "${n}" not possible, handler is missing`));return hasValue(POST_MESSAGE_MAP.get(e))||e.removeEventListener("message",windowPostMessageHandler),o}export function emitPostMessage(e,t,n,a=null){e=resolvePostMessageTarget(e,"emitPostMessage"),t=orDefault(t,"*","str");const s={type:n=`${n}`};return hasValue(a)&&(s.payload=a),e.postMessage(s,t),e} +const MODULE_NAME="Events";import{assert,isFunction,isString,isArray,isBoolean,isObject,isWindow,isEventTarget,isPlainObject,isElement,orDefault,hasValue,isEmpty,isSelector}from"./basic.js";import{slugify,replace}from"./strings.js";import{removeFrom}from"./arrays.js";import{detectInteractionType}from"./context.js";import{warn}from"./logging.js";export const EVENT_MAP=new Map,POST_MESSAGE_MAP=new Map;const DEFAULT_NAMESPACE="__default",SWIPE_DIRECTIONS=["up","right","down","left"],SWIPE_HANDLERS=new WeakMap,SWIPE_TOUCH={startX:0,startY:0,endX:0,endY:0},EVENT_OPTION_SUPPORT={capture:!1,once:!1,passive:!1,signal:!1};try{const e={get capture(){return EVENT_OPTION_SUPPORT.capture=!0,!1},get once(){return EVENT_OPTION_SUPPORT.once=!0,!1},get passive(){return EVENT_OPTION_SUPPORT.passive=!0,!1},get signal(){return EVENT_OPTION_SUPPORT.signal=!0,!1}};window.addEventListener("test",null,e),window.removeEventListener("test",null,e)}catch(t){}function prepareEventMethodBaseParams(e,t,n,a,r=!1){t=orDefault(t,[],"arr"),assert(t.length>0,`${MODULE_NAME}:${e} | no targets provided`),n=orDefault(n,[],"arr"),assert(n.length>0,`${MODULE_NAME}:${e} | no events provided`),r&&!hasValue(a)||assert(isFunction(a),`${MODULE_NAME}:${e} | handler is not a function`);let s=!0,o=!0;t.forEach(((e,n)=>{if(isString(e)){const a=n>0?t[n-1]:null;o&&=isSelector(e)&&isEventTarget(a)}else s&&=isEventTarget(e)})),assert(s,`${MODULE_NAME}:${e} | not all targets are event targets`),assert(o,`${MODULE_NAME}:${e} | not all delegated targets are a selector or have an ancestor`);const l=n.map((e=>e.replace(`.${DEFAULT_NAMESPACE}`,".-default-ns"))).map((e=>replace(e,["xxyxxx-","-xxyxx"],""))).map((e=>slugify(e,{_:"xxyxx-underscore-xxyxx",".":"xxyxx-dot-xxyxx","*":"xxyxx-star-xxyxx",":":"xxyxx-colon-xxyxx"}))).map((e=>replace(e,["xxyxx-underscore-xxyxx","xxyxx-dot-xxyxx","xxyxx-star-xxyxx","xxyxx-colon-xxyxx"],["_",".","*",":"]))).map((e=>e.replace(".-default-ns",`.${DEFAULT_NAMESPACE}`)));for(const t in l)l[t]!==n[t]&&warn(`${MODULE_NAME}:${e} | invalid event name "${n[t]}" has been normalized to "${l[t]}", please check event handling`);return{targets:t,events:n=l,handler:a}}function prepareEventMethodAdditionalTargetInfo(e,t,n){const a=n-1>=0?t[n-1]:null,r=n{const t=r[e];!hasValue(t[n])||hasValue(a)&&!hasValue(t[n].delegations[a])||(hasValue(s[e])||(s[e]=new Set([])),s[e].add(n))}));else{const e=r[t];hasValue(e)&&(s[t]=new Set([]),Object.keys(r[t]).forEach((n=>{hasValue(a)&&!hasValue(e[n].delegations[a])||s[t].add(n)})))}else Object.keys(r).forEach((e=>{s[e]=new Set([]),Object.keys(r[e]).forEach((t=>{hasValue(a)&&!hasValue(r[e][t].delegations[a])||s[e].add(t)}))}));return s}function cleanUpEventMap(e){e=hasValue(e)?new Set([].concat(e)):null;const t=[];EVENT_MAP.forEach(((n,a)=>{hasValue(e)&&!e.has(a)||(Object.keys(n).forEach((e=>{Object.keys(n[e]).forEach((t=>{const a=n[e][t];let r=a.handlers.length;Object.keys(a.delegations).forEach((e=>{const t=a.delegations[e].handlers.length;r+=t,0===t&&delete a.delegations[e]})),0===r&&delete n[e][t]})),0===Object.keys(n[e]).length&&delete n[e]})),0===Object.keys(n).length&&t.push(a))})),t.forEach((e=>{EVENT_MAP.delete(e)}))}function createDelegatedHandler(e,t){return function(n){const a=`${e}`;(hasValue(n.target?.matches)?n.target.matches(a):isEventTarget(n.syntheticTarget)||isArray(n.syntheticTarget)&&isSelector(n.syntheticTarget[1])?isEventTarget(n.syntheticTarget)?n.syntheticTarget.matches(a):n.syntheticTarget[1]===a:null)&&t(n)}}function createHandlerRemover(e,t,n,a,r=null,s=!1){const o="createHandlerRemover",l=EVENT_MAP.get(e);let c=l?.[t]?.[n];if(hasValue(r)&&(assert(isSelector(r),`${MODULE_NAME}:${o} | invalid delegation "${r}"`),c=c.delegations[`${r}`]),s){if(!isPlainObject(c))return()=>{}}else assert(isPlainObject(c),`${MODULE_NAME}:${o} | invalid handlerScope`);return function(){const t=c.handlers.filter((e=>e.handler===a));c.handlers=removeFrom(c.handlers,t),t.forEach((t=>{e.removeEventListener(n,t.action)})),cleanUpEventMap(e)}}function createSelfRemovingHandler(e,t,n,a,r=null){return function(s){a(s),createHandlerRemover(e,t,n,a,r,!0)()}}function removeLocatedHandler(e,t,n,a,r=null){const s="removeLocatedHandler",o=EVENT_MAP.get(e),l=o?.[t]?.[n];let c;if(assert(isPlainObject(l),`${MODULE_NAME}:${s} | invalid targetScope`),hasValue(r)){const e=l.delegations[`${r}`];assert(isPlainObject(e),`${MODULE_NAME}:${s} | invalid delegation "${r}"`),c=e}else c=l;const i=c.handlers.filter((e=>!hasValue(a)||a===e.handler));return c.handlers=removeFrom(c.handlers,i),i.forEach((t=>{e.removeEventListener(n,t.action),e.removeEventListener(n,t.action,{capture:!0})})),i.length}function removeHandlers(e,t=null,n=null,a=null,r=null){const s=gatherTargetEvents(e,t,n,r);let o=0;return Object.keys(s).forEach((t=>{Array.from(s[t]).forEach((n=>{o+=removeLocatedHandler(e,t,n,a,r)}))})),o}function removeDelegatedHandlers(e,t,n=null,a=null,r=null){return removeHandlers(e,n,a,r,t)}function pauseLocatedHandlers(e,t,n,a,r=null,s=!0){const o="pauseLocatedHandlers",l=EVENT_MAP.get(e),c=l?.[t]?.[n];let i;if(assert(isPlainObject(c),`${MODULE_NAME}:${o} | invalid targetScope`),hasValue(r)){const e=c.delegations[`${r}`];assert(isPlainObject(e),`${MODULE_NAME}:${o} | invalid delegation "${r}"`),i=e}else i=c;const u=i.handlers.filter((e=>!hasValue(a)||a===e.handler));return u.forEach((e=>{e.paused=!!s})),u.length}function pauseHandlers(e,t=null,n=null,a=null,r=null,s=!0){const o=gatherTargetEvents(e,t,n,r);let l=0;return Object.keys(o).forEach((t=>{Array.from(o[t]).forEach((n=>{l+=pauseLocatedHandlers(e,t,n,a,r,s)}))})),l}function pauseDelegatedHandlers(e,t,n=null,a=null,r=null,s=!0){return pauseHandlers(e,n,a,r,t,s)}function createPauseAwareAction(e,t){return function(n){e.paused||t(n)}}function compileEventListenerOptions(e){if(isBoolean(e))return e;if(!isObject(e))return null;const t={};return Object.keys(EVENT_OPTION_SUPPORT).forEach((n=>{EVENT_OPTION_SUPPORT[n]&&hasValue(e[n])&&(t[n]=e[n])})),!(0!==Object.keys(t).length||!e.capture)||t}function createSyntheticEvent(e,t=null,n=null,a=null,r=null,s=null,o=null,l=null){let c;return e=`${e}`,a=orDefault(a,!1,"bool"),r=orDefault(r,a,"bool"),l=isPlainObject(l)?l:{},isFunction(o)?(hasValue(n)&&warn(`${MODULE_NAME}:createSyntheticEvent | can't add payload to event "${o.name}", skipping`),c=new o(e,{bubbles:a,cancelable:r,...l})):c=hasValue(n)?new CustomEvent(e,{detail:n,bubbles:a,cancelable:r,...l}):new CustomEvent(e,{bubbles:a,cancelable:r,...l}),hasValue(t)&&(c.namespace=`${t}`),isEventTarget(s)?(c.syntheticTarget=s,c.syntheticTargetElements=[s]):isArray(s)&&isEventTarget(s[0])&&isSelector(s[1])&&(c.syntheticTarget=s,Object.defineProperty(c,"syntheticTargetElements",{get:()=>Array.from(s[0].querySelectorAll(`${s[1]}`))})),c}function updateSwipeTouch(e){const t=["touchstart","mousedown"].includes(e.type)?"start":"end";["touchstart","touchend"].includes(e.type)?(SWIPE_TOUCH[`${t}X`]=e.changedTouches[0].screenX,SWIPE_TOUCH[`${t}Y`]=e.changedTouches[0].screenY):(SWIPE_TOUCH[`${t}X`]=e.screenX,SWIPE_TOUCH[`${t}Y`]=e.screenY)}function resolvePostMessageTarget(e,t){return e=isWindow(e)?e:isWindow(e?.contentWindow)?e.contentWindow:null,assert(hasValue(e),`${MODULE_NAME}:${t} | no usable target`),e}function windowPostMessageHandler(e){const t=e.currentTarget,n=POST_MESSAGE_MAP.get(t),a=isEmpty(e.origin)?window.__AVA_ENV__?window.location.href:null:e.origin,r=e.data?.type;if(hasValue(n)){(hasValue(r)?[r]:Object.keys(n)).forEach((t=>{(n[t]??[]).forEach((t=>{"*"!==t.origin&&t.origin!==a||t.handler(e)}))}))}}function removePostMessageHandlers(e,t,n=null,a=null){if(hasValue(e[t])){const r=e[t].length;hasValue(n)||hasValue(a)?hasValue(n)&&!hasValue(a)?e[t]=e[t].filter((e=>e.origin!==n)):!hasValue(n)&&hasValue(a)?e[t]=e[t].filter((e=>e.handler!==a)):hasValue(n,a)&&(e[t]=e[t].filter((e=>e.origin!==n&&e.handler!==a))):e[t]=[];const s=e[t].length;return 0===e[t].length&&delete e[t],r-s}return 0}export function on(e,t,n,a=null,r=!1){({targets:e,events:t,handler:n}=prepareEventMethodBaseParams("on",e,t,n)),r=!!r||!!a?.once,delete a?.once;const s=[];return e.forEach(((o,l)=>{const{prevTarget:c,hasDelegation:i,isDelegation:u}=prepareEventMethodAdditionalTargetInfo("on",e,l);let E=EVENT_MAP.get(o);u?E=EVENT_MAP.get(c):hasValue(E)||(EVENT_MAP.set(o,{[DEFAULT_NAMESPACE]:{}}),E=EVENT_MAP.get(o)),i||t.forEach((e=>{const{event:t,namespace:l}=prepareEventMethodEventInfo(e,DEFAULT_NAMESPACE);hasValue(E[l])||(E[l]={}),hasValue(E[l][t])||(E[l][t]={target:u?c:o,handlers:[],delegations:{}});const i=E[l][t];let d,h,g;u?(hasValue(i.delegations[o])||(i.delegations[o]={handlers:[]}),d=i.delegations[o],h=createDelegatedHandler(o,r?createSelfRemovingHandler(i.target,l,t,n,o):n),g=createHandlerRemover(i.target,l,t,n,o)):(d=i,h=r?createSelfRemovingHandler(i.target,l,t,n):n,g=createHandlerRemover(i.target,l,t,n));const f={handler:n,remover:g,paused:!1};f.action=createPauseAwareAction(f,h),d.handlers=d.handlers.concat(f);const p=compileEventListenerOptions(a);hasValue(p)?i.target.addEventListener(t,f.action,p):i.target.addEventListener(t,f.action),s.push(g)}))})),s.length>1?function(){s.forEach((e=>e()))}:s.length>0?s[0]:null}export function once(e,t,n,a=null){return on(e,t,n,a,!0)}export function off(e,t,n=null,a=!0){const r="off";({targets:e,events:t,handler:n}=prepareEventMethodBaseParams(r,e,t,n,!0)),a=orDefault(a,!0,"bool");let s=0;return e.forEach(((o,l)=>{const{prevTarget:c,hasDelegation:i,isDelegation:u}=prepareEventMethodAdditionalTargetInfo(r,e,l);if(!i){const e=u?EVENT_MAP.get(c):EVENT_MAP.get(o);t.forEach((t=>{const{event:l,namespace:i}=prepareEventMethodEventInfo(t);hasValue(e)?(s+=u?removeDelegatedHandlers(c,o,i,l,n):removeHandlers(o,i,l,n),cleanUpEventMap(u?c:o)):a&&(hasValue(n)?((u?c:o).removeEventListener(t,n),(u?c:o).removeEventListener(t,n,{capture:!0})):warn(`${MODULE_NAME}:${r} | native fallback event removal for "${t}" not possible, handler is missing`))}))}})),s}export function pause(e,t,n=null,a=!0){const r="pause";({targets:e,events:t,handler:n}=prepareEventMethodBaseParams(r,e,t,n,!0));let s=0;return e.forEach(((o,l)=>{const{prevTarget:c,hasDelegation:i,isDelegation:u}=prepareEventMethodAdditionalTargetInfo(r,e,l);if(!i){const e=u?EVENT_MAP.get(c):EVENT_MAP.get(o);hasValue(e)&&t.forEach((e=>{const{event:t,namespace:r}=prepareEventMethodEventInfo(e);s+=u?pauseDelegatedHandlers(c,o,r,t,n,a):pauseHandlers(o,r,t,n,null,a)}))}})),s}export function resume(e,t,n=null){return pause(e,t,n,!1)}export function fire(e,t,n=null){const a="fire";({targets:e,events:t}=prepareEventMethodBaseParams(a,e,t,null,!0));let r=0;return e.forEach(((s,o)=>{const{prevTarget:l,hasDelegation:c,isDelegation:i}=prepareEventMethodAdditionalTargetInfo(a,e,o);if(!c){const e=i?EVENT_MAP.get(l):EVENT_MAP.get(s);hasValue(e)&&t.forEach((t=>{const{event:a,namespace:o}=prepareEventMethodEventInfo(t);let c;c=i?gatherTargetEvents(l,o,a,s):gatherTargetEvents(s,o,a),Object.keys(c).forEach((t=>{Array.from(c[t]).forEach((a=>{const o=i?e[t][a].delegations[s]:e[t][a],c=createSyntheticEvent(a,t,n,!1,!1,i?[l,s]:s);o.handlers.forEach((e=>{e.action(c),r++}))}))}))}))}})),r}export function emit(e,t,n=null,a=null,r=null){const s="emit";({targets:e,events:t}=prepareEventMethodBaseParams(s,e,t,null,!0));let o=0;return e.forEach(((l,c)=>{const{prevTarget:i,hasDelegation:u,isDelegation:E}=prepareEventMethodAdditionalTargetInfo(s,e,c);u||t.forEach((e=>{const{event:t,namespace:c}=prepareEventMethodEventInfo(e);assert(hasValue(t),`${MODULE_NAME}:${s} | missing event name`),E?Array.from(i.querySelectorAll(l)).forEach((e=>{e.dispatchEvent(createSyntheticEvent(t,c,n,!0,!0,null,a,r)),o++})):(l.dispatchEvent(createSyntheticEvent(t,c,n,!0,!0,null,a,r)),o++)}))})),o}export function offDetachedElements(e){0===(e=orDefault(e,[],"arr")).length&&(e=Array.from(EVENT_MAP.keys()));let t=0;return e.forEach((e=>{isElement(e)&&!document.body.contains(e)&&EVENT_MAP.has(e)&&(t++,off(e,"*"))})),t}export function onSwipe(e,t,n,a=.2,r=!0,s="annex-swipe"){const o="onSwipe";t=orDefault(t,"","str"),a=orDefault(a,.2,"float"),r=orDefault(r,!0,"bool"),s=orDefault(s,"annex-swipe","str"),assert(SWIPE_DIRECTIONS.includes(t),`${MODULE_NAME}:${o} | unknown direction "${t}"`);let l=[`touchstart.${s}-${t}`,`touchend.${s}-${t}`];r||(l.push(`mousedown.${s}-${t}`),l.push(`mouseup.${s}-${t}`)),({targets:e,events:l,handler:n}=prepareEventMethodBaseParams(o,e,l,n));const c=n;n=r&&"touch"!==detectInteractionType()?()=>{}:c;const i=SWIPE_HANDLERS.get(c)??(e=>{if(updateSwipeTouch(e),["touchend","mouseup"].includes(e.type)){const s=e.currentTarget.offsetWidth,o=e.currentTarget.offsetHeight;r&&"touch"!==detectInteractionType()||!("up"===t&&SWIPE_TOUCH.startY>SWIPE_TOUCH.endY+o*a||"right"===t&&SWIPE_TOUCH.startXSWIPE_TOUCH.endX+s*a)||n(e)}});return SWIPE_HANDLERS.set(c,i),on(e,l,i)}export function offSwipe(e,t=null,n=null,a="annex-swipe"){const r="offSwipe";t=orDefault(t,"","str"),a=orDefault(a,"annex-swipe","str"),assert(SWIPE_DIRECTIONS.concat("").includes(t),`${MODULE_NAME}:${r} | unknown direction "${t}"`);let s=0;return(""===t?SWIPE_DIRECTIONS:[t]).forEach((t=>{let o=[`touchstart.${a}-${t}`,`touchend.${a}-${t}`,`mousedown.${a}-${t}`,`mouseup.${a}-${t}`];if(({targets:e,events:o,handler:n}=prepareEventMethodBaseParams(r,e,o,n,!0)),hasValue(n)){const t=SWIPE_HANDLERS.get(n);hasValue(t)&&(s+=off(e,o,t))}else s+=off(e,o)})),s}export function onDomReady(e){if("loading"!==document.readyState)e();else{const t=()=>{document.removeEventListener("DOMContentLoaded",t),e()};document.addEventListener("DOMContentLoaded",t)}}export function onPostMessage(e,t,n,a){const r="onPostMessage";e=resolvePostMessageTarget(e,r),t=orDefault(t,"*","str"),n=`${n}`,assert(isFunction(a),`${MODULE_NAME}:${r} | handler is not a function`),hasValue(POST_MESSAGE_MAP.get(e))||(POST_MESSAGE_MAP.set(e,{}),e.addEventListener("message",windowPostMessageHandler));const s=POST_MESSAGE_MAP.get(e);return hasValue(s[n])||(s[n]=[]),s[n].push({handler:a,origin:t}),()=>{offPostMessage(e,t,n,a)}}export function offPostMessage(e,t=null,n=null,a=null,r=!0){const s="offPostMessage";e=resolvePostMessageTarget(e,s),t=orDefault(t,null,"str"),n=orDefault(n,null,"str"),r=orDefault(r,!0,"bool"),hasValue(a)&&assert(isFunction(a),`${MODULE_NAME}:${s} | handler is not a function`);let o=0;const l=POST_MESSAGE_MAP.get(e);if(hasValue(l)){(hasValue(n)?[n]:Object.keys(l)).forEach((e=>{o+=removePostMessageHandlers(l,e,t,a)})),0===Object.keys(l).length&&POST_MESSAGE_MAP.delete(e)}else r&&(hasValue(a)?e.removeEventListener("message",a):warn(`${MODULE_NAME}:${s} | native fallback event removal for "${n}" not possible, handler is missing`));return hasValue(POST_MESSAGE_MAP.get(e))||e.removeEventListener("message",windowPostMessageHandler),o}export function emitPostMessage(e,t,n,a=null){e=resolvePostMessageTarget(e,"emitPostMessage"),t=orDefault(t,"*","str");const r={type:n=`${n}`};return hasValue(a)&&(r.payload=a),e.postMessage(r,t),e} //# sourceMappingURL=events.js.map diff --git a/dist/events.js.map b/dist/events.js.map index d1012902..5e74d7bf 100644 --- a/dist/events.js.map +++ b/dist/events.js.map @@ -1 +1 @@ -{"version":3,"file":"events.js","names":["MODULE_NAME","assert","isFunction","isString","isArray","isBoolean","isObject","isWindow","isEventTarget","isPlainObject","isElement","orDefault","hasValue","isEmpty","isSelector","slugify","replace","removeFrom","detectInteractionType","warn","EVENT_MAP","Map","POST_MESSAGE_MAP","DEFAULT_NAMESPACE","SWIPE_DIRECTIONS","SWIPE_HANDLERS","WeakMap","SWIPE_TOUCH","startX","startY","endX","endY","EVENT_OPTION_SUPPORT","capture","once","passive","signal","options","window","addEventListener","removeEventListener","err","prepareEventMethodBaseParams","methodName","targets","events","handler","handlerIsOptional","length","targetsAreEventTargets","delegatedTargetsAreSelectorsAndHaveAncestor","forEach","target","targetIndex","ancestor","normalizedEvents","map","event","_","normalizedEventIndex","prepareEventMethodAdditionalTargetInfo","prevTarget","nextTarget","hasDelegation","isDelegation","prepareEventMethodEventInfo","eventName","defaultNamespace","defaultEvent","eventParts","split","namespace","gatherTargetEvents","delegation","targetEvents","get","gatheredTargetEvents","nameSpaceScope","delegations","Set","add","Object","keys","ns","ev","cleanUpEventMap","concat","desertedTargets","has","targetNamespace","targetEvent","targetScope","handlerCount","handlers","delegationHandlerCount","push","desertedTarget","delete","createDelegatedHandler","e","delegationSelector","matches","syntheticTarget","createHandlerRemover","ignoreInvalidScope","__methodName__","handlerScope","removedHandlers","filter","existingHandler","removedHandler","action","createSelfRemovingHandler","removeLocatedHandler","delegationScope","removeHandlers","removedCount","Array","from","removeDelegatedHandlers","pauseLocatedHandlers","paused","pausedHandlers","pausedHandler","pauseHandlers","pausedCount","pauseDelegatedHandlers","createPauseAwareAction","managedHandler","nonPauseAwareAction","compileEventListenerOptions","supportedOptions","option","createSyntheticEvent","payload","bubbles","cancelable","EventConstructor","eventOptions","name","CustomEvent","detail","syntheticTargetElements","defineProperty","querySelectorAll","updateSwipeTouch","startOrEnd","includes","type","changedTouches","screenX","screenY","resolvePostMessageTarget","method","contentWindow","windowPostMessageHandler","currentTarget","targetPostMessages","origin","__AVA_ENV__","location","href","messageType","data","removePostMessageHandlers","handlerCountBefore","h","handlerCountAfter","on","removers","set","__default","remover","eventListenerOptions","off","tryNativeRemoval","pause","resume","fire","fireCount","syntheticEvent","emit","emitCount","element","dispatchEvent","offDetachedElements","offCount","document","body","contains","onSwipe","direction","dimensionFactor","hasToBeTouchDevice","eventNameSpace","originalHandler","swipeHandler","width","offsetWidth","height","offsetHeight","offSwipe","onDomReady","callback","readyState","wrappedCallback","onPostMessage","offPostMessage","emitPostMessage","message","postMessage"],"sources":["events.js"],"mappings":"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","sourcesContent":["/*!\n * Module Events\n */\n\n/**\n * @namespace Events\n */\n\nconst MODULE_NAME = 'Events';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {\n\tassert,\n\tisFunction,\n\tisString,\n\tisArray,\n\tisBoolean,\n\tisObject,\n\tisWindow,\n\tisEventTarget,\n\tisPlainObject,\n\tisElement,\n\torDefault,\n\thasValue,\n\tisEmpty,\n\tisSelector\n} from './basic.js';\nimport {slugify, replace} from './strings.js';\nimport {removeFrom} from './arrays.js';\nimport {detectInteractionType} from './context.js';\nimport {warn} from './logging.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const\n\tEVENT_MAP = new Map(),\n\tPOST_MESSAGE_MAP = new Map()\n;\n\nconst\n\tDEFAULT_NAMESPACE = '__default',\n\tSWIPE_DIRECTIONS = ['up', 'right', 'down', 'left'],\n\tSWIPE_HANDLERS = new WeakMap(),\n\tSWIPE_TOUCH = {\n\t\tstartX : 0,\n\t\tstartY : 0,\n\t\tendX : 0,\n\t\tendY : 0\n\t},\n\tEVENT_OPTION_SUPPORT = {\n\t\tcapture : false,\n\t\tonce : false,\n\t\tpassive : false,\n\t\tsignal : false\n\t}\n;\n\ntry {\n\tconst options = {\n\t\tget capture(){\n\t\t\tEVENT_OPTION_SUPPORT.capture = true;\n\t\t\treturn false;\n\t\t},\n\t\tget once(){\n\t\t\tEVENT_OPTION_SUPPORT.once = true;\n\t\t\treturn false;\n\t\t},\n\t\tget passive(){\n\t\t\tEVENT_OPTION_SUPPORT.passive = true;\n\t\t\treturn false;\n\t\t},\n\t\tget signal(){\n\t\t\tEVENT_OPTION_SUPPORT.signal = true;\n\t\t\treturn false;\n\t\t},\n\t};\n\n\twindow.addEventListener('test', null, options);\n\twindow.removeEventListener('test', null, options);\n} catch (err){}\n\n\n\n//###[ HELPERS ]########################################################################################################\n\n/*\n * Takes the standard set of event function parameters, sanitizes the values and asserts basic compatability.\n * Returns the transformed parameters as an object, with keys of the same name as the relevant parameters.\n *\n * @private\n */\nfunction prepareEventMethodBaseParams(methodName, targets, events, handler, handlerIsOptional=false){\n\ttargets = orDefault(targets, [], 'arr');\n\tassert(targets.length > 0, `${MODULE_NAME}:${methodName} | no targets provided`);\n\tevents = orDefault(events, [], 'arr');\n\tassert(events.length > 0, `${MODULE_NAME}:${methodName} | no events provided`);\n\tif( !handlerIsOptional || hasValue(handler) ){\n\t\tassert(isFunction(handler), `${MODULE_NAME}:${methodName} | handler is not a function`);\n\t}\n\n\tlet\n\t\ttargetsAreEventTargets = true,\n\t\tdelegatedTargetsAreSelectorsAndHaveAncestor = true\n\t;\n\n\ttargets.forEach((target, targetIndex) => {\n\t\tif( isString(target) ){\n\t\t\tconst ancestor = (targetIndex > 0) ? targets[targetIndex - 1] : null;\n\t\t\tdelegatedTargetsAreSelectorsAndHaveAncestor &&= isSelector(target) && isEventTarget(ancestor);\n\t\t} else {\n\t\t\ttargetsAreEventTargets &&= isEventTarget(target);\n\t\t}\n\t});\n\n\tassert(targetsAreEventTargets, `${MODULE_NAME}:${methodName} | not all targets are event targets`);\n\tassert(\n\t\tdelegatedTargetsAreSelectorsAndHaveAncestor,\n\t\t`${MODULE_NAME}:${methodName} | not all delegated targets are a selector or have an ancestor`\n\t);\n\n\tconst normalizedEvents = events\n\t\t.map(event => event.replace(`.${DEFAULT_NAMESPACE}`, '.-default-ns'))\n\t\t.map(event => replace(event, ['xxyxxx-', '-xxyxx',], ''))\n\t\t.map(event => slugify(event, {\n\t\t\t'_' : 'xxyxx-underscore-xxyxx',\n\t\t\t'.' : 'xxyxx-dot-xxyxx',\n\t\t\t'*' : 'xxyxx-star-xxyxx',\n\t\t\t':' : 'xxyxx-colon-xxyxx'\n\t\t}))\n\t\t.map(event => replace(event, [\n\t\t\t'xxyxx-underscore-xxyxx',\n\t\t\t'xxyxx-dot-xxyxx',\n\t\t\t'xxyxx-star-xxyxx',\n\t\t\t'xxyxx-colon-xxyxx',\n\t\t], [\n\t\t\t'_',\n\t\t\t'.',\n\t\t\t'*',\n\t\t\t':'\n\t\t]))\n\t\t.map(event => event.replace('.-default-ns', `.${DEFAULT_NAMESPACE}`))\n\t;\n\n\tfor( const normalizedEventIndex in normalizedEvents ){\n\t\tif( normalizedEvents[normalizedEventIndex] !== events[normalizedEventIndex] ){\n\t\t\twarn(`${MODULE_NAME}:${methodName} | invalid event name \"${events[normalizedEventIndex]}\" has been normalized to \"${normalizedEvents[normalizedEventIndex]}\", please check event handling`);\n\t\t}\n\t}\n\n\tevents = normalizedEvents;\n\n\treturn {targets, events, handler};\n}\n\n\n\n/*\n * Prepares basic information about the current target in a list of targets.\n * The current target is identified by index, since the same target may appear multiple times in a list,\n * for example as a target and a delegation ancestor.\n *\n * @private\n */\nfunction prepareEventMethodAdditionalTargetInfo(methodName, targets, targetIndex){\n\tconst\n\t\tprevTarget = ((targetIndex - 1) >= 0) ? targets[targetIndex - 1] : null,\n\t\tnextTarget = (targetIndex < (targets.length - 1)) ? targets[targetIndex + 1] : null,\n\t\thasDelegation = isSelector(nextTarget),\n\t\tisDelegation = isSelector(targets[targetIndex])\n\t;\n\n\tassert(\n\t\t!isDelegation || (isDelegation && isEventTarget(prevTarget)),\n\t\t`${MODULE_NAME}:${methodName} | delegation has no ancestor`\n\t);\n\n\treturn {prevTarget, nextTarget, hasDelegation, isDelegation};\n}\n\n\n\n/*\n * Prepares basic information about the current event in a list of events.\n * The current event is identified by a complete eventName string containing the event itself,\n * as well as the complete dot-separated namespace.\n *\n * @private\n */\nfunction prepareEventMethodEventInfo(eventName, defaultNamespace=null, defaultEvent=null){\n\tconst\n\t\teventParts = eventName.replace('.', '/////').split('/////'),\n\t\tevent = (isEmpty(eventParts[0]) || (eventParts[0] === '*')) ? defaultEvent : eventParts[0],\n\t\tnamespace = (isEmpty(eventParts[1]) || (eventParts[1] === '*')) ? defaultNamespace : eventParts[1]\n\t;\n\n\treturn {event, namespace};\n}\n\n\n\n/*\n * Gathers matching events with namespaces for a given target (with or without a delegation).\n * Returns the found namespaces and events as a dictionary of namespaces with values of sets containing\n * the corresponding event names.\n *\n * @private\n */\nfunction gatherTargetEvents(target, namespace=null, event=null, delegation=null){\n\tconst __methodName__ = 'gatherTargetEvents';\n\n\tconst targetEvents = EVENT_MAP.get(target);\n\tassert(isPlainObject(targetEvents), `${MODULE_NAME}:${__methodName__} | invalid target \"${target}\"`);\n\n\tconst gatheredTargetEvents = {};\n\n\tif( !hasValue(namespace) && !hasValue(event) ){\n\t\tObject.keys(targetEvents).forEach(ns => {\n\t\t\tgatheredTargetEvents[ns] = new Set([]);\n\t\t\tObject.keys(targetEvents[ns]).forEach(ev => {\n\t\t\t\tif( !hasValue(delegation) || hasValue(targetEvents[ns][ev].delegations[delegation]) ){\n\t\t\t\t\tgatheredTargetEvents[ns].add(ev);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t} else if( !hasValue(event) ){\n\t\tconst nameSpaceScope = targetEvents[namespace];\n\t\tif( hasValue(nameSpaceScope) ){\n\t\t\tgatheredTargetEvents[namespace] = new Set([]);\n\t\t\tObject.keys(targetEvents[namespace]).forEach(ev => {\n\t\t\t\tif( !hasValue(delegation) || hasValue(nameSpaceScope[ev].delegations[delegation]) ){\n\t\t\t\t\tgatheredTargetEvents[namespace].add(ev);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else if( !hasValue(namespace) ){\n\t\tObject.keys(targetEvents).forEach(ns => {\n\t\t\tconst nameSpaceScope = targetEvents[ns];\n\t\t\tif(\n\t\t\t\thasValue(nameSpaceScope[event])\n\t\t\t\t&& (!hasValue(delegation) || hasValue(nameSpaceScope[event].delegations[delegation]))\n\t\t\t){\n\t\t\t\tif( !hasValue(gatheredTargetEvents[ns]) ){\n\t\t\t\t\tgatheredTargetEvents[ns] = new Set([]);\n\t\t\t\t}\n\t\t\t\tgatheredTargetEvents[ns].add(event);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tconst nameSpaceScope = targetEvents[namespace];\n\t\tif(\n\t\t\thasValue(nameSpaceScope)\n\t\t\t&& hasValue(nameSpaceScope[event])\n\t\t\t&& (!hasValue(delegation) || hasValue(nameSpaceScope[event].delegations[delegation]))\n\t\t){\n\t\t\tif( !hasValue(gatheredTargetEvents[namespace]) ){\n\t\t\t\tgatheredTargetEvents[namespace] = new Set([]);\n\t\t\t}\n\t\t\tgatheredTargetEvents[namespace].add(event);\n\t\t}\n\t}\n\n\treturn gatheredTargetEvents;\n}\n\n\n\n/*\n * Iterates through the event map (starting with a specific target or using all targets) and searches for\n * deserted handler definitions. Deletes definitions that do not contain any handlers anymore and recursively\n * removes the path back to the starting point(s) if it turns out to be empty afterwards.\n *\n * @private\n */\nfunction cleanUpEventMap(targets){\n\ttargets = hasValue(targets) ? new Set([].concat(targets)) : null;\n\n\tconst desertedTargets = [];\n\n\tEVENT_MAP.forEach((targetEvents, target) => {\n\t\tif( !hasValue(targets) || targets.has(target) ){\n\t\t\tObject.keys(targetEvents).forEach(targetNamespace => {\n\t\t\t\tObject.keys(targetEvents[targetNamespace]).forEach(targetEvent => {\n\t\t\t\t\tconst targetScope = targetEvents[targetNamespace][targetEvent];\n\t\t\t\t\tlet handlerCount = targetScope.handlers.length;\n\n\t\t\t\t\tObject.keys(targetScope.delegations).forEach(delegation => {\n\t\t\t\t\t\tconst delegationHandlerCount = targetScope.delegations[delegation].handlers.length;\n\t\t\t\t\t\thandlerCount += delegationHandlerCount;\n\n\t\t\t\t\t\tif( delegationHandlerCount === 0 ){\n\t\t\t\t\t\t\tdelete targetScope.delegations[delegation];\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tif( handlerCount === 0){\n\t\t\t\t\t\tdelete targetEvents[targetNamespace][targetEvent];\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif( Object.keys(targetEvents[targetNamespace]).length === 0 ){\n\t\t\t\t\tdelete targetEvents[targetNamespace];\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif( Object.keys(targetEvents).length === 0 ){\n\t\t\t\tdesertedTargets.push(target);\n\t\t\t}\n\t\t}\n\t});\n\n\tdesertedTargets.forEach(desertedTarget => {\n\t\tEVENT_MAP.delete(desertedTarget);\n\t});\n}\n\n\n\n/*\n * Takes a handler function and returns a new function wrapping the handler, making sure, that the handler only\n * executes, if the event target matches the given delegation selector. So, the returned function automatically\n * checks if the delegation is actually met.\n *\n * @private\n */\nfunction createDelegatedHandler(delegation, handler){\n\treturn function delegatedHandler(e){\n\t\tconst\n\t\t\tdelegationSelector = `${delegation}`,\n\t\t\tdelegationFulfilled = hasValue(e.target?.matches)\n\t\t\t\t? e.target.matches(delegationSelector)\n\t\t\t\t: (\n\t\t\t\t\tisEventTarget(e.syntheticTarget)\n\t\t\t\t\t|| (\n\t\t\t\t\t\tisArray(e.syntheticTarget)\n\t\t\t\t\t\t&& isSelector(e.syntheticTarget[1])\n\t\t\t\t\t)\n\t\t\t\t\t? (\n\t\t\t\t\t\tisEventTarget(e.syntheticTarget)\n\t\t\t\t\t\t? e.syntheticTarget.matches(delegationSelector)\n\t\t\t\t\t\t: (e.syntheticTarget[1] === delegationSelector))\n\t\t\t\t\t: null\n\t\t\t\t)\n\t\t;\n\n\t\tif( delegationFulfilled ){\n\t\t\thandler(e);\n\t\t}\n\t};\n}\n\n\n\n/*\n * Takes a handler function and returns a new function, which, when executed, removes the handler from the exact\n * path in the EVENT_MAP, defined by the given target, namespace and event (and, optionally, a delegation selector).\n * Using this function, one can undo the setting of a handler, using \"on\" or \"once\".\n *\n * @private\n */\nfunction createHandlerRemover(target, namespace, event, handler, delegation=null, ignoreInvalidScope=false){\n\tconst\n\t\t__methodName__ = 'createHandlerRemover',\n\t\ttargetEvents = EVENT_MAP.get(target)\n\t;\n\tlet handlerScope = targetEvents?.[namespace]?.[event];\n\n\tif( hasValue(delegation) ){\n\t\tassert(isSelector(delegation), `${MODULE_NAME}:${__methodName__} | invalid delegation \"${delegation}\"`);\n\t\thandlerScope = handlerScope.delegations[`${delegation}`];\n\t}\n\n\tif( !ignoreInvalidScope ){\n\t\tassert(isPlainObject(handlerScope), `${MODULE_NAME}:${__methodName__} | invalid handlerScope`);\n\t} else if( !isPlainObject(handlerScope) ){\n\t\treturn () => {};\n\t}\n\n\treturn function handlerRemover(){\n\t\tconst removedHandlers = handlerScope.handlers.filter(existingHandler => existingHandler.handler === handler);\n\t\thandlerScope.handlers = removeFrom(handlerScope.handlers, removedHandlers);\n\n\t\tremovedHandlers.forEach(removedHandler => {\n\t\t\ttarget.removeEventListener(event, removedHandler.action);\n\t\t});\n\n\t\tcleanUpEventMap(target);\n\t};\n}\n\n\n\n/*\n * Takes a handler function and returns a new function, which, when executed, calls the handler and, afterwards,\n * automatically removes the handler from the path in the EVENT_MAP, defined by the given target, namespace and event\n * (and, optionally, a delegation selector). So, the returned function is essentially a self-destructing handler.\n *\n * @private\n */\nfunction createSelfRemovingHandler(target, namespace, event, handler, delegation=null){\n\treturn function selfRemovingHandler(e){\n\t\thandler(e);\n\t\tcreateHandlerRemover(target, namespace, event, handler, delegation, true)();\n\t};\n}\n\n\n\n/*\n * Removes (a) handler(s) from a path in the EVENT_MAP, defined by the given target, namespace, event and handler\n * (and, optionally, a delegation selector).\n *\n * @private\n */\nfunction removeLocatedHandler(target, namespace, event, handler, delegation=null){\n\tconst\n\t\t__methodName__ = 'removeLocatedHandler',\n\t\ttargetEvents = EVENT_MAP.get(target),\n\t\ttargetScope = targetEvents?.[namespace]?.[event]\n\t;\n\n\tassert(isPlainObject(targetScope), `${MODULE_NAME}:${__methodName__} | invalid targetScope`);\n\n\tlet handlerScope;\n\tif( hasValue(delegation) ){\n\t\tconst delegationScope = targetScope.delegations[`${delegation}`];\n\t\tassert(isPlainObject(delegationScope), `${MODULE_NAME}:${__methodName__} | invalid delegation \"${delegation}\"`);\n\t\thandlerScope = delegationScope;\n\t} else {\n\t\thandlerScope = targetScope;\n\t}\n\tconst removedHandlers = handlerScope.handlers.filter(existingHandler => {\n\t\treturn hasValue(handler)\n\t\t\t? (handler === existingHandler.handler)\n\t\t\t: true\n\t\t;\n\t});\n\n\thandlerScope.handlers = removeFrom(handlerScope.handlers, removedHandlers);\n\n\tremovedHandlers.forEach(removedHandler => {\n\t\ttarget.removeEventListener(event, removedHandler.action);\n\t\ttarget.removeEventListener(event, removedHandler.action, {capture : true});\n\t});\n\n\treturn removedHandlers.length;\n}\n\n\n\n/*\n * Removes all handlers matching the given definition provided by target, namespace, event and handler\n * (and, optionally, a delegation selector). Leaving out namespace, event or handler works as a wildcard.\n *\n * @private\n */\nfunction removeHandlers(target, namespace=null, event=null, handler=null, delegation=null){\n\tconst targetEvents = gatherTargetEvents(target, namespace, event, delegation);\n\n\tlet removedCount = 0;\n\n\tObject.keys(targetEvents).forEach(ns => {\n\t\tArray.from(targetEvents[ns]).forEach(ev => {\n\t\t\tremovedCount += removeLocatedHandler(target, ns, ev, handler, delegation);\n\t\t});\n\t});\n\n\treturn removedCount;\n}\n\n\n\n/*\n * Shorthand-function for \"removeHandlers\" with more sane parameter order for delegations.\n *\n * @private\n */\nfunction removeDelegatedHandlers(ancestor, delegation, namespace=null, event=null, handler=null){\n\treturn removeHandlers(ancestor, namespace, event, handler, delegation);\n}\n\n\n\n/*\n * Pauses (a) handler(s) from a path in the EVENT_MAP, defined by the given target, namespace, event and handler\n * (and, optionally, a delegation selector). If paused is false, the function instead resumes the handlers.\n *\n * @private\n */\nfunction pauseLocatedHandlers(target, namespace, event, handler, delegation=null, paused=true){\n\tconst\n\t\t__methodName__ = 'pauseLocatedHandlers',\n\t\ttargetEvents = EVENT_MAP.get(target),\n\t\ttargetScope = targetEvents?.[namespace]?.[event]\n\t;\n\n\tassert(isPlainObject(targetScope), `${MODULE_NAME}:${__methodName__} | invalid targetScope`);\n\n\tlet handlerScope;\n\tif( hasValue(delegation) ){\n\t\tconst delegationScope = targetScope.delegations[`${delegation}`];\n\t\tassert(isPlainObject(delegationScope), `${MODULE_NAME}:${__methodName__} | invalid delegation \"${delegation}\"`);\n\t\thandlerScope = delegationScope;\n\t} else {\n\t\thandlerScope = targetScope;\n\t}\n\n\tconst pausedHandlers = handlerScope.handlers.filter(existingHandler => {\n\t\treturn hasValue(handler)\n\t\t\t? (handler === existingHandler.handler)\n\t\t\t: true\n\t\t;\n\t});\n\n\tpausedHandlers.forEach(pausedHandler => {\n\t\tpausedHandler.paused = !!paused;\n\t});\n\n\treturn pausedHandlers.length;\n}\n\n\n\n/*\n * Pauses all handlers matching the given definition provided by target, namespace, event and handler\n * (and, optionally, a delegation selector). Leaving out namespace, event or handler works as a wildcard.\n * If paused is false, the function instead resumes the handlers.\n *\n * @private\n */\nfunction pauseHandlers(target, namespace=null, event=null, handler=null, delegation=null, paused=true){\n\tconst targetEvents = gatherTargetEvents(target, namespace, event, delegation);\n\n\tlet pausedCount = 0;\n\n\tObject.keys(targetEvents).forEach(ns => {\n\t\tArray.from(targetEvents[ns]).forEach(ev => {\n\t\t\tpausedCount += pauseLocatedHandlers(target, ns, ev, handler, delegation, paused);\n\t\t});\n\t});\n\n\treturn pausedCount;\n}\n\n\n\n/*\n * Shorthand-function for \"pauseHandlers\" with more sane parameter order for delegations.\n *\n * @private\n */\nfunction pauseDelegatedHandlers(ancestor, delegation, namespace=null, event=null, handler=null, paused=true){\n\treturn pauseHandlers(ancestor, namespace, event, handler, delegation, paused);\n}\n\n\n\n/*\n * Takes a handler object and a corresponding action, which is not yet aware of its pause state and\n * returns an action function, which checks if the handler is paused, before executing the original action.\n * Using this, we can wrap handler actions to automatically react to the handler's pause state, preventing any\n * handler execution if the handler is currently paused.\n *\n * @private\n */\nfunction createPauseAwareAction(managedHandler, nonPauseAwareAction){\n\treturn function pauseAwareHandler(e){\n\t\tif( !managedHandler.paused ){\n\t\t\tnonPauseAwareAction(e);\n\t\t}\n\t};\n}\n\n\n\n/*\n * Takes an event listener options object as provided by the user, to be used as the third parameter of\n * addEventListener, and returns a sanitized version, taking into regard what options the browser actually supports\n * and falling back to boolean capture values, if the browser does not know about listener options at all.\n *\n * @private\n */\nfunction compileEventListenerOptions(options){\n\tif( isBoolean(options) ) return options;\n\tif( !isObject(options) ) return null;\n\n\tconst supportedOptions = {};\n\n\tObject.keys(EVENT_OPTION_SUPPORT).forEach(option => {\n\t\tif( !!EVENT_OPTION_SUPPORT[option] && hasValue(options[option]) ){\n\t\t\tsupportedOptions[option] = options[option];\n\t\t}\n\t});\n\n\tif( (Object.keys(supportedOptions).length === 0) && !!options.capture ){\n\t\treturn true;\n\t}\n\n\treturn supportedOptions;\n}\n\n\n\n/*\n * Creates a synthetic event to dispatch on an event target.\n *\n * @private\n */\nfunction createSyntheticEvent(\n\tevent,\n\tnamespace=null,\n\tpayload=null,\n\tbubbles=null,\n\tcancelable=null,\n\tsyntheticTarget=null,\n\tEventConstructor=null,\n\teventOptions=null\n){\n\tconst __methodName__ = 'createSyntheticEvent';\n\n\tevent = `${event}`;\n\tbubbles = orDefault(bubbles, false, 'bool');\n\tcancelable = orDefault(cancelable, bubbles, 'bool');\n\teventOptions = isPlainObject(eventOptions) ? eventOptions : {};\n\n\tlet e;\n\tif( isFunction(EventConstructor) ){\n\t\tif( hasValue(payload) ){\n\t\t\twarn(`${MODULE_NAME}:${__methodName__} | can't add payload to event \"${EventConstructor.name}\", skipping`);\n\t\t}\n\t\te = new EventConstructor(event, {bubbles, cancelable, ...eventOptions});\n\t} else {\n\t\te = hasValue(payload)\n\t\t\t? new CustomEvent(event, {detail : payload, bubbles, cancelable, ...eventOptions})\n\t\t\t// we could use new Event() here, but jsdom and ava cannot use that constructor for dispatchEvent :(\n\t\t\t: new CustomEvent(event, {bubbles, cancelable, ...eventOptions})\n\t\t;\n\t}\n\n\tif( hasValue(namespace) ){\n\t\te.namespace = `${namespace}`;\n\t}\n\n\tif( isEventTarget(syntheticTarget) ){\n\t\te.syntheticTarget = syntheticTarget;\n\t\te.syntheticTargetElements = [syntheticTarget]\n\t} else if(\n\t\tisArray(syntheticTarget)\n\t\t&& isEventTarget(syntheticTarget[0])\n\t\t&& isSelector(syntheticTarget[1])\n\t){\n\t\te.syntheticTarget = syntheticTarget;\n\t\tObject.defineProperty(e, 'syntheticTargetElements', {\n\t\t\tget(){\n\t\t\t\treturn Array.from(syntheticTarget[0].querySelectorAll(`${syntheticTarget[1]}`));\n\t\t\t}\n\t\t});\n\t}\n\n\treturn e;\n}\n\n\n\n/*\n * Updates touch data for a start swipe event.\n *\n * @private\n */\nfunction updateSwipeTouch(e){\n\tconst startOrEnd = ['touchstart', 'mousedown'].includes(e.type) ? 'start' : 'end';\n\tif( ['touchstart', 'touchend'].includes(e.type) ){\n\t\tSWIPE_TOUCH[`${startOrEnd}X`] = e.changedTouches[0].screenX;\n\t\tSWIPE_TOUCH[`${startOrEnd}Y`] = e.changedTouches[0].screenY;\n\t} else {\n\t\tSWIPE_TOUCH[`${startOrEnd}X`] = e.screenX;\n\t\tSWIPE_TOUCH[`${startOrEnd}Y`] = e.screenY;\n\t}\n}\n\n\n\n/*\n * Tries to find a usable target for post messages, based on a given target element.\n *\n * @private\n */\nfunction resolvePostMessageTarget(target, method){\n\ttarget = isWindow(target)\n\t\t? target\n\t\t: (\n\t\t\tisWindow(target?.contentWindow)\n\t\t\t? target.contentWindow\n\t\t\t: null\n\t\t)\n\t;\n\n\tassert(hasValue(target), `${MODULE_NAME}:${method} | no usable target`);\n\n\treturn target\n}\n\n\n\n/*\n * Default handling for post messages for a window.\n *\n * @private\n */\nfunction windowPostMessageHandler(e){\n\tconst\n\t\ttarget = e.currentTarget,\n\t\ttargetPostMessages = POST_MESSAGE_MAP.get(target),\n\t\torigin = !isEmpty(e.origin) ? e.origin : (!!window.__AVA_ENV__ ? window.location.href : null),\n\t\tmessageType = e.data?.type\n\t;\n\n\tif( hasValue(targetPostMessages) ){\n\t\tconst messageTypes = hasValue(messageType) ? [messageType] : Object.keys(targetPostMessages);\n\t\tmessageTypes.forEach(messageType => {\n\t\t\t(targetPostMessages[messageType] ?? []).forEach(handler => {\n\t\t\t\tif( (handler.origin === '*') || (handler.origin === origin) ){\n\t\t\t\t\thandler.handler(e);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n}\n\n\n\n/*\n * Iterates message handlers for a target, and removes handlers, based on given handler and origin.\n *\n * @private\n */\nfunction removePostMessageHandlers(targetPostMessages, messageType, origin=null, handler=null){\n\tif( hasValue(targetPostMessages[messageType]) ){\n\t\tconst handlerCountBefore = targetPostMessages[messageType].length;\n\n\t\tif( !hasValue(origin) && !hasValue(handler) ){\n\t\t\ttargetPostMessages[messageType] = [];\n\t\t} else if( hasValue(origin) && !hasValue(handler) ){\n\t\t\ttargetPostMessages[messageType] = targetPostMessages[messageType].filter(h => h.origin !== origin);\n\t\t} else if( !hasValue(origin) && hasValue(handler) ){\n\t\t\ttargetPostMessages[messageType] = targetPostMessages[messageType].filter(h => h.handler !== handler);\n\t\t} else if( hasValue(origin, handler) ) {\n\t\t\ttargetPostMessages[messageType] = targetPostMessages[messageType].filter(\n\t\t\t\th => (h.origin !== origin) && (h.handler !== handler)\n\t\t\t);\n\t\t}\n\n\t\tconst handlerCountAfter = targetPostMessages[messageType].length;\n\n\t\tif( targetPostMessages[messageType].length === 0 ){\n\t\t\tdelete targetPostMessages[messageType];\n\t\t}\n\n\t\treturn handlerCountBefore - handlerCountAfter;\n\t} else {\n\t\treturn 0;\n\t}\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Events:on\n */\n\n/**\n * Registers (an) event listener(s) to (a) valid EventTarget(s) (most likely (a) DOM-element(s)).\n *\n * This method is inspired by jQuery and cash, though not identical.\n * You may define one or more targets as well as one or more events to register a handler to, by either providing single\n * arguments or arrays. You may also, additionally, namespace events, like in jQuery/cash, by adding it after the event\n * name, separated by a dot ('click.namespace').\n *\n * This method returns a remover function, which removes all event registrations done by this method call.\n * So, in essence, calling that function, removes exactly, what was added, in a single call.\n *\n * @param {EventTarget|Array} targets - the target(s) to register event handlers on\n * @param {String|Array} events - the event name(s) to listen to, can be either a single name or a list of names, each name may also have a namespace, separated by a dot, to target all events/namespaces, you may use \"*\"/\"*.*\"\n * @param {Function} handler - the callback to execute if the event(s) defined in events are being received on target\n * @param {?Object|Boolean} [options=null] - event listener options according to \"addEventListener\"-syntax, will be ignored, if browser does not support this, if boolean, will be used as \"useCapture\", the same will happen if options are not supported, but you defined \"{capture : true}\", \"{once : true}\" will not be applied directly to the listener, but will, instead, set the \"once\"-parameter to true (otherwise delegated listeners would self-destroy immediately on any check)\n * @param {?Boolean} [once=false] - defines if the handler should only execute once, after which it self-destroys automatically, this will automatically be enabled, if you set options.once to true\n * @throws error in case no targets are defined\n * @throws error in case no events are defined\n * @throws error in case handler is not a function\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Function} remover function, which removes all handlers again, added by the current execution\n *\n * @memberof Events:on\n * @alias on\n * @see off\n * @see once\n * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget\n * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener?retiredLocale=de#syntax\n * @example\n * on(linkElement, 'click', e => {\te.stopPropagation(); });\n * on(someElementWithCustomEvents, 'crash.test', () => { alert('crashed!'); });\n * on([ancestorElement, 'a'], 'click', e => { e.target.classList.add('clicked'); });\n * on(buttonElement, 'click', () => { console.log('click twice, but I'll just print once); }, {passive : true, once : true});\n * on([ancestorElement, '.btn[data-foobar=\"test\"]'], 'click', () => { console.log('I'll just fire once); }, null, true);\n * on(document.body, 'click', e => { console.log(`oh, a bubbled event, let's see what has been clicked: \"${e.target}\"`); });\n * on([foo, foo, 'button', bar], ['mousedown', 'touchstart'], e => { e.target.classList.add('interaction-start'); });\n */\nexport function on(targets, events, handler, options=null, once=false){\n\tconst __methodName__ = 'on';\n\n\t({targets, events, handler} = prepareEventMethodBaseParams(__methodName__, targets, events, handler));\n\tonce = !!once || !!options?.once;\n\tdelete options?.once;\n\n\tconst removers = [];\n\n\ttargets.forEach((target, targetIndex) => {\n\t\tconst {\n\t\t\tprevTarget,\n\t\t\thasDelegation,\n\t\t\tisDelegation\n\t\t} = prepareEventMethodAdditionalTargetInfo(__methodName__, targets, targetIndex);\n\n\t\tlet targetEvents = EVENT_MAP.get(target);\n\t\tif( isDelegation ){\n\t\t\ttargetEvents = EVENT_MAP.get(prevTarget);\n\t\t} else if( !hasValue(targetEvents) ){\n\t\t\tEVENT_MAP.set(target, {[DEFAULT_NAMESPACE] : {}});\n\t\t\ttargetEvents = EVENT_MAP.get(target);\n\t\t}\n\n\t\tif( !hasDelegation ){\n\t\t\tevents.forEach(eventName => {\n\t\t\t\tconst {event, namespace} = prepareEventMethodEventInfo(eventName, DEFAULT_NAMESPACE);\n\n\t\t\t\tif( !hasValue(targetEvents[namespace]) ){\n\t\t\t\t\ttargetEvents[namespace] = {};\n\t\t\t\t}\n\n\t\t\t\tif( !hasValue(targetEvents[namespace][event]) ){\n\t\t\t\t\ttargetEvents[namespace][event] = {\n\t\t\t\t\t\ttarget : isDelegation ? prevTarget : target,\n\t\t\t\t\t\thandlers : [],\n\t\t\t\t\t\tdelegations : {}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst targetScope = targetEvents[namespace][event];\n\t\t\t\tlet handlerScope, action, remover;\n\n\t\t\t\tif( isDelegation ){\n\t\t\t\t\tif( !hasValue(targetScope.delegations[target]) ){\n\t\t\t\t\t\ttargetScope.delegations[target] = {handlers : []};\n\t\t\t\t\t}\n\t\t\t\t\thandlerScope = targetScope.delegations[target];\n\n\t\t\t\t\taction = !!once\n\t\t\t\t\t\t? createDelegatedHandler(\n\t\t\t\t\t\t\ttarget,\n\t\t\t\t\t\t\tcreateSelfRemovingHandler(targetScope.target, namespace, event, handler, target)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t: createDelegatedHandler(target, handler)\n\t\t\t\t\t;\n\t\t\t\t\tremover = createHandlerRemover(targetScope.target, namespace, event, handler, target);\n\t\t\t\t} else {\n\t\t\t\t\thandlerScope = targetScope;\n\t\t\t\t\taction = !!once\n\t\t\t\t\t\t? createSelfRemovingHandler(targetScope.target, namespace, event, handler)\n\t\t\t\t\t\t: handler\n\t\t\t\t\t;\n\t\t\t\t\tremover = createHandlerRemover(targetScope.target, namespace, event, handler);\n\t\t\t\t}\n\n\t\t\t\tconst managedHandler = {\n\t\t\t\t\thandler,\n\t\t\t\t\tremover,\n\t\t\t\t\tpaused : false,\n\t\t\t\t};\n\t\t\t\tmanagedHandler.action = createPauseAwareAction(managedHandler, action);\n\t\t\t\thandlerScope.handlers = handlerScope.handlers.concat(managedHandler);\n\n\t\t\t\tconst eventListenerOptions = compileEventListenerOptions(options);\n\t\t\t\tif( hasValue(eventListenerOptions) ){\n\t\t\t\t\ttargetScope.target.addEventListener(event, managedHandler.action, eventListenerOptions);\n\t\t\t\t} else {\n\t\t\t\t\ttargetScope.target.addEventListener(event, managedHandler.action);\n\t\t\t\t}\n\n\t\t\t\tremovers.push(remover);\n\t\t\t});\n\t\t}\n\t});\n\n\treturn (removers.length > 1)\n\t\t? function(){\n\t\t\tremovers.forEach(remover => remover());\n\t\t}\n\t\t: (\n\t\t\t(removers.length > 0)\n\t\t\t? removers[0]\n\t\t\t: null\n\t\t)\n\t;\n}\n\n\n\n/**\n * @namespace Events:once\n */\n\n/**\n * Registers (an) event listener(s) to (a) valid EventTarget(s) (most likely (a) DOM-element(s)).\n *\n * This version automatically removes the handler, after it has fired once.\n *\n * This method is inspired by jQuery and cash, though not identical.\n * You may define one or more targets as well as one or more events to register a handler to, by either providing single\n * arguments or arrays. You may also, additionally, namespace events, like in jQuery/cash, by adding it after the event\n * name, separated by a dot ('click.namespace').\n *\n * This method returns a remover function, which removes all event registrations done by this method call.\n * So, in essence, calling that function, removes exactly, what was added, in a single call.\n *\n * @param {EventTarget|Array} targets - the target(s) to register event handlers on\n * @param {String|Array} events - the event name(s) to listen to, can be either a single name or a list of names, each name may also have a namespace, separated by a dot, to target all events/namespaces, you may use \"*\"/\"*.*\"\n * @param {Function} handler - the callback to execute if the event(s) defined in events are being received on target\n * @param {?Object|Boolean} [options=null] - event listener options according to \"addEventListener\"-syntax, will be ignored, if browser does not support this, if boolean, will be used as \"useCapture\", the same will happen if options are not supported, but you defined \"{capture : true}\", \"{once : true}\" makes no sense in this case, because the behaviour will automatically be applied anyway\n * @throws error in case no targets are defined\n * @throws error in case no events are defined\n * @throws error in case handler is not a function\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Function} remover function, which removes all handlers again, added by the current execution\n *\n * @memberof Events:once\n * @alias once\n * @see on\n * @see off\n * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget\n * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener?retiredLocale=de#syntax\n * @example\n * once(linkElement, 'click', e => {\te.stopPropagation(); });\n * once(someElementWithCustomEvents, 'crash.test', () => { alert('crashed!'); });\n * once([ancestorElement, 'a'], 'click', e => { e.target.classList.add('clicked'); });\n * once(buttonElement, 'click', () => { console.log('click twice, but I'll just print once); }, {passive : true});\n * once([ancestorElement, '.btn[data-foobar=\"test\"]'], 'click', () => { console.log('I'll just fire once); });\n * once(document.body, 'click', e => { console.log(`oh, a bubbled event, let's see what has been clicked: \"${e.target}\"`); });\n * once([foo, foo, 'button', bar], ['mousedown', 'touchstart'], e => { e.target.classList.add('interaction-start'); });\n */\nexport function once(targets, events, handler, options=null){\n\treturn on(targets, events, handler, options, true);\n}\n\n\n\n/**\n * @namespace Events:off\n */\n\n/**\n * Removes (a), previously defined, event listener(s) on (a) valid EventTarget(s) (most likely (a) DOM-element(s)).\n *\n * The definition of targets and events works exactly as in \"on\" and \"once\", the only difference being, that the handler\n * is optional in this case, which results in the removal of all handlers, without targeting a specific one.\n *\n * To specifically target handlers without a namespace, please use the namespace-string \"__default\".\n *\n * This function does _not_ differentiate between removal of capture/non-capture events, but always removes both.\n *\n * If you try to remove event handlers not previously created with `on` (and therefore there are no fitting target\n * entries in the EVENT_MAP), the function will fall back to native `removeEventListener`\n * (if `tryNativeRemoval` is true), but in that case, a handler has to be defined and the return value will not\n * increment, since we do not know if the removal really worked.\n *\n * @param {EventTarget|Array} targets - the target(s) to remove event handlers from\n * @param {String|Array} events - the event name(s) to remove, can be either a single name or a list of names, each name may also have a namespace, separated by a dot, to target all events/namespaces, you may use \"*\"/\"*.*\"\n * @param {?Function} [handler=null] - a specific callback function to remove\n * @param {?Boolean} [tryNativeRemoval=true] - if a target is not part of the EVENT_MAP native removeEventListener is used as a fallback if this is true (handler needs to be set in that case)\n * @throws error in case no targets are defined\n * @throws error in case no events are defined\n * @throws error in case a defined handler is not a function\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Number} the number of handlers actually removed by the function call, may also be 0 if nothing matched\n *\n * @memberof Events:off\n * @alias off\n * @see on\n * @see once\n * @example\n * off(buttonElement, 'click');\n * off(bar, '*.__default');\n * off(customEventElement, 'crash');\n * off([ancestorElement, 'a'], 'click');\n * off([ancestorElement, '.btn[data-foobar=\"test\"]'], '*.delegated', fSpecificHandler);\n * off(linkElement, '*', fSpecificHandler);\n * off(customEventElement, ['*.test', '*.site']);\n * off([ancestorElement, 'a', ancestorElement, '.btn[data-foobar=\"test\"]'], '*.*', fSpecificHandler);\n * off(buttonElement, '*.*');\n */\nexport function off(targets, events, handler=null, tryNativeRemoval=true){\n\tconst __methodName__ = 'off';\n\n\t({targets, events, handler} = prepareEventMethodBaseParams(__methodName__, targets, events, handler, true));\n\ttryNativeRemoval = orDefault(tryNativeRemoval, true, 'bool');\n\n\tlet removedCount = 0;\n\n\ttargets.forEach((target, targetIndex) => {\n\t\tconst {\n\t\t\tprevTarget,\n\t\t\thasDelegation,\n\t\t\tisDelegation\n\t\t} = prepareEventMethodAdditionalTargetInfo(__methodName__, targets, targetIndex);\n\n\t\tif( !hasDelegation ){\n\t\t\tconst targetEvents = isDelegation ? EVENT_MAP.get(prevTarget) : EVENT_MAP.get(target);\n\n\t\t\tevents.forEach(eventName => {\n\t\t\t\tconst {event, namespace} = prepareEventMethodEventInfo(eventName);\n\n\t\t\t\tif( hasValue(targetEvents) ){\n\t\t\t\t\tif( isDelegation ){\n\t\t\t\t\t\tremovedCount += removeDelegatedHandlers(prevTarget, target, namespace, event, handler);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tremovedCount += removeHandlers(target, namespace, event, handler);\n\t\t\t\t\t}\n\n\t\t\t\t\tcleanUpEventMap(isDelegation ? prevTarget : target);\n\t\t\t\t} else if( tryNativeRemoval ){\n\t\t\t\t\tif( hasValue(handler) ){\n\t\t\t\t\t\t(isDelegation ? prevTarget : target).removeEventListener(eventName, handler);\n\t\t\t\t\t\t(isDelegation ? prevTarget : target).removeEventListener(eventName, handler, {capture : true});\n\t\t\t\t\t} else {\n\t\t\t\t\t\twarn(`${MODULE_NAME}:${__methodName__} | native fallback event removal for \"${eventName}\" not possible, handler is missing`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\n\treturn removedCount;\n}\n\n\n\n/**\n * @namespace Events:pause\n */\n\n/**\n * Pauses (a), previously defined, event listener(s), without actually removing anything. Subsequent executions\n * of the handler will not fire, while the handler is paused, which also means, that paused handlers, set up to only\n * fire once, will not self-destroy while being paused.\n *\n * The definition of targets and events works exactly as in \"on\" and \"once\", the only difference being, that the handler\n * is optional in this case, which results in the pausing of all handlers, without targeting a specific one.\n *\n * To specifically target handlers without a namespace, please use the namespace-string \"__default\".\n *\n * @param {EventTarget|Array} targets - the target(s) to pause event handlers on\n * @param {String|Array} events - the event name(s) to pause, can be either a single name or a list of names, each name may also have a namespace, separated by a dot, to target all events/namespaces, you may use \"*\"/\"*.*\"\n * @param {?Function} [handler=null] - a specific callback function to pause\n * @param {?Boolean} [paused=true] - defines if the matched handlers are being paused or resumed\n * @throws error in case no targets are defined\n * @throws error in case no events are defined\n * @throws error in case a defined handler is not a function\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Number} the number of handlers actually paused by the function call, may also be 0 if nothing matched\n *\n * @memberof Events:pause\n * @alias pause\n * @see on\n * @see resume\n * @example\n * pause(buttonElement, 'click');\n * pause(linkElement, '*.__default');\n * pause(customEventElement, 'crash');\n * pause([ancestorElement, 'a'], 'click');\n * pause([ancestorElement, '.btn[data-foobar=\"test\"]'], '*.delegated', fSpecificHandler);\n */\nexport function pause(targets, events, handler=null, paused=true){\n\tconst __methodName__ = 'pause';\n\n\t({targets, events, handler} = prepareEventMethodBaseParams(__methodName__, targets, events, handler, true));\n\n\tlet pausedCount = 0;\n\n\ttargets.forEach((target, targetIndex) => {\n\t\tconst {\n\t\t\tprevTarget,\n\t\t\thasDelegation,\n\t\t\tisDelegation\n\t\t} = prepareEventMethodAdditionalTargetInfo(__methodName__, targets, targetIndex);\n\n\t\tif( !hasDelegation ){\n\t\t\tconst targetEvents = isDelegation ? EVENT_MAP.get(prevTarget) : EVENT_MAP.get(target);\n\n\t\t\tif( hasValue(targetEvents) ){\n\t\t\t\tevents.forEach(eventName => {\n\t\t\t\t\tconst {event, namespace} = prepareEventMethodEventInfo(eventName);\n\n\t\t\t\t\tif( isDelegation ){\n\t\t\t\t\t\tpausedCount += pauseDelegatedHandlers(prevTarget, target, namespace, event, handler, paused);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpausedCount += pauseHandlers(target, namespace, event, handler, null, paused);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t});\n\n\treturn pausedCount;\n}\n\n\n\n/**\n * @namespace Events:resume\n */\n\n/**\n * Resumes (a), previously paused, event listener(s). Subsequent executions of the handler will fire again.\n *\n * The definition of targets and events works exactly as in \"on\" and \"once\", the only difference being, that the handler\n * is optional in this case, which results in the un-pausing of all handlers, without targeting a specific one.\n *\n * To specifically target handlers without a namespace, please use the namespace-string \"__default\".\n *\n * @param {EventTarget|Array} targets - the target(s) to resume event handlers on\n * @param {String|Array} events - the event name(s) to resume, can be either a single name or a list of names, each name may also have a namespace, separated by a dot, to target all events/namespaces, you may use \"*\"/\"*.*\"\n * @param {?Function} [handler=null] - a specific callback function to resume\n * @throws error in case no targets are defined\n * @throws error in case no events are defined\n * @throws error in case a defined handler is not a function\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Number} the number of handlers actually resumed by the function call, may also be 0 if nothing matched\n *\n * @memberof Events:resume\n * @alias resume\n * @see on\n * @see pause\n * @example\n * resume(linkElement, '*', fSpecificHandler);\n * resume(customEventElement, ['*.test', '*.site']);\n * resume([ancestorElement, 'a', ancestorElement, '.btn[data-foobar=\"test\"]'], '*.*', fSpecificHandler);\n * resume(buttonElement, '*.*');\n */\nexport function resume(targets, events, handler=null){\n\treturn pause(targets, events, handler, false);\n}\n\n\n\n/**\n * @namespace Events:fire\n */\n\n/**\n * Fires event handlers of all matched targets for given events.\n *\n * This function does not actually dispatch events, but identifies matches in the internal event map, based on\n * previously registered handlers using \"on\" and \"once\" and executes the attached handlers, providing them a synthetic\n * CustomEvent as first parameter, carrying the event name as well as a potential payload. So this, function is\n * using the event map as an event bus, instead of the DOM, so these events also will never bubble, but just hit the\n * currently present handlers identified exactly by the provided parameters.\n *\n * The definition of targets and events works exactly as in \"on\" and \"once\", the only difference being, that we have no\n * handler, since if we'd have the handler already, we could just call it.\n *\n * Since we do not use the DOM in this function, we also do not have native events, and therefore we do not have normal\n * event targets we can work with. Instead, this implementation adds the \"syntheticTarget\" and the\n * \"syntheticTargetElements\" event properties to the event that is given to the handler. \"syntheticTarget\" contains\n * the defined event map target, either as a EventTarget or an array of an EventTarget and a corresponding delegation\n * selector (just as you defined them before), while \"syntheticTargetElements\" returns the actual elements as an\n * iterable array. So, in case of a delegation, this gives you the power to actually work with the current delegation\n * targets, without having to write own logic for this.\n *\n * @param {EventTarget|Array} targets - the target(s) to execute event handlers on\n * @param {String|Array} events - the event name(s) to fire, can be either a single name or a list of names, each name may also have a namespace, separated by a dot, to target all events/namespaces, you may use \"*\"/\"*.*\"\n * @param {?Object} [payload=null] - a plain object payload to relay to the event handlers via the detail of the CustomEvent given to the handler as first parameter\n * @throws error in case no targets are defined\n * @throws error in case no events are defined\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Number} the number of handlers actually executed by the function call, may also be 0 if nothing matched\n *\n * @memberof Events:fire\n * @alias fire\n * @see on\n * @see once\n * @see emit\n * @example\n * fire(buttonElement, 'click');\n * fire(linkElement, '*.__default', {importantFlag : true});\n * fire(divElement, 'crash');\n * fire([ancestorElement, 'a'], 'click', {linkWasClicked : true});\n * fire([ancestorElement, '.btn[data-foobar=\"test\"]'], '*.delegated');\n * fire(linkElement, '*');\n * fire([ancestorElement, 'a', ancestorElement, '.btn[data-foobar=\"test\"]'], '*.*');\n * fire(buttonElement, 'click.*', {price : 666});\n */\nexport function fire(targets, events, payload=null){\n\tconst __methodName__ = 'fire';\n\n\t({targets, events} = prepareEventMethodBaseParams(__methodName__, targets, events, null, true));\n\n\tlet fireCount = 0;\n\n\ttargets.forEach((target, targetIndex) => {\n\t\tconst {\n\t\t\tprevTarget,\n\t\t\thasDelegation,\n\t\t\tisDelegation\n\t\t} = prepareEventMethodAdditionalTargetInfo(__methodName__, targets, targetIndex);\n\n\t\tif( !hasDelegation ){\n\t\t\tconst targetEvents = isDelegation ? EVENT_MAP.get(prevTarget) : EVENT_MAP.get(target);\n\n\t\t\tif( hasValue(targetEvents) ){\n\t\t\t\tevents.forEach(eventName => {\n\t\t\t\t\tconst {event, namespace} = prepareEventMethodEventInfo(eventName);\n\n\t\t\t\t\tlet gatheredTargetEvents;\n\t\t\t\t\tif( isDelegation ){\n\t\t\t\t\t\tgatheredTargetEvents = gatherTargetEvents(prevTarget, namespace, event, target);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgatheredTargetEvents = gatherTargetEvents(target, namespace, event);\n\t\t\t\t\t}\n\n\t\t\t\t\tObject.keys(gatheredTargetEvents).forEach(ns => {\n\t\t\t\t\t\tArray.from(gatheredTargetEvents[ns]).forEach(ev => {\n\t\t\t\t\t\t\tconst\n\t\t\t\t\t\t\t\thandlerScope = isDelegation\n\t\t\t\t\t\t\t\t\t? targetEvents[ns][ev].delegations[target]\n\t\t\t\t\t\t\t\t\t: targetEvents[ns][ev]\n\t\t\t\t\t\t\t\t,\n\t\t\t\t\t\t\t\tsyntheticEvent = isDelegation\n\t\t\t\t\t\t\t\t\t? createSyntheticEvent(ev, ns, payload, false, false, [prevTarget, target])\n\t\t\t\t\t\t\t\t\t: createSyntheticEvent(ev, ns, payload, false, false, target)\n\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\thandlerScope.handlers.forEach(handler => {\n\t\t\t\t\t\t\t\thandler.action(syntheticEvent);\n\t\t\t\t\t\t\t\tfireCount++;\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t});\n\n\treturn fireCount;\n}\n\n\n\n/**\n * @namespace Events:emit\n */\n\n/**\n * Dispatches synthetic events on all given targets.\n *\n * In contrast to \"fire\", this function actually dispatches bubbling events on the provided EventTargets. Delegations\n * are resolved using \"querySelectorAll\". This function does not check actual handler presence using the event map, but\n * blindly emits what has been given, purely using the DOM as the event bus. Handlers defined with \"on\" and \"once\" will\n * of course still be triggered if hit, since they always also register a native event listener. The events emitted\n * are purely synthetic basic Events and CustomEvents, lacking special properties, which, for example, MouseEvents\n * provide. So, using \"screenX\" in the handler will not work. If you need a certain base class for the created events,\n * use the \"EventConstructor\" to provide the base class and add special options via \"eventOptions\".\n *\n * The definition of targets and events works almost as in \"on\" and \"once\", the only differences being, that we have no\n * handler, and we cannot leave out the event name. Using a wildcard for the namespace will leave out the namespace in\n * the created events.\n *\n * @param {EventTarget|Array} targets - the target(s) to dispatch events on\n * @param {String|Array} events - the event name(s) to emit, can be either a single name or a list of names, each name may also have a namespace, separated by a dot, to target all events/namespaces, you may use \"*\"/\"*.*\"\n * @param {?Object} [payload=null] - a plain object payload to relay to the event handlers via the detail of the CustomEvent given to the handler as first parameter\n * @param {?Function} [EventConstructor=null] - the default constructor is Event/CustomEvent, if you need another specific synthetic event, provide a constructor such as MouseEvent here\n * @param {?Object} [eventOptions=null] - use this plain object to provide constructor specific options to use in event construction, this should especially come in handy in case you provide a custom EventConstructor\n * @throws error in case no targets are defined\n * @throws error in case no events are defined\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Number} the number of events actually dispatched by the function call, may also be 0 if nothing matched\n *\n * @memberof Events:emit\n * @alias emit\n * @see on\n * @see once\n * @see fire\n * @example\n * emit([buttonElement, ancestorElement, 'a'], 'click');\n * emit(linkElement, 'click.__default', {defaultClick: true});\n * emit([divElement, document.body], 'crash');\n * emit([ancestorElement, 'a'], 'click', {trackingId : 'abc123'});\n * emit([ancestorElement, '.btn[data-foobar=\"test\"]'], 'click.delegated');\n * emit(ancestorElement, ['crash.test', 'crash.site'], {damage : 1000});\n * emit([ancestorElement, 'a', ancestorElement, '.btn[data-foobar=\"test\"]'], 'click.delegated', null, null, {bubbles : false});\n * emit(buttonElement, 'click.*', {price : 666}, MouseEvent, {bubbles : false});\n */\nexport function emit(targets, events, payload=null, EventConstructor=null, eventOptions=null){\n\tconst __methodName__ = 'emit';\n\n\t({targets, events} = prepareEventMethodBaseParams(__methodName__, targets, events, null, true));\n\n\tlet emitCount = 0;\n\n\ttargets.forEach((target, targetIndex) => {\n\t\tconst {\n\t\t\tprevTarget,\n\t\t\thasDelegation,\n\t\t\tisDelegation\n\t\t} = prepareEventMethodAdditionalTargetInfo(__methodName__, targets, targetIndex);\n\n\t\tif( !hasDelegation ){\n\t\t\tevents.forEach(eventName => {\n\t\t\t\tconst {event, namespace} = prepareEventMethodEventInfo(eventName);\n\n\t\t\t\tassert(hasValue(event), `${MODULE_NAME}:${__methodName__} | missing event name`);\n\n\t\t\t\tif( isDelegation ){\n\t\t\t\t\tArray.from(prevTarget.querySelectorAll(target)).forEach(element => {\n\t\t\t\t\t\telement.dispatchEvent(\n\t\t\t\t\t\t\tcreateSyntheticEvent(event, namespace, payload, true, true, null, EventConstructor, eventOptions)\n\t\t\t\t\t\t);\n\t\t\t\t\t\temitCount++;\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\ttarget.dispatchEvent(\n\t\t\t\t\t\tcreateSyntheticEvent(event, namespace, payload, true, true, null, EventConstructor, eventOptions)\n\t\t\t\t\t);\n\t\t\t\t\temitCount++;\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\t});\n\n\treturn emitCount;\n}\n\n\n\n/**\n * @namespace Events:offDetachedElements\n */\n\n/**\n * This method completely removes all handlers and listeners for provided targets in case that they\n * are actually an element and not part of the DOM (anymore).\n *\n * The most common use-case for this is to clean the event map after dynamically removing an element from the interface\n * during runtime, maybe as a reaction to a user interaction.\n *\n * Since we are overlaying the DOM event system with a separate (non-weak) event map, handlers in the map do not\n * automatically disappear if the event targets, being elements, are removed from the DOM. In that case, we have to\n * actually unregister events again, for which this is a handy little helper method.\n *\n * There are two common ways to use this:\n * 1. Just call it with the removed element, after removal of the element. This will only remove all data for that\n * element, if it actually is an element and is not currently in the DOM.\n * 2. Call it without parameters, to iterate all current targets, check if they are elements and currently not in the\n * DOM and remove all handlers and listeners in that case.\n *\n * So, you can either directly clean-up anything you remove or remove everything, that needs removing and do a general\n * clean-up after everything has been done.\n *\n * Be aware, that the definition of what an element is and if that element is part of the dom is defined by the actual\n * event target. So delegations are not automatically covered by this, since they rely on the ancestor element for\n * event handling.\n *\n * @param {?EventTarget|Array} [targets=null] - the target(s) to remove from the event map, if not set, all event targets in the current event map are used\n * @returns {Number} the number of targets for which registered handlers and listeners have been removed\n *\n * @memberof Events:offDetachedElements\n * @alias offDetachedElements\n * @example\n * button.remove();\n * offDetachedElements(button);\n * => 1\n * link.innerText = 'test';\n * button.remove();\n * offDetachedElements([link, button]);\n * => 1\n * offDetachedElements()\n * => number of all currently registered targets, being elements and not in the dom\n */\n\nexport function offDetachedElements(targets){\n\ttargets = orDefault(targets, [], 'arr');\n\n\tif( targets.length === 0 ){\n\t\ttargets = Array.from(EVENT_MAP.keys());\n\t}\n\n\tlet offCount = 0;\n\n\ttargets.forEach(target => {\n\t\tif( isElement(target) && !document.body.contains(target) && EVENT_MAP.has(target) ){\n\t\t\toffCount++;\n\t\t\toff(target, '*');\n\t\t}\n\t});\n\n\treturn offCount;\n}\n\n\n\n/**\n * @namespace Events:onSwipe\n */\n\n/**\n * Defines a handler for a swipe gesture on (an) element(s).\n * Offers four swipe directions (up/right/down/left), where triggering the handler depends on the distance\n * between touchstart and touchend in relation to the element's width or height, depending on the direction,\n * multiplied by a factor to express a percentage.\n *\n * You may also set this method to also fire upon mouse swipes, by setting \"hasToBeTouchDevice\" to false.\n *\n * @param {EventTarget|Array} targets - the target(s) to register event handlers on\n * @param {String} direction - the direction to bind => up/down/left/right\n * @param {Function} handler - the callback to execute if the event(s) defined in events are being received on target\n * @param {?Number} [dimensionFactor=0.2] - to determine what registers as a swipe we use a percentage of the element's width/height, the touch has to move, default is 20%\n * @param {?Boolean} [hasToBeTouchDevice=true] - if true, makes sure the handlers are only active on touch devices, if false, also reacts to mouse swipes\n * @param {?String} [eventNameSpace='annex-swipe'] - apply an event namespace, which identifies specific events, helpful for a specific unbind later using the same namespace\n * @throws error in case no targets are defined\n * @throws error in case unknown direction is defined\n * @throws error in case handler is not a function\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Function} remover function, which removes all handlers again, added by the current execution\n *\n * @memberof Events:onSwipe\n * @alias onSwipe\n * @see offSwipe\n * @example\n * onSwipe(slider, 'up', e => { e.currentTarget.fadeOut(); });\n * onSwipe(slider, 'right', () => { document.body.dispatchEvent(new CustomEvent('load-previous-thing')); }, 0.15, false, 'foobar-prev');\n */\nexport function onSwipe(targets, direction, handler, dimensionFactor=0.2, hasToBeTouchDevice=true, eventNameSpace='annex-swipe'){\n\tconst __methodName__ = 'onSwipe';\n\n\tdirection = orDefault(direction, '', 'str');\n\tdimensionFactor = orDefault(dimensionFactor, 0.2, 'float');\n\thasToBeTouchDevice = orDefault(hasToBeTouchDevice, true, 'bool');\n\teventNameSpace = orDefault(eventNameSpace, 'annex-swipe', 'str');\n\n\tassert(SWIPE_DIRECTIONS.includes(direction), `${MODULE_NAME}:${__methodName__} | unknown direction \"${direction}\"`);\n\n\tlet events = [`touchstart.${eventNameSpace}-${direction}`, `touchend.${eventNameSpace}-${direction}`];\n\tif( !hasToBeTouchDevice ){\n\t\tevents.push(`mousedown.${eventNameSpace}-${direction}`);\n\t\tevents.push(`mouseup.${eventNameSpace}-${direction}`);\n\t}\n\n\t({targets, events, handler} = prepareEventMethodBaseParams(__methodName__, targets, events, handler));\n\n\tconst originalHandler = handler;\n\thandler = (hasToBeTouchDevice && (detectInteractionType() !== 'touch')) ? () => {} : originalHandler;\n\tconst swipeHandler = SWIPE_HANDLERS.get(originalHandler) ?? (e => {\n\t\tupdateSwipeTouch(e);\n\n\t\tif( ['touchend', 'mouseup'].includes(e.type) ){\n\t\t\tconst\n\t\t\t\twidth = e.currentTarget.offsetWidth,\n\t\t\t\theight = e.currentTarget.offsetHeight\n\t\t\t;\n\n\t\t\tif(\n\t\t\t\t(!hasToBeTouchDevice || (detectInteractionType() === 'touch'))\n\t\t\t\t&& (\n\t\t\t\t\t((direction === 'up') && (SWIPE_TOUCH.startY > (SWIPE_TOUCH.endY + height * dimensionFactor)))\n\t\t\t\t\t|| ((direction === 'right') && (SWIPE_TOUCH.startX < (SWIPE_TOUCH.endX - width * dimensionFactor)))\n\t\t\t\t\t|| ((direction === 'down') && (SWIPE_TOUCH.startY < (SWIPE_TOUCH.endY - height * dimensionFactor)))\n\t\t\t\t\t|| ((direction === 'left') && (SWIPE_TOUCH.startX > (SWIPE_TOUCH.endX + width * dimensionFactor)))\n\t\t\t\t)\n\t\t\t){\n\t\t\t\thandler(e);\n\t\t\t}\n\t\t}\n\t});\n\tSWIPE_HANDLERS.set(originalHandler, swipeHandler);\n\n\treturn on(targets, events, swipeHandler);\n}\n\n\n\n/**\n * @namespace Events:offSwipe\n */\n\n/**\n * Removes (a) handler(s) for a swipe gesture from (an) element(s).\n *\n * Normally all directions are removed individually, but if you leave out `direction` all directions are removed at once.\n *\n * @param {EventTarget|Array} targets - the target(s) to remove event handlers from\n * @param {?String} [direction=null] - the direction to remove => up/down/left/right, if empty, all directions are removed\n * @param {?Function} [handler=null] - a specific callback function to remove\n * @param {?String} [eventNameSpace='annex-swipe'] - event namespace to remove\n * @throws error in case no targets are defined\n * @throws error in case unknown direction is defined\n * @throws error in case a defined handler is not a function\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Number} the number of handlers actually removed by the function call, may also be 0 if nothing matched\n *\n * @memberof Events:offSwipe\n * @alias offSwipe\n * @see onSwipe\n * @example\n * offSwipe(slider, 'right');\n * offSwipe(slider, 'left', fSpecialHandler, 'foobar-prev');\n * offSwipe(slider);\n */\nexport function offSwipe(targets, direction=null, handler=null, eventNameSpace='annex-swipe'){\n\tconst __methodName__ = 'offSwipe';\n\n\tdirection = orDefault(direction, '', 'str');\n\teventNameSpace = orDefault(eventNameSpace, 'annex-swipe', 'str');\n\n\tassert(SWIPE_DIRECTIONS.concat('').includes(direction), `${MODULE_NAME}:${__methodName__} | unknown direction \"${direction}\"`);\n\n\tconst directions = (direction === '') ? SWIPE_DIRECTIONS : [direction];\n\tlet removedCount = 0;\n\n\tdirections.forEach(direction => {\n\t\tlet events = [\n\t\t\t`touchstart.${eventNameSpace}-${direction}`,\n\t\t\t`touchend.${eventNameSpace}-${direction}`,\n\t\t\t`mousedown.${eventNameSpace}-${direction}`,\n\t\t\t`mouseup.${eventNameSpace}-${direction}`\n\t\t];\n\n\t\t({targets, events, handler} = prepareEventMethodBaseParams(__methodName__, targets, events, handler, true));\n\n\t\tif( hasValue(handler) ){\n\t\t\tconst swipeHandler = SWIPE_HANDLERS.get(handler);\n\t\t\tif( hasValue(swipeHandler) ){\n\t\t\t\tremovedCount += off(targets, events, swipeHandler);\n\t\t\t}\n\t\t} else {\n\t\t\tremovedCount += off(targets, events);\n\t\t}\n\t});\n\n\treturn removedCount;\n}\n\n\n\n/**\n * @namespace Events:onDomReady\n */\n\n/**\n * Executes a callback on document ready (DOM parsed, complete and usable, not loaded/onload).\n *\n * @param {Function} callback - function to execute, once document is parsed and ready\n *\n * @memberof Events:onDomReady\n * @alias onDomReady\n * @example\n * onDomReady(() => {\n * document.body.classList.add('dom-ready');\n * });\n */\nexport function onDomReady(callback){\n\tif( document.readyState !== 'loading' ){\n\t\tcallback();\n\t} else {\n\t\tconst wrappedCallback = () => {\n\t\t\tdocument.removeEventListener('DOMContentLoaded', wrappedCallback);\n\t\t\tcallback();\n\t\t};\n\t\tdocument.addEventListener('DOMContentLoaded', wrappedCallback);\n\t}\n}\n\n\n\n/**\n * @namespace Events:onPostMessage\n */\n\n/**\n * Register an event handler for a post message on a valid target, like a window or an iframe.\n *\n * The handler will only be executed, if the messageType as well as the origin match. The messageType must be\n * part of the payload, using the key \"type\", which `emitPostMessage` does automatically.\n *\n * Putting the origin as an obligatory parameter at the second place, is deliberate by design, to force everyone\n * to really think about, what to use here. Usually, most people, just throw in the \"*\" wildcard, paying no attention\n * to the security implications. Please really think about what to use here.\n *\n * A word of advice: keep in mind, that, contrary to most other events in javascript, post messages actually work\n * asynchronously (so you cannot be sure, that the handler has been executed, directly after a post message has been\n * sent) and that messages/payload are not transferred as-is, but are cloned, using the \"structured clone algorithm\",\n * which means, that not every javascript object is transferable without losses.\n *\n * @param {Window|HTMLIFrameElement} target - window/iframe to register the handler to (iframes are automatically resolved to the contentWindow)\n * @param {String} origin - the origin the received post message has to have, for the handler to get executed (defaults to \"*\", if receiving a nullish value)\n * @param {String} messageType - the type/name the post message has to have, for the handler to get executed (will be checked using the key \"type\" in the message's payload)\n * @param {Function} handler - the handler to execute, if a post message, matching all conditions, is received\n * @throws error if target is not usable\n * @return a function, which, if executed, removes everything registered by the current call\n *\n * @memberof Events:onPostMessage\n * @alias onPostMessage\n * @see offPostMessage\n * @see emitPostMessage\n * @see https://developer.mozilla.org/en-US/docs/Glossary/Origin\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm\n * @example\n * const removeAgainFunction = onPostMessage(window, '*', 'foobar-message', () => { doSomething(); });\n * onPostMessage(iframeElement, 'https://foobar.com:80/', 'foobar-message', e => { resizeIframe(e.data.payload.height); });\n */\nexport function onPostMessage(target, origin, messageType, handler){\n\tconst __methodName__ = 'onPostMessage';\n\n\ttarget = resolvePostMessageTarget(target, __methodName__);\n\torigin = orDefault(origin, '*', 'str');\n\tmessageType = `${messageType}`;\n\n\tassert(isFunction(handler), `${MODULE_NAME}:${__methodName__} | handler is not a function`);\n\n\tif( !hasValue(POST_MESSAGE_MAP.get(target)) ){\n\t\tPOST_MESSAGE_MAP.set(target, {});\n\t\ttarget.addEventListener('message', windowPostMessageHandler);\n\t}\n\n\tconst targetPostMessages = POST_MESSAGE_MAP.get(target);\n\tif( !hasValue(targetPostMessages[messageType]) ){\n\t\ttargetPostMessages[messageType] = [];\n\t}\n\n\ttargetPostMessages[messageType].push({handler, origin});\n\n\treturn () => { offPostMessage(target, origin, messageType, handler); };\n}\n\n\n\n/**\n * @namespace Events:offPostMessage\n */\n\n/**\n * Unregister (an) event handler(s) for (a) post message(s) on a valid target, like a window or an iframe.\n *\n * Similar to `off`, this function can handle rather unspecific cases as well as very specific definitions.\n * Just setting the target, removes all registrations for that target. Setting an `origin` and/or a `messageType`\n * additionally, only removes handlers, that were registered explicitly for these values. Adding a handler only\n * removes that specific handler (without origin and/or messageType, the handler is removed everywhere).\n *\n * Putting the origin parameter at the second place, is deliberate by design, to force everyone to really think about,\n * what to use here. Usually, most people, just throw in the \"*\" wildcard, paying no attention to the security\n * implications, when setting a post message handler. Since we force this on `onPostMessage`, we keep the signature\n * here as well, just making everything except target optional.\n *\n * If you try to remove event handlers not previously created with `onPostMessage` (and therefore there are no fitting\n * target entries in the POST_MESSAGE_MAP), the function will fall back to native `removeEventListener`\n * (if `tryNativeRemoval` is true), but in that case, a handler has to be defined and the return value will not\n * increment, since we do not know if the removal really worked.\n *\n * @param {Window|HTMLIFrameElement} target - window/iframe to remove handler(s) from (iframes are automatically resolved to the contentWindow)\n * @param {?String} [origin=null] - the origin the received post message has to have, for the handler to get executed (defaults to \"*\", if receiving a nullish value)\n * @param {?String} [messageType=null] - the type/name the post message has to have, for the handler to get executed (will be checked using the key \"type\" in the message's payload)\n * @param {?Function} [handler=null] - the handler to execute, if a post message, matching all conditions, is received\n * @param {?Boolean} [tryNativeRemoval=true] - if a target is not part of the POST_MESSAGE_MAP native removeEventListener is used as a fallback if this is true (handler needs to be set in that case)\n * @throws error if target is not usable\n * @return the number of actually removed handlers, that matched the conditions\n *\n * @memberof Events:offPostMessage\n * @alias offPostMessage\n * @see onPostMessage\n * @see emitPostMessage\n * @see https://developer.mozilla.org/en-US/docs/Glossary/Origin\n * @example\n * const offCount = offPostMessage(window, 'https://foobar.com:80/', 'foobar-message');\n * offPostMessage(window, null, null, specialHandlerFunction);\n */\nexport function offPostMessage(target, origin=null, messageType=null, handler=null, tryNativeRemoval=true){\n\tconst __methodName__ = 'offPostMessage';\n\n\ttarget = resolvePostMessageTarget(target, __methodName__);\n\torigin = orDefault(origin, null, 'str');\n\tmessageType = orDefault(messageType, null, 'str');\n\ttryNativeRemoval = orDefault(tryNativeRemoval, true, 'bool');\n\n\tif( hasValue(handler) ){\n\t\tassert(isFunction(handler), `${MODULE_NAME}:${__methodName__} | handler is not a function`);\n\t}\n\n\tlet removedCount = 0;\n\n\tconst targetPostMessages = POST_MESSAGE_MAP.get(target);\n\tif( hasValue(targetPostMessages) ){\n\t\tconst messageTypes = hasValue(messageType) ? [messageType] : Object.keys(targetPostMessages);\n\t\tmessageTypes.forEach(messageType => {\n\t\t\tremovedCount += removePostMessageHandlers(targetPostMessages, messageType, origin, handler);\n\t\t});\n\n\t\tif( Object.keys(targetPostMessages).length === 0 ){\n\t\t\tPOST_MESSAGE_MAP.delete(target);\n\t\t}\n\t} else if( tryNativeRemoval ){\n\t\tif( hasValue(handler) ){\n\t\t\ttarget.removeEventListener('message', handler);\n\t\t} else {\n\t\t\twarn(`${MODULE_NAME}:${__methodName__} | native fallback event removal for \"${messageType}\" not possible, handler is missing`);\n\t\t}\n\t}\n\n\tif( !hasValue(POST_MESSAGE_MAP.get(target)) ){\n\t\ttarget.removeEventListener('message', windowPostMessageHandler);\n\t}\n\n\treturn removedCount;\n}\n\n\n\n/**\n * @namespace Events:emitPostMessage\n */\n\n/**\n * Emit/dispatch a post message on a valid target, like a window or an iframe.\n *\n * Putting the origin as an obligatory parameter at the second place, is deliberate by design, to force everyone\n * to really think about, what to use here. Usually, most people, just throw in the \"*\" wildcard, paying no attention\n * to the security implications. Please really think about what to use here.\n *\n * This function adds the `messageType` automatically to the message/payload using the key `type`. `onPostMessage` will\n * use that information additionally to the `origin` to determine if a registration fits the occurred event. The\n * `payload` will be placed in the message using the key `payload`. So `e.data` will look like this in the\n * handler at the end: `{type : messageType, payload : {...payload}}`\n *\n * A word of advice: keep in mind, that, contrary to most other events in javascript, post messages actually work\n * asynchronously (so you cannot be sure, that the handler has been executed, directly after a post message has been\n * sent) and that messages/payload are not transferred as-is, but are cloned, using the \"structured clone algorithm\",\n * which means, that not every javascript object is transferable without losses.\n *\n * @param {Window|HTMLIFrameElement} target - window/iframe to receive the post message (iframes are automatically resolved to the contentWindow)\n * @param {String} origin - the origin the current context has to have, to actually send the post message the received post message has to have, this does NOT set the origin! (defaults to \"*\", if receiving a nullish value)\n * @param {String} messageType - the type/name of the post message (will be checked using the key \"type\" in the message's payload, which will automatically be set using this function)\n * @param {?*} [payload=null] - a payload to add to the message under the key \"payload\"\n * @throws error if target is not usable\n * @return the resolved target of the post message\n *\n * @memberof Events:emitPostMessage\n * @alias emitPostMessage\n * @see onPostMessage\n * @see offPostMessage\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage\n * @see https://developer.mozilla.org/en-US/docs/Glossary/Origin\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm\n * @example\n * emitPostMessage(window, '*', 'foobar-message', {timestamp : new Date()});\n * emitPostMessage(iframeElement, 'https://foobar.com:80/', 'foobar-message');\n */\nexport function emitPostMessage(target, origin, messageType, payload=null){\n\tconst __methodName__ = 'emitPostMessage';\n\n\ttarget = resolvePostMessageTarget(target, __methodName__);\n\torigin = orDefault(origin, '*', 'str');\n\tmessageType = `${messageType}`;\n\n\tconst message = {type : messageType};\n\tif( hasValue(payload) ){\n\t\tmessage.payload = payload;\n\t}\n\n\ttarget.postMessage(message, origin);\n\n\treturn target;\n}\n"]} \ No newline at end of file +{"version":3,"file":"events.js","names":["MODULE_NAME","assert","isFunction","isString","isArray","isBoolean","isObject","isWindow","isEventTarget","isPlainObject","isElement","orDefault","hasValue","isEmpty","isSelector","slugify","replace","removeFrom","detectInteractionType","warn","EVENT_MAP","Map","POST_MESSAGE_MAP","DEFAULT_NAMESPACE","SWIPE_DIRECTIONS","SWIPE_HANDLERS","WeakMap","SWIPE_TOUCH","startX","startY","endX","endY","EVENT_OPTION_SUPPORT","capture","once","passive","signal","options","window","addEventListener","removeEventListener","err","prepareEventMethodBaseParams","methodName","targets","events","handler","handlerIsOptional","length","targetsAreEventTargets","delegatedTargetsAreSelectorsAndHaveAncestor","forEach","target","targetIndex","ancestor","normalizedEvents","map","event","_","normalizedEventIndex","prepareEventMethodAdditionalTargetInfo","prevTarget","nextTarget","hasDelegation","isDelegation","prepareEventMethodEventInfo","eventName","defaultNamespace","defaultEvent","eventParts","split","namespace","gatherTargetEvents","delegation","targetEvents","get","gatheredTargetEvents","nameSpaceScope","delegations","Set","add","Object","keys","ns","ev","cleanUpEventMap","concat","desertedTargets","has","targetNamespace","targetEvent","targetScope","handlerCount","handlers","delegationHandlerCount","push","desertedTarget","delete","createDelegatedHandler","e","delegationSelector","matches","syntheticTarget","createHandlerRemover","ignoreInvalidScope","__methodName__","handlerScope","removedHandlers","filter","existingHandler","removedHandler","action","createSelfRemovingHandler","removeLocatedHandler","delegationScope","removeHandlers","removedCount","Array","from","removeDelegatedHandlers","pauseLocatedHandlers","paused","pausedHandlers","pausedHandler","pauseHandlers","pausedCount","pauseDelegatedHandlers","createPauseAwareAction","managedHandler","nonPauseAwareAction","compileEventListenerOptions","supportedOptions","option","createSyntheticEvent","payload","bubbles","cancelable","EventConstructor","eventOptions","name","CustomEvent","detail","syntheticTargetElements","defineProperty","querySelectorAll","updateSwipeTouch","startOrEnd","includes","type","changedTouches","screenX","screenY","resolvePostMessageTarget","method","contentWindow","windowPostMessageHandler","currentTarget","targetPostMessages","origin","__AVA_ENV__","location","href","messageType","data","removePostMessageHandlers","handlerCountBefore","h","handlerCountAfter","on","removers","set","remover","eventListenerOptions","off","tryNativeRemoval","pause","resume","fire","fireCount","syntheticEvent","emit","emitCount","element","dispatchEvent","offDetachedElements","offCount","document","body","contains","onSwipe","direction","dimensionFactor","hasToBeTouchDevice","eventNameSpace","originalHandler","swipeHandler","width","offsetWidth","height","offsetHeight","offSwipe","onDomReady","callback","readyState","wrappedCallback","onPostMessage","offPostMessage","emitPostMessage","message","postMessage"],"sources":["events.js"],"mappings":"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","ignoreList":[],"sourcesContent":["/*!\n * Module Events\n */\n\n/**\n * @namespace Events\n */\n\nconst MODULE_NAME = 'Events';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {\n\tassert,\n\tisFunction,\n\tisString,\n\tisArray,\n\tisBoolean,\n\tisObject,\n\tisWindow,\n\tisEventTarget,\n\tisPlainObject,\n\tisElement,\n\torDefault,\n\thasValue,\n\tisEmpty,\n\tisSelector\n} from './basic.js';\nimport {slugify, replace} from './strings.js';\nimport {removeFrom} from './arrays.js';\nimport {detectInteractionType} from './context.js';\nimport {warn} from './logging.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const\n\tEVENT_MAP = new Map(),\n\tPOST_MESSAGE_MAP = new Map()\n;\n\nconst\n\tDEFAULT_NAMESPACE = '__default',\n\tSWIPE_DIRECTIONS = ['up', 'right', 'down', 'left'],\n\tSWIPE_HANDLERS = new WeakMap(),\n\tSWIPE_TOUCH = {\n\t\tstartX : 0,\n\t\tstartY : 0,\n\t\tendX : 0,\n\t\tendY : 0\n\t},\n\tEVENT_OPTION_SUPPORT = {\n\t\tcapture : false,\n\t\tonce : false,\n\t\tpassive : false,\n\t\tsignal : false\n\t}\n;\n\ntry {\n\tconst options = {\n\t\tget capture(){\n\t\t\tEVENT_OPTION_SUPPORT.capture = true;\n\t\t\treturn false;\n\t\t},\n\t\tget once(){\n\t\t\tEVENT_OPTION_SUPPORT.once = true;\n\t\t\treturn false;\n\t\t},\n\t\tget passive(){\n\t\t\tEVENT_OPTION_SUPPORT.passive = true;\n\t\t\treturn false;\n\t\t},\n\t\tget signal(){\n\t\t\tEVENT_OPTION_SUPPORT.signal = true;\n\t\t\treturn false;\n\t\t},\n\t};\n\n\twindow.addEventListener('test', null, options);\n\twindow.removeEventListener('test', null, options);\n} catch (err){}\n\n\n\n//###[ HELPERS ]########################################################################################################\n\n/*\n * Takes the standard set of event function parameters, sanitizes the values and asserts basic compatability.\n * Returns the transformed parameters as an object, with keys of the same name as the relevant parameters.\n *\n * @private\n */\nfunction prepareEventMethodBaseParams(methodName, targets, events, handler, handlerIsOptional=false){\n\ttargets = orDefault(targets, [], 'arr');\n\tassert(targets.length > 0, `${MODULE_NAME}:${methodName} | no targets provided`);\n\tevents = orDefault(events, [], 'arr');\n\tassert(events.length > 0, `${MODULE_NAME}:${methodName} | no events provided`);\n\tif( !handlerIsOptional || hasValue(handler) ){\n\t\tassert(isFunction(handler), `${MODULE_NAME}:${methodName} | handler is not a function`);\n\t}\n\n\tlet\n\t\ttargetsAreEventTargets = true,\n\t\tdelegatedTargetsAreSelectorsAndHaveAncestor = true\n\t;\n\n\ttargets.forEach((target, targetIndex) => {\n\t\tif( isString(target) ){\n\t\t\tconst ancestor = (targetIndex > 0) ? targets[targetIndex - 1] : null;\n\t\t\tdelegatedTargetsAreSelectorsAndHaveAncestor &&= isSelector(target) && isEventTarget(ancestor);\n\t\t} else {\n\t\t\ttargetsAreEventTargets &&= isEventTarget(target);\n\t\t}\n\t});\n\n\tassert(targetsAreEventTargets, `${MODULE_NAME}:${methodName} | not all targets are event targets`);\n\tassert(\n\t\tdelegatedTargetsAreSelectorsAndHaveAncestor,\n\t\t`${MODULE_NAME}:${methodName} | not all delegated targets are a selector or have an ancestor`\n\t);\n\n\tconst normalizedEvents = events\n\t\t.map(event => event.replace(`.${DEFAULT_NAMESPACE}`, '.-default-ns'))\n\t\t.map(event => replace(event, ['xxyxxx-', '-xxyxx',], ''))\n\t\t.map(event => slugify(event, {\n\t\t\t'_' : 'xxyxx-underscore-xxyxx',\n\t\t\t'.' : 'xxyxx-dot-xxyxx',\n\t\t\t'*' : 'xxyxx-star-xxyxx',\n\t\t\t':' : 'xxyxx-colon-xxyxx'\n\t\t}))\n\t\t.map(event => replace(event, [\n\t\t\t'xxyxx-underscore-xxyxx',\n\t\t\t'xxyxx-dot-xxyxx',\n\t\t\t'xxyxx-star-xxyxx',\n\t\t\t'xxyxx-colon-xxyxx',\n\t\t], [\n\t\t\t'_',\n\t\t\t'.',\n\t\t\t'*',\n\t\t\t':'\n\t\t]))\n\t\t.map(event => event.replace('.-default-ns', `.${DEFAULT_NAMESPACE}`))\n\t;\n\n\tfor( const normalizedEventIndex in normalizedEvents ){\n\t\tif( normalizedEvents[normalizedEventIndex] !== events[normalizedEventIndex] ){\n\t\t\twarn(`${MODULE_NAME}:${methodName} | invalid event name \"${events[normalizedEventIndex]}\" has been normalized to \"${normalizedEvents[normalizedEventIndex]}\", please check event handling`);\n\t\t}\n\t}\n\n\tevents = normalizedEvents;\n\n\treturn {targets, events, handler};\n}\n\n\n\n/*\n * Prepares basic information about the current target in a list of targets.\n * The current target is identified by index, since the same target may appear multiple times in a list,\n * for example as a target and a delegation ancestor.\n *\n * @private\n */\nfunction prepareEventMethodAdditionalTargetInfo(methodName, targets, targetIndex){\n\tconst\n\t\tprevTarget = ((targetIndex - 1) >= 0) ? targets[targetIndex - 1] : null,\n\t\tnextTarget = (targetIndex < (targets.length - 1)) ? targets[targetIndex + 1] : null,\n\t\thasDelegation = isSelector(nextTarget),\n\t\tisDelegation = isSelector(targets[targetIndex])\n\t;\n\n\tassert(\n\t\t!isDelegation || (isDelegation && isEventTarget(prevTarget)),\n\t\t`${MODULE_NAME}:${methodName} | delegation has no ancestor`\n\t);\n\n\treturn {prevTarget, nextTarget, hasDelegation, isDelegation};\n}\n\n\n\n/*\n * Prepares basic information about the current event in a list of events.\n * The current event is identified by a complete eventName string containing the event itself,\n * as well as the complete dot-separated namespace.\n *\n * @private\n */\nfunction prepareEventMethodEventInfo(eventName, defaultNamespace=null, defaultEvent=null){\n\tconst\n\t\teventParts = eventName.replace('.', '/////').split('/////'),\n\t\tevent = (isEmpty(eventParts[0]) || (eventParts[0] === '*')) ? defaultEvent : eventParts[0],\n\t\tnamespace = (isEmpty(eventParts[1]) || (eventParts[1] === '*')) ? defaultNamespace : eventParts[1]\n\t;\n\n\treturn {event, namespace};\n}\n\n\n\n/*\n * Gathers matching events with namespaces for a given target (with or without a delegation).\n * Returns the found namespaces and events as a dictionary of namespaces with values of sets containing\n * the corresponding event names.\n *\n * @private\n */\nfunction gatherTargetEvents(target, namespace=null, event=null, delegation=null){\n\tconst __methodName__ = 'gatherTargetEvents';\n\n\tconst targetEvents = EVENT_MAP.get(target);\n\tassert(isPlainObject(targetEvents), `${MODULE_NAME}:${__methodName__} | invalid target \"${target}\"`);\n\n\tconst gatheredTargetEvents = {};\n\n\tif( !hasValue(namespace) && !hasValue(event) ){\n\t\tObject.keys(targetEvents).forEach(ns => {\n\t\t\tgatheredTargetEvents[ns] = new Set([]);\n\t\t\tObject.keys(targetEvents[ns]).forEach(ev => {\n\t\t\t\tif( !hasValue(delegation) || hasValue(targetEvents[ns][ev].delegations[delegation]) ){\n\t\t\t\t\tgatheredTargetEvents[ns].add(ev);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t} else if( !hasValue(event) ){\n\t\tconst nameSpaceScope = targetEvents[namespace];\n\t\tif( hasValue(nameSpaceScope) ){\n\t\t\tgatheredTargetEvents[namespace] = new Set([]);\n\t\t\tObject.keys(targetEvents[namespace]).forEach(ev => {\n\t\t\t\tif( !hasValue(delegation) || hasValue(nameSpaceScope[ev].delegations[delegation]) ){\n\t\t\t\t\tgatheredTargetEvents[namespace].add(ev);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else if( !hasValue(namespace) ){\n\t\tObject.keys(targetEvents).forEach(ns => {\n\t\t\tconst nameSpaceScope = targetEvents[ns];\n\t\t\tif(\n\t\t\t\thasValue(nameSpaceScope[event])\n\t\t\t\t&& (!hasValue(delegation) || hasValue(nameSpaceScope[event].delegations[delegation]))\n\t\t\t){\n\t\t\t\tif( !hasValue(gatheredTargetEvents[ns]) ){\n\t\t\t\t\tgatheredTargetEvents[ns] = new Set([]);\n\t\t\t\t}\n\t\t\t\tgatheredTargetEvents[ns].add(event);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tconst nameSpaceScope = targetEvents[namespace];\n\t\tif(\n\t\t\thasValue(nameSpaceScope)\n\t\t\t&& hasValue(nameSpaceScope[event])\n\t\t\t&& (!hasValue(delegation) || hasValue(nameSpaceScope[event].delegations[delegation]))\n\t\t){\n\t\t\tif( !hasValue(gatheredTargetEvents[namespace]) ){\n\t\t\t\tgatheredTargetEvents[namespace] = new Set([]);\n\t\t\t}\n\t\t\tgatheredTargetEvents[namespace].add(event);\n\t\t}\n\t}\n\n\treturn gatheredTargetEvents;\n}\n\n\n\n/*\n * Iterates through the event map (starting with a specific target or using all targets) and searches for\n * deserted handler definitions. Deletes definitions that do not contain any handlers anymore and recursively\n * removes the path back to the starting point(s) if it turns out to be empty afterwards.\n *\n * @private\n */\nfunction cleanUpEventMap(targets){\n\ttargets = hasValue(targets) ? new Set([].concat(targets)) : null;\n\n\tconst desertedTargets = [];\n\n\tEVENT_MAP.forEach((targetEvents, target) => {\n\t\tif( !hasValue(targets) || targets.has(target) ){\n\t\t\tObject.keys(targetEvents).forEach(targetNamespace => {\n\t\t\t\tObject.keys(targetEvents[targetNamespace]).forEach(targetEvent => {\n\t\t\t\t\tconst targetScope = targetEvents[targetNamespace][targetEvent];\n\t\t\t\t\tlet handlerCount = targetScope.handlers.length;\n\n\t\t\t\t\tObject.keys(targetScope.delegations).forEach(delegation => {\n\t\t\t\t\t\tconst delegationHandlerCount = targetScope.delegations[delegation].handlers.length;\n\t\t\t\t\t\thandlerCount += delegationHandlerCount;\n\n\t\t\t\t\t\tif( delegationHandlerCount === 0 ){\n\t\t\t\t\t\t\tdelete targetScope.delegations[delegation];\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tif( handlerCount === 0){\n\t\t\t\t\t\tdelete targetEvents[targetNamespace][targetEvent];\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif( Object.keys(targetEvents[targetNamespace]).length === 0 ){\n\t\t\t\t\tdelete targetEvents[targetNamespace];\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif( Object.keys(targetEvents).length === 0 ){\n\t\t\t\tdesertedTargets.push(target);\n\t\t\t}\n\t\t}\n\t});\n\n\tdesertedTargets.forEach(desertedTarget => {\n\t\tEVENT_MAP.delete(desertedTarget);\n\t});\n}\n\n\n\n/*\n * Takes a handler function and returns a new function wrapping the handler, making sure, that the handler only\n * executes, if the event target matches the given delegation selector. So, the returned function automatically\n * checks if the delegation is actually met.\n *\n * @private\n */\nfunction createDelegatedHandler(delegation, handler){\n\treturn function delegatedHandler(e){\n\t\tconst\n\t\t\tdelegationSelector = `${delegation}`,\n\t\t\tdelegationFulfilled = hasValue(e.target?.matches)\n\t\t\t\t? e.target.matches(delegationSelector)\n\t\t\t\t: (\n\t\t\t\t\tisEventTarget(e.syntheticTarget)\n\t\t\t\t\t|| (\n\t\t\t\t\t\tisArray(e.syntheticTarget)\n\t\t\t\t\t\t&& isSelector(e.syntheticTarget[1])\n\t\t\t\t\t)\n\t\t\t\t\t? (\n\t\t\t\t\t\tisEventTarget(e.syntheticTarget)\n\t\t\t\t\t\t? e.syntheticTarget.matches(delegationSelector)\n\t\t\t\t\t\t: (e.syntheticTarget[1] === delegationSelector))\n\t\t\t\t\t: null\n\t\t\t\t)\n\t\t;\n\n\t\tif( delegationFulfilled ){\n\t\t\thandler(e);\n\t\t}\n\t};\n}\n\n\n\n/*\n * Takes a handler function and returns a new function, which, when executed, removes the handler from the exact\n * path in the EVENT_MAP, defined by the given target, namespace and event (and, optionally, a delegation selector).\n * Using this function, one can undo the setting of a handler, using \"on\" or \"once\".\n *\n * @private\n */\nfunction createHandlerRemover(target, namespace, event, handler, delegation=null, ignoreInvalidScope=false){\n\tconst\n\t\t__methodName__ = 'createHandlerRemover',\n\t\ttargetEvents = EVENT_MAP.get(target)\n\t;\n\tlet handlerScope = targetEvents?.[namespace]?.[event];\n\n\tif( hasValue(delegation) ){\n\t\tassert(isSelector(delegation), `${MODULE_NAME}:${__methodName__} | invalid delegation \"${delegation}\"`);\n\t\thandlerScope = handlerScope.delegations[`${delegation}`];\n\t}\n\n\tif( !ignoreInvalidScope ){\n\t\tassert(isPlainObject(handlerScope), `${MODULE_NAME}:${__methodName__} | invalid handlerScope`);\n\t} else if( !isPlainObject(handlerScope) ){\n\t\treturn () => {};\n\t}\n\n\treturn function handlerRemover(){\n\t\tconst removedHandlers = handlerScope.handlers.filter(existingHandler => existingHandler.handler === handler);\n\t\thandlerScope.handlers = removeFrom(handlerScope.handlers, removedHandlers);\n\n\t\tremovedHandlers.forEach(removedHandler => {\n\t\t\ttarget.removeEventListener(event, removedHandler.action);\n\t\t});\n\n\t\tcleanUpEventMap(target);\n\t};\n}\n\n\n\n/*\n * Takes a handler function and returns a new function, which, when executed, calls the handler and, afterwards,\n * automatically removes the handler from the path in the EVENT_MAP, defined by the given target, namespace and event\n * (and, optionally, a delegation selector). So, the returned function is essentially a self-destructing handler.\n *\n * @private\n */\nfunction createSelfRemovingHandler(target, namespace, event, handler, delegation=null){\n\treturn function selfRemovingHandler(e){\n\t\thandler(e);\n\t\tcreateHandlerRemover(target, namespace, event, handler, delegation, true)();\n\t};\n}\n\n\n\n/*\n * Removes (a) handler(s) from a path in the EVENT_MAP, defined by the given target, namespace, event and handler\n * (and, optionally, a delegation selector).\n *\n * @private\n */\nfunction removeLocatedHandler(target, namespace, event, handler, delegation=null){\n\tconst\n\t\t__methodName__ = 'removeLocatedHandler',\n\t\ttargetEvents = EVENT_MAP.get(target),\n\t\ttargetScope = targetEvents?.[namespace]?.[event]\n\t;\n\n\tassert(isPlainObject(targetScope), `${MODULE_NAME}:${__methodName__} | invalid targetScope`);\n\n\tlet handlerScope;\n\tif( hasValue(delegation) ){\n\t\tconst delegationScope = targetScope.delegations[`${delegation}`];\n\t\tassert(isPlainObject(delegationScope), `${MODULE_NAME}:${__methodName__} | invalid delegation \"${delegation}\"`);\n\t\thandlerScope = delegationScope;\n\t} else {\n\t\thandlerScope = targetScope;\n\t}\n\tconst removedHandlers = handlerScope.handlers.filter(existingHandler => {\n\t\treturn hasValue(handler)\n\t\t\t? (handler === existingHandler.handler)\n\t\t\t: true\n\t\t;\n\t});\n\n\thandlerScope.handlers = removeFrom(handlerScope.handlers, removedHandlers);\n\n\tremovedHandlers.forEach(removedHandler => {\n\t\ttarget.removeEventListener(event, removedHandler.action);\n\t\ttarget.removeEventListener(event, removedHandler.action, {capture : true});\n\t});\n\n\treturn removedHandlers.length;\n}\n\n\n\n/*\n * Removes all handlers matching the given definition provided by target, namespace, event and handler\n * (and, optionally, a delegation selector). Leaving out namespace, event or handler works as a wildcard.\n *\n * @private\n */\nfunction removeHandlers(target, namespace=null, event=null, handler=null, delegation=null){\n\tconst targetEvents = gatherTargetEvents(target, namespace, event, delegation);\n\n\tlet removedCount = 0;\n\n\tObject.keys(targetEvents).forEach(ns => {\n\t\tArray.from(targetEvents[ns]).forEach(ev => {\n\t\t\tremovedCount += removeLocatedHandler(target, ns, ev, handler, delegation);\n\t\t});\n\t});\n\n\treturn removedCount;\n}\n\n\n\n/*\n * Shorthand-function for \"removeHandlers\" with more sane parameter order for delegations.\n *\n * @private\n */\nfunction removeDelegatedHandlers(ancestor, delegation, namespace=null, event=null, handler=null){\n\treturn removeHandlers(ancestor, namespace, event, handler, delegation);\n}\n\n\n\n/*\n * Pauses (a) handler(s) from a path in the EVENT_MAP, defined by the given target, namespace, event and handler\n * (and, optionally, a delegation selector). If paused is false, the function instead resumes the handlers.\n *\n * @private\n */\nfunction pauseLocatedHandlers(target, namespace, event, handler, delegation=null, paused=true){\n\tconst\n\t\t__methodName__ = 'pauseLocatedHandlers',\n\t\ttargetEvents = EVENT_MAP.get(target),\n\t\ttargetScope = targetEvents?.[namespace]?.[event]\n\t;\n\n\tassert(isPlainObject(targetScope), `${MODULE_NAME}:${__methodName__} | invalid targetScope`);\n\n\tlet handlerScope;\n\tif( hasValue(delegation) ){\n\t\tconst delegationScope = targetScope.delegations[`${delegation}`];\n\t\tassert(isPlainObject(delegationScope), `${MODULE_NAME}:${__methodName__} | invalid delegation \"${delegation}\"`);\n\t\thandlerScope = delegationScope;\n\t} else {\n\t\thandlerScope = targetScope;\n\t}\n\n\tconst pausedHandlers = handlerScope.handlers.filter(existingHandler => {\n\t\treturn hasValue(handler)\n\t\t\t? (handler === existingHandler.handler)\n\t\t\t: true\n\t\t;\n\t});\n\n\tpausedHandlers.forEach(pausedHandler => {\n\t\tpausedHandler.paused = !!paused;\n\t});\n\n\treturn pausedHandlers.length;\n}\n\n\n\n/*\n * Pauses all handlers matching the given definition provided by target, namespace, event and handler\n * (and, optionally, a delegation selector). Leaving out namespace, event or handler works as a wildcard.\n * If paused is false, the function instead resumes the handlers.\n *\n * @private\n */\nfunction pauseHandlers(target, namespace=null, event=null, handler=null, delegation=null, paused=true){\n\tconst targetEvents = gatherTargetEvents(target, namespace, event, delegation);\n\n\tlet pausedCount = 0;\n\n\tObject.keys(targetEvents).forEach(ns => {\n\t\tArray.from(targetEvents[ns]).forEach(ev => {\n\t\t\tpausedCount += pauseLocatedHandlers(target, ns, ev, handler, delegation, paused);\n\t\t});\n\t});\n\n\treturn pausedCount;\n}\n\n\n\n/*\n * Shorthand-function for \"pauseHandlers\" with more sane parameter order for delegations.\n *\n * @private\n */\nfunction pauseDelegatedHandlers(ancestor, delegation, namespace=null, event=null, handler=null, paused=true){\n\treturn pauseHandlers(ancestor, namespace, event, handler, delegation, paused);\n}\n\n\n\n/*\n * Takes a handler object and a corresponding action, which is not yet aware of its pause state and\n * returns an action function, which checks if the handler is paused, before executing the original action.\n * Using this, we can wrap handler actions to automatically react to the handler's pause state, preventing any\n * handler execution if the handler is currently paused.\n *\n * @private\n */\nfunction createPauseAwareAction(managedHandler, nonPauseAwareAction){\n\treturn function pauseAwareHandler(e){\n\t\tif( !managedHandler.paused ){\n\t\t\tnonPauseAwareAction(e);\n\t\t}\n\t};\n}\n\n\n\n/*\n * Takes an event listener options object as provided by the user, to be used as the third parameter of\n * addEventListener, and returns a sanitized version, taking into regard what options the browser actually supports\n * and falling back to boolean capture values, if the browser does not know about listener options at all.\n *\n * @private\n */\nfunction compileEventListenerOptions(options){\n\tif( isBoolean(options) ) return options;\n\tif( !isObject(options) ) return null;\n\n\tconst supportedOptions = {};\n\n\tObject.keys(EVENT_OPTION_SUPPORT).forEach(option => {\n\t\tif( !!EVENT_OPTION_SUPPORT[option] && hasValue(options[option]) ){\n\t\t\tsupportedOptions[option] = options[option];\n\t\t}\n\t});\n\n\tif( (Object.keys(supportedOptions).length === 0) && !!options.capture ){\n\t\treturn true;\n\t}\n\n\treturn supportedOptions;\n}\n\n\n\n/*\n * Creates a synthetic event to dispatch on an event target.\n *\n * @private\n */\nfunction createSyntheticEvent(\n\tevent,\n\tnamespace=null,\n\tpayload=null,\n\tbubbles=null,\n\tcancelable=null,\n\tsyntheticTarget=null,\n\tEventConstructor=null,\n\teventOptions=null\n){\n\tconst __methodName__ = 'createSyntheticEvent';\n\n\tevent = `${event}`;\n\tbubbles = orDefault(bubbles, false, 'bool');\n\tcancelable = orDefault(cancelable, bubbles, 'bool');\n\teventOptions = isPlainObject(eventOptions) ? eventOptions : {};\n\n\tlet e;\n\tif( isFunction(EventConstructor) ){\n\t\tif( hasValue(payload) ){\n\t\t\twarn(`${MODULE_NAME}:${__methodName__} | can't add payload to event \"${EventConstructor.name}\", skipping`);\n\t\t}\n\t\te = new EventConstructor(event, {bubbles, cancelable, ...eventOptions});\n\t} else {\n\t\te = hasValue(payload)\n\t\t\t? new CustomEvent(event, {detail : payload, bubbles, cancelable, ...eventOptions})\n\t\t\t// we could use new Event() here, but jsdom and ava cannot use that constructor for dispatchEvent :(\n\t\t\t: new CustomEvent(event, {bubbles, cancelable, ...eventOptions})\n\t\t;\n\t}\n\n\tif( hasValue(namespace) ){\n\t\te.namespace = `${namespace}`;\n\t}\n\n\tif( isEventTarget(syntheticTarget) ){\n\t\te.syntheticTarget = syntheticTarget;\n\t\te.syntheticTargetElements = [syntheticTarget]\n\t} else if(\n\t\tisArray(syntheticTarget)\n\t\t&& isEventTarget(syntheticTarget[0])\n\t\t&& isSelector(syntheticTarget[1])\n\t){\n\t\te.syntheticTarget = syntheticTarget;\n\t\tObject.defineProperty(e, 'syntheticTargetElements', {\n\t\t\tget(){\n\t\t\t\treturn Array.from(syntheticTarget[0].querySelectorAll(`${syntheticTarget[1]}`));\n\t\t\t}\n\t\t});\n\t}\n\n\treturn e;\n}\n\n\n\n/*\n * Updates touch data for a start swipe event.\n *\n * @private\n */\nfunction updateSwipeTouch(e){\n\tconst startOrEnd = ['touchstart', 'mousedown'].includes(e.type) ? 'start' : 'end';\n\tif( ['touchstart', 'touchend'].includes(e.type) ){\n\t\tSWIPE_TOUCH[`${startOrEnd}X`] = e.changedTouches[0].screenX;\n\t\tSWIPE_TOUCH[`${startOrEnd}Y`] = e.changedTouches[0].screenY;\n\t} else {\n\t\tSWIPE_TOUCH[`${startOrEnd}X`] = e.screenX;\n\t\tSWIPE_TOUCH[`${startOrEnd}Y`] = e.screenY;\n\t}\n}\n\n\n\n/*\n * Tries to find a usable target for post messages, based on a given target element.\n *\n * @private\n */\nfunction resolvePostMessageTarget(target, method){\n\ttarget = isWindow(target)\n\t\t? target\n\t\t: (\n\t\t\tisWindow(target?.contentWindow)\n\t\t\t? target.contentWindow\n\t\t\t: null\n\t\t)\n\t;\n\n\tassert(hasValue(target), `${MODULE_NAME}:${method} | no usable target`);\n\n\treturn target\n}\n\n\n\n/*\n * Default handling for post messages for a window.\n *\n * @private\n */\nfunction windowPostMessageHandler(e){\n\tconst\n\t\ttarget = e.currentTarget,\n\t\ttargetPostMessages = POST_MESSAGE_MAP.get(target),\n\t\torigin = !isEmpty(e.origin) ? e.origin : (!!window.__AVA_ENV__ ? window.location.href : null),\n\t\tmessageType = e.data?.type\n\t;\n\n\tif( hasValue(targetPostMessages) ){\n\t\tconst messageTypes = hasValue(messageType) ? [messageType] : Object.keys(targetPostMessages);\n\t\tmessageTypes.forEach(messageType => {\n\t\t\t(targetPostMessages[messageType] ?? []).forEach(handler => {\n\t\t\t\tif( (handler.origin === '*') || (handler.origin === origin) ){\n\t\t\t\t\thandler.handler(e);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n}\n\n\n\n/*\n * Iterates message handlers for a target, and removes handlers, based on given handler and origin.\n *\n * @private\n */\nfunction removePostMessageHandlers(targetPostMessages, messageType, origin=null, handler=null){\n\tif( hasValue(targetPostMessages[messageType]) ){\n\t\tconst handlerCountBefore = targetPostMessages[messageType].length;\n\n\t\tif( !hasValue(origin) && !hasValue(handler) ){\n\t\t\ttargetPostMessages[messageType] = [];\n\t\t} else if( hasValue(origin) && !hasValue(handler) ){\n\t\t\ttargetPostMessages[messageType] = targetPostMessages[messageType].filter(h => h.origin !== origin);\n\t\t} else if( !hasValue(origin) && hasValue(handler) ){\n\t\t\ttargetPostMessages[messageType] = targetPostMessages[messageType].filter(h => h.handler !== handler);\n\t\t} else if( hasValue(origin, handler) ) {\n\t\t\ttargetPostMessages[messageType] = targetPostMessages[messageType].filter(\n\t\t\t\th => (h.origin !== origin) && (h.handler !== handler)\n\t\t\t);\n\t\t}\n\n\t\tconst handlerCountAfter = targetPostMessages[messageType].length;\n\n\t\tif( targetPostMessages[messageType].length === 0 ){\n\t\t\tdelete targetPostMessages[messageType];\n\t\t}\n\n\t\treturn handlerCountBefore - handlerCountAfter;\n\t} else {\n\t\treturn 0;\n\t}\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Events:on\n */\n\n/**\n * Registers (an) event listener(s) to (a) valid EventTarget(s) (most likely (a) DOM-element(s)).\n *\n * This method is inspired by jQuery and cash, though not identical.\n * You may define one or more targets as well as one or more events to register a handler to, by either providing single\n * arguments or arrays. You may also, additionally, namespace events, like in jQuery/cash, by adding it after the event\n * name, separated by a dot ('click.namespace').\n *\n * This method returns a remover function, which removes all event registrations done by this method call.\n * So, in essence, calling that function, removes exactly, what was added, in a single call.\n *\n * @param {EventTarget|Array} targets - the target(s) to register event handlers on\n * @param {String|Array} events - the event name(s) to listen to, can be either a single name or a list of names, each name may also have a namespace, separated by a dot, to target all events/namespaces, you may use \"*\"/\"*.*\"\n * @param {Function} handler - the callback to execute if the event(s) defined in events are being received on target\n * @param {?Object|Boolean} [options=null] - event listener options according to \"addEventListener\"-syntax, will be ignored, if browser does not support this, if boolean, will be used as \"useCapture\", the same will happen if options are not supported, but you defined \"{capture : true}\", \"{once : true}\" will not be applied directly to the listener, but will, instead, set the \"once\"-parameter to true (otherwise delegated listeners would self-destroy immediately on any check)\n * @param {?Boolean} [once=false] - defines if the handler should only execute once, after which it self-destroys automatically, this will automatically be enabled, if you set options.once to true\n * @throws error in case no targets are defined\n * @throws error in case no events are defined\n * @throws error in case handler is not a function\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Function} remover function, which removes all handlers again, added by the current execution\n *\n * @memberof Events:on\n * @alias on\n * @see off\n * @see once\n * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget\n * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener?retiredLocale=de#syntax\n * @example\n * on(linkElement, 'click', e => {\te.stopPropagation(); });\n * on(someElementWithCustomEvents, 'crash.test', () => { alert('crashed!'); });\n * on([ancestorElement, 'a'], 'click', e => { e.target.classList.add('clicked'); });\n * on(buttonElement, 'click', () => { console.log('click twice, but I'll just print once); }, {passive : true, once : true});\n * on([ancestorElement, '.btn[data-foobar=\"test\"]'], 'click', () => { console.log('I'll just fire once); }, null, true);\n * on(document.body, 'click', e => { console.log(`oh, a bubbled event, let's see what has been clicked: \"${e.target}\"`); });\n * on([foo, foo, 'button', bar], ['mousedown', 'touchstart'], e => { e.target.classList.add('interaction-start'); });\n */\nexport function on(targets, events, handler, options=null, once=false){\n\tconst __methodName__ = 'on';\n\n\t({targets, events, handler} = prepareEventMethodBaseParams(__methodName__, targets, events, handler));\n\tonce = !!once || !!options?.once;\n\tdelete options?.once;\n\n\tconst removers = [];\n\n\ttargets.forEach((target, targetIndex) => {\n\t\tconst {\n\t\t\tprevTarget,\n\t\t\thasDelegation,\n\t\t\tisDelegation\n\t\t} = prepareEventMethodAdditionalTargetInfo(__methodName__, targets, targetIndex);\n\n\t\tlet targetEvents = EVENT_MAP.get(target);\n\t\tif( isDelegation ){\n\t\t\ttargetEvents = EVENT_MAP.get(prevTarget);\n\t\t} else if( !hasValue(targetEvents) ){\n\t\t\tEVENT_MAP.set(target, {[DEFAULT_NAMESPACE] : {}});\n\t\t\ttargetEvents = EVENT_MAP.get(target);\n\t\t}\n\n\t\tif( !hasDelegation ){\n\t\t\tevents.forEach(eventName => {\n\t\t\t\tconst {event, namespace} = prepareEventMethodEventInfo(eventName, DEFAULT_NAMESPACE);\n\n\t\t\t\tif( !hasValue(targetEvents[namespace]) ){\n\t\t\t\t\ttargetEvents[namespace] = {};\n\t\t\t\t}\n\n\t\t\t\tif( !hasValue(targetEvents[namespace][event]) ){\n\t\t\t\t\ttargetEvents[namespace][event] = {\n\t\t\t\t\t\ttarget : isDelegation ? prevTarget : target,\n\t\t\t\t\t\thandlers : [],\n\t\t\t\t\t\tdelegations : {}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst targetScope = targetEvents[namespace][event];\n\t\t\t\tlet handlerScope, action, remover;\n\n\t\t\t\tif( isDelegation ){\n\t\t\t\t\tif( !hasValue(targetScope.delegations[target]) ){\n\t\t\t\t\t\ttargetScope.delegations[target] = {handlers : []};\n\t\t\t\t\t}\n\t\t\t\t\thandlerScope = targetScope.delegations[target];\n\n\t\t\t\t\taction = !!once\n\t\t\t\t\t\t? createDelegatedHandler(\n\t\t\t\t\t\t\ttarget,\n\t\t\t\t\t\t\tcreateSelfRemovingHandler(targetScope.target, namespace, event, handler, target)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t: createDelegatedHandler(target, handler)\n\t\t\t\t\t;\n\t\t\t\t\tremover = createHandlerRemover(targetScope.target, namespace, event, handler, target);\n\t\t\t\t} else {\n\t\t\t\t\thandlerScope = targetScope;\n\t\t\t\t\taction = !!once\n\t\t\t\t\t\t? createSelfRemovingHandler(targetScope.target, namespace, event, handler)\n\t\t\t\t\t\t: handler\n\t\t\t\t\t;\n\t\t\t\t\tremover = createHandlerRemover(targetScope.target, namespace, event, handler);\n\t\t\t\t}\n\n\t\t\t\tconst managedHandler = {\n\t\t\t\t\thandler,\n\t\t\t\t\tremover,\n\t\t\t\t\tpaused : false,\n\t\t\t\t};\n\t\t\t\tmanagedHandler.action = createPauseAwareAction(managedHandler, action);\n\t\t\t\thandlerScope.handlers = handlerScope.handlers.concat(managedHandler);\n\n\t\t\t\tconst eventListenerOptions = compileEventListenerOptions(options);\n\t\t\t\tif( hasValue(eventListenerOptions) ){\n\t\t\t\t\ttargetScope.target.addEventListener(event, managedHandler.action, eventListenerOptions);\n\t\t\t\t} else {\n\t\t\t\t\ttargetScope.target.addEventListener(event, managedHandler.action);\n\t\t\t\t}\n\n\t\t\t\tremovers.push(remover);\n\t\t\t});\n\t\t}\n\t});\n\n\treturn (removers.length > 1)\n\t\t? function(){\n\t\t\tremovers.forEach(remover => remover());\n\t\t}\n\t\t: (\n\t\t\t(removers.length > 0)\n\t\t\t? removers[0]\n\t\t\t: null\n\t\t)\n\t;\n}\n\n\n\n/**\n * @namespace Events:once\n */\n\n/**\n * Registers (an) event listener(s) to (a) valid EventTarget(s) (most likely (a) DOM-element(s)).\n *\n * This version automatically removes the handler, after it has fired once.\n *\n * This method is inspired by jQuery and cash, though not identical.\n * You may define one or more targets as well as one or more events to register a handler to, by either providing single\n * arguments or arrays. You may also, additionally, namespace events, like in jQuery/cash, by adding it after the event\n * name, separated by a dot ('click.namespace').\n *\n * This method returns a remover function, which removes all event registrations done by this method call.\n * So, in essence, calling that function, removes exactly, what was added, in a single call.\n *\n * @param {EventTarget|Array} targets - the target(s) to register event handlers on\n * @param {String|Array} events - the event name(s) to listen to, can be either a single name or a list of names, each name may also have a namespace, separated by a dot, to target all events/namespaces, you may use \"*\"/\"*.*\"\n * @param {Function} handler - the callback to execute if the event(s) defined in events are being received on target\n * @param {?Object|Boolean} [options=null] - event listener options according to \"addEventListener\"-syntax, will be ignored, if browser does not support this, if boolean, will be used as \"useCapture\", the same will happen if options are not supported, but you defined \"{capture : true}\", \"{once : true}\" makes no sense in this case, because the behaviour will automatically be applied anyway\n * @throws error in case no targets are defined\n * @throws error in case no events are defined\n * @throws error in case handler is not a function\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Function} remover function, which removes all handlers again, added by the current execution\n *\n * @memberof Events:once\n * @alias once\n * @see on\n * @see off\n * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget\n * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener?retiredLocale=de#syntax\n * @example\n * once(linkElement, 'click', e => {\te.stopPropagation(); });\n * once(someElementWithCustomEvents, 'crash.test', () => { alert('crashed!'); });\n * once([ancestorElement, 'a'], 'click', e => { e.target.classList.add('clicked'); });\n * once(buttonElement, 'click', () => { console.log('click twice, but I'll just print once); }, {passive : true});\n * once([ancestorElement, '.btn[data-foobar=\"test\"]'], 'click', () => { console.log('I'll just fire once); });\n * once(document.body, 'click', e => { console.log(`oh, a bubbled event, let's see what has been clicked: \"${e.target}\"`); });\n * once([foo, foo, 'button', bar], ['mousedown', 'touchstart'], e => { e.target.classList.add('interaction-start'); });\n */\nexport function once(targets, events, handler, options=null){\n\treturn on(targets, events, handler, options, true);\n}\n\n\n\n/**\n * @namespace Events:off\n */\n\n/**\n * Removes (a), previously defined, event listener(s) on (a) valid EventTarget(s) (most likely (a) DOM-element(s)).\n *\n * The definition of targets and events works exactly as in \"on\" and \"once\", the only difference being, that the handler\n * is optional in this case, which results in the removal of all handlers, without targeting a specific one.\n *\n * To specifically target handlers without a namespace, please use the namespace-string \"__default\".\n *\n * This function does _not_ differentiate between removal of capture/non-capture events, but always removes both.\n *\n * If you try to remove event handlers not previously created with `on` (and therefore there are no fitting target\n * entries in the EVENT_MAP), the function will fall back to native `removeEventListener`\n * (if `tryNativeRemoval` is true), but in that case, a handler has to be defined and the return value will not\n * increment, since we do not know if the removal really worked.\n *\n * @param {EventTarget|Array} targets - the target(s) to remove event handlers from\n * @param {String|Array} events - the event name(s) to remove, can be either a single name or a list of names, each name may also have a namespace, separated by a dot, to target all events/namespaces, you may use \"*\"/\"*.*\"\n * @param {?Function} [handler=null] - a specific callback function to remove\n * @param {?Boolean} [tryNativeRemoval=true] - if a target is not part of the EVENT_MAP native removeEventListener is used as a fallback if this is true (handler needs to be set in that case)\n * @throws error in case no targets are defined\n * @throws error in case no events are defined\n * @throws error in case a defined handler is not a function\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Number} the number of handlers actually removed by the function call, may also be 0 if nothing matched\n *\n * @memberof Events:off\n * @alias off\n * @see on\n * @see once\n * @example\n * off(buttonElement, 'click');\n * off(bar, '*.__default');\n * off(customEventElement, 'crash');\n * off([ancestorElement, 'a'], 'click');\n * off([ancestorElement, '.btn[data-foobar=\"test\"]'], '*.delegated', fSpecificHandler);\n * off(linkElement, '*', fSpecificHandler);\n * off(customEventElement, ['*.test', '*.site']);\n * off([ancestorElement, 'a', ancestorElement, '.btn[data-foobar=\"test\"]'], '*.*', fSpecificHandler);\n * off(buttonElement, '*.*');\n */\nexport function off(targets, events, handler=null, tryNativeRemoval=true){\n\tconst __methodName__ = 'off';\n\n\t({targets, events, handler} = prepareEventMethodBaseParams(__methodName__, targets, events, handler, true));\n\ttryNativeRemoval = orDefault(tryNativeRemoval, true, 'bool');\n\n\tlet removedCount = 0;\n\n\ttargets.forEach((target, targetIndex) => {\n\t\tconst {\n\t\t\tprevTarget,\n\t\t\thasDelegation,\n\t\t\tisDelegation\n\t\t} = prepareEventMethodAdditionalTargetInfo(__methodName__, targets, targetIndex);\n\n\t\tif( !hasDelegation ){\n\t\t\tconst targetEvents = isDelegation ? EVENT_MAP.get(prevTarget) : EVENT_MAP.get(target);\n\n\t\t\tevents.forEach(eventName => {\n\t\t\t\tconst {event, namespace} = prepareEventMethodEventInfo(eventName);\n\n\t\t\t\tif( hasValue(targetEvents) ){\n\t\t\t\t\tif( isDelegation ){\n\t\t\t\t\t\tremovedCount += removeDelegatedHandlers(prevTarget, target, namespace, event, handler);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tremovedCount += removeHandlers(target, namespace, event, handler);\n\t\t\t\t\t}\n\n\t\t\t\t\tcleanUpEventMap(isDelegation ? prevTarget : target);\n\t\t\t\t} else if( tryNativeRemoval ){\n\t\t\t\t\tif( hasValue(handler) ){\n\t\t\t\t\t\t(isDelegation ? prevTarget : target).removeEventListener(eventName, handler);\n\t\t\t\t\t\t(isDelegation ? prevTarget : target).removeEventListener(eventName, handler, {capture : true});\n\t\t\t\t\t} else {\n\t\t\t\t\t\twarn(`${MODULE_NAME}:${__methodName__} | native fallback event removal for \"${eventName}\" not possible, handler is missing`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\n\treturn removedCount;\n}\n\n\n\n/**\n * @namespace Events:pause\n */\n\n/**\n * Pauses (a), previously defined, event listener(s), without actually removing anything. Subsequent executions\n * of the handler will not fire, while the handler is paused, which also means, that paused handlers, set up to only\n * fire once, will not self-destroy while being paused.\n *\n * The definition of targets and events works exactly as in \"on\" and \"once\", the only difference being, that the handler\n * is optional in this case, which results in the pausing of all handlers, without targeting a specific one.\n *\n * To specifically target handlers without a namespace, please use the namespace-string \"__default\".\n *\n * @param {EventTarget|Array} targets - the target(s) to pause event handlers on\n * @param {String|Array} events - the event name(s) to pause, can be either a single name or a list of names, each name may also have a namespace, separated by a dot, to target all events/namespaces, you may use \"*\"/\"*.*\"\n * @param {?Function} [handler=null] - a specific callback function to pause\n * @param {?Boolean} [paused=true] - defines if the matched handlers are being paused or resumed\n * @throws error in case no targets are defined\n * @throws error in case no events are defined\n * @throws error in case a defined handler is not a function\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Number} the number of handlers actually paused by the function call, may also be 0 if nothing matched\n *\n * @memberof Events:pause\n * @alias pause\n * @see on\n * @see resume\n * @example\n * pause(buttonElement, 'click');\n * pause(linkElement, '*.__default');\n * pause(customEventElement, 'crash');\n * pause([ancestorElement, 'a'], 'click');\n * pause([ancestorElement, '.btn[data-foobar=\"test\"]'], '*.delegated', fSpecificHandler);\n */\nexport function pause(targets, events, handler=null, paused=true){\n\tconst __methodName__ = 'pause';\n\n\t({targets, events, handler} = prepareEventMethodBaseParams(__methodName__, targets, events, handler, true));\n\n\tlet pausedCount = 0;\n\n\ttargets.forEach((target, targetIndex) => {\n\t\tconst {\n\t\t\tprevTarget,\n\t\t\thasDelegation,\n\t\t\tisDelegation\n\t\t} = prepareEventMethodAdditionalTargetInfo(__methodName__, targets, targetIndex);\n\n\t\tif( !hasDelegation ){\n\t\t\tconst targetEvents = isDelegation ? EVENT_MAP.get(prevTarget) : EVENT_MAP.get(target);\n\n\t\t\tif( hasValue(targetEvents) ){\n\t\t\t\tevents.forEach(eventName => {\n\t\t\t\t\tconst {event, namespace} = prepareEventMethodEventInfo(eventName);\n\n\t\t\t\t\tif( isDelegation ){\n\t\t\t\t\t\tpausedCount += pauseDelegatedHandlers(prevTarget, target, namespace, event, handler, paused);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpausedCount += pauseHandlers(target, namespace, event, handler, null, paused);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t});\n\n\treturn pausedCount;\n}\n\n\n\n/**\n * @namespace Events:resume\n */\n\n/**\n * Resumes (a), previously paused, event listener(s). Subsequent executions of the handler will fire again.\n *\n * The definition of targets and events works exactly as in \"on\" and \"once\", the only difference being, that the handler\n * is optional in this case, which results in the un-pausing of all handlers, without targeting a specific one.\n *\n * To specifically target handlers without a namespace, please use the namespace-string \"__default\".\n *\n * @param {EventTarget|Array} targets - the target(s) to resume event handlers on\n * @param {String|Array} events - the event name(s) to resume, can be either a single name or a list of names, each name may also have a namespace, separated by a dot, to target all events/namespaces, you may use \"*\"/\"*.*\"\n * @param {?Function} [handler=null] - a specific callback function to resume\n * @throws error in case no targets are defined\n * @throws error in case no events are defined\n * @throws error in case a defined handler is not a function\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Number} the number of handlers actually resumed by the function call, may also be 0 if nothing matched\n *\n * @memberof Events:resume\n * @alias resume\n * @see on\n * @see pause\n * @example\n * resume(linkElement, '*', fSpecificHandler);\n * resume(customEventElement, ['*.test', '*.site']);\n * resume([ancestorElement, 'a', ancestorElement, '.btn[data-foobar=\"test\"]'], '*.*', fSpecificHandler);\n * resume(buttonElement, '*.*');\n */\nexport function resume(targets, events, handler=null){\n\treturn pause(targets, events, handler, false);\n}\n\n\n\n/**\n * @namespace Events:fire\n */\n\n/**\n * Fires event handlers of all matched targets for given events.\n *\n * This function does not actually dispatch events, but identifies matches in the internal event map, based on\n * previously registered handlers using \"on\" and \"once\" and executes the attached handlers, providing them a synthetic\n * CustomEvent as first parameter, carrying the event name as well as a potential payload. So this, function is\n * using the event map as an event bus, instead of the DOM, so these events also will never bubble, but just hit the\n * currently present handlers identified exactly by the provided parameters.\n *\n * The definition of targets and events works exactly as in \"on\" and \"once\", the only difference being, that we have no\n * handler, since if we'd have the handler already, we could just call it.\n *\n * Since we do not use the DOM in this function, we also do not have native events, and therefore we do not have normal\n * event targets we can work with. Instead, this implementation adds the \"syntheticTarget\" and the\n * \"syntheticTargetElements\" event properties to the event that is given to the handler. \"syntheticTarget\" contains\n * the defined event map target, either as a EventTarget or an array of an EventTarget and a corresponding delegation\n * selector (just as you defined them before), while \"syntheticTargetElements\" returns the actual elements as an\n * iterable array. So, in case of a delegation, this gives you the power to actually work with the current delegation\n * targets, without having to write own logic for this.\n *\n * @param {EventTarget|Array} targets - the target(s) to execute event handlers on\n * @param {String|Array} events - the event name(s) to fire, can be either a single name or a list of names, each name may also have a namespace, separated by a dot, to target all events/namespaces, you may use \"*\"/\"*.*\"\n * @param {?Object} [payload=null] - a plain object payload to relay to the event handlers via the detail of the CustomEvent given to the handler as first parameter\n * @throws error in case no targets are defined\n * @throws error in case no events are defined\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Number} the number of handlers actually executed by the function call, may also be 0 if nothing matched\n *\n * @memberof Events:fire\n * @alias fire\n * @see on\n * @see once\n * @see emit\n * @example\n * fire(buttonElement, 'click');\n * fire(linkElement, '*.__default', {importantFlag : true});\n * fire(divElement, 'crash');\n * fire([ancestorElement, 'a'], 'click', {linkWasClicked : true});\n * fire([ancestorElement, '.btn[data-foobar=\"test\"]'], '*.delegated');\n * fire(linkElement, '*');\n * fire([ancestorElement, 'a', ancestorElement, '.btn[data-foobar=\"test\"]'], '*.*');\n * fire(buttonElement, 'click.*', {price : 666});\n */\nexport function fire(targets, events, payload=null){\n\tconst __methodName__ = 'fire';\n\n\t({targets, events} = prepareEventMethodBaseParams(__methodName__, targets, events, null, true));\n\n\tlet fireCount = 0;\n\n\ttargets.forEach((target, targetIndex) => {\n\t\tconst {\n\t\t\tprevTarget,\n\t\t\thasDelegation,\n\t\t\tisDelegation\n\t\t} = prepareEventMethodAdditionalTargetInfo(__methodName__, targets, targetIndex);\n\n\t\tif( !hasDelegation ){\n\t\t\tconst targetEvents = isDelegation ? EVENT_MAP.get(prevTarget) : EVENT_MAP.get(target);\n\n\t\t\tif( hasValue(targetEvents) ){\n\t\t\t\tevents.forEach(eventName => {\n\t\t\t\t\tconst {event, namespace} = prepareEventMethodEventInfo(eventName);\n\n\t\t\t\t\tlet gatheredTargetEvents;\n\t\t\t\t\tif( isDelegation ){\n\t\t\t\t\t\tgatheredTargetEvents = gatherTargetEvents(prevTarget, namespace, event, target);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgatheredTargetEvents = gatherTargetEvents(target, namespace, event);\n\t\t\t\t\t}\n\n\t\t\t\t\tObject.keys(gatheredTargetEvents).forEach(ns => {\n\t\t\t\t\t\tArray.from(gatheredTargetEvents[ns]).forEach(ev => {\n\t\t\t\t\t\t\tconst\n\t\t\t\t\t\t\t\thandlerScope = isDelegation\n\t\t\t\t\t\t\t\t\t? targetEvents[ns][ev].delegations[target]\n\t\t\t\t\t\t\t\t\t: targetEvents[ns][ev]\n\t\t\t\t\t\t\t\t,\n\t\t\t\t\t\t\t\tsyntheticEvent = isDelegation\n\t\t\t\t\t\t\t\t\t? createSyntheticEvent(ev, ns, payload, false, false, [prevTarget, target])\n\t\t\t\t\t\t\t\t\t: createSyntheticEvent(ev, ns, payload, false, false, target)\n\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\thandlerScope.handlers.forEach(handler => {\n\t\t\t\t\t\t\t\thandler.action(syntheticEvent);\n\t\t\t\t\t\t\t\tfireCount++;\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t});\n\n\treturn fireCount;\n}\n\n\n\n/**\n * @namespace Events:emit\n */\n\n/**\n * Dispatches synthetic events on all given targets.\n *\n * In contrast to \"fire\", this function actually dispatches bubbling events on the provided EventTargets. Delegations\n * are resolved using \"querySelectorAll\". This function does not check actual handler presence using the event map, but\n * blindly emits what has been given, purely using the DOM as the event bus. Handlers defined with \"on\" and \"once\" will\n * of course still be triggered if hit, since they always also register a native event listener. The events emitted\n * are purely synthetic basic Events and CustomEvents, lacking special properties, which, for example, MouseEvents\n * provide. So, using \"screenX\" in the handler will not work. If you need a certain base class for the created events,\n * use the \"EventConstructor\" to provide the base class and add special options via \"eventOptions\".\n *\n * The definition of targets and events works almost as in \"on\" and \"once\", the only differences being, that we have no\n * handler, and we cannot leave out the event name. Using a wildcard for the namespace will leave out the namespace in\n * the created events.\n *\n * @param {EventTarget|Array} targets - the target(s) to dispatch events on\n * @param {String|Array} events - the event name(s) to emit, can be either a single name or a list of names, each name may also have a namespace, separated by a dot, to target all events/namespaces, you may use \"*\"/\"*.*\"\n * @param {?Object} [payload=null] - a plain object payload to relay to the event handlers via the detail of the CustomEvent given to the handler as first parameter\n * @param {?Function} [EventConstructor=null] - the default constructor is Event/CustomEvent, if you need another specific synthetic event, provide a constructor such as MouseEvent here\n * @param {?Object} [eventOptions=null] - use this plain object to provide constructor specific options to use in event construction, this should especially come in handy in case you provide a custom EventConstructor\n * @throws error in case no targets are defined\n * @throws error in case no events are defined\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Number} the number of events actually dispatched by the function call, may also be 0 if nothing matched\n *\n * @memberof Events:emit\n * @alias emit\n * @see on\n * @see once\n * @see fire\n * @example\n * emit([buttonElement, ancestorElement, 'a'], 'click');\n * emit(linkElement, 'click.__default', {defaultClick: true});\n * emit([divElement, document.body], 'crash');\n * emit([ancestorElement, 'a'], 'click', {trackingId : 'abc123'});\n * emit([ancestorElement, '.btn[data-foobar=\"test\"]'], 'click.delegated');\n * emit(ancestorElement, ['crash.test', 'crash.site'], {damage : 1000});\n * emit([ancestorElement, 'a', ancestorElement, '.btn[data-foobar=\"test\"]'], 'click.delegated', null, null, {bubbles : false});\n * emit(buttonElement, 'click.*', {price : 666}, MouseEvent, {bubbles : false});\n */\nexport function emit(targets, events, payload=null, EventConstructor=null, eventOptions=null){\n\tconst __methodName__ = 'emit';\n\n\t({targets, events} = prepareEventMethodBaseParams(__methodName__, targets, events, null, true));\n\n\tlet emitCount = 0;\n\n\ttargets.forEach((target, targetIndex) => {\n\t\tconst {\n\t\t\tprevTarget,\n\t\t\thasDelegation,\n\t\t\tisDelegation\n\t\t} = prepareEventMethodAdditionalTargetInfo(__methodName__, targets, targetIndex);\n\n\t\tif( !hasDelegation ){\n\t\t\tevents.forEach(eventName => {\n\t\t\t\tconst {event, namespace} = prepareEventMethodEventInfo(eventName);\n\n\t\t\t\tassert(hasValue(event), `${MODULE_NAME}:${__methodName__} | missing event name`);\n\n\t\t\t\tif( isDelegation ){\n\t\t\t\t\tArray.from(prevTarget.querySelectorAll(target)).forEach(element => {\n\t\t\t\t\t\telement.dispatchEvent(\n\t\t\t\t\t\t\tcreateSyntheticEvent(event, namespace, payload, true, true, null, EventConstructor, eventOptions)\n\t\t\t\t\t\t);\n\t\t\t\t\t\temitCount++;\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\ttarget.dispatchEvent(\n\t\t\t\t\t\tcreateSyntheticEvent(event, namespace, payload, true, true, null, EventConstructor, eventOptions)\n\t\t\t\t\t);\n\t\t\t\t\temitCount++;\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\t});\n\n\treturn emitCount;\n}\n\n\n\n/**\n * @namespace Events:offDetachedElements\n */\n\n/**\n * This method completely removes all handlers and listeners for provided targets in case that they\n * are actually an element and not part of the DOM (anymore).\n *\n * The most common use-case for this is to clean the event map after dynamically removing an element from the interface\n * during runtime, maybe as a reaction to a user interaction.\n *\n * Since we are overlaying the DOM event system with a separate (non-weak) event map, handlers in the map do not\n * automatically disappear if the event targets, being elements, are removed from the DOM. In that case, we have to\n * actually unregister events again, for which this is a handy little helper method.\n *\n * There are two common ways to use this:\n * 1. Just call it with the removed element, after removal of the element. This will only remove all data for that\n * element, if it actually is an element and is not currently in the DOM.\n * 2. Call it without parameters, to iterate all current targets, check if they are elements and currently not in the\n * DOM and remove all handlers and listeners in that case.\n *\n * So, you can either directly clean-up anything you remove or remove everything, that needs removing and do a general\n * clean-up after everything has been done.\n *\n * Be aware, that the definition of what an element is and if that element is part of the dom is defined by the actual\n * event target. So delegations are not automatically covered by this, since they rely on the ancestor element for\n * event handling.\n *\n * @param {?EventTarget|Array} [targets=null] - the target(s) to remove from the event map, if not set, all event targets in the current event map are used\n * @returns {Number} the number of targets for which registered handlers and listeners have been removed\n *\n * @memberof Events:offDetachedElements\n * @alias offDetachedElements\n * @example\n * button.remove();\n * offDetachedElements(button);\n * => 1\n * link.innerText = 'test';\n * button.remove();\n * offDetachedElements([link, button]);\n * => 1\n * offDetachedElements()\n * => number of all currently registered targets, being elements and not in the dom\n */\n\nexport function offDetachedElements(targets){\n\ttargets = orDefault(targets, [], 'arr');\n\n\tif( targets.length === 0 ){\n\t\ttargets = Array.from(EVENT_MAP.keys());\n\t}\n\n\tlet offCount = 0;\n\n\ttargets.forEach(target => {\n\t\tif( isElement(target) && !document.body.contains(target) && EVENT_MAP.has(target) ){\n\t\t\toffCount++;\n\t\t\toff(target, '*');\n\t\t}\n\t});\n\n\treturn offCount;\n}\n\n\n\n/**\n * @namespace Events:onSwipe\n */\n\n/**\n * Defines a handler for a swipe gesture on (an) element(s).\n * Offers four swipe directions (up/right/down/left), where triggering the handler depends on the distance\n * between touchstart and touchend in relation to the element's width or height, depending on the direction,\n * multiplied by a factor to express a percentage.\n *\n * You may also set this method to also fire upon mouse swipes, by setting \"hasToBeTouchDevice\" to false.\n *\n * @param {EventTarget|Array} targets - the target(s) to register event handlers on\n * @param {String} direction - the direction to bind => up/down/left/right\n * @param {Function} handler - the callback to execute if the event(s) defined in events are being received on target\n * @param {?Number} [dimensionFactor=0.2] - to determine what registers as a swipe we use a percentage of the element's width/height, the touch has to move, default is 20%\n * @param {?Boolean} [hasToBeTouchDevice=true] - if true, makes sure the handlers are only active on touch devices, if false, also reacts to mouse swipes\n * @param {?String} [eventNameSpace='annex-swipe'] - apply an event namespace, which identifies specific events, helpful for a specific unbind later using the same namespace\n * @throws error in case no targets are defined\n * @throws error in case unknown direction is defined\n * @throws error in case handler is not a function\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Function} remover function, which removes all handlers again, added by the current execution\n *\n * @memberof Events:onSwipe\n * @alias onSwipe\n * @see offSwipe\n * @example\n * onSwipe(slider, 'up', e => { e.currentTarget.fadeOut(); });\n * onSwipe(slider, 'right', () => { document.body.dispatchEvent(new CustomEvent('load-previous-thing')); }, 0.15, false, 'foobar-prev');\n */\nexport function onSwipe(targets, direction, handler, dimensionFactor=0.2, hasToBeTouchDevice=true, eventNameSpace='annex-swipe'){\n\tconst __methodName__ = 'onSwipe';\n\n\tdirection = orDefault(direction, '', 'str');\n\tdimensionFactor = orDefault(dimensionFactor, 0.2, 'float');\n\thasToBeTouchDevice = orDefault(hasToBeTouchDevice, true, 'bool');\n\teventNameSpace = orDefault(eventNameSpace, 'annex-swipe', 'str');\n\n\tassert(SWIPE_DIRECTIONS.includes(direction), `${MODULE_NAME}:${__methodName__} | unknown direction \"${direction}\"`);\n\n\tlet events = [`touchstart.${eventNameSpace}-${direction}`, `touchend.${eventNameSpace}-${direction}`];\n\tif( !hasToBeTouchDevice ){\n\t\tevents.push(`mousedown.${eventNameSpace}-${direction}`);\n\t\tevents.push(`mouseup.${eventNameSpace}-${direction}`);\n\t}\n\n\t({targets, events, handler} = prepareEventMethodBaseParams(__methodName__, targets, events, handler));\n\n\tconst originalHandler = handler;\n\thandler = (hasToBeTouchDevice && (detectInteractionType() !== 'touch')) ? () => {} : originalHandler;\n\tconst swipeHandler = SWIPE_HANDLERS.get(originalHandler) ?? (e => {\n\t\tupdateSwipeTouch(e);\n\n\t\tif( ['touchend', 'mouseup'].includes(e.type) ){\n\t\t\tconst\n\t\t\t\twidth = e.currentTarget.offsetWidth,\n\t\t\t\theight = e.currentTarget.offsetHeight\n\t\t\t;\n\n\t\t\tif(\n\t\t\t\t(!hasToBeTouchDevice || (detectInteractionType() === 'touch'))\n\t\t\t\t&& (\n\t\t\t\t\t((direction === 'up') && (SWIPE_TOUCH.startY > (SWIPE_TOUCH.endY + height * dimensionFactor)))\n\t\t\t\t\t|| ((direction === 'right') && (SWIPE_TOUCH.startX < (SWIPE_TOUCH.endX - width * dimensionFactor)))\n\t\t\t\t\t|| ((direction === 'down') && (SWIPE_TOUCH.startY < (SWIPE_TOUCH.endY - height * dimensionFactor)))\n\t\t\t\t\t|| ((direction === 'left') && (SWIPE_TOUCH.startX > (SWIPE_TOUCH.endX + width * dimensionFactor)))\n\t\t\t\t)\n\t\t\t){\n\t\t\t\thandler(e);\n\t\t\t}\n\t\t}\n\t});\n\tSWIPE_HANDLERS.set(originalHandler, swipeHandler);\n\n\treturn on(targets, events, swipeHandler);\n}\n\n\n\n/**\n * @namespace Events:offSwipe\n */\n\n/**\n * Removes (a) handler(s) for a swipe gesture from (an) element(s).\n *\n * Normally all directions are removed individually, but if you leave out `direction` all directions are removed at once.\n *\n * @param {EventTarget|Array} targets - the target(s) to remove event handlers from\n * @param {?String} [direction=null] - the direction to remove => up/down/left/right, if empty, all directions are removed\n * @param {?Function} [handler=null] - a specific callback function to remove\n * @param {?String} [eventNameSpace='annex-swipe'] - event namespace to remove\n * @throws error in case no targets are defined\n * @throws error in case unknown direction is defined\n * @throws error in case a defined handler is not a function\n * @throws error in case targets are not all usable event targets\n * @throws error in case delegations are missing viable ancestor targets\n * @returns {Number} the number of handlers actually removed by the function call, may also be 0 if nothing matched\n *\n * @memberof Events:offSwipe\n * @alias offSwipe\n * @see onSwipe\n * @example\n * offSwipe(slider, 'right');\n * offSwipe(slider, 'left', fSpecialHandler, 'foobar-prev');\n * offSwipe(slider);\n */\nexport function offSwipe(targets, direction=null, handler=null, eventNameSpace='annex-swipe'){\n\tconst __methodName__ = 'offSwipe';\n\n\tdirection = orDefault(direction, '', 'str');\n\teventNameSpace = orDefault(eventNameSpace, 'annex-swipe', 'str');\n\n\tassert(SWIPE_DIRECTIONS.concat('').includes(direction), `${MODULE_NAME}:${__methodName__} | unknown direction \"${direction}\"`);\n\n\tconst directions = (direction === '') ? SWIPE_DIRECTIONS : [direction];\n\tlet removedCount = 0;\n\n\tdirections.forEach(direction => {\n\t\tlet events = [\n\t\t\t`touchstart.${eventNameSpace}-${direction}`,\n\t\t\t`touchend.${eventNameSpace}-${direction}`,\n\t\t\t`mousedown.${eventNameSpace}-${direction}`,\n\t\t\t`mouseup.${eventNameSpace}-${direction}`\n\t\t];\n\n\t\t({targets, events, handler} = prepareEventMethodBaseParams(__methodName__, targets, events, handler, true));\n\n\t\tif( hasValue(handler) ){\n\t\t\tconst swipeHandler = SWIPE_HANDLERS.get(handler);\n\t\t\tif( hasValue(swipeHandler) ){\n\t\t\t\tremovedCount += off(targets, events, swipeHandler);\n\t\t\t}\n\t\t} else {\n\t\t\tremovedCount += off(targets, events);\n\t\t}\n\t});\n\n\treturn removedCount;\n}\n\n\n\n/**\n * @namespace Events:onDomReady\n */\n\n/**\n * Executes a callback on document ready (DOM parsed, complete and usable, not loaded/onload).\n *\n * @param {Function} callback - function to execute, once document is parsed and ready\n *\n * @memberof Events:onDomReady\n * @alias onDomReady\n * @example\n * onDomReady(() => {\n * document.body.classList.add('dom-ready');\n * });\n */\nexport function onDomReady(callback){\n\tif( document.readyState !== 'loading' ){\n\t\tcallback();\n\t} else {\n\t\tconst wrappedCallback = () => {\n\t\t\tdocument.removeEventListener('DOMContentLoaded', wrappedCallback);\n\t\t\tcallback();\n\t\t};\n\t\tdocument.addEventListener('DOMContentLoaded', wrappedCallback);\n\t}\n}\n\n\n\n/**\n * @namespace Events:onPostMessage\n */\n\n/**\n * Register an event handler for a post message on a valid target, like a window or an iframe.\n *\n * The handler will only be executed, if the messageType as well as the origin match. The messageType must be\n * part of the payload, using the key \"type\", which `emitPostMessage` does automatically.\n *\n * Putting the origin as an obligatory parameter at the second place, is deliberate by design, to force everyone\n * to really think about, what to use here. Usually, most people, just throw in the \"*\" wildcard, paying no attention\n * to the security implications. Please really think about what to use here.\n *\n * A word of advice: keep in mind, that, contrary to most other events in javascript, post messages actually work\n * asynchronously (so you cannot be sure, that the handler has been executed, directly after a post message has been\n * sent) and that messages/payload are not transferred as-is, but are cloned, using the \"structured clone algorithm\",\n * which means, that not every javascript object is transferable without losses.\n *\n * @param {Window|HTMLIFrameElement} target - window/iframe to register the handler to (iframes are automatically resolved to the contentWindow)\n * @param {String} origin - the origin the received post message has to have, for the handler to get executed (defaults to \"*\", if receiving a nullish value)\n * @param {String} messageType - the type/name the post message has to have, for the handler to get executed (will be checked using the key \"type\" in the message's payload)\n * @param {Function} handler - the handler to execute, if a post message, matching all conditions, is received\n * @throws error if target is not usable\n * @return a function, which, if executed, removes everything registered by the current call\n *\n * @memberof Events:onPostMessage\n * @alias onPostMessage\n * @see offPostMessage\n * @see emitPostMessage\n * @see https://developer.mozilla.org/en-US/docs/Glossary/Origin\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm\n * @example\n * const removeAgainFunction = onPostMessage(window, '*', 'foobar-message', () => { doSomething(); });\n * onPostMessage(iframeElement, 'https://foobar.com:80/', 'foobar-message', e => { resizeIframe(e.data.payload.height); });\n */\nexport function onPostMessage(target, origin, messageType, handler){\n\tconst __methodName__ = 'onPostMessage';\n\n\ttarget = resolvePostMessageTarget(target, __methodName__);\n\torigin = orDefault(origin, '*', 'str');\n\tmessageType = `${messageType}`;\n\n\tassert(isFunction(handler), `${MODULE_NAME}:${__methodName__} | handler is not a function`);\n\n\tif( !hasValue(POST_MESSAGE_MAP.get(target)) ){\n\t\tPOST_MESSAGE_MAP.set(target, {});\n\t\ttarget.addEventListener('message', windowPostMessageHandler);\n\t}\n\n\tconst targetPostMessages = POST_MESSAGE_MAP.get(target);\n\tif( !hasValue(targetPostMessages[messageType]) ){\n\t\ttargetPostMessages[messageType] = [];\n\t}\n\n\ttargetPostMessages[messageType].push({handler, origin});\n\n\treturn () => { offPostMessage(target, origin, messageType, handler); };\n}\n\n\n\n/**\n * @namespace Events:offPostMessage\n */\n\n/**\n * Unregister (an) event handler(s) for (a) post message(s) on a valid target, like a window or an iframe.\n *\n * Similar to `off`, this function can handle rather unspecific cases as well as very specific definitions.\n * Just setting the target, removes all registrations for that target. Setting an `origin` and/or a `messageType`\n * additionally, only removes handlers, that were registered explicitly for these values. Adding a handler only\n * removes that specific handler (without origin and/or messageType, the handler is removed everywhere).\n *\n * Putting the origin parameter at the second place, is deliberate by design, to force everyone to really think about,\n * what to use here. Usually, most people, just throw in the \"*\" wildcard, paying no attention to the security\n * implications, when setting a post message handler. Since we force this on `onPostMessage`, we keep the signature\n * here as well, just making everything except target optional.\n *\n * If you try to remove event handlers not previously created with `onPostMessage` (and therefore there are no fitting\n * target entries in the POST_MESSAGE_MAP), the function will fall back to native `removeEventListener`\n * (if `tryNativeRemoval` is true), but in that case, a handler has to be defined and the return value will not\n * increment, since we do not know if the removal really worked.\n *\n * @param {Window|HTMLIFrameElement} target - window/iframe to remove handler(s) from (iframes are automatically resolved to the contentWindow)\n * @param {?String} [origin=null] - the origin the received post message has to have, for the handler to get executed (defaults to \"*\", if receiving a nullish value)\n * @param {?String} [messageType=null] - the type/name the post message has to have, for the handler to get executed (will be checked using the key \"type\" in the message's payload)\n * @param {?Function} [handler=null] - the handler to execute, if a post message, matching all conditions, is received\n * @param {?Boolean} [tryNativeRemoval=true] - if a target is not part of the POST_MESSAGE_MAP native removeEventListener is used as a fallback if this is true (handler needs to be set in that case)\n * @throws error if target is not usable\n * @return the number of actually removed handlers, that matched the conditions\n *\n * @memberof Events:offPostMessage\n * @alias offPostMessage\n * @see onPostMessage\n * @see emitPostMessage\n * @see https://developer.mozilla.org/en-US/docs/Glossary/Origin\n * @example\n * const offCount = offPostMessage(window, 'https://foobar.com:80/', 'foobar-message');\n * offPostMessage(window, null, null, specialHandlerFunction);\n */\nexport function offPostMessage(target, origin=null, messageType=null, handler=null, tryNativeRemoval=true){\n\tconst __methodName__ = 'offPostMessage';\n\n\ttarget = resolvePostMessageTarget(target, __methodName__);\n\torigin = orDefault(origin, null, 'str');\n\tmessageType = orDefault(messageType, null, 'str');\n\ttryNativeRemoval = orDefault(tryNativeRemoval, true, 'bool');\n\n\tif( hasValue(handler) ){\n\t\tassert(isFunction(handler), `${MODULE_NAME}:${__methodName__} | handler is not a function`);\n\t}\n\n\tlet removedCount = 0;\n\n\tconst targetPostMessages = POST_MESSAGE_MAP.get(target);\n\tif( hasValue(targetPostMessages) ){\n\t\tconst messageTypes = hasValue(messageType) ? [messageType] : Object.keys(targetPostMessages);\n\t\tmessageTypes.forEach(messageType => {\n\t\t\tremovedCount += removePostMessageHandlers(targetPostMessages, messageType, origin, handler);\n\t\t});\n\n\t\tif( Object.keys(targetPostMessages).length === 0 ){\n\t\t\tPOST_MESSAGE_MAP.delete(target);\n\t\t}\n\t} else if( tryNativeRemoval ){\n\t\tif( hasValue(handler) ){\n\t\t\ttarget.removeEventListener('message', handler);\n\t\t} else {\n\t\t\twarn(`${MODULE_NAME}:${__methodName__} | native fallback event removal for \"${messageType}\" not possible, handler is missing`);\n\t\t}\n\t}\n\n\tif( !hasValue(POST_MESSAGE_MAP.get(target)) ){\n\t\ttarget.removeEventListener('message', windowPostMessageHandler);\n\t}\n\n\treturn removedCount;\n}\n\n\n\n/**\n * @namespace Events:emitPostMessage\n */\n\n/**\n * Emit/dispatch a post message on a valid target, like a window or an iframe.\n *\n * Putting the origin as an obligatory parameter at the second place, is deliberate by design, to force everyone\n * to really think about, what to use here. Usually, most people, just throw in the \"*\" wildcard, paying no attention\n * to the security implications. Please really think about what to use here.\n *\n * This function adds the `messageType` automatically to the message/payload using the key `type`. `onPostMessage` will\n * use that information additionally to the `origin` to determine if a registration fits the occurred event. The\n * `payload` will be placed in the message using the key `payload`. So `e.data` will look like this in the\n * handler at the end: `{type : messageType, payload : {...payload}}`\n *\n * A word of advice: keep in mind, that, contrary to most other events in javascript, post messages actually work\n * asynchronously (so you cannot be sure, that the handler has been executed, directly after a post message has been\n * sent) and that messages/payload are not transferred as-is, but are cloned, using the \"structured clone algorithm\",\n * which means, that not every javascript object is transferable without losses.\n *\n * @param {Window|HTMLIFrameElement} target - window/iframe to receive the post message (iframes are automatically resolved to the contentWindow)\n * @param {String} origin - the origin the current context has to have, to actually send the post message the received post message has to have, this does NOT set the origin! (defaults to \"*\", if receiving a nullish value)\n * @param {String} messageType - the type/name of the post message (will be checked using the key \"type\" in the message's payload, which will automatically be set using this function)\n * @param {?*} [payload=null] - a payload to add to the message under the key \"payload\"\n * @throws error if target is not usable\n * @return the resolved target of the post message\n *\n * @memberof Events:emitPostMessage\n * @alias emitPostMessage\n * @see onPostMessage\n * @see offPostMessage\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage\n * @see https://developer.mozilla.org/en-US/docs/Glossary/Origin\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm\n * @example\n * emitPostMessage(window, '*', 'foobar-message', {timestamp : new Date()});\n * emitPostMessage(iframeElement, 'https://foobar.com:80/', 'foobar-message');\n */\nexport function emitPostMessage(target, origin, messageType, payload=null){\n\tconst __methodName__ = 'emitPostMessage';\n\n\ttarget = resolvePostMessageTarget(target, __methodName__);\n\torigin = orDefault(origin, '*', 'str');\n\tmessageType = `${messageType}`;\n\n\tconst message = {type : messageType};\n\tif( hasValue(payload) ){\n\t\tmessage.payload = payload;\n\t}\n\n\ttarget.postMessage(message, origin);\n\n\treturn target;\n}\n"]} \ No newline at end of file diff --git a/dist/fonts.js b/dist/fonts.js index ccd04722..97311209 100644 --- a/dist/fonts.js +++ b/dist/fonts.js @@ -1,5 +1,5 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Fonts diff --git a/dist/fonts.js.map b/dist/fonts.js.map index 353ab698..bbab6031 100644 --- a/dist/fonts.js.map +++ b/dist/fonts.js.map @@ -1 +1 @@ -{"version":3,"file":"fonts.js","names":["MODULE_NAME","hasValue","orDefault","Deferred","createNode","applyStyles","loop","countermand","waitForWebfonts","fonts","fallbackFontName","timeout","map","font","deferred","start","Date","now","loadedFonts","forEach","node","position","visibility","left","top","document","body","appendChild","systemFontDims","width","offsetWidth","height","offsetHeight","fontLoadedCheckTimer","fCheckFont","removeChild","reject","Error","dims1","dims2","length","resolve"],"sources":["fonts.js"],"mappings":";;;AAQA,MAAMA,YAAc,eAMZC,SAAUC,UAAWC,aAAe,oBACpCC,eAAiB,uBACjBC,gBAAkB,kBAClBC,KAAMC,gBAAmB,qBAoC1B,SAASC,gBAAgBC,EAAOC,EAAiB,aAAcC,EAAQ,KAC7EF,EAAQP,UAAUO,EAAO,GAAI,OAAOG,KAAIC,GAAQ,GAAGA,MACnDH,EAAmBR,UAAUQ,EAAkB,aAAc,UAC7DC,EAAUT,UAAUS,EAAS,IAAM,OAEnC,MACCG,EAAW,IAAIX,SACfY,EAAQC,KAAKC,MAGd,IAAIC,EAAc,EA4DlB,OA1DAT,EAAMU,SAAQN,IACb,IAAIO,EAAOhB,WAAW,OAAQ,KAAM,oBACpCC,YAAYe,EAAM,CACjBC,SAAa,WACbC,WAAe,SACfC,KAAS,WACTC,IAAQ,WACR,YAAc,QACd,cAAgBd,EAChB,eAAiB,SACjB,aAAe,SACf,cAAgB,SAChB,iBAAmB,IACnB,cAAgB,MAChB,cAAgB,IAEjBe,SAASC,KAAKC,YAAYP,GAE1B,MAAMQ,EAAiB,CACtBC,MAAQT,EAAKU,YACbC,OAASX,EAAKY,cAEf3B,YAAYe,EAAM,CAAC,cAAgB,GAAGP,MAASH,MAE/C,IAAIuB,EAAuB,KAC3B,MAAMC,EAAa,KAClB,OAAKlB,KAAKC,MAAQF,GAAUJ,GAC3BJ,YAAY0B,GACRhC,SAASmB,KACZK,SAASC,KAAKS,YAAYf,GAC1BA,EAAO,MAERN,EAASsB,OAAO,IAAIC,MAAM,aACnB,IAIPpC,SAASmB,KAzCUkB,EA0CG,CAACT,MAAQT,EAAKU,YAAaC,OAASX,EAAKY,cA1CrCO,EA0CoDX,EA1CxCU,EAAMT,QAAUU,EAAMV,OAAWS,EAAMP,SAAWQ,EAAMR,UA4C9FxB,YAAY0B,GACZR,SAASC,KAAKS,YAAYf,GAC1BA,EAAO,KACPF,KAGGA,GAAeT,EAAM+B,SACxB1B,EAAS2B,QAA0B,IAAjBhC,EAAM+B,OAAgB/B,EAAM,GAAKA,IAC5C,IApDW,IAAC6B,EAAOC,CAuDf,EAERL,MACJD,EAAuB3B,KAAK,IAAK4B,GAClC,IAGMpB,CACR","sourcesContent":["/*!\n * Module Fonts\n */\n\n/**\n * @namespace Fonts\n */\n\nconst MODULE_NAME = 'Fonts';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {hasValue, orDefault, Deferred} from './basic.js';\nimport {createNode} from './elements.js';\nimport {applyStyles} from './css.js';\nimport {loop, countermand} from './timers.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Fonts:waitForWebfonts\n */\n\n/**\n * Waits for a list of webfonts to load. This includes the fact, that the font is ready to display and renders in the\n * browser's rendering engine and not just a completed request or a loaded resource.\n *\n * Also works for fonts, that have already been loaded.\n *\n * @param {String|String[]} fonts - the CSS-names of the fonts to wait for\n * @param {?String} [fallbackFontName=sans-serif] - the system font which the page falls back on if the webfont is not loaded\n * @param {?Number} [timeout=5000] - timeout in ms after which the call fails and the return value rejects\n * @returns {Basic.Deferred|String>} a Deferred, that resolves once all webfonts are available and rejects when the timeout is reached\n *\n * @memberof Fonts:waitForWebfonts\n * @alias waitForWebfonts\n * @example\n * waitForWebfonts(['purr-regular', 'scratch-light'], 'helvetica, sans-serif')\n * .then(fonts => {\n * document.body.classList.add('webfonts-loaded');\n * alert(`${fonts.length} webfonts ready to render`);\n * })\n * .catch(error => {\n * if( error.message === 'timeout' ){\n * document.body.classList.add('webfonts-timeout');\n * }\n * })\n * ;\n */\nexport function waitForWebfonts(fonts, fallbackFontName='sans-serif', timeout=5000){\n\tfonts = orDefault(fonts, [], 'arr').map(font => `${font}`);\n\tfallbackFontName = orDefault(fallbackFontName, 'sans-serif', 'string');\n\ttimeout = orDefault(timeout, 5000, 'int');\n\n\tconst\n\t\tdeferred = new Deferred(),\n\t\tstart = Date.now(),\n\t\tfDimsAreIdentical = (dims1, dims2) => ((dims1.width === dims2.width) && (dims1.height === dims2.height))\n\t;\n\tlet\tloadedFonts = 0;\n\n\tfonts.forEach(font => {\n\t\tlet node = createNode('span', null, 'giItT1WQy@!-/#');\n\t\tapplyStyles(node, {\n\t\t\t'position' : 'absolute',\n\t\t\t'visibility' : 'hidden',\n\t\t\t'left' : '-10000px',\n\t\t\t'top' : '-10000px',\n\t\t\t'font-size' : '300px',\n\t\t\t'font-family' : fallbackFontName,\n\t\t\t'font-variant' : 'normal',\n\t\t\t'font-style' : 'normal',\n\t\t\t'font-weight' : 'normal',\n\t\t\t'letter-spacing' : '0',\n\t\t\t'white-space' : 'pre',\n\t\t\t'line-height' : 1\n\t\t});\n\t\tdocument.body.appendChild(node);\n\n\t\tconst systemFontDims = {\n\t\t\twidth : node.offsetWidth,\n\t\t\theight : node.offsetHeight\n\t\t};\n\t\tapplyStyles(node, {'font-family' : `${font}, ${fallbackFontName}`});\n\n\t\tlet fontLoadedCheckTimer = null;\n\t\tconst fCheckFont = () => {\n\t\t\tif( (Date.now() - start) >= timeout ){\n\t\t\t\tcountermand(fontLoadedCheckTimer);\n\t\t\t\tif( hasValue(node) ){\n\t\t\t\t\tdocument.body.removeChild(node);\n\t\t\t\t\tnode = null;\n\t\t\t\t}\n\t\t\t\tdeferred.reject(new Error('timeout'));\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif(\n\t\t\t\thasValue(node)\n\t\t\t\t&& !fDimsAreIdentical({width : node.offsetWidth, height : node.offsetHeight}, systemFontDims)\n\t\t\t){\n\t\t\t\tcountermand(fontLoadedCheckTimer);\n\t\t\t\tdocument.body.removeChild(node);\n\t\t\t\tnode = null;\n\t\t\t\tloadedFonts++;\n\t\t\t}\n\n\t\t\tif( loadedFonts >= fonts.length ){\n\t\t\t\tdeferred.resolve((fonts.length === 1) ? fonts[0] : fonts);\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\t\tif( !fCheckFont() ){\n\t\t\tfontLoadedCheckTimer = loop(100, fCheckFont);\n\t\t}\n\t});\n\n\treturn deferred;\n}\n"]} \ No newline at end of file +{"version":3,"file":"fonts.js","names":["MODULE_NAME","hasValue","orDefault","Deferred","createNode","applyStyles","loop","countermand","waitForWebfonts","fonts","fallbackFontName","timeout","map","font","deferred","start","Date","now","loadedFonts","forEach","node","position","visibility","left","top","document","body","appendChild","systemFontDims","width","offsetWidth","height","offsetHeight","fontLoadedCheckTimer","fCheckFont","removeChild","reject","Error","dims1","dims2","length","resolve"],"sources":["fonts.js"],"mappings":";;;AAQA,MAAMA,YAAc,eAMZC,SAAUC,UAAWC,aAAe,oBACpCC,eAAiB,uBACjBC,gBAAkB,kBAClBC,KAAMC,gBAAmB,qBAoC1B,SAASC,gBAAgBC,EAAOC,EAAiB,aAAcC,EAAQ,KAC7EF,EAAQP,UAAUO,EAAO,GAAI,OAAOG,KAAIC,GAAQ,GAAGA,MACnDH,EAAmBR,UAAUQ,EAAkB,aAAc,UAC7DC,EAAUT,UAAUS,EAAS,IAAM,OAEnC,MACCG,EAAW,IAAIX,SACfY,EAAQC,KAAKC,MAGd,IAAIC,EAAc,EA4DlB,OA1DAT,EAAMU,SAAQN,IACb,IAAIO,EAAOhB,WAAW,OAAQ,KAAM,oBACpCC,YAAYe,EAAM,CACjBC,SAAa,WACbC,WAAe,SACfC,KAAS,WACTC,IAAQ,WACR,YAAc,QACd,cAAgBd,EAChB,eAAiB,SACjB,aAAe,SACf,cAAgB,SAChB,iBAAmB,IACnB,cAAgB,MAChB,cAAgB,IAEjBe,SAASC,KAAKC,YAAYP,GAE1B,MAAMQ,EAAiB,CACtBC,MAAQT,EAAKU,YACbC,OAASX,EAAKY,cAEf3B,YAAYe,EAAM,CAAC,cAAgB,GAAGP,MAASH,MAE/C,IAAIuB,EAAuB,KAC3B,MAAMC,EAAa,KAClB,OAAKlB,KAAKC,MAAQF,GAAUJ,GAC3BJ,YAAY0B,GACRhC,SAASmB,KACZK,SAASC,KAAKS,YAAYf,GAC1BA,EAAO,MAERN,EAASsB,OAAO,IAAIC,MAAM,aACnB,IAIPpC,SAASmB,KAzCUkB,EA0CG,CAACT,MAAQT,EAAKU,YAAaC,OAASX,EAAKY,cA1CrCO,EA0CoDX,EA1CxCU,EAAMT,QAAUU,EAAMV,OAAWS,EAAMP,SAAWQ,EAAMR,UA4C9FxB,YAAY0B,GACZR,SAASC,KAAKS,YAAYf,GAC1BA,EAAO,KACPF,KAGGA,GAAeT,EAAM+B,SACxB1B,EAAS2B,QAA0B,IAAjBhC,EAAM+B,OAAgB/B,EAAM,GAAKA,IAC5C,IApDW,IAAC6B,EAAOC,CAuDf,EAERL,MACJD,EAAuB3B,KAAK,IAAK4B,GAClC,IAGMpB,CACR","ignoreList":[],"sourcesContent":["/*!\n * Module Fonts\n */\n\n/**\n * @namespace Fonts\n */\n\nconst MODULE_NAME = 'Fonts';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {hasValue, orDefault, Deferred} from './basic.js';\nimport {createNode} from './elements.js';\nimport {applyStyles} from './css.js';\nimport {loop, countermand} from './timers.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Fonts:waitForWebfonts\n */\n\n/**\n * Waits for a list of webfonts to load. This includes the fact, that the font is ready to display and renders in the\n * browser's rendering engine and not just a completed request or a loaded resource.\n *\n * Also works for fonts, that have already been loaded.\n *\n * @param {String|String[]} fonts - the CSS-names of the fonts to wait for\n * @param {?String} [fallbackFontName=sans-serif] - the system font which the page falls back on if the webfont is not loaded\n * @param {?Number} [timeout=5000] - timeout in ms after which the call fails and the return value rejects\n * @returns {Basic.Deferred|String>} a Deferred, that resolves once all webfonts are available and rejects when the timeout is reached\n *\n * @memberof Fonts:waitForWebfonts\n * @alias waitForWebfonts\n * @example\n * waitForWebfonts(['purr-regular', 'scratch-light'], 'helvetica, sans-serif')\n * .then(fonts => {\n * document.body.classList.add('webfonts-loaded');\n * alert(`${fonts.length} webfonts ready to render`);\n * })\n * .catch(error => {\n * if( error.message === 'timeout' ){\n * document.body.classList.add('webfonts-timeout');\n * }\n * })\n * ;\n */\nexport function waitForWebfonts(fonts, fallbackFontName='sans-serif', timeout=5000){\n\tfonts = orDefault(fonts, [], 'arr').map(font => `${font}`);\n\tfallbackFontName = orDefault(fallbackFontName, 'sans-serif', 'string');\n\ttimeout = orDefault(timeout, 5000, 'int');\n\n\tconst\n\t\tdeferred = new Deferred(),\n\t\tstart = Date.now(),\n\t\tfDimsAreIdentical = (dims1, dims2) => ((dims1.width === dims2.width) && (dims1.height === dims2.height))\n\t;\n\tlet\tloadedFonts = 0;\n\n\tfonts.forEach(font => {\n\t\tlet node = createNode('span', null, 'giItT1WQy@!-/#');\n\t\tapplyStyles(node, {\n\t\t\t'position' : 'absolute',\n\t\t\t'visibility' : 'hidden',\n\t\t\t'left' : '-10000px',\n\t\t\t'top' : '-10000px',\n\t\t\t'font-size' : '300px',\n\t\t\t'font-family' : fallbackFontName,\n\t\t\t'font-variant' : 'normal',\n\t\t\t'font-style' : 'normal',\n\t\t\t'font-weight' : 'normal',\n\t\t\t'letter-spacing' : '0',\n\t\t\t'white-space' : 'pre',\n\t\t\t'line-height' : 1\n\t\t});\n\t\tdocument.body.appendChild(node);\n\n\t\tconst systemFontDims = {\n\t\t\twidth : node.offsetWidth,\n\t\t\theight : node.offsetHeight\n\t\t};\n\t\tapplyStyles(node, {'font-family' : `${font}, ${fallbackFontName}`});\n\n\t\tlet fontLoadedCheckTimer = null;\n\t\tconst fCheckFont = () => {\n\t\t\tif( (Date.now() - start) >= timeout ){\n\t\t\t\tcountermand(fontLoadedCheckTimer);\n\t\t\t\tif( hasValue(node) ){\n\t\t\t\t\tdocument.body.removeChild(node);\n\t\t\t\t\tnode = null;\n\t\t\t\t}\n\t\t\t\tdeferred.reject(new Error('timeout'));\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif(\n\t\t\t\thasValue(node)\n\t\t\t\t&& !fDimsAreIdentical({width : node.offsetWidth, height : node.offsetHeight}, systemFontDims)\n\t\t\t){\n\t\t\t\tcountermand(fontLoadedCheckTimer);\n\t\t\t\tdocument.body.removeChild(node);\n\t\t\t\tnode = null;\n\t\t\t\tloadedFonts++;\n\t\t\t}\n\n\t\t\tif( loadedFonts >= fonts.length ){\n\t\t\t\tdeferred.resolve((fonts.length === 1) ? fonts[0] : fonts);\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\t\tif( !fCheckFont() ){\n\t\t\tfontLoadedCheckTimer = loop(100, fCheckFont);\n\t\t}\n\t});\n\n\treturn deferred;\n}\n"]} \ No newline at end of file diff --git a/dist/forms.js b/dist/forms.js index 116d399b..9808c561 100644 --- a/dist/forms.js +++ b/dist/forms.js @@ -1,5 +1,5 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Forms diff --git a/dist/forms.js.map b/dist/forms.js.map index 59fb39bb..2874ef54 100644 --- a/dist/forms.js.map +++ b/dist/forms.js.map @@ -1 +1 @@ -{"version":3,"file":"forms.js","names":["MODULE_NAME","isFunction","isPlainObject","hasValue","formDataToObject","formDataOrForm","formData","append","getAll","entries","FormData","ex","formDataObject","Array","from","forEach","key","values","endsWith","slice","concat","length","objectToFormData","Object","fieldName","fieldValue","file","File","name","undefined","blob","Blob","mimeType","type"],"sources":["forms.js"],"mappings":";;;AAQA,MAAMA,YAAc,eAMZC,WAAYC,cAAeC,aAAe,oBAyD3C,SAASC,iBAAiBC,GAChC,IAAIC,EAGJ,GACCL,WAAWI,EAAeE,SACvBN,WAAWI,EAAeG,SAC1BP,WAAWI,EAAeI,SAE7BH,EAAWD,OAEX,IACCC,EAAW,IAAII,SAASL,EAGzB,CAFE,MAAMM,GACPL,EAAW,IACZ,CAGD,IAAKH,SAASG,GAAY,OAAO,KAEjC,MAAMM,EAAiB,CAAC,EAexB,OAbAC,MAAMC,KAAKR,EAASG,WAAWM,SAAQ,EAAEC,EAAKC,MACzCD,EAAIE,SAAS,QAChBF,EAAMA,EAAIG,MAAM,GAAI,IAErBF,EAAS,GAAGG,OAAOH,GAEdd,SAASS,EAAeI,IAG5BJ,EAAeI,GAAO,GAAGI,OAAOR,EAAeI,GAAMC,GAFrDL,EAAeI,GAA0B,IAAlBC,EAAOI,OAAgBJ,EAAO,GAAKA,CAG3D,IAGML,CACR,QA8CO,SAASU,iBAAiBV,GAChC,MAAMN,EAAW,IAAII,SAsCrB,OApCAa,OAAOd,QAAQG,GAAgBG,SAAQ,EAAES,EAAWC,MAC/CD,EAAUN,SAAS,QACtBM,EAAYA,EAAUL,MAAM,GAAI,IAGjC,GAAGC,OAAOK,GAAYV,SAAQU,IAC7B,GAAIvB,cAAcuB,GACjB,GAAItB,SAASsB,EAAWC,OAAUD,EAAWC,gBAAgBC,KAC5DrB,EAASC,OACRiB,EACAC,EAAWC,KACXvB,SAASsB,EAAWG,MAAQ,GAAGH,EAAWG,YAASC,QAE9C,GAAI1B,SAASsB,EAAWK,MAAO,CACrC,MAAMA,EAAQL,EAAWK,gBAAgBC,KACtCN,EAAWK,KACX,IAAIC,KACL,CAAC,GAAGN,EAAWK,QACf3B,SAASsB,EAAWO,UAAY,CAACC,KAAO,GAAGR,EAAWO,iBAAcH,GAItEvB,EAASC,OACRiB,EACAM,EACA3B,SAASsB,EAAWG,MAAQ,GAAGH,EAAWG,YAASC,EAErD,MACCvB,EAASC,OAAOiB,EAAW,GAAGC,UAG/BnB,EAASC,OAAOiB,EAAWC,EAC5B,GACC,IAGInB,CACR","sourcesContent":["/*!\n * Module Forms\n */\n\n/**\n * @namespace Forms\n */\n\nconst MODULE_NAME = 'Forms';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {isFunction, isPlainObject, hasValue} from './basic.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Forms:formDataToObject\n */\n\n/**\n * Constructs a plain object from an existing FormData object or a given form element.\n *\n * The idea of this function is, to make working with form data easier in programmatic contexts by allowing operations\n * like optional chaining and \"in\" operators. This might especially come in handy if you need to do programmatic\n * validations.\n *\n * Additionally, this function streamlines field names, by discarding PHP-style array field name conventions like\n * \"files[]\", by removing the brackets. So, if you have a field named \"files[]\" and another field named \"files\",\n * both will just end up in one \"files\"-field, having an array as a value containing all combined values.\n *\n * Keep in mind, that the status of form fields in a form matters when retrieving FormData from a form element.\n * Disabled fields will not be included for example. Make sure to handle this before using the data.\n *\n * On Internet Explorers, this function needs a polyfill, which is not included in annex, due to its size and\n * complexity, since IEs, while supporting FormData basically, are lacking all functions to access values of an existing\n * FormData object, thereby making it impossible to iterate its values.\n *\n * @param {FormData|HTMLFormElement} formDataOrForm - either an existing FormData object or a form, from which we can retrieve formdata\n * @returns {Object} plain object, containing all form values based on the exisiting fields as key/value-pairs\n *\n * @memberof Forms:formDataToObject\n * @alias formDataToObject\n * @see objectToFormData\n * @see https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData\n * @see https://github.com/jimmywarting/FormData\n * @example\n * const formData = new FormData();\n * formData.append('secrethash', 123456789);\n * formData.append('firstname', 'Paul');\n * formData.append('lastname', 'Atreides');\n * formData.append('houses', 'Atreides');\n * formData.append('houses', 'Fremen');\n * formData.append('houses', 'Corrino');\n * formData.append('diary', new File(['Dear Diary, ...'], 'diary.txt', {type : 'text/plain', lastModified : new Date()}));\n * formData.append('instagramPage', new Blob(['...'], {type : 'text/html'}));\n * formDataToObject(formData)\n * =>\n * {\n * secrethash : '123456789',\n * \t firstname : 'Paul',\n * \t lastname : 'Atreides',\n * \t houses : ['Atreides', 'Fremen', 'Corrino'],\n * \t diary : File,\n * \t instagramPage : Blob\n * }\n */\nexport function formDataToObject(formDataOrForm){\n\tlet formData;\n\n\t// let's do duck-typing to allow polyfills\n\tif(\n\t\tisFunction(formDataOrForm.append)\n\t\t&& isFunction(formDataOrForm.getAll)\n\t\t&& isFunction(formDataOrForm.entries)\n\t){\n\t\tformData = formDataOrForm;\n\t} else {\n\t\ttry {\n\t\t\tformData = new FormData(formDataOrForm);\n\t\t} catch(ex){\n\t\t\tformData = null;\n\t\t}\n\t}\n\n\tif( !hasValue(formData) ) return null;\n\n\tconst formDataObject = {};\n\n\tArray.from(formData.entries()).forEach(([key, values]) => {\n\t\tif( key.endsWith('[]') ){\n\t\t\tkey = key.slice(0, -2);\n\t\t}\n\t\tvalues = [].concat(values);\n\n\t\tif( !hasValue(formDataObject[key]) ){\n\t\t\tformDataObject[key] = (values.length === 1) ? values[0] : values;\n\t\t} else {\n\t\t\tformDataObject[key] = [].concat(formDataObject[key], values);\n\t\t}\n\t});\n\n\treturn formDataObject;\n}\n\n\n\n/**\n * @namespace Forms:objectToFormData\n */\n\n/**\n * Constructs a FormData object, to be used in requests, from a given (plain) object, iterating its entries.\n *\n * Additionally, this function streamlines field names, by discarding PHP-style array field name conventions like\n * \"files[]\", by removing the brackets. So, if you have a field named \"files[]\" and another field named \"files\",\n * both will just end up in one \"files\"-field.\n *\n * Files and Blobs can be provided as-is (constructed programmatically of retrieved from file inputs via `.files`).\n * Alternatively (and if you manually want to define the filename), you can provide plain objects to describe a File or\n * Blob to add to the FormData:\n * - use {file : File, ?name : String} to add \"file\" as a File and optionally set \"name\" to define a filename, taking\n * precedence over what is already defined in the File object itself\n * - use {blob : Blob|String, ?name : String, ?mimeType : String} to add \"blob\" as a Blob (if this is a string, it\n * will be treated as the content of a new Blob), optionally using \"name\" as the filename (I'd recommend to set this)\n * and optionally setting the file type via the MIME type defined in \"mimeType\".\n *\n * In contrast to `formDataToObject`, this function does not need a polyfill in Internet Explorer, since it only uses\n * the FormData constructor and the `.append()` method, which are both supported.\n *\n * @param {Object} formDataObject - object to iterate, to create FormData based on its entries\n * @returns {FormData} FormData object to be used in a request\n *\n * @memberof Forms:objectToFormData\n * @alias objectToFormData\n * @see formDataToObject\n * @see https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData\n * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types\n * @example\n * const formData = objectToFormData({\n * secrethash : 123456789,\n * \t firstname : 'Paul',\n * \t lastname : 'Atreides',\n * \t houses : ['Atreides', 'Fremen', 'Corrino'],\n * \t diary : {file : new File(['Dear Diary, ...'], 'diary.txt', {type : 'text/plain', lastModified : new Date()})},\n * \t instagramPage : {blob : '...', name : 'instagram.html', mimeType : 'text/html'},\n * }).getAll('houses');\n * => ['Atreides', 'Fremen', 'Corrino']\n */\nexport function objectToFormData(formDataObject){\n\tconst formData = new FormData();\n\n\tObject.entries(formDataObject).forEach(([fieldName, fieldValue]) => {\n\t\tif( fieldName.endsWith('[]') ){\n\t\t\tfieldName = fieldName.slice(0, -2);\n\t\t}\n\n\t\t[].concat(fieldValue).forEach(fieldValue => {\n\t\t\tif( isPlainObject(fieldValue) ){\n\t\t\t\tif( hasValue(fieldValue.file) && (fieldValue.file instanceof File) ){\n\t\t\t\t\tformData.append(\n\t\t\t\t\t\tfieldName,\n\t\t\t\t\t\tfieldValue.file,\n\t\t\t\t\t\thasValue(fieldValue.name) ? `${fieldValue.name}` : undefined\n\t\t\t\t\t);\n\t\t\t\t} else if( hasValue(fieldValue.blob) ){\n\t\t\t\t\tconst blob = (fieldValue.blob instanceof Blob)\n\t\t\t\t\t\t? fieldValue.blob\n\t\t\t\t\t\t: new Blob(\n\t\t\t\t\t\t\t[`${fieldValue.blob}`],\n\t\t\t\t\t\t\thasValue(fieldValue.mimeType) ? {type : `${fieldValue.mimeType}`} : undefined\n\t\t\t\t\t\t)\n\t\t\t\t\t;\n\n\t\t\t\t\tformData.append(\n\t\t\t\t\t\tfieldName,\n\t\t\t\t\t\tblob,\n\t\t\t\t\t\thasValue(fieldValue.name) ? `${fieldValue.name}` : undefined\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tformData.append(fieldName, `${fieldValue}`);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tformData.append(fieldName, fieldValue);\n\t\t\t}\n\t\t});\n\t});\n\n\treturn formData;\n}\n"]} \ No newline at end of file +{"version":3,"file":"forms.js","names":["MODULE_NAME","isFunction","isPlainObject","hasValue","formDataToObject","formDataOrForm","formData","append","getAll","entries","FormData","ex","formDataObject","Array","from","forEach","key","values","endsWith","slice","concat","length","objectToFormData","Object","fieldName","fieldValue","file","File","name","undefined","blob","Blob","mimeType","type"],"sources":["forms.js"],"mappings":";;;AAQA,MAAMA,YAAc,eAMZC,WAAYC,cAAeC,aAAe,oBAyD3C,SAASC,iBAAiBC,GAChC,IAAIC,EAGJ,GACCL,WAAWI,EAAeE,SACvBN,WAAWI,EAAeG,SAC1BP,WAAWI,EAAeI,SAE7BH,EAAWD,OAEX,IACCC,EAAW,IAAII,SAASL,EACzB,CAAE,MAAMM,GACPL,EAAW,IACZ,CAGD,IAAKH,SAASG,GAAY,OAAO,KAEjC,MAAMM,EAAiB,CAAC,EAexB,OAbAC,MAAMC,KAAKR,EAASG,WAAWM,SAAQ,EAAEC,EAAKC,MACzCD,EAAIE,SAAS,QAChBF,EAAMA,EAAIG,MAAM,GAAI,IAErBF,EAAS,GAAGG,OAAOH,GAEdd,SAASS,EAAeI,IAG5BJ,EAAeI,GAAO,GAAGI,OAAOR,EAAeI,GAAMC,GAFrDL,EAAeI,GAA0B,IAAlBC,EAAOI,OAAgBJ,EAAO,GAAKA,CAG3D,IAGML,CACR,QA8CO,SAASU,iBAAiBV,GAChC,MAAMN,EAAW,IAAII,SAsCrB,OApCAa,OAAOd,QAAQG,GAAgBG,SAAQ,EAAES,EAAWC,MAC/CD,EAAUN,SAAS,QACtBM,EAAYA,EAAUL,MAAM,GAAI,IAGjC,GAAGC,OAAOK,GAAYV,SAAQU,IAC7B,GAAIvB,cAAcuB,GACjB,GAAItB,SAASsB,EAAWC,OAAUD,EAAWC,gBAAgBC,KAC5DrB,EAASC,OACRiB,EACAC,EAAWC,KACXvB,SAASsB,EAAWG,MAAQ,GAAGH,EAAWG,YAASC,QAE9C,GAAI1B,SAASsB,EAAWK,MAAO,CACrC,MAAMA,EAAQL,EAAWK,gBAAgBC,KACtCN,EAAWK,KACX,IAAIC,KACL,CAAC,GAAGN,EAAWK,QACf3B,SAASsB,EAAWO,UAAY,CAACC,KAAO,GAAGR,EAAWO,iBAAcH,GAItEvB,EAASC,OACRiB,EACAM,EACA3B,SAASsB,EAAWG,MAAQ,GAAGH,EAAWG,YAASC,EAErD,MACCvB,EAASC,OAAOiB,EAAW,GAAGC,UAG/BnB,EAASC,OAAOiB,EAAWC,EAC5B,GACC,IAGInB,CACR","ignoreList":[],"sourcesContent":["/*!\n * Module Forms\n */\n\n/**\n * @namespace Forms\n */\n\nconst MODULE_NAME = 'Forms';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {isFunction, isPlainObject, hasValue} from './basic.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Forms:formDataToObject\n */\n\n/**\n * Constructs a plain object from an existing FormData object or a given form element.\n *\n * The idea of this function is, to make working with form data easier in programmatic contexts by allowing operations\n * like optional chaining and \"in\" operators. This might especially come in handy if you need to do programmatic\n * validations.\n *\n * Additionally, this function streamlines field names, by discarding PHP-style array field name conventions like\n * \"files[]\", by removing the brackets. So, if you have a field named \"files[]\" and another field named \"files\",\n * both will just end up in one \"files\"-field, having an array as a value containing all combined values.\n *\n * Keep in mind, that the status of form fields in a form matters when retrieving FormData from a form element.\n * Disabled fields will not be included for example. Make sure to handle this before using the data.\n *\n * On Internet Explorers, this function needs a polyfill, which is not included in annex, due to its size and\n * complexity, since IEs, while supporting FormData basically, are lacking all functions to access values of an existing\n * FormData object, thereby making it impossible to iterate its values.\n *\n * @param {FormData|HTMLFormElement} formDataOrForm - either an existing FormData object or a form, from which we can retrieve formdata\n * @returns {Object} plain object, containing all form values based on the exisiting fields as key/value-pairs\n *\n * @memberof Forms:formDataToObject\n * @alias formDataToObject\n * @see objectToFormData\n * @see https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData\n * @see https://github.com/jimmywarting/FormData\n * @example\n * const formData = new FormData();\n * formData.append('secrethash', 123456789);\n * formData.append('firstname', 'Paul');\n * formData.append('lastname', 'Atreides');\n * formData.append('houses', 'Atreides');\n * formData.append('houses', 'Fremen');\n * formData.append('houses', 'Corrino');\n * formData.append('diary', new File(['Dear Diary, ...'], 'diary.txt', {type : 'text/plain', lastModified : new Date()}));\n * formData.append('instagramPage', new Blob(['...'], {type : 'text/html'}));\n * formDataToObject(formData)\n * =>\n * {\n * secrethash : '123456789',\n * \t firstname : 'Paul',\n * \t lastname : 'Atreides',\n * \t houses : ['Atreides', 'Fremen', 'Corrino'],\n * \t diary : File,\n * \t instagramPage : Blob\n * }\n */\nexport function formDataToObject(formDataOrForm){\n\tlet formData;\n\n\t// let's do duck-typing to allow polyfills\n\tif(\n\t\tisFunction(formDataOrForm.append)\n\t\t&& isFunction(formDataOrForm.getAll)\n\t\t&& isFunction(formDataOrForm.entries)\n\t){\n\t\tformData = formDataOrForm;\n\t} else {\n\t\ttry {\n\t\t\tformData = new FormData(formDataOrForm);\n\t\t} catch(ex){\n\t\t\tformData = null;\n\t\t}\n\t}\n\n\tif( !hasValue(formData) ) return null;\n\n\tconst formDataObject = {};\n\n\tArray.from(formData.entries()).forEach(([key, values]) => {\n\t\tif( key.endsWith('[]') ){\n\t\t\tkey = key.slice(0, -2);\n\t\t}\n\t\tvalues = [].concat(values);\n\n\t\tif( !hasValue(formDataObject[key]) ){\n\t\t\tformDataObject[key] = (values.length === 1) ? values[0] : values;\n\t\t} else {\n\t\t\tformDataObject[key] = [].concat(formDataObject[key], values);\n\t\t}\n\t});\n\n\treturn formDataObject;\n}\n\n\n\n/**\n * @namespace Forms:objectToFormData\n */\n\n/**\n * Constructs a FormData object, to be used in requests, from a given (plain) object, iterating its entries.\n *\n * Additionally, this function streamlines field names, by discarding PHP-style array field name conventions like\n * \"files[]\", by removing the brackets. So, if you have a field named \"files[]\" and another field named \"files\",\n * both will just end up in one \"files\"-field.\n *\n * Files and Blobs can be provided as-is (constructed programmatically of retrieved from file inputs via `.files`).\n * Alternatively (and if you manually want to define the filename), you can provide plain objects to describe a File or\n * Blob to add to the FormData:\n * - use {file : File, ?name : String} to add \"file\" as a File and optionally set \"name\" to define a filename, taking\n * precedence over what is already defined in the File object itself\n * - use {blob : Blob|String, ?name : String, ?mimeType : String} to add \"blob\" as a Blob (if this is a string, it\n * will be treated as the content of a new Blob), optionally using \"name\" as the filename (I'd recommend to set this)\n * and optionally setting the file type via the MIME type defined in \"mimeType\".\n *\n * In contrast to `formDataToObject`, this function does not need a polyfill in Internet Explorer, since it only uses\n * the FormData constructor and the `.append()` method, which are both supported.\n *\n * @param {Object} formDataObject - object to iterate, to create FormData based on its entries\n * @returns {FormData} FormData object to be used in a request\n *\n * @memberof Forms:objectToFormData\n * @alias objectToFormData\n * @see formDataToObject\n * @see https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData\n * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types\n * @example\n * const formData = objectToFormData({\n * secrethash : 123456789,\n * \t firstname : 'Paul',\n * \t lastname : 'Atreides',\n * \t houses : ['Atreides', 'Fremen', 'Corrino'],\n * \t diary : {file : new File(['Dear Diary, ...'], 'diary.txt', {type : 'text/plain', lastModified : new Date()})},\n * \t instagramPage : {blob : '...', name : 'instagram.html', mimeType : 'text/html'},\n * }).getAll('houses');\n * => ['Atreides', 'Fremen', 'Corrino']\n */\nexport function objectToFormData(formDataObject){\n\tconst formData = new FormData();\n\n\tObject.entries(formDataObject).forEach(([fieldName, fieldValue]) => {\n\t\tif( fieldName.endsWith('[]') ){\n\t\t\tfieldName = fieldName.slice(0, -2);\n\t\t}\n\n\t\t[].concat(fieldValue).forEach(fieldValue => {\n\t\t\tif( isPlainObject(fieldValue) ){\n\t\t\t\tif( hasValue(fieldValue.file) && (fieldValue.file instanceof File) ){\n\t\t\t\t\tformData.append(\n\t\t\t\t\t\tfieldName,\n\t\t\t\t\t\tfieldValue.file,\n\t\t\t\t\t\thasValue(fieldValue.name) ? `${fieldValue.name}` : undefined\n\t\t\t\t\t);\n\t\t\t\t} else if( hasValue(fieldValue.blob) ){\n\t\t\t\t\tconst blob = (fieldValue.blob instanceof Blob)\n\t\t\t\t\t\t? fieldValue.blob\n\t\t\t\t\t\t: new Blob(\n\t\t\t\t\t\t\t[`${fieldValue.blob}`],\n\t\t\t\t\t\t\thasValue(fieldValue.mimeType) ? {type : `${fieldValue.mimeType}`} : undefined\n\t\t\t\t\t\t)\n\t\t\t\t\t;\n\n\t\t\t\t\tformData.append(\n\t\t\t\t\t\tfieldName,\n\t\t\t\t\t\tblob,\n\t\t\t\t\t\thasValue(fieldValue.name) ? `${fieldValue.name}` : undefined\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tformData.append(fieldName, `${fieldValue}`);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tformData.append(fieldName, fieldValue);\n\t\t\t}\n\t\t});\n\t});\n\n\treturn formData;\n}\n"]} \ No newline at end of file diff --git a/dist/functions.js b/dist/functions.js index a7ca5ee2..9cba8b12 100644 --- a/dist/functions.js +++ b/dist/functions.js @@ -1,5 +1,5 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Functions diff --git a/dist/functions.js.map b/dist/functions.js.map index ecd433c5..a3c9efd1 100644 --- a/dist/functions.js.map +++ b/dist/functions.js.map @@ -1 +1 @@ -{"version":3,"file":"functions.js","names":["MODULE_NAME","orDefault","isFunction","isPlainObject","assert","hasValue","schedule","reschedule","throttle","ms","func","hasLeadingExecution","hasTrailingExecution","frameHasStarted","callsInFrame","args","Array","from","arguments","apply","this","debounce","debounceTimer","defer","delay","id","kwargs","defaults","argNamesString","toString","match","argNames","split","map","argName","trim","length","applicableArgs","forEach","arg","argIndex","argNameIndex"],"sources":["functions.js"],"mappings":";;;AAQA,MAAMA,YAAc,mBAMZC,UAAWC,WAAYC,cAAeC,OAAQC,aAAe,oBAC7DC,SAAUC,eAAiB,qBAqC5B,SAASC,SAASC,EAAIC,EAAMC,GAAoB,EAAOC,GAAqB,GAClFH,EAAKR,UAAUQ,EAAI,EAAG,OACtBE,EAAsBV,UAAUU,GAAqB,EAAO,QAC5DC,EAAuBX,UAAUW,GAAsB,EAAO,QAE9DR,OAAOK,EAAK,EAAG,uCACfL,OAAOF,WAAWQ,GAAO,0CAEzB,IACCG,GAAkB,EAClBC,EAAe,EAGhB,OAAO,WACN,MAAMC,EAAOC,MAAMC,KAAKC,WAEnBL,EAgBuB,IAAjBC,GACVA,IACAJ,EAAKS,MAAMC,KAAML,IAEjBD,KAnBAD,GAAkB,EACbF,GACJG,IAGDJ,EAAKS,MAAMC,KAAML,GAEhBT,SAASG,GAAI,KACTG,GAAyBE,EAAe,GAC3CJ,EAAKS,MAAMC,KAAML,GAGlBF,GAAkB,EAClBC,EAAe,CAAC,IAQnB,CACD,QAyBO,SAASO,SAASZ,EAAIC,GAM5B,IAAIY,EAEJ,OAPAb,EAAKR,UAAUQ,EAAI,EAAG,OAEtBL,OAAOK,EAAK,EAAG,uCACfL,OAAOF,WAAWQ,GAAO,0CAIlB,WACNY,EAAgBf,WAAWe,EAAeb,GAAI,KAAQC,EAAKS,MAAMC,KAAMJ,MAAMC,KAAKC,WAAW,GAC9F,CACD,QAuBO,SAASK,MAAMb,EAAMc,EAAM,GAMjC,OALAA,EAAQvB,UAAUuB,EAAO,EAAG,OAE5BpB,OAAOF,WAAWQ,GAAO,uCACzBN,OAAOoB,EAAQ,EAAG,uCAEX,WACN,OAAOlB,SAASkB,GAAO,KAAQd,EAAKS,MAAMC,KAAMJ,MAAMC,KAAKC,WAAW,IAAKO,EAC5E,CACD,QA4CO,SAASC,OAAOhB,EAAMiB,EAAS,MACrCA,EAAWxB,cAAcwB,GAAYA,EAAW,CAAC,EAEjDvB,OAAOF,WAAWQ,GAAO,wCAEzB,MACCkB,EAAiBlB,EAAKmB,WAAWC,MAAM,aAAa,GACpDC,EAAWH,EAAiBA,EAAeI,MAAM,KAAKC,KAAIC,GAAW,GAAGA,IAAUC,SAAU,GAK7F,OAFA/B,OAAO2B,EAASK,OAAS,EAAG,6DAAkE1B,EAAKmB,uCAAuCD,MAEnI,WACN,MAAMS,EAAiB,GA2BvB,OAzBArB,MAAMC,KAAKC,WAAWoB,SAAQ,CAACC,EAAKC,MAElCrC,cAAcoC,IAETlC,SAASkC,EAAIb,UAAaa,EAAIb,OAQnCW,EAAeG,GAAYD,EAN3BR,EAASO,SAAQ,CAACJ,EAASO,KACtBpC,SAASkC,EAAIL,MAChBG,EAAeI,GAAgBF,EAAIL,GACpC,GAIF,IAGDH,EAASO,SAAQ,CAACJ,EAASO,MAExBpC,SAASgC,EAAeI,KACtBpC,SAASsB,EAASO,MAErBG,EAAeI,GAAgBd,EAASO,GACzC,IAGMxB,EAAKS,MAAMC,KAAMiB,EACzB,CACD","sourcesContent":["/*!\n * Module Functions\n */\n\n/**\n * @namespace Functions\n */\n\nconst MODULE_NAME = 'Functions';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {orDefault, isFunction, isPlainObject, assert, hasValue} from './basic.js';\nimport {schedule, reschedule} from './timers.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Functions:throttle\n */\n\n/**\n * Returns a throttled function (based on an unthrottled one), which executes only once in a timeframe at most.\n * This is especially helpful to react to events, that might come in avalanches in an orderly and performant way,\n * let's say changing layout due to a resizing or scrolling event.\n *\n * If you are trying to react to events, that occur a lot, in a synchronous fashion, meaning, that you rely on values\n * and data having been updated after the event, so there is a clear time arrow of things happening in order, you might\n * need to set hasLeadingExecution and/or hasTrailingExecution to true to better cover those cases.\n *\n * Be aware that the precision of this method relies in part on the client's cpu, so this is implementation might\n * not be right if you need a razor sharp exact amount of calls in a given time every time, this is a more simple\n * and fuzzy implementation for basic purposes, which should cover 90% of your needs.\n * For a more precise and battle-tested version, see lodash's complex implementation:\n * https://www.npmjs.com/package/lodash.throttle\n *\n * @param {Number} ms - the timeframe for one execution at most in milliseconds\n * @param {Function} func - the function to throttle\n * @param {?Boolean} [hasLeadingExecution=false] - defines that the function call that starts a timeframe, does not count, so that during the following frame another call is possible\n * @param {?Boolean} [hasTrailingExecution=false] - defines if the function is executed at the end of the timeframe (will only happen, if there were more than one calls to the function in the time frame)\n * @throws error if ms is no number > 0 or func is not a function\n * @returns {Function} the throttling function (parameters will be handed as is to the throttled function)\n *\n * @memberof Functions:throttle\n * @alias throttle\n * @example\n * window.addEventListener('resize', throttle(400, function(){ console.log(`the viewport is now ${window.innerWidth}px wide`); }));\n */\nexport function throttle(ms, func, hasLeadingExecution=false, hasTrailingExecution=false){\n\tms = orDefault(ms, 0, 'int');\n\thasLeadingExecution = orDefault(hasLeadingExecution, false, 'bool');\n\thasTrailingExecution = orDefault(hasTrailingExecution, false, 'bool');\n\n\tassert(ms > 0, `${MODULE_NAME}:throttle | ms must be > 0`);\n\tassert(isFunction(func), `${MODULE_NAME}:throttle | no function given`);\n\n\tlet\n\t\tframeHasStarted = false,\n\t\tcallsInFrame = 0\n\t;\n\n\treturn function(){\n\t\tconst args = Array.from(arguments);\n\n\t\tif( !frameHasStarted ){\n\t\t\tframeHasStarted = true;\n\t\t\tif( !hasLeadingExecution ){\n\t\t\t\tcallsInFrame++;\n\t\t\t}\n\n\t\t\tfunc.apply(this, args);\n\n\t\t\t schedule(ms, () => {\n\t\t\t\tif( hasTrailingExecution && (callsInFrame > 1) ){\n\t\t\t\t\tfunc.apply(this, args);\n\t\t\t\t}\n\n\t\t\t\tframeHasStarted = false;\n\t\t\t\tcallsInFrame = 0;\n\t\t\t});\n\t\t} else if( callsInFrame === 0 ){\n\t\t\tcallsInFrame++;\n\t\t\tfunc.apply(this, args);\n\t\t} else {\n\t\t\tcallsInFrame++;\n\t\t}\n\t};\n}\n\n\n\n/**\n * @namespace Functions:debounce\n */\n\n/**\n * Hold the execution of a function until it has not been called for a specific timeframe.\n *\n * This is a basic implementation for 90% of all cases, if you need more options and more control\n * over details, have a look at lodash's implementation:\n * https://www.npmjs.com/package/lodash.debounce\n *\n * @param {Number} ms - timeframe in milliseconds without call before execution\n * @param {Function} func - the function to delay the execution of\n * @throws error if ms is no number > 0 or func is not a function\n * @returns {Function} the debounced function (parameters will be handed as is to the provided function)\n *\n * @memberof Functions:debounce\n * @alias debounce\n * @example\n * document.querySelector('input[name=search]').addEventListener('change', debounce(1000, function(){ refreshSearch(); }));\n */\nexport function debounce(ms, func){\n\tms = orDefault(ms, 0, 'int');\n\n\tassert(ms > 0, `${MODULE_NAME}:debounce | ms must be > 0`);\n\tassert(isFunction(func), `${MODULE_NAME}:debounce | no function given`);\n\n\tlet\tdebounceTimer;\n\n\treturn function(){\n\t\tdebounceTimer = reschedule(debounceTimer, ms, () => { func.apply(this, Array.from(arguments)); });\n\t};\n}\n\n\n\n/**\n * @namespace Functions:defer\n */\n\n/**\n * Defer the execution of a function until the callstack is empty.\n * This works identical to setTimeout(function(){}, 1);\n *\n * @param {Function} func - the function to defer\n * @param {?Number} [delay=1] - the delay to apply in milliseconds, 1 is a non-minifiable value to target the next tick, but you may define any millisecond value you want, to manually delay the function execution\n * @throws error if func is not a function or delay is no number > 0\n * @returns {Function} the deferred function; the deferred function returns the timer id, in case you want to cancel execution\n *\n * @memberof Functions:defer\n * @alias defer\n * @example\n * defer(function(){ doOnNextTick(); })();\n * defer(function(){ doInTwoSeconds(); }, 2000)();\n */\nexport function defer(func, delay=1){\n\tdelay = orDefault(delay, 1, 'int');\n\n\tassert(isFunction(func), `${MODULE_NAME}:defer | no function given`);\n\tassert(delay > 0, `${MODULE_NAME}:defer | delay must be > 0`);\n\n\treturn function(){\n\t\treturn schedule(delay, () => { func.apply(this, Array.from(arguments)); }).id;\n\t};\n}\n\n\n\n/**\n * @namespace Functions:kwargs\n */\n\n/**\n * This function creates a function where we can set all parameters as a config object by name for each\n * call, while also allowing to set default values for parameters on function creation.\n *\n * This is heavily inspired by Python's way of handling parameters, therefore the name.\n *\n * This enables you to overload complex function signatures with tailor-fit version for your use cases and\n * to call functions with specific parameter sets in a very readable way, without adding empty values to the\n * list of parameters. So you just define what you want to set and those parts are clearly named.\n *\n * Each parameter you pass to the created kwargs function may be one of two variants:\n * - either it is not a plain object; in that case the parameter is passed to the original function as is at the\n * position the parameter is declared in the call\n * - or the parameter is a plain object, in which case we treat the parameter as kwargs and try to match keys\n * to parameters; in case you ever have to pass a plain object as-is: setting \"kwargs: false\" in the object\n * tells the parser to skip matching props to parameters\n *\n * You can even mix these types. If two parameters describe the same value in the call, the last declaration wins.\n *\n * @param {Function} func - the function to provide kwargs to\n * @param {?Object} [defaults=null] - the default kwargs to apply to func, essentially setting default values for all given keys fitting parameters of the function\n * @throws error if func is not a function or parameter names of func could not be identified\n * @returns {Function} new function accepting mixed args, also being possible kwarg dicts\n *\n * @memberof Functions:kwargs\n * @alias kwargs\n * @example\n * const fTest = function(tick, trick, track){ console.log(tick, trick, track); };\n * const fKwargsTest = kwargs(fTest, {track : 'defaultTrack'});\n * fKwargsTest({tick : 'tiick', trick : 'trick'});\n * => \"tiick, trick, defaultTrack\"\n * kwargs(fTest, {track : 'defaultTrack'})('argumentTick', {trick : 'triick', track : 'trACK'});\n * => \"argumentTick, triick, trACK\"\n * kwargs(fTest, {track : 'defaultTrack'})('argumentTick', {trick : 'triick', track : 'track'}, 'trackkkk');\n * => \"argumentTick, triick, trackkkk\"\n */\nexport function kwargs(func, defaults=null){\n\tdefaults = isPlainObject(defaults) ? defaults : {};\n\n\tassert(isFunction(func), `${MODULE_NAME}:kwargs | no function given`);\n\n\tconst\n\t\targNamesString = func.toString().match(/\\(([^)]+)/)[1],\n\t\targNames = argNamesString ? argNamesString.split(',').map(argName => `${argName}`.trim()) : []\n\t;\n\n\tassert(argNames.length > 0, `${MODULE_NAME}:kwargs | could not identify parameter names in \"${func.toString()}\" using parameter string \"${argNamesString}\"`);\n\n\treturn function(){\n\t\tconst applicableArgs = [];\n\n\t\tArray.from(arguments).forEach((arg, argIndex) => {\n\t\t\tif(\n\t\t\t\tisPlainObject(arg)\n\t\t\t\t// if object contains falsy property \"kwargs\" leave it as is\n\t\t\t\t&& (!hasValue(arg.kwargs) || !!arg.kwargs)\n\t\t\t){\n\t\t\t\targNames.forEach((argName, argNameIndex) => {\n\t\t\t\t\tif( hasValue(arg[argName]) ){\n\t\t\t\t\t\tapplicableArgs[argNameIndex] = arg[argName];\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tapplicableArgs[argIndex] = arg;\n\t\t\t}\n\t\t});\n\n\t\targNames.forEach((argName, argNameIndex) => {\n\t\t\tif(\n\t\t\t\t!hasValue(applicableArgs[argNameIndex])\n\t\t\t\t&& hasValue(defaults[argName])\n\t\t\t){\n\t\t\t\tapplicableArgs[argNameIndex] = defaults[argName];\n\t\t\t}\n\t\t});\n\n\t\treturn func.apply(this, applicableArgs);\n\t};\n}\n"]} \ No newline at end of file +{"version":3,"file":"functions.js","names":["MODULE_NAME","orDefault","isFunction","isPlainObject","assert","hasValue","schedule","reschedule","throttle","ms","func","hasLeadingExecution","hasTrailingExecution","frameHasStarted","callsInFrame","args","Array","from","arguments","apply","this","debounce","debounceTimer","defer","delay","id","kwargs","defaults","argNamesString","toString","match","argNames","split","map","argName","trim","length","applicableArgs","forEach","arg","argIndex","argNameIndex"],"sources":["functions.js"],"mappings":";;;AAQA,MAAMA,YAAc,mBAMZC,UAAWC,WAAYC,cAAeC,OAAQC,aAAe,oBAC7DC,SAAUC,eAAiB,qBAqC5B,SAASC,SAASC,EAAIC,EAAMC,GAAoB,EAAOC,GAAqB,GAClFH,EAAKR,UAAUQ,EAAI,EAAG,OACtBE,EAAsBV,UAAUU,GAAqB,EAAO,QAC5DC,EAAuBX,UAAUW,GAAsB,EAAO,QAE9DR,OAAOK,EAAK,EAAG,uCACfL,OAAOF,WAAWQ,GAAO,0CAEzB,IACCG,GAAkB,EAClBC,EAAe,EAGhB,OAAO,WACN,MAAMC,EAAOC,MAAMC,KAAKC,WAEnBL,EAgBuB,IAAjBC,GACVA,IACAJ,EAAKS,MAAMC,KAAML,IAEjBD,KAnBAD,GAAkB,EACbF,GACJG,IAGDJ,EAAKS,MAAMC,KAAML,GAEhBT,SAASG,GAAI,KACTG,GAAyBE,EAAe,GAC3CJ,EAAKS,MAAMC,KAAML,GAGlBF,GAAkB,EAClBC,EAAe,CAAC,IAQnB,CACD,QAyBO,SAASO,SAASZ,EAAIC,GAM5B,IAAIY,EAEJ,OAPAb,EAAKR,UAAUQ,EAAI,EAAG,OAEtBL,OAAOK,EAAK,EAAG,uCACfL,OAAOF,WAAWQ,GAAO,0CAIlB,WACNY,EAAgBf,WAAWe,EAAeb,GAAI,KAAQC,EAAKS,MAAMC,KAAMJ,MAAMC,KAAKC,WAAW,GAC9F,CACD,QAuBO,SAASK,MAAMb,EAAMc,EAAM,GAMjC,OALAA,EAAQvB,UAAUuB,EAAO,EAAG,OAE5BpB,OAAOF,WAAWQ,GAAO,uCACzBN,OAAOoB,EAAQ,EAAG,uCAEX,WACN,OAAOlB,SAASkB,GAAO,KAAQd,EAAKS,MAAMC,KAAMJ,MAAMC,KAAKC,WAAW,IAAKO,EAC5E,CACD,QA4CO,SAASC,OAAOhB,EAAMiB,EAAS,MACrCA,EAAWxB,cAAcwB,GAAYA,EAAW,CAAC,EAEjDvB,OAAOF,WAAWQ,GAAO,wCAEzB,MACCkB,EAAiBlB,EAAKmB,WAAWC,MAAM,aAAa,GACpDC,EAAWH,EAAiBA,EAAeI,MAAM,KAAKC,KAAIC,GAAW,GAAGA,IAAUC,SAAU,GAK7F,OAFA/B,OAAO2B,EAASK,OAAS,EAAG,6DAAkE1B,EAAKmB,uCAAuCD,MAEnI,WACN,MAAMS,EAAiB,GA2BvB,OAzBArB,MAAMC,KAAKC,WAAWoB,SAAQ,CAACC,EAAKC,MAElCrC,cAAcoC,IAETlC,SAASkC,EAAIb,UAAaa,EAAIb,OAQnCW,EAAeG,GAAYD,EAN3BR,EAASO,SAAQ,CAACJ,EAASO,KACtBpC,SAASkC,EAAIL,MAChBG,EAAeI,GAAgBF,EAAIL,GACpC,GAIF,IAGDH,EAASO,SAAQ,CAACJ,EAASO,MAExBpC,SAASgC,EAAeI,KACtBpC,SAASsB,EAASO,MAErBG,EAAeI,GAAgBd,EAASO,GACzC,IAGMxB,EAAKS,MAAMC,KAAMiB,EACzB,CACD","ignoreList":[],"sourcesContent":["/*!\n * Module Functions\n */\n\n/**\n * @namespace Functions\n */\n\nconst MODULE_NAME = 'Functions';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {orDefault, isFunction, isPlainObject, assert, hasValue} from './basic.js';\nimport {schedule, reschedule} from './timers.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Functions:throttle\n */\n\n/**\n * Returns a throttled function (based on an unthrottled one), which executes only once in a timeframe at most.\n * This is especially helpful to react to events, that might come in avalanches in an orderly and performant way,\n * let's say changing layout due to a resizing or scrolling event.\n *\n * If you are trying to react to events, that occur a lot, in a synchronous fashion, meaning, that you rely on values\n * and data having been updated after the event, so there is a clear time arrow of things happening in order, you might\n * need to set hasLeadingExecution and/or hasTrailingExecution to true to better cover those cases.\n *\n * Be aware that the precision of this method relies in part on the client's cpu, so this is implementation might\n * not be right if you need a razor sharp exact amount of calls in a given time every time, this is a more simple\n * and fuzzy implementation for basic purposes, which should cover 90% of your needs.\n * For a more precise and battle-tested version, see lodash's complex implementation:\n * https://www.npmjs.com/package/lodash.throttle\n *\n * @param {Number} ms - the timeframe for one execution at most in milliseconds\n * @param {Function} func - the function to throttle\n * @param {?Boolean} [hasLeadingExecution=false] - defines that the function call that starts a timeframe, does not count, so that during the following frame another call is possible\n * @param {?Boolean} [hasTrailingExecution=false] - defines if the function is executed at the end of the timeframe (will only happen, if there were more than one calls to the function in the time frame)\n * @throws error if ms is no number > 0 or func is not a function\n * @returns {Function} the throttling function (parameters will be handed as is to the throttled function)\n *\n * @memberof Functions:throttle\n * @alias throttle\n * @example\n * window.addEventListener('resize', throttle(400, function(){ console.log(`the viewport is now ${window.innerWidth}px wide`); }));\n */\nexport function throttle(ms, func, hasLeadingExecution=false, hasTrailingExecution=false){\n\tms = orDefault(ms, 0, 'int');\n\thasLeadingExecution = orDefault(hasLeadingExecution, false, 'bool');\n\thasTrailingExecution = orDefault(hasTrailingExecution, false, 'bool');\n\n\tassert(ms > 0, `${MODULE_NAME}:throttle | ms must be > 0`);\n\tassert(isFunction(func), `${MODULE_NAME}:throttle | no function given`);\n\n\tlet\n\t\tframeHasStarted = false,\n\t\tcallsInFrame = 0\n\t;\n\n\treturn function(){\n\t\tconst args = Array.from(arguments);\n\n\t\tif( !frameHasStarted ){\n\t\t\tframeHasStarted = true;\n\t\t\tif( !hasLeadingExecution ){\n\t\t\t\tcallsInFrame++;\n\t\t\t}\n\n\t\t\tfunc.apply(this, args);\n\n\t\t\t schedule(ms, () => {\n\t\t\t\tif( hasTrailingExecution && (callsInFrame > 1) ){\n\t\t\t\t\tfunc.apply(this, args);\n\t\t\t\t}\n\n\t\t\t\tframeHasStarted = false;\n\t\t\t\tcallsInFrame = 0;\n\t\t\t});\n\t\t} else if( callsInFrame === 0 ){\n\t\t\tcallsInFrame++;\n\t\t\tfunc.apply(this, args);\n\t\t} else {\n\t\t\tcallsInFrame++;\n\t\t}\n\t};\n}\n\n\n\n/**\n * @namespace Functions:debounce\n */\n\n/**\n * Hold the execution of a function until it has not been called for a specific timeframe.\n *\n * This is a basic implementation for 90% of all cases, if you need more options and more control\n * over details, have a look at lodash's implementation:\n * https://www.npmjs.com/package/lodash.debounce\n *\n * @param {Number} ms - timeframe in milliseconds without call before execution\n * @param {Function} func - the function to delay the execution of\n * @throws error if ms is no number > 0 or func is not a function\n * @returns {Function} the debounced function (parameters will be handed as is to the provided function)\n *\n * @memberof Functions:debounce\n * @alias debounce\n * @example\n * document.querySelector('input[name=search]').addEventListener('change', debounce(1000, function(){ refreshSearch(); }));\n */\nexport function debounce(ms, func){\n\tms = orDefault(ms, 0, 'int');\n\n\tassert(ms > 0, `${MODULE_NAME}:debounce | ms must be > 0`);\n\tassert(isFunction(func), `${MODULE_NAME}:debounce | no function given`);\n\n\tlet\tdebounceTimer;\n\n\treturn function(){\n\t\tdebounceTimer = reschedule(debounceTimer, ms, () => { func.apply(this, Array.from(arguments)); });\n\t};\n}\n\n\n\n/**\n * @namespace Functions:defer\n */\n\n/**\n * Defer the execution of a function until the callstack is empty.\n * This works identical to setTimeout(function(){}, 1);\n *\n * @param {Function} func - the function to defer\n * @param {?Number} [delay=1] - the delay to apply in milliseconds, 1 is a non-minifiable value to target the next tick, but you may define any millisecond value you want, to manually delay the function execution\n * @throws error if func is not a function or delay is no number > 0\n * @returns {Function} the deferred function; the deferred function returns the timer id, in case you want to cancel execution\n *\n * @memberof Functions:defer\n * @alias defer\n * @example\n * defer(function(){ doOnNextTick(); })();\n * defer(function(){ doInTwoSeconds(); }, 2000)();\n */\nexport function defer(func, delay=1){\n\tdelay = orDefault(delay, 1, 'int');\n\n\tassert(isFunction(func), `${MODULE_NAME}:defer | no function given`);\n\tassert(delay > 0, `${MODULE_NAME}:defer | delay must be > 0`);\n\n\treturn function(){\n\t\treturn schedule(delay, () => { func.apply(this, Array.from(arguments)); }).id;\n\t};\n}\n\n\n\n/**\n * @namespace Functions:kwargs\n */\n\n/**\n * This function creates a function where we can set all parameters as a config object by name for each\n * call, while also allowing to set default values for parameters on function creation.\n *\n * This is heavily inspired by Python's way of handling parameters, therefore the name.\n *\n * This enables you to overload complex function signatures with tailor-fit version for your use cases and\n * to call functions with specific parameter sets in a very readable way, without adding empty values to the\n * list of parameters. So you just define what you want to set and those parts are clearly named.\n *\n * Each parameter you pass to the created kwargs function may be one of two variants:\n * - either it is not a plain object; in that case the parameter is passed to the original function as is at the\n * position the parameter is declared in the call\n * - or the parameter is a plain object, in which case we treat the parameter as kwargs and try to match keys\n * to parameters; in case you ever have to pass a plain object as-is: setting \"kwargs: false\" in the object\n * tells the parser to skip matching props to parameters\n *\n * You can even mix these types. If two parameters describe the same value in the call, the last declaration wins.\n *\n * @param {Function} func - the function to provide kwargs to\n * @param {?Object} [defaults=null] - the default kwargs to apply to func, essentially setting default values for all given keys fitting parameters of the function\n * @throws error if func is not a function or parameter names of func could not be identified\n * @returns {Function} new function accepting mixed args, also being possible kwarg dicts\n *\n * @memberof Functions:kwargs\n * @alias kwargs\n * @example\n * const fTest = function(tick, trick, track){ console.log(tick, trick, track); };\n * const fKwargsTest = kwargs(fTest, {track : 'defaultTrack'});\n * fKwargsTest({tick : 'tiick', trick : 'trick'});\n * => \"tiick, trick, defaultTrack\"\n * kwargs(fTest, {track : 'defaultTrack'})('argumentTick', {trick : 'triick', track : 'trACK'});\n * => \"argumentTick, triick, trACK\"\n * kwargs(fTest, {track : 'defaultTrack'})('argumentTick', {trick : 'triick', track : 'track'}, 'trackkkk');\n * => \"argumentTick, triick, trackkkk\"\n */\nexport function kwargs(func, defaults=null){\n\tdefaults = isPlainObject(defaults) ? defaults : {};\n\n\tassert(isFunction(func), `${MODULE_NAME}:kwargs | no function given`);\n\n\tconst\n\t\targNamesString = func.toString().match(/\\(([^)]+)/)[1],\n\t\targNames = argNamesString ? argNamesString.split(',').map(argName => `${argName}`.trim()) : []\n\t;\n\n\tassert(argNames.length > 0, `${MODULE_NAME}:kwargs | could not identify parameter names in \"${func.toString()}\" using parameter string \"${argNamesString}\"`);\n\n\treturn function(){\n\t\tconst applicableArgs = [];\n\n\t\tArray.from(arguments).forEach((arg, argIndex) => {\n\t\t\tif(\n\t\t\t\tisPlainObject(arg)\n\t\t\t\t// if object contains falsy property \"kwargs\" leave it as is\n\t\t\t\t&& (!hasValue(arg.kwargs) || !!arg.kwargs)\n\t\t\t){\n\t\t\t\targNames.forEach((argName, argNameIndex) => {\n\t\t\t\t\tif( hasValue(arg[argName]) ){\n\t\t\t\t\t\tapplicableArgs[argNameIndex] = arg[argName];\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tapplicableArgs[argIndex] = arg;\n\t\t\t}\n\t\t});\n\n\t\targNames.forEach((argName, argNameIndex) => {\n\t\t\tif(\n\t\t\t\t!hasValue(applicableArgs[argNameIndex])\n\t\t\t\t&& hasValue(defaults[argName])\n\t\t\t){\n\t\t\t\tapplicableArgs[argNameIndex] = defaults[argName];\n\t\t\t}\n\t\t});\n\n\t\treturn func.apply(this, applicableArgs);\n\t};\n}\n"]} \ No newline at end of file diff --git a/dist/images.js b/dist/images.js index 1d7fcd55..e4bb4646 100644 --- a/dist/images.js +++ b/dist/images.js @@ -1,8 +1,8 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Images */ -const MODULE_NAME="Images";import{orDefault,isArray,isPlainObject,assert,isEmpty,isElement,hasValue,Deferred}from"./basic.js";import{waitForRepaint}from"./timers.js";const PRELOADED_IMAGES={unnamed:[],named:{}};export function preload(e){const r=[],t=new Deferred;let n;if(!isPlainObject(e)&&!isArray(e)){if(e=`${e}`,hasValue(PRELOADED_IMAGES.named[e]))return PRELOADED_IMAGES.named[e];e=[e]}return isPlainObject(e)?(n={},Object.entries(e).forEach((([e,t])=>{e=`${e}`,t=`${t}`,hasValue(PRELOADED_IMAGES.named[e])||(n[e]=new Image,n[e].src=t,r.push(n[e]))})),PRELOADED_IMAGES.named={...PRELOADED_IMAGES.named,...n}):isArray(e)&&(n=[],e.forEach((e=>{const t=new Image;t.src=`${e}`,n.push(t),r.push(t)})),PRELOADED_IMAGES.unnamed=Array.from(new Set(PRELOADED_IMAGES.unnamed.concat(n)))),t.provision=isArray(n)&&1===n.length?n[0]:n,loaded(r).then(t.resolve).catch(t.reject),t}export function loaded(e,r=!1){function t(i){const m=i.currentTarget;!r||r&&m.naturalWidth>0?(s--,s<=0&&(e.map((e=>{e.removeEventListener("load",t),e.removeEventListener("error",n)})),a.map((e=>{e.removeEventListener("load",t),e.removeEventListener("error",n)})),o.resolve(1===e.length?e[0]:e))):waitForRepaint((()=>{t(i)}))}function n(r){e.map((e=>{e.removeEventListener("load",t),e.removeEventListener("error",n)})),a.map((e=>{e.removeEventListener("load",t),e.removeEventListener("error",n)})),o.reject(r)}e=orDefault(e,[],"arr").filter((e=>"htmlimageelement"===Object.prototype.toString.call(e).slice(8,-1).toLowerCase())),r=orDefault(r,!1,"bool");const o=new Deferred,a=[];let s=e.length;return o.provision=1===e.length?e[0]:e,e.forEach((e=>{e.removeEventListener("load",t),e.addEventListener("load",t),e.removeEventListener("error",n),e.addEventListener("error",n);const r=e.src,o=e.parentNode,s=!!isElement(e.parentNode)&&"picture"===o.nodeName.toLowerCase();if(assert(!isEmpty(r),"Images:loaded | image has no src"),s||e.complete){let i;s?(window.respimage?(window.respimage({elements:[o]}),i=o.querySelector("img")):window.picturefill?(window.picturefill({elements:[o]}),i=o.querySelector("img")):i=e,i.complete?(i=new Image,i.addEventListener("load",t),i.addEventListener("error",n),i.src=r,a.push(i)):(i.removeEventListener("load",t),i.addEventListener("load",t),i.removeEventListener("error",n),i.addEventListener("error",n))):(i=new Image,i.addEventListener("load",t),i.addEventListener("error",n),i.src=r,a.push(i))}})),o} +const MODULE_NAME="Images";import{orDefault,isArray,isPlainObject,assert,isEmpty,isElement,hasValue,Deferred}from"./basic.js";import{waitForRepaint}from"./timers.js";const PRELOADED_IMAGES={unnamed:[],named:{}};export function preload(e){const r=[],t=new Deferred;let n;if(!isPlainObject(e)&&!isArray(e)){if(e=`${e}`,hasValue(PRELOADED_IMAGES.named[e]))return PRELOADED_IMAGES.named[e];e=[e]}return isPlainObject(e)?(n={},Object.entries(e).forEach((([e,t])=>{e=`${e}`,t=`${t}`,hasValue(PRELOADED_IMAGES.named[e])||(n[e]=new Image,n[e].src=t,r.push(n[e]))})),PRELOADED_IMAGES.named={...PRELOADED_IMAGES.named,...n}):isArray(e)&&(n=[],e.forEach((e=>{const t=new Image;t.src=`${e}`,n.push(t),r.push(t)})),PRELOADED_IMAGES.unnamed=Array.from(new Set(PRELOADED_IMAGES.unnamed.concat(n)))),t.provision=isArray(n)&&1===n.length?n[0]:n,loaded(r).then(t.resolve).catch(t.reject),t}export function loaded(e,r=!1){function t(i){const E=i.currentTarget;!r||r&&E.naturalWidth>0?(s--,s<=0&&(e.map((e=>{e.removeEventListener("load",t),e.removeEventListener("error",n)})),a.map((e=>{e.removeEventListener("load",t),e.removeEventListener("error",n)})),o.resolve(1===e.length?e[0]:e))):waitForRepaint((()=>{t(i)}))}function n(r){e.map((e=>{e.removeEventListener("load",t),e.removeEventListener("error",n)})),a.map((e=>{e.removeEventListener("load",t),e.removeEventListener("error",n)})),o.reject(r)}e=orDefault(e,[],"arr").filter((e=>"htmlimageelement"===Object.prototype.toString.call(e).slice(8,-1).toLowerCase())),r=orDefault(r,!1,"bool");const o=new Deferred,a=[];let s=e.length;return o.provision=1===e.length?e[0]:e,e.forEach((e=>{e.removeEventListener("load",t),e.addEventListener("load",t),e.removeEventListener("error",n),e.addEventListener("error",n);const r=e.src,o=e.parentNode,s=!!isElement(e.parentNode)&&"picture"===o.nodeName.toLowerCase();if(assert(!isEmpty(r),`${MODULE_NAME}:loaded | image has no src`),s||e.complete){let i;s?(window.respimage?(window.respimage({elements:[o]}),i=o.querySelector("img")):window.picturefill?(window.picturefill({elements:[o]}),i=o.querySelector("img")):i=e,i.complete?(i=new Image,i.addEventListener("load",t),i.addEventListener("error",n),i.src=r,a.push(i)):(i.removeEventListener("load",t),i.addEventListener("load",t),i.removeEventListener("error",n),i.addEventListener("error",n))):(i=new Image,i.addEventListener("load",t),i.addEventListener("error",n),i.src=r,a.push(i))}})),o} //# sourceMappingURL=images.js.map diff --git a/dist/images.js.map b/dist/images.js.map index 83082797..e6a06d07 100644 --- a/dist/images.js.map +++ b/dist/images.js.map @@ -1 +1 @@ -{"version":3,"file":"images.js","names":["MODULE_NAME","orDefault","isArray","isPlainObject","assert","isEmpty","isElement","hasValue","Deferred","waitForRepaint","PRELOADED_IMAGES","unnamed","named","preload","images","preloadedImages","deferred","newImages","Object","entries","forEach","key","value","Image","src","push","newImage","Array","from","Set","concat","provision","length","loaded","then","resolve","catch","reject","dimensionsNeeded","onLoad","e","image","currentTarget","naturalWidth","loadCount","map","removeEventListener","onError","loaderImages","error","filter","prototype","toString","call","slice","toLowerCase","addEventListener","parent","parentNode","isPicture","nodeName","complete","img","window","respimage","elements","querySelector","picturefill"],"sources":["images.js"],"mappings":"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","sourcesContent":["/*!\n * Module Images\n */\n\n/**\n * @namespace Images\n */\n\nconst MODULE_NAME = 'Images';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {orDefault, isArray, isPlainObject, assert, isEmpty, isElement, hasValue, Deferred} from './basic.js';\nimport {waitForRepaint} from './timers.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst PRELOADED_IMAGES = {\n\tunnamed : [],\n\tnamed : {}\n};\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Images:preload\n */\n\n/**\n * Preloads images by URL, so that subsequent usages are served from browser cache.\n * Images can be preloaded anonymously or with a given name. So you can either just use the url again,\n * or, to be super-sure, call the method again, with just the image name to get the preloaded image itself.\n *\n * The function returns a Deferred, which resolves, after the images have loaded, with either an array of preloaded\n * images or a single image, if only one has been defined. The Deferred contains all images newly created for\n * preloading on the provision property before the Deferred resolves.\n *\n * @param {(String|String[]|Object.)} images - a URL, an array of URLs or a plain object containing named URLs. In case the string is an already used name, the image object from the named preloaded images cache is returned.\n * @returns {Basic.Deferred|Image} either a Deferred, resolving after images are preloaded, or a requested cached image\n *\n * @memberof Images:preload\n * @alias preload\n * @example\n * preload([url1, url2, url3]).then(images => { alert(`loaded ${images.length} images`); });\n * const provisionalImage preload({name1 : url1, name2 : url2}}).provision.name1;\n * const preloadedImage = preload('name1');\n */\nexport function preload(images){\n\tconst\n\t\tpreloadedImages = [],\n\t\tdeferred = new Deferred()\n\t;\n\tlet newImages;\n\n\tif( !isPlainObject(images) && !isArray(images) ){\n\t\timages = `${images}`;\n\n\t\tif( hasValue(PRELOADED_IMAGES.named[images]) ){\n\t\t\treturn PRELOADED_IMAGES.named[images];\n\t\t} else {\n\t\t\timages = [images];\n\t\t}\n\t}\n\n\tif( isPlainObject(images) ){\n\t\tnewImages = {};\n\n\t\tObject.entries(images).forEach(([key, value]) => {\n\t\t\tkey = `${key}`;\n\t\t\tvalue = `${value}`;\n\n\t\t\tif( !hasValue(PRELOADED_IMAGES.named[key]) ){\n\t\t\t\tnewImages[key] = new Image();\n\t\t\t\tnewImages[key].src = value;\n\t\t\t\tpreloadedImages.push(newImages[key]);\n\t\t\t}\n\t\t});\n\n\t\tPRELOADED_IMAGES.named = {...PRELOADED_IMAGES.named, ...newImages};\n\t} else if( isArray(images) ){\n\t\tnewImages = [];\n\n\t\timages.forEach(value => {\n\t\t\tconst newImage = new Image();\n\t\t\tnewImage.src = `${value}`;\n\t\t\tnewImages.push(newImage);\n\t\t\tpreloadedImages.push(newImage);\n\t\t});\n\n\t\tPRELOADED_IMAGES.unnamed = Array.from(new Set(PRELOADED_IMAGES.unnamed.concat(newImages)));\n\t}\n\n\tdeferred.provision = (isArray(newImages) && (newImages.length === 1)) ? newImages[0] : newImages;\n\tloaded(preloadedImages)\n\t\t.then(deferred.resolve)\n\t\t.catch(deferred.reject)\n\t;\n\n\treturn deferred;\n}\n\n\n\n/**\n * @namespace Images:loaded\n */\n\n/**\n * Fixes problems with image \"load\" events and fires the event even in case the image is already loaded or served from\n * browser cache. So repeated calls to this method on the same loaded image will actually work.\n *\n * Also supports imgs inside picture elements, while automatically handling the polyfills respimage and picturefill if\n * present in window. Make sure to apply this method to the img _inside_ the picture and _not_ on the picture itself!\n *\n * Define \"dimensionsNeeded\" if your definition of \"loaded\" includes, that the loaded image should already have usable\n * image dimensions for layouting. Use this, if you need to do calculations based on image dimensions after load.\n * Dimensions are determined using the images \"naturalWidth\".\n *\n * The function returns a Deferred, which resolves, after the images have loaded, with either an array of loaded\n * images or a single image, if only one has been defined. The Deferred contains all initially given images on the\n * provision property before the Deferred resolves.\n *\n * @param {Image|Array} images - an image or an array of images\n * @param {?Boolean} [dimensionsNeeded=false] - tells the check if we expect the loaded image to have readable dimensions\n * @returns {Basic.Deferred} a Deferred, resolving after all given images have loaded\n *\n * @memberof Images:loaded\n * @alias loaded\n * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalWidth\n * @example\n * loaded(image).then(image => { image.classList.remove('hidden'); });\n * loaded([image1, image2, image3]).then(images => { alert(`all ${images.length} images have loaded`); })\n */\nexport function loaded(images, dimensionsNeeded=false){\n\tconst __methodName__ = 'loaded';\n\n\timages = orDefault(images, [], 'arr').filter(image => {\n\t\treturn Object.prototype.toString.call(image).slice(8, -1).toLowerCase() === 'htmlimageelement';\n\t});\n\tdimensionsNeeded = orDefault(dimensionsNeeded, false, 'bool');\n\n\tfunction onLoad(e){\n\t\tconst image = e.currentTarget;\n\t\tif( !dimensionsNeeded || (dimensionsNeeded && (image.naturalWidth > 0)) ){\n\t\t\tloadCount--;\n\t\t\tif( loadCount <= 0 ){\n\t\t\t\timages.map(image => {\n\t\t\t\t\timage.removeEventListener('load', onLoad);\n\t\t\t\t\timage.removeEventListener('error', onError);\n\t\t\t\t});\n\t\t\t\tloaderImages.map(image => {\n\t\t\t\t\timage.removeEventListener('load', onLoad);\n\t\t\t\t\timage.removeEventListener('error', onError);\n\t\t\t\t});\n\t\t\t\tdeferred.resolve((images.length === 1) ? images[0] : images);\n\t\t\t}\n\t\t} else {\n\t\t\twaitForRepaint(() => { onLoad(e); });\n\t\t}\n\t}\n\n\tfunction onError(error){\n\t\timages.map(image => {\n\t\t\timage.removeEventListener('load', onLoad);\n\t\t\timage.removeEventListener('error', onError);\n\t\t});\n\t\tloaderImages.map(image => {\n\t\t\timage.removeEventListener('load', onLoad);\n\t\t\timage.removeEventListener('error', onError);\n\t\t});\n\t\tdeferred.reject(error);\n\t}\n\n\tconst\n\t\tdeferred = new Deferred(),\n\t\tloaderImages = []\n\t;\n\tlet loadCount = images.length;\n\n\tdeferred.provision = (images.length === 1) ? images[0] : images;\n\timages.forEach(image => {\n\t\timage.removeEventListener('load', onLoad);\n\t\timage.addEventListener('load', onLoad);\n\t\timage.removeEventListener('error', onError);\n\t\timage.addEventListener('error', onError);\n\n\t\tconst\n\t\t\tsrc = image.src,\n\t\t\tparent = image.parentNode,\n\t\t\tisPicture = isElement(image.parentNode) ? (parent.nodeName.toLowerCase() === 'picture') : false\n\t\t;\n\n\t\tassert(!isEmpty(src), `${MODULE_NAME}:${__methodName__} | image has no src`);\n\n\t\tif( isPicture || !!image.complete ){\n\t\t\tlet img;\n\n\t\t\tif( isPicture ){\n\t\t\t\tif( window.respimage ){\n\t\t\t\t\twindow.respimage({elements : [parent]});\n\t\t\t\t\timg = parent.querySelector('img');\n\t\t\t\t} else if( window.picturefill ){\n\t\t\t\t\twindow.picturefill({elements : [parent]});\n\t\t\t\t\timg = parent.querySelector('img');\n\t\t\t\t} else {\n\t\t\t\t\timg = image;\n\t\t\t\t}\n\n\t\t\t\tif( !!img.complete ){\n\t\t\t\t\timg = new Image();\n\t\t\t\t\timg.addEventListener('load', onLoad);\n\t\t\t\t\timg.addEventListener('error', onError);\n\t\t\t\t\timg.src = src;\n\t\t\t\t\tloaderImages.push(img);\n\t\t\t\t} else {\n\t\t\t\t\timg.removeEventListener('load', onLoad);\n\t\t\t\t\timg.addEventListener('load', onLoad);\n\t\t\t\t\timg.removeEventListener('error', onError);\n\t\t\t\t\timg.addEventListener('error', onError);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\timg = new Image();\n\t\t\t\timg.addEventListener('load', onLoad);\n\t\t\t\timg.addEventListener('error', onError);\n\t\t\t\timg.src = src;\n\t\t\t\tloaderImages.push(img);\n\t\t\t}\n\t\t}\n\t});\n\n\treturn deferred;\n}\n"]} \ No newline at end of file +{"version":3,"file":"images.js","names":["MODULE_NAME","orDefault","isArray","isPlainObject","assert","isEmpty","isElement","hasValue","Deferred","waitForRepaint","PRELOADED_IMAGES","unnamed","named","preload","images","preloadedImages","deferred","newImages","Object","entries","forEach","key","value","Image","src","push","newImage","Array","from","Set","concat","provision","length","loaded","then","resolve","catch","reject","dimensionsNeeded","onLoad","e","image","currentTarget","naturalWidth","loadCount","map","removeEventListener","onError","loaderImages","error","filter","prototype","toString","call","slice","toLowerCase","addEventListener","parent","parentNode","isPicture","nodeName","complete","img","window","respimage","elements","querySelector","picturefill"],"sources":["images.js"],"mappings":"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","ignoreList":[],"sourcesContent":["/*!\n * Module Images\n */\n\n/**\n * @namespace Images\n */\n\nconst MODULE_NAME = 'Images';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {orDefault, isArray, isPlainObject, assert, isEmpty, isElement, hasValue, Deferred} from './basic.js';\nimport {waitForRepaint} from './timers.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst PRELOADED_IMAGES = {\n\tunnamed : [],\n\tnamed : {}\n};\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Images:preload\n */\n\n/**\n * Preloads images by URL, so that subsequent usages are served from browser cache.\n * Images can be preloaded anonymously or with a given name. So you can either just use the url again,\n * or, to be super-sure, call the method again, with just the image name to get the preloaded image itself.\n *\n * The function returns a Deferred, which resolves, after the images have loaded, with either an array of preloaded\n * images or a single image, if only one has been defined. The Deferred contains all images newly created for\n * preloading on the provision property before the Deferred resolves.\n *\n * @param {(String|String[]|Object.)} images - a URL, an array of URLs or a plain object containing named URLs. In case the string is an already used name, the image object from the named preloaded images cache is returned.\n * @returns {Basic.Deferred|Image} either a Deferred, resolving after images are preloaded, or a requested cached image\n *\n * @memberof Images:preload\n * @alias preload\n * @example\n * preload([url1, url2, url3]).then(images => { alert(`loaded ${images.length} images`); });\n * const provisionalImage preload({name1 : url1, name2 : url2}}).provision.name1;\n * const preloadedImage = preload('name1');\n */\nexport function preload(images){\n\tconst\n\t\tpreloadedImages = [],\n\t\tdeferred = new Deferred()\n\t;\n\tlet newImages;\n\n\tif( !isPlainObject(images) && !isArray(images) ){\n\t\timages = `${images}`;\n\n\t\tif( hasValue(PRELOADED_IMAGES.named[images]) ){\n\t\t\treturn PRELOADED_IMAGES.named[images];\n\t\t} else {\n\t\t\timages = [images];\n\t\t}\n\t}\n\n\tif( isPlainObject(images) ){\n\t\tnewImages = {};\n\n\t\tObject.entries(images).forEach(([key, value]) => {\n\t\t\tkey = `${key}`;\n\t\t\tvalue = `${value}`;\n\n\t\t\tif( !hasValue(PRELOADED_IMAGES.named[key]) ){\n\t\t\t\tnewImages[key] = new Image();\n\t\t\t\tnewImages[key].src = value;\n\t\t\t\tpreloadedImages.push(newImages[key]);\n\t\t\t}\n\t\t});\n\n\t\tPRELOADED_IMAGES.named = {...PRELOADED_IMAGES.named, ...newImages};\n\t} else if( isArray(images) ){\n\t\tnewImages = [];\n\n\t\timages.forEach(value => {\n\t\t\tconst newImage = new Image();\n\t\t\tnewImage.src = `${value}`;\n\t\t\tnewImages.push(newImage);\n\t\t\tpreloadedImages.push(newImage);\n\t\t});\n\n\t\tPRELOADED_IMAGES.unnamed = Array.from(new Set(PRELOADED_IMAGES.unnamed.concat(newImages)));\n\t}\n\n\tdeferred.provision = (isArray(newImages) && (newImages.length === 1)) ? newImages[0] : newImages;\n\tloaded(preloadedImages)\n\t\t.then(deferred.resolve)\n\t\t.catch(deferred.reject)\n\t;\n\n\treturn deferred;\n}\n\n\n\n/**\n * @namespace Images:loaded\n */\n\n/**\n * Fixes problems with image \"load\" events and fires the event even in case the image is already loaded or served from\n * browser cache. So repeated calls to this method on the same loaded image will actually work.\n *\n * Also supports imgs inside picture elements, while automatically handling the polyfills respimage and picturefill if\n * present in window. Make sure to apply this method to the img _inside_ the picture and _not_ on the picture itself!\n *\n * Define \"dimensionsNeeded\" if your definition of \"loaded\" includes, that the loaded image should already have usable\n * image dimensions for layouting. Use this, if you need to do calculations based on image dimensions after load.\n * Dimensions are determined using the images \"naturalWidth\".\n *\n * The function returns a Deferred, which resolves, after the images have loaded, with either an array of loaded\n * images or a single image, if only one has been defined. The Deferred contains all initially given images on the\n * provision property before the Deferred resolves.\n *\n * @param {Image|Array} images - an image or an array of images\n * @param {?Boolean} [dimensionsNeeded=false] - tells the check if we expect the loaded image to have readable dimensions\n * @returns {Basic.Deferred} a Deferred, resolving after all given images have loaded\n *\n * @memberof Images:loaded\n * @alias loaded\n * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalWidth\n * @example\n * loaded(image).then(image => { image.classList.remove('hidden'); });\n * loaded([image1, image2, image3]).then(images => { alert(`all ${images.length} images have loaded`); })\n */\nexport function loaded(images, dimensionsNeeded=false){\n\tconst __methodName__ = 'loaded';\n\n\timages = orDefault(images, [], 'arr').filter(image => {\n\t\treturn Object.prototype.toString.call(image).slice(8, -1).toLowerCase() === 'htmlimageelement';\n\t});\n\tdimensionsNeeded = orDefault(dimensionsNeeded, false, 'bool');\n\n\tfunction onLoad(e){\n\t\tconst image = e.currentTarget;\n\t\tif( !dimensionsNeeded || (dimensionsNeeded && (image.naturalWidth > 0)) ){\n\t\t\tloadCount--;\n\t\t\tif( loadCount <= 0 ){\n\t\t\t\timages.map(image => {\n\t\t\t\t\timage.removeEventListener('load', onLoad);\n\t\t\t\t\timage.removeEventListener('error', onError);\n\t\t\t\t});\n\t\t\t\tloaderImages.map(image => {\n\t\t\t\t\timage.removeEventListener('load', onLoad);\n\t\t\t\t\timage.removeEventListener('error', onError);\n\t\t\t\t});\n\t\t\t\tdeferred.resolve((images.length === 1) ? images[0] : images);\n\t\t\t}\n\t\t} else {\n\t\t\twaitForRepaint(() => { onLoad(e); });\n\t\t}\n\t}\n\n\tfunction onError(error){\n\t\timages.map(image => {\n\t\t\timage.removeEventListener('load', onLoad);\n\t\t\timage.removeEventListener('error', onError);\n\t\t});\n\t\tloaderImages.map(image => {\n\t\t\timage.removeEventListener('load', onLoad);\n\t\t\timage.removeEventListener('error', onError);\n\t\t});\n\t\tdeferred.reject(error);\n\t}\n\n\tconst\n\t\tdeferred = new Deferred(),\n\t\tloaderImages = []\n\t;\n\tlet loadCount = images.length;\n\n\tdeferred.provision = (images.length === 1) ? images[0] : images;\n\timages.forEach(image => {\n\t\timage.removeEventListener('load', onLoad);\n\t\timage.addEventListener('load', onLoad);\n\t\timage.removeEventListener('error', onError);\n\t\timage.addEventListener('error', onError);\n\n\t\tconst\n\t\t\tsrc = image.src,\n\t\t\tparent = image.parentNode,\n\t\t\tisPicture = isElement(image.parentNode) ? (parent.nodeName.toLowerCase() === 'picture') : false\n\t\t;\n\n\t\tassert(!isEmpty(src), `${MODULE_NAME}:${__methodName__} | image has no src`);\n\n\t\tif( isPicture || !!image.complete ){\n\t\t\tlet img;\n\n\t\t\tif( isPicture ){\n\t\t\t\tif( window.respimage ){\n\t\t\t\t\twindow.respimage({elements : [parent]});\n\t\t\t\t\timg = parent.querySelector('img');\n\t\t\t\t} else if( window.picturefill ){\n\t\t\t\t\twindow.picturefill({elements : [parent]});\n\t\t\t\t\timg = parent.querySelector('img');\n\t\t\t\t} else {\n\t\t\t\t\timg = image;\n\t\t\t\t}\n\n\t\t\t\tif( !!img.complete ){\n\t\t\t\t\timg = new Image();\n\t\t\t\t\timg.addEventListener('load', onLoad);\n\t\t\t\t\timg.addEventListener('error', onError);\n\t\t\t\t\timg.src = src;\n\t\t\t\t\tloaderImages.push(img);\n\t\t\t\t} else {\n\t\t\t\t\timg.removeEventListener('load', onLoad);\n\t\t\t\t\timg.addEventListener('load', onLoad);\n\t\t\t\t\timg.removeEventListener('error', onError);\n\t\t\t\t\timg.addEventListener('error', onError);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\timg = new Image();\n\t\t\t\timg.addEventListener('load', onLoad);\n\t\t\t\timg.addEventListener('error', onError);\n\t\t\t\timg.src = src;\n\t\t\t\tloaderImages.push(img);\n\t\t\t}\n\t\t}\n\t});\n\n\treturn deferred;\n}\n"]} \ No newline at end of file diff --git a/dist/interaction.js b/dist/interaction.js index a53d3c89..c7c2b659 100644 --- a/dist/interaction.js +++ b/dist/interaction.js @@ -1,5 +1,5 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Interaction diff --git a/dist/interaction.js.map b/dist/interaction.js.map index c2d9b826..5baae809 100644 --- a/dist/interaction.js.map +++ b/dist/interaction.js.map @@ -1 +1 @@ -{"version":3,"file":"interaction.js","names":["MODULE_NAME","assert","isFunction","isElement","orDefault","hasValue","Deferred","findTextNodes","applyStyles","TAPPABLE_ELEMENTS_SELECTOR","NOT_AN_HTMLELEMENT_ERROR","createSelection","node","startOffset","endOffset","selectionText","range","selection","rangeText","selectionStart","selectionEnd","focus","select","value","length","substring","window","getSelection","document","createRange","selectNodeContents","textNodes","startNodeIndex","startNode","endNodeIndex","endNode","remainingStartOffset","startOffsetNodeFound","setStart","remainingEndOffset","endOffsetNodeFound","setEnd","removeAllRanges","addRange","toString","body","createTextRange","moveToElementText","moveStart","moveEnd","text","removeSelections","empty","disableSelection","onselectstart","unselectable","enableSelection","undefined","obfuscatePrivateMailToLink","link","setAsContent","tld","afterAtWithoutTld","beforeAt","subject","ccTld","ccAfterAtWithoutTld","ccBeforeAt","optionParams","URLSearchParams","set","replaceAll","interactionCount","fAddLinkUrl","setAttribute","addEventListener","fRemoveLinkUrl","innerHTML","replace","obfuscatePrivateTelLink","secondTelPart","firstTelPart","regionPart","countryPart","setTappedState","element","tappedClass","tappedDuration","deferred","classList","add","setTimeout","remove","blur","resolve","setupAutoTappedStates","tappableElementsSelector","tapEvents","concat","forEach","tapEvent","e","target","matches"],"sources":["interaction.js"],"mappings":"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","sourcesContent":["/*!\n * Module Interaction\n */\n\n/**\n * @namespace Interaction\n */\n\nconst MODULE_NAME = 'Interaction';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {assert, isFunction, isElement, orDefault, hasValue, Deferred} from './basic.js';\nimport {findTextNodes} from './elements.js';\nimport {applyStyles} from './css.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const TAPPABLE_ELEMENTS_SELECTOR = 'a, button, .button, input[type=button], input[type=submit]';\nconst NOT_AN_HTMLELEMENT_ERROR = 'given node/target is not an HTMLElement';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Interaction:createSelection\n */\n\n/**\n * Programmatically create a text selection inside a node, possibly reaching across several child nodes,\n * but virtually only working with the raw text content. Can also be used to create a selection in text\n * inputs for example.\n *\n * Be aware that the endOffset is neither the length to select nor the last index, but the offset starting\n * from the last character in the node counting backwards (like a reverse startOffset). The reason for this wonkyness\n * is the fact that we have to implement three different ways of creating selections in this function, this\n * notation being the most compatible one. We assume the default use case for this method is to select all content\n * of a node with the possibility to skip one or two unwanted characters on each side of the content.\n *\n * Hint: You cannot create a selection spanning normal inline text into an input, ending there. To create a selection in\n * a text input, please target that element specifically or make sure the selection spans the whole input.\n * Furthermore, on mobile/iOS devices creation of selection ranges might only be possible in text inputs.\n *\n * @param {HTMLElement} node - the element to create a selection inside\n * @param {?Number} [startOffset=0] - characters to leave out at the beginning of the text content\n * @param {?Number} [endOffset=0] - characters to leave out at the end of the text content\n * @return {String} the selected text\n *\n * @memberof Interaction:createSelection\n * @alias createSelection\n * @see removeSelections\n * @example\n * const selectedText = createSelection(copytextElement, 12, 6);\n */\nexport function createSelection(node, startOffset=0, endOffset=0){\n\tconst __methodName__ = 'createSelection';\n\n\tstartOffset = orDefault(startOffset, 0, 'int');\n\tendOffset = orDefault(endOffset, 0, 'int');\n\n\tassert(isElement(node), `${MODULE_NAME}:${__methodName__} | ${NOT_AN_HTMLELEMENT_ERROR}`);\n\n\tlet\tselectionText, range, selection, rangeText;\n\n\tif( hasValue(node.selectionStart, node.selectionEnd) ){\n\t\tnode.focus();\n\t\tnode.select();\n\t\trangeText = node.value;\n\t\tnode.selectionStart = startOffset;\n\t\tnode.selectionEnd = rangeText.length - endOffset;\n\t\tselectionText = rangeText.substring(node.selectionStart, node.selectionEnd);\n\t} else if( isFunction(window.getSelection) ){\n\t\trange = document.createRange();\n\t\trange.selectNodeContents(node);\n\n\t\tif( hasValue(startOffset) || hasValue(endOffset) ){\n\t\t\tconst textNodes = findTextNodes(node);\n\t\t\tif( textNodes.length > 0 ){\n\t\t\t\tlet\n\t\t\t\t\tstartNodeIndex = 0,\n\t\t\t\t\tstartNode = textNodes[startNodeIndex],\n\t\t\t\t\tendNodeIndex = textNodes.length - 1,\n\t\t\t\t\tendNode = textNodes[endNodeIndex]\n\t\t\t\t;\n\n\t\t\t\tif( hasValue(startOffset) ){\n\t\t\t\t\tlet\n\t\t\t\t\t\tremainingStartOffset = startOffset,\n\t\t\t\t\t\tstartOffsetNodeFound = (remainingStartOffset <= startNode.length)\n\t\t\t\t\t;\n\n\t\t\t\t\twhile( !startOffsetNodeFound && hasValue(startNode) ){\n\t\t\t\t\t\tstartNodeIndex++;\n\t\t\t\t\t\tif( hasValue(textNodes[startNodeIndex]) ){\n\t\t\t\t\t\t\tremainingStartOffset -= startNode.length;\n\t\t\t\t\t\t\tstartNode = textNodes[startNodeIndex];\n\t\t\t\t\t\t\tstartOffsetNodeFound = (remainingStartOffset <= startNode.length);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tremainingStartOffset = startNode.length;\n\t\t\t\t\t\t\tstartOffsetNodeFound = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\trange.setStart(startNode, remainingStartOffset);\n\t\t\t\t}\n\n\t\t\t\tif( hasValue(endOffset) ){\n\t\t\t\t\tlet\n\t\t\t\t\t\tremainingEndOffset = endOffset,\n\t\t\t\t\t\tendOffsetNodeFound = (remainingEndOffset <= endNode.length)\n\t\t\t\t\t;\n\n\t\t\t\t\twhile( !endOffsetNodeFound && hasValue(endNode) ){\n\t\t\t\t\t\tendNodeIndex--;\n\t\t\t\t\t\tif( hasValue(textNodes[endNodeIndex]) ){\n\t\t\t\t\t\t\tremainingEndOffset -= endNode.length;\n\t\t\t\t\t\t\tendNode = textNodes[endNodeIndex];\n\t\t\t\t\t\t\tendOffsetNodeFound = (remainingEndOffset <= endNode.length);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tremainingEndOffset = endNode.length;\n\t\t\t\t\t\t\tendOffsetNodeFound = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\trange.setEnd(endNode, endNode.length - remainingEndOffset);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tselection = window.getSelection();\n\t\tselection.removeAllRanges();\n\t\tselection.addRange(range);\n\t\tselectionText = range.toString();\n\t} else if( isFunction(document.body.createTextRange) ){\n\t\trange = document.body.createTextRange();\n\t\trange.moveToElementText(node);\n\n\t\tif( hasValue(startOffset) ){\n\t\t\trange.moveStart('character', startOffset);\n\t\t}\n\n\t\tif( hasValue(endOffset) ){\n\t\t\trange.moveEnd('character', -endOffset);\n\t\t}\n\n\t\trange.select();\n\n\t\tselectionText = range.text;\n\t}\n\n\treturn selectionText;\n}\n\n\n\n/**\n * @namespace Interaction:removeSelections\n */\n\n/**\n * Removes all text selections from the current window if possible.\n * Certain mobile devices like iOS devices might block this behaviour actively.\n *\n * @memberof Interaction:removeSelections\n * @alias removeSelections\n * @see createSelection\n * @example\n * removeSelections();\n */\nexport function removeSelections(){\n\tif( isFunction(window.getSelection) ){\n\t\twindow.getSelection().removeAllRanges();\n\t} else if( isFunction(document.getSelection) ){\n\t\tdocument.getSelection().removeAllRanges();\n\t}\n\n\tif( hasValue(document.selection) ){\n\t\tdocument.selection.empty();\n\t}\n}\n\n\n\n/**\n * @namespace Interaction:disableSelection\n */\n\n/**\n * Disables the possibility to create a selection in an element.\n *\n * @param {HTMLElement} node - the element to disable user selection for\n * @return {HTMLElement} the node with disabled selection\n *\n * @memberof Interaction:disableSelection\n * @alias disableSelection\n * @see enableSelection\n * @example\n * disableSelection(widget);\n */\nexport function disableSelection(node){\n\tconst __methodName__ = 'disableSelection';\n\n\tassert(isElement(node), `${MODULE_NAME}:${__methodName__} | ${NOT_AN_HTMLELEMENT_ERROR}`);\n\n\tnode.onselectstart = () => false;\n\tnode.unselectable = 'on';\n\tapplyStyles(node, {'user-select' : 'none'}, true);\n\tapplyStyles(node, {'-webkit-touch-callout' : 'none'});\n\n\treturn node;\n}\n\n\n\n/**\n * @namespace Interaction:enableSelection\n */\n\n/**\n * (Re)enables the possibility to create a selection in an element. Most likely after having been disabled\n * using `disableSelection`.\n *\n * @param {HTMLElement} node - the element to (re)enable user selection for\n * @return {HTMLElement} the node with (re)enabled selection\n *\n * @memberof Interaction:enableSelection\n * @alias enableSelection\n * @see disableSelection\n * @example\n * enableSelection(widget);\n */\nexport function enableSelection(node){\n\tconst __methodName__ = 'disableSelection';\n\n\tassert(isElement(node), `${MODULE_NAME}:${__methodName__} | ${NOT_AN_HTMLELEMENT_ERROR}`);\n\n\tnode.onselectstart = undefined;\n\tnode.unselectable = 'off';\n\tapplyStyles(node, {'user-select' : null}, true);\n\tapplyStyles(node, {'-webkit-touch-callout' : null});\n\n\treturn node;\n}\n\n\n\n/**\n * @namespace Interaction:obfuscatePrivateMailToLink\n */\n\n/**\n * Augment a link element to hold an obfuscated private mailto link, to be able to contact people\n * via their own mail address, without the need to openly write the address into the DOM permanently,\n * in a way crawlers could identify easily.\n *\n * The method takes all parts of the address as (hopefully) unidentifiable parameters and then applies them internally,\n * to build an email string with mailto protocol dynamically on mouse or focus interaction in the link's href,\n * offering normal link functionality from here on. If the interaction ends, the href is removed again immediately,\n * so the link is only and exclusively readable and complete during user interaction.\n *\n * You may set the link text yourself or set `setAsContent` to true, to let the function fill the link text with\n * the completed address. Be aware, that this, although still being obfuscated, lowers the level of security for this\n * solution.\n *\n * Although most parameters are technically optional, this function still expects `beforeAt` and `afterAtWithoutTld` to\n * be filled. While these parts are strictly necessary here: I'd always suggest to use all parts, since, the more\n * of an address is written together, the easier the address can be parsed.\n *\n * @param {HTMLElement} link - the link to augment, has to be a node where we can set a \"href\" attribute\n * @param {?Boolean} [setAsContent=false] - define if the address should be used as link text (still uses string obfuscation, but weaker against bot with JS execution)\n * @param {?String} [tld=''] - the top level domain to use\n * @param {?String} [afterAtWithoutTld=''] - the address part after the @ but before the tld\n * @param {?String} [beforeAt=''] - the address part before the @\n * @param {?String} [subject=''] - the subject the mail should have, if you want to preset this\n * @param {?String} [body=''] - the body text the mail should have initially, if you want to preset this\n * @param {?String} [ccTld=''] - the top level domain to use for the cc address\n * @param {?String} [ccAfterAtWithoutTld=''] - the address part after the @ but before the tld for the cc address\n * @param {?String} [ccBeforeAt=''] - the address part before the @ for the cc address\n * @throws error if beforeAt or afterAtWithoutTld are empty\n * @return {HTMLElement} the augmented link\n *\n * @memberof Interaction:obfuscatePrivateMailToLink\n * @alias obfuscatePrivateMailToLink\n * @example\n * obfuscatePrivateMailToLink(document.querySelector('a'), true, 'de', 'gmail', 'recipient', 'Hello there!', 'How are you these days?');\n */\nexport function obfuscatePrivateMailToLink(\n\tlink,\n\tsetAsContent=false,\n\ttld='',\n\tafterAtWithoutTld='',\n\tbeforeAt='',\n\tsubject='',\n\tbody='',\n\tccTld='',\n\tccAfterAtWithoutTld='',\n\tccBeforeAt=''\n){\n\tconst __methodName__ = 'obfuscatePrivateMailToLink';\n\n\tsetAsContent = orDefault(setAsContent, false, 'bool');\n\tsubject = orDefault(subject, '', 'str');\n\tbody = orDefault(body, '', 'str');\n\tbeforeAt = orDefault(beforeAt, '', 'str');\n\tafterAtWithoutTld = orDefault(afterAtWithoutTld, '', 'str');\n\ttld = orDefault(tld, '', 'str');\n\tccBeforeAt = orDefault(ccBeforeAt, '', 'str');\n\tccAfterAtWithoutTld = orDefault(ccAfterAtWithoutTld, '', 'str');\n\tccTld = orDefault(ccTld, '', 'str');\n\n\tassert((beforeAt !== '') && (afterAtWithoutTld !== ''), `${MODULE_NAME}:${__methodName__} | basic mail parts missing`);\n\n\tif( tld !== '' ){\n\t\ttld = `.${tld}`;\n\t}\n\n\tif( ccTld !== '' ){\n\t\tccTld = `.${ccTld}`;\n\t}\n\n\tlet optionParams = new URLSearchParams();\n\tif( subject !== '' ){\n\t\toptionParams.set('subject', subject);\n\t}\n\tif( body !== '' ){\n\t\toptionParams.set('body', body);\n\t}\n\tif( (ccBeforeAt !== '') && (ccAfterAtWithoutTld !== '') ){\n\t\toptionParams.set('cc', `${ccBeforeAt}@${ccAfterAtWithoutTld}${ccTld}`);\n\t}\n\toptionParams = optionParams.toString();\n\tif( optionParams !== '' ){\n\t\toptionParams = `?${optionParams.replaceAll('+', '%20')}`;\n\t}\n\n\tlet interactionCount = 0;\n\tconst fAddLinkUrl = () => {\n\t\tinteractionCount++;\n\t\tlink.setAttribute('href', `mailto:${beforeAt}@${afterAtWithoutTld}${tld}${optionParams}`);\n\t};\n\tlink.addEventListener('mouseenter', fAddLinkUrl);\n\tlink.addEventListener('focusin', fAddLinkUrl);\n\tconst fRemoveLinkUrl = () => {\n\t\tinteractionCount--;\n\t\tif( interactionCount <= 0 ){\n\t\t\tlink.setAttribute('href', '');\n\t\t}\n\t};\n\tlink.addEventListener('mouseleave', fRemoveLinkUrl);\n\tlink.addEventListener('focusout', fRemoveLinkUrl);\n\n\tif( setAsContent ){\n\t\tlink.innerHTML = (`${beforeAt}@${afterAtWithoutTld}${tld}`).replace(/(\\w{1})/g, '$1‌');\n\t}\n\n\treturn link;\n}\n\n\n\n/**\n * @namespace Interaction:obfuscatePrivateTelLink\n */\n\n/**\n * Augment a link element to hold an obfuscated private tel link, to be able to contact people\n * via their own phone number, without the need to openly write the number into the DOM permanently,\n * in a way crawlers could identify easily.\n *\n * The method takes all parts of the number as (hopefully) unidentifiable parameters and then applies them internally,\n * to build a number string with tel protocol dynamically on mouse or focus interaction in the link's href,\n * offering normal link functionality from here on. If the interaction ends, the href is removed again immediately,\n * so the link is only and exclusively readable and complete during user interaction.\n *\n * You may set the link text yourself or set `setAsContent` to true, to let the function fill the link text with\n * the completed address. Be aware, that this, although still being obfuscated, lowers the level of security for this\n * solution.\n *\n * Although most parameters are technically optional, this function still expects `secondTelPart` or `firstTelPart` to\n * be filled. While only one part is strictly necessary here: I'd always suggest to use all parts, since, the more\n * of a number is written together, the easier the number can be parsed.\n *\n * @param {HTMLElement} link - the link to augment, has to be a node where we can set a \"href\" attribute\n * @param {?Boolean} [setAsContent=false] - define if the number should be used as link text, being formatted according to DIN 5008 (still uses string obfuscation, but weaker against bot with JS execution)\n * @param {?Number|String} [secondTelPart=''] - second half of the main number +49 04 123(4-56)<-this; add a dash to signify where a base number ends and the personal part starts\n * @param {?Number|String} [firstTelPart=''] - first half of the main number +49 04 (123)<-this 4-56\n * @param {?Number|String} [regionPart=''] - the local part of the number after the country part e.g. +49(04)<-this 1234-56\n * @param {?Number|String} [countryPart=''] - the country identifier with or without + this->(+49) 04 1234-56 (do not prefix with a local 0!)\n * @throws error if `secondTelPart` and `firstTelPart` are empty\n * @return {HTMLElement} the augmented link\n *\n * @memberof Interaction:obfuscatePrivateTelLink\n * @alias obfuscatePrivateTelLink\n * @example\n * obfuscatePrivateTelLink(document.querySelector('a'), true, 123, 439, 40, '+49');\n */\nexport function obfuscatePrivateTelLink(\n\tlink,\n\tsetAsContent=false,\n\tsecondTelPart='',\n\tfirstTelPart='',\n\tregionPart='',\n\tcountryPart=''\n){\n\tconst __methodName__ = 'obfuscatePrivateTelLink';\n\n\tsetAsContent = orDefault(setAsContent, false, 'bool');\n\tsecondTelPart = orDefault(secondTelPart, '', 'str').replace(/[^0-9\\-]/g, '');\n\tfirstTelPart = orDefault(firstTelPart, '', 'str').replace(/[^0-9\\-]/g, '');\n\tregionPart = orDefault(regionPart, '', 'str').replace(/[^0-9]/g, '');\n\tcountryPart = orDefault(countryPart, '', 'str').replace(/[^0-9]/g, '');\n\n\tassert((firstTelPart !== '') || (secondTelPart !== ''), `${MODULE_NAME}:${__methodName__} | basic tel parts missing`);\n\n\tlet interactionCount = 0;\n\tconst fAddLinkUrl = () => {\n\t\tinteractionCount++;\n\t\tlink.setAttribute('href', `tel:+${countryPart}${regionPart}${firstTelPart.replace(/-/g, '')}${secondTelPart.replace(/-/g, '')}`);\n\t};\n\tlink.addEventListener('mouseenter', fAddLinkUrl);\n\tlink.addEventListener('focusin', fAddLinkUrl);\n\tconst fRemoveLinkUrl = () => {\n\t\tinteractionCount--;\n\t\tif( interactionCount <= 0 ){\n\t\t\tlink.setAttribute('href', '');\n\t\t}\n\t};\n\tlink.addEventListener('mouseleave', fRemoveLinkUrl);\n\tlink.addEventListener('focusout', fRemoveLinkUrl);\n\n\tif( setAsContent ){\n\t\tlink.innerHTML = (`+${countryPart} ${regionPart} ${firstTelPart}${secondTelPart}`).replace(/(\\w{1})/g, '$1‌');\n\t}\n}\n\n\n\n/**\n * @namespace Interaction:setTappedState\n */\n\n/**\n * Sets a \"tapped\" state on an element (via a CSS class), which removes itself again after a short time.\n *\n * The sole reason for doing this, is to be able to apply styling to a tap/click action across devices without\n * trailing styles, which would result by using something like `:focus`.\n *\n * @param {HTMLElement} element - the link to augment, has to be a node where we can set a \"href\" attribute\n * @param {?String} [tappedClass='tapped'] - the CSS class to set on the element to signify the \"tapped\" state\n * @param {?Number} [tappedDuration=200] - the duration in milliseconds, the \"tapped\" state should last\n * @throws error if element is not an HTMLElement\n * @return {Basic.Deferred} resolves with the element, when the tapped state ends\n *\n * @memberof Interaction:setTappedState\n * @alias setTappedState\n * @example\n * setTappedState(link);\n * setTappedState(link, 'clicked', 500);\n */\nexport function setTappedState(element, tappedClass='tapped', tappedDuration=200){\n\tconst __methodName__ = 'setTappedState';\n\n\ttappedClass = orDefault(tappedClass, 'tapped', 'str');\n\ttappedDuration = orDefault(tappedDuration, 200, 'int');\n\n\tassert(isElement(element), `${MODULE_NAME}:${__methodName__} | ${NOT_AN_HTMLELEMENT_ERROR}`);\n\n\tconst deferred = new Deferred();\n\n\telement.classList.add(tappedClass);\n\twindow.setTimeout(() =>{\n\t\telement.classList.remove(tappedClass);\n\t\telement.blur();\n\t\tdeferred.resolve(element);\n\t}, tappedDuration);\n\n\treturn deferred;\n}\n\n\n\n/**\n * @namespace Interaction:setupAutoTappedStates\n */\n\n/**\n * This function registers a global event handler on the document body, to automatically add \"tapped\" states (as a CSS\n * class) to \"tappable\" elements on \"tap\".\n *\n * What is a \"tap\" you ask? Well, it's either a pointer click or a finger touch or anything resembling these actions\n * on your current device.\n *\n * The idea behind that is this: usually, on pointer devices, we have a `:hover` state to signify user interaction\n * with an element, while on touch devices, we only know that an interaction took place after a user touched an element\n * with his/her finger, \"tapped\" it so to speak. Styling a touch with CSS would only be possible via `:focus`, which\n * has the problems, that focus has a different meaning on pointer devices and the focus state does not end\n * automatically, resulting in trailing visual states.\n *\n * So, what we do instead, is that we just generally observe taps (via \"click\" event, which works across devices as\n * expected) and set a class on the element, for a short time, which removes itself automatically again, to be able\n * to define a visual state or a short animation for that class. So, for example, let's say the function has been\n * executed. After that, you can define something like `a.tapped { color: orange; }`, which would result in orange\n * coloring for a short time, after clicking/touching the element. Combine this with `:hover`, `:focus` definitions\n * in CSS to define a complete effect setup.\n *\n * @param {?HTMLElement} [element=document.body] - the element to use as delegation parent for events, should contain the tappable elements you'd like to target\n * @param {?String} [tappableElementsSelector='a, button, .button, input[type=button], input[type=submit]'] - selector to identify a tappable element by in a delegated event handler\n * @param {?String|Array} [tapEvents='click'] - the DOM event(s) to register for taps\n * @param {?String} [tappedClass='tapped'] - the CSS class to set on the element to signify the \"tapped\" state\n * @param {?Number} [tappedDuration=200] - the duration in milliseconds, the \"tapped\" state should last\n * @throws error if element is not an HTMLElement\n *\n * @memberof Interaction:setupAutoTappedStates\n * @alias setupAutoTappedStates\n * @example\n * setupAutoTappedStates();\n * setupAutoTappedStates(document.body, 'a, button', 'customevent');\n */\nexport function setupAutoTappedStates(\n\telement=null,\n\ttappableElementsSelector=TAPPABLE_ELEMENTS_SELECTOR,\n\ttapEvents='click',\n\ttappedClass='tapped',\n\ttappedDuration=200\n){\n\tconst __methodName__ = 'setupAutoTappedStates';\n\n\t// document.body not in function default to prevent errors on import in document-less contexts\n\telement = orDefault(element, document.body);\n\ttappableElementsSelector = orDefault(tappableElementsSelector, TAPPABLE_ELEMENTS_SELECTOR, 'str');\n\ttapEvents = orDefault(tapEvents, 'click', 'str');\n\ttapEvents = [].concat(tapEvents);\n\n\tassert(isElement(element), `${MODULE_NAME}:${__methodName__} | ${NOT_AN_HTMLELEMENT_ERROR}`);\n\n\ttapEvents.forEach(tapEvent => {\n\t\telement.addEventListener(tapEvent, e => {\n\t\t\tif(\n\t\t\t\thasValue(e.target?.matches)\n\t\t\t\t&& e.target.matches(tappableElementsSelector)\n\t\t\t){\n\t\t\t\tsetTappedState(e.target, tappedClass, tappedDuration);\n\t\t\t}\n\t\t});\n\t});\n}\n"]} \ No newline at end of file +{"version":3,"file":"interaction.js","names":["MODULE_NAME","assert","isFunction","isElement","orDefault","hasValue","Deferred","findTextNodes","applyStyles","TAPPABLE_ELEMENTS_SELECTOR","NOT_AN_HTMLELEMENT_ERROR","createSelection","node","startOffset","endOffset","selectionText","range","selection","rangeText","selectionStart","selectionEnd","focus","select","value","length","substring","window","getSelection","document","createRange","selectNodeContents","textNodes","startNodeIndex","startNode","endNodeIndex","endNode","remainingStartOffset","startOffsetNodeFound","setStart","remainingEndOffset","endOffsetNodeFound","setEnd","removeAllRanges","addRange","toString","body","createTextRange","moveToElementText","moveStart","moveEnd","text","removeSelections","empty","disableSelection","onselectstart","unselectable","enableSelection","undefined","obfuscatePrivateMailToLink","link","setAsContent","tld","afterAtWithoutTld","beforeAt","subject","ccTld","ccAfterAtWithoutTld","ccBeforeAt","optionParams","URLSearchParams","set","replaceAll","interactionCount","fAddLinkUrl","setAttribute","addEventListener","fRemoveLinkUrl","innerHTML","replace","obfuscatePrivateTelLink","secondTelPart","firstTelPart","regionPart","countryPart","setTappedState","element","tappedClass","tappedDuration","deferred","classList","add","setTimeout","remove","blur","resolve","setupAutoTappedStates","tappableElementsSelector","tapEvents","concat","forEach","tapEvent","e","target","matches"],"sources":["interaction.js"],"mappings":"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","ignoreList":[],"sourcesContent":["/*!\n * Module Interaction\n */\n\n/**\n * @namespace Interaction\n */\n\nconst MODULE_NAME = 'Interaction';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {assert, isFunction, isElement, orDefault, hasValue, Deferred} from './basic.js';\nimport {findTextNodes} from './elements.js';\nimport {applyStyles} from './css.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const TAPPABLE_ELEMENTS_SELECTOR = 'a, button, .button, input[type=button], input[type=submit]';\nconst NOT_AN_HTMLELEMENT_ERROR = 'given node/target is not an HTMLElement';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Interaction:createSelection\n */\n\n/**\n * Programmatically create a text selection inside a node, possibly reaching across several child nodes,\n * but virtually only working with the raw text content. Can also be used to create a selection in text\n * inputs for example.\n *\n * Be aware that the endOffset is neither the length to select nor the last index, but the offset starting\n * from the last character in the node counting backwards (like a reverse startOffset). The reason for this wonkyness\n * is the fact that we have to implement three different ways of creating selections in this function, this\n * notation being the most compatible one. We assume the default use case for this method is to select all content\n * of a node with the possibility to skip one or two unwanted characters on each side of the content.\n *\n * Hint: You cannot create a selection spanning normal inline text into an input, ending there. To create a selection in\n * a text input, please target that element specifically or make sure the selection spans the whole input.\n * Furthermore, on mobile/iOS devices creation of selection ranges might only be possible in text inputs.\n *\n * @param {HTMLElement} node - the element to create a selection inside\n * @param {?Number} [startOffset=0] - characters to leave out at the beginning of the text content\n * @param {?Number} [endOffset=0] - characters to leave out at the end of the text content\n * @return {String} the selected text\n *\n * @memberof Interaction:createSelection\n * @alias createSelection\n * @see removeSelections\n * @example\n * const selectedText = createSelection(copytextElement, 12, 6);\n */\nexport function createSelection(node, startOffset=0, endOffset=0){\n\tconst __methodName__ = 'createSelection';\n\n\tstartOffset = orDefault(startOffset, 0, 'int');\n\tendOffset = orDefault(endOffset, 0, 'int');\n\n\tassert(isElement(node), `${MODULE_NAME}:${__methodName__} | ${NOT_AN_HTMLELEMENT_ERROR}`);\n\n\tlet\tselectionText, range, selection, rangeText;\n\n\tif( hasValue(node.selectionStart, node.selectionEnd) ){\n\t\tnode.focus();\n\t\tnode.select();\n\t\trangeText = node.value;\n\t\tnode.selectionStart = startOffset;\n\t\tnode.selectionEnd = rangeText.length - endOffset;\n\t\tselectionText = rangeText.substring(node.selectionStart, node.selectionEnd);\n\t} else if( isFunction(window.getSelection) ){\n\t\trange = document.createRange();\n\t\trange.selectNodeContents(node);\n\n\t\tif( hasValue(startOffset) || hasValue(endOffset) ){\n\t\t\tconst textNodes = findTextNodes(node);\n\t\t\tif( textNodes.length > 0 ){\n\t\t\t\tlet\n\t\t\t\t\tstartNodeIndex = 0,\n\t\t\t\t\tstartNode = textNodes[startNodeIndex],\n\t\t\t\t\tendNodeIndex = textNodes.length - 1,\n\t\t\t\t\tendNode = textNodes[endNodeIndex]\n\t\t\t\t;\n\n\t\t\t\tif( hasValue(startOffset) ){\n\t\t\t\t\tlet\n\t\t\t\t\t\tremainingStartOffset = startOffset,\n\t\t\t\t\t\tstartOffsetNodeFound = (remainingStartOffset <= startNode.length)\n\t\t\t\t\t;\n\n\t\t\t\t\twhile( !startOffsetNodeFound && hasValue(startNode) ){\n\t\t\t\t\t\tstartNodeIndex++;\n\t\t\t\t\t\tif( hasValue(textNodes[startNodeIndex]) ){\n\t\t\t\t\t\t\tremainingStartOffset -= startNode.length;\n\t\t\t\t\t\t\tstartNode = textNodes[startNodeIndex];\n\t\t\t\t\t\t\tstartOffsetNodeFound = (remainingStartOffset <= startNode.length);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tremainingStartOffset = startNode.length;\n\t\t\t\t\t\t\tstartOffsetNodeFound = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\trange.setStart(startNode, remainingStartOffset);\n\t\t\t\t}\n\n\t\t\t\tif( hasValue(endOffset) ){\n\t\t\t\t\tlet\n\t\t\t\t\t\tremainingEndOffset = endOffset,\n\t\t\t\t\t\tendOffsetNodeFound = (remainingEndOffset <= endNode.length)\n\t\t\t\t\t;\n\n\t\t\t\t\twhile( !endOffsetNodeFound && hasValue(endNode) ){\n\t\t\t\t\t\tendNodeIndex--;\n\t\t\t\t\t\tif( hasValue(textNodes[endNodeIndex]) ){\n\t\t\t\t\t\t\tremainingEndOffset -= endNode.length;\n\t\t\t\t\t\t\tendNode = textNodes[endNodeIndex];\n\t\t\t\t\t\t\tendOffsetNodeFound = (remainingEndOffset <= endNode.length);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tremainingEndOffset = endNode.length;\n\t\t\t\t\t\t\tendOffsetNodeFound = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\trange.setEnd(endNode, endNode.length - remainingEndOffset);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tselection = window.getSelection();\n\t\tselection.removeAllRanges();\n\t\tselection.addRange(range);\n\t\tselectionText = range.toString();\n\t} else if( isFunction(document.body.createTextRange) ){\n\t\trange = document.body.createTextRange();\n\t\trange.moveToElementText(node);\n\n\t\tif( hasValue(startOffset) ){\n\t\t\trange.moveStart('character', startOffset);\n\t\t}\n\n\t\tif( hasValue(endOffset) ){\n\t\t\trange.moveEnd('character', -endOffset);\n\t\t}\n\n\t\trange.select();\n\n\t\tselectionText = range.text;\n\t}\n\n\treturn selectionText;\n}\n\n\n\n/**\n * @namespace Interaction:removeSelections\n */\n\n/**\n * Removes all text selections from the current window if possible.\n * Certain mobile devices like iOS devices might block this behaviour actively.\n *\n * @memberof Interaction:removeSelections\n * @alias removeSelections\n * @see createSelection\n * @example\n * removeSelections();\n */\nexport function removeSelections(){\n\tif( isFunction(window.getSelection) ){\n\t\twindow.getSelection().removeAllRanges();\n\t} else if( isFunction(document.getSelection) ){\n\t\tdocument.getSelection().removeAllRanges();\n\t}\n\n\tif( hasValue(document.selection) ){\n\t\tdocument.selection.empty();\n\t}\n}\n\n\n\n/**\n * @namespace Interaction:disableSelection\n */\n\n/**\n * Disables the possibility to create a selection in an element.\n *\n * @param {HTMLElement} node - the element to disable user selection for\n * @return {HTMLElement} the node with disabled selection\n *\n * @memberof Interaction:disableSelection\n * @alias disableSelection\n * @see enableSelection\n * @example\n * disableSelection(widget);\n */\nexport function disableSelection(node){\n\tconst __methodName__ = 'disableSelection';\n\n\tassert(isElement(node), `${MODULE_NAME}:${__methodName__} | ${NOT_AN_HTMLELEMENT_ERROR}`);\n\n\tnode.onselectstart = () => false;\n\tnode.unselectable = 'on';\n\tapplyStyles(node, {'user-select' : 'none'}, true);\n\tapplyStyles(node, {'-webkit-touch-callout' : 'none'});\n\n\treturn node;\n}\n\n\n\n/**\n * @namespace Interaction:enableSelection\n */\n\n/**\n * (Re)enables the possibility to create a selection in an element. Most likely after having been disabled\n * using `disableSelection`.\n *\n * @param {HTMLElement} node - the element to (re)enable user selection for\n * @return {HTMLElement} the node with (re)enabled selection\n *\n * @memberof Interaction:enableSelection\n * @alias enableSelection\n * @see disableSelection\n * @example\n * enableSelection(widget);\n */\nexport function enableSelection(node){\n\tconst __methodName__ = 'disableSelection';\n\n\tassert(isElement(node), `${MODULE_NAME}:${__methodName__} | ${NOT_AN_HTMLELEMENT_ERROR}`);\n\n\tnode.onselectstart = undefined;\n\tnode.unselectable = 'off';\n\tapplyStyles(node, {'user-select' : null}, true);\n\tapplyStyles(node, {'-webkit-touch-callout' : null});\n\n\treturn node;\n}\n\n\n\n/**\n * @namespace Interaction:obfuscatePrivateMailToLink\n */\n\n/**\n * Augment a link element to hold an obfuscated private mailto link, to be able to contact people\n * via their own mail address, without the need to openly write the address into the DOM permanently,\n * in a way crawlers could identify easily.\n *\n * The method takes all parts of the address as (hopefully) unidentifiable parameters and then applies them internally,\n * to build an email string with mailto protocol dynamically on mouse or focus interaction in the link's href,\n * offering normal link functionality from here on. If the interaction ends, the href is removed again immediately,\n * so the link is only and exclusively readable and complete during user interaction.\n *\n * You may set the link text yourself or set `setAsContent` to true, to let the function fill the link text with\n * the completed address. Be aware, that this, although still being obfuscated, lowers the level of security for this\n * solution.\n *\n * Although most parameters are technically optional, this function still expects `beforeAt` and `afterAtWithoutTld` to\n * be filled. While these parts are strictly necessary here: I'd always suggest to use all parts, since, the more\n * of an address is written together, the easier the address can be parsed.\n *\n * @param {HTMLElement} link - the link to augment, has to be a node where we can set a \"href\" attribute\n * @param {?Boolean} [setAsContent=false] - define if the address should be used as link text (still uses string obfuscation, but weaker against bot with JS execution)\n * @param {?String} [tld=''] - the top level domain to use\n * @param {?String} [afterAtWithoutTld=''] - the address part after the @ but before the tld\n * @param {?String} [beforeAt=''] - the address part before the @\n * @param {?String} [subject=''] - the subject the mail should have, if you want to preset this\n * @param {?String} [body=''] - the body text the mail should have initially, if you want to preset this\n * @param {?String} [ccTld=''] - the top level domain to use for the cc address\n * @param {?String} [ccAfterAtWithoutTld=''] - the address part after the @ but before the tld for the cc address\n * @param {?String} [ccBeforeAt=''] - the address part before the @ for the cc address\n * @throws error if beforeAt or afterAtWithoutTld are empty\n * @return {HTMLElement} the augmented link\n *\n * @memberof Interaction:obfuscatePrivateMailToLink\n * @alias obfuscatePrivateMailToLink\n * @example\n * obfuscatePrivateMailToLink(document.querySelector('a'), true, 'de', 'gmail', 'recipient', 'Hello there!', 'How are you these days?');\n */\nexport function obfuscatePrivateMailToLink(\n\tlink,\n\tsetAsContent=false,\n\ttld='',\n\tafterAtWithoutTld='',\n\tbeforeAt='',\n\tsubject='',\n\tbody='',\n\tccTld='',\n\tccAfterAtWithoutTld='',\n\tccBeforeAt=''\n){\n\tconst __methodName__ = 'obfuscatePrivateMailToLink';\n\n\tsetAsContent = orDefault(setAsContent, false, 'bool');\n\tsubject = orDefault(subject, '', 'str');\n\tbody = orDefault(body, '', 'str');\n\tbeforeAt = orDefault(beforeAt, '', 'str');\n\tafterAtWithoutTld = orDefault(afterAtWithoutTld, '', 'str');\n\ttld = orDefault(tld, '', 'str');\n\tccBeforeAt = orDefault(ccBeforeAt, '', 'str');\n\tccAfterAtWithoutTld = orDefault(ccAfterAtWithoutTld, '', 'str');\n\tccTld = orDefault(ccTld, '', 'str');\n\n\tassert((beforeAt !== '') && (afterAtWithoutTld !== ''), `${MODULE_NAME}:${__methodName__} | basic mail parts missing`);\n\n\tif( tld !== '' ){\n\t\ttld = `.${tld}`;\n\t}\n\n\tif( ccTld !== '' ){\n\t\tccTld = `.${ccTld}`;\n\t}\n\n\tlet optionParams = new URLSearchParams();\n\tif( subject !== '' ){\n\t\toptionParams.set('subject', subject);\n\t}\n\tif( body !== '' ){\n\t\toptionParams.set('body', body);\n\t}\n\tif( (ccBeforeAt !== '') && (ccAfterAtWithoutTld !== '') ){\n\t\toptionParams.set('cc', `${ccBeforeAt}@${ccAfterAtWithoutTld}${ccTld}`);\n\t}\n\toptionParams = optionParams.toString();\n\tif( optionParams !== '' ){\n\t\toptionParams = `?${optionParams.replaceAll('+', '%20')}`;\n\t}\n\n\tlet interactionCount = 0;\n\tconst fAddLinkUrl = () => {\n\t\tinteractionCount++;\n\t\tlink.setAttribute('href', `mailto:${beforeAt}@${afterAtWithoutTld}${tld}${optionParams}`);\n\t};\n\tlink.addEventListener('mouseenter', fAddLinkUrl);\n\tlink.addEventListener('focusin', fAddLinkUrl);\n\tconst fRemoveLinkUrl = () => {\n\t\tinteractionCount--;\n\t\tif( interactionCount <= 0 ){\n\t\t\tlink.setAttribute('href', '');\n\t\t}\n\t};\n\tlink.addEventListener('mouseleave', fRemoveLinkUrl);\n\tlink.addEventListener('focusout', fRemoveLinkUrl);\n\n\tif( setAsContent ){\n\t\tlink.innerHTML = (`${beforeAt}@${afterAtWithoutTld}${tld}`).replace(/(\\w{1})/g, '$1‌');\n\t}\n\n\treturn link;\n}\n\n\n\n/**\n * @namespace Interaction:obfuscatePrivateTelLink\n */\n\n/**\n * Augment a link element to hold an obfuscated private tel link, to be able to contact people\n * via their own phone number, without the need to openly write the number into the DOM permanently,\n * in a way crawlers could identify easily.\n *\n * The method takes all parts of the number as (hopefully) unidentifiable parameters and then applies them internally,\n * to build a number string with tel protocol dynamically on mouse or focus interaction in the link's href,\n * offering normal link functionality from here on. If the interaction ends, the href is removed again immediately,\n * so the link is only and exclusively readable and complete during user interaction.\n *\n * You may set the link text yourself or set `setAsContent` to true, to let the function fill the link text with\n * the completed address. Be aware, that this, although still being obfuscated, lowers the level of security for this\n * solution.\n *\n * Although most parameters are technically optional, this function still expects `secondTelPart` or `firstTelPart` to\n * be filled. While only one part is strictly necessary here: I'd always suggest to use all parts, since, the more\n * of a number is written together, the easier the number can be parsed.\n *\n * @param {HTMLElement} link - the link to augment, has to be a node where we can set a \"href\" attribute\n * @param {?Boolean} [setAsContent=false] - define if the number should be used as link text, being formatted according to DIN 5008 (still uses string obfuscation, but weaker against bot with JS execution)\n * @param {?Number|String} [secondTelPart=''] - second half of the main number +49 04 123(4-56)<-this; add a dash to signify where a base number ends and the personal part starts\n * @param {?Number|String} [firstTelPart=''] - first half of the main number +49 04 (123)<-this 4-56\n * @param {?Number|String} [regionPart=''] - the local part of the number after the country part e.g. +49(04)<-this 1234-56\n * @param {?Number|String} [countryPart=''] - the country identifier with or without + this->(+49) 04 1234-56 (do not prefix with a local 0!)\n * @throws error if `secondTelPart` and `firstTelPart` are empty\n * @return {HTMLElement} the augmented link\n *\n * @memberof Interaction:obfuscatePrivateTelLink\n * @alias obfuscatePrivateTelLink\n * @example\n * obfuscatePrivateTelLink(document.querySelector('a'), true, 123, 439, 40, '+49');\n */\nexport function obfuscatePrivateTelLink(\n\tlink,\n\tsetAsContent=false,\n\tsecondTelPart='',\n\tfirstTelPart='',\n\tregionPart='',\n\tcountryPart=''\n){\n\tconst __methodName__ = 'obfuscatePrivateTelLink';\n\n\tsetAsContent = orDefault(setAsContent, false, 'bool');\n\tsecondTelPart = orDefault(secondTelPart, '', 'str').replace(/[^0-9\\-]/g, '');\n\tfirstTelPart = orDefault(firstTelPart, '', 'str').replace(/[^0-9\\-]/g, '');\n\tregionPart = orDefault(regionPart, '', 'str').replace(/[^0-9]/g, '');\n\tcountryPart = orDefault(countryPart, '', 'str').replace(/[^0-9]/g, '');\n\n\tassert((firstTelPart !== '') || (secondTelPart !== ''), `${MODULE_NAME}:${__methodName__} | basic tel parts missing`);\n\n\tlet interactionCount = 0;\n\tconst fAddLinkUrl = () => {\n\t\tinteractionCount++;\n\t\tlink.setAttribute('href', `tel:+${countryPart}${regionPart}${firstTelPart.replace(/-/g, '')}${secondTelPart.replace(/-/g, '')}`);\n\t};\n\tlink.addEventListener('mouseenter', fAddLinkUrl);\n\tlink.addEventListener('focusin', fAddLinkUrl);\n\tconst fRemoveLinkUrl = () => {\n\t\tinteractionCount--;\n\t\tif( interactionCount <= 0 ){\n\t\t\tlink.setAttribute('href', '');\n\t\t}\n\t};\n\tlink.addEventListener('mouseleave', fRemoveLinkUrl);\n\tlink.addEventListener('focusout', fRemoveLinkUrl);\n\n\tif( setAsContent ){\n\t\tlink.innerHTML = (`+${countryPart} ${regionPart} ${firstTelPart}${secondTelPart}`).replace(/(\\w{1})/g, '$1‌');\n\t}\n}\n\n\n\n/**\n * @namespace Interaction:setTappedState\n */\n\n/**\n * Sets a \"tapped\" state on an element (via a CSS class), which removes itself again after a short time.\n *\n * The sole reason for doing this, is to be able to apply styling to a tap/click action across devices without\n * trailing styles, which would result by using something like `:focus`.\n *\n * @param {HTMLElement} element - the link to augment, has to be a node where we can set a \"href\" attribute\n * @param {?String} [tappedClass='tapped'] - the CSS class to set on the element to signify the \"tapped\" state\n * @param {?Number} [tappedDuration=200] - the duration in milliseconds, the \"tapped\" state should last\n * @throws error if element is not an HTMLElement\n * @return {Basic.Deferred} resolves with the element, when the tapped state ends\n *\n * @memberof Interaction:setTappedState\n * @alias setTappedState\n * @example\n * setTappedState(link);\n * setTappedState(link, 'clicked', 500);\n */\nexport function setTappedState(element, tappedClass='tapped', tappedDuration=200){\n\tconst __methodName__ = 'setTappedState';\n\n\ttappedClass = orDefault(tappedClass, 'tapped', 'str');\n\ttappedDuration = orDefault(tappedDuration, 200, 'int');\n\n\tassert(isElement(element), `${MODULE_NAME}:${__methodName__} | ${NOT_AN_HTMLELEMENT_ERROR}`);\n\n\tconst deferred = new Deferred();\n\n\telement.classList.add(tappedClass);\n\twindow.setTimeout(() =>{\n\t\telement.classList.remove(tappedClass);\n\t\telement.blur();\n\t\tdeferred.resolve(element);\n\t}, tappedDuration);\n\n\treturn deferred;\n}\n\n\n\n/**\n * @namespace Interaction:setupAutoTappedStates\n */\n\n/**\n * This function registers a global event handler on the document body, to automatically add \"tapped\" states (as a CSS\n * class) to \"tappable\" elements on \"tap\".\n *\n * What is a \"tap\" you ask? Well, it's either a pointer click or a finger touch or anything resembling these actions\n * on your current device.\n *\n * The idea behind that is this: usually, on pointer devices, we have a `:hover` state to signify user interaction\n * with an element, while on touch devices, we only know that an interaction took place after a user touched an element\n * with his/her finger, \"tapped\" it so to speak. Styling a touch with CSS would only be possible via `:focus`, which\n * has the problems, that focus has a different meaning on pointer devices and the focus state does not end\n * automatically, resulting in trailing visual states.\n *\n * So, what we do instead, is that we just generally observe taps (via \"click\" event, which works across devices as\n * expected) and set a class on the element, for a short time, which removes itself automatically again, to be able\n * to define a visual state or a short animation for that class. So, for example, let's say the function has been\n * executed. After that, you can define something like `a.tapped { color: orange; }`, which would result in orange\n * coloring for a short time, after clicking/touching the element. Combine this with `:hover`, `:focus` definitions\n * in CSS to define a complete effect setup.\n *\n * @param {?HTMLElement} [element=document.body] - the element to use as delegation parent for events, should contain the tappable elements you'd like to target\n * @param {?String} [tappableElementsSelector='a, button, .button, input[type=button], input[type=submit]'] - selector to identify a tappable element by in a delegated event handler\n * @param {?String|Array} [tapEvents='click'] - the DOM event(s) to register for taps\n * @param {?String} [tappedClass='tapped'] - the CSS class to set on the element to signify the \"tapped\" state\n * @param {?Number} [tappedDuration=200] - the duration in milliseconds, the \"tapped\" state should last\n * @throws error if element is not an HTMLElement\n *\n * @memberof Interaction:setupAutoTappedStates\n * @alias setupAutoTappedStates\n * @example\n * setupAutoTappedStates();\n * setupAutoTappedStates(document.body, 'a, button', 'customevent');\n */\nexport function setupAutoTappedStates(\n\telement=null,\n\ttappableElementsSelector=TAPPABLE_ELEMENTS_SELECTOR,\n\ttapEvents='click',\n\ttappedClass='tapped',\n\ttappedDuration=200\n){\n\tconst __methodName__ = 'setupAutoTappedStates';\n\n\t// document.body not in function default to prevent errors on import in document-less contexts\n\telement = orDefault(element, document.body);\n\ttappableElementsSelector = orDefault(tappableElementsSelector, TAPPABLE_ELEMENTS_SELECTOR, 'str');\n\ttapEvents = orDefault(tapEvents, 'click', 'str');\n\ttapEvents = [].concat(tapEvents);\n\n\tassert(isElement(element), `${MODULE_NAME}:${__methodName__} | ${NOT_AN_HTMLELEMENT_ERROR}`);\n\n\ttapEvents.forEach(tapEvent => {\n\t\telement.addEventListener(tapEvent, e => {\n\t\t\tif(\n\t\t\t\thasValue(e.target?.matches)\n\t\t\t\t&& e.target.matches(tappableElementsSelector)\n\t\t\t){\n\t\t\t\tsetTappedState(e.target, tappedClass, tappedDuration);\n\t\t\t}\n\t\t});\n\t});\n}\n"]} \ No newline at end of file diff --git a/dist/logging.js b/dist/logging.js index 6f2c27a6..051b5761 100644 --- a/dist/logging.js +++ b/dist/logging.js @@ -1,5 +1,5 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Logging diff --git a/dist/logging.js.map b/dist/logging.js.map index c43e9800..00397cce 100644 --- a/dist/logging.js.map +++ b/dist/logging.js.map @@ -1 +1 @@ -{"version":3,"file":"logging.js","names":["MODULE_NAME","LOG_LEVELS","XLOG_CONTEXT_COUNTS","LOG_LEVEL","TRY_TO_LOG_TO_PARENT","LOG_CHAINABLE_OBJECT","__documentation_for_chainable_object_of_log_execution__","setLogLevel","level","includes","log","tryToLogToParent","setting","undefined","assert","genericConsoleMethodWrapperFactory","clear","count","dir","dirxml","dirXml","error","err","Array","from","arguments","group","groupCollapsed","groupEnd","info","profile","profileEnd","table","time","timeEnd","timeLog","timeStamp","trace","warn","genericConsoleMethodWrapper","name","logLevel","args","indexOf","window","console","parent","apply","ex","forEach","obj","xlog","message","context","Error","stack","split","trim"],"sources":["logging.js"],"mappings":"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","sourcesContent":["/*!\n * Module Logging\n */\n\n/**\n * @namespace Logging\n */\n\nconst MODULE_NAME = 'Logging';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const\n\tLOG_LEVELS = ['log', 'warn', 'err'],\n\tXLOG_CONTEXT_COUNTS = {}\n;\n\nexport let\n\tLOG_LEVEL = 'log',\n\tTRY_TO_LOG_TO_PARENT = false\n;\n\n/*\n * to make log calls chainable, this object is returned for every logging call, this offers extended functionality,\n * going far beyond log/warn/err, while keeping a very narrow interface for everyday stuff\n */\nconst LOG_CHAINABLE_OBJECT = {\n\t__documentation_for_chainable_object_of_log_execution__(){\n\t\treturn 'Use this object to chain logging calls. All standard methods are supported'\n\t\t\t+' (see https://developer.mozilla.org/en-US/docs/Web/API/Console) and are executed'\n\t\t\t+' with silent fails if not supported by the browser. See other methods in this'\n\t\t\t+' object for an overview. Use disable()/enable() to deactivate/activate all debug outputs'\n\t\t\t+' (exceptions are assert, clear, error and warn) to the console centrally'\n\t\t;\n\t},\n\tsetLogLevel(level){\n\t\tlevel = `${level}`;\n\n\t\tif( LOG_LEVELS.includes(level) ){\n\t\t\tLOG_LEVEL = level;\n\t\t}\n\n\t\treturn log();\n\t},\n\ttryToLogToParent(setting){\n\t\tsetting = (setting === undefined) ? true : !!setting;\n\t\tTRY_TO_LOG_TO_PARENT = setting;\n\n\t\treturn log();\n\t},\n\tassert : genericConsoleMethodWrapperFactory('assert'),\n\tclear : genericConsoleMethodWrapperFactory('clear'),\n\tcount : genericConsoleMethodWrapperFactory('count'),\n\tdir : genericConsoleMethodWrapperFactory('dir'),\n\tdirxml : genericConsoleMethodWrapperFactory('dirxml'),\n\tdirXml : genericConsoleMethodWrapperFactory('dirxml'),\n\terror(){\n\t\treturn err(...Array.from(arguments));\n\t},\n\tgroup : genericConsoleMethodWrapperFactory('group'),\n\tgroupCollapsed : genericConsoleMethodWrapperFactory('groupCollapsed'),\n\tgroupEnd : genericConsoleMethodWrapperFactory('groupEnd'),\n\tinfo : genericConsoleMethodWrapperFactory('info'),\n\tlog(){\n\t\treturn log(...Array.from(arguments));\n\t},\n\tprofile : genericConsoleMethodWrapperFactory('profile'),\n\tprofileEnd : genericConsoleMethodWrapperFactory('profileEnd'),\n\ttable : genericConsoleMethodWrapperFactory('table'),\n\ttime : genericConsoleMethodWrapperFactory('time'),\n\ttimeEnd : genericConsoleMethodWrapperFactory('timeEnd'),\n\ttimeLog : genericConsoleMethodWrapperFactory('timeLog'),\n\ttimeStamp : genericConsoleMethodWrapperFactory('timeStamp'),\n\ttrace : genericConsoleMethodWrapperFactory('trace'),\n\twarn(){\n\t\treturn warn(...Array.from(arguments));\n\t}\n};\n\n\n\n//###[ HELPERS ]########################################################################################################\n\n/*\n * generically wraps console functions for chainability even if method is unavailable or fails\n * used in LOG_CHAINABLE_OBJECT below\n *\n * @private\n */\nfunction genericConsoleMethodWrapper(name, logLevel=null, ...args){\n\tname = `${name}`;\n\tlogLevel = LOG_LEVELS.includes(`${logLevel}`) ? `${logLevel}` : LOG_LEVELS[0];\n\n\tif( LOG_LEVELS.indexOf(LOG_LEVEL) <= LOG_LEVELS.indexOf(logLevel) ){\n\t\tif( typeof window.console?.[name] === 'function' ){\n\t\t\ttry {\n\t\t\t\tif( TRY_TO_LOG_TO_PARENT ){\n\t\t\t\t\tparent.console[name].apply(parent.console, args);\n\t\t\t\t} else {\n\t\t\t\t\tconsole[name].apply(console, args);\n\t\t\t\t}\n\t\t\t} catch(ex){\n\t\t\t\ttry {\n\t\t\t\t\twarn(`console call to \"${name}\" failed, implementation seemingly incompatible`);\n\t\t\t\t} catch(ex){}\n\t\t\t}\n\t\t} else {\n\t\t\ttry {\n\t\t\t\twarn(`console call to \"${name}\" failed, is seemingly not supported`);\n\t\t\t} catch(ex){}\n\t\t}\n\t}\n\n\treturn log();\n}\n\n/*\n * prepare an executable wrapper version based on a specific function name\n * used in LOG_CHAINABLE_OBJECT below\n *\n * @private\n */\nfunction genericConsoleMethodWrapperFactory(name, logLevel){\n\treturn function(){\n\t\treturn genericConsoleMethodWrapper(name, logLevel, ...Array.from(arguments));\n\t};\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Logging:log\n */\n\n/**\n * Logs a message to the console. Prevents errors in browsers, that don't support this feature.\n * This method is chainable (always returns a chainable object with all methods) and wraps all\n * advanced logging methods like dir, assert and count (https://developer.mozilla.org/en-US/docs/Web/API/Console).\n *\n * Use setLogLevel() on the chainable object to globally define the current log level.\n * 'log' is the default value and allows for all logs to appear on console. 'warn' reduces logs to warnings and errors.\n * 'err' only shows errors on console. Use this to mute debug stuff in production.\n *\n * You can use the method tryToLogToParent(true/false) to instruct log to try to log to the parent window also,\n * which comes in handy if you are developing inside a same domain iframe.\n *\n * @param {...*} [...] - any number of arguments you wish to log\n * @returns {Object} - chainable logging object\n *\n * @memberof Logging:log\n * @alias log\n * @example\n * log(randomVar, 'string');\n * log(false, true);\n * log().group().log(1).log(2).log(3).groupEnd().error('ouch');\n * log().setLogLevel('warn');\n * log('test', {test : 'test'}).setLogLevel('warn').warn('oh noez, but printed').log('not printed').setLogLevel('log').clear();\n * log().tryToLogToParent().log('hooray times two').tryToLogToParent(false);\n */\nexport function log(){\n\tif(\n\t\t(typeof window.console?.log === 'function')\n\t\t&& (LOG_LEVELS.indexOf(LOG_LEVEL) <= LOG_LEVELS.indexOf('log'))\n\t){\n\t\tArray.from(arguments).forEach(obj => {\n\t\t\tif( (obj === true) || (obj === false) ){\n\t\t\t\tobj = obj ? 'true' : 'false';\n\t\t\t}\n\n\t\t\tif( TRY_TO_LOG_TO_PARENT ){\n\t\t\t\tparent.console.log(obj);\n\t\t\t} else {\n\t\t\t\tconsole.log(obj);\n\t\t\t}\n\t\t});\n\t}\n\n\treturn LOG_CHAINABLE_OBJECT;\n}\n\n\n\n/**\n * @namespace Logging:warn\n */\n\n/**\n * Logs a warning to the console. Prevents errors in browsers, that don't support this feature.\n *\n * @param {...*} [...] - add any number of arguments you wish to log\n *\n * @memberof Logging:warn\n * @alias warn\n * @example\n * warn('warning yo!');\n * warn(randomVar, 'string');\n * warn(false);\n * warn(true);\n */\nexport function warn(){\n\tif(\n\t\t(typeof window.console?.warn === 'function')\n\t\t&& (LOG_LEVELS.indexOf(LOG_LEVEL) <= LOG_LEVELS.indexOf('warn'))\n\t){\n\t\tArray.from(arguments).forEach(obj => {\n\t\t\tif( (obj === true) || (obj === false) ){\n\t\t\t\tobj = obj ? 'true' : 'false';\n\t\t\t}\n\n\t\t\tif( TRY_TO_LOG_TO_PARENT ){\n\t\t\t\tparent.console.warn(obj);\n\t\t\t} else {\n\t\t\t\tconsole.warn(obj);\n\t\t\t}\n\t\t});\n\t}\n\n\treturn LOG_CHAINABLE_OBJECT;\n}\n\n\n\n/**\n * @namespace Logging:err\n */\n\n/**\n * Logs an error to the console. Prevents errors in browsers, that don't support this feature.\n *\n * This function is not named error because that already might be misleading with the Error object and is not a verb.\n *\n * @param {...*} [...] - add any number of arguments you wish to log\n *\n * @memberof Logging:err\n * @alias err\n * @example\n * err('error yo!');\n * err(randomVar, 'string');\n * err(false);\n * err(true);\n */\nexport function err(){\n\tif(\n\t\t(typeof window.console?.error === 'function')\n\t\t&& (LOG_LEVELS.indexOf(LOG_LEVEL) <= LOG_LEVELS.indexOf('err'))\n\t){\n\t\tArray.from(arguments).forEach(obj => {\n\t\t\tif( (obj === true) || (obj === false) ){\n\t\t\t\tobj = obj ? 'true' : 'false';\n\t\t\t}\n\n\t\t\tif( TRY_TO_LOG_TO_PARENT ){\n\t\t\t\tparent.console.error(obj);\n\t\t\t} else {\n\t\t\t\tconsole.error(obj);\n\t\t\t}\n\t\t});\n\t}\n\n\treturn LOG_CHAINABLE_OBJECT;\n}\n\n\n\n/**\n * @namespace Logging:xlog\n */\n\n/**\n * X marks the spot. A very simple method for urgent cases of printf-debugging.\n * Simply logs the context of the call to the console, also providing a counter,\n * counting the executions from that context.\n *\n * For real detailed debugging, you have to instantiate/throw an error and work with that information,\n * this is just for quick checking.\n *\n * This method uses Error.stack, which is a rather wonky and unstable feature feature. Use this for debugging and better\n * remove it again afterwards. For more info on Error.stack, read:\n * https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Error/Stack\n *\n * @param {?String} [message=null] - an optional message to be printed besides the context information\n *\n * @memberof Logging:xlog\n * @alias xlog\n * @example\n * for( let i = 0; i < 10; i++ ){\n * xlog('purely optional message');\n * }\n */\nexport function xlog(message=null){\n\tlet context;\n\n\ttry {\n\t\tcontext = (new Error()).stack.split('\\n')[2].trim();\n\t} catch(ex){\n\t\tcontext = 'anonymous';\n\t}\n\n\tif( XLOG_CONTEXT_COUNTS[context] === undefined ){\n\t\tXLOG_CONTEXT_COUNTS[context] = 0;\n\t}\n\tXLOG_CONTEXT_COUNTS[context]++;\n\n\tlog(`<> ${context} [${XLOG_CONTEXT_COUNTS[context]}]${!!message ? ' | '+message : ''}`);\n}\n"]} \ No newline at end of file +{"version":3,"file":"logging.js","names":["MODULE_NAME","LOG_LEVELS","XLOG_CONTEXT_COUNTS","LOG_LEVEL","TRY_TO_LOG_TO_PARENT","LOG_CHAINABLE_OBJECT","__documentation_for_chainable_object_of_log_execution__","setLogLevel","level","includes","log","tryToLogToParent","setting","undefined","assert","genericConsoleMethodWrapperFactory","clear","count","dir","dirxml","dirXml","error","err","Array","from","arguments","group","groupCollapsed","groupEnd","info","profile","profileEnd","table","time","timeEnd","timeLog","timeStamp","trace","warn","genericConsoleMethodWrapper","name","logLevel","args","indexOf","window","console","parent","apply","ex","forEach","obj","xlog","message","context","Error","stack","split","trim"],"sources":["logging.js"],"mappings":"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","ignoreList":[],"sourcesContent":["/*!\n * Module Logging\n */\n\n/**\n * @namespace Logging\n */\n\nconst MODULE_NAME = 'Logging';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const\n\tLOG_LEVELS = ['log', 'warn', 'err'],\n\tXLOG_CONTEXT_COUNTS = {}\n;\n\nexport let\n\tLOG_LEVEL = 'log',\n\tTRY_TO_LOG_TO_PARENT = false\n;\n\n/*\n * to make log calls chainable, this object is returned for every logging call, this offers extended functionality,\n * going far beyond log/warn/err, while keeping a very narrow interface for everyday stuff\n */\nconst LOG_CHAINABLE_OBJECT = {\n\t__documentation_for_chainable_object_of_log_execution__(){\n\t\treturn 'Use this object to chain logging calls. All standard methods are supported'\n\t\t\t+' (see https://developer.mozilla.org/en-US/docs/Web/API/Console) and are executed'\n\t\t\t+' with silent fails if not supported by the browser. See other methods in this'\n\t\t\t+' object for an overview. Use disable()/enable() to deactivate/activate all debug outputs'\n\t\t\t+' (exceptions are assert, clear, error and warn) to the console centrally'\n\t\t;\n\t},\n\tsetLogLevel(level){\n\t\tlevel = `${level}`;\n\n\t\tif( LOG_LEVELS.includes(level) ){\n\t\t\tLOG_LEVEL = level;\n\t\t}\n\n\t\treturn log();\n\t},\n\ttryToLogToParent(setting){\n\t\tsetting = (setting === undefined) ? true : !!setting;\n\t\tTRY_TO_LOG_TO_PARENT = setting;\n\n\t\treturn log();\n\t},\n\tassert : genericConsoleMethodWrapperFactory('assert'),\n\tclear : genericConsoleMethodWrapperFactory('clear'),\n\tcount : genericConsoleMethodWrapperFactory('count'),\n\tdir : genericConsoleMethodWrapperFactory('dir'),\n\tdirxml : genericConsoleMethodWrapperFactory('dirxml'),\n\tdirXml : genericConsoleMethodWrapperFactory('dirxml'),\n\terror(){\n\t\treturn err(...Array.from(arguments));\n\t},\n\tgroup : genericConsoleMethodWrapperFactory('group'),\n\tgroupCollapsed : genericConsoleMethodWrapperFactory('groupCollapsed'),\n\tgroupEnd : genericConsoleMethodWrapperFactory('groupEnd'),\n\tinfo : genericConsoleMethodWrapperFactory('info'),\n\tlog(){\n\t\treturn log(...Array.from(arguments));\n\t},\n\tprofile : genericConsoleMethodWrapperFactory('profile'),\n\tprofileEnd : genericConsoleMethodWrapperFactory('profileEnd'),\n\ttable : genericConsoleMethodWrapperFactory('table'),\n\ttime : genericConsoleMethodWrapperFactory('time'),\n\ttimeEnd : genericConsoleMethodWrapperFactory('timeEnd'),\n\ttimeLog : genericConsoleMethodWrapperFactory('timeLog'),\n\ttimeStamp : genericConsoleMethodWrapperFactory('timeStamp'),\n\ttrace : genericConsoleMethodWrapperFactory('trace'),\n\twarn(){\n\t\treturn warn(...Array.from(arguments));\n\t}\n};\n\n\n\n//###[ HELPERS ]########################################################################################################\n\n/*\n * generically wraps console functions for chainability even if method is unavailable or fails\n * used in LOG_CHAINABLE_OBJECT below\n *\n * @private\n */\nfunction genericConsoleMethodWrapper(name, logLevel=null, ...args){\n\tname = `${name}`;\n\tlogLevel = LOG_LEVELS.includes(`${logLevel}`) ? `${logLevel}` : LOG_LEVELS[0];\n\n\tif( LOG_LEVELS.indexOf(LOG_LEVEL) <= LOG_LEVELS.indexOf(logLevel) ){\n\t\tif( typeof window.console?.[name] === 'function' ){\n\t\t\ttry {\n\t\t\t\tif( TRY_TO_LOG_TO_PARENT ){\n\t\t\t\t\tparent.console[name].apply(parent.console, args);\n\t\t\t\t} else {\n\t\t\t\t\tconsole[name].apply(console, args);\n\t\t\t\t}\n\t\t\t} catch(ex){\n\t\t\t\ttry {\n\t\t\t\t\twarn(`console call to \"${name}\" failed, implementation seemingly incompatible`);\n\t\t\t\t} catch(ex){}\n\t\t\t}\n\t\t} else {\n\t\t\ttry {\n\t\t\t\twarn(`console call to \"${name}\" failed, is seemingly not supported`);\n\t\t\t} catch(ex){}\n\t\t}\n\t}\n\n\treturn log();\n}\n\n/*\n * prepare an executable wrapper version based on a specific function name\n * used in LOG_CHAINABLE_OBJECT below\n *\n * @private\n */\nfunction genericConsoleMethodWrapperFactory(name, logLevel){\n\treturn function(){\n\t\treturn genericConsoleMethodWrapper(name, logLevel, ...Array.from(arguments));\n\t};\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Logging:log\n */\n\n/**\n * Logs a message to the console. Prevents errors in browsers, that don't support this feature.\n * This method is chainable (always returns a chainable object with all methods) and wraps all\n * advanced logging methods like dir, assert and count (https://developer.mozilla.org/en-US/docs/Web/API/Console).\n *\n * Use setLogLevel() on the chainable object to globally define the current log level.\n * 'log' is the default value and allows for all logs to appear on console. 'warn' reduces logs to warnings and errors.\n * 'err' only shows errors on console. Use this to mute debug stuff in production.\n *\n * You can use the method tryToLogToParent(true/false) to instruct log to try to log to the parent window also,\n * which comes in handy if you are developing inside a same domain iframe.\n *\n * @param {...*} [...] - any number of arguments you wish to log\n * @returns {Object} - chainable logging object\n *\n * @memberof Logging:log\n * @alias log\n * @example\n * log(randomVar, 'string');\n * log(false, true);\n * log().group().log(1).log(2).log(3).groupEnd().error('ouch');\n * log().setLogLevel('warn');\n * log('test', {test : 'test'}).setLogLevel('warn').warn('oh noez, but printed').log('not printed').setLogLevel('log').clear();\n * log().tryToLogToParent().log('hooray times two').tryToLogToParent(false);\n */\nexport function log(){\n\tif(\n\t\t(typeof window.console?.log === 'function')\n\t\t&& (LOG_LEVELS.indexOf(LOG_LEVEL) <= LOG_LEVELS.indexOf('log'))\n\t){\n\t\tArray.from(arguments).forEach(obj => {\n\t\t\tif( (obj === true) || (obj === false) ){\n\t\t\t\tobj = obj ? 'true' : 'false';\n\t\t\t}\n\n\t\t\tif( TRY_TO_LOG_TO_PARENT ){\n\t\t\t\tparent.console.log(obj);\n\t\t\t} else {\n\t\t\t\tconsole.log(obj);\n\t\t\t}\n\t\t});\n\t}\n\n\treturn LOG_CHAINABLE_OBJECT;\n}\n\n\n\n/**\n * @namespace Logging:warn\n */\n\n/**\n * Logs a warning to the console. Prevents errors in browsers, that don't support this feature.\n *\n * @param {...*} [...] - add any number of arguments you wish to log\n *\n * @memberof Logging:warn\n * @alias warn\n * @example\n * warn('warning yo!');\n * warn(randomVar, 'string');\n * warn(false);\n * warn(true);\n */\nexport function warn(){\n\tif(\n\t\t(typeof window.console?.warn === 'function')\n\t\t&& (LOG_LEVELS.indexOf(LOG_LEVEL) <= LOG_LEVELS.indexOf('warn'))\n\t){\n\t\tArray.from(arguments).forEach(obj => {\n\t\t\tif( (obj === true) || (obj === false) ){\n\t\t\t\tobj = obj ? 'true' : 'false';\n\t\t\t}\n\n\t\t\tif( TRY_TO_LOG_TO_PARENT ){\n\t\t\t\tparent.console.warn(obj);\n\t\t\t} else {\n\t\t\t\tconsole.warn(obj);\n\t\t\t}\n\t\t});\n\t}\n\n\treturn LOG_CHAINABLE_OBJECT;\n}\n\n\n\n/**\n * @namespace Logging:err\n */\n\n/**\n * Logs an error to the console. Prevents errors in browsers, that don't support this feature.\n *\n * This function is not named error because that already might be misleading with the Error object and is not a verb.\n *\n * @param {...*} [...] - add any number of arguments you wish to log\n *\n * @memberof Logging:err\n * @alias err\n * @example\n * err('error yo!');\n * err(randomVar, 'string');\n * err(false);\n * err(true);\n */\nexport function err(){\n\tif(\n\t\t(typeof window.console?.error === 'function')\n\t\t&& (LOG_LEVELS.indexOf(LOG_LEVEL) <= LOG_LEVELS.indexOf('err'))\n\t){\n\t\tArray.from(arguments).forEach(obj => {\n\t\t\tif( (obj === true) || (obj === false) ){\n\t\t\t\tobj = obj ? 'true' : 'false';\n\t\t\t}\n\n\t\t\tif( TRY_TO_LOG_TO_PARENT ){\n\t\t\t\tparent.console.error(obj);\n\t\t\t} else {\n\t\t\t\tconsole.error(obj);\n\t\t\t}\n\t\t});\n\t}\n\n\treturn LOG_CHAINABLE_OBJECT;\n}\n\n\n\n/**\n * @namespace Logging:xlog\n */\n\n/**\n * X marks the spot. A very simple method for urgent cases of printf-debugging.\n * Simply logs the context of the call to the console, also providing a counter,\n * counting the executions from that context.\n *\n * For real detailed debugging, you have to instantiate/throw an error and work with that information,\n * this is just for quick checking.\n *\n * This method uses Error.stack, which is a rather wonky and unstable feature feature. Use this for debugging and better\n * remove it again afterwards. For more info on Error.stack, read:\n * https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Error/Stack\n *\n * @param {?String} [message=null] - an optional message to be printed besides the context information\n *\n * @memberof Logging:xlog\n * @alias xlog\n * @example\n * for( let i = 0; i < 10; i++ ){\n * xlog('purely optional message');\n * }\n */\nexport function xlog(message=null){\n\tlet context;\n\n\ttry {\n\t\tcontext = (new Error()).stack.split('\\n')[2].trim();\n\t} catch(ex){\n\t\tcontext = 'anonymous';\n\t}\n\n\tif( XLOG_CONTEXT_COUNTS[context] === undefined ){\n\t\tXLOG_CONTEXT_COUNTS[context] = 0;\n\t}\n\tXLOG_CONTEXT_COUNTS[context]++;\n\n\tlog(`<> ${context} [${XLOG_CONTEXT_COUNTS[context]}]${!!message ? ' | '+message : ''}`);\n}\n"]} \ No newline at end of file diff --git a/dist/navigation.js b/dist/navigation.js index fb7fd1e3..f0087f33 100644 --- a/dist/navigation.js +++ b/dist/navigation.js @@ -1,5 +1,5 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Navigation diff --git a/dist/navigation.js.map b/dist/navigation.js.map index 01109210..038ba9e9 100644 --- a/dist/navigation.js.map +++ b/dist/navigation.js.map @@ -1 +1 @@ -{"version":3,"file":"navigation.js","names":["MODULE_NAME","warn","hasValue","orDefault","isPlainObject","isArray","isWindow","isFunction","assert","createNode","browserSupportsHistoryManipulation","urlHref","HISTORY","current","state","title","getHostAndPathname","popState","listening","callbacks","handler","e","historyNew","forEach","cb","stateful","hostAndPathname","host","undefined","pathname","window","location","ex","redirect","url","params","anchor","target","postParams","markListParams","formAttributes","method","action","redirectForm","paramName","val","appendChild","type","name","value","document","body","submit","removeChild","URL","origin","eLink","createElement","href","rel","click","parentNode","open","assign","openTab","openWindow","options","parentWindow","tryAsPopup","windowName","optionArray","prop","includes","push","join","reload","cached","postUsable","form","replace","changeCurrentUrl","usePushState","history","pushState","replaceState","path","onHistoryChange","callback","clearOld","usePreviousState","__methodName__","statefulCallback","original","addEventListener","offHistoryChange","oldCallbackCount","length","reduce","cbs","newCallbackCount","removeEventListener"],"sources":["navigation.js"],"mappings":"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","sourcesContent":["/*!\n * Module Navigation\n */\n\n/**\n * @namespace Navigation\n */\n\nconst MODULE_NAME = 'Navigation';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {warn} from './logging.js';\nimport {hasValue, orDefault, isPlainObject, isArray, isWindow, isFunction, assert} from './basic.js';\nimport {createNode} from './elements.js';\nimport {browserSupportsHistoryManipulation} from './context.js';\nimport {urlHref} from './urls.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const HISTORY = {\n\tcurrent : {\n\t\tstate : null,\n\t\ttitle : '',\n\t\t...getHostAndPathname()\n\t},\n\tpopState : {\n\t\tlistening : false,\n\t\tcallbacks : [],\n\t\thandler(e){\n\t\t\tconst historyNew = {\n\t\t\t\tstate : e.state,\n\t\t\t\ttitle : e.title,\n\t\t\t\t...getHostAndPathname()\n\t\t\t};\n\n\t\t\tHISTORY.popState.callbacks.forEach(cb => {\n\t\t\t\tcb.stateful(e, historyNew);\n\t\t\t});\n\n\t\t\tHISTORY.current = historyNew;\n\t\t}\n\t}\n};\n\n\n\n//###[ HELPERS ]########################################################################################################\n\nfunction getHostAndPathname(){\n\tconst hostAndPathname = {\n\t\thost : undefined,\n\t\tpathname : undefined\n\t};\n\n\ttry {\n\t\thostAndPathname.host = window.location.host;\n\t\thostAndPathname.pathname = window.location.pathname;\n\t} catch(ex){\n\t\thostAndPathname.host = undefined;\n\t\thostAndPathname.pathname = undefined;\n\t}\n\n\treturn hostAndPathname;\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Navigation:redirect\n */\n\n/**\n * Everything you need to do basic navigation without history API.\n *\n * Provide a URL to navigate to or leave the URL out, to use the current full URL. See `urlHref` for details.\n *\n * Add GET-parameters (adding to those already present in the URL), define an anchor (or automatically get the one\n * defined in the URL), set a target to define a window to navigate to (or open a new one) and even\n * define POST-parameters to navigate while providing POST-data.\n *\n * Provided params have to be a flat plain object, with ordinal values or arrays of ordinal values on the first level.\n * Everything else will be stringified and url-encoded as is. Usually, parameters defined here add to present\n * parameters in the URL. To force-override present values, declare the param name with a \"!\" prefix\n * (`{'!presentparam' : 'new'}`).\n *\n * If you define POST-params to navigate to a URL providing POST-data we internally build a custom form element,\n * with type \"post\", filled with hidden fields adding the form data, which we submit to navigate to the action, which\n * contains our url. Even the target carries over.\n *\n * If you define a target window and therefore open a new tab/window this function adds \"noopener,noreferrer\"\n * automatically if the origins do not match to increase security. If you need the opener, have a look at\n * \"openWindow\", which gives you more manual control in that regard.\n *\n * If you define a target and open an external URL, repeated calls to the same target will open multiple windows\n * due to the security settings.\n *\n * @param {?String|URL} [url=null] - the location to load, if null current location is reloaded/used\n * @param {?Object} [params=null] - plain object of GET-parameters to add to the url\n * @param {?String} [anchor=null] - anchor/hash to set for called url, has precedence over URL hash\n * @param {?String} [target=null] - name of the window to perform the redirect to/in, use \"_blank\" to open a new window/tab\n * @param {?Object} [postParams=null] - plain object of postParameters to send with the redirect, solved with a hidden form\n * @param {?Boolean} [markListParams=false] - if true, params with more than one value will be marked with \"[]\" preceding the param name\n * @throws error if url is not usable\n *\n * @memberof Navigation:redirect\n * @alias redirect\n * @see Urls.urlHref\n * @example\n * redirect('https://test.com', {search : 'kittens', order : 'asc'}, 'fluffykittens');\n * redirect(null, {order : 'desc'});\n */\nexport function redirect(url=null, params=null, anchor=null, target=null, postParams=null, markListParams=false){\n\turl = urlHref(url, params, anchor, markListParams);\n\ttarget = orDefault(target, null, 'str');\n\tpostParams = isPlainObject(postParams) ? postParams : null;\n\n\n\tif( hasValue(postParams) ){\n\t\tconst formAttributes = {method : 'post', action : url, 'data-ajax' : 'false'};\n\t\tif( hasValue(target) ){\n\t\t\tformAttributes.target = target;\n\t\t}\n\n\t\tconst redirectForm = createNode('form', formAttributes);\n\t\tfor( let paramName in postParams ){\n\t\t\tif( isArray(postParams[paramName]) ){\n\t\t\t\tpostParams[paramName].forEach(val => {\n\t\t\t\t\tredirectForm.appendChild(createNode(\n\t\t\t\t\t\t'input',\n\t\t\t\t\t\t{type : 'hidden', name : `${paramName}[]`, value : `${val}`}\n\t\t\t\t\t));\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tredirectForm.appendChild(createNode(\n\t\t\t\t\t'input',\n\t\t\t\t\t{type : 'hidden', name : paramName, value : `${postParams[paramName]}`}\n\t\t\t\t));\n\t\t\t}\n\t\t}\n\n\t\tdocument.body.appendChild(redirectForm);\n\t\tredirectForm.submit();\n\t\tdocument.body.removeChild(redirectForm);\n\t} else if( hasValue(target) ){\n\t\tconst parsedUrl = new URL(url);\n\n\t\tif( parsedUrl.origin !== window.location.origin ){\n\t\t\t// we have to jump through hoops here, since adding security features to window.open\n\t\t\t// forces popup windows in some browsers and although we can set opener via the created\n\t\t\t// window, we cannot reliably set the referrer that way\n\t\t\tconst eLink = document.createElement('a');\n\t\t\teLink.href = url;\n\t\t\teLink.target = target;\n\t\t\teLink.rel = 'noopener noreferrer';\n\t\t\tdocument.body.appendChild(eLink);\n\t\t\teLink.click();\n\t\t\teLink.parentNode.removeChild(eLink);\n\t\t} else {\n\t\t\twindow.open(url, target);\n\t\t}\n\t} else {\n\t\twindow.location.assign(url);\n\t}\n}\n\n\n\n/**\n * @namespace Navigation:openTab\n */\n\n/**\n * Opens a sub-window for the current window as _blank, which should result in a new tab in most browsers.\n *\n * This method is just a shortcut for \"redirect\" with a set target and reasonable parameters.\n *\n * By using \"redirect\", this method also automatically takes care of adding \"noopener,noreferrer\" to external\n * links, which are determined by not having the same origin as the current location. For more manual control\n * over such parameters, have a look at \"openWindow\" instead.\n *\n * @param {?String} [url] - the location to load, if null current location is reloaded/used\n * @param {?Object} [params=null] - plain object of GET-parameters to add to the url, adds to existing ones in the URL and overwrites existing ones with same name\n * @param {?String} [anchor=null] - anchor/hash to set for called url, has precedence over URL hash\n * @param {?Object} [postParams=null] - plain object of postParameters to send with the redirect, solved with a hidden form\n *\n * @memberof Navigation:openTab\n * @alias openTab\n * @see redirect\n * @example\n * openTab('/misc/faq.html');\n */\nexport function openTab(url, params=null, anchor=null, postParams=null){\n\tredirect(url, params, anchor, '_blank', postParams);\n}\n\n\n\n/**\n * @namespace Navigation:openWindow\n */\n\n/**\n * Opens a sub-window for the current window or another defined parent window.\n * Be aware that most browsers open new windows as a tab by default, have a look at the \"tryAsPopup\"-parameter\n * if you need to open a new standalone window and your configuration results in new tabs instead.\n *\n * For window options (in this implementation, we consider \"name\" to be an option as well), see:\n * https://developer.mozilla.org/en-US/docs/Web/API/Window/open#window_features\n *\n * Keep in mind to set \"noopener\" and/or \"noreferrer\" for external URLs in options, to improve security and privacy.\n * Hint for older MS browsers: if you set these security options, these will most likely open the URL in a popup\n * window. If you want to circumvent this, you'll have to drop the \"noreferrer\" and settle for \"noopener\", by\n * setting opener to null on the returned window like this: `openWindow('url').opener = null;`\n *\n * @param {?String|URL} [url=null] - the URL to load in the new window, if nullish, the current URL is used\n * @param {?Object} [options=null] - parameters for the new window according to the definitions of window.open & \"name\" for the window name\n * @param {?Window} [parentWindow=null] - parent window for the new window, current if not defined\n * @param {?Boolean} [tryAsPopup=false] - defines if it should be tried to force a real new window instead of a tab\n * @throws error if url is not usable\n * @returns {Window} the newly opened window/tab\n *\n * @memberof Navigation:openWindow\n * @alias openWindow\n * @see Urls.urlHref\n * @example\n * openWindow('/img/gallery.html');\n * openWindow('http://www.kittens.com', {name : 'kitten_popup'}, parent);\n */\nexport function openWindow(url=null, options=null, parentWindow=null, tryAsPopup=false){\n\turl = urlHref(url);\n\toptions = isPlainObject(options) ? options : null;\n\tparentWindow = isWindow(parentWindow) ? parentWindow : window;\n\ttryAsPopup = orDefault(tryAsPopup, false, 'bool');\n\n\tlet\twindowName = '';\n\tconst optionArray = [];\n\n\tif( hasValue(options) ){\n\t\tfor( let prop in options ){\n\t\t\tif( prop === 'name' ){\n\t\t\t\twindowName = options[prop];\n\t\t\t}\n\n\t\t\tif( (prop !== 'name') || tryAsPopup ){\n\t\t\t\tif( [true, 1, 'yes'].includes(options[prop]) ){\n\t\t\t\t\toptionArray.push(`${prop}`);\n\t\t\t\t} else {\n\t\t\t\t\toptionArray.push(`${prop}=${options[prop]}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn parentWindow.open(url, windowName, optionArray.join(','));\n}\n\n\n\n/**\n * @namespace Navigation:reload\n */\n\n/**\n * Reloads the current window-location. Differentiates between cached and cache-refreshing reload.\n * Hint: the forcedReload param in window.location.reload is deprecated and not supported anymore in all browsers,\n * so, in order to do a cache busting reload we have to use a trick, by using a POST-reload, since POST never\n * gets cached. If, for some reason, you cannot POST to a URL, I also provided a second, less effective fallback,\n * using \"replace\".\n *\n * Hint: depending on your browser a cached reload may keep the current scrolling position in the document, while\n * the uncached variants won't\n *\n * @param {?Boolean} [cached=true] - should we use the cache on reload?\n * @param {?Boolean} [postUsable=true] - if set to false, we try to replace URL instead of POSTing to it\n *\n * @memberof Navigation:reload\n * @alias reload\n * @example\n * // with cache\n * reload();\n * // without cache via POST\n * reload(false);\n * // without cache via \"replace\"\n * reload(false, false);\n */\nexport function reload(cached=true, postUsable=true){\n\tcached = orDefault(cached, true, 'bool');\n\tpostUsable = orDefault(postUsable, true, 'bool');\n\n\tif( !cached && postUsable ){\n\t\tconst form = document.createElement('form');\n\t\tform.method = 'post';\n\t\tform.action = window.location.href;\n\t\tdocument.body.appendChild(form);\n\t\tform.submit();\n\t\tdocument.body.removeChild(form);\n\t} else if( !cached && !postUsable ){\n\t\twindow.location.replace(window.location.href);\n\t} else {\n\t\twindow.location.reload();\n\t}\n}\n\n\n\n/**\n * @namespace Navigation:changeCurrentUrl\n */\n\n/**\n * Changes the current URL by using the history API (this means, we can only change to a path on the same origin).\n * Be aware that this replaces the current URL in the history _without_ any normal navigation or reload.\n * This method only works if the history API is supported by the browser, otherwise no navigation will occur\n * (but a warning will be shown in console).\n * For more details on the history API see:\n * https://developer.mozilla.org/en-US/docs/Web/API/History\n *\n * @param {?String|URL} [url=null] - a url to change the current address to on the same origin, will use current URL if nullish\n * @param {?Boolean} [usePushState=false] - push new state instead of replacing current\n * @param {?*} [state=null] - a serializable object to append to the history state (gets retrieved on popState-event)\n * @param {?String} [title=null] - a name/title for the new state (as of yet, only Safari uses this, other browser will return undefined)\n * @throws error if state is not serializable by browser\n *\n * @memberof Navigation:changeCurrentUrl\n * @alias changeCurrentUrl\n * @see onHistoryChange\n * @see Urls.urlHref\n * @example\n * changeCurrentUrl('/article/important-stuff', false, {id : 666});\n */\nexport function changeCurrentUrl(url=null, usePushState=false, state=null, title=null){\n\turl = urlHref(url);\n\tusePushState = orDefault(usePushState, false, 'bool');\n\ttitle = orDefault(title, '', 'str');\n\n\tif ( browserSupportsHistoryManipulation() ) {\n\t\tif( usePushState ){\n\t\t\twindow.history.pushState(state, title, url);\n\t\t} else {\n\t\t\twindow.history.replaceState(state, title, url);\n\t\t}\n\n\t\tHISTORY.current = {\n\t\t\tstate,\n\t\t\ttitle,\n\t\t\thost : window.location.host,\n\t\t\tpath : window.location.pathname\n\t\t};\n\t} else {\n\t\twarn(`${MODULE_NAME}:changeCurrentUrl | this browser does not support history api, skipping`);\n\t}\n}\n\n\n\n/**\n * @namespace Navigation:onHistoryChange\n */\n\n/**\n * Registers an onpopstate event if history API is available (does nothing and warns if not available).\n * Takes a callback, which is provided with states as plain objects like: {state, title, host, path}.\n * Hint: do not rely on title, since that property may only be supported by browsers like Safari,\n * serialize everything important into state and use title as orientation only.\n *\n * In case of a regular binding all callbacks get the current state, so the state that is being changed to, but\n * if you set \"usePreviousState\" to true and prior navigation was done with \"changeCurrentUrl\", all callbacks\n * get two states: \"from\" and \"to\". With this you can define rules an behaviour depending on the state you are\n * coming from. Keep in mind: this only works if you use \"changeCurrentUrl\" for navigation in tandem with this method.\n *\n * @param {Function} callback - function to execute on popstate\n * @param {?Boolean} [clearOld=false] - defines if old handlers should be removed before setting new one\n * @param {?Boolean} [usePreviousState=false] - defines if callbacks should be provided with previous state as well (in that case, changeCurrentUrl must have been used for prior navigation)\n * @throws error if callback is no function\n *\n * @memberof Navigation:onHistoryChange\n * @alias onHistoryChange\n * @see changeCurrentUrl\n * @see offHistoryChange\n * @example\n * onHistoryChange(function(){ alert('Hey, don\\'t do this!'); }, true);\n */\nexport function onHistoryChange(callback, clearOld=false, usePreviousState=false){\n\tconst __methodName__ = 'onHistoryChange';\n\n\tclearOld = orDefault(clearOld, false, 'bool');\n\tusePreviousState = orDefault(usePreviousState, false, 'bool');\n\n\tassert(isFunction(callback), `${MODULE_NAME}:${__methodName__} | callback is no function`);\n\n\tif ( browserSupportsHistoryManipulation() ) {\n\t\tif( clearOld ){\n\t\t\tHISTORY.popState.callbacks = [];\n\t\t}\n\n\t\tconst statefulCallback = function(e, historyNew){\n\t\t\tif( usePreviousState ){\n\t\t\t\tcallback(HISTORY.current, historyNew);\n\t\t\t} else {\n\t\t\t\tcallback(historyNew);\n\t\t\t}\n\t\t};\n\n\t\tHISTORY.popState.callbacks.push({\n\t\t\toriginal : callback,\n\t\t\tstateful : statefulCallback\n\t\t});\n\n\t\tif( !HISTORY.popState.listening ){\n\t\t\tHISTORY.popState.listening = true;\n\n\t\t\twindow.addEventListener('popstate',\tHISTORY.popState.handler);\n\t\t}\n\t} else {\n\t\twarn(`${MODULE_NAME}:${__methodName__} | this browser does not support history api, skipping`);\n\t}\n}\n\n\n\n/**\n * @namespace Navigation:offHistoryChange\n */\n\n/**\n * Removes registered history change handlers, that have been created with \"onHistoryChange\".\n * If a callback is provided, that callback is removed from callbacks, if the function is called\n * without parameters all callbacks are removed and the event listener for the callbacks is removed.\n *\n * @param {?Function} [callback=true] - reference to the callback to be removed, if missing all callbacks are removed\n * @throws error if callback is no function\n * @return {Boolean} true if callback(s) are/were removed, false if nothing was done\n *\n * @memberof Navigation:offHistoryChange\n * @alias offHistoryChange\n * @see changeCurrentUrl\n * @see onHistoryChange\n * @example\n * offHistoryChange(thatOneCallback);\n * offHistoryChange();\n */\nexport function offHistoryChange(callback=null){\n\tconst __methodName__ = 'offHistoryChange';\n\n\tif( hasValue(callback) ){\n\t\tassert(isFunction(callback), `${MODULE_NAME}:${__methodName__} | callback is not a function`);\n\n\t\tconst oldCallbackCount = HISTORY.popState.callbacks.length;\n\t\tHISTORY.popState.callbacks = HISTORY.popState.callbacks.reduce((cbs, cb) => {\n\t\t\tif( cb.original !== callback ){\n\t\t\t\tcbs.push(cb);\n\t\t\t}\n\n\t\t\treturn cbs;\n\t\t}, []);\n\t\tconst newCallbackCount = HISTORY.popState.callbacks.length;\n\n\t\tif( newCallbackCount === 0 ){\n\t\t\twindow.removeEventListener('popstate', HISTORY.popState.handler);\n\t\t\tHISTORY.popState.listening = false;\n\t\t}\n\n\t\treturn oldCallbackCount > newCallbackCount;\n\t} else {\n\t\tHISTORY.popState.callbacks = [];\n\t\twindow.removeEventListener('popstate', HISTORY.popState.handler);\n\t\tHISTORY.popState.listening = false;\n\n\t\treturn true;\n\t}\n}\n"]} \ No newline at end of file +{"version":3,"file":"navigation.js","names":["MODULE_NAME","warn","hasValue","orDefault","isPlainObject","isArray","isWindow","isFunction","assert","createNode","browserSupportsHistoryManipulation","urlHref","HISTORY","current","state","title","getHostAndPathname","popState","listening","callbacks","handler","e","historyNew","forEach","cb","stateful","hostAndPathname","host","undefined","pathname","window","location","ex","redirect","url","params","anchor","target","postParams","markListParams","formAttributes","method","action","redirectForm","paramName","val","appendChild","type","name","value","document","body","submit","removeChild","URL","origin","eLink","createElement","href","rel","click","parentNode","open","assign","openTab","openWindow","options","parentWindow","tryAsPopup","windowName","optionArray","prop","includes","push","join","reload","cached","postUsable","form","replace","changeCurrentUrl","usePushState","history","pushState","replaceState","path","onHistoryChange","callback","clearOld","usePreviousState","__methodName__","statefulCallback","original","addEventListener","offHistoryChange","oldCallbackCount","length","reduce","cbs","newCallbackCount","removeEventListener"],"sources":["navigation.js"],"mappings":"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","ignoreList":[],"sourcesContent":["/*!\n * Module Navigation\n */\n\n/**\n * @namespace Navigation\n */\n\nconst MODULE_NAME = 'Navigation';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {warn} from './logging.js';\nimport {hasValue, orDefault, isPlainObject, isArray, isWindow, isFunction, assert} from './basic.js';\nimport {createNode} from './elements.js';\nimport {browserSupportsHistoryManipulation} from './context.js';\nimport {urlHref} from './urls.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const HISTORY = {\n\tcurrent : {\n\t\tstate : null,\n\t\ttitle : '',\n\t\t...getHostAndPathname()\n\t},\n\tpopState : {\n\t\tlistening : false,\n\t\tcallbacks : [],\n\t\thandler(e){\n\t\t\tconst historyNew = {\n\t\t\t\tstate : e.state,\n\t\t\t\ttitle : e.title,\n\t\t\t\t...getHostAndPathname()\n\t\t\t};\n\n\t\t\tHISTORY.popState.callbacks.forEach(cb => {\n\t\t\t\tcb.stateful(e, historyNew);\n\t\t\t});\n\n\t\t\tHISTORY.current = historyNew;\n\t\t}\n\t}\n};\n\n\n\n//###[ HELPERS ]########################################################################################################\n\nfunction getHostAndPathname(){\n\tconst hostAndPathname = {\n\t\thost : undefined,\n\t\tpathname : undefined\n\t};\n\n\ttry {\n\t\thostAndPathname.host = window.location.host;\n\t\thostAndPathname.pathname = window.location.pathname;\n\t} catch(ex){\n\t\thostAndPathname.host = undefined;\n\t\thostAndPathname.pathname = undefined;\n\t}\n\n\treturn hostAndPathname;\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Navigation:redirect\n */\n\n/**\n * Everything you need to do basic navigation without history API.\n *\n * Provide a URL to navigate to or leave the URL out, to use the current full URL. See `urlHref` for details.\n *\n * Add GET-parameters (adding to those already present in the URL), define an anchor (or automatically get the one\n * defined in the URL), set a target to define a window to navigate to (or open a new one) and even\n * define POST-parameters to navigate while providing POST-data.\n *\n * Provided params have to be a flat plain object, with ordinal values or arrays of ordinal values on the first level.\n * Everything else will be stringified and url-encoded as is. Usually, parameters defined here add to present\n * parameters in the URL. To force-override present values, declare the param name with a \"!\" prefix\n * (`{'!presentparam' : 'new'}`).\n *\n * If you define POST-params to navigate to a URL providing POST-data we internally build a custom form element,\n * with type \"post\", filled with hidden fields adding the form data, which we submit to navigate to the action, which\n * contains our url. Even the target carries over.\n *\n * If you define a target window and therefore open a new tab/window this function adds \"noopener,noreferrer\"\n * automatically if the origins do not match to increase security. If you need the opener, have a look at\n * \"openWindow\", which gives you more manual control in that regard.\n *\n * If you define a target and open an external URL, repeated calls to the same target will open multiple windows\n * due to the security settings.\n *\n * @param {?String|URL} [url=null] - the location to load, if null current location is reloaded/used\n * @param {?Object} [params=null] - plain object of GET-parameters to add to the url\n * @param {?String} [anchor=null] - anchor/hash to set for called url, has precedence over URL hash\n * @param {?String} [target=null] - name of the window to perform the redirect to/in, use \"_blank\" to open a new window/tab\n * @param {?Object} [postParams=null] - plain object of postParameters to send with the redirect, solved with a hidden form\n * @param {?Boolean} [markListParams=false] - if true, params with more than one value will be marked with \"[]\" preceding the param name\n * @throws error if url is not usable\n *\n * @memberof Navigation:redirect\n * @alias redirect\n * @see Urls.urlHref\n * @example\n * redirect('https://test.com', {search : 'kittens', order : 'asc'}, 'fluffykittens');\n * redirect(null, {order : 'desc'});\n */\nexport function redirect(url=null, params=null, anchor=null, target=null, postParams=null, markListParams=false){\n\turl = urlHref(url, params, anchor, markListParams);\n\ttarget = orDefault(target, null, 'str');\n\tpostParams = isPlainObject(postParams) ? postParams : null;\n\n\n\tif( hasValue(postParams) ){\n\t\tconst formAttributes = {method : 'post', action : url, 'data-ajax' : 'false'};\n\t\tif( hasValue(target) ){\n\t\t\tformAttributes.target = target;\n\t\t}\n\n\t\tconst redirectForm = createNode('form', formAttributes);\n\t\tfor( let paramName in postParams ){\n\t\t\tif( isArray(postParams[paramName]) ){\n\t\t\t\tpostParams[paramName].forEach(val => {\n\t\t\t\t\tredirectForm.appendChild(createNode(\n\t\t\t\t\t\t'input',\n\t\t\t\t\t\t{type : 'hidden', name : `${paramName}[]`, value : `${val}`}\n\t\t\t\t\t));\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tredirectForm.appendChild(createNode(\n\t\t\t\t\t'input',\n\t\t\t\t\t{type : 'hidden', name : paramName, value : `${postParams[paramName]}`}\n\t\t\t\t));\n\t\t\t}\n\t\t}\n\n\t\tdocument.body.appendChild(redirectForm);\n\t\tredirectForm.submit();\n\t\tdocument.body.removeChild(redirectForm);\n\t} else if( hasValue(target) ){\n\t\tconst parsedUrl = new URL(url);\n\n\t\tif( parsedUrl.origin !== window.location.origin ){\n\t\t\t// we have to jump through hoops here, since adding security features to window.open\n\t\t\t// forces popup windows in some browsers and although we can set opener via the created\n\t\t\t// window, we cannot reliably set the referrer that way\n\t\t\tconst eLink = document.createElement('a');\n\t\t\teLink.href = url;\n\t\t\teLink.target = target;\n\t\t\teLink.rel = 'noopener noreferrer';\n\t\t\tdocument.body.appendChild(eLink);\n\t\t\teLink.click();\n\t\t\teLink.parentNode.removeChild(eLink);\n\t\t} else {\n\t\t\twindow.open(url, target);\n\t\t}\n\t} else {\n\t\twindow.location.assign(url);\n\t}\n}\n\n\n\n/**\n * @namespace Navigation:openTab\n */\n\n/**\n * Opens a sub-window for the current window as _blank, which should result in a new tab in most browsers.\n *\n * This method is just a shortcut for \"redirect\" with a set target and reasonable parameters.\n *\n * By using \"redirect\", this method also automatically takes care of adding \"noopener,noreferrer\" to external\n * links, which are determined by not having the same origin as the current location. For more manual control\n * over such parameters, have a look at \"openWindow\" instead.\n *\n * @param {?String} [url] - the location to load, if null current location is reloaded/used\n * @param {?Object} [params=null] - plain object of GET-parameters to add to the url, adds to existing ones in the URL and overwrites existing ones with same name\n * @param {?String} [anchor=null] - anchor/hash to set for called url, has precedence over URL hash\n * @param {?Object} [postParams=null] - plain object of postParameters to send with the redirect, solved with a hidden form\n *\n * @memberof Navigation:openTab\n * @alias openTab\n * @see redirect\n * @example\n * openTab('/misc/faq.html');\n */\nexport function openTab(url, params=null, anchor=null, postParams=null){\n\tredirect(url, params, anchor, '_blank', postParams);\n}\n\n\n\n/**\n * @namespace Navigation:openWindow\n */\n\n/**\n * Opens a sub-window for the current window or another defined parent window.\n * Be aware that most browsers open new windows as a tab by default, have a look at the \"tryAsPopup\"-parameter\n * if you need to open a new standalone window and your configuration results in new tabs instead.\n *\n * For window options (in this implementation, we consider \"name\" to be an option as well), see:\n * https://developer.mozilla.org/en-US/docs/Web/API/Window/open#window_features\n *\n * Keep in mind to set \"noopener\" and/or \"noreferrer\" for external URLs in options, to improve security and privacy.\n * Hint for older MS browsers: if you set these security options, these will most likely open the URL in a popup\n * window. If you want to circumvent this, you'll have to drop the \"noreferrer\" and settle for \"noopener\", by\n * setting opener to null on the returned window like this: `openWindow('url').opener = null;`\n *\n * @param {?String|URL} [url=null] - the URL to load in the new window, if nullish, the current URL is used\n * @param {?Object} [options=null] - parameters for the new window according to the definitions of window.open & \"name\" for the window name\n * @param {?Window} [parentWindow=null] - parent window for the new window, current if not defined\n * @param {?Boolean} [tryAsPopup=false] - defines if it should be tried to force a real new window instead of a tab\n * @throws error if url is not usable\n * @returns {Window} the newly opened window/tab\n *\n * @memberof Navigation:openWindow\n * @alias openWindow\n * @see Urls.urlHref\n * @example\n * openWindow('/img/gallery.html');\n * openWindow('http://www.kittens.com', {name : 'kitten_popup'}, parent);\n */\nexport function openWindow(url=null, options=null, parentWindow=null, tryAsPopup=false){\n\turl = urlHref(url);\n\toptions = isPlainObject(options) ? options : null;\n\tparentWindow = isWindow(parentWindow) ? parentWindow : window;\n\ttryAsPopup = orDefault(tryAsPopup, false, 'bool');\n\n\tlet\twindowName = '';\n\tconst optionArray = [];\n\n\tif( hasValue(options) ){\n\t\tfor( let prop in options ){\n\t\t\tif( prop === 'name' ){\n\t\t\t\twindowName = options[prop];\n\t\t\t}\n\n\t\t\tif( (prop !== 'name') || tryAsPopup ){\n\t\t\t\tif( [true, 1, 'yes'].includes(options[prop]) ){\n\t\t\t\t\toptionArray.push(`${prop}`);\n\t\t\t\t} else {\n\t\t\t\t\toptionArray.push(`${prop}=${options[prop]}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn parentWindow.open(url, windowName, optionArray.join(','));\n}\n\n\n\n/**\n * @namespace Navigation:reload\n */\n\n/**\n * Reloads the current window-location. Differentiates between cached and cache-refreshing reload.\n * Hint: the forcedReload param in window.location.reload is deprecated and not supported anymore in all browsers,\n * so, in order to do a cache busting reload we have to use a trick, by using a POST-reload, since POST never\n * gets cached. If, for some reason, you cannot POST to a URL, I also provided a second, less effective fallback,\n * using \"replace\".\n *\n * Hint: depending on your browser a cached reload may keep the current scrolling position in the document, while\n * the uncached variants won't\n *\n * @param {?Boolean} [cached=true] - should we use the cache on reload?\n * @param {?Boolean} [postUsable=true] - if set to false, we try to replace URL instead of POSTing to it\n *\n * @memberof Navigation:reload\n * @alias reload\n * @example\n * // with cache\n * reload();\n * // without cache via POST\n * reload(false);\n * // without cache via \"replace\"\n * reload(false, false);\n */\nexport function reload(cached=true, postUsable=true){\n\tcached = orDefault(cached, true, 'bool');\n\tpostUsable = orDefault(postUsable, true, 'bool');\n\n\tif( !cached && postUsable ){\n\t\tconst form = document.createElement('form');\n\t\tform.method = 'post';\n\t\tform.action = window.location.href;\n\t\tdocument.body.appendChild(form);\n\t\tform.submit();\n\t\tdocument.body.removeChild(form);\n\t} else if( !cached && !postUsable ){\n\t\twindow.location.replace(window.location.href);\n\t} else {\n\t\twindow.location.reload();\n\t}\n}\n\n\n\n/**\n * @namespace Navigation:changeCurrentUrl\n */\n\n/**\n * Changes the current URL by using the history API (this means, we can only change to a path on the same origin).\n * Be aware that this replaces the current URL in the history _without_ any normal navigation or reload.\n * This method only works if the history API is supported by the browser, otherwise no navigation will occur\n * (but a warning will be shown in console).\n * For more details on the history API see:\n * https://developer.mozilla.org/en-US/docs/Web/API/History\n *\n * @param {?String|URL} [url=null] - a url to change the current address to on the same origin, will use current URL if nullish\n * @param {?Boolean} [usePushState=false] - push new state instead of replacing current\n * @param {?*} [state=null] - a serializable object to append to the history state (gets retrieved on popState-event)\n * @param {?String} [title=null] - a name/title for the new state (as of yet, only Safari uses this, other browser will return undefined)\n * @throws error if state is not serializable by browser\n *\n * @memberof Navigation:changeCurrentUrl\n * @alias changeCurrentUrl\n * @see onHistoryChange\n * @see Urls.urlHref\n * @example\n * changeCurrentUrl('/article/important-stuff', false, {id : 666});\n */\nexport function changeCurrentUrl(url=null, usePushState=false, state=null, title=null){\n\turl = urlHref(url);\n\tusePushState = orDefault(usePushState, false, 'bool');\n\ttitle = orDefault(title, '', 'str');\n\n\tif ( browserSupportsHistoryManipulation() ) {\n\t\tif( usePushState ){\n\t\t\twindow.history.pushState(state, title, url);\n\t\t} else {\n\t\t\twindow.history.replaceState(state, title, url);\n\t\t}\n\n\t\tHISTORY.current = {\n\t\t\tstate,\n\t\t\ttitle,\n\t\t\thost : window.location.host,\n\t\t\tpath : window.location.pathname\n\t\t};\n\t} else {\n\t\twarn(`${MODULE_NAME}:changeCurrentUrl | this browser does not support history api, skipping`);\n\t}\n}\n\n\n\n/**\n * @namespace Navigation:onHistoryChange\n */\n\n/**\n * Registers an onpopstate event if history API is available (does nothing and warns if not available).\n * Takes a callback, which is provided with states as plain objects like: {state, title, host, path}.\n * Hint: do not rely on title, since that property may only be supported by browsers like Safari,\n * serialize everything important into state and use title as orientation only.\n *\n * In case of a regular binding all callbacks get the current state, so the state that is being changed to, but\n * if you set \"usePreviousState\" to true and prior navigation was done with \"changeCurrentUrl\", all callbacks\n * get two states: \"from\" and \"to\". With this you can define rules an behaviour depending on the state you are\n * coming from. Keep in mind: this only works if you use \"changeCurrentUrl\" for navigation in tandem with this method.\n *\n * @param {Function} callback - function to execute on popstate\n * @param {?Boolean} [clearOld=false] - defines if old handlers should be removed before setting new one\n * @param {?Boolean} [usePreviousState=false] - defines if callbacks should be provided with previous state as well (in that case, changeCurrentUrl must have been used for prior navigation)\n * @throws error if callback is no function\n *\n * @memberof Navigation:onHistoryChange\n * @alias onHistoryChange\n * @see changeCurrentUrl\n * @see offHistoryChange\n * @example\n * onHistoryChange(function(){ alert('Hey, don\\'t do this!'); }, true);\n */\nexport function onHistoryChange(callback, clearOld=false, usePreviousState=false){\n\tconst __methodName__ = 'onHistoryChange';\n\n\tclearOld = orDefault(clearOld, false, 'bool');\n\tusePreviousState = orDefault(usePreviousState, false, 'bool');\n\n\tassert(isFunction(callback), `${MODULE_NAME}:${__methodName__} | callback is no function`);\n\n\tif ( browserSupportsHistoryManipulation() ) {\n\t\tif( clearOld ){\n\t\t\tHISTORY.popState.callbacks = [];\n\t\t}\n\n\t\tconst statefulCallback = function(e, historyNew){\n\t\t\tif( usePreviousState ){\n\t\t\t\tcallback(HISTORY.current, historyNew);\n\t\t\t} else {\n\t\t\t\tcallback(historyNew);\n\t\t\t}\n\t\t};\n\n\t\tHISTORY.popState.callbacks.push({\n\t\t\toriginal : callback,\n\t\t\tstateful : statefulCallback\n\t\t});\n\n\t\tif( !HISTORY.popState.listening ){\n\t\t\tHISTORY.popState.listening = true;\n\n\t\t\twindow.addEventListener('popstate',\tHISTORY.popState.handler);\n\t\t}\n\t} else {\n\t\twarn(`${MODULE_NAME}:${__methodName__} | this browser does not support history api, skipping`);\n\t}\n}\n\n\n\n/**\n * @namespace Navigation:offHistoryChange\n */\n\n/**\n * Removes registered history change handlers, that have been created with \"onHistoryChange\".\n * If a callback is provided, that callback is removed from callbacks, if the function is called\n * without parameters all callbacks are removed and the event listener for the callbacks is removed.\n *\n * @param {?Function} [callback=true] - reference to the callback to be removed, if missing all callbacks are removed\n * @throws error if callback is no function\n * @return {Boolean} true if callback(s) are/were removed, false if nothing was done\n *\n * @memberof Navigation:offHistoryChange\n * @alias offHistoryChange\n * @see changeCurrentUrl\n * @see onHistoryChange\n * @example\n * offHistoryChange(thatOneCallback);\n * offHistoryChange();\n */\nexport function offHistoryChange(callback=null){\n\tconst __methodName__ = 'offHistoryChange';\n\n\tif( hasValue(callback) ){\n\t\tassert(isFunction(callback), `${MODULE_NAME}:${__methodName__} | callback is not a function`);\n\n\t\tconst oldCallbackCount = HISTORY.popState.callbacks.length;\n\t\tHISTORY.popState.callbacks = HISTORY.popState.callbacks.reduce((cbs, cb) => {\n\t\t\tif( cb.original !== callback ){\n\t\t\t\tcbs.push(cb);\n\t\t\t}\n\n\t\t\treturn cbs;\n\t\t}, []);\n\t\tconst newCallbackCount = HISTORY.popState.callbacks.length;\n\n\t\tif( newCallbackCount === 0 ){\n\t\t\twindow.removeEventListener('popstate', HISTORY.popState.handler);\n\t\t\tHISTORY.popState.listening = false;\n\t\t}\n\n\t\treturn oldCallbackCount > newCallbackCount;\n\t} else {\n\t\tHISTORY.popState.callbacks = [];\n\t\twindow.removeEventListener('popstate', HISTORY.popState.handler);\n\t\tHISTORY.popState.listening = false;\n\n\t\treturn true;\n\t}\n}\n"]} \ No newline at end of file diff --git a/dist/objects.js b/dist/objects.js index 4e2c763c..3ad204c3 100644 --- a/dist/objects.js +++ b/dist/objects.js @@ -1,5 +1,5 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Objects diff --git a/dist/objects.js.map b/dist/objects.js.map index ecbe2473..0c5b4604 100644 --- a/dist/objects.js.map +++ b/dist/objects.js.map @@ -1 +1 @@ -{"version":3,"file":"objects.js","names":["MODULE_NAME","getType","isFunction","isPlainObject","orDefault","clone","target","deep","seenReferences","Array","from","arguments","seenCopies","indexOf","targetType","arrayCopy","push","i","length","setCopy","WeakSet","Set","forEach","value","add","mapCopy","WeakMap","Map","key","set","urlCopy","URL","urlSearchParamsCopy","URLSearchParams","toString","objectCopy","Object","create","getPrototypeOf","__proto__","prop","hasOwnProperty","fragment","document","createDocumentFragment","element","appendChild","item","childNodes","outerNode","createElement","innerHTML","outerHTML","firstChild","Date","getTime","RegExp","cloneNode","merge","base","extensions","extension","keys"],"sources":["objects.js"],"mappings":";;;AAQA,MAAMA,YAAc,iBAMZC,QAASC,WAAYC,cAAeC,cAAgB,oBA6CrD,SAASC,MAAMC,EAAQC,GAAK,GAGlC,GAFAA,EAAOH,UAAUG,GAAM,EAAM,QAEzBL,WAAWI,GAAQD,OACtB,OAAOC,EAAOD,MAAME,GAGrB,MACCC,EAAiBC,MAAMC,KAAKC,WAAW,IAAM,GAC7CC,EAAaH,MAAMC,KAAKC,WAAW,IAAM,GAG1C,GAAIH,EAAeK,QAAQP,IAAW,EACrC,OAAOM,EAAWJ,EAAeK,QAAQP,IAG1C,MAAMQ,EAAab,QAAQK,GAC3B,OAAQQ,GACP,IAAK,QACJ,MAAMC,EAAY,IAAIT,GAKtB,GAHAE,EAAeQ,KAAKV,GACpBM,EAAWI,KAAKD,GAEZR,EAAM,CACT,IAAIU,EAAIF,EAAUG,OAClB,KAAOD,KACNF,EAAUE,GAAKZ,MAAMU,EAAUE,GAAIV,EAAMC,EAAgBI,EAE3D,CAEA,OAAOG,EAER,IAAK,MACL,IAAK,UACJ,MAAMI,EAA0B,YAAfL,EACd,IAAIM,QACJ,IAAIC,IAcP,OAXAb,EAAeQ,KAAKV,GACpBM,EAAWI,KAAKG,GAEhBb,EAAOgB,SAAQC,IACVhB,EACHY,EAAQK,IAAInB,MAAMkB,EAAOhB,EAAMC,EAAgBI,IAE/CO,EAAQK,IAAID,EACb,IAGMJ,EAER,IAAK,MACL,IAAK,UACJ,MAAMM,EAA0B,YAAfX,EACd,IAAIY,QACJ,IAAIC,IAcP,OAXAnB,EAAeQ,KAAKV,GACpBM,EAAWI,KAAKS,GAEhBnB,EAAOgB,SAAQ,CAACC,EAAOK,KAClBrB,EACHkB,EAAQI,IAAID,EAAKvB,MAAMkB,EAAOhB,EAAMC,EAAgBI,IAEpDa,EAAQI,IAAID,EAAKL,EAClB,IAGME,EAER,IAAK,MACJ,MAAMK,EAAU,IAAIC,IAAIzB,GAKxB,OAHSE,EAAeQ,KAAKV,GACpBM,EAAWI,KAAKc,GAElBA,EAER,IAAK,kBACK,MAAME,EAAsB,IAAIC,gBAAgB3B,EAAO4B,YAKvD,OAHA1B,EAAeQ,KAAKV,GACpBM,EAAWI,KAAKgB,GAETA,EAEjB,IAAK,SACJ,MAAMG,EAAaC,OAAOC,OAAOD,OAAOE,eAAiBF,OAAOE,eAAehC,GAAUA,EAAOiC,WAEhG/B,EAAeQ,KAAKV,GACpBM,EAAWI,KAAKmB,GAEhB,IAAK,IAAIK,KAAQlC,EACZA,EAAOmC,eAAeD,KAExBL,EAAWK,GADRjC,EACgBF,MAAMC,EAAOkC,GAAOjC,EAAMC,EAAgBI,GAE1CN,EAAOkC,IAK7B,OAAOL,EAER,IAAK,WACJ,MAAMO,EAAWC,SAASC,yBAK1B,GAAIrC,EACHD,EAAOgB,SAAQuB,IACVtC,GACHmC,EAASI,YAAYzC,MAAMwC,EAAStC,EAAMC,EAAgBI,GAC3D,SAKD,KAAON,EAAOY,QACbwB,EAASI,YAAYxC,EAAOyC,KAAK,IAInC,OAAOL,EAASM,WAEjB,IAAK,aACJ,MAAMC,EAAYN,SAASO,cAAc,OAGzC,OAFAD,EAAUE,UAAY7C,EAAO8C,UAEtBH,EAAUI,WAElB,IAAK,OAAQ,OAAO,IAAIC,KAAKhD,EAAOiD,WACpC,IAAK,SAAU,OAAO,IAAIC,OAAOlD,GACjC,IAAK,cAAe,OAAOA,EAAOmD,UAAUlD,GAC5C,QAAS,OAAOD,EAElB,QAkCO,SAASoD,MAAMC,KAASC,GAqB9B,OApBAD,EAAOtD,MAAMsD,GAEblD,MAAMC,KAAKkD,GAAYtC,SAAQuC,IAC9BA,EAAYxD,MAAMwD,GAElB,IAAK,IAAIrB,KAAQqB,EACZA,EAAUpB,eAAeD,KAE3BmB,EAAKlB,eAAeD,IAChBrC,cAAcwD,EAAKnB,KAAUrC,cAAc0D,EAAUrB,KACrDJ,OAAO0B,KAAKD,EAAUrB,IAAOtB,OAAS,EAE1CyC,EAAKnB,GAAQkB,MAAMC,EAAKnB,GAAOqB,EAAUrB,IAEzCmB,EAAKnB,GAAQqB,EAAUrB,GAG1B,IAGMmB,CACR","sourcesContent":["/*!\n * Module Objects\n */\n\n/**\n * @namespace Objects\n */\n\nconst MODULE_NAME = 'Objects';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {getType, isFunction, isPlainObject, orDefault} from './basic.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Objects:clone\n */\n\n/**\n * Cloning arbitrary objects, values and structured values is no trivial task in JavaScript.\n * For basic values this can easily be achieved by serializing/deserializing via JSON.parse(JSON.stringify(value)), but\n * for everything not included in the JSON standard, such as nodes, sets, maps, functions and objects with constructors\n * this gets hairy pretty quickly.\n *\n * This function implements a fairly robust recursive cloning algorithm with circular dependency detection and should\n * be sufficient for 90% of your cloning needs. It can create deep and shallow copies, although I generally presume\n * that you need a deep copy if you are in need of a clone method to begin with. This method handles ordinal values,\n * regexes, dates and htmlelements/nodes, as well as nested structures consisting of arrays, plain objects,\n * simple constructed objects with settable properties, sets, maps and even nodelists.\n *\n * Be aware of these restrictions:\n * - map keys are not cloned since, if you would, you'd lose all access to values,\n * because you would have no valid references\n * - cloning a nodelist in a shallow manner results in the original list being empty afterwards, since moving a node\n * reference from one nodelist to another automatically removes the reference from the first, because a node may\n * only appear at exactly one place in a dom tree\n *\n * If this function does not suffice, have a look at lodash's cloneDeep method, which is a very robust and complete\n * (but large and complex) solution: https://www.npmjs.com/package/lodash.clonedeep\n *\n * @param {*} target - the object/value to clone\n * @param {?Boolean} [deep=true] - define if nested objects/values are to be cloned as well or just referenced in a shallow way\n * @returns {*} the cloned object/value\n *\n * @memberof Objects:clone\n * @alias clone\n * @example\n * const foo = {foo : 'bar', bar : [new Foobar(1, 2, 3), new Set([new Date('2021-03-09'), new RegExp('^foobar$')])]};\n * const allNewFoo = clone(foo);\n * const shallowNewFoo = clone(foo, false);\n * const thatOneTextAgain = clone(document.querySelector('p.that-one-text'));\n * thatOneTextAgain.classList.add('hooray');\n */\nexport function clone(target, deep=true){\n\tdeep = orDefault(deep, true, 'bool');\n\n\tif( isFunction(target?.clone) ){\n\t\treturn target.clone(deep);\n\t}\n\n\tconst\n\t\tseenReferences = Array.from(arguments)[2] ?? [],\n\t\tseenCopies = Array.from(arguments)[3] ?? []\n\t;\n\n\tif( seenReferences.indexOf(target) >= 0 ){\n\t\treturn seenCopies[seenReferences.indexOf(target)];\n\t}\n\n\tconst targetType = getType(target);\n\tswitch( targetType ){\n\t\tcase 'array':\n\t\t\tconst arrayCopy = [...target];\n\n\t\t\tseenReferences.push(target);\n\t\t\tseenCopies.push(arrayCopy);\n\n\t\t\tif( deep ){\n\t\t\t\tlet i = arrayCopy.length;\n\t\t\t\twhile( i-- ){\n\t\t\t\t\tarrayCopy[i] = clone(arrayCopy[i], deep, seenReferences, seenCopies);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn arrayCopy;\n\n\t\tcase 'set':\n\t\tcase 'weakset':\n\t\t\tconst setCopy = (targetType === 'weakset')\n\t\t\t\t? new WeakSet()\n\t\t\t\t: new Set()\n\t\t\t;\n\n\t\t\tseenReferences.push(target);\n\t\t\tseenCopies.push(setCopy);\n\n\t\t\ttarget.forEach(value => {\n\t\t\t\tif( deep ){\n\t\t\t\t\tsetCopy.add(clone(value, deep, seenReferences, seenCopies));\n\t\t\t\t} else {\n\t\t\t\t\tsetCopy.add(value);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn setCopy;\n\n\t\tcase 'map':\n\t\tcase 'weakmap':\n\t\t\tconst mapCopy = (targetType === 'weakmap')\n\t\t\t\t? new WeakMap()\n\t\t\t\t: new Map()\n\t\t\t;\n\n\t\t\tseenReferences.push(target);\n\t\t\tseenCopies.push(mapCopy);\n\n\t\t\ttarget.forEach((value, key) => {\n\t\t\t\tif( deep ){\n\t\t\t\t\tmapCopy.set(key, clone(value, deep, seenReferences, seenCopies));\n\t\t\t\t} else {\n\t\t\t\t\tmapCopy.set(key, value);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn mapCopy;\n\n\t\tcase 'url':\n\t\t\tconst urlCopy = new URL(target);\n\n seenReferences.push(target);\n seenCopies.push(urlCopy);\n\n\t\t\treturn urlCopy;\n\n\t\tcase 'urlsearchparams':\n const urlSearchParamsCopy = new URLSearchParams(target.toString());\n\n seenReferences.push(target);\n seenCopies.push(urlSearchParamsCopy);\n\n return urlSearchParamsCopy;\n\n\t\tcase 'object':\n\t\t\tconst objectCopy = Object.create(Object.getPrototypeOf ? Object.getPrototypeOf(target) : target.__proto__);\n\n\t\t\tseenReferences.push(target);\n\t\t\tseenCopies.push(objectCopy);\n\n\t\t\tfor( let prop in target ){\n\t\t\t\tif( target.hasOwnProperty(prop) ){\n\t\t\t\t\tif( deep ){\n\t\t\t\t\t\tobjectCopy[prop] = clone(target[prop], deep, seenReferences, seenCopies);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tobjectCopy[prop] = target[prop];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn objectCopy;\n\n\t\tcase 'nodelist':\n\t\t\tconst fragment = document.createDocumentFragment();\n\n\t\t\t// no optimization with seenReferences or seenCopies, since, in a dom tree, we cannot reuse\n\t\t\t// references or elements, since that would mean reattaching a node, which would move the node\n\n\t\t\tif( deep ){\n\t\t\t\ttarget.forEach(element => {\n\t\t\t\t\tif( deep ){\n\t\t\t\t\t\tfragment.appendChild(clone(element, deep, seenReferences, seenCopies));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t// shallow copying a nodelist is destructive, since appending the original element, empties the original\n\t\t\t// list, since every node may only exist once inside a dom\n\t\t\t} else {\n\t\t\t\twhile( target.length ){\n\t\t\t\t\tfragment.appendChild(target.item(0));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn fragment.childNodes;\n\n\t\tcase 'svgelement':\n\t\t\tconst outerNode = document.createElement('div');\n\t\t\touterNode.innerHTML = target.outerHTML;\n\n\t\t\treturn outerNode.firstChild;\n\n\t\tcase 'date': return new Date(target.getTime());\n\t\tcase 'regexp': return new RegExp(target);\n\t\tcase 'htmlelement': return target.cloneNode(deep);\n\t\tdefault: return target;\n\t}\n}\n\n\n\n/**\n * @namespace Objects:merge\n */\n\n/**\n * Merging objects in JS is easy, using spread operators, as long as we are talking about shallow merging of the first\n * level. This method aims to deep merge recursively, always returning a new object, never touching or changing the\n * original one.\n *\n * This method implements LIFO precedence: the last extension wins.\n *\n * Possible differences to other implementations (like lodash's):\n * - arrays are not concatenated here, but replaced.\n * - explicitly extending an empty object, replaces the value with the empty object instead of doing nothing\n * - all involved objects are cloned, so references in the resulting object will differ\n *\n * @param {Object} base - the object to extend\n * @param {Array} extensions - one or more objects to merge into base sequentially, the last taking precedence\n * @returns {Object} the (newly created) merged object\n *\n * @memberof Objects:merge\n * @alias merge\n * @example\n * merge(\n * {ducks : {uncles : ['Donald', 'Scrooge'], nephews : {huey : true}}},\n * {ducks : {nephews : {dewey : true}}, mice : ['Mickey']},\n * {ducks : {uncles : ['Gladstone'], nephews : {louie : true}}, mice : ['Mickey', 'Minnie']}\n * )\n * => {ducks : {uncles : ['Gladstone'], nephews : {huey : true, dewey : true, louie : true}}, mice : ['Mickey', 'Minnie']}\n */\nexport function merge(base, ...extensions){\n\tbase = clone(base);\n\n\tArray.from(extensions).forEach(extension => {\n\t\textension = clone(extension);\n\n\t\tfor( let prop in extension ){\n\t\t\tif( extension.hasOwnProperty(prop) ){\n\t\t\t\tif(\n\t\t\t\t\tbase.hasOwnProperty(prop)\n\t\t\t\t\t&& (isPlainObject(base[prop]) && isPlainObject(extension[prop]))\n\t\t\t\t\t&& (Object.keys(extension[prop]).length > 0)\n\t\t\t\t){\n\t\t\t\t\tbase[prop] = merge(base[prop], extension[prop]);\n\t\t\t\t} else {\n\t\t\t\t\tbase[prop] = extension[prop];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\treturn base;\n}\n"]} \ No newline at end of file +{"version":3,"file":"objects.js","names":["MODULE_NAME","getType","isFunction","isPlainObject","orDefault","clone","target","deep","seenReferences","Array","from","arguments","seenCopies","indexOf","targetType","arrayCopy","push","i","length","setCopy","WeakSet","Set","forEach","value","add","mapCopy","WeakMap","Map","key","set","urlCopy","URL","urlSearchParamsCopy","URLSearchParams","toString","objectCopy","Object","create","getPrototypeOf","__proto__","prop","hasOwnProperty","fragment","document","createDocumentFragment","element","appendChild","item","childNodes","outerNode","createElement","innerHTML","outerHTML","firstChild","Date","getTime","RegExp","cloneNode","merge","base","extensions","extension","keys"],"sources":["objects.js"],"mappings":"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","ignoreList":[],"sourcesContent":["/*!\n * Module Objects\n */\n\n/**\n * @namespace Objects\n */\n\nconst MODULE_NAME = 'Objects';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {getType, isFunction, isPlainObject, orDefault} from './basic.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Objects:clone\n */\n\n/**\n * Cloning arbitrary objects, values and structured values is no trivial task in JavaScript.\n * For basic values this can easily be achieved by serializing/deserializing via JSON.parse(JSON.stringify(value)), but\n * for everything not included in the JSON standard, such as nodes, sets, maps, functions and objects with constructors\n * this gets hairy pretty quickly.\n *\n * This function implements a fairly robust recursive cloning algorithm with circular dependency detection and should\n * be sufficient for 90% of your cloning needs. It can create deep and shallow copies, although I generally presume\n * that you need a deep copy if you are in need of a clone method to begin with. This method handles ordinal values,\n * regexes, dates and htmlelements/nodes, as well as nested structures consisting of arrays, plain objects,\n * simple constructed objects with settable properties, sets, maps and even nodelists.\n *\n * Be aware of these restrictions:\n * - map keys are not cloned since, if you would, you'd lose all access to values,\n * because you would have no valid references\n * - cloning a nodelist in a shallow manner results in the original list being empty afterwards, since moving a node\n * reference from one nodelist to another automatically removes the reference from the first, because a node may\n * only appear at exactly one place in a dom tree\n *\n * If this function does not suffice, have a look at lodash's cloneDeep method, which is a very robust and complete\n * (but large and complex) solution: https://www.npmjs.com/package/lodash.clonedeep\n *\n * @param {*} target - the object/value to clone\n * @param {?Boolean} [deep=true] - define if nested objects/values are to be cloned as well or just referenced in a shallow way\n * @returns {*} the cloned object/value\n *\n * @memberof Objects:clone\n * @alias clone\n * @example\n * const foo = {foo : 'bar', bar : [new Foobar(1, 2, 3), new Set([new Date('2021-03-09'), new RegExp('^foobar$')])]};\n * const allNewFoo = clone(foo);\n * const shallowNewFoo = clone(foo, false);\n * const thatOneTextAgain = clone(document.querySelector('p.that-one-text'));\n * thatOneTextAgain.classList.add('hooray');\n */\nexport function clone(target, deep=true){\n\tdeep = orDefault(deep, true, 'bool');\n\n\tif( isFunction(target?.clone) ){\n\t\treturn target.clone(deep);\n\t}\n\n\tconst\n\t\tseenReferences = Array.from(arguments)[2] ?? [],\n\t\tseenCopies = Array.from(arguments)[3] ?? []\n\t;\n\n\tif( seenReferences.indexOf(target) >= 0 ){\n\t\treturn seenCopies[seenReferences.indexOf(target)];\n\t}\n\n\tconst targetType = getType(target);\n\tswitch( targetType ){\n\t\tcase 'array':\n\t\t\tconst arrayCopy = [...target];\n\n\t\t\tseenReferences.push(target);\n\t\t\tseenCopies.push(arrayCopy);\n\n\t\t\tif( deep ){\n\t\t\t\tlet i = arrayCopy.length;\n\t\t\t\twhile( i-- ){\n\t\t\t\t\tarrayCopy[i] = clone(arrayCopy[i], deep, seenReferences, seenCopies);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn arrayCopy;\n\n\t\tcase 'set':\n\t\tcase 'weakset':\n\t\t\tconst setCopy = (targetType === 'weakset')\n\t\t\t\t? new WeakSet()\n\t\t\t\t: new Set()\n\t\t\t;\n\n\t\t\tseenReferences.push(target);\n\t\t\tseenCopies.push(setCopy);\n\n\t\t\ttarget.forEach(value => {\n\t\t\t\tif( deep ){\n\t\t\t\t\tsetCopy.add(clone(value, deep, seenReferences, seenCopies));\n\t\t\t\t} else {\n\t\t\t\t\tsetCopy.add(value);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn setCopy;\n\n\t\tcase 'map':\n\t\tcase 'weakmap':\n\t\t\tconst mapCopy = (targetType === 'weakmap')\n\t\t\t\t? new WeakMap()\n\t\t\t\t: new Map()\n\t\t\t;\n\n\t\t\tseenReferences.push(target);\n\t\t\tseenCopies.push(mapCopy);\n\n\t\t\ttarget.forEach((value, key) => {\n\t\t\t\tif( deep ){\n\t\t\t\t\tmapCopy.set(key, clone(value, deep, seenReferences, seenCopies));\n\t\t\t\t} else {\n\t\t\t\t\tmapCopy.set(key, value);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn mapCopy;\n\n\t\tcase 'url':\n\t\t\tconst urlCopy = new URL(target);\n\n seenReferences.push(target);\n seenCopies.push(urlCopy);\n\n\t\t\treturn urlCopy;\n\n\t\tcase 'urlsearchparams':\n const urlSearchParamsCopy = new URLSearchParams(target.toString());\n\n seenReferences.push(target);\n seenCopies.push(urlSearchParamsCopy);\n\n return urlSearchParamsCopy;\n\n\t\tcase 'object':\n\t\t\tconst objectCopy = Object.create(Object.getPrototypeOf ? Object.getPrototypeOf(target) : target.__proto__);\n\n\t\t\tseenReferences.push(target);\n\t\t\tseenCopies.push(objectCopy);\n\n\t\t\tfor( let prop in target ){\n\t\t\t\tif( target.hasOwnProperty(prop) ){\n\t\t\t\t\tif( deep ){\n\t\t\t\t\t\tobjectCopy[prop] = clone(target[prop], deep, seenReferences, seenCopies);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tobjectCopy[prop] = target[prop];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn objectCopy;\n\n\t\tcase 'nodelist':\n\t\t\tconst fragment = document.createDocumentFragment();\n\n\t\t\t// no optimization with seenReferences or seenCopies, since, in a dom tree, we cannot reuse\n\t\t\t// references or elements, since that would mean reattaching a node, which would move the node\n\n\t\t\tif( deep ){\n\t\t\t\ttarget.forEach(element => {\n\t\t\t\t\tif( deep ){\n\t\t\t\t\t\tfragment.appendChild(clone(element, deep, seenReferences, seenCopies));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t// shallow copying a nodelist is destructive, since appending the original element, empties the original\n\t\t\t// list, since every node may only exist once inside a dom\n\t\t\t} else {\n\t\t\t\twhile( target.length ){\n\t\t\t\t\tfragment.appendChild(target.item(0));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn fragment.childNodes;\n\n\t\tcase 'svgelement':\n\t\t\tconst outerNode = document.createElement('div');\n\t\t\touterNode.innerHTML = target.outerHTML;\n\n\t\t\treturn outerNode.firstChild;\n\n\t\tcase 'date': return new Date(target.getTime());\n\t\tcase 'regexp': return new RegExp(target);\n\t\tcase 'htmlelement': return target.cloneNode(deep);\n\t\tdefault: return target;\n\t}\n}\n\n\n\n/**\n * @namespace Objects:merge\n */\n\n/**\n * Merging objects in JS is easy, using spread operators, as long as we are talking about shallow merging of the first\n * level. This method aims to deep merge recursively, always returning a new object, never touching or changing the\n * original one.\n *\n * This method implements LIFO precedence: the last extension wins.\n *\n * Possible differences to other implementations (like lodash's):\n * - arrays are not concatenated here, but replaced.\n * - explicitly extending an empty object, replaces the value with the empty object instead of doing nothing\n * - all involved objects are cloned, so references in the resulting object will differ\n *\n * @param {Object} base - the object to extend\n * @param {Array} extensions - one or more objects to merge into base sequentially, the last taking precedence\n * @returns {Object} the (newly created) merged object\n *\n * @memberof Objects:merge\n * @alias merge\n * @example\n * merge(\n * {ducks : {uncles : ['Donald', 'Scrooge'], nephews : {huey : true}}},\n * {ducks : {nephews : {dewey : true}}, mice : ['Mickey']},\n * {ducks : {uncles : ['Gladstone'], nephews : {louie : true}}, mice : ['Mickey', 'Minnie']}\n * )\n * => {ducks : {uncles : ['Gladstone'], nephews : {huey : true, dewey : true, louie : true}}, mice : ['Mickey', 'Minnie']}\n */\nexport function merge(base, ...extensions){\n\tbase = clone(base);\n\n\tArray.from(extensions).forEach(extension => {\n\t\textension = clone(extension);\n\n\t\tfor( let prop in extension ){\n\t\t\tif( extension.hasOwnProperty(prop) ){\n\t\t\t\tif(\n\t\t\t\t\tbase.hasOwnProperty(prop)\n\t\t\t\t\t&& (isPlainObject(base[prop]) && isPlainObject(extension[prop]))\n\t\t\t\t\t&& (Object.keys(extension[prop]).length > 0)\n\t\t\t\t){\n\t\t\t\t\tbase[prop] = merge(base[prop], extension[prop]);\n\t\t\t\t} else {\n\t\t\t\t\tbase[prop] = extension[prop];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\treturn base;\n}\n"]} \ No newline at end of file diff --git a/dist/polling.js b/dist/polling.js index 996880d4..cd470606 100644 --- a/dist/polling.js +++ b/dist/polling.js @@ -1,5 +1,5 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Polling diff --git a/dist/polling.js.map b/dist/polling.js.map index b49ee93c..e66f89c7 100644 --- a/dist/polling.js.map +++ b/dist/polling.js.map @@ -1 +1 @@ -{"version":3,"file":"polling.js","names":["MODULE_NAME","orDefault","isFunction","isObject","assert","hasValue","loop","countermand","POLLS","defaultLoop","activePollCount","activePolls","POLL_DEFAULT_LOOP_MS","poll","name","fCondition","fAction","fElseAction","newLoopMs","useOwnTimer","trim","newPoll","condition","action","elseAction","lastPollResult","isActive","fire","changed","unpoll","hasOwnProperty"],"sources":["polling.js"],"mappings":";;;AAQA,MAAMA,YAAc,iBAMZC,UAAWC,WAAYC,SAAUC,OAAQC,aAAe,oBACxDC,KAAMC,gBAAkB,qBAMzB,MAAMC,MAAQ,CACpBC,YAAc,KACdC,gBAAkB,EAClBC,YAAc,CAAC,GAGhB,MAAMC,qBAAuB,WAyCtB,SAASC,KAAKC,EAAMC,EAAYC,EAASC,EAAY,KAAMC,EAzCrC,IAyCqEC,GAAY,GAC7GL,EAAOb,UAAUa,EAAM,GAAI,OAAOM,OAClCH,EAAcf,WAAWe,GAAeA,EAAc,OACtDC,EAAYjB,UAAUiB,EA5CM,IA4C2B,OACvDC,EAAclB,UAAUkB,GAAa,EAAO,QAE5Cf,OAAgB,KAATU,EAAa,kCACpBV,OAAOF,WAAWa,GAAa,+CAC/BX,OAAOF,WAAWc,GAAU,4CAE5B,MAAMK,EAAU,CACfP,OACAQ,UAAWP,EACXQ,OAASP,EACTQ,WAAaP,EACbX,KAAO,KACPmB,gBAAiB,EACjBC,UAAW,EACXC,KAAKC,EAAQ,MACRvB,SAASG,MAAMG,YAAYU,EAAQP,SAClCO,EAAQC,cACgF,IAAvFD,EAAQE,OAAOlB,SAASuB,KAAaA,GAAsC,IAA3BP,EAAQI,kBACvDpB,SAASgB,EAAQf,QACpBC,YAAYc,EAAQf,MACpBe,EAAQf,KAAO,MAEhBe,EAAQK,UAAW,SACZlB,MAAMG,YAAYU,EAAQP,MACjCN,MAAME,mBAEPW,EAAQI,gBAAiB,IAEzBJ,EAAQG,WAAWnB,SAASuB,KAAaA,GAAsC,IAA3BP,EAAQI,gBAC5DJ,EAAQI,gBAAiB,GAG5B,GA2CD,OAxCIN,IACHE,EAAQf,KAAOA,KAAKY,GAAW,WAC9BG,EAAQM,MACT,KAGGtB,SAASG,MAAMG,YAAYG,KAC9Be,OAAOf,GAERN,MAAMG,YAAYG,GAAQO,EAC1Bb,MAAME,oBAIHL,SAASG,MAAMC,cA9FU,MA+FrBS,IAAwCC,IAE1CX,MAAME,gBAAkB,IAExBL,SAASG,MAAMC,cAClBF,YAAYC,MAAMC,aAGnBD,MAAMC,YAAcH,KAAKY,GAAW,WACnC,GAAIV,MAAME,gBAAkB,GAC3B,IAAK,IAAII,KAAQN,MAAMG,YACtB,GAAIH,MAAMG,YAAYmB,eAAehB,GAAO,CAC3C,MAAMD,EAAOL,MAAMG,YAAYG,GAC1BT,SAASQ,EAAKP,OAClBO,EAAKc,MAEP,OAGDpB,YAAYC,MAAMC,aAClBD,MAAMC,YAAc,IAEtB,KAGMY,CACR,QAqBO,SAASQ,OAAOhB,GACtB,MAAMC,EAAQX,SAASU,IAASR,SAASQ,EAAKC,MAAS,GAAGD,EAAKC,OAAS,GAAGD,IAAOO,OAClF,MAAa,KAATN,IAEJD,EAAOL,MAAMG,YAAYG,KACpBT,SAASQ,KAEVR,SAASQ,EAAKP,OACjBC,YAAYM,EAAKP,MAGlBO,EAAKa,UAAW,SACTlB,MAAMG,YAAYE,EAAKC,MAC9BN,MAAME,kBAEFF,MAAME,iBAAmB,IAC5BH,YAAYC,MAAMC,aAClBD,MAAMC,YAAc,KACpBD,MAAME,gBAAkB,IAGlB,GACR","sourcesContent":["/*!\n * Module Polling\n */\n\n/**\n * @namespace Polling\n */\n\nconst MODULE_NAME = 'Polling';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {orDefault, isFunction, isObject, assert, hasValue} from './basic.js';\nimport {loop, countermand} from './timers.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const POLLS = {\n\tdefaultLoop : null,\n\tactivePollCount : 0,\n\tactivePolls : {}\n};\n\nconst POLL_DEFAULT_LOOP_MS = 250;\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Polling:poll\n */\n\n/**\n * Waits for a certain program- or DOM-state before executing a certain action. Waiting is implemented via\n * a global timer (and optionally locals as well). If you need to react to a certain case, that's not\n * defined by standard events and reaction does not have to be razor sharp, this is your method.\n * Pick a name for the state/event you want to poll, define a condition closure and an action closure that\n * holds what is to be done in case the condition works out.\n * Polls end or are repeated after an execution of the action depending on the result of the action closure.\n * There can always be only one poll of a certain name, redefining it overwrites the first one.\n *\n * If you need to evaluate a poll out of the line, to trigger a sharp synchronous evaluation due to an event\n * for example, you can use the \"fire\" method of the poll object itself, which will trigger the condition and all\n * subsequent actions. You can provide a boolean parameter to this function to override manually if the result\n * should be considered changed to the last run. You can only fire polls, that are still active, you can check this\n * state easily via \"isActive\" on the poll.\n *\n * @param {String} name - name of the state or event you are waiting/polling for\n * @param {Function} fCondition - closure to define the state to wait for, returns true if state exists and false if not\n * @param {Function} fAction - closure to define action to take place if condition is fulfilled, poll removes itself if this evaluates to true, receives Boolean parameter defining if condition result has changed since last call\n * @param {?Function} [fElseAction=null] - closure to define action to take place if condition is not fulfilled, receives Boolean parameter defining if condition result has changed since last call\n * @param {?Number} [newLoopMs=250] - sets interval length from here on, resets global loop if useOwnTimer is not set, otherwise sets local interval for that poll poll\n * @param {?Boolean} [useOwnTimer=false] - has to be true to tell the poll to use an independent local timer instead of the global one, use this if you need different levels of fuzziness for you polls, performance-wise it's better to have less independent intervals running\n * @throws error in case name, fCondition or fAction are missing or unfit to use\n * @returns {Object} new poll - structure: {name, condition, action, elseAction, loop, lastPollResult, isActive, fire()}\n *\n * @memberof Polling:poll\n * @alias poll\n * @see unpoll\n * @example\n * const pollBodyHeightPermanently = poll('permanent-body-height-poll', function(){ return document.body.scrollHeight > 1000; }, function(changed){ console.log(`too high${changed ? ' as of yet' : ''}!`); }, null, 5000);\n * const pollBodyHeightAndStopIfHighEnough = poll('one-time-body-height-poll', function(){ return document.body.scrollHeight > 1000; }, function(){ console.log('high enough!'); return true; }, function(){ console.log('not high enough yet :(') }, null, true);\n */\nexport function poll(name, fCondition, fAction, fElseAction=null, newLoopMs=POLL_DEFAULT_LOOP_MS, useOwnTimer=false){\n\tname = orDefault(name, '', 'str').trim();\n\tfElseAction = isFunction(fElseAction) ? fElseAction : () => {};\n\tnewLoopMs = orDefault(newLoopMs, POLL_DEFAULT_LOOP_MS, 'int');\n\tuseOwnTimer = orDefault(useOwnTimer, false, 'bool');\n\n\tassert(name !== '', `${MODULE_NAME}:poll | name is missing`);\n\tassert(isFunction(fCondition), `${MODULE_NAME}:poll | fCondition is not a function`);\n\tassert(isFunction(fAction), `${MODULE_NAME}:poll | fAction is not a function`);\n\n\tconst newPoll = {\n\t\tname,\n\t\tcondition: fCondition,\n\t\taction : fAction,\n\t\telseAction : fElseAction,\n\t\tloop : null,\n\t\tlastPollResult : false,\n\t\tisActive : true,\n\t\tfire(changed=null){\n\t\t\tif( hasValue(POLLS.activePolls[newPoll.name]) ){\n\t\t\t\tif( newPoll.condition() ){\n\t\t\t\t\tif( newPoll.action(hasValue(changed) ? !!changed : (newPoll.lastPollResult === false)) === true ){\n\t\t\t\t\t\tif( hasValue(newPoll.loop) ){\n\t\t\t\t\t\t\tcountermand(newPoll.loop);\n\t\t\t\t\t\t\tnewPoll.loop = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnewPoll.isActive = false;\n\t\t\t\t\t\tdelete POLLS.activePolls[newPoll.name];\n\t\t\t\t\t\tPOLLS.activePollCount--;\n\t\t\t\t\t}\n\t\t\t\t\tnewPoll.lastPollResult = true;\n\t\t\t\t} else {\n\t\t\t\t\tnewPoll.elseAction(hasValue(changed) ? !!changed : (newPoll.lastPollResult === true));\n\t\t\t\t\tnewPoll.lastPollResult = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tif( useOwnTimer ){\n\t\tnewPoll.loop = loop(newLoopMs, function(){\n\t\t\tnewPoll.fire();\n\t\t});\n\t}\n\n\tif( hasValue(POLLS.activePolls[name]) ){\n\t\tunpoll(name);\n\t}\n\tPOLLS.activePolls[name] = newPoll;\n\tPOLLS.activePollCount++;\n\n\tif(\n\t\t(\n\t\t\t!hasValue(POLLS.defaultLoop)\n\t\t\t|| ((newLoopMs !== POLL_DEFAULT_LOOP_MS) && !useOwnTimer)\n\t\t)\n\t\t&& (POLLS.activePollCount > 0)\n\t){\n\t\tif( hasValue(POLLS.defaultLoop) ){\n\t\t\tcountermand(POLLS.defaultLoop);\n\t\t}\n\n\t\tPOLLS.defaultLoop = loop(newLoopMs, function(){\n\t\t\tif( POLLS.activePollCount > 0 ){\n\t\t\t\tfor( let name in POLLS.activePolls ){\n\t\t\t\t\tif( POLLS.activePolls.hasOwnProperty(name) ){\n\t\t\t\t\t\tconst poll = POLLS.activePolls[name];\n\t\t\t\t\t\tif( !hasValue(poll.loop) ){\n\t\t\t\t\t\t\tpoll.fire();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcountermand(POLLS.defaultLoop);\n\t\t\t\tPOLLS.defaultLoop = null;\n\t\t\t}\n\t\t});\n\t}\n\n\treturn newPoll;\n}\n\n\n\n/**\n * @namespace Polling:unpoll\n */\n\n/**\n * Removes an active poll.\n *\n * @param {String|Object} poll - name of the poll to be removed or the poll object itself\n * @returns {Boolean} true if poll has been removed, false if poll has not been found\n *\n * @memberof Polling:unpoll\n * @alias unpoll\n * @see poll\n * @example\n * unpoll('permanent-body-height-poll');\n * unpoll(pollBodyHeightAndStopIfHighEnough);\n */\nexport function unpoll(poll){\n\tconst name = (isObject(poll) && hasValue(poll.name)) ? `${poll.name}` : `${poll}`.trim();\n\tif( name === '' ) return false;\n\n\tpoll = POLLS.activePolls[name];\n\tif( !hasValue(poll) ) return false;\n\n\tif( hasValue(poll.loop) ){\n\t\tcountermand(poll.loop);\n\t}\n\n\tpoll.isActive = false;\n\tdelete POLLS.activePolls[poll.name];\n\tPOLLS.activePollCount--;\n\n\tif( POLLS.activePollCount <= 0 ){\n\t\tcountermand(POLLS.defaultLoop);\n\t\tPOLLS.defaultLoop = null;\n\t\tPOLLS.activePollCount = 0;\n\t}\n\n\treturn true;\n}\n"]} \ No newline at end of file +{"version":3,"file":"polling.js","names":["MODULE_NAME","orDefault","isFunction","isObject","assert","hasValue","loop","countermand","POLLS","defaultLoop","activePollCount","activePolls","POLL_DEFAULT_LOOP_MS","poll","name","fCondition","fAction","fElseAction","newLoopMs","useOwnTimer","trim","newPoll","condition","action","elseAction","lastPollResult","isActive","fire","changed","unpoll","hasOwnProperty"],"sources":["polling.js"],"mappings":";;;AAQA,MAAMA,YAAc,iBAMZC,UAAWC,WAAYC,SAAUC,OAAQC,aAAe,oBACxDC,KAAMC,gBAAkB,qBAMzB,MAAMC,MAAQ,CACpBC,YAAc,KACdC,gBAAkB,EAClBC,YAAc,CAAC,GAGhB,MAAMC,qBAAuB,WAyCtB,SAASC,KAAKC,EAAMC,EAAYC,EAASC,EAAY,KAAMC,EAzCrC,IAyCqEC,GAAY,GAC7GL,EAAOb,UAAUa,EAAM,GAAI,OAAOM,OAClCH,EAAcf,WAAWe,GAAeA,EAAc,OACtDC,EAAYjB,UAAUiB,EA5CM,IA4C2B,OACvDC,EAAclB,UAAUkB,GAAa,EAAO,QAE5Cf,OAAgB,KAATU,EAAa,kCACpBV,OAAOF,WAAWa,GAAa,+CAC/BX,OAAOF,WAAWc,GAAU,4CAE5B,MAAMK,EAAU,CACfP,OACAQ,UAAWP,EACXQ,OAASP,EACTQ,WAAaP,EACbX,KAAO,KACPmB,gBAAiB,EACjBC,UAAW,EACX,IAAAC,CAAKC,EAAQ,MACRvB,SAASG,MAAMG,YAAYU,EAAQP,SAClCO,EAAQC,cACgF,IAAvFD,EAAQE,OAAOlB,SAASuB,KAAaA,GAAsC,IAA3BP,EAAQI,kBACvDpB,SAASgB,EAAQf,QACpBC,YAAYc,EAAQf,MACpBe,EAAQf,KAAO,MAEhBe,EAAQK,UAAW,SACZlB,MAAMG,YAAYU,EAAQP,MACjCN,MAAME,mBAEPW,EAAQI,gBAAiB,IAEzBJ,EAAQG,WAAWnB,SAASuB,KAAaA,GAAsC,IAA3BP,EAAQI,gBAC5DJ,EAAQI,gBAAiB,GAG5B,GA2CD,OAxCIN,IACHE,EAAQf,KAAOA,KAAKY,GAAW,WAC9BG,EAAQM,MACT,KAGGtB,SAASG,MAAMG,YAAYG,KAC9Be,OAAOf,GAERN,MAAMG,YAAYG,GAAQO,EAC1Bb,MAAME,oBAIHL,SAASG,MAAMC,cA9FU,MA+FrBS,IAAwCC,IAE1CX,MAAME,gBAAkB,IAExBL,SAASG,MAAMC,cAClBF,YAAYC,MAAMC,aAGnBD,MAAMC,YAAcH,KAAKY,GAAW,WACnC,GAAIV,MAAME,gBAAkB,GAC3B,IAAK,IAAII,KAAQN,MAAMG,YACtB,GAAIH,MAAMG,YAAYmB,eAAehB,GAAO,CAC3C,MAAMD,EAAOL,MAAMG,YAAYG,GAC1BT,SAASQ,EAAKP,OAClBO,EAAKc,MAEP,OAGDpB,YAAYC,MAAMC,aAClBD,MAAMC,YAAc,IAEtB,KAGMY,CACR,QAqBO,SAASQ,OAAOhB,GACtB,MAAMC,EAAQX,SAASU,IAASR,SAASQ,EAAKC,MAAS,GAAGD,EAAKC,OAAS,GAAGD,IAAOO,OAClF,MAAa,KAATN,IAEJD,EAAOL,MAAMG,YAAYG,KACpBT,SAASQ,KAEVR,SAASQ,EAAKP,OACjBC,YAAYM,EAAKP,MAGlBO,EAAKa,UAAW,SACTlB,MAAMG,YAAYE,EAAKC,MAC9BN,MAAME,kBAEFF,MAAME,iBAAmB,IAC5BH,YAAYC,MAAMC,aAClBD,MAAMC,YAAc,KACpBD,MAAME,gBAAkB,IAGlB,GACR","ignoreList":[],"sourcesContent":["/*!\n * Module Polling\n */\n\n/**\n * @namespace Polling\n */\n\nconst MODULE_NAME = 'Polling';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {orDefault, isFunction, isObject, assert, hasValue} from './basic.js';\nimport {loop, countermand} from './timers.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const POLLS = {\n\tdefaultLoop : null,\n\tactivePollCount : 0,\n\tactivePolls : {}\n};\n\nconst POLL_DEFAULT_LOOP_MS = 250;\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Polling:poll\n */\n\n/**\n * Waits for a certain program- or DOM-state before executing a certain action. Waiting is implemented via\n * a global timer (and optionally locals as well). If you need to react to a certain case, that's not\n * defined by standard events and reaction does not have to be razor sharp, this is your method.\n * Pick a name for the state/event you want to poll, define a condition closure and an action closure that\n * holds what is to be done in case the condition works out.\n * Polls end or are repeated after an execution of the action depending on the result of the action closure.\n * There can always be only one poll of a certain name, redefining it overwrites the first one.\n *\n * If you need to evaluate a poll out of the line, to trigger a sharp synchronous evaluation due to an event\n * for example, you can use the \"fire\" method of the poll object itself, which will trigger the condition and all\n * subsequent actions. You can provide a boolean parameter to this function to override manually if the result\n * should be considered changed to the last run. You can only fire polls, that are still active, you can check this\n * state easily via \"isActive\" on the poll.\n *\n * @param {String} name - name of the state or event you are waiting/polling for\n * @param {Function} fCondition - closure to define the state to wait for, returns true if state exists and false if not\n * @param {Function} fAction - closure to define action to take place if condition is fulfilled, poll removes itself if this evaluates to true, receives Boolean parameter defining if condition result has changed since last call\n * @param {?Function} [fElseAction=null] - closure to define action to take place if condition is not fulfilled, receives Boolean parameter defining if condition result has changed since last call\n * @param {?Number} [newLoopMs=250] - sets interval length from here on, resets global loop if useOwnTimer is not set, otherwise sets local interval for that poll poll\n * @param {?Boolean} [useOwnTimer=false] - has to be true to tell the poll to use an independent local timer instead of the global one, use this if you need different levels of fuzziness for you polls, performance-wise it's better to have less independent intervals running\n * @throws error in case name, fCondition or fAction are missing or unfit to use\n * @returns {Object} new poll - structure: {name, condition, action, elseAction, loop, lastPollResult, isActive, fire()}\n *\n * @memberof Polling:poll\n * @alias poll\n * @see unpoll\n * @example\n * const pollBodyHeightPermanently = poll('permanent-body-height-poll', function(){ return document.body.scrollHeight > 1000; }, function(changed){ console.log(`too high${changed ? ' as of yet' : ''}!`); }, null, 5000);\n * const pollBodyHeightAndStopIfHighEnough = poll('one-time-body-height-poll', function(){ return document.body.scrollHeight > 1000; }, function(){ console.log('high enough!'); return true; }, function(){ console.log('not high enough yet :(') }, null, true);\n */\nexport function poll(name, fCondition, fAction, fElseAction=null, newLoopMs=POLL_DEFAULT_LOOP_MS, useOwnTimer=false){\n\tname = orDefault(name, '', 'str').trim();\n\tfElseAction = isFunction(fElseAction) ? fElseAction : () => {};\n\tnewLoopMs = orDefault(newLoopMs, POLL_DEFAULT_LOOP_MS, 'int');\n\tuseOwnTimer = orDefault(useOwnTimer, false, 'bool');\n\n\tassert(name !== '', `${MODULE_NAME}:poll | name is missing`);\n\tassert(isFunction(fCondition), `${MODULE_NAME}:poll | fCondition is not a function`);\n\tassert(isFunction(fAction), `${MODULE_NAME}:poll | fAction is not a function`);\n\n\tconst newPoll = {\n\t\tname,\n\t\tcondition: fCondition,\n\t\taction : fAction,\n\t\telseAction : fElseAction,\n\t\tloop : null,\n\t\tlastPollResult : false,\n\t\tisActive : true,\n\t\tfire(changed=null){\n\t\t\tif( hasValue(POLLS.activePolls[newPoll.name]) ){\n\t\t\t\tif( newPoll.condition() ){\n\t\t\t\t\tif( newPoll.action(hasValue(changed) ? !!changed : (newPoll.lastPollResult === false)) === true ){\n\t\t\t\t\t\tif( hasValue(newPoll.loop) ){\n\t\t\t\t\t\t\tcountermand(newPoll.loop);\n\t\t\t\t\t\t\tnewPoll.loop = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnewPoll.isActive = false;\n\t\t\t\t\t\tdelete POLLS.activePolls[newPoll.name];\n\t\t\t\t\t\tPOLLS.activePollCount--;\n\t\t\t\t\t}\n\t\t\t\t\tnewPoll.lastPollResult = true;\n\t\t\t\t} else {\n\t\t\t\t\tnewPoll.elseAction(hasValue(changed) ? !!changed : (newPoll.lastPollResult === true));\n\t\t\t\t\tnewPoll.lastPollResult = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tif( useOwnTimer ){\n\t\tnewPoll.loop = loop(newLoopMs, function(){\n\t\t\tnewPoll.fire();\n\t\t});\n\t}\n\n\tif( hasValue(POLLS.activePolls[name]) ){\n\t\tunpoll(name);\n\t}\n\tPOLLS.activePolls[name] = newPoll;\n\tPOLLS.activePollCount++;\n\n\tif(\n\t\t(\n\t\t\t!hasValue(POLLS.defaultLoop)\n\t\t\t|| ((newLoopMs !== POLL_DEFAULT_LOOP_MS) && !useOwnTimer)\n\t\t)\n\t\t&& (POLLS.activePollCount > 0)\n\t){\n\t\tif( hasValue(POLLS.defaultLoop) ){\n\t\t\tcountermand(POLLS.defaultLoop);\n\t\t}\n\n\t\tPOLLS.defaultLoop = loop(newLoopMs, function(){\n\t\t\tif( POLLS.activePollCount > 0 ){\n\t\t\t\tfor( let name in POLLS.activePolls ){\n\t\t\t\t\tif( POLLS.activePolls.hasOwnProperty(name) ){\n\t\t\t\t\t\tconst poll = POLLS.activePolls[name];\n\t\t\t\t\t\tif( !hasValue(poll.loop) ){\n\t\t\t\t\t\t\tpoll.fire();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcountermand(POLLS.defaultLoop);\n\t\t\t\tPOLLS.defaultLoop = null;\n\t\t\t}\n\t\t});\n\t}\n\n\treturn newPoll;\n}\n\n\n\n/**\n * @namespace Polling:unpoll\n */\n\n/**\n * Removes an active poll.\n *\n * @param {String|Object} poll - name of the poll to be removed or the poll object itself\n * @returns {Boolean} true if poll has been removed, false if poll has not been found\n *\n * @memberof Polling:unpoll\n * @alias unpoll\n * @see poll\n * @example\n * unpoll('permanent-body-height-poll');\n * unpoll(pollBodyHeightAndStopIfHighEnough);\n */\nexport function unpoll(poll){\n\tconst name = (isObject(poll) && hasValue(poll.name)) ? `${poll.name}` : `${poll}`.trim();\n\tif( name === '' ) return false;\n\n\tpoll = POLLS.activePolls[name];\n\tif( !hasValue(poll) ) return false;\n\n\tif( hasValue(poll.loop) ){\n\t\tcountermand(poll.loop);\n\t}\n\n\tpoll.isActive = false;\n\tdelete POLLS.activePolls[poll.name];\n\tPOLLS.activePollCount--;\n\n\tif( POLLS.activePollCount <= 0 ){\n\t\tcountermand(POLLS.defaultLoop);\n\t\tPOLLS.defaultLoop = null;\n\t\tPOLLS.activePollCount = 0;\n\t}\n\n\treturn true;\n}\n"]} \ No newline at end of file diff --git a/dist/polyfills.js b/dist/polyfills.js index 3e04a800..13dc3dc2 100644 --- a/dist/polyfills.js +++ b/dist/polyfills.js @@ -1,5 +1,5 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Polyfills diff --git a/dist/polyfills.js.map b/dist/polyfills.js.map index 31d9d7c9..b96a84f4 100644 --- a/dist/polyfills.js.map +++ b/dist/polyfills.js.map @@ -1 +1 @@ -{"version":3,"file":"polyfills.js","names":["MODULE_NAME","assert","hasValue","isFunction","orDefault","createFetchRequest","polyfillFetch","force","window","fetch","url","options","execute","polyfillElementMatches","Element","prototype","matches","msMatchesSelector","webkitMatchesSelector","polyfillCustomEvent","CustomEvent","event","params","bubbles","cancelable","detail","undefined","e","document","createEvent","initCustomEvent","Event","polyfillArrayAt","Array","at","Object","defineProperty","value","n","Math","trunc","this","length","writable","enumerable","configurable"],"sources":["polyfills.js"],"mappings":";;;AAQA,MAAMA,YAAc,mBAMZC,OAAQC,SAAUC,WAAYC,cAAgB,oBAC9CC,uBAAyB,uBA0B1B,SAASC,cAAcC,GAAM,KACnCA,EAAQH,UAAUG,GAAO,EAAO,UAElBJ,WAAWK,OAAOC,SAC/BD,OAAOC,MAAQ,SAASC,EAAKC,EAAQ,MACpC,OAAON,mBAAmBK,EAAKC,GAASC,SACzC,EAEF,QAqBO,SAASC,yBAGVC,QAAQC,UAAUC,UACtBF,QAAQC,UAAUC,QAAUF,QAAQC,UAAUE,mBAC1CH,QAAQC,UAAUG,uBAClB,MAILjB,OAAOC,SAASY,QAAQC,UAAUC,SAAU,8EAC7C,QAmBO,SAASG,sBACf,GAAIhB,WAAWK,OAAOY,aAAe,OAAO,EAE5C,MAAMA,EAAc,SAASC,EAAOC,GACnCA,EAASA,GAAU,CAACC,SAAU,EAAOC,YAAa,EAAOC,YAASC,GAClE,MAAMC,EAAIC,SAASC,YAAY,eAE/B,OADAF,EAAEG,gBAAgBT,EAAOC,EAAOC,QAASD,EAAOE,WAAYF,EAAOG,QAC5DE,CACR,EACAP,EAAYL,UAAYP,OAAOuB,MAAMhB,UAErCP,OAAOY,YAAcA,CACtB,QAoBO,SAASY,kBACf,GAAI7B,WAAW8B,MAAMlB,UAAUmB,IAAM,OAAO,EAE5CC,OAAOC,eAAeH,MAAMlB,UAAW,KAAM,CAC5CsB,MAAQ,SAASC,GAGhB,IAFAA,EAAIC,KAAKC,MAAMF,IAAM,GACb,IAAIA,GAAKG,KAAKC,UACjBJ,EAAI,GAAOA,GAAKG,KAAKC,QAC1B,OAAOD,KAAKH,EACb,EACAK,UAAW,EACXC,YAAa,EACbC,cAAe,GAEjB","sourcesContent":["/*!\n * Module Polyfills\n */\n\n/**\n * @namespace Polyfills\n */\n\nconst MODULE_NAME = 'Polyfills';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {assert, hasValue, isFunction, orDefault} from './basic.js';\nimport {createFetchRequest} from './requests.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Polyfills:polyfillFetch\n */\n\n/**\n * Polyfills window.fetch with a simple XMLHttpRequest-based implementation adapted from \"unfetch\", to provide\n * basic functionality with a compatible signature while keeping the source as small as possible.\n *\n * This polyfill should cover most basic use cases, but for complex cases you might need to polyfill something more\n * complete (for example Github's implementation: https://github.com/github/fetch).\n *\n * @param {?Boolean} [force=false] - if true, replaces a possibly present native implementation with the polyfill as well\n *\n * @memberof Polyfills:polyfillFetch\n * @alias polyfillFetch\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch\n * @see https://github.com/developit/unfetch\n * @example\n * polyfillFetch(true);\n */\nexport function polyfillFetch(force=false){\n\tforce = orDefault(force, false, 'bool');\n\n\tif( force || !isFunction(window.fetch) ){\n\t\twindow.fetch = function(url, options=null){\n\t\t\treturn createFetchRequest(url, options).execute();\n\t\t};\n\t}\n}\n\n\n\n/**\n * @namespace Polyfills:polyfillElementMatches\n */\n\n/**\n * Adds Element.matches support, if not already present in browser. Falls back to ms or mozilla implementations\n * if necessary.\n *\n * @throws error if Element.matches is not supported\n *\n * @memberof Polyfills:polyfillElementMatches\n * @alias polyfillElementMatches\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/matches\n * @example\n * polyfillElementMatches()\n * => makes Element.prototype.matches available, if not already present\n */\nexport function polyfillElementMatches(){\n\tconst __methodName__ = 'polyfillElementMatches';\n\n\tif( !Element.prototype.matches ){\n\t\tElement.prototype.matches = Element.prototype.msMatchesSelector\n\t\t\t?? Element.prototype.webkitMatchesSelector\n\t\t\t?? null\n\t\t;\n\t}\n\n\tassert(hasValue(Element.prototype.matches), `${MODULE_NAME}:${__methodName__} | browser does not support Element.matches`);\n}\n\n\n\n/**\n * @namespace Polyfills:polyfillCustomEvent\n */\n\n/**\n * Adds CustomEvent support, if not already present in browser. Falls back to manual implementation via\n * document.createEvent and event.initCustomEvent, if necessary.\n *\n * @memberof Polyfills:polyfillCustomEvent\n * @alias polyfillCustomEvent\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent\n * @example\n * polyfillCustomEvent()\n * => makes \"window.CustomEvent\" and \"new CustomEvent()\" available, if not already present\n */\nexport function polyfillCustomEvent(){\n\tif( isFunction(window.CustomEvent) ) return false;\n\n\tconst CustomEvent = function(event, params){\n\t\tparams = params ?? {bubbles : false, cancelable : false, detail : undefined};\n\t\tconst e = document.createEvent('CustomEvent');\n\t\te.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n\t\treturn e;\n\t};\n\tCustomEvent.prototype = window.Event.prototype;\n\n\twindow.CustomEvent = CustomEvent;\n}\n\n\n\n/**\n * @namespace Polyfills:polyfillArrayAt\n */\n\n/**\n * Adds support for Array.prototype.at, which is a fairly recent feature, compared to most other basic array\n * operations, resulting in even modern Chrome, Firefox and Safari versions not having implemented this.\n * But adding this is quite forward, it just being general array index access with possible negative index.\n *\n * @memberof Polyfills:polyfillArrayAt\n * @alias polyfillArrayAt\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at\n * @example\n * polyfillArrayAt()\n * => adds Array.prototype.at if not already defined\n */\nexport function polyfillArrayAt(){\n\tif( isFunction(Array.prototype.at) ) return false;\n\n\tObject.defineProperty(Array.prototype, 'at', {\n\t\tvalue : function(n){\n\t\t\tn = Math.trunc(n) || 0;\n\t\t\tif( n < 0 ) n += this.length;\n\t\t\tif( (n < 0) || (n >= this.length) ) return undefined;\n\t\t\treturn this[n];\n\t\t},\n\t\twritable : true,\n\t\tenumerable : false,\n\t\tconfigurable : true\n\t});\n}\n"]} \ No newline at end of file +{"version":3,"file":"polyfills.js","names":["MODULE_NAME","assert","hasValue","isFunction","orDefault","createFetchRequest","polyfillFetch","force","window","fetch","url","options","execute","polyfillElementMatches","Element","prototype","matches","msMatchesSelector","webkitMatchesSelector","polyfillCustomEvent","CustomEvent","event","params","bubbles","cancelable","detail","undefined","e","document","createEvent","initCustomEvent","Event","polyfillArrayAt","Array","at","Object","defineProperty","value","n","Math","trunc","this","length","writable","enumerable","configurable"],"sources":["polyfills.js"],"mappings":";;;AAQA,MAAMA,YAAc,mBAMZC,OAAQC,SAAUC,WAAYC,cAAgB,oBAC9CC,uBAAyB,uBA0B1B,SAASC,cAAcC,GAAM,KACnCA,EAAQH,UAAUG,GAAO,EAAO,UAElBJ,WAAWK,OAAOC,SAC/BD,OAAOC,MAAQ,SAASC,EAAKC,EAAQ,MACpC,OAAON,mBAAmBK,EAAKC,GAASC,SACzC,EAEF,QAqBO,SAASC,yBAGVC,QAAQC,UAAUC,UACtBF,QAAQC,UAAUC,QAAUF,QAAQC,UAAUE,mBAC1CH,QAAQC,UAAUG,uBAClB,MAILjB,OAAOC,SAASY,QAAQC,UAAUC,SAAU,8EAC7C,QAmBO,SAASG,sBACf,GAAIhB,WAAWK,OAAOY,aAAe,OAAO,EAE5C,MAAMA,EAAc,SAASC,EAAOC,GACnCA,EAASA,GAAU,CAACC,SAAU,EAAOC,YAAa,EAAOC,YAASC,GAClE,MAAMC,EAAIC,SAASC,YAAY,eAE/B,OADAF,EAAEG,gBAAgBT,EAAOC,EAAOC,QAASD,EAAOE,WAAYF,EAAOG,QAC5DE,CACR,EACAP,EAAYL,UAAYP,OAAOuB,MAAMhB,UAErCP,OAAOY,YAAcA,CACtB,QAoBO,SAASY,kBACf,GAAI7B,WAAW8B,MAAMlB,UAAUmB,IAAM,OAAO,EAE5CC,OAAOC,eAAeH,MAAMlB,UAAW,KAAM,CAC5CsB,MAAQ,SAASC,GAGhB,IAFAA,EAAIC,KAAKC,MAAMF,IAAM,GACb,IAAIA,GAAKG,KAAKC,UACjBJ,EAAI,GAAOA,GAAKG,KAAKC,QAC1B,OAAOD,KAAKH,EACb,EACAK,UAAW,EACXC,YAAa,EACbC,cAAe,GAEjB","ignoreList":[],"sourcesContent":["/*!\n * Module Polyfills\n */\n\n/**\n * @namespace Polyfills\n */\n\nconst MODULE_NAME = 'Polyfills';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {assert, hasValue, isFunction, orDefault} from './basic.js';\nimport {createFetchRequest} from './requests.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Polyfills:polyfillFetch\n */\n\n/**\n * Polyfills window.fetch with a simple XMLHttpRequest-based implementation adapted from \"unfetch\", to provide\n * basic functionality with a compatible signature while keeping the source as small as possible.\n *\n * This polyfill should cover most basic use cases, but for complex cases you might need to polyfill something more\n * complete (for example Github's implementation: https://github.com/github/fetch).\n *\n * @param {?Boolean} [force=false] - if true, replaces a possibly present native implementation with the polyfill as well\n *\n * @memberof Polyfills:polyfillFetch\n * @alias polyfillFetch\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch\n * @see https://github.com/developit/unfetch\n * @example\n * polyfillFetch(true);\n */\nexport function polyfillFetch(force=false){\n\tforce = orDefault(force, false, 'bool');\n\n\tif( force || !isFunction(window.fetch) ){\n\t\twindow.fetch = function(url, options=null){\n\t\t\treturn createFetchRequest(url, options).execute();\n\t\t};\n\t}\n}\n\n\n\n/**\n * @namespace Polyfills:polyfillElementMatches\n */\n\n/**\n * Adds Element.matches support, if not already present in browser. Falls back to ms or mozilla implementations\n * if necessary.\n *\n * @throws error if Element.matches is not supported\n *\n * @memberof Polyfills:polyfillElementMatches\n * @alias polyfillElementMatches\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/matches\n * @example\n * polyfillElementMatches()\n * => makes Element.prototype.matches available, if not already present\n */\nexport function polyfillElementMatches(){\n\tconst __methodName__ = 'polyfillElementMatches';\n\n\tif( !Element.prototype.matches ){\n\t\tElement.prototype.matches = Element.prototype.msMatchesSelector\n\t\t\t?? Element.prototype.webkitMatchesSelector\n\t\t\t?? null\n\t\t;\n\t}\n\n\tassert(hasValue(Element.prototype.matches), `${MODULE_NAME}:${__methodName__} | browser does not support Element.matches`);\n}\n\n\n\n/**\n * @namespace Polyfills:polyfillCustomEvent\n */\n\n/**\n * Adds CustomEvent support, if not already present in browser. Falls back to manual implementation via\n * document.createEvent and event.initCustomEvent, if necessary.\n *\n * @memberof Polyfills:polyfillCustomEvent\n * @alias polyfillCustomEvent\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent\n * @example\n * polyfillCustomEvent()\n * => makes \"window.CustomEvent\" and \"new CustomEvent()\" available, if not already present\n */\nexport function polyfillCustomEvent(){\n\tif( isFunction(window.CustomEvent) ) return false;\n\n\tconst CustomEvent = function(event, params){\n\t\tparams = params ?? {bubbles : false, cancelable : false, detail : undefined};\n\t\tconst e = document.createEvent('CustomEvent');\n\t\te.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n\t\treturn e;\n\t};\n\tCustomEvent.prototype = window.Event.prototype;\n\n\twindow.CustomEvent = CustomEvent;\n}\n\n\n\n/**\n * @namespace Polyfills:polyfillArrayAt\n */\n\n/**\n * Adds support for Array.prototype.at, which is a fairly recent feature, compared to most other basic array\n * operations, resulting in even modern Chrome, Firefox and Safari versions not having implemented this.\n * But adding this is quite forward, it just being general array index access with possible negative index.\n *\n * @memberof Polyfills:polyfillArrayAt\n * @alias polyfillArrayAt\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at\n * @example\n * polyfillArrayAt()\n * => adds Array.prototype.at if not already defined\n */\nexport function polyfillArrayAt(){\n\tif( isFunction(Array.prototype.at) ) return false;\n\n\tObject.defineProperty(Array.prototype, 'at', {\n\t\tvalue : function(n){\n\t\t\tn = Math.trunc(n) || 0;\n\t\t\tif( n < 0 ) n += this.length;\n\t\t\tif( (n < 0) || (n >= this.length) ) return undefined;\n\t\t\treturn this[n];\n\t\t},\n\t\twritable : true,\n\t\tenumerable : false,\n\t\tconfigurable : true\n\t});\n}\n"]} \ No newline at end of file diff --git a/dist/random.js b/dist/random.js index bc93e8f0..3713f3c1 100644 --- a/dist/random.js +++ b/dist/random.js @@ -1,8 +1,8 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Random */ -const MODULE_NAME="Random";import{orDefault,assert,hasValue,isFunction}from"./basic.js";import{pad}from"./strings.js";import{toBaseX}from"./conversion.js";const RANDOM_UUIDS_USED_SINCE_RELOAD=new Set,DEFAULT_USER_CODE_ALPHABET="ACDEFGHKLMNPQRSTUVWXYZ2345679";export function randomNumber(o=0,t=10,e=!1,r=2){o=orDefault(o,0,"float"),t=orDefault(t,10,"float"),e=orDefault(e,!1,"bool"),r=orDefault(r,2,"int"),assert(t>=o,"Random:randomInt | ceiling smaller than floor");const n=Math.pow(10,r);e&&(o*=n,t*=n);const a=Math.floor(Math.random()*(t-o+1)+o);return e?Math.round(parseFloat(a)*n)/n/n:a}export function randomUuid(o=!0){o=orDefault(o,!0,"bool");let t=null,e=0;for(;!hasValue(t)||RANDOM_UUIDS_USED_SINCE_RELOAD.has(t);)t=isFunction(window.crypto?.getRandomValues)||isFunction(window.msCrypto?.getRandomValues)?([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,(o=>(o^(isFunction(window.crypto?.getRandomValues)?window.crypto.getRandomValues(new Uint8Array(1)):window.msCrypto?.getRandomValues(new Uint8Array(1)))[0]&15>>o/4).toString(16))):"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(o=>{const t=16*Math.random()|0;return("x"===o?t:3&t|8).toString(16)})),RANDOM_UUIDS_USED_SINCE_RELOAD.has(t)&&(e++,e>100&&assert(e<=100,"Random:randomUuid | too many collisions, there seems to be randomization problem"));return RANDOM_UUIDS_USED_SINCE_RELOAD.add(t),o?t:t.replace(/-/g,"")}export function randomUserCode(o=DEFAULT_USER_CODE_ALPHABET,t="8",e=8,r=12,n=null){const a="randomUserCode";if(o=orDefault(o,DEFAULT_USER_CODE_ALPHABET,"str"),t=orDefault(t,"8","str")[0],e=orDefault(e,8,"int"),r=orDefault(r,12,"int"),n=orDefault(n,window.crypto?.getRandomValues?.(new Uint16Array(15)).reduce(((o,t)=>o+t),0)??window.msCrypto?.getRandomValues?.(new Uint16Array(15)).reduce(((o,t)=>o+t),0)??randomNumber(1,999999),"int"),ro+Number(t)),0)}`),o);if(s.length>r)throw Error(`Random:${a} | code too long, check maxLength and custom randomValue`);return s.length=o,`${MODULE_NAME}:randomInt | ceiling smaller than floor`);const n=Math.pow(10,r);e&&(o*=n,t*=n);const a=Math.floor(Math.random()*(t-o+1)+o);return e?Math.round(parseFloat(a)*n)/n/n:a}export function randomUuid(o=!0){o=orDefault(o,!0,"bool");let t=null,e=0;for(;!hasValue(t)||RANDOM_UUIDS_USED_SINCE_RELOAD.has(t);)t=isFunction(window.crypto?.getRandomValues)||isFunction(window.msCrypto?.getRandomValues)?([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,(o=>(o^(isFunction(window.crypto?.getRandomValues)?window.crypto.getRandomValues(new Uint8Array(1)):window.msCrypto?.getRandomValues(new Uint8Array(1)))[0]&15>>o/4).toString(16))):"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(o=>{const t=16*Math.random()|0;return("x"===o?t:3&t|8).toString(16)})),RANDOM_UUIDS_USED_SINCE_RELOAD.has(t)&&(e++,e>100&&assert(e<=100,`${MODULE_NAME}:randomUuid | too many collisions, there seems to be randomization problem`));return RANDOM_UUIDS_USED_SINCE_RELOAD.add(t),o?t:t.replace(/-/g,"")}export function randomUserCode(o=DEFAULT_USER_CODE_ALPHABET,t="8",e=8,r=12,n=null){const a="randomUserCode";if(o=orDefault(o,DEFAULT_USER_CODE_ALPHABET,"str"),t=orDefault(t,"8","str")[0],e=orDefault(e,8,"int"),r=orDefault(r,12,"int"),n=orDefault(n,window.crypto?.getRandomValues?.(new Uint16Array(15)).reduce(((o,t)=>o+t),0)??window.msCrypto?.getRandomValues?.(new Uint16Array(15)).reduce(((o,t)=>o+t),0)??randomNumber(1,999999),"int"),ro+Number(t)),0)}`),o);if(s.length>r)throw Error(`${MODULE_NAME}:${a} | code too long, check maxLength and custom randomValue`);return s.length= floor), `${MODULE_NAME}:randomInt | ceiling smaller than floor`);\n\n\tconst power = Math.pow(10, precision);\n\n\tif( float ){\n\t\tfloor *= power;\n\t\tceiling *= power;\n\t}\n\n\tconst res = Math.floor(Math.random() * (ceiling - floor + 1) + floor);\n\n\treturn float ? ((Math.round(parseFloat(res) * power) / power) / power) : res;\n}\n\n\n\n/**\n * @namespace Random:randomUuid\n */\n\n/**\n * Generate a RFC4122-compliant random UUID, as far as possible with JS.\n * Generation is heavily dependent on the quality of randomization, which in some JS-engines is weak using\n * Math.random. Therefore, we are using the specific crypto api if available and only fall back to random if necessary.\n * Additionally, we track used UUIDs to never return the same id twice per reload.\n *\n * For a detailed discussion, see: https://stackoverflow.com/a/2117523\n *\n * @param {?Boolean} [withDashes=true] - defines if UUID shall include dashes or not\n * @throws error if too many collisions happen and the random implementation seems to be broken\n * @returns {String} a \"UUID\"\n *\n * @memberof Random:randomUuid\n * @alias randomUuid\n * @example\n * const uuidWithDashes = randomUuid();\n * const uuidWithoutDashes = randomUuid(false);\n */\nexport function randomUuid(withDashes=true){\n\twithDashes = orDefault(withDashes, true, 'bool');\n\n\tlet\n\t\tuuid = null,\n\t\tcollisions = 0\n\t;\n\n\twhile( !hasValue(uuid) || RANDOM_UUIDS_USED_SINCE_RELOAD.has(uuid) ){\n\t\t// we have to do this highly convoluted check, because we have to call getRandomValues\n\t\t// explicitly from either window.crypto or window.msCrypto, since invoking it from another\n\t\t// context will trigger an \"illegal invocation\" of the method :(\n\t\tif(\n\t\t\tisFunction(window.crypto?.getRandomValues)\n\t\t\t|| isFunction(window.msCrypto?.getRandomValues)\n\t\t){\n\t\t\tuuid = ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => (\n\t\t\t\tc\n\t\t\t\t^ (\n\t\t\t\t\tisFunction(window.crypto?.getRandomValues)\n\t\t\t\t\t? window.crypto.getRandomValues(new Uint8Array(1))\n\t\t\t\t\t: window.msCrypto?.getRandomValues(new Uint8Array(1))\n\t\t\t\t)[0]\n\t\t\t\t& 15 >> c / 4\n\t\t\t).toString(16));\n\t\t} else {\n\t\t\tuuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n\t\t\t\tconst\n\t\t\t\t\tr = Math.random() * 16 | 0,\n\t\t\t\t\tv = c === 'x' ? r : (r & 0x3 | 0x8)\n\t\t\t\t;\n\t\t\t\treturn v.toString(16);\n\t\t\t});\n\t\t}\n\n\t\tif( RANDOM_UUIDS_USED_SINCE_RELOAD.has(uuid) ){\n\t\t\tcollisions++;\n\n\t\t\tif( collisions > 100 ){\n\t\t\t\tassert(collisions <= 100, `${MODULE_NAME}:randomUuid | too many collisions, there seems to be randomization problem`)\n\t\t\t}\n\t\t}\n\t}\n\n\tRANDOM_UUIDS_USED_SINCE_RELOAD.add(uuid);\n\n\treturn withDashes ? uuid : uuid.replace(/-/g, '');\n}\n\n\n\n/**\n * @namespace Random:randomUserCode\n */\n\n/**\n * Generates a random code, to be presented to the user, being easily readable and concise.\n * Use this for things like, coupon codes, session IDs and everything, that might be transcribed by hand.\n *\n * The algorithm used is using time-based information in combination with a larger random number, so, there should not\n * be any collisions, but build in a fail-safe, if you persist this code to a database, to make absolutely sure, that\n * the code is unique.\n *\n * The used method here is formulated, to result in a short, concise highly readable code, while keeping the value\n * highly random and as collision-free as possible. The basis for this is a combination of a compressed ISO-datetime\n * string and a crypto-random-based combination of several random Uint8-values.\n *\n * Hint: if you need a general implementation to convert a value to a certain alphabet/base, have a look at\n * `Conversion:toBaseX`.\n *\n * @param {?String} [alphabet='ACDEFGHKLMNPQRSTUVWXYZ2345679'] - the character pool to use for code generation\n * @param {?String} [paddingCharacter='8'] - the character to use for value padding if generated code is too short\n * @param {?Number} [minLength=8] - the min length, the code has to have at least, will be padded if too short\n * @param {?Number} [maxLength=12] - the max length, the code can have at most, a code longer than this, will result in an error\n * @param {?Number} [randomValue=null] - random integer to include in the code's base value, should be ~6 digits, will automatically be generated if missing\n * @throws error if maxLength is smaller than minLength\n * @throws error if the generated code is longer than maxLength\n * @returns {String} the generated user code\n *\n * @memberof Random:randomUserCode\n * @alias randomUserCode\n * @see Conversion:toBaseX\n * @example\n * randomUserCode()\n * => 'GVK6RNQ8'\n * randomUserCode('0123456789ABCDEF', 10, 10, '=')\n * => 'A03CF25D7='\n */\nexport function randomUserCode(\n\talphabet=DEFAULT_USER_CODE_ALPHABET,\n\tpaddingCharacter='8',\n\tminLength=8,\n\tmaxLength=12,\n\trandomValue=null\n){\n\tconst __methodName__ = 'randomUserCode';\n\n\talphabet = orDefault(alphabet, DEFAULT_USER_CODE_ALPHABET, 'str');\n\tpaddingCharacter = orDefault(paddingCharacter, '8', 'str')[0];\n\tminLength = orDefault(minLength, 8, 'int');\n\tmaxLength = orDefault(maxLength, 12, 'int');\n\trandomValue = orDefault(\n\t\trandomValue,\n\t\twindow.crypto?.getRandomValues?.(new Uint16Array(15)).reduce((sum, v) => sum + v, 0)\n\t\t\t?? window.msCrypto?.getRandomValues?.(new Uint16Array(15)).reduce((sum, v) => sum + v, 0)\n\t\t\t?? randomNumber(1, 999999)\n\t\t,\n\t\t'int'\n\t);\n\n\tif( maxLength < minLength ){\n\t\tthrow Error(`${MODULE_NAME}:${__methodName__} | minLength cannot be smaller than maxLength`);\n\t}\n\n\tlet code = ''+toBaseX(Number(\n\t\t`${randomValue}${\n\t\t\t(new Date()).toISOString().replace(/[\\-T:.Z]/g, '?')\n\t\t\t\t.split('?')\n\t\t\t\t.reduce((sum, v) => sum + Number(v), 0)\n\t\t}`\n\t), alphabet);\n\n\tif( code.length > maxLength ){\n\t\tthrow Error(\n\t\t\t`${MODULE_NAME}:${__methodName__} | code too long, check maxLength and custom randomValue`\n\t\t);\n\t} else if( code.length < minLength ){\n\t\tcode = pad(code, paddingCharacter, minLength, 'right');\n\t}\n\n\treturn code;\n}\n"]} \ No newline at end of file +{"version":3,"file":"random.js","names":["MODULE_NAME","orDefault","assert","hasValue","isFunction","pad","toBaseX","RANDOM_UUIDS_USED_SINCE_RELOAD","Set","DEFAULT_USER_CODE_ALPHABET","randomNumber","floor","ceiling","float","precision","power","Math","pow","res","random","round","parseFloat","randomUuid","withDashes","uuid","collisions","has","window","crypto","getRandomValues","msCrypto","replace","c","Uint8Array","toString","r","add","randomUserCode","alphabet","paddingCharacter","minLength","maxLength","randomValue","__methodName__","Uint16Array","reduce","sum","v","Error","code","Number","Date","toISOString","split","length"],"sources":["random.js"],"mappings":";;;AAQA,MAAMA,YAAc,gBAMZC,UAAWC,OAAQC,SAAUC,eAAiB,oBAC9CC,QAAU,sBACVC,YAAc,kBAMtB,MACCC,+BAAiC,IAAIC,IACrCC,2BAA6B,uCA+BvB,SAASC,aAAaC,EAAM,EAAGC,EAAQ,GAAIC,GAAM,EAAOC,EAAU,GACxEH,EAAQV,UAAUU,EAAO,EAAG,SAC5BC,EAAUX,UAAUW,EAAS,GAAI,SACjCC,EAAQZ,UAAUY,GAAO,EAAO,QAChCC,EAAYb,UAAUa,EAAW,EAAG,OAEpCZ,OAAQU,GAAWD,EAAQ,GAAGX,sDAE9B,MAAMe,EAAQC,KAAKC,IAAI,GAAIH,GAEvBD,IACHF,GAASI,EACTH,GAAWG,GAGZ,MAAMG,EAAMF,KAAKL,MAAMK,KAAKG,UAAYP,EAAUD,EAAQ,GAAKA,GAE/D,OAAOE,EAAUG,KAAKI,MAAMC,WAAWH,GAAOH,GAASA,EAASA,EAASG,CAC1E,QA0BO,SAASI,WAAWC,GAAW,GACrCA,EAAatB,UAAUsB,GAAY,EAAM,QAEzC,IACCC,EAAO,KACPC,EAAa,EAGd,MAAQtB,SAASqB,IAASjB,+BAA+BmB,IAAIF,IAQ3DA,EAHApB,WAAWuB,OAAOC,QAAQC,kBACvBzB,WAAWuB,OAAOG,UAAUD,kBAEvB,CAAC,MAAM,KAAK,KAAK,KAAK,MAAME,QAAQ,UAAUC,IACrDA,GAEC5B,WAAWuB,OAAOC,QAAQC,iBACxBF,OAAOC,OAAOC,gBAAgB,IAAII,WAAW,IAC7CN,OAAOG,UAAUD,gBAAgB,IAAII,WAAW,KACjD,GACA,IAAMD,EAAI,GACXE,SAAS,MAEJ,uCAAuCH,QAAQ,SAASC,IAC9D,MACCG,EAAoB,GAAhBnB,KAAKG,SAAgB,EAG1B,OAFW,MAANa,EAAYG,EAAS,EAAJA,EAAU,GAEvBD,SAAS,GAAG,IAInB3B,+BAA+BmB,IAAIF,KACtCC,IAEIA,EAAa,KAChBvB,OAAOuB,GAAc,IAAK,GAAGzB,0FAOhC,OAFAO,+BAA+B6B,IAAIZ,GAE5BD,EAAaC,EAAOA,EAAKO,QAAQ,KAAM,GAC/C,QAyCO,SAASM,eACfC,EAAS7B,2BACT8B,EAAiB,IACjBC,EAAU,EACVC,EAAU,GACVC,EAAY,MAEZ,MAAMC,EAAiB,iBAevB,GAbAL,EAAWrC,UAAUqC,EAAU7B,2BAA4B,OAC3D8B,EAAmBtC,UAAUsC,EAAkB,IAAK,OAAO,GAC3DC,EAAYvC,UAAUuC,EAAW,EAAG,OACpCC,EAAYxC,UAAUwC,EAAW,GAAI,OACrCC,EAAczC,UACbyC,EACAf,OAAOC,QAAQC,kBAAkB,IAAIe,YAAY,KAAKC,QAAO,CAACC,EAAKC,IAAMD,EAAMC,GAAG,IAC9EpB,OAAOG,UAAUD,kBAAkB,IAAIe,YAAY,KAAKC,QAAO,CAACC,EAAKC,IAAMD,EAAMC,GAAG,IACpFrC,aAAa,EAAG,QAEpB,OAGG+B,EAAYD,EACf,MAAMQ,MAAM,GAAGhD,eAAe2C,kDAG/B,IAAIM,EAAO,GAAG3C,QAAQ4C,OACrB,GAAGR,KACF,IAAKS,MAAQC,cAAcrB,QAAQ,YAAa,KAC9CsB,MAAM,KACNR,QAAO,CAACC,EAAKC,IAAMD,EAAMI,OAAOH,IAAI,MAErCT,GAEH,GAAIW,EAAKK,OAASb,EACjB,MAAMO,MACL,GAAGhD,eAAe2C,6DAMpB,OAJWM,EAAKK,OAASd,IACxBS,EAAO5C,IAAI4C,EAAMV,EAAkBC,EAAW,UAGxCS,CACR","ignoreList":[],"sourcesContent":["/*!\n * Module Random\n */\n\n/**\n * @namespace Random\n */\n\nconst MODULE_NAME = 'Random';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {orDefault, assert, hasValue, isFunction} from './basic.js';\nimport {pad} from './strings.js';\nimport {toBaseX} from './conversion.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst\n\tRANDOM_UUIDS_USED_SINCE_RELOAD = new Set(),\n\tDEFAULT_USER_CODE_ALPHABET = 'ACDEFGHKLMNPQRSTUVWXYZ2345679'\n;\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Random:randomNumber\n */\n\n/**\n * Special form of Math.random, returning a value in a defined range,\n * where floor and ceiling are included in the range.\n *\n * By default, this method return an integer, but by setting \"float\" to true and\n * optionally providing a float precision you can also work with floating point numbers.\n *\n * @param {?Number} [floor=0] - the lower end of random range, can either be integer or float\n * @param {?Number} [ceiling=10] - the upper end of random range, can either be integer or float\n * @param {?Boolean} [float=false] - define if we are working with floating point numbers\n * @param {?Number} [precision=2] - if we are working with floats, what precision are we working with, considering floor, ceiling and result?\n * @throws error if ceiling is smaller than floor\n * @returns {Number} random integer or float between floor and ceiling\n *\n * @memberof Random:randomNumber\n * @alias randomNumber\n * @example\n * let randomInt = randomNumber(23, 42);\n * let randomFloat = randomNumber(23.5, 42.123, true, 3);\n */\nexport function randomNumber(floor=0, ceiling=10, float=false, precision=2){\n\tfloor = orDefault(floor, 0, 'float');\n\tceiling = orDefault(ceiling, 10, 'float');\n\tfloat = orDefault(float, false, 'bool');\n\tprecision = orDefault(precision, 2, 'int');\n\n\tassert((ceiling >= floor), `${MODULE_NAME}:randomInt | ceiling smaller than floor`);\n\n\tconst power = Math.pow(10, precision);\n\n\tif( float ){\n\t\tfloor *= power;\n\t\tceiling *= power;\n\t}\n\n\tconst res = Math.floor(Math.random() * (ceiling - floor + 1) + floor);\n\n\treturn float ? ((Math.round(parseFloat(res) * power) / power) / power) : res;\n}\n\n\n\n/**\n * @namespace Random:randomUuid\n */\n\n/**\n * Generate a RFC4122-compliant random UUID, as far as possible with JS.\n * Generation is heavily dependent on the quality of randomization, which in some JS-engines is weak using\n * Math.random. Therefore, we are using the specific crypto api if available and only fall back to random if necessary.\n * Additionally, we track used UUIDs to never return the same id twice per reload.\n *\n * For a detailed discussion, see: https://stackoverflow.com/a/2117523\n *\n * @param {?Boolean} [withDashes=true] - defines if UUID shall include dashes or not\n * @throws error if too many collisions happen and the random implementation seems to be broken\n * @returns {String} a \"UUID\"\n *\n * @memberof Random:randomUuid\n * @alias randomUuid\n * @example\n * const uuidWithDashes = randomUuid();\n * const uuidWithoutDashes = randomUuid(false);\n */\nexport function randomUuid(withDashes=true){\n\twithDashes = orDefault(withDashes, true, 'bool');\n\n\tlet\n\t\tuuid = null,\n\t\tcollisions = 0\n\t;\n\n\twhile( !hasValue(uuid) || RANDOM_UUIDS_USED_SINCE_RELOAD.has(uuid) ){\n\t\t// we have to do this highly convoluted check, because we have to call getRandomValues\n\t\t// explicitly from either window.crypto or window.msCrypto, since invoking it from another\n\t\t// context will trigger an \"illegal invocation\" of the method :(\n\t\tif(\n\t\t\tisFunction(window.crypto?.getRandomValues)\n\t\t\t|| isFunction(window.msCrypto?.getRandomValues)\n\t\t){\n\t\t\tuuid = ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => (\n\t\t\t\tc\n\t\t\t\t^ (\n\t\t\t\t\tisFunction(window.crypto?.getRandomValues)\n\t\t\t\t\t? window.crypto.getRandomValues(new Uint8Array(1))\n\t\t\t\t\t: window.msCrypto?.getRandomValues(new Uint8Array(1))\n\t\t\t\t)[0]\n\t\t\t\t& 15 >> c / 4\n\t\t\t).toString(16));\n\t\t} else {\n\t\t\tuuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n\t\t\t\tconst\n\t\t\t\t\tr = Math.random() * 16 | 0,\n\t\t\t\t\tv = c === 'x' ? r : (r & 0x3 | 0x8)\n\t\t\t\t;\n\t\t\t\treturn v.toString(16);\n\t\t\t});\n\t\t}\n\n\t\tif( RANDOM_UUIDS_USED_SINCE_RELOAD.has(uuid) ){\n\t\t\tcollisions++;\n\n\t\t\tif( collisions > 100 ){\n\t\t\t\tassert(collisions <= 100, `${MODULE_NAME}:randomUuid | too many collisions, there seems to be randomization problem`)\n\t\t\t}\n\t\t}\n\t}\n\n\tRANDOM_UUIDS_USED_SINCE_RELOAD.add(uuid);\n\n\treturn withDashes ? uuid : uuid.replace(/-/g, '');\n}\n\n\n\n/**\n * @namespace Random:randomUserCode\n */\n\n/**\n * Generates a random code, to be presented to the user, being easily readable and concise.\n * Use this for things like, coupon codes, session IDs and everything, that might be transcribed by hand.\n *\n * The algorithm used is using time-based information in combination with a larger random number, so, there should not\n * be any collisions, but build in a fail-safe, if you persist this code to a database, to make absolutely sure, that\n * the code is unique.\n *\n * The used method here is formulated, to result in a short, concise highly readable code, while keeping the value\n * highly random and as collision-free as possible. The basis for this is a combination of a compressed ISO-datetime\n * string and a crypto-random-based combination of several random Uint8-values.\n *\n * Hint: if you need a general implementation to convert a value to a certain alphabet/base, have a look at\n * `Conversion:toBaseX`.\n *\n * @param {?String} [alphabet='ACDEFGHKLMNPQRSTUVWXYZ2345679'] - the character pool to use for code generation\n * @param {?String} [paddingCharacter='8'] - the character to use for value padding if generated code is too short\n * @param {?Number} [minLength=8] - the min length, the code has to have at least, will be padded if too short\n * @param {?Number} [maxLength=12] - the max length, the code can have at most, a code longer than this, will result in an error\n * @param {?Number} [randomValue=null] - random integer to include in the code's base value, should be ~6 digits, will automatically be generated if missing\n * @throws error if maxLength is smaller than minLength\n * @throws error if the generated code is longer than maxLength\n * @returns {String} the generated user code\n *\n * @memberof Random:randomUserCode\n * @alias randomUserCode\n * @see Conversion:toBaseX\n * @example\n * randomUserCode()\n * => 'GVK6RNQ8'\n * randomUserCode('0123456789ABCDEF', 10, 10, '=')\n * => 'A03CF25D7='\n */\nexport function randomUserCode(\n\talphabet=DEFAULT_USER_CODE_ALPHABET,\n\tpaddingCharacter='8',\n\tminLength=8,\n\tmaxLength=12,\n\trandomValue=null\n){\n\tconst __methodName__ = 'randomUserCode';\n\n\talphabet = orDefault(alphabet, DEFAULT_USER_CODE_ALPHABET, 'str');\n\tpaddingCharacter = orDefault(paddingCharacter, '8', 'str')[0];\n\tminLength = orDefault(minLength, 8, 'int');\n\tmaxLength = orDefault(maxLength, 12, 'int');\n\trandomValue = orDefault(\n\t\trandomValue,\n\t\twindow.crypto?.getRandomValues?.(new Uint16Array(15)).reduce((sum, v) => sum + v, 0)\n\t\t\t?? window.msCrypto?.getRandomValues?.(new Uint16Array(15)).reduce((sum, v) => sum + v, 0)\n\t\t\t?? randomNumber(1, 999999)\n\t\t,\n\t\t'int'\n\t);\n\n\tif( maxLength < minLength ){\n\t\tthrow Error(`${MODULE_NAME}:${__methodName__} | minLength cannot be smaller than maxLength`);\n\t}\n\n\tlet code = ''+toBaseX(Number(\n\t\t`${randomValue}${\n\t\t\t(new Date()).toISOString().replace(/[\\-T:.Z]/g, '?')\n\t\t\t\t.split('?')\n\t\t\t\t.reduce((sum, v) => sum + Number(v), 0)\n\t\t}`\n\t), alphabet);\n\n\tif( code.length > maxLength ){\n\t\tthrow Error(\n\t\t\t`${MODULE_NAME}:${__methodName__} | code too long, check maxLength and custom randomValue`\n\t\t);\n\t} else if( code.length < minLength ){\n\t\tcode = pad(code, paddingCharacter, minLength, 'right');\n\t}\n\n\treturn code;\n}\n"]} \ No newline at end of file diff --git a/dist/requests.js b/dist/requests.js index ae4b444e..523cc96a 100644 --- a/dist/requests.js +++ b/dist/requests.js @@ -1,8 +1,8 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Requests */ -const MODULE_NAME="Requests";import{warn}from"./logging.js";import{hasValue,orDefault,isPlainObject,assert,Deferred,getType}from"./basic.js";import{merge}from"./objects.js";import{createNode,insertNode}from"./elements.js";import{schedule,countermand}from"./timers.js";export function createFetchRequest(e,t=null,s=!1){const n="createFetchRequest";return assert(hasValue(e),`Requests:${n} | no url given`),t=orDefault(t,{}),assert(isPlainObject(t),`Requests:${n} | options must be plain object`),t.method=orDefault(t.method,"GET","str"),t.method=["GET","POST","PUT","PATCH","HEAD","OPTIONS","DELETE"].includes(t.method.toUpperCase())?t.method.toUpperCase():"GET",t.timeout=orDefault(t.timeout,1e4,"int"),t.timeout=t.timeout<0?0:t.timeout,s=window.__ANNEX_USE_NATIVE_FETCH__??s,{url:e,options:t,execute:!s||"auto"===s&&!("fetch"in window)?function(){const s=new Deferred,n=new XMLHttpRequest,r=new Set,o=new Map,a=()=>({ok:parseInt(n.status,10)>=200&&parseInt(n.status,10)<=299,statusText:n.statusText,status:n.status,url:n.responseURL,text:()=>Promise.resolve(n.responseText),json:()=>Promise.resolve(n.responseText).then(JSON.parse),blob:()=>Promise.resolve(new Blob([n.response])),clone:a,headers:{keys:()=>r,entries:()=>o,get:e=>o.get(e),has:e=>r.has(e)}});if(n.open(t.method,e,!0),t.timeout>0&&(n.timeout=t.timeout,n.ontimeout=()=>{s.reject(new Error("timeout"))}),n.onload=()=>{n.getAllResponseHeaders().replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm,((e,t,s)=>{t=`${t}`,r.add(t),o.has(t)?o.set(t,`${o.get(t)},${s}`):o.set(t,`${s}`)})),s.resolve(a())},n.onerror=s.reject,n.withCredentials="include"===t.credentials,hasValue(t.headers))for(let e in t.headers)t.headers.hasOwnProperty(e)&&n.setRequestHeader(e,t.headers[e]);return n.send(t.body??null),s}:function(){const s=new Deferred,n=t.timeout;let r,o;return n>0&&"AbortController"in window&&(o=new AbortController,t.signal=o.signal),window.fetch(e,t).then((e=>{countermand(r),s.resolve(e)})).catch((e=>{countermand(r),s.reject(e)})),n>0&&"AbortController"in window&&(r=schedule(n,(()=>{o.abort()}))),s}}}export function createJsonRequest(e,t=null,s=!1,n=!0){const r="application/json";return n&&(hasValue(t)||(t={}),hasValue(t.headers)||(t.headers={}),t.headers.Accept=r),{url:e,options:t,execute(o="object",a=null,i=null){const l=new Deferred;return createFetchRequest(e,t,s).execute().then((e=>{const t=(e.headers.get("content-type")??e.headers.get("Content-Type")??"").split(";")[0].trim();if(t!==r){const e=`Requests:createJsonRequest | content-type "${t}" is not valid for JSON, expecting "application/json"`;if(n)throw new Error(e);warn(e)}return e.json()})).then((e=>{const t=createNode(``);\n\t\t\t\t\tif( dataId !== null ){\n\t\t\t\t\t\telement.setAttribute('data-id', `${dataId}`);\n\t\t\t\t\t}\n\n\t\t\t\t\tif( hasValue(insertTarget) ){\n\t\t\t\t\t\tconst\n\t\t\t\t\t\t\ttarget = insertTarget.element ?? insertTarget,\n\t\t\t\t\t\t\tposition = insertTarget.position ?? null\n\t\t\t\t\t\t;\n\n\t\t\t\t\t\tif( position === null ){\n\t\t\t\t\t\t\tinsertNode(target, element);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tinsertNode(target, element, position);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tres.resolve(\n\t\t\t\t\t\t(resolveTo === 'element')\n\t\t\t\t\t\t\t? element\n\t\t\t\t\t\t\t: (\n\t\t\t\t\t\t\t\t(resolveTo === 'raw')\n\t\t\t\t\t\t\t\t? JSON.stringify(json)\n\t\t\t\t\t\t\t\t: json\n\t\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t})\n\t\t\t\t.catch(error => {\n\t\t\t\t\tres.reject(error);\n\t\t\t\t})\n\t\t\t;\n\n\t\t\treturn res;\n\t\t}\n\t};\n}\n\n\n\n/**\n * @namespace Requests:RestfulJsonClient\n */\n\n/**\n * @typedef RestfulJsonClientConfig\n * @type {Object}\n *\n * @property {URL} url - the current request URL, build from baseUrl and path\n * @property {Object} options - the current options with which requests are been created, build from baseOptions and options, see createFetchRequest for details\n * @property {URLSearchParams} params - the current URL params\n * @property {Object} data - the current payload to be sent with requests like POST and PUT\n *\n * @memberof Requests\n * @see createFetchRequest\n */\n\n/**\n * This class provides a dedicated client for restful operations against an API via JSON payloads and responses.\n *\n * Internally this implementation uses createJsonRequest to actually request stuff, while this class\n * is a wrapper, providing central configuration, such as a base URL and options like credentials,\n * as well as standard methods for HTTP verbs and setup things like setting headers.\n *\n * See class documentation below for details.\n *\n * @memberof Requests:RestfulJsonClient\n * @name RestfulJsonClient\n *\n * @see RestfulJsonClient\n * @see createJsonRequest\n * @see Requests.FetchRequest\n * @example\n * const client = new RestfulJsonClient('https://jsonplaceholder.typicode.com', {credentials : 'include'});\n * const postJson = await client\n * .path('/posts')\n * \t .params({\n * \t ids : [1, 2],\n * \t q : 'lorem'\n * \t })\n * \t .data({\n * \t title : 'foo',\n * \t body : 'bar',\n * \t userId : 1,\n * \t })\n * \t .post()\n * ;\n */\nclass RestfulJsonClient {\n\n\t#__className__ = 'RestfulJsonClient';\n\t#invalidRequestMethodMessage = 'invalid request method';\n\t#dataValidationMessage = 'data must be plain object';\n\t#baseUrl = null;\n\t#baseOptions = null;\n\t#useNative = false;\n\t#strict = true;\n\t#config = null;\n\n\t/**\n\t * Creates a new RestfulJsonClient\n\t *\n\t * @param {?String} [baseUrl=window.location.origin] - the base URL for all queries, based on which final request URLs will be built, adding the paths, may be absolute or relative to current origin\n\t * @param {?Object} [baseOptions=null] - the base request options, can be expanded later via options() (see createFetchRequests for details)\n\t * @param {?Boolean|String} [useNative=false] - determines if the native Fetch implementation of the browser should be used, true forces usage, \"auto\" uses it only if available\n\t * @param {?Boolean} [strict=true] - if true, enforces \"application/json\" as accept header as well as response mime type, if false, accept header is not set and different mime type only results in warning\n\t *\n\t * @see createJsonRequest\n * @see Requests.FetchRequest\n\t */\n\tconstructor(baseUrl=null, baseOptions=null, useNative=false, strict=true){\n\t\tthis.#baseUrl = orDefault(baseUrl, window.location.origin, 'str');\n\t\tthis.#baseOptions = isPlainObject(baseOptions) ? baseOptions : {};\n\t\tthis.#useNative = orDefault(useNative, false, 'bool');\n\t\tthis.#strict = orDefault(strict, true, 'bool');\n\n\t\tif( !this.#baseUrl.startsWith('//') && this.#baseUrl.startsWith('/') ){\n\t\t\tthis.#baseUrl = `${window.location.origin}${this.#baseUrl}`;\n\t\t}\n\n\t\tthis.#config = {\n\t\t\turl : new URL('', this.#baseUrl),\n\t\t\toptions : {},\n\t\t\tparams : new URLSearchParams(),\n\t\t\tdata : {},\n\t\t};\n\t}\n\n\n\n\t/**\n\t * Sets the current request path, which will be concatenated to baseUrl.\n\t *\n\t * @param {String} path - the current path to request from baseUrl\n\t * @returns {RestfulJsonClient}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/food')).path('/pizzas').get();\n\t */\n\tpath(path){\n\t\tpath = `${path}`.replaceAll(/^\\/+/g, '');\n\n\t\tthis.#config.url = new URL(path, this.#baseUrl);\n\n\t\treturn this;\n\t}\n\n\n\t/**\n\t * Sets the current request options, which will be merged with baseOptions.\n\t *\n\t * @param {?Object} options - plain options object to merge with baseOptions to define current request options (see createFetchRequest for details and defaults); if nullish, baseOptions will be used\n\t * @throws error if given options are not a plain object\n\t * @returns {RestfulJsonClient}\n\t *\n\t * @see createJsonRequest\n\t * @see Requests.FetchRequest\n\t * @example\n\t * (new RestfulJsonClient('/run-forrest-run')).options({timeout : 1});\n\t */\n\toptions(options){\n\t\tconst __methodName__ = 'options';\n\n\t\tif( hasValue(options) ){\n\t\t\tassert(isPlainObject(options), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | options must be plain object`);\n\t\t\tthis.#config.options = options;\n\t\t} else {\n\t\t\tthis.#config.options = {};\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\t/**\n\t * Sets a header for all subsequent requests.\n\t * Use a nullish value to unset a header.\n\t *\n\t * @param {String} key - the header to set for all following requests\n\t * @param {?String} value - the header's value; a nullish value will remove the header again\n\t * @returns {RestfulJsonClient}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/run-forrest-run')).header('X-Test', 42).header('X-Test', null);\n\t */\n\theader(key, value){\n\t\tkey = `${key}`;\n\n\t\tif( !isPlainObject(this.#config.options.headers) ){\n\t\t\tthis.#config.options.headers = {};\n\t\t}\n\n\t\tif( hasValue(value) ){\n\t\t\tthis.#config.options.headers[key] = `${value}`;\n\t\t} else {\n\t\t\tdelete this.#config.options.headers[key];\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Sets query parameters to be added to the request URL.\n\t *\n\t * @param {?*} params - query parameters to set on the current URL, this parameter takes all regular definitions for URLSearchParams constructor, as well as flat plain objects, which may also have arrays as values; if nullish, parameters are emptied\n\t * @returns {RestfulJsonClient}\n\t *\n\t * @see https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/URLSearchParams\n\t * @example\n\t * (new RestfulJsonClient('/food/search')).params({q : 'delicious pizza'}).get();\n\t */\n\tparams(params){\n\t\tif( hasValue(params) ){\n\t\t\tthis.#config.params = new URLSearchParams(isPlainObject(params) ? this.#toFlatEntries(params) : params);\n\t\t} else {\n\t\t\tthis.#config.params = new URLSearchParams();\n\t\t}\n\n\t\tthis.#config.url.search = this.#config.params.toString();\n\n\t\treturn this;\n\t}\n\n\n\n /**\n * Sets a query parameter to be added to the request URL.\n * Use a nullish value to unset a parameter.\n *\n * @param {String} key - the parameter name to set\n * @param {?String} value - the parameter's value; a nullish value will remove the param again\n * @param {?Boolean} [append=false] - if true, the parameter is appended instead of overwritten\n * @returns {RestfulJsonClient}\n *\n * @example\n * (new RestfulJsonClient('/food/search')).param('q', 'delicious pizza').get();\n */\n\tparam(key, value, append=false){\n key = `${key}`;\n\t\tappend = orDefault(append, false, 'bool');\n\n if( hasValue(value) ){\n\t\t\tif( append ){\n this.#config.params.append(key, `${value}`);\n\t\t\t} else {\n this.#config.params.set(key, `${value}`);\n\t\t\t}\n } else {\n delete this.#config.params.delete(key);\n }\n\n this.#config.url.search = this.#config.params.toString();\n\n return this;\n\t}\n\n\n\n\t/**\n\t * Sets data payload for POST, PUT and PATCH requests.\n\t *\n\t * @param {?Object} data - data payload to send with the next POST, PUT or PATCH request, this parameter will set a permanent payload; for one-off payloads, use the verb method's data parameter; if nullish, data will be emptied\n\t * @throws error if given data is not a plain object\n\t * @returns {RestfulJsonClient}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/food/order')).data({pizza : 'diavolo'}).post();\n\t */\n\tdata(data){\n\t\tconst __methodName__ = 'data';\n\n\t\tif( hasValue(data) ){\n\t\t\tassert(isPlainObject(data), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#dataValidationMessage}`);\n\t\t\tthis.#config.data = data;\n\t\t} else {\n\t\t\tthis.#config.data = {};\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Queries the current URL with GET.\n\t *\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns {Basic.Deferred}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/food/')).path('pizza').get();\n\t */\n\tget(){\n\t\treturn this.#executeRequest('GET');\n\t}\n\n\n\n\t/**\n\t * Queries the current URL with POST using defined payload/data.\n\t *\n\t * @param {?Object} [data=null] - one-off data to use in this request, will replace any central data defined before and will only be valid for this request\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns {Basic.Deferred}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/food/order')).post({pizza : 'diavolo'});\n\t */\n\tpost(data=null){\n\t\treturn this.#executeRequestWithPayload('POST', data);\n\t}\n\n\n\n\t/**\n\t * Queries the current URL with PUT using defined payload/data.\n\t *\n\t * @param {?Object} [data=null] - one-off data to use in this request, will replace any central data defined before and will only be valid for this request\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns {Basic.Deferred}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/food/deliver')).put({pizza : 'diavolo'});\n\t */\n\tput(data=null){\n\t\treturn this.#executeRequestWithPayload('PUT', data);\n\t}\n\n\n\n\t/**\n\t * Queries the current URL with PATCH using defined payload/data.\n\t *\n\t * @param {?Object} [data=null] - one-off data to use in this request, will replace any central data defined before and will only be valid for this request\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns {Basic.Deferred}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/software')).data({version : 2}).patch();\n\t */\n\tpatch(data=null){\n\t\treturn this.#executeRequestWithPayload('PATCH', data);\n\t}\n\n\n\n\t/**\n\t * Queries the current URL with DELETE.\n\t *\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns {Basic.Deferred}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/')).data({command : 'rm -rf'}).delete();\n\t */\n\tdelete(){\n\t\treturn this.#executeRequest('DELETE');\n\t}\n\n\n\n\t/**\n\t * Returns the current config.\n\t *\n\t * baseUrl is retrievable from the url property (via origin).\n\t * Options are the merged result of baseOptions and currently set option values.\n\t *\n\t * Changes to this object, will not reflect in the client config directly, use the client's methods to\n\t * alter config values.\n\t *\n\t * @returns {RestfulJsonClientConfig} a clone of the current config\n\t *\n\t * @example\n\t * client.getConfig().url.toString()\n\t * => https://pizza.com\n\t */\n\tgetConfig(){\n\t\treturn merge(this.#config, {options : merge(this.#baseOptions, this.#config.options)});\n\t}\n\n\n\n\t/**\n\t * Creates and executes an HTTP request without a payload, such as GET and DELETE.\n\t * Uses current config from class to construct request.\n\t *\n\t * @param {String} method - either GET or DELETE\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns Basic.Deferred\n\t *\n\t * @example\n\t * this.#executeRequest('GET');\n\t */\n\t#executeRequest(method){\n\t\tconst __methodName__ = '#executeRequest';\n\n\t\tmethod = method.toUpperCase();\n\t\tassert(\n\t\t\t['GET', 'DELETE'].includes(method),\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#invalidRequestMethodMessage} \"${method}\"`\n\t\t);\n\n\t\tconst options = merge(this.#baseOptions, this.#config.options, {method});\n\t\treturn createJsonRequest(this.#config.url, options, this.#useNative, this.#strict).execute();\n\t}\n\n\n\n\t/**\n\t * Creates and executes an HTTP request with a payload, such as POST and PUT.\n\t * Uses current config from class to construct request.\n\t *\n\t * @param {String} method - either POST, PUT or PATCH\n\t * @param {?Object} [data=null] - the data to send to the request URL as payload\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns Basic.Deferred\n\t *\n\t * @example\n\t * this.#executeRequestWithPayload('POST', {foo : 'bar'});\n\t */\n\t#executeRequestWithPayload(method, data=null){\n\t\tconst __methodName__ = '#executeRequestWithPayload';\n\n\t\tmethod = method.toUpperCase();\n\t\tassert(\n\t\t\t['POST', 'PUT', 'PATCH'].includes(method),\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#invalidRequestMethodMessage} \"${method}\"`\n\t\t);\n\t\tif( hasValue(data) ){\n\t\t\tassert(isPlainObject(data), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#dataValidationMessage}`);\n\t\t}\n\n\t\tconst contentTypeHeader = 'Content-Type';\n\t\tthis.header(contentTypeHeader, 'application/json; charset=UTF-8');\n\t\tconst\n\t\t\tbody = JSON.stringify(data ?? this.#config.data),\n\t\t\toptions = merge(this.#baseOptions, this.#config.options, {method, body})\n\t\t;\n\t\treturn createJsonRequest(this.#config.url, options, this.#useNative, this.#strict)\n\t\t\t.execute()\n\t\t\t.finally(() => {\n\t\t\t\tthis.header(contentTypeHeader, null);\n\t\t\t})\n\t\t;\n\t}\n\n\n\n\t/**\n\t * Transforms a dictionary to an entries array, but handles list values, such as arrays and sets, specially, by\n\t * iterating them and creating a new entry for each list value, thereby producing a notation, which is compatible\n\t * to URLSearchParams, based on an object with a readable notation.\n\t *\n\t * @param {Object} obj - the object to transform into a flattened array of entries\n\t * @returns {Array>} flat array of entries\n\t *\n\t * @private\n\t * @see https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams\n\t */\n\t#toFlatEntries(obj){\n\t\tconst\n\t\t\tentries = Object.entries(obj),\n\t\t\tflattenedEntries = []\n\t\t;\n\n\t\tfor(const entryIndex in entries ){\n\t\t\tconst\n\t\t\t\tentryKey = entries[entryIndex][0],\n\t\t\t\tentryVal = entries[entryIndex][1],\n\t\t\t\tentryValType = getType(entryVal)\n\t\t\t;\n\n\t\t\tif( ['array', 'set'].includes(entryValType) ){\n\t\t\t\tArray.from(entryVal).forEach(val => {\n\t\t\t\t\tflattenedEntries.push([entryKey, `${val}`]);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tflattenedEntries.push([entryKey, `${entryVal}`]);\n\t\t\t}\n\t\t}\n\n\t\treturn flattenedEntries;\n\t}\n\n}\n\nexport {RestfulJsonClient};\n\n\n\n/**\n * @namespace Requests:createJsRequest\n */\n\n/**\n * @typedef JsFetchResponse\n * @type {HTMLElement|String}\n *\n * @memberof Requests\n */\n\n/**\n * @typedef JsFetchRequestExecuteFunction\n * @type {Function}\n *\n * @param {?String} [resolveTo='element'] - defines what the response should resolve to, may either be \"element\", \"raw\" or \"sourced-element\" (which is the special case to insert a script with a src instead of doing a real request)\n * @param {?HTMLElement|Object} [insertTarget=null] - defines if the retrieved value should be inserted as a dom element and if so where; if this is an element, the value gets appended into that as a script tag, otherwise the properties below apply\n * @param {?HTMLElement} [insertTarget.element] - target element in relation to which the resolved value should be inserted into the dom\n * @param {?String} [insertTarget.position] - defines where, in relation to the target element, the resolved value will be inserted, see insertNode for more details\n * @param {?String} [dataId=null] - if you need an identifier, to find inserted elements again after they are inserted into dom, you can define an id here, which will be set as the \"data-id\" attribute on the created node\n * @param {?Boolean} [resolveSourcedOnInsert=false] - normally sourced elements resolve on load to work with the request as far as possible, but if you want to ignore the request after insertion, you may set this parameter to \"true\", resulting in immediate resolution after insertion\n * @returns {Basic.Deferred}\n *\n * @memberof Requests\n * @see insertNode\n */\n\n/**\n * @typedef JsFetchRequest\n * @type {Object}\n *\n * @property {String} url - the request URL\n * @property {Object} options - the options with which the request has been created\n * @property {String} options.method - the request method\n * @property {?Object} options.headers - the set headers for the request\n * @property {?String} options.credentials - the credentials setting for the request\n * @property {?String} options.body - the provided request body of the request\n * @property {?Number} [options.timeout=10000] - milliseconds until the request fails due to a timeout\n * @property {Requests.JsFetchRequestExecuteFunction} execute - call this to execute the request\n *\n * @memberof Requests\n */\n\n/**\n * This method creates a special version of a FetchRequest specifically designed to retrieve JavaScript.\n *\n * Usually you'll want to retrieve JavaScript to include it into a page to execute the script on the page\n * currently open, so the default mode of this method is to resolve to a directly usable script tag, you may\n * insert into the DOM wherever you please. However, you may also specify to retrieve the raw JavaScript source.\n *\n * Be aware that requesting JavaScript from an unsecure source is a very big security risk. Do not load and execute\n * source from a source you do not fully trust!\n *\n * If you plan on inserting the result into DOM anyway you'll like the fact that this is also directly possible, by\n * defining an insert target. In case you decide to insert the result directly, the default is an inline script, but\n * you may also choose to insert a sourced script tag, loading a script on insertion and executing in asynchronously\n * in turn. This is not strictly a programmatic \"request\" anymore, but very handy. If you are inserting a sourced\n * script, the Deferred resolves on load by default (and rejects on error), thereby keeping the general idea of\n * working with a request. But you may also define a parameter on execute to force resolve immediately on insert.\n *\n * BTW: Inserting does not automatically change the resolve value, those are separate concerns.\n *\n * @param {String} url - the complete URL to query\n * @param {?Object} [options=null] - the request options (see: createFetchRequests for details)\n * @param {?Boolean|String} [useNative=false] - determines if the native Fetch implementation of the browser should be used, true forces usage, \"auto\" uses it only if available\n * @param {?Boolean} [strict=true] - if true, enforces \"application/javascript\" as accept header as well as response mime type, if false, accept header is not set and different mime type only results in warning\n * @throws error in strict mode if response content type is not \"application/javascript\"\n * @returns {Requests.JsFetchRequest} use this via the \"execute\" method, which resolves to a FetchResponse or rejects with error in case of a technical request error (request is not completable)\n *\n * @memberof Requests:createJsRequest\n * @alias createJsRequest\n * @see createFetchRequest\n * @example\n * createJsRequest('/js/test.js')\n * .execute()\n * .then(jsElement => { document.body.appendChild(jsElement); })\n * ;\n * createJsRequest('/js/test.js')\n * .execute(null, injectTarget, 'request-2')\n * .then(jsElement => { alert(`has been injected: \"${jsElement.textContent}\"`); })\n * ;\n * createJsRequest('/js/test.js')\n * .execute('raw', {element : injectTarget, position : 'beforebegin'})\n * .then(rawJs => { alert(`has been injected: \"${rawJs}\"`); })\n * ;\n * createJsRequest('/js/test.js')\n * .execute('sourced-element', {element : injectTarget, position : 'prepend'}, 'request-4')\n * .then(jsElement => { alert(`has been injected: \"${jsElement.getAttribute('data-id')}\"`); })\n * ;\n */\nexport function createJsRequest(url, options=null, useNative=false, strict=true){\n\tconst\n\t\t__methodName__ = 'createJsRequest',\n\t\tcontentType = 'application/javascript'\n\t;\n\n\tif( strict ){\n\t\tif( !hasValue(options) ){\n\t\t\toptions = {};\n\t\t}\n\n\t\tif( !hasValue(options.headers) ){\n\t\t\toptions.headers = {};\n\t\t}\n\n\t\toptions.headers['Accept'] = contentType;\n\t}\n\n\treturn {\n\t\turl,\n\t\toptions,\n\t\texecute(resolveTo='element', insertTarget=null, dataId=null, resolveSourcedOnInsert=false){\n\t\t\tconst\n\t\t\t\tsourceElementValue = 'sourced-element',\n\t\t\t\tres = new Deferred(),\n\t\t\t\tfInsertAndResolve = (element, js='') => {\n\t\t\t\t\tif( dataId !== null ){\n\t\t\t\t\t\telement.setAttribute('data-id', `${dataId}`);\n\t\t\t\t\t}\n\n\t\t\t\t\tif( hasValue(insertTarget) ){\n\t\t\t\t\t\tconst\n\t\t\t\t\t\t\ttarget = insertTarget.element ?? insertTarget,\n\t\t\t\t\t\t\tposition = insertTarget.position ?? null\n\t\t\t\t\t\t;\n\n\t\t\t\t\t\tif( !resolveSourcedOnInsert ){\n\t\t\t\t\t\t\telement.onload = () => { res.resolve((resolveTo === 'raw') ? js : element); };\n\t\t\t\t\t\t\telement.onerror = error => { res.reject(error); };\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( position === null ){\n\t\t\t\t\t\t\tinsertNode(target, element);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tinsertNode(target, element, position);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(\n\t\t\t\t\t\t(resolveTo !== sourceElementValue)\n\t\t\t\t\t\t|| ((resolveTo === sourceElementValue) && resolveSourcedOnInsert)\n\t\t\t\t\t){\n\t\t\t\t\t\tres.resolve((resolveTo === 'raw') ? js : element);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t;\n\n\t\t\tif( resolveTo === sourceElementValue ){\n\t\t\t\tfInsertAndResolve(createNode('script', {src : url}));\n\t\t\t} else {\n\t\t\t\tcreateFetchRequest(url, options, useNative).execute()\n\t\t\t\t\t.then(response => {\n\t\t\t\t\t\tconst responseContentType = (\n\t\t\t\t\t\t\tresponse.headers.get('content-type') ?? response.headers.get('Content-Type') ?? ''\n\t\t\t\t\t\t).split(';')[0].trim();\n\n\t\t\t\t\t\tif( responseContentType !== contentType ){\n\t\t\t\t\t\t\tconst message = `${MODULE_NAME}:${__methodName__} | content-type \"${responseContentType}\" is not valid for JavaScript, expecting \"application/javascript\"`;\n\t\t\t\t\t\t\tif( strict ){\n\t\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\twarn(message);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn response.text();\n\t\t\t\t\t})\n\t\t\t\t\t.then(js => {\n\t\t\t\t\t\tfInsertAndResolve(createNode('script', null, js), js);\n\t\t\t\t\t})\n\t\t\t\t\t.catch(error => {\n\t\t\t\t\t\tres.reject(error);\n\t\t\t\t\t})\n\t\t\t\t;\n\t\t\t}\n\n\t\t\treturn res;\n\t\t}\n\t};\n}\n\n\n\n/**\n * @namespace Requests:createCssRequest\n */\n\n/**\n * @typedef CssFetchResponse\n * @type {HTMLElement|String}\n *\n * @memberof Requests\n */\n\n/**\n * @typedef CssFetchRequestExecuteFunction\n * @type {Function}\n *\n * @param {?String} [resolveTo='element'] - defines what the response should resolve to, may either be \"element\", \"raw\" or \"sourced-element\" (which is the special case to insert a link with a href instead of doing a real request)\n * @param {?HTMLElement|Object} [insertTarget=null] - defines if the retrieved value should be inserted as a dom element and if so where; if this is an element, the value gets appended into that as a style/link tag, otherwise the properties below apply\n * @param {?HTMLElement} [insertTarget.element] - target element in relation to which the resolved value should be inserted into the dom\n * @param {?String} [insertTarget.position] - defines where, in relation to the target element, the resolved value will be inserted, see insertNode for more details\n * @param {?String} [dataId=null] - if you need an identifier, to find inserted elements again after they are inserted into dom, you can define an id here, which will be set as the \"data-id\" attribute on the created node\n * @param {?String} [media='all'] - define the style's media attribute here to target the output device(s), could be \"screen\" or \"print\" for example\n * @param {?Boolean} [resolveSourcedOnInsert=false] - normally sourced elements resolve on load to work with the request as far as possible, but if you want to ignore the request after insertion, you may set this parameter to \"true\", resulting in immediate resolution after insertion\n * @returns {Basic.Deferred}\n *\n * @memberof Requests\n * @see insertNode\n */\n\n/**\n * @typedef CssFetchRequest\n * @type {Object}\n *\n * @property {String} url - the request URL\n * @property {Object} options - the options with which the request has been created\n * @property {String} options.method - the request method\n * @property {?Object} options.headers - the set headers for the request\n * @property {?String} options.credentials - the credentials setting for the request\n * @property {?String} options.body - the provided request body of the request\n * @property {?Number} [options.timeout=10000] - milliseconds until the request fails due to a timeout\n * @property {Requests.CssFetchRequestExecuteFunction} execute - call this to execute the request\n *\n * @memberof Requests\n */\n\n/**\n * This method creates a special version of a FetchRequest specifically designed to retrieve Cascading Stylesheets.\n *\n * Usually you'll want to retrieve CSS to include it into a page and thereby style something on the page\n * currently open, so the default mode of this method is to resolve to a directly usable style tag, you may\n * insert into the DOM wherever you please. However, you may also specify to retrieve the raw CSS source.\n *\n * If you plan on inserting the result into DOM anyway you'll like the fact that this is also directly possible, by\n * defining an insert target. In case you decide to insert the result directly, the default is an inline style, but\n * you may also choose to insert a sourced link tag, loading a stylesheet on insertion and adding the included styles\n * on load. This is not strictly a programmatic \"request\" anymore, but very handy. If you are inserting a sourced\n * link, the Deferred resolves on load by default (and rejects on error), thereby keeping the general idea of\n * working with a request. But you may also define a parameter on execute to force resolve immediately on insert.\n *\n * BTW: Inserting does not automatically change the resolve value, those are separate concerns.\n *\n * @param {String} url - the complete URL to query\n * @param {?Object} [options=null] - the request options (see: createFetchRequests for details)\n * @param {?Boolean|String} [useNative=false] - determines if the native Fetch implementation of the browser should be used, true forces usage, \"auto\" uses it only if available\n * @param {?Boolean} [strict=true] - if true, enforces \"text/css\" as accept header as well as response mime type, if false, accept header is not set and different mime type only results in warning\n * @throws error in strict mode if response content type is not \"text/css\"\n * @returns {Requests.CssFetchRequest} use this via the \"execute\" method, which resolves to a FetchResponse or rejects with error in case of a technical request error (request is not completable)\n *\n * @memberof Requests:createCssRequest\n * @alias createCssRequest\n * @see createFetchRequest\n * @example\n * createCssRequest('/css/test.css')\n * .execute()\n * .then(cssElement => { document.head.appendChild(cssElement); })\n * ;\n * createCssRequest('/css/test.css')\n * .execute(null, injectTarget, 'request-2')\n * .then(cssElement => { alert(`has been injected: \"${cssElement.textContent}\"`); })\n * ;\n * createCssRequest('/css/test.css')\n * .execute('raw', {element : injectTarget, position : 'beforebegin'}, 'request-3', 'screen')\n * .then(rawCss => { alert(`has been injected: \"${rawCss}\"`); })\n * ;\n * createCssRequest('/css/test.css')\n * .execute('sourced-element', {element : injectTarget, position : 'prepend'}, 'request-4', 'screen')\n * .then(cssElement => { alert(`has been injected: \"${cssElement.getAttribute('data-id')+}\"`); })\n * ;\n */\nexport function createCssRequest(url, options=null, useNative=false, strict=true){\n\tconst\n\t\t__methodName__ = 'createCssRequest',\n\t\tcontentType = 'text/css'\n\t;\n\n\n\tif( strict ){\n\t\tif( !hasValue(options) ){\n\t\t\toptions = {};\n\t\t}\n\n\t\tif( !hasValue(options.headers) ){\n\t\t\toptions.headers = {};\n\t\t}\n\n\t\toptions.headers['Accept'] = contentType;\n\t}\n\n\treturn {\n\t\turl,\n\t\toptions,\n\t\texecute(resolveTo='element', insertTarget=null, dataId=null, media='all', resolveSourcedOnInsert=false){\n\t\t\tconst\n\t\t\t\tsourceElementValue = 'sourced-element',\n\t\t\t\tres = new Deferred(),\n\t\t\t\tfInsertAndResolve = (element, css='') => {\n\t\t\t\t\tif( dataId !== null ){\n\t\t\t\t\t\telement.setAttribute('data-id', `${dataId}`);\n\t\t\t\t\t}\n\n\t\t\t\t\tif( hasValue(insertTarget) ){\n\t\t\t\t\t\tconst\n\t\t\t\t\t\t\ttarget = insertTarget.element ?? insertTarget,\n\t\t\t\t\t\t\tposition = insertTarget.position ?? null\n\t\t\t\t\t\t;\n\n\t\t\t\t\t\tif( !resolveSourcedOnInsert ){\n\t\t\t\t\t\t\telement.onload = () => { res.resolve((resolveTo === 'raw') ? css : element); };\n\t\t\t\t\t\t\telement.onerror = error => { res.reject(error); };\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( position === null ){\n\t\t\t\t\t\t\tinsertNode(target, element);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tinsertNode(target, element, position);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(\n\t\t\t\t\t\t(resolveTo !== sourceElementValue)\n\t\t\t\t\t\t|| ((resolveTo === sourceElementValue) && resolveSourcedOnInsert)\n\t\t\t\t\t){\n\t\t\t\t\t\tres.resolve((resolveTo === 'raw') ? css : element);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t;\n\n\t\t\tif( resolveTo === sourceElementValue ){\n\t\t\t\tconst linkAttrs = {href : url, rel : 'stylesheet'};\n\t\t\t\tif( media !== 'all' ){\n\t\t\t\t\tlinkAttrs.media = media;\n\t\t\t\t}\n\t\t\t\tfInsertAndResolve(createNode('link', linkAttrs));\n\t\t\t} else {\n\t\t\t\tcreateFetchRequest(url, options, useNative).execute()\n\t\t\t\t\t.then(response => {\n\t\t\t\t\t\tconst responseContentType = (\n\t\t\t\t\t\t\tresponse.headers.get('content-type') ?? response.headers.get('Content-Type') ?? ''\n\t\t\t\t\t\t).split(';')[0].trim();\n\n\t\t\t\t\t\tif( responseContentType !== contentType ){\n\t\t\t\t\t\t\tconst message = `${MODULE_NAME}:${__methodName__} | content-type \"${responseContentType}\" is not valid for CSS, expecting \"text/css\"`;\n\t\t\t\t\t\t\tif( strict ){\n\t\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\twarn(message);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn response.text();\n\t\t\t\t\t})\n\t\t\t\t\t.then(css => {\n\t\t\t\t\t\tfInsertAndResolve(createNode('style', (media !== 'all') ? {media} : null, css), css);\n\t\t\t\t\t})\n\t\t\t\t\t.catch(error => {\n\t\t\t\t\t\tres.reject(error);\n\t\t\t\t\t})\n\t\t\t\t;\n\t\t\t}\n\n\t\t\treturn res;\n\t\t}\n\t};\n}\n\n\n\n/**\n * @namespace Requests:createHtmlRequest\n */\n\n/**\n * @typedef HtmlFetchResponse\n * @type {HTMLElement|Array|String}\n *\n * @memberof Requests\n */\n\n/**\n * @typedef HtmlFetchRequestExecuteFunction\n * @type {Function}\n *\n * @param {?String} [resolveTo='element'] - defines what the response should resolve to, may either be \"element\" or \"raw\"\n * @param {?HTMLElement|Object} [insertTarget=null] - defines if the retrieved value should be inserted as a dom element and if so where; if this is an element, the value gets appended into that as (a) node(s), otherwise the properties below apply\n * @param {?HTMLElement} [insertTarget.element] - target element in relation to which the resolved value should be inserted into the dom\n * @param {?String} [insertTarget.position] - defines where, in relation to the target element, the resolved value will be inserted, see insertNode for more details\n * @param {?String} [dataId=null] - if you need an identifier, to find inserted elements again after they are inserted into dom, you can define an id here, which will be set as the \"data-id\" attribute on the created node(s)\n * @param {?String} [selector=null] - if you'd like to preselect something from the result, you may define a regular query selector to find matching elements in the result\n * @param {?Boolean} [selectAll=false] - usually, if a selector is defined, we select a single element, if you need to select a list, set this to true\n * @returns {Basic.Deferred}\n *\n * @memberof Requests\n * @see insertNode\n */\n\n/**\n * @typedef HtmlFetchRequest\n * @type {Object}\n *\n * @property {String} url - the request URL\n * @property {Object} options - the options with which the request has been created\n * @property {String} options.method - the request method\n * @property {?Object} options.headers - the set headers for the request\n * @property {?String} options.credentials - the credentials setting for the request\n * @property {?String} options.body - the provided request body of the request\n * @property {?Number} [options.timeout=10000] - milliseconds until the request fails due to a timeout\n * @property {Requests.HtmlFetchRequestExecuteFunction} execute - call this to execute the request\n *\n * @memberof Requests\n */\n\n/**\n * This method creates a special version of a FetchRequest specifically designed to retrieve HTML content.\n *\n * Usually you'll want to retrieve HTML to include it into a page or extract information from it, so the default mode\n * of this method is to resolve to a node, you may insert into the DOM wherever you please or use stuff like a\n * querySelector on. However, you may also specify to retrieve the raw HTML source.\n *\n * Be aware, that requesting and parsing HTML from an unsecure source comes with a high risk. If you cannot fully\n * trust the source, request the HTML raw and use something like dom purify before using the result.\n *\n * If you plan on inserting the result into DOM anyway you'll like the fact that this is also directly possible, by\n * defining an insert target.\n *\n * BTW: Inserting does not automatically change the resolve value, those are separate concerns.\n *\n * @param {String} url - the complete URL to query\n * @param {?Object} [options=null] - the request options (see: createFetchRequests for details)\n * @param {?Boolean|String} [useNative=false] - determines if the native Fetch implementation of the browser should be used, true forces usage, \"auto\" uses it only if available\n * @param {?Boolean} [strict=true] - if true, enforces \"text/html\" as accept header as well as response mime type, if false, accept header is not set and different mime type only results in warning\n * @throws error in strict mode if response content type is not \"text/html\"\n * @returns {Requests.HtmlFetchRequest} use this via the \"execute\" method, which resolves to a FetchResponse or rejects with error in case of a technical request error (request is not completable)\n *\n * @memberof Requests:createHtmlRequest\n * @alias createHtmlRequest\n * @see createFetchRequest\n * @example\n * createHtmlRequest('/html/test.html')\n * .execute()\n * .then(htmlElement => { document.body.appendChild(htmlElement); })\n * ;\n * createHtmlRequest('/html/test.html')\n * .execute('raw', null, 'request-1')\n * .then(rawHtml => { alert(`document has been loaded: \"${rawHtml}\"`); })\n * ;\n * createHtmlRequest('/html/test.html')\n * .execute(null, injectTarget, 'request-3', 'body > main > h1')\n * .then(htmlElement => { alert(`has been injected: \"${htmlElement.outerHTML}\"`); })\n * ;\n * createHtmlRequest('/files/html/requests-test-1.html')\n * .execute('raw', {element : injectTarget, position : 'beforebegin'}, 'request-4', 'h1 ~ p', true)\n * .then(rawHtml => { alert(`has been injected: \"${rawHtml}\"`); })\n * ;\n * createHtmlRequest('/files/html/requests-test-2.html')\n * .execute('element', {element : injectTarget, position : 'prepend'}, 'request-5', 'p', true)\n * .then(htmlElements => { alert(`has been injected: \"${htmlElements.map(e => e.outerHTML).join('')}\"`); })\n * ;\n */\nexport function createHtmlRequest(url, options=null, useNative=false, strict=true){\n\tconst\n\t\t__methodName__ = 'createHtmlRequest',\n\t\tcontentType = 'text/html'\n\t;\n\n\tif( strict ){\n\t\tif( !hasValue(options) ){\n\t\t\toptions = {};\n\t\t}\n\n\t\tif( !hasValue(options.headers) ){\n\t\t\toptions.headers = {};\n\t\t}\n\n\t\toptions.headers['Accept'] = contentType;\n\t}\n\n\treturn {\n\t\turl,\n\t\toptions,\n\t\texecute(resolveTo='element', insertTarget=null, dataId=null, selector=null, selectAll=false){\n\t\t\tconst\n\t\t\t\tres = new Deferred(),\n\t\t\t\tfInsertAndResolve = (element, html='') => {\n\t\t\t\t\tif( hasValue(element) ){\n\t\t\t\t\t\tconst elements = [].concat(element);\n\n\t\t\t\t\t\tif( dataId !== null ){\n\t\t\t\t\t\t\telements.forEach(element => {\n\t\t\t\t\t\t\t\telement.setAttribute('data-id', `${dataId}`);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( hasValue(insertTarget) ){\n\t\t\t\t\t\t\tconst\n\t\t\t\t\t\t\t\ttarget = insertTarget.element ?? insertTarget,\n\t\t\t\t\t\t\t\tposition = insertTarget.position ?? null\n\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\tif( ['before', 'beforebegin', 'prepend', 'afterbegin'].includes(position) ){\n\t\t\t\t\t\t\t\telements.reverse();\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\telements.forEach(element => {\n\t\t\t\t\t\t\t\tif( position === null ){\n\t\t\t\t\t\t\t\t\tinsertNode(target, element);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tinsertNode(target, element, position);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tres.resolve((resolveTo === 'raw') ? html : element);\n\t\t\t\t}\n\t\t\t;\n\n\t\t\tcreateFetchRequest(url, options, useNative).execute()\n\t\t\t\t.then(response => {\n\t\t\t\t\tconst responseContentType = (\n\t\t\t\t\t\tresponse.headers.get('content-type') ?? response.headers.get('Content-Type') ?? ''\n\t\t\t\t\t).split(';')[0].trim();\n\t\t\t\t\tif( responseContentType !== contentType ){\n\t\t\t\t\t\tconst message = `${MODULE_NAME}:${__methodName__} | content-type \"${responseContentType}\" is not valid for HTML, expecting \"text/html\"`;\n\t\t\t\t\t\tif( strict ){\n\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\twarn(message);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn response.text();\n\t\t\t\t})\n\t\t\t\t.then(html => {\n\t\t\t\t\tconst\n\t\t\t\t\t\tisWholeDocument = html.includes(' {\n\t\t\t\t\t\t\t\thtml += element.outerHTML;\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tfInsertAndResolve(element, html);\n\t\t\t\t})\n\t\t\t\t.catch(error => {\n\t\t\t\t\tres.reject(error);\n\t\t\t\t})\n\t\t\t;\n\n\t\t\treturn res;\n\t\t}\n\t};\n}\n\n\n\n/**\n * @namespace Requests:visitUrl\n */\n\n/**\n * This function opens a given URL, using a dynamically created iframe, thereby opening the URL as if the user\n * him- or herself navigates to the URL using a browser window. Why should we do this you ask?\n *\n * For example: In session management, you'll sometimes have the case, that you need to trigger URLs on login or logout,\n * that construct or destruct parts of the session by creating of removing cookie or other client-storage items.\n * If that domain is part of a system running on another (sub)domain, using a usual client request for this will\n * not work, since the calling context of the request will have no access to the storage scope of that domain.\n *\n * So, to allow those domains to do their tasks, triggered from a different context, we can use this method to execute\n * those webhooks with the iframe, which natively runs in the called domains scope and therefore can do all necessary\n * domain-based storage actions.\n *\n * The big downside of this is, that we cannot really handle errors well this way. So if the URL returns a 404\n * or a 500, this will actually be treated as a resolved promise, since the iframe loaded. The only case a request\n * of this kind fails, is if the request runs into a timeout. So, for really critical actions, this way of handling\n * thing should be avoided in favour of an approach, that actually includes a postMessage implementation on the other\n * domain, to verify completion on load.\n *\n * @param {String} url - the URL to query, will be the current one if left empty\n * @param {?Number} [timeout=5000] - the timeout in ms to wait for completion of the request, before rejecting the promise\n * @param {?String} [tokenValue=null] - if the URL needs to include a token, you can provide this token here, which will replace the placeholder defined in \"tokenPlaceholder\"\n * @param {?String} [tokenPlaceholder='token'] = the placeholder in the url to replace with the tokenValue, must be surrounded with curly braces in the url (\"{token}\")\n * @returns {Basic.Deferred} resolves on load of URL (with the final URL as resolution value), rejects on timeout (with a \"timeout\" error)\n *\n * @memberof Requests:visitUrl\n * @alias visitUrl\n * @example\n * visitUrl('https://some.other.domain?token={token}', 2500, 'A38')\n * .then(() => { console.log('loaded!'); })\n * ;\n * visitUrl(\n * 'https://some.other.domain?token={session_value}',\n * 5000,\n * 'A38',\n * 'session_value'\n * )\n * .then(url => { console.log(`\"${url}\" loaded!`); })\n * .catch(error => { console.log(`${error.message} - URL did not load super fast, blimey!`); })\n * ;\n */\nexport function visitUrl(url, timeout=5000, tokenValue=null, tokenPlaceholder='token'){\n\turl = orDefault(url, '', 'str');\n\ttimeout = Math.abs(orDefault(timeout, 5000, 'int'));\n\ttokenValue = orDefault(tokenValue, null, 'str');\n\ttokenPlaceholder = orDefault(tokenPlaceholder, 'token', 'str');\n\turl = hasValue(tokenValue) ? url.replaceAll(`{${tokenPlaceholder}}`, tokenValue) : url;\n\n\tconst\n\t\tdeferred = new Deferred(),\n\t\touterNode = document.createElement('div')\n\t;\n\n\touterNode.innerHTML = `\n\t\t\n\t`.trim();\n\n\tconst\n\t\tiframe = outerNode.firstChild,\n\t\tfOnLoad = () => {\n\t\t\tiframe.removeEventListener('load', fOnLoad);\n\t\t\twindow.clearTimeout(loadTimeout);\n\t\t\t// we need to wait a bit after load before removing the iframe,\n\t\t\t// otherwise safari considers the request cancelled :(\n\t\t\twindow.setTimeout(() => {\n\t\t\t\tdocument.body.removeChild(iframe);\n\t\t\t\tdeferred.resolve(url);\n\t\t\t}, 250);\n\t\t},\n\t\tloadTimeout = window.setTimeout(() => {\n\t\t\tiframe.removeEventListener('load', fOnLoad);\n\t\t\tdocument.body.removeChild(iframe);\n\t\t\tdeferred.reject(new Error('timeout'));\n\t\t}, timeout)\n\t;\n\n\tiframe.addEventListener('load', fOnLoad);\n\tdocument.body.appendChild(iframe);\n\n\treturn deferred;\n}\n"]} \ No newline at end of file +{"version":3,"file":"requests.js","names":["MODULE_NAME","warn","hasValue","orDefault","isPlainObject","assert","Deferred","getType","merge","createNode","insertNode","schedule","countermand","createFetchRequest","url","options","useNative","__methodName__","method","includes","toUpperCase","timeout","window","__ANNEX_USE_NATIVE_FETCH__","execute","res","request","XMLHttpRequest","headerKeys","Set","headerEntries","Map","response","ok","parseInt","status","statusText","responseURL","text","Promise","resolve","responseText","json","then","JSON","parse","blob","Blob","clone","headers","keys","entries","get","key","has","open","ontimeout","reject","Error","onload","getAllResponseHeaders","replace","m","value","add","set","onerror","withCredentials","credentials","i","hasOwnProperty","setRequestHeader","send","body","timeoutTimer","abortController","AbortController","signal","fetch","catch","error","abort","createJsonRequest","strict","contentType","resolveTo","insertTarget","dataId","responseContentType","split","trim","message","element","stringify","setAttribute","target","position","RestfulJsonClient","__className__","invalidRequestMethodMessage","dataValidationMessage","baseUrl","baseOptions","config","constructor","this","location","origin","startsWith","URL","params","URLSearchParams","data","path","replaceAll","header","toFlatEntries","search","toString","param","append","delete","executeRequest","post","executeRequestWithPayload","put","patch","getConfig","contentTypeHeader","finally","obj","Object","flattenedEntries","entryIndex","entryKey","entryVal","entryValType","Array","from","forEach","val","push","createJsRequest","resolveSourcedOnInsert","sourceElementValue","fInsertAndResolve","js","src","createCssRequest","media","css","linkAttrs","href","rel","createHtmlRequest","selector","selectAll","html","isWholeDocument","isDocument","fragmentNode","DOMParser","parseFromString","documentElement","querySelectorAll","querySelector","children","length","item","concat","outerHTML","elements","reverse","visitUrl","tokenValue","tokenPlaceholder","Math","abs","deferred","outerNode","document","createElement","innerHTML","iframe","firstChild","fOnLoad","removeEventListener","clearTimeout","loadTimeout","setTimeout","removeChild","addEventListener","appendChild"],"sources":["requests.js"],"mappings":"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","ignoreList":[],"sourcesContent":["/*!\n * Module Requests\n */\n\n/**\n * @namespace Requests\n */\n\nconst MODULE_NAME = 'Requests';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {warn} from './logging.js';\nimport {hasValue, orDefault, isPlainObject, assert, Deferred, getType} from './basic.js';\nimport {merge} from './objects.js';\nimport {createNode, insertNode} from './elements.js';\nimport {schedule, countermand} from './timers.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Requests:createFetchRequest\n */\n\n/**\n * @typedef FetchResponse\n * @type {Object}\n *\n * @property {Boolean} ok - returns true if the request received a status in the OK range (200-299)\n * @property {Number} status - contains the status code of the response, e.g. 404 for a not found resource, 200 for a success\n * @property {String} statusText - a message related to the status attribute, e.g. OK for a status 200\n * @property {Function} clone - will return another object with the same shape and content as response\n * @property {Function} text - will return the response content as plain text\n * @property {Function} json - will return the response content as JSON\n * @property {Function} blob - will return the response content as a (binary) blob\n * @property {Object} headers - we do not implement a full spec-compliant Headers class, but emulate some of the functionality\n * @property {Function} headers.keys - returns an Iterable containing the key for every header in the response, transform to array with Array.from\n * @property {Function} headers.entries - returns an Iterable containing the [key, value] pairs for every header in the response, transform to array with Array.from\n * @property {Function} headers.get - returns the value associated with the given key\n * @property {Function} headers.has - returns a boolean asserting the existence of a value for the given key among the response headers\n *\n * @memberof Requests\n */\n\n/**\n * @typedef FetchRequestExecuteFunction\n * @type {Function}\n *\n * @returns {Basic.Deferred}\n *\n * @memberof Requests\n */\n\n/**\n * @typedef FetchRequest\n * @type {Object}\n *\n * @property {String} url - the request URL\n * @property {Object} options - the options with which the request has been created\n * @property {String} options.method - the request method\n * @property {?Object} options.headers - the set headers for the request\n * @property {?String} options.credentials - the credentials setting for the request\n * @property {?String} options.body - the provided request body of the request\n * @property {?Number} [options.timeout=10000] - milliseconds until the request fails due to a timeout\n * @property {Requests.FetchRequestExecuteFunction} execute - call this to execute the request\n *\n * @memberof Requests\n */\n\n/**\n * This method creates a ponyfilled fetch request based on \"unfetch\", but basically fulfilling the signature of\n * a native fetch request.\n *\n * The reasoning for this is to provide a baseline fetch implementation for all requests of annex, as long as we\n * still support non ES6 browsers or old implementations in any way. During transpilation with core js, fetch does\n * not automatically get polyfilled, so we need to do this ourselves and to actually stay testable, we provide the\n * polyfill as long as we might target legacy contexts. As soon as we drop legacy contexts, we can immediately also\n * remove this method and its uses.\n *\n * The function signature is the same as \"unfetch\"'s and all non-implemented features are absent here as well.\n *\n * All usual responses (40X and 50X as well) resolve, only uncompletable requests, such as those being prevented by a\n * general network error, reject with the provided error.\n *\n * Set __ANNEX_USE_NATIVE_FETCH__ on window (true/false/'auto') to force useNative setting for all annex requests\n * globally.\n *\n * @param {String} url - the complete URL to query\n * @param {?Object} [options=null] - the request options\n * @param {?String} [options.method='GET'] - indicates the request method to be performed on the target resource (one of \"GET\", \"POST\", \"PUT\", \"PATCH\", \"HEAD\", \"OPTIONS\" or \"DELETE\")\n * @param {?Object} [options.headers] - an object containing additional information to be sent with the request (e.g. {\"Content-Type\": \"application/json\"} to indicate a JSON-typed request body)\n * @param {?String} [options.credentials] - accepts an \"include\" string, which will allow both CORS and same origin requests to work with cookies; the method won't send or receive cookies otherwise; the \"same-origin\" value is not supported\n * @param {?Object|String} [options.body] - the content to be transmitted in request's body; common content types include FormData, JSON, Blob, ArrayBuffer or plain text\n * @param {?Boolean|String} [useNative=false] - determines if the native Fetch implementation of the browser should be used, true forces usage, \"auto\" uses it only if available\n * @returns {Requests.FetchRequest} use this via the \"execute\" method, which resolves to a FetchResponse or rejects with error in case of a technical request error (request is not completable)\n *\n * @memberof Requests:createFetchRequest\n * @alias createFetchRequest\n * @see https://github.com/developit/unfetch\n * @see https://github.com/developit/unfetch#fetchurl-string-options-object\n * @example\n * createFetchRequest('/foo').execute()\n * .then(r => r.text())\n * .then(txt => console.log(txt))\n * ;\n * createFetchRequest(\n * '/bear',\n * {\n * method : 'POST',\n * headers : {'Content-Type' : 'application/json'},\n * body : JSON.stringify({hungry : true})\n * })\n * .execute()\n * .then(r => { open(r.headers.get('location')); return r.json(); })\n * ;\n */\nexport function createFetchRequest(url, options=null, useNative=false){\n\tconst __methodName__ = 'createFetchRequest';\n\n\tassert(hasValue(url), `${MODULE_NAME}:${__methodName__} | no url given`);\n\toptions = orDefault(options, {});\n\tassert(isPlainObject(options), `${MODULE_NAME}:${__methodName__} | options must be plain object`);\n\n\toptions.method = orDefault(options.method, 'GET', 'str');\n\toptions.method = ['GET', 'POST', 'PUT', 'PATCH', 'HEAD', 'OPTIONS', 'DELETE'].includes(options.method.toUpperCase())\n\t\t? options.method.toUpperCase()\n\t\t: 'GET'\n\t;\n\n\t// 0 would be unlimited/unset\n\toptions.timeout = orDefault(options.timeout, 10000, 'int');\n\toptions.timeout = (options.timeout < 0) ? 0 : options.timeout;\n\n\tuseNative = window.__ANNEX_USE_NATIVE_FETCH__ ?? useNative;\n\n\treturn {\n\t\turl,\n\t\toptions,\n\t\texecute : !useNative || ((useNative === 'auto') && !('fetch' in window))\n\t\t\t? function(){\n\t\t\t\tconst\n\t\t\t\t\tres = new Deferred(),\n\t\t\t\t\trequest = new XMLHttpRequest(),\n\t\t\t\t\theaderKeys = new Set(),\n\t\t\t\t\theaderEntries = new Map(),\n\t\t\t\t\tresponse = () => ({\n\t\t\t\t\t\tok : (parseInt(request.status, 10) >= 200) && (parseInt(request.status, 10) <= 299),\n\t\t\t\t\t\tstatusText : request.statusText,\n\t\t\t\t\t\tstatus : request.status,\n\t\t\t\t\t\turl : request.responseURL,\n\t\t\t\t\t\ttext : () => Promise.resolve(request.responseText),\n\t\t\t\t\t\tjson : () => Promise.resolve(request.responseText).then(JSON.parse),\n\t\t\t\t\t\tblob : () => Promise.resolve(new Blob([request.response])),\n\t\t\t\t\t\tclone : response,\n\t\t\t\t\t\theaders : {\n\t\t\t\t\t\t\tkeys(){\n\t\t\t\t\t\t\t\treturn headerKeys;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tentries(){\n\t\t\t\t\t\t\t\treturn headerEntries;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tget(key){\n\t\t\t\t\t\t\t\treturn headerEntries.get(key);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\thas(key){\n\t\t\t\t\t\t\t\treturn headerKeys.has(key);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t;\n\n\t\t\t\trequest.open(options.method, url, true);\n\n\t\t\t\tif( options.timeout > 0 ){\n\t\t\t\t\trequest.timeout = options.timeout;\n\t\t\t\t\trequest.ontimeout = () => { res.reject(new Error('timeout')); };\n\t\t\t\t}\n\n\t\t\t\trequest.onload = () => {\n\t\t\t\t\trequest.getAllResponseHeaders().replace(/^(.*?):[^\\S\\n]*([\\s\\S]*?)$/gm, (m, key, value) => {\n\t\t\t\t\t\tkey = `${key}`;\n\t\t\t\t\t\theaderKeys.add(key);\n\t\t\t\t\t\tif( headerEntries.has(key) ){\n\t\t\t\t\t\t\theaderEntries.set(key, `${headerEntries.get(key)},${value}`);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\theaderEntries.set(key, `${value}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tres.resolve(response());\n\t\t\t\t};\n\n\t\t\t\trequest.onerror = res.reject;\n\n\t\t\t\trequest.withCredentials = (options.credentials === 'include');\n\n\t\t\t\tif( hasValue(options.headers) ){\n\t\t\t\t\tfor( let i in options.headers ){\n\t\t\t\t\t\tif( options.headers.hasOwnProperty(i) ){\n\t\t\t\t\t\t\trequest.setRequestHeader(i, options.headers[i]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\trequest.send(options.body ?? null);\n\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\t: function(){\n\t\t\t\tconst\n\t\t\t\t\tres = new Deferred(),\n\t\t\t\t\ttimeout = options.timeout\n\t\t\t\t;\n\n\t\t\t\tlet timeoutTimer, abortController;\n\n\t\t\t\tif( (timeout > 0) && ('AbortController' in window) ){\n\t\t\t\t\tabortController = new AbortController();\n\t\t\t\t\toptions.signal = abortController.signal;\n\t\t\t\t}\n\n\t\t\t\twindow.fetch(url, options)\n\t\t\t\t\t.then(response => {\n\t\t\t\t\t\tcountermand(timeoutTimer);\n\t\t\t\t\t\tres.resolve(response);\n\t\t\t\t\t})\n\t\t\t\t\t.catch(error => {\n\t\t\t\t\t\tcountermand(timeoutTimer);\n\t\t\t\t\t\tres.reject(error);\n\t\t\t\t\t})\n\t\t\t\t;\n\n\t\t\t\tif( (timeout > 0) && ('AbortController' in window) ){\n\t\t\t\t\ttimeoutTimer = schedule(timeout, () => { abortController.abort(); });\n\t\t\t\t}\n\n\t\t\t\treturn res;\n\t\t\t}\n\t};\n}\n\n\n\n/**\n * @namespace Requests:createJsonRequest\n */\n\n/**\n * @typedef JsonFetchResponse\n * @type {Object|HTMLElement|String}\n *\n * @memberof Requests\n */\n\n/**\n * @typedef JsonFetchRequestExecuteFunction\n * @type {Function}\n *\n * @param {?String} [resolveTo='object'] - defines what the response should resolve to, may either be \"object\", \"element\" or \"raw\"\n * @param {?HTMLElement|Object} [insertTarget=null] - defines if the retrieved value should be inserted as a dom element and if so where; if this is an element, the value gets appended into that as a script tag, otherwise the properties below apply\n * @param {?HTMLElement} [insertTarget.element] - target element in relation to which the resolved value should be inserted into the dom\n * @param {?String} [insertTarget.position] - defines where, in relation to the target element, the resolved value will be inserted, see insertNode for more details\n * @param {?String} [dataId=null] - if you need an identifier, to find inserted elements again after they are inserted into dom, you can define an id here, which will be set as the \"data-id\" attribute on the created node\n * @returns {Basic.Deferred}\n *\n * @memberof Requests\n * @see insertNode\n */\n\n/**\n * @typedef JsonFetchRequest\n * @type {Object}\n *\n * @property {String} url - the request URL\n * @property {Object} options - the options with which the request has been created\n * @property {String} options.method - the request method\n * @property {?Object} options.headers - the set headers for the request\n * @property {?String} options.credentials - the credentials setting for the request\n * @property {?String} options.body - the provided request body of the request\n * @property {?Number} [options.timeout=10000] - milliseconds until the request fails due to a timeout\n * @property {Requests.JsonFetchRequestExecuteFunction} execute - call this to execute the request\n *\n * @memberof Requests\n */\n\n/**\n * This method creates a special version of a FetchRequest specifically designed to retrieve JSON data.\n *\n * Usually you'll want to retrieve JSON as a PlainObject, so that's the default resolve value here.\n * However, you may also specify to retrieve the raw JSON or let the method handle the creation of a DOM element\n * for you and return that, ready to be used/inserted however you like.\n *\n * If you plan on inserting the result into DOM anyway you'll like the fact that this is also directly possible, by\n * defining an insert target. BTW: Inserting does not automatically change the resolve value, those are separate\n * concerns.\n *\n * @param {String} url - the complete URL to query\n * @param {?Object} [options=null] - the request options (see: createFetchRequests for details)\n * @param {?Boolean|String} [useNative=false] - determines if the native Fetch implementation of the browser should be used, true forces usage, \"auto\" uses it only if available\n * @param {?Boolean} [strict=true] - if true, enforces \"application/json\" as accept header as well as response mime type, if false, accept header is not set and different mime type only results in warning\n * @throws error in strict mode if response content type is not \"application/json\"\n * @returns {Requests.JsonFetchRequest} use this via the \"execute\" method, which resolves to a FetchResponse or rejects with error in case of a technical request error (request is not completable)\n *\n * @memberof Requests:createJsonRequest\n * @alias createJsonRequest\n * @see createFetchRequest\n * @example\n * createJsonRequest('message.json').execute()\n * .then(json => { alert(json.someProperty); })\n * ;\n * createJsonRequest('/dev/config.json')\n * .execute('element', null, 'config-json-id')\n * .then(jsonElement => { document.querySelector('main').appendChild(jsonElement); })\n * ;\n * createJsonRequest('https://foobar.com/config.json')\n * .execute('raw', {element : document.body, position : 'prepend'}, 'config-json-id')\n * .then(rawJson => { console.log(`\"${rawJson}\" has been inserted at the beginning of the document's body`); })\n * ;\n */\nexport function createJsonRequest(url, options=null, useNative=false, strict=true){\n\tconst\n\t\t__methodName__ = 'createJsonRequest',\n\t\tcontentType = 'application/json'\n\t;\n\n\tif( strict ){\n\t\tif( !hasValue(options) ){\n\t\t\toptions = {};\n\t\t}\n\n\t\tif( !hasValue(options.headers) ){\n\t\t\toptions.headers = {};\n\t\t}\n\n\t\toptions.headers['Accept'] = contentType;\n\t}\n\n\treturn {\n\t\turl,\n\t\toptions,\n\t\texecute(resolveTo='object', insertTarget=null, dataId=null){\n\t\t\tconst res = new Deferred();\n\n\t\t\tcreateFetchRequest(url, options, useNative).execute()\n\t\t\t\t.then(response => {\n\t\t\t\t\tconst responseContentType = (\n\t\t\t\t\t\tresponse.headers.get('content-type') ?? response.headers.get('Content-Type') ?? ''\n\t\t\t\t\t).split(';')[0].trim();\n\n\t\t\t\t\tif( responseContentType !== contentType ){\n\t\t\t\t\t\tconst message = `${MODULE_NAME}:${__methodName__} | content-type \"${responseContentType}\" is not valid for JSON, expecting \"application/json\"`;\n\t\t\t\t\t\tif( strict ){\n\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\twarn(message);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn response.json();\n\t\t\t\t})\n\t\t\t\t.then(json => {\n\t\t\t\t\tconst element = createNode(``);\n\t\t\t\t\tif( dataId !== null ){\n\t\t\t\t\t\telement.setAttribute('data-id', `${dataId}`);\n\t\t\t\t\t}\n\n\t\t\t\t\tif( hasValue(insertTarget) ){\n\t\t\t\t\t\tconst\n\t\t\t\t\t\t\ttarget = insertTarget.element ?? insertTarget,\n\t\t\t\t\t\t\tposition = insertTarget.position ?? null\n\t\t\t\t\t\t;\n\n\t\t\t\t\t\tif( position === null ){\n\t\t\t\t\t\t\tinsertNode(target, element);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tinsertNode(target, element, position);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tres.resolve(\n\t\t\t\t\t\t(resolveTo === 'element')\n\t\t\t\t\t\t\t? element\n\t\t\t\t\t\t\t: (\n\t\t\t\t\t\t\t\t(resolveTo === 'raw')\n\t\t\t\t\t\t\t\t? JSON.stringify(json)\n\t\t\t\t\t\t\t\t: json\n\t\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t})\n\t\t\t\t.catch(error => {\n\t\t\t\t\tres.reject(error);\n\t\t\t\t})\n\t\t\t;\n\n\t\t\treturn res;\n\t\t}\n\t};\n}\n\n\n\n/**\n * @namespace Requests:RestfulJsonClient\n */\n\n/**\n * @typedef RestfulJsonClientConfig\n * @type {Object}\n *\n * @property {URL} url - the current request URL, build from baseUrl and path\n * @property {Object} options - the current options with which requests are been created, build from baseOptions and options, see createFetchRequest for details\n * @property {URLSearchParams} params - the current URL params\n * @property {Object} data - the current payload to be sent with requests like POST and PUT\n *\n * @memberof Requests\n * @see createFetchRequest\n */\n\n/**\n * This class provides a dedicated client for restful operations against an API via JSON payloads and responses.\n *\n * Internally this implementation uses createJsonRequest to actually request stuff, while this class\n * is a wrapper, providing central configuration, such as a base URL and options like credentials,\n * as well as standard methods for HTTP verbs and setup things like setting headers.\n *\n * See class documentation below for details.\n *\n * @memberof Requests:RestfulJsonClient\n * @name RestfulJsonClient\n *\n * @see RestfulJsonClient\n * @see createJsonRequest\n * @see Requests.FetchRequest\n * @example\n * const client = new RestfulJsonClient('https://jsonplaceholder.typicode.com', {credentials : 'include'});\n * const postJson = await client\n * .path('/posts')\n * \t .params({\n * \t ids : [1, 2],\n * \t q : 'lorem'\n * \t })\n * \t .data({\n * \t title : 'foo',\n * \t body : 'bar',\n * \t userId : 1,\n * \t })\n * \t .post()\n * ;\n */\nclass RestfulJsonClient {\n\n\t#__className__ = 'RestfulJsonClient';\n\t#invalidRequestMethodMessage = 'invalid request method';\n\t#dataValidationMessage = 'data must be plain object';\n\t#baseUrl = null;\n\t#baseOptions = null;\n\t#useNative = false;\n\t#strict = true;\n\t#config = null;\n\n\t/**\n\t * Creates a new RestfulJsonClient\n\t *\n\t * @param {?String} [baseUrl=window.location.origin] - the base URL for all queries, based on which final request URLs will be built, adding the paths, may be absolute or relative to current origin\n\t * @param {?Object} [baseOptions=null] - the base request options, can be expanded later via options() (see createFetchRequests for details)\n\t * @param {?Boolean|String} [useNative=false] - determines if the native Fetch implementation of the browser should be used, true forces usage, \"auto\" uses it only if available\n\t * @param {?Boolean} [strict=true] - if true, enforces \"application/json\" as accept header as well as response mime type, if false, accept header is not set and different mime type only results in warning\n\t *\n\t * @see createJsonRequest\n * @see Requests.FetchRequest\n\t */\n\tconstructor(baseUrl=null, baseOptions=null, useNative=false, strict=true){\n\t\tthis.#baseUrl = orDefault(baseUrl, window.location.origin, 'str');\n\t\tthis.#baseOptions = isPlainObject(baseOptions) ? baseOptions : {};\n\t\tthis.#useNative = orDefault(useNative, false, 'bool');\n\t\tthis.#strict = orDefault(strict, true, 'bool');\n\n\t\tif( !this.#baseUrl.startsWith('//') && this.#baseUrl.startsWith('/') ){\n\t\t\tthis.#baseUrl = `${window.location.origin}${this.#baseUrl}`;\n\t\t}\n\n\t\tthis.#config = {\n\t\t\turl : new URL('', this.#baseUrl),\n\t\t\toptions : {},\n\t\t\tparams : new URLSearchParams(),\n\t\t\tdata : {},\n\t\t};\n\t}\n\n\n\n\t/**\n\t * Sets the current request path, which will be concatenated to baseUrl.\n\t *\n\t * @param {String} path - the current path to request from baseUrl\n\t * @returns {RestfulJsonClient}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/food')).path('/pizzas').get();\n\t */\n\tpath(path){\n\t\tpath = `${path}`.replaceAll(/^\\/+/g, '');\n\n\t\tthis.#config.url = new URL(path, this.#baseUrl);\n\n\t\treturn this;\n\t}\n\n\n\t/**\n\t * Sets the current request options, which will be merged with baseOptions.\n\t *\n\t * @param {?Object} options - plain options object to merge with baseOptions to define current request options (see createFetchRequest for details and defaults); if nullish, baseOptions will be used\n\t * @throws error if given options are not a plain object\n\t * @returns {RestfulJsonClient}\n\t *\n\t * @see createJsonRequest\n\t * @see Requests.FetchRequest\n\t * @example\n\t * (new RestfulJsonClient('/run-forrest-run')).options({timeout : 1});\n\t */\n\toptions(options){\n\t\tconst __methodName__ = 'options';\n\n\t\tif( hasValue(options) ){\n\t\t\tassert(isPlainObject(options), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | options must be plain object`);\n\t\t\tthis.#config.options = options;\n\t\t} else {\n\t\t\tthis.#config.options = {};\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\t/**\n\t * Sets a header for all subsequent requests.\n\t * Use a nullish value to unset a header.\n\t *\n\t * @param {String} key - the header to set for all following requests\n\t * @param {?String} value - the header's value; a nullish value will remove the header again\n\t * @returns {RestfulJsonClient}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/run-forrest-run')).header('X-Test', 42).header('X-Test', null);\n\t */\n\theader(key, value){\n\t\tkey = `${key}`;\n\n\t\tif( !isPlainObject(this.#config.options.headers) ){\n\t\t\tthis.#config.options.headers = {};\n\t\t}\n\n\t\tif( hasValue(value) ){\n\t\t\tthis.#config.options.headers[key] = `${value}`;\n\t\t} else {\n\t\t\tdelete this.#config.options.headers[key];\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Sets query parameters to be added to the request URL.\n\t *\n\t * @param {?*} params - query parameters to set on the current URL, this parameter takes all regular definitions for URLSearchParams constructor, as well as flat plain objects, which may also have arrays as values; if nullish, parameters are emptied\n\t * @returns {RestfulJsonClient}\n\t *\n\t * @see https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/URLSearchParams\n\t * @example\n\t * (new RestfulJsonClient('/food/search')).params({q : 'delicious pizza'}).get();\n\t */\n\tparams(params){\n\t\tif( hasValue(params) ){\n\t\t\tthis.#config.params = new URLSearchParams(isPlainObject(params) ? this.#toFlatEntries(params) : params);\n\t\t} else {\n\t\t\tthis.#config.params = new URLSearchParams();\n\t\t}\n\n\t\tthis.#config.url.search = this.#config.params.toString();\n\n\t\treturn this;\n\t}\n\n\n\n /**\n * Sets a query parameter to be added to the request URL.\n * Use a nullish value to unset a parameter.\n *\n * @param {String} key - the parameter name to set\n * @param {?String} value - the parameter's value; a nullish value will remove the param again\n * @param {?Boolean} [append=false] - if true, the parameter is appended instead of overwritten\n * @returns {RestfulJsonClient}\n *\n * @example\n * (new RestfulJsonClient('/food/search')).param('q', 'delicious pizza').get();\n */\n\tparam(key, value, append=false){\n key = `${key}`;\n\t\tappend = orDefault(append, false, 'bool');\n\n if( hasValue(value) ){\n\t\t\tif( append ){\n this.#config.params.append(key, `${value}`);\n\t\t\t} else {\n this.#config.params.set(key, `${value}`);\n\t\t\t}\n } else {\n delete this.#config.params.delete(key);\n }\n\n this.#config.url.search = this.#config.params.toString();\n\n return this;\n\t}\n\n\n\n\t/**\n\t * Sets data payload for POST, PUT and PATCH requests.\n\t *\n\t * @param {?Object} data - data payload to send with the next POST, PUT or PATCH request, this parameter will set a permanent payload; for one-off payloads, use the verb method's data parameter; if nullish, data will be emptied\n\t * @throws error if given data is not a plain object\n\t * @returns {RestfulJsonClient}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/food/order')).data({pizza : 'diavolo'}).post();\n\t */\n\tdata(data){\n\t\tconst __methodName__ = 'data';\n\n\t\tif( hasValue(data) ){\n\t\t\tassert(isPlainObject(data), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#dataValidationMessage}`);\n\t\t\tthis.#config.data = data;\n\t\t} else {\n\t\t\tthis.#config.data = {};\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Queries the current URL with GET.\n\t *\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns {Basic.Deferred}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/food/')).path('pizza').get();\n\t */\n\tget(){\n\t\treturn this.#executeRequest('GET');\n\t}\n\n\n\n\t/**\n\t * Queries the current URL with POST using defined payload/data.\n\t *\n\t * @param {?Object} [data=null] - one-off data to use in this request, will replace any central data defined before and will only be valid for this request\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns {Basic.Deferred}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/food/order')).post({pizza : 'diavolo'});\n\t */\n\tpost(data=null){\n\t\treturn this.#executeRequestWithPayload('POST', data);\n\t}\n\n\n\n\t/**\n\t * Queries the current URL with PUT using defined payload/data.\n\t *\n\t * @param {?Object} [data=null] - one-off data to use in this request, will replace any central data defined before and will only be valid for this request\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns {Basic.Deferred}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/food/deliver')).put({pizza : 'diavolo'});\n\t */\n\tput(data=null){\n\t\treturn this.#executeRequestWithPayload('PUT', data);\n\t}\n\n\n\n\t/**\n\t * Queries the current URL with PATCH using defined payload/data.\n\t *\n\t * @param {?Object} [data=null] - one-off data to use in this request, will replace any central data defined before and will only be valid for this request\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns {Basic.Deferred}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/software')).data({version : 2}).patch();\n\t */\n\tpatch(data=null){\n\t\treturn this.#executeRequestWithPayload('PATCH', data);\n\t}\n\n\n\n\t/**\n\t * Queries the current URL with DELETE.\n\t *\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns {Basic.Deferred}\n\t *\n\t * @example\n\t * (new RestfulJsonClient('/')).data({command : 'rm -rf'}).delete();\n\t */\n\tdelete(){\n\t\treturn this.#executeRequest('DELETE');\n\t}\n\n\n\n\t/**\n\t * Returns the current config.\n\t *\n\t * baseUrl is retrievable from the url property (via origin).\n\t * Options are the merged result of baseOptions and currently set option values.\n\t *\n\t * Changes to this object, will not reflect in the client config directly, use the client's methods to\n\t * alter config values.\n\t *\n\t * @returns {RestfulJsonClientConfig} a clone of the current config\n\t *\n\t * @example\n\t * client.getConfig().url.toString()\n\t * => https://pizza.com\n\t */\n\tgetConfig(){\n\t\treturn merge(this.#config, {options : merge(this.#baseOptions, this.#config.options)});\n\t}\n\n\n\n\t/**\n\t * Creates and executes an HTTP request without a payload, such as GET and DELETE.\n\t * Uses current config from class to construct request.\n\t *\n\t * @param {String} method - either GET or DELETE\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns Basic.Deferred\n\t *\n\t * @example\n\t * this.#executeRequest('GET');\n\t */\n\t#executeRequest(method){\n\t\tconst __methodName__ = '#executeRequest';\n\n\t\tmethod = method.toUpperCase();\n\t\tassert(\n\t\t\t['GET', 'DELETE'].includes(method),\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#invalidRequestMethodMessage} \"${method}\"`\n\t\t);\n\n\t\tconst options = merge(this.#baseOptions, this.#config.options, {method});\n\t\treturn createJsonRequest(this.#config.url, options, this.#useNative, this.#strict).execute();\n\t}\n\n\n\n\t/**\n\t * Creates and executes an HTTP request with a payload, such as POST and PUT.\n\t * Uses current config from class to construct request.\n\t *\n\t * @param {String} method - either POST, PUT or PATCH\n\t * @param {?Object} [data=null] - the data to send to the request URL as payload\n\t * @throws error in strict mode if response content type is not \"application/json\"\n\t * @returns Basic.Deferred\n\t *\n\t * @example\n\t * this.#executeRequestWithPayload('POST', {foo : 'bar'});\n\t */\n\t#executeRequestWithPayload(method, data=null){\n\t\tconst __methodName__ = '#executeRequestWithPayload';\n\n\t\tmethod = method.toUpperCase();\n\t\tassert(\n\t\t\t['POST', 'PUT', 'PATCH'].includes(method),\n\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#invalidRequestMethodMessage} \"${method}\"`\n\t\t);\n\t\tif( hasValue(data) ){\n\t\t\tassert(isPlainObject(data), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#dataValidationMessage}`);\n\t\t}\n\n\t\tconst contentTypeHeader = 'Content-Type';\n\t\tthis.header(contentTypeHeader, 'application/json; charset=UTF-8');\n\t\tconst\n\t\t\tbody = JSON.stringify(data ?? this.#config.data),\n\t\t\toptions = merge(this.#baseOptions, this.#config.options, {method, body})\n\t\t;\n\t\treturn createJsonRequest(this.#config.url, options, this.#useNative, this.#strict)\n\t\t\t.execute()\n\t\t\t.finally(() => {\n\t\t\t\tthis.header(contentTypeHeader, null);\n\t\t\t})\n\t\t;\n\t}\n\n\n\n\t/**\n\t * Transforms a dictionary to an entries array, but handles list values, such as arrays and sets, specially, by\n\t * iterating them and creating a new entry for each list value, thereby producing a notation, which is compatible\n\t * to URLSearchParams, based on an object with a readable notation.\n\t *\n\t * @param {Object} obj - the object to transform into a flattened array of entries\n\t * @returns {Array>} flat array of entries\n\t *\n\t * @private\n\t * @see https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams\n\t */\n\t#toFlatEntries(obj){\n\t\tconst\n\t\t\tentries = Object.entries(obj),\n\t\t\tflattenedEntries = []\n\t\t;\n\n\t\tfor(const entryIndex in entries ){\n\t\t\tconst\n\t\t\t\tentryKey = entries[entryIndex][0],\n\t\t\t\tentryVal = entries[entryIndex][1],\n\t\t\t\tentryValType = getType(entryVal)\n\t\t\t;\n\n\t\t\tif( ['array', 'set'].includes(entryValType) ){\n\t\t\t\tArray.from(entryVal).forEach(val => {\n\t\t\t\t\tflattenedEntries.push([entryKey, `${val}`]);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tflattenedEntries.push([entryKey, `${entryVal}`]);\n\t\t\t}\n\t\t}\n\n\t\treturn flattenedEntries;\n\t}\n\n}\n\nexport {RestfulJsonClient};\n\n\n\n/**\n * @namespace Requests:createJsRequest\n */\n\n/**\n * @typedef JsFetchResponse\n * @type {HTMLElement|String}\n *\n * @memberof Requests\n */\n\n/**\n * @typedef JsFetchRequestExecuteFunction\n * @type {Function}\n *\n * @param {?String} [resolveTo='element'] - defines what the response should resolve to, may either be \"element\", \"raw\" or \"sourced-element\" (which is the special case to insert a script with a src instead of doing a real request)\n * @param {?HTMLElement|Object} [insertTarget=null] - defines if the retrieved value should be inserted as a dom element and if so where; if this is an element, the value gets appended into that as a script tag, otherwise the properties below apply\n * @param {?HTMLElement} [insertTarget.element] - target element in relation to which the resolved value should be inserted into the dom\n * @param {?String} [insertTarget.position] - defines where, in relation to the target element, the resolved value will be inserted, see insertNode for more details\n * @param {?String} [dataId=null] - if you need an identifier, to find inserted elements again after they are inserted into dom, you can define an id here, which will be set as the \"data-id\" attribute on the created node\n * @param {?Boolean} [resolveSourcedOnInsert=false] - normally sourced elements resolve on load to work with the request as far as possible, but if you want to ignore the request after insertion, you may set this parameter to \"true\", resulting in immediate resolution after insertion\n * @returns {Basic.Deferred}\n *\n * @memberof Requests\n * @see insertNode\n */\n\n/**\n * @typedef JsFetchRequest\n * @type {Object}\n *\n * @property {String} url - the request URL\n * @property {Object} options - the options with which the request has been created\n * @property {String} options.method - the request method\n * @property {?Object} options.headers - the set headers for the request\n * @property {?String} options.credentials - the credentials setting for the request\n * @property {?String} options.body - the provided request body of the request\n * @property {?Number} [options.timeout=10000] - milliseconds until the request fails due to a timeout\n * @property {Requests.JsFetchRequestExecuteFunction} execute - call this to execute the request\n *\n * @memberof Requests\n */\n\n/**\n * This method creates a special version of a FetchRequest specifically designed to retrieve JavaScript.\n *\n * Usually you'll want to retrieve JavaScript to include it into a page to execute the script on the page\n * currently open, so the default mode of this method is to resolve to a directly usable script tag, you may\n * insert into the DOM wherever you please. However, you may also specify to retrieve the raw JavaScript source.\n *\n * Be aware that requesting JavaScript from an unsecure source is a very big security risk. Do not load and execute\n * source from a source you do not fully trust!\n *\n * If you plan on inserting the result into DOM anyway you'll like the fact that this is also directly possible, by\n * defining an insert target. In case you decide to insert the result directly, the default is an inline script, but\n * you may also choose to insert a sourced script tag, loading a script on insertion and executing in asynchronously\n * in turn. This is not strictly a programmatic \"request\" anymore, but very handy. If you are inserting a sourced\n * script, the Deferred resolves on load by default (and rejects on error), thereby keeping the general idea of\n * working with a request. But you may also define a parameter on execute to force resolve immediately on insert.\n *\n * BTW: Inserting does not automatically change the resolve value, those are separate concerns.\n *\n * @param {String} url - the complete URL to query\n * @param {?Object} [options=null] - the request options (see: createFetchRequests for details)\n * @param {?Boolean|String} [useNative=false] - determines if the native Fetch implementation of the browser should be used, true forces usage, \"auto\" uses it only if available\n * @param {?Boolean} [strict=true] - if true, enforces \"application/javascript\" as accept header as well as response mime type, if false, accept header is not set and different mime type only results in warning\n * @throws error in strict mode if response content type is not \"application/javascript\"\n * @returns {Requests.JsFetchRequest} use this via the \"execute\" method, which resolves to a FetchResponse or rejects with error in case of a technical request error (request is not completable)\n *\n * @memberof Requests:createJsRequest\n * @alias createJsRequest\n * @see createFetchRequest\n * @example\n * createJsRequest('/js/test.js')\n * .execute()\n * .then(jsElement => { document.body.appendChild(jsElement); })\n * ;\n * createJsRequest('/js/test.js')\n * .execute(null, injectTarget, 'request-2')\n * .then(jsElement => { alert(`has been injected: \"${jsElement.textContent}\"`); })\n * ;\n * createJsRequest('/js/test.js')\n * .execute('raw', {element : injectTarget, position : 'beforebegin'})\n * .then(rawJs => { alert(`has been injected: \"${rawJs}\"`); })\n * ;\n * createJsRequest('/js/test.js')\n * .execute('sourced-element', {element : injectTarget, position : 'prepend'}, 'request-4')\n * .then(jsElement => { alert(`has been injected: \"${jsElement.getAttribute('data-id')}\"`); })\n * ;\n */\nexport function createJsRequest(url, options=null, useNative=false, strict=true){\n\tconst\n\t\t__methodName__ = 'createJsRequest',\n\t\tcontentType = 'application/javascript'\n\t;\n\n\tif( strict ){\n\t\tif( !hasValue(options) ){\n\t\t\toptions = {};\n\t\t}\n\n\t\tif( !hasValue(options.headers) ){\n\t\t\toptions.headers = {};\n\t\t}\n\n\t\toptions.headers['Accept'] = contentType;\n\t}\n\n\treturn {\n\t\turl,\n\t\toptions,\n\t\texecute(resolveTo='element', insertTarget=null, dataId=null, resolveSourcedOnInsert=false){\n\t\t\tconst\n\t\t\t\tsourceElementValue = 'sourced-element',\n\t\t\t\tres = new Deferred(),\n\t\t\t\tfInsertAndResolve = (element, js='') => {\n\t\t\t\t\tif( dataId !== null ){\n\t\t\t\t\t\telement.setAttribute('data-id', `${dataId}`);\n\t\t\t\t\t}\n\n\t\t\t\t\tif( hasValue(insertTarget) ){\n\t\t\t\t\t\tconst\n\t\t\t\t\t\t\ttarget = insertTarget.element ?? insertTarget,\n\t\t\t\t\t\t\tposition = insertTarget.position ?? null\n\t\t\t\t\t\t;\n\n\t\t\t\t\t\tif( !resolveSourcedOnInsert ){\n\t\t\t\t\t\t\telement.onload = () => { res.resolve((resolveTo === 'raw') ? js : element); };\n\t\t\t\t\t\t\telement.onerror = error => { res.reject(error); };\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( position === null ){\n\t\t\t\t\t\t\tinsertNode(target, element);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tinsertNode(target, element, position);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(\n\t\t\t\t\t\t(resolveTo !== sourceElementValue)\n\t\t\t\t\t\t|| ((resolveTo === sourceElementValue) && resolveSourcedOnInsert)\n\t\t\t\t\t){\n\t\t\t\t\t\tres.resolve((resolveTo === 'raw') ? js : element);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t;\n\n\t\t\tif( resolveTo === sourceElementValue ){\n\t\t\t\tfInsertAndResolve(createNode('script', {src : url}));\n\t\t\t} else {\n\t\t\t\tcreateFetchRequest(url, options, useNative).execute()\n\t\t\t\t\t.then(response => {\n\t\t\t\t\t\tconst responseContentType = (\n\t\t\t\t\t\t\tresponse.headers.get('content-type') ?? response.headers.get('Content-Type') ?? ''\n\t\t\t\t\t\t).split(';')[0].trim();\n\n\t\t\t\t\t\tif( responseContentType !== contentType ){\n\t\t\t\t\t\t\tconst message = `${MODULE_NAME}:${__methodName__} | content-type \"${responseContentType}\" is not valid for JavaScript, expecting \"application/javascript\"`;\n\t\t\t\t\t\t\tif( strict ){\n\t\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\twarn(message);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn response.text();\n\t\t\t\t\t})\n\t\t\t\t\t.then(js => {\n\t\t\t\t\t\tfInsertAndResolve(createNode('script', null, js), js);\n\t\t\t\t\t})\n\t\t\t\t\t.catch(error => {\n\t\t\t\t\t\tres.reject(error);\n\t\t\t\t\t})\n\t\t\t\t;\n\t\t\t}\n\n\t\t\treturn res;\n\t\t}\n\t};\n}\n\n\n\n/**\n * @namespace Requests:createCssRequest\n */\n\n/**\n * @typedef CssFetchResponse\n * @type {HTMLElement|String}\n *\n * @memberof Requests\n */\n\n/**\n * @typedef CssFetchRequestExecuteFunction\n * @type {Function}\n *\n * @param {?String} [resolveTo='element'] - defines what the response should resolve to, may either be \"element\", \"raw\" or \"sourced-element\" (which is the special case to insert a link with a href instead of doing a real request)\n * @param {?HTMLElement|Object} [insertTarget=null] - defines if the retrieved value should be inserted as a dom element and if so where; if this is an element, the value gets appended into that as a style/link tag, otherwise the properties below apply\n * @param {?HTMLElement} [insertTarget.element] - target element in relation to which the resolved value should be inserted into the dom\n * @param {?String} [insertTarget.position] - defines where, in relation to the target element, the resolved value will be inserted, see insertNode for more details\n * @param {?String} [dataId=null] - if you need an identifier, to find inserted elements again after they are inserted into dom, you can define an id here, which will be set as the \"data-id\" attribute on the created node\n * @param {?String} [media='all'] - define the style's media attribute here to target the output device(s), could be \"screen\" or \"print\" for example\n * @param {?Boolean} [resolveSourcedOnInsert=false] - normally sourced elements resolve on load to work with the request as far as possible, but if you want to ignore the request after insertion, you may set this parameter to \"true\", resulting in immediate resolution after insertion\n * @returns {Basic.Deferred}\n *\n * @memberof Requests\n * @see insertNode\n */\n\n/**\n * @typedef CssFetchRequest\n * @type {Object}\n *\n * @property {String} url - the request URL\n * @property {Object} options - the options with which the request has been created\n * @property {String} options.method - the request method\n * @property {?Object} options.headers - the set headers for the request\n * @property {?String} options.credentials - the credentials setting for the request\n * @property {?String} options.body - the provided request body of the request\n * @property {?Number} [options.timeout=10000] - milliseconds until the request fails due to a timeout\n * @property {Requests.CssFetchRequestExecuteFunction} execute - call this to execute the request\n *\n * @memberof Requests\n */\n\n/**\n * This method creates a special version of a FetchRequest specifically designed to retrieve Cascading Stylesheets.\n *\n * Usually you'll want to retrieve CSS to include it into a page and thereby style something on the page\n * currently open, so the default mode of this method is to resolve to a directly usable style tag, you may\n * insert into the DOM wherever you please. However, you may also specify to retrieve the raw CSS source.\n *\n * If you plan on inserting the result into DOM anyway you'll like the fact that this is also directly possible, by\n * defining an insert target. In case you decide to insert the result directly, the default is an inline style, but\n * you may also choose to insert a sourced link tag, loading a stylesheet on insertion and adding the included styles\n * on load. This is not strictly a programmatic \"request\" anymore, but very handy. If you are inserting a sourced\n * link, the Deferred resolves on load by default (and rejects on error), thereby keeping the general idea of\n * working with a request. But you may also define a parameter on execute to force resolve immediately on insert.\n *\n * BTW: Inserting does not automatically change the resolve value, those are separate concerns.\n *\n * @param {String} url - the complete URL to query\n * @param {?Object} [options=null] - the request options (see: createFetchRequests for details)\n * @param {?Boolean|String} [useNative=false] - determines if the native Fetch implementation of the browser should be used, true forces usage, \"auto\" uses it only if available\n * @param {?Boolean} [strict=true] - if true, enforces \"text/css\" as accept header as well as response mime type, if false, accept header is not set and different mime type only results in warning\n * @throws error in strict mode if response content type is not \"text/css\"\n * @returns {Requests.CssFetchRequest} use this via the \"execute\" method, which resolves to a FetchResponse or rejects with error in case of a technical request error (request is not completable)\n *\n * @memberof Requests:createCssRequest\n * @alias createCssRequest\n * @see createFetchRequest\n * @example\n * createCssRequest('/css/test.css')\n * .execute()\n * .then(cssElement => { document.head.appendChild(cssElement); })\n * ;\n * createCssRequest('/css/test.css')\n * .execute(null, injectTarget, 'request-2')\n * .then(cssElement => { alert(`has been injected: \"${cssElement.textContent}\"`); })\n * ;\n * createCssRequest('/css/test.css')\n * .execute('raw', {element : injectTarget, position : 'beforebegin'}, 'request-3', 'screen')\n * .then(rawCss => { alert(`has been injected: \"${rawCss}\"`); })\n * ;\n * createCssRequest('/css/test.css')\n * .execute('sourced-element', {element : injectTarget, position : 'prepend'}, 'request-4', 'screen')\n * .then(cssElement => { alert(`has been injected: \"${cssElement.getAttribute('data-id')+}\"`); })\n * ;\n */\nexport function createCssRequest(url, options=null, useNative=false, strict=true){\n\tconst\n\t\t__methodName__ = 'createCssRequest',\n\t\tcontentType = 'text/css'\n\t;\n\n\n\tif( strict ){\n\t\tif( !hasValue(options) ){\n\t\t\toptions = {};\n\t\t}\n\n\t\tif( !hasValue(options.headers) ){\n\t\t\toptions.headers = {};\n\t\t}\n\n\t\toptions.headers['Accept'] = contentType;\n\t}\n\n\treturn {\n\t\turl,\n\t\toptions,\n\t\texecute(resolveTo='element', insertTarget=null, dataId=null, media='all', resolveSourcedOnInsert=false){\n\t\t\tconst\n\t\t\t\tsourceElementValue = 'sourced-element',\n\t\t\t\tres = new Deferred(),\n\t\t\t\tfInsertAndResolve = (element, css='') => {\n\t\t\t\t\tif( dataId !== null ){\n\t\t\t\t\t\telement.setAttribute('data-id', `${dataId}`);\n\t\t\t\t\t}\n\n\t\t\t\t\tif( hasValue(insertTarget) ){\n\t\t\t\t\t\tconst\n\t\t\t\t\t\t\ttarget = insertTarget.element ?? insertTarget,\n\t\t\t\t\t\t\tposition = insertTarget.position ?? null\n\t\t\t\t\t\t;\n\n\t\t\t\t\t\tif( !resolveSourcedOnInsert ){\n\t\t\t\t\t\t\telement.onload = () => { res.resolve((resolveTo === 'raw') ? css : element); };\n\t\t\t\t\t\t\telement.onerror = error => { res.reject(error); };\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( position === null ){\n\t\t\t\t\t\t\tinsertNode(target, element);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tinsertNode(target, element, position);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(\n\t\t\t\t\t\t(resolveTo !== sourceElementValue)\n\t\t\t\t\t\t|| ((resolveTo === sourceElementValue) && resolveSourcedOnInsert)\n\t\t\t\t\t){\n\t\t\t\t\t\tres.resolve((resolveTo === 'raw') ? css : element);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t;\n\n\t\t\tif( resolveTo === sourceElementValue ){\n\t\t\t\tconst linkAttrs = {href : url, rel : 'stylesheet'};\n\t\t\t\tif( media !== 'all' ){\n\t\t\t\t\tlinkAttrs.media = media;\n\t\t\t\t}\n\t\t\t\tfInsertAndResolve(createNode('link', linkAttrs));\n\t\t\t} else {\n\t\t\t\tcreateFetchRequest(url, options, useNative).execute()\n\t\t\t\t\t.then(response => {\n\t\t\t\t\t\tconst responseContentType = (\n\t\t\t\t\t\t\tresponse.headers.get('content-type') ?? response.headers.get('Content-Type') ?? ''\n\t\t\t\t\t\t).split(';')[0].trim();\n\n\t\t\t\t\t\tif( responseContentType !== contentType ){\n\t\t\t\t\t\t\tconst message = `${MODULE_NAME}:${__methodName__} | content-type \"${responseContentType}\" is not valid for CSS, expecting \"text/css\"`;\n\t\t\t\t\t\t\tif( strict ){\n\t\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\twarn(message);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn response.text();\n\t\t\t\t\t})\n\t\t\t\t\t.then(css => {\n\t\t\t\t\t\tfInsertAndResolve(createNode('style', (media !== 'all') ? {media} : null, css), css);\n\t\t\t\t\t})\n\t\t\t\t\t.catch(error => {\n\t\t\t\t\t\tres.reject(error);\n\t\t\t\t\t})\n\t\t\t\t;\n\t\t\t}\n\n\t\t\treturn res;\n\t\t}\n\t};\n}\n\n\n\n/**\n * @namespace Requests:createHtmlRequest\n */\n\n/**\n * @typedef HtmlFetchResponse\n * @type {HTMLElement|Array|String}\n *\n * @memberof Requests\n */\n\n/**\n * @typedef HtmlFetchRequestExecuteFunction\n * @type {Function}\n *\n * @param {?String} [resolveTo='element'] - defines what the response should resolve to, may either be \"element\" or \"raw\"\n * @param {?HTMLElement|Object} [insertTarget=null] - defines if the retrieved value should be inserted as a dom element and if so where; if this is an element, the value gets appended into that as (a) node(s), otherwise the properties below apply\n * @param {?HTMLElement} [insertTarget.element] - target element in relation to which the resolved value should be inserted into the dom\n * @param {?String} [insertTarget.position] - defines where, in relation to the target element, the resolved value will be inserted, see insertNode for more details\n * @param {?String} [dataId=null] - if you need an identifier, to find inserted elements again after they are inserted into dom, you can define an id here, which will be set as the \"data-id\" attribute on the created node(s)\n * @param {?String} [selector=null] - if you'd like to preselect something from the result, you may define a regular query selector to find matching elements in the result\n * @param {?Boolean} [selectAll=false] - usually, if a selector is defined, we select a single element, if you need to select a list, set this to true\n * @returns {Basic.Deferred}\n *\n * @memberof Requests\n * @see insertNode\n */\n\n/**\n * @typedef HtmlFetchRequest\n * @type {Object}\n *\n * @property {String} url - the request URL\n * @property {Object} options - the options with which the request has been created\n * @property {String} options.method - the request method\n * @property {?Object} options.headers - the set headers for the request\n * @property {?String} options.credentials - the credentials setting for the request\n * @property {?String} options.body - the provided request body of the request\n * @property {?Number} [options.timeout=10000] - milliseconds until the request fails due to a timeout\n * @property {Requests.HtmlFetchRequestExecuteFunction} execute - call this to execute the request\n *\n * @memberof Requests\n */\n\n/**\n * This method creates a special version of a FetchRequest specifically designed to retrieve HTML content.\n *\n * Usually you'll want to retrieve HTML to include it into a page or extract information from it, so the default mode\n * of this method is to resolve to a node, you may insert into the DOM wherever you please or use stuff like a\n * querySelector on. However, you may also specify to retrieve the raw HTML source.\n *\n * Be aware, that requesting and parsing HTML from an unsecure source comes with a high risk. If you cannot fully\n * trust the source, request the HTML raw and use something like dom purify before using the result.\n *\n * If you plan on inserting the result into DOM anyway you'll like the fact that this is also directly possible, by\n * defining an insert target.\n *\n * BTW: Inserting does not automatically change the resolve value, those are separate concerns.\n *\n * @param {String} url - the complete URL to query\n * @param {?Object} [options=null] - the request options (see: createFetchRequests for details)\n * @param {?Boolean|String} [useNative=false] - determines if the native Fetch implementation of the browser should be used, true forces usage, \"auto\" uses it only if available\n * @param {?Boolean} [strict=true] - if true, enforces \"text/html\" as accept header as well as response mime type, if false, accept header is not set and different mime type only results in warning\n * @throws error in strict mode if response content type is not \"text/html\"\n * @returns {Requests.HtmlFetchRequest} use this via the \"execute\" method, which resolves to a FetchResponse or rejects with error in case of a technical request error (request is not completable)\n *\n * @memberof Requests:createHtmlRequest\n * @alias createHtmlRequest\n * @see createFetchRequest\n * @example\n * createHtmlRequest('/html/test.html')\n * .execute()\n * .then(htmlElement => { document.body.appendChild(htmlElement); })\n * ;\n * createHtmlRequest('/html/test.html')\n * .execute('raw', null, 'request-1')\n * .then(rawHtml => { alert(`document has been loaded: \"${rawHtml}\"`); })\n * ;\n * createHtmlRequest('/html/test.html')\n * .execute(null, injectTarget, 'request-3', 'body > main > h1')\n * .then(htmlElement => { alert(`has been injected: \"${htmlElement.outerHTML}\"`); })\n * ;\n * createHtmlRequest('/files/html/requests-test-1.html')\n * .execute('raw', {element : injectTarget, position : 'beforebegin'}, 'request-4', 'h1 ~ p', true)\n * .then(rawHtml => { alert(`has been injected: \"${rawHtml}\"`); })\n * ;\n * createHtmlRequest('/files/html/requests-test-2.html')\n * .execute('element', {element : injectTarget, position : 'prepend'}, 'request-5', 'p', true)\n * .then(htmlElements => { alert(`has been injected: \"${htmlElements.map(e => e.outerHTML).join('')}\"`); })\n * ;\n */\nexport function createHtmlRequest(url, options=null, useNative=false, strict=true){\n\tconst\n\t\t__methodName__ = 'createHtmlRequest',\n\t\tcontentType = 'text/html'\n\t;\n\n\tif( strict ){\n\t\tif( !hasValue(options) ){\n\t\t\toptions = {};\n\t\t}\n\n\t\tif( !hasValue(options.headers) ){\n\t\t\toptions.headers = {};\n\t\t}\n\n\t\toptions.headers['Accept'] = contentType;\n\t}\n\n\treturn {\n\t\turl,\n\t\toptions,\n\t\texecute(resolveTo='element', insertTarget=null, dataId=null, selector=null, selectAll=false){\n\t\t\tconst\n\t\t\t\tres = new Deferred(),\n\t\t\t\tfInsertAndResolve = (element, html='') => {\n\t\t\t\t\tif( hasValue(element) ){\n\t\t\t\t\t\tconst elements = [].concat(element);\n\n\t\t\t\t\t\tif( dataId !== null ){\n\t\t\t\t\t\t\telements.forEach(element => {\n\t\t\t\t\t\t\t\telement.setAttribute('data-id', `${dataId}`);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( hasValue(insertTarget) ){\n\t\t\t\t\t\t\tconst\n\t\t\t\t\t\t\t\ttarget = insertTarget.element ?? insertTarget,\n\t\t\t\t\t\t\t\tposition = insertTarget.position ?? null\n\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\tif( ['before', 'beforebegin', 'prepend', 'afterbegin'].includes(position) ){\n\t\t\t\t\t\t\t\telements.reverse();\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\telements.forEach(element => {\n\t\t\t\t\t\t\t\tif( position === null ){\n\t\t\t\t\t\t\t\t\tinsertNode(target, element);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tinsertNode(target, element, position);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tres.resolve((resolveTo === 'raw') ? html : element);\n\t\t\t\t}\n\t\t\t;\n\n\t\t\tcreateFetchRequest(url, options, useNative).execute()\n\t\t\t\t.then(response => {\n\t\t\t\t\tconst responseContentType = (\n\t\t\t\t\t\tresponse.headers.get('content-type') ?? response.headers.get('Content-Type') ?? ''\n\t\t\t\t\t).split(';')[0].trim();\n\t\t\t\t\tif( responseContentType !== contentType ){\n\t\t\t\t\t\tconst message = `${MODULE_NAME}:${__methodName__} | content-type \"${responseContentType}\" is not valid for HTML, expecting \"text/html\"`;\n\t\t\t\t\t\tif( strict ){\n\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\twarn(message);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn response.text();\n\t\t\t\t})\n\t\t\t\t.then(html => {\n\t\t\t\t\tconst\n\t\t\t\t\t\tisWholeDocument = html.includes(' {\n\t\t\t\t\t\t\t\thtml += element.outerHTML;\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tfInsertAndResolve(element, html);\n\t\t\t\t})\n\t\t\t\t.catch(error => {\n\t\t\t\t\tres.reject(error);\n\t\t\t\t})\n\t\t\t;\n\n\t\t\treturn res;\n\t\t}\n\t};\n}\n\n\n\n/**\n * @namespace Requests:visitUrl\n */\n\n/**\n * This function opens a given URL, using a dynamically created iframe, thereby opening the URL as if the user\n * him- or herself navigates to the URL using a browser window. Why should we do this you ask?\n *\n * For example: In session management, you'll sometimes have the case, that you need to trigger URLs on login or logout,\n * that construct or destruct parts of the session by creating of removing cookie or other client-storage items.\n * If that domain is part of a system running on another (sub)domain, using a usual client request for this will\n * not work, since the calling context of the request will have no access to the storage scope of that domain.\n *\n * So, to allow those domains to do their tasks, triggered from a different context, we can use this method to execute\n * those webhooks with the iframe, which natively runs in the called domains scope and therefore can do all necessary\n * domain-based storage actions.\n *\n * The big downside of this is, that we cannot really handle errors well this way. So if the URL returns a 404\n * or a 500, this will actually be treated as a resolved promise, since the iframe loaded. The only case a request\n * of this kind fails, is if the request runs into a timeout. So, for really critical actions, this way of handling\n * thing should be avoided in favour of an approach, that actually includes a postMessage implementation on the other\n * domain, to verify completion on load.\n *\n * @param {String} url - the URL to query, will be the current one if left empty\n * @param {?Number} [timeout=5000] - the timeout in ms to wait for completion of the request, before rejecting the promise\n * @param {?String} [tokenValue=null] - if the URL needs to include a token, you can provide this token here, which will replace the placeholder defined in \"tokenPlaceholder\"\n * @param {?String} [tokenPlaceholder='token'] = the placeholder in the url to replace with the tokenValue, must be surrounded with curly braces in the url (\"{token}\")\n * @returns {Basic.Deferred} resolves on load of URL (with the final URL as resolution value), rejects on timeout (with a \"timeout\" error)\n *\n * @memberof Requests:visitUrl\n * @alias visitUrl\n * @example\n * visitUrl('https://some.other.domain?token={token}', 2500, 'A38')\n * .then(() => { console.log('loaded!'); })\n * ;\n * visitUrl(\n * 'https://some.other.domain?token={session_value}',\n * 5000,\n * 'A38',\n * 'session_value'\n * )\n * .then(url => { console.log(`\"${url}\" loaded!`); })\n * .catch(error => { console.log(`${error.message} - URL did not load super fast, blimey!`); })\n * ;\n */\nexport function visitUrl(url, timeout=5000, tokenValue=null, tokenPlaceholder='token'){\n\turl = orDefault(url, '', 'str');\n\ttimeout = Math.abs(orDefault(timeout, 5000, 'int'));\n\ttokenValue = orDefault(tokenValue, null, 'str');\n\ttokenPlaceholder = orDefault(tokenPlaceholder, 'token', 'str');\n\turl = hasValue(tokenValue) ? url.replaceAll(`{${tokenPlaceholder}}`, tokenValue) : url;\n\n\tconst\n\t\tdeferred = new Deferred(),\n\t\touterNode = document.createElement('div')\n\t;\n\n\touterNode.innerHTML = `\n\t\t\n\t`.trim();\n\n\tconst\n\t\tiframe = outerNode.firstChild,\n\t\tfOnLoad = () => {\n\t\t\tiframe.removeEventListener('load', fOnLoad);\n\t\t\twindow.clearTimeout(loadTimeout);\n\t\t\t// we need to wait a bit after load before removing the iframe,\n\t\t\t// otherwise safari considers the request cancelled :(\n\t\t\twindow.setTimeout(() => {\n\t\t\t\tdocument.body.removeChild(iframe);\n\t\t\t\tdeferred.resolve(url);\n\t\t\t}, 250);\n\t\t},\n\t\tloadTimeout = window.setTimeout(() => {\n\t\t\tiframe.removeEventListener('load', fOnLoad);\n\t\t\tdocument.body.removeChild(iframe);\n\t\t\tdeferred.reject(new Error('timeout'));\n\t\t}, timeout)\n\t;\n\n\tiframe.addEventListener('load', fOnLoad);\n\tdocument.body.appendChild(iframe);\n\n\treturn deferred;\n}\n"]} \ No newline at end of file diff --git a/dist/strings.js b/dist/strings.js index 9fe38574..10719a23 100644 --- a/dist/strings.js +++ b/dist/strings.js @@ -1,8 +1,8 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Strings */ -const MODULE_NAME="Strings";import{isFunction,isArray,orDefault,isNaN,hasValue,isPlainObject,round}from"./basic.js";const SLUGIFY_LATINMAP={"Á":"A","Ă":"A","Ắ":"A","Ặ":"A","Ằ":"A","Ẳ":"A","Ẵ":"A","Ǎ":"A","Â":"A","Ấ":"A","Ậ":"A","Ầ":"A","Ẩ":"A","Ẫ":"A","Ä":"Ae","Ǟ":"A","Ȧ":"A","Ǡ":"A","Ạ":"A","Ȁ":"A","À":"A","Ả":"A","Ȃ":"A","Ā":"A","Ą":"A","Å":"A","Ǻ":"A","Ḁ":"A","Ⱥ":"A","Ã":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ḃ":"B","Ḅ":"B","Ɓ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ć":"C","Č":"C","Ç":"C","Ḉ":"C","Ĉ":"C","Ċ":"C","Ƈ":"C","Ȼ":"C","Ď":"D","Ḑ":"D","Ḓ":"D","Ḋ":"D","Ḍ":"D","Ɗ":"D","Ḏ":"D","Dz":"D","Dž":"D","Đ":"D","Ƌ":"D","DZ":"DZ","DŽ":"DZ","É":"E","Ĕ":"E","Ě":"E","Ȩ":"E","Ḝ":"E","Ê":"E","Ế":"E","Ệ":"E","Ề":"E","Ể":"E","Ễ":"E","Ḙ":"E","Ë":"E","Ė":"E","Ẹ":"E","Ȅ":"E","È":"E","Ẻ":"E","Ȇ":"E","Ē":"E","Ḗ":"E","Ḕ":"E","Ę":"E","Ɇ":"E","Ẽ":"E","Ḛ":"E","Ꝫ":"ET","Ḟ":"F","Ƒ":"F","Ǵ":"G","Ğ":"G","Ǧ":"G","Ģ":"G","Ĝ":"G","Ġ":"G","Ɠ":"G","Ḡ":"G","Ǥ":"G","Ḫ":"H","Ȟ":"H","Ḩ":"H","Ĥ":"H","Ⱨ":"H","Ḧ":"H","Ḣ":"H","Ḥ":"H","Ħ":"H","Í":"I","Ĭ":"I","Ǐ":"I","Î":"I","Ï":"I","Ḯ":"I","İ":"I","Ị":"I","Ȉ":"I","Ì":"I","Ỉ":"I","Ȋ":"I","Ī":"I","Į":"I","Ɨ":"I","Ĩ":"I","Ḭ":"I","Ꝺ":"D","Ꝼ":"F","Ᵹ":"G","Ꞃ":"R","Ꞅ":"S","Ꞇ":"T","Ꝭ":"IS","Ĵ":"J","Ɉ":"J","Ḱ":"K","Ǩ":"K","Ķ":"K","Ⱪ":"K","Ꝃ":"K","Ḳ":"K","Ƙ":"K","Ḵ":"K","Ꝁ":"K","Ꝅ":"K","Ĺ":"L","Ƚ":"L","Ľ":"L","Ļ":"L","Ḽ":"L","Ḷ":"L","Ḹ":"L","Ⱡ":"L","Ꝉ":"L","Ḻ":"L","Ŀ":"L","Ɫ":"L","Lj":"L","Ł":"L","LJ":"LJ","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ń":"N","Ň":"N","Ņ":"N","Ṋ":"N","Ṅ":"N","Ṇ":"N","Ǹ":"N","Ɲ":"N","Ṉ":"N","Ƞ":"N","Nj":"N","Ñ":"N","NJ":"NJ","Ó":"O","Ŏ":"O","Ǒ":"O","Ô":"O","Ố":"O","Ộ":"O","Ồ":"O","Ổ":"O","Ỗ":"O","Ö":"Oe","Ȫ":"O","Ȯ":"O","Ȱ":"O","Ọ":"O","Ő":"O","Ȍ":"O","Ò":"O","Ỏ":"O","Ơ":"O","Ớ":"O","Ợ":"O","Ờ":"O","Ở":"O","Ỡ":"O","Ȏ":"O","Ꝋ":"O","Ꝍ":"O","Ō":"O","Ṓ":"O","Ṑ":"O","Ɵ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Õ":"O","Ṍ":"O","Ṏ":"O","Ȭ":"O","Ƣ":"OI","Ꝏ":"OO","Ɛ":"E","Ɔ":"O","Ȣ":"OU","Ṕ":"P","Ṗ":"P","Ꝓ":"P","Ƥ":"P","Ꝕ":"P","Ᵽ":"P","Ꝑ":"P","Ꝙ":"Q","Ꝗ":"Q","Ŕ":"R","Ř":"R","Ŗ":"R","Ṙ":"R","Ṛ":"R","Ṝ":"R","Ȑ":"R","Ȓ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꜿ":"C","Ǝ":"E","Ś":"S","Ṥ":"S","Š":"S","Ṧ":"S","Ş":"S","Ŝ":"S","Ș":"S","Ṡ":"S","Ṣ":"S","Ṩ":"S","ẞ":"Ss","Ť":"T","Ţ":"T","Ṱ":"T","Ț":"T","Ⱦ":"T","Ṫ":"T","Ṭ":"T","Ƭ":"T","Ṯ":"T","Ʈ":"T","Ŧ":"T","Ɐ":"A","Ꞁ":"L","Ɯ":"M","Ʌ":"V","Ꜩ":"TZ","Ú":"U","Ŭ":"U","Ǔ":"U","Û":"U","Ṷ":"U","Ü":"Ue","Ǘ":"U","Ǚ":"U","Ǜ":"U","Ǖ":"U","Ṳ":"U","Ụ":"U","Ű":"U","Ȕ":"U","Ù":"U","Ủ":"U","Ư":"U","Ứ":"U","Ự":"U","Ừ":"U","Ử":"U","Ữ":"U","Ȗ":"U","Ū":"U","Ṻ":"U","Ų":"U","Ů":"U","Ũ":"U","Ṹ":"U","Ṵ":"U","Ꝟ":"V","Ṿ":"V","Ʋ":"V","Ṽ":"V","Ꝡ":"VY","Ẃ":"W","Ŵ":"W","Ẅ":"W","Ẇ":"W","Ẉ":"W","Ẁ":"W","Ⱳ":"W","Ẍ":"X","Ẋ":"X","Ý":"Y","Ŷ":"Y","Ÿ":"Y","Ẏ":"Y","Ỵ":"Y","Ỳ":"Y","Ƴ":"Y","Ỷ":"Y","Ỿ":"Y","Ȳ":"Y","Ɏ":"Y","Ỹ":"Y","Ź":"Z","Ž":"Z","Ẑ":"Z","Ⱬ":"Z","Ż":"Z","Ẓ":"Z","Ȥ":"Z","Ẕ":"Z","Ƶ":"Z","IJ":"IJ","Œ":"OE","ᴀ":"A","ᴁ":"AE","ʙ":"B","ᴃ":"B","ᴄ":"C","ᴅ":"D","ᴇ":"E","ꜰ":"F","ɢ":"G","ʛ":"G","ʜ":"H","ɪ":"I","ʁ":"R","ᴊ":"J","ᴋ":"K","ʟ":"L","ᴌ":"L","ᴍ":"M","ɴ":"N","ᴏ":"O","ɶ":"OE","ᴐ":"O","ᴕ":"OU","ᴘ":"P","ʀ":"R","ᴎ":"N","ᴙ":"R","ꜱ":"S","ᴛ":"T","ⱻ":"E","ᴚ":"R","ᴜ":"U","ᴠ":"V","ᴡ":"W","ʏ":"Y","ᴢ":"Z","á":"a","ă":"a","ắ":"a","ặ":"a","ằ":"a","ẳ":"a","ẵ":"a","ǎ":"a","â":"a","ấ":"a","ậ":"a","ầ":"a","ẩ":"a","ẫ":"a","ä":"ae","ǟ":"a","ȧ":"a","ǡ":"a","ạ":"a","ȁ":"a","à":"a","ả":"a","ȃ":"a","ā":"a","ą":"a","ᶏ":"a","ẚ":"a","å":"a","ǻ":"a","ḁ":"a","ⱥ":"a","ã":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ḃ":"b","ḅ":"b","ɓ":"b","ḇ":"b","ᵬ":"b","ᶀ":"b","ƀ":"b","ƃ":"b","ɵ":"o","ć":"c","č":"c","ç":"c","ḉ":"c","ĉ":"c","ɕ":"c","ċ":"c","ƈ":"c","ȼ":"c","ď":"d","ḑ":"d","ḓ":"d","ȡ":"d","ḋ":"d","ḍ":"d","ɗ":"d","ᶑ":"d","ḏ":"d","ᵭ":"d","ᶁ":"d","đ":"d","ɖ":"d","ƌ":"d","ı":"i","ȷ":"j","ɟ":"j","ʄ":"j","dz":"dz","dž":"dz","é":"e","ĕ":"e","ě":"e","ȩ":"e","ḝ":"e","ê":"e","ế":"e","ệ":"e","ề":"e","ể":"e","ễ":"e","ḙ":"e","ë":"e","ė":"e","ẹ":"e","ȅ":"e","è":"e","ẻ":"e","ȇ":"e","ē":"e","ḗ":"e","ḕ":"e","ⱸ":"e","ę":"e","ᶒ":"e","ɇ":"e","ẽ":"e","ḛ":"e","ꝫ":"et","ḟ":"f","ƒ":"f","ᵮ":"f","ᶂ":"f","ǵ":"g","ğ":"g","ǧ":"g","ģ":"g","ĝ":"g","ġ":"g","ɠ":"g","ḡ":"g","ᶃ":"g","ǥ":"g","ḫ":"h","ȟ":"h","ḩ":"h","ĥ":"h","ⱨ":"h","ḧ":"h","ḣ":"h","ḥ":"h","ɦ":"h","ẖ":"h","ħ":"h","ƕ":"hv","í":"i","ĭ":"i","ǐ":"i","î":"i","ï":"i","ḯ":"i","ị":"i","ȉ":"i","ì":"i","ỉ":"i","ȋ":"i","ī":"i","į":"i","ᶖ":"i","ɨ":"i","ĩ":"i","ḭ":"i","ꝺ":"d","ꝼ":"f","ᵹ":"g","ꞃ":"r","ꞅ":"s","ꞇ":"t","ꝭ":"is","ǰ":"j","ĵ":"j","ʝ":"j","ɉ":"j","ḱ":"k","ǩ":"k","ķ":"k","ⱪ":"k","ꝃ":"k","ḳ":"k","ƙ":"k","ḵ":"k","ᶄ":"k","ꝁ":"k","ꝅ":"k","ĺ":"l","ƚ":"l","ɬ":"l","ľ":"l","ļ":"l","ḽ":"l","ȴ":"l","ḷ":"l","ḹ":"l","ⱡ":"l","ꝉ":"l","ḻ":"l","ŀ":"l","ɫ":"l","ᶅ":"l","ɭ":"l","ł":"l","lj":"lj","ſ":"s","ẜ":"s","ẛ":"s","ẝ":"s","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ᵯ":"m","ᶆ":"m","ń":"n","ň":"n","ņ":"n","ṋ":"n","ȵ":"n","ṅ":"n","ṇ":"n","ǹ":"n","ɲ":"n","ṉ":"n","ƞ":"n","ᵰ":"n","ᶇ":"n","ɳ":"n","ñ":"n","nj":"nj","ó":"o","ŏ":"o","ǒ":"o","ô":"o","ố":"o","ộ":"o","ồ":"o","ổ":"o","ỗ":"o","ö":"oe","ȫ":"o","ȯ":"o","ȱ":"o","ọ":"o","ő":"o","ȍ":"o","ò":"o","ỏ":"o","ơ":"o","ớ":"o","ợ":"o","ờ":"o","ở":"o","ỡ":"o","ȏ":"o","ꝋ":"o","ꝍ":"o","ⱺ":"o","ō":"o","ṓ":"o","ṑ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","õ":"o","ṍ":"o","ṏ":"o","ȭ":"o","ƣ":"oi","ꝏ":"oo","ɛ":"e","ᶓ":"e","ɔ":"o","ᶗ":"o","ȣ":"ou","ṕ":"p","ṗ":"p","ꝓ":"p","ƥ":"p","ᵱ":"p","ᶈ":"p","ꝕ":"p","ᵽ":"p","ꝑ":"p","ꝙ":"q","ʠ":"q","ɋ":"q","ꝗ":"q","ŕ":"r","ř":"r","ŗ":"r","ṙ":"r","ṛ":"r","ṝ":"r","ȑ":"r","ɾ":"r","ᵳ":"r","ȓ":"r","ṟ":"r","ɼ":"r","ᵲ":"r","ᶉ":"r","ɍ":"r","ɽ":"r","ↄ":"c","ꜿ":"c","ɘ":"e","ɿ":"r","ś":"s","ṥ":"s","š":"s","ṧ":"s","ş":"s","ŝ":"s","ș":"s","ṡ":"s","ṣ":"s","ṩ":"s","ʂ":"s","ᵴ":"s","ᶊ":"s","ȿ":"s","ɡ":"g","ß":"ss","ᴑ":"o","ᴓ":"o","ᴝ":"u","ť":"t","ţ":"t","ṱ":"t","ț":"t","ȶ":"t","ẗ":"t","ⱦ":"t","ṫ":"t","ṭ":"t","ƭ":"t","ṯ":"t","ᵵ":"t","ƫ":"t","ʈ":"t","ŧ":"t","ᵺ":"th","ɐ":"a","ᴂ":"ae","ǝ":"e","ᵷ":"g","ɥ":"h","ʮ":"h","ʯ":"h","ᴉ":"i","ʞ":"k","ꞁ":"l","ɯ":"m","ɰ":"m","ᴔ":"oe","ɹ":"r","ɻ":"r","ɺ":"r","ⱹ":"r","ʇ":"t","ʌ":"v","ʍ":"w","ʎ":"y","ꜩ":"tz","ú":"u","ŭ":"u","ǔ":"u","û":"u","ṷ":"u","ü":"ue","ǘ":"u","ǚ":"u","ǜ":"u","ǖ":"u","ṳ":"u","ụ":"u","ű":"u","ȕ":"u","ù":"u","ủ":"u","ư":"u","ứ":"u","ự":"u","ừ":"u","ử":"u","ữ":"u","ȗ":"u","ū":"u","ṻ":"u","ų":"u","ᶙ":"u","ů":"u","ũ":"u","ṹ":"u","ṵ":"u","ᵫ":"ue","ꝸ":"um","ⱴ":"v","ꝟ":"v","ṿ":"v","ʋ":"v","ᶌ":"v","ⱱ":"v","ṽ":"v","ꝡ":"vy","ẃ":"w","ŵ":"w","ẅ":"w","ẇ":"w","ẉ":"w","ẁ":"w","ⱳ":"w","ẘ":"w","ẍ":"x","ẋ":"x","ᶍ":"x","ý":"y","ŷ":"y","ÿ":"y","ẏ":"y","ỵ":"y","ỳ":"y","ƴ":"y","ỷ":"y","ỿ":"y","ȳ":"y","ẙ":"y","ɏ":"y","ỹ":"y","ź":"z","ž":"z","ẑ":"z","ʑ":"z","ⱬ":"z","ż":"z","ẓ":"z","ȥ":"z","ẕ":"z","ᵶ":"z","ᶎ":"z","ʐ":"z","ƶ":"z","ɀ":"z","ff":"ff","ffi":"ffi","ffl":"ffl","fi":"fi","fl":"fl","ij":"ij","œ":"oe","st":"st","ₐ":"a","ₑ":"e","ᵢ":"i","ⱼ":"j","ₒ":"o","ᵣ":"r","ᵤ":"u","ᵥ":"v","ₓ":"x"};export function replace(t,e,r){t=`${t}`,e=[].concat(e),r=[].concat(r);let o="";return e.forEach(((e,n)=>{o=r.length>1?void 0!==r[n]?r[n]:"":r[0],t=isFunction(String.prototype.replaceAll)?t.replaceAll(`${e}`,`${o}`):t.split(`${e}`).join(`${o}`)})),t}export function truncate(t,e=30,r="..."){if(t=`${t}`,e=orDefault(e,30,"int"),(r=orDefault(r,"...","str")).length>e)throw new Error("Strings:truncate | suffix cannot be longer than maxLength");return t.length>e&&(t=`${t.slice(0,e-r.length)}${r}`),t}export function pad(t,e,r,o="left"){t=`${t}`,e=`${e}`[0],r=orDefault(r,2,"int"),o=["left","right"].includes(`${o}`)?`${o}`:"left";const n=r-t.length;if(n>0)for(let r=0;rt?`${t}`:"\\s")),r=["both","left","right"].includes(`${r}`)?`${r}`:"both",["both","left"].includes(r)&&(t=t.replace(new RegExp(`^(${e.join("|")})+`,"g"),"")),["both","right"].includes(r)&&(t=t.replace(new RegExp(`(${e.join("|")})+$`,"g"),"")),t}export function concat(t="",...e){return t=orDefault(t,"","str"),e.length>0&&isArray(e[0])?e[0].join(t):e.join(t)}export function format(t,...e){let r=0,o=!1,n=!1;const a=function(t,e){const r=t[e];return isFunction(r)?r.call(t):r},l={int(t,e){e=orDefault(e,10,"int");const r=parseInt(t,e);return isNaN(r)?"":`${r}`},float(t,e){e=orDefault(e,null,"str");let r=null;if(hasValue(e)){let o=0;try{o=e.split(".")[1].length}catch(t){throw new Error("Strings:format | float precision arg malformed")}r=round(t,o)}else r=parseFloat(t);return isNaN(r)?"":`${r}`}};return(t=`${t}`).replace(/([{}])\1|[{](.*?)(?:!(.+?))?[}]/g,(function(t,i,u){let c=null,s="",f=function(t){return t},p=null;if(i)return i;if(u.length){const t=u.split(":");if(t.length>1){u=t[0];const e=t[1].split("("),r=e[0];e.length>1&&(p=e[1].replace(")",""));try{f=l[r]}catch(t){throw new Error("Strings:format | unknown formatter")}}if(n)throw new Error("Strings:format | cannot switch from implicit to explicit numbering");o=!0,c=function(t,e){/^(\d+)([.]|$)/.test(e)||(e=`0.${e}`);let r=/(.+?)[.](.+)/.exec(e);for(;r;)t=a(t,r[1]),e=r[2],r=/(.+?)[.](.+)/.exec(e);return a(t,e)}(e,u),s=orDefault(c,"")}else{if(o)throw new Error("Strings:format | cannot switch from explicit to implicit numbering");n=!0,c=e[r],s=orDefault(c,""),r++}return f(s,p)}))}export function slugify(t,e=null,r=!0){return isPlainObject(e)||(e={}),t=`${t}`,(r=orDefault(r,!0,"bool"))&&(t=t.toLowerCase()),t.replace(/[^\-]/g,(t=>e[t]??SLUGIFY_LATINMAP[t]??t)).replace(/\s+|_+/g,"-").replace(/[^\w\-]+/g,"").replace(/--+/g,"-").replace(/^-+/,"").replace(/-+$/,"")}export function maskForSelector(t){return`${t}`.replace(/([#;&,.+*~':"!^$\[\]()=>|\/@])/g,"\\$&")}export function maskForRegEx(t){return`${t}`.replace(/([\-\[\]\/{}()*+?.\\^$|])/g,"\\$&")}export function maskForHtml(t){const e=document.createElement("textarea");return e.textContent=`${t}`,e.innerHTML}export function unmaskFromHtml(t){const e=document.createElement("textarea");return e.innerHTML=`${t}`,e.textContent} +const MODULE_NAME="Strings";import{isFunction,isArray,orDefault,isNaN,hasValue,isPlainObject,round}from"./basic.js";const SLUGIFY_LATINMAP={"Á":"A","Ă":"A","Ắ":"A","Ặ":"A","Ằ":"A","Ẳ":"A","Ẵ":"A","Ǎ":"A","Â":"A","Ấ":"A","Ậ":"A","Ầ":"A","Ẩ":"A","Ẫ":"A","Ä":"Ae","Ǟ":"A","Ȧ":"A","Ǡ":"A","Ạ":"A","Ȁ":"A","À":"A","Ả":"A","Ȃ":"A","Ā":"A","Ą":"A","Å":"A","Ǻ":"A","Ḁ":"A","Ⱥ":"A","Ã":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ḃ":"B","Ḅ":"B","Ɓ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ć":"C","Č":"C","Ç":"C","Ḉ":"C","Ĉ":"C","Ċ":"C","Ƈ":"C","Ȼ":"C","Ď":"D","Ḑ":"D","Ḓ":"D","Ḋ":"D","Ḍ":"D","Ɗ":"D","Ḏ":"D","Dz":"D","Dž":"D","Đ":"D","Ƌ":"D","DZ":"DZ","DŽ":"DZ","É":"E","Ĕ":"E","Ě":"E","Ȩ":"E","Ḝ":"E","Ê":"E","Ế":"E","Ệ":"E","Ề":"E","Ể":"E","Ễ":"E","Ḙ":"E","Ë":"E","Ė":"E","Ẹ":"E","Ȅ":"E","È":"E","Ẻ":"E","Ȇ":"E","Ē":"E","Ḗ":"E","Ḕ":"E","Ę":"E","Ɇ":"E","Ẽ":"E","Ḛ":"E","Ꝫ":"ET","Ḟ":"F","Ƒ":"F","Ǵ":"G","Ğ":"G","Ǧ":"G","Ģ":"G","Ĝ":"G","Ġ":"G","Ɠ":"G","Ḡ":"G","Ǥ":"G","Ḫ":"H","Ȟ":"H","Ḩ":"H","Ĥ":"H","Ⱨ":"H","Ḧ":"H","Ḣ":"H","Ḥ":"H","Ħ":"H","Í":"I","Ĭ":"I","Ǐ":"I","Î":"I","Ï":"I","Ḯ":"I","İ":"I","Ị":"I","Ȉ":"I","Ì":"I","Ỉ":"I","Ȋ":"I","Ī":"I","Į":"I","Ɨ":"I","Ĩ":"I","Ḭ":"I","Ꝺ":"D","Ꝼ":"F","Ᵹ":"G","Ꞃ":"R","Ꞅ":"S","Ꞇ":"T","Ꝭ":"IS","Ĵ":"J","Ɉ":"J","Ḱ":"K","Ǩ":"K","Ķ":"K","Ⱪ":"K","Ꝃ":"K","Ḳ":"K","Ƙ":"K","Ḵ":"K","Ꝁ":"K","Ꝅ":"K","Ĺ":"L","Ƚ":"L","Ľ":"L","Ļ":"L","Ḽ":"L","Ḷ":"L","Ḹ":"L","Ⱡ":"L","Ꝉ":"L","Ḻ":"L","Ŀ":"L","Ɫ":"L","Lj":"L","Ł":"L","LJ":"LJ","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ń":"N","Ň":"N","Ņ":"N","Ṋ":"N","Ṅ":"N","Ṇ":"N","Ǹ":"N","Ɲ":"N","Ṉ":"N","Ƞ":"N","Nj":"N","Ñ":"N","NJ":"NJ","Ó":"O","Ŏ":"O","Ǒ":"O","Ô":"O","Ố":"O","Ộ":"O","Ồ":"O","Ổ":"O","Ỗ":"O","Ö":"Oe","Ȫ":"O","Ȯ":"O","Ȱ":"O","Ọ":"O","Ő":"O","Ȍ":"O","Ò":"O","Ỏ":"O","Ơ":"O","Ớ":"O","Ợ":"O","Ờ":"O","Ở":"O","Ỡ":"O","Ȏ":"O","Ꝋ":"O","Ꝍ":"O","Ō":"O","Ṓ":"O","Ṑ":"O","Ɵ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Õ":"O","Ṍ":"O","Ṏ":"O","Ȭ":"O","Ƣ":"OI","Ꝏ":"OO","Ɛ":"E","Ɔ":"O","Ȣ":"OU","Ṕ":"P","Ṗ":"P","Ꝓ":"P","Ƥ":"P","Ꝕ":"P","Ᵽ":"P","Ꝑ":"P","Ꝙ":"Q","Ꝗ":"Q","Ŕ":"R","Ř":"R","Ŗ":"R","Ṙ":"R","Ṛ":"R","Ṝ":"R","Ȑ":"R","Ȓ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꜿ":"C","Ǝ":"E","Ś":"S","Ṥ":"S","Š":"S","Ṧ":"S","Ş":"S","Ŝ":"S","Ș":"S","Ṡ":"S","Ṣ":"S","Ṩ":"S","ẞ":"Ss","Ť":"T","Ţ":"T","Ṱ":"T","Ț":"T","Ⱦ":"T","Ṫ":"T","Ṭ":"T","Ƭ":"T","Ṯ":"T","Ʈ":"T","Ŧ":"T","Ɐ":"A","Ꞁ":"L","Ɯ":"M","Ʌ":"V","Ꜩ":"TZ","Ú":"U","Ŭ":"U","Ǔ":"U","Û":"U","Ṷ":"U","Ü":"Ue","Ǘ":"U","Ǚ":"U","Ǜ":"U","Ǖ":"U","Ṳ":"U","Ụ":"U","Ű":"U","Ȕ":"U","Ù":"U","Ủ":"U","Ư":"U","Ứ":"U","Ự":"U","Ừ":"U","Ử":"U","Ữ":"U","Ȗ":"U","Ū":"U","Ṻ":"U","Ų":"U","Ů":"U","Ũ":"U","Ṹ":"U","Ṵ":"U","Ꝟ":"V","Ṿ":"V","Ʋ":"V","Ṽ":"V","Ꝡ":"VY","Ẃ":"W","Ŵ":"W","Ẅ":"W","Ẇ":"W","Ẉ":"W","Ẁ":"W","Ⱳ":"W","Ẍ":"X","Ẋ":"X","Ý":"Y","Ŷ":"Y","Ÿ":"Y","Ẏ":"Y","Ỵ":"Y","Ỳ":"Y","Ƴ":"Y","Ỷ":"Y","Ỿ":"Y","Ȳ":"Y","Ɏ":"Y","Ỹ":"Y","Ź":"Z","Ž":"Z","Ẑ":"Z","Ⱬ":"Z","Ż":"Z","Ẓ":"Z","Ȥ":"Z","Ẕ":"Z","Ƶ":"Z","IJ":"IJ","Œ":"OE","ᴀ":"A","ᴁ":"AE","ʙ":"B","ᴃ":"B","ᴄ":"C","ᴅ":"D","ᴇ":"E","ꜰ":"F","ɢ":"G","ʛ":"G","ʜ":"H","ɪ":"I","ʁ":"R","ᴊ":"J","ᴋ":"K","ʟ":"L","ᴌ":"L","ᴍ":"M","ɴ":"N","ᴏ":"O","ɶ":"OE","ᴐ":"O","ᴕ":"OU","ᴘ":"P","ʀ":"R","ᴎ":"N","ᴙ":"R","ꜱ":"S","ᴛ":"T","ⱻ":"E","ᴚ":"R","ᴜ":"U","ᴠ":"V","ᴡ":"W","ʏ":"Y","ᴢ":"Z","á":"a","ă":"a","ắ":"a","ặ":"a","ằ":"a","ẳ":"a","ẵ":"a","ǎ":"a","â":"a","ấ":"a","ậ":"a","ầ":"a","ẩ":"a","ẫ":"a","ä":"ae","ǟ":"a","ȧ":"a","ǡ":"a","ạ":"a","ȁ":"a","à":"a","ả":"a","ȃ":"a","ā":"a","ą":"a","ᶏ":"a","ẚ":"a","å":"a","ǻ":"a","ḁ":"a","ⱥ":"a","ã":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ḃ":"b","ḅ":"b","ɓ":"b","ḇ":"b","ᵬ":"b","ᶀ":"b","ƀ":"b","ƃ":"b","ɵ":"o","ć":"c","č":"c","ç":"c","ḉ":"c","ĉ":"c","ɕ":"c","ċ":"c","ƈ":"c","ȼ":"c","ď":"d","ḑ":"d","ḓ":"d","ȡ":"d","ḋ":"d","ḍ":"d","ɗ":"d","ᶑ":"d","ḏ":"d","ᵭ":"d","ᶁ":"d","đ":"d","ɖ":"d","ƌ":"d","ı":"i","ȷ":"j","ɟ":"j","ʄ":"j","dz":"dz","dž":"dz","é":"e","ĕ":"e","ě":"e","ȩ":"e","ḝ":"e","ê":"e","ế":"e","ệ":"e","ề":"e","ể":"e","ễ":"e","ḙ":"e","ë":"e","ė":"e","ẹ":"e","ȅ":"e","è":"e","ẻ":"e","ȇ":"e","ē":"e","ḗ":"e","ḕ":"e","ⱸ":"e","ę":"e","ᶒ":"e","ɇ":"e","ẽ":"e","ḛ":"e","ꝫ":"et","ḟ":"f","ƒ":"f","ᵮ":"f","ᶂ":"f","ǵ":"g","ğ":"g","ǧ":"g","ģ":"g","ĝ":"g","ġ":"g","ɠ":"g","ḡ":"g","ᶃ":"g","ǥ":"g","ḫ":"h","ȟ":"h","ḩ":"h","ĥ":"h","ⱨ":"h","ḧ":"h","ḣ":"h","ḥ":"h","ɦ":"h","ẖ":"h","ħ":"h","ƕ":"hv","í":"i","ĭ":"i","ǐ":"i","î":"i","ï":"i","ḯ":"i","ị":"i","ȉ":"i","ì":"i","ỉ":"i","ȋ":"i","ī":"i","į":"i","ᶖ":"i","ɨ":"i","ĩ":"i","ḭ":"i","ꝺ":"d","ꝼ":"f","ᵹ":"g","ꞃ":"r","ꞅ":"s","ꞇ":"t","ꝭ":"is","ǰ":"j","ĵ":"j","ʝ":"j","ɉ":"j","ḱ":"k","ǩ":"k","ķ":"k","ⱪ":"k","ꝃ":"k","ḳ":"k","ƙ":"k","ḵ":"k","ᶄ":"k","ꝁ":"k","ꝅ":"k","ĺ":"l","ƚ":"l","ɬ":"l","ľ":"l","ļ":"l","ḽ":"l","ȴ":"l","ḷ":"l","ḹ":"l","ⱡ":"l","ꝉ":"l","ḻ":"l","ŀ":"l","ɫ":"l","ᶅ":"l","ɭ":"l","ł":"l","lj":"lj","ſ":"s","ẜ":"s","ẛ":"s","ẝ":"s","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ᵯ":"m","ᶆ":"m","ń":"n","ň":"n","ņ":"n","ṋ":"n","ȵ":"n","ṅ":"n","ṇ":"n","ǹ":"n","ɲ":"n","ṉ":"n","ƞ":"n","ᵰ":"n","ᶇ":"n","ɳ":"n","ñ":"n","nj":"nj","ó":"o","ŏ":"o","ǒ":"o","ô":"o","ố":"o","ộ":"o","ồ":"o","ổ":"o","ỗ":"o","ö":"oe","ȫ":"o","ȯ":"o","ȱ":"o","ọ":"o","ő":"o","ȍ":"o","ò":"o","ỏ":"o","ơ":"o","ớ":"o","ợ":"o","ờ":"o","ở":"o","ỡ":"o","ȏ":"o","ꝋ":"o","ꝍ":"o","ⱺ":"o","ō":"o","ṓ":"o","ṑ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","õ":"o","ṍ":"o","ṏ":"o","ȭ":"o","ƣ":"oi","ꝏ":"oo","ɛ":"e","ᶓ":"e","ɔ":"o","ᶗ":"o","ȣ":"ou","ṕ":"p","ṗ":"p","ꝓ":"p","ƥ":"p","ᵱ":"p","ᶈ":"p","ꝕ":"p","ᵽ":"p","ꝑ":"p","ꝙ":"q","ʠ":"q","ɋ":"q","ꝗ":"q","ŕ":"r","ř":"r","ŗ":"r","ṙ":"r","ṛ":"r","ṝ":"r","ȑ":"r","ɾ":"r","ᵳ":"r","ȓ":"r","ṟ":"r","ɼ":"r","ᵲ":"r","ᶉ":"r","ɍ":"r","ɽ":"r","ↄ":"c","ꜿ":"c","ɘ":"e","ɿ":"r","ś":"s","ṥ":"s","š":"s","ṧ":"s","ş":"s","ŝ":"s","ș":"s","ṡ":"s","ṣ":"s","ṩ":"s","ʂ":"s","ᵴ":"s","ᶊ":"s","ȿ":"s","ɡ":"g","ß":"ss","ᴑ":"o","ᴓ":"o","ᴝ":"u","ť":"t","ţ":"t","ṱ":"t","ț":"t","ȶ":"t","ẗ":"t","ⱦ":"t","ṫ":"t","ṭ":"t","ƭ":"t","ṯ":"t","ᵵ":"t","ƫ":"t","ʈ":"t","ŧ":"t","ᵺ":"th","ɐ":"a","ᴂ":"ae","ǝ":"e","ᵷ":"g","ɥ":"h","ʮ":"h","ʯ":"h","ᴉ":"i","ʞ":"k","ꞁ":"l","ɯ":"m","ɰ":"m","ᴔ":"oe","ɹ":"r","ɻ":"r","ɺ":"r","ⱹ":"r","ʇ":"t","ʌ":"v","ʍ":"w","ʎ":"y","ꜩ":"tz","ú":"u","ŭ":"u","ǔ":"u","û":"u","ṷ":"u","ü":"ue","ǘ":"u","ǚ":"u","ǜ":"u","ǖ":"u","ṳ":"u","ụ":"u","ű":"u","ȕ":"u","ù":"u","ủ":"u","ư":"u","ứ":"u","ự":"u","ừ":"u","ử":"u","ữ":"u","ȗ":"u","ū":"u","ṻ":"u","ų":"u","ᶙ":"u","ů":"u","ũ":"u","ṹ":"u","ṵ":"u","ᵫ":"ue","ꝸ":"um","ⱴ":"v","ꝟ":"v","ṿ":"v","ʋ":"v","ᶌ":"v","ⱱ":"v","ṽ":"v","ꝡ":"vy","ẃ":"w","ŵ":"w","ẅ":"w","ẇ":"w","ẉ":"w","ẁ":"w","ⱳ":"w","ẘ":"w","ẍ":"x","ẋ":"x","ᶍ":"x","ý":"y","ŷ":"y","ÿ":"y","ẏ":"y","ỵ":"y","ỳ":"y","ƴ":"y","ỷ":"y","ỿ":"y","ȳ":"y","ẙ":"y","ɏ":"y","ỹ":"y","ź":"z","ž":"z","ẑ":"z","ʑ":"z","ⱬ":"z","ż":"z","ẓ":"z","ȥ":"z","ẕ":"z","ᵶ":"z","ᶎ":"z","ʐ":"z","ƶ":"z","ɀ":"z","ff":"ff","ffi":"ffi","ffl":"ffl","fi":"fi","fl":"fl","ij":"ij","œ":"oe","st":"st","ₐ":"a","ₑ":"e","ᵢ":"i","ⱼ":"j","ₒ":"o","ᵣ":"r","ᵤ":"u","ᵥ":"v","ₓ":"x"};export function replace(t,e,r){t=`${t}`,e=[].concat(e),r=[].concat(r);let o="";return e.forEach(((e,n)=>{o=r.length>1?void 0!==r[n]?r[n]:"":r[0],t=isFunction(String.prototype.replaceAll)?t.replaceAll(`${e}`,`${o}`):t.split(`${e}`).join(`${o}`)})),t}export function truncate(t,e=30,r="..."){if(t=`${t}`,e=orDefault(e,30,"int"),(r=orDefault(r,"...","str")).length>e)throw new Error("Strings:truncate | suffix cannot be longer than maxLength");return t.length>e&&(t=`${t.slice(0,e-r.length)}${r}`),t}export function pad(t,e,r,o="left"){t=`${t}`,e=`${e}`[0],r=orDefault(r,2,"int"),o=["left","right"].includes(`${o}`)?`${o}`:"left";const n=r-t.length;if(n>0)for(let r=0;rt?`${t}`:"\\s")),r=["both","left","right"].includes(`${r}`)?`${r}`:"both",["both","left"].includes(r)&&(t=t.replace(new RegExp(`^(${e.join("|")})+`,"g"),"")),["both","right"].includes(r)&&(t=t.replace(new RegExp(`(${e.join("|")})+$`,"g"),"")),t}export function concat(t="",...e){return t=orDefault(t,"","str"),e.length>0&&isArray(e[0])?e[0].join(t):e.join(t)}export function format(t,...e){t=`${t}`;let r=0,o=!1,n=!1;const a=function(t,e){const r=t[e];return isFunction(r)?r.call(t):r},l={int(t,e){e=orDefault(e,10,"int");const r=parseInt(t,e);return isNaN(r)?"":`${r}`},float(t,e){e=orDefault(e,null,"str");let r=null;if(hasValue(e)){let o=0;try{o=e.split(".")[1].length}catch(t){throw new Error("Strings:format | float precision arg malformed")}r=round(t,o)}else r=parseFloat(t);return isNaN(r)?"":`${r}`}};return t.replace(/([{}])\1|[{](.*?)(?:!(.+?))?[}]/g,(function(t,i,u){let c=null,s="",f=function(t){return t},p=null;if(i)return i;if(u.length){const t=u.split(":");if(t.length>1){u=t[0];const e=t[1].split("("),r=e[0];e.length>1&&(p=e[1].replace(")",""));try{f=l[r]}catch(t){throw new Error("Strings:format | unknown formatter")}}if(n)throw new Error("Strings:format | cannot switch from implicit to explicit numbering");o=!0,c=function(t,e){/^(\d+)([.]|$)/.test(e)||(e=`0.${e}`);let r=/(.+?)[.](.+)/.exec(e);for(;r;)t=a(t,r[1]),e=r[2],r=/(.+?)[.](.+)/.exec(e);return a(t,e)}(e,u),s=orDefault(c,"")}else{if(o)throw new Error("Strings:format | cannot switch from explicit to implicit numbering");n=!0,c=e[r],s=orDefault(c,""),r++}return f(s,p)}))}export function slugify(t,e=null,r=!0){return isPlainObject(e)||(e={}),t=`${t}`,(r=orDefault(r,!0,"bool"))&&(t=t.toLowerCase()),t.replace(/[^\-]/g,(t=>e[t]??SLUGIFY_LATINMAP[t]??t)).replace(/\s+|_+/g,"-").replace(/[^\w\-]+/g,"").replace(/--+/g,"-").replace(/^-+/,"").replace(/-+$/,"")}export function maskForSelector(t){return`${t}`.replace(/([#;&,.+*~':"!^$\[\]()=>|\/@])/g,"\\$&")}export function maskForRegEx(t){return`${t}`.replace(/([\-\[\]\/{}()*+?.\\^$|])/g,"\\$&")}export function maskForHtml(t){const e=document.createElement("textarea");return e.textContent=`${t}`,e.innerHTML}export function unmaskFromHtml(t){const e=document.createElement("textarea");return e.innerHTML=`${t}`,e.textContent} //# sourceMappingURL=strings.js.map diff --git a/dist/strings.js.map b/dist/strings.js.map index 62882013..8014d82e 100644 --- a/dist/strings.js.map +++ b/dist/strings.js.map @@ -1 +1 @@ -{"version":3,"file":"strings.js","names":["MODULE_NAME","isFunction","isArray","orDefault","isNaN","hasValue","isPlainObject","round","SLUGIFY_LATINMAP","replace","subject","search","concat","tmp","forEach","searchTerm","index","length","undefined","String","prototype","replaceAll","split","join","truncate","maxLength","suffix","Error","slice","pad","paddingCharacter","expectedLength","from","includes","difference","i","trim","characters","map","char","RegExp","glue","strings","format","template","replacements","idx","explicit","implicit","fResolve","object","key","value","call","formatters","int","radix","res","parseInt","float","precision","ex","parseFloat","match","literal","ref","formatter","formatterArg","keyParts","formatterParts","formatterName","test","exec","fLookup","slugify","text","additionalMap","toLowerCase","maskForSelector","str","maskForRegEx","maskForHtml","escape","document","createElement","textContent","innerHTML","unmaskFromHtml","html"],"sources":["strings.js"],"mappings":";;;AAQA,MAAMA,YAAc,iBAMZC,WAAYC,QAASC,UAAWC,MAAOC,SAAUC,cAAeC,UAAY,aAMpF,MAAMC,iBAAmB,CACxB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,IACrG,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC/G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAC5G,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAC3G,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAC/G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,KAAK,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI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","sourcesContent":["/*!\n * Module Strings\n */\n\n/**\n * @namespace Strings\n */\n\nconst MODULE_NAME = 'Strings';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {isFunction, isArray, orDefault, isNaN, hasValue, isPlainObject, round} from './basic.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst SLUGIFY_LATINMAP = {\n\t'Á':'A','Ă':'A','Ắ':'A','Ặ':'A','Ằ':'A','Ẳ':'A','Ẵ':'A','Ǎ':'A','Â':'A','Ấ':'A','Ậ':'A','Ầ':'A','Ẩ':'A','Ẫ':'A',\n\t'Ä':'Ae','Ǟ':'A','Ȧ':'A','Ǡ':'A','Ạ':'A','Ȁ':'A','À':'A','Ả':'A','Ȃ':'A','Ā':'A','Ą':'A','Å':'A','Ǻ':'A','Ḁ':'A',\n\t'Ⱥ':'A','Ã':'A','Ꜳ':'AA','Æ':'AE','Ǽ':'AE','Ǣ':'AE','Ꜵ':'AO','Ꜷ':'AU','Ꜹ':'AV','Ꜻ':'AV','Ꜽ':'AY','Ḃ':'B',\n\t'Ḅ':'B','Ɓ':'B','Ḇ':'B','Ƀ':'B','Ƃ':'B','Ć':'C','Č':'C','Ç':'C','Ḉ':'C','Ĉ':'C','Ċ':'C','Ƈ':'C','Ȼ':'C','Ď':'D',\n\t'Ḑ':'D','Ḓ':'D','Ḋ':'D','Ḍ':'D','Ɗ':'D','Ḏ':'D','Dz':'D','Dž':'D','Đ':'D','Ƌ':'D','DZ':'DZ','DŽ':'DZ','É':'E','Ĕ':'E',\n\t'Ě':'E','Ȩ':'E','Ḝ':'E','Ê':'E','Ế':'E','Ệ':'E','Ề':'E','Ể':'E','Ễ':'E','Ḙ':'E','Ë':'E','Ė':'E','Ẹ':'E','Ȅ':'E',\n\t'È':'E','Ẻ':'E','Ȇ':'E','Ē':'E','Ḗ':'E','Ḕ':'E','Ę':'E','Ɇ':'E','Ẽ':'E','Ḛ':'E','Ꝫ':'ET','Ḟ':'F','Ƒ':'F','Ǵ':'G',\n\t'Ğ':'G','Ǧ':'G','Ģ':'G','Ĝ':'G','Ġ':'G','Ɠ':'G','Ḡ':'G','Ǥ':'G','Ḫ':'H','Ȟ':'H','Ḩ':'H','Ĥ':'H','Ⱨ':'H','Ḧ':'H',\n\t'Ḣ':'H','Ḥ':'H','Ħ':'H','Í':'I','Ĭ':'I','Ǐ':'I','Î':'I','Ï':'I','Ḯ':'I','İ':'I','Ị':'I','Ȉ':'I','Ì':'I','Ỉ':'I',\n\t'Ȋ':'I','Ī':'I','Į':'I','Ɨ':'I','Ĩ':'I','Ḭ':'I','Ꝺ':'D','Ꝼ':'F','Ᵹ':'G','Ꞃ':'R','Ꞅ':'S','Ꞇ':'T','Ꝭ':'IS','Ĵ':'J',\n\t'Ɉ':'J','Ḱ':'K','Ǩ':'K','Ķ':'K','Ⱪ':'K','Ꝃ':'K','Ḳ':'K','Ƙ':'K','Ḵ':'K','Ꝁ':'K','Ꝅ':'K','Ĺ':'L','Ƚ':'L','Ľ':'L',\n\t'Ļ':'L','Ḽ':'L','Ḷ':'L','Ḹ':'L','Ⱡ':'L','Ꝉ':'L','Ḻ':'L','Ŀ':'L','Ɫ':'L','Lj':'L','Ł':'L','LJ':'LJ','Ḿ':'M','Ṁ':'M',\n\t'Ṃ':'M','Ɱ':'M','Ń':'N','Ň':'N','Ņ':'N','Ṋ':'N','Ṅ':'N','Ṇ':'N','Ǹ':'N','Ɲ':'N','Ṉ':'N','Ƞ':'N','Nj':'N','Ñ':'N',\n\t'NJ':'NJ','Ó':'O','Ŏ':'O','Ǒ':'O','Ô':'O','Ố':'O','Ộ':'O','Ồ':'O','Ổ':'O','Ỗ':'O','Ö':'Oe','Ȫ':'O','Ȯ':'O','Ȱ':'O',\n\t'Ọ':'O','Ő':'O','Ȍ':'O','Ò':'O','Ỏ':'O','Ơ':'O','Ớ':'O','Ợ':'O','Ờ':'O','Ở':'O','Ỡ':'O','Ȏ':'O','Ꝋ':'O','Ꝍ':'O',\n\t'Ō':'O','Ṓ':'O','Ṑ':'O','Ɵ':'O','Ǫ':'O','Ǭ':'O','Ø':'O','Ǿ':'O','Õ':'O','Ṍ':'O','Ṏ':'O','Ȭ':'O','Ƣ':'OI','Ꝏ':'OO',\n\t'Ɛ':'E','Ɔ':'O','Ȣ':'OU','Ṕ':'P','Ṗ':'P','Ꝓ':'P','Ƥ':'P','Ꝕ':'P','Ᵽ':'P','Ꝑ':'P','Ꝙ':'Q','Ꝗ':'Q','Ŕ':'R','Ř':'R',\n\t'Ŗ':'R','Ṙ':'R','Ṛ':'R','Ṝ':'R','Ȑ':'R','Ȓ':'R','Ṟ':'R','Ɍ':'R','Ɽ':'R','Ꜿ':'C','Ǝ':'E','Ś':'S','Ṥ':'S','Š':'S',\n\t'Ṧ':'S','Ş':'S','Ŝ':'S','Ș':'S','Ṡ':'S','Ṣ':'S','Ṩ':'S','ẞ':'Ss','Ť':'T','Ţ':'T','Ṱ':'T','Ț':'T','Ⱦ':'T','Ṫ':'T',\n\t'Ṭ':'T','Ƭ':'T','Ṯ':'T','Ʈ':'T','Ŧ':'T','Ɐ':'A','Ꞁ':'L','Ɯ':'M','Ʌ':'V','Ꜩ':'TZ','Ú':'U','Ŭ':'U','Ǔ':'U','Û':'U',\n\t'Ṷ':'U','Ü':'Ue','Ǘ':'U','Ǚ':'U','Ǜ':'U','Ǖ':'U','Ṳ':'U','Ụ':'U','Ű':'U','Ȕ':'U','Ù':'U','Ủ':'U','Ư':'U','Ứ':'U',\n\t'Ự':'U','Ừ':'U','Ử':'U','Ữ':'U','Ȗ':'U','Ū':'U','Ṻ':'U','Ų':'U','Ů':'U','Ũ':'U','Ṹ':'U','Ṵ':'U','Ꝟ':'V','Ṿ':'V',\n\t'Ʋ':'V','Ṽ':'V','Ꝡ':'VY','Ẃ':'W','Ŵ':'W','Ẅ':'W','Ẇ':'W','Ẉ':'W','Ẁ':'W','Ⱳ':'W','Ẍ':'X','Ẋ':'X','Ý':'Y','Ŷ':'Y',\n\t'Ÿ':'Y','Ẏ':'Y','Ỵ':'Y','Ỳ':'Y','Ƴ':'Y','Ỷ':'Y','Ỿ':'Y','Ȳ':'Y','Ɏ':'Y','Ỹ':'Y','Ź':'Z','Ž':'Z','Ẑ':'Z','Ⱬ':'Z',\n\t'Ż':'Z','Ẓ':'Z','Ȥ':'Z','Ẕ':'Z','Ƶ':'Z','IJ':'IJ','Œ':'OE','ᴀ':'A','ᴁ':'AE','ʙ':'B','ᴃ':'B','ᴄ':'C','ᴅ':'D','ᴇ':'E',\n\t'ꜰ':'F','ɢ':'G','ʛ':'G','ʜ':'H','ɪ':'I','ʁ':'R','ᴊ':'J','ᴋ':'K','ʟ':'L','ᴌ':'L','ᴍ':'M','ɴ':'N','ᴏ':'O','ɶ':'OE',\n\t'ᴐ':'O','ᴕ':'OU','ᴘ':'P','ʀ':'R','ᴎ':'N','ᴙ':'R','ꜱ':'S','ᴛ':'T','ⱻ':'E','ᴚ':'R','ᴜ':'U','ᴠ':'V','ᴡ':'W','ʏ':'Y',\n\t'ᴢ':'Z','á':'a','ă':'a','ắ':'a','ặ':'a','ằ':'a','ẳ':'a','ẵ':'a','ǎ':'a','â':'a','ấ':'a','ậ':'a','ầ':'a','ẩ':'a',\n\t'ẫ':'a','ä':'ae','ǟ':'a','ȧ':'a','ǡ':'a','ạ':'a','ȁ':'a','à':'a','ả':'a','ȃ':'a','ā':'a','ą':'a','ᶏ':'a','ẚ':'a',\n\t'å':'a','ǻ':'a','ḁ':'a','ⱥ':'a','ã':'a','ꜳ':'aa','æ':'ae','ǽ':'ae','ǣ':'ae','ꜵ':'ao','ꜷ':'au','ꜹ':'av','ꜻ':'av',\n\t'ꜽ':'ay','ḃ':'b','ḅ':'b','ɓ':'b','ḇ':'b','ᵬ':'b','ᶀ':'b','ƀ':'b','ƃ':'b','ɵ':'o','ć':'c','č':'c','ç':'c','ḉ':'c',\n\t'ĉ':'c','ɕ':'c','ċ':'c','ƈ':'c','ȼ':'c','ď':'d','ḑ':'d','ḓ':'d','ȡ':'d','ḋ':'d','ḍ':'d','ɗ':'d','ᶑ':'d','ḏ':'d',\n\t'ᵭ':'d','ᶁ':'d','đ':'d','ɖ':'d','ƌ':'d','ı':'i','ȷ':'j','ɟ':'j','ʄ':'j','dz':'dz','dž':'dz','é':'e','ĕ':'e','ě':'e',\n\t'ȩ':'e','ḝ':'e','ê':'e','ế':'e','ệ':'e','ề':'e','ể':'e','ễ':'e','ḙ':'e','ë':'e','ė':'e','ẹ':'e','ȅ':'e','è':'e',\n\t'ẻ':'e','ȇ':'e','ē':'e','ḗ':'e','ḕ':'e','ⱸ':'e','ę':'e','ᶒ':'e','ɇ':'e','ẽ':'e','ḛ':'e','ꝫ':'et','ḟ':'f','ƒ':'f',\n\t'ᵮ':'f','ᶂ':'f','ǵ':'g','ğ':'g','ǧ':'g','ģ':'g','ĝ':'g','ġ':'g','ɠ':'g','ḡ':'g','ᶃ':'g','ǥ':'g','ḫ':'h','ȟ':'h',\n\t'ḩ':'h','ĥ':'h','ⱨ':'h','ḧ':'h','ḣ':'h','ḥ':'h','ɦ':'h','ẖ':'h','ħ':'h','ƕ':'hv','í':'i','ĭ':'i','ǐ':'i','î':'i',\n\t'ï':'i','ḯ':'i','ị':'i','ȉ':'i','ì':'i','ỉ':'i','ȋ':'i','ī':'i','į':'i','ᶖ':'i','ɨ':'i','ĩ':'i','ḭ':'i','ꝺ':'d',\n\t'ꝼ':'f','ᵹ':'g','ꞃ':'r','ꞅ':'s','ꞇ':'t','ꝭ':'is','ǰ':'j','ĵ':'j','ʝ':'j','ɉ':'j','ḱ':'k','ǩ':'k','ķ':'k','ⱪ':'k',\n\t'ꝃ':'k','ḳ':'k','ƙ':'k','ḵ':'k','ᶄ':'k','ꝁ':'k','ꝅ':'k','ĺ':'l','ƚ':'l','ɬ':'l','ľ':'l','ļ':'l','ḽ':'l','ȴ':'l',\n\t'ḷ':'l','ḹ':'l','ⱡ':'l','ꝉ':'l','ḻ':'l','ŀ':'l','ɫ':'l','ᶅ':'l','ɭ':'l','ł':'l','lj':'lj','ſ':'s','ẜ':'s','ẛ':'s',\n\t'ẝ':'s','ḿ':'m','ṁ':'m','ṃ':'m','ɱ':'m','ᵯ':'m','ᶆ':'m','ń':'n','ň':'n','ņ':'n','ṋ':'n','ȵ':'n','ṅ':'n','ṇ':'n',\n\t'ǹ':'n','ɲ':'n','ṉ':'n','ƞ':'n','ᵰ':'n','ᶇ':'n','ɳ':'n','ñ':'n','nj':'nj','ó':'o','ŏ':'o','ǒ':'o','ô':'o','ố':'o',\n\t'ộ':'o','ồ':'o','ổ':'o','ỗ':'o','ö':'oe','ȫ':'o','ȯ':'o','ȱ':'o','ọ':'o','ő':'o','ȍ':'o','ò':'o','ỏ':'o','ơ':'o',\n\t'ớ':'o','ợ':'o','ờ':'o','ở':'o','ỡ':'o','ȏ':'o','ꝋ':'o','ꝍ':'o','ⱺ':'o','ō':'o','ṓ':'o','ṑ':'o','ǫ':'o','ǭ':'o',\n\t'ø':'o','ǿ':'o','õ':'o','ṍ':'o','ṏ':'o','ȭ':'o','ƣ':'oi','ꝏ':'oo','ɛ':'e','ᶓ':'e','ɔ':'o','ᶗ':'o','ȣ':'ou','ṕ':'p',\n\t'ṗ':'p','ꝓ':'p','ƥ':'p','ᵱ':'p','ᶈ':'p','ꝕ':'p','ᵽ':'p','ꝑ':'p','ꝙ':'q','ʠ':'q','ɋ':'q','ꝗ':'q','ŕ':'r','ř':'r',\n\t'ŗ':'r','ṙ':'r','ṛ':'r','ṝ':'r','ȑ':'r','ɾ':'r','ᵳ':'r','ȓ':'r','ṟ':'r','ɼ':'r','ᵲ':'r','ᶉ':'r','ɍ':'r','ɽ':'r',\n\t'ↄ':'c','ꜿ':'c','ɘ':'e','ɿ':'r','ś':'s','ṥ':'s','š':'s','ṧ':'s','ş':'s','ŝ':'s','ș':'s','ṡ':'s','ṣ':'s','ṩ':'s',\n\t'ʂ':'s','ᵴ':'s','ᶊ':'s','ȿ':'s','ɡ':'g','ß':'ss','ᴑ':'o','ᴓ':'o','ᴝ':'u','ť':'t','ţ':'t','ṱ':'t','ț':'t','ȶ':'t',\n\t'ẗ':'t','ⱦ':'t','ṫ':'t','ṭ':'t','ƭ':'t','ṯ':'t','ᵵ':'t','ƫ':'t','ʈ':'t','ŧ':'t','ᵺ':'th','ɐ':'a','ᴂ':'ae','ǝ':'e',\n\t'ᵷ':'g','ɥ':'h','ʮ':'h','ʯ':'h','ᴉ':'i','ʞ':'k','ꞁ':'l','ɯ':'m','ɰ':'m','ᴔ':'oe','ɹ':'r','ɻ':'r','ɺ':'r','ⱹ':'r',\n\t'ʇ':'t','ʌ':'v','ʍ':'w','ʎ':'y','ꜩ':'tz','ú':'u','ŭ':'u','ǔ':'u','û':'u','ṷ':'u','ü':'ue','ǘ':'u','ǚ':'u','ǜ':'u',\n\t'ǖ':'u','ṳ':'u','ụ':'u','ű':'u','ȕ':'u','ù':'u','ủ':'u','ư':'u','ứ':'u','ự':'u','ừ':'u','ử':'u','ữ':'u','ȗ':'u',\n\t'ū':'u','ṻ':'u','ų':'u','ᶙ':'u','ů':'u','ũ':'u','ṹ':'u','ṵ':'u','ᵫ':'ue','ꝸ':'um','ⱴ':'v','ꝟ':'v','ṿ':'v','ʋ':'v',\n\t'ᶌ':'v','ⱱ':'v','ṽ':'v','ꝡ':'vy','ẃ':'w','ŵ':'w','ẅ':'w','ẇ':'w','ẉ':'w','ẁ':'w','ⱳ':'w','ẘ':'w','ẍ':'x','ẋ':'x',\n\t'ᶍ':'x','ý':'y','ŷ':'y','ÿ':'y','ẏ':'y','ỵ':'y','ỳ':'y','ƴ':'y','ỷ':'y','ỿ':'y','ȳ':'y','ẙ':'y','ɏ':'y','ỹ':'y',\n\t'ź':'z','ž':'z','ẑ':'z','ʑ':'z','ⱬ':'z','ż':'z','ẓ':'z','ȥ':'z','ẕ':'z','ᵶ':'z','ᶎ':'z','ʐ':'z','ƶ':'z','ɀ':'z',\n\t'ff':'ff','ffi':'ffi','ffl':'ffl','fi':'fi','fl':'fl','ij':'ij','œ':'oe','st':'st','ₐ':'a','ₑ':'e','ᵢ':'i','ⱼ':'j','ₒ':'o',\n\t'ᵣ':'r','ᵤ':'u','ᵥ':'v','ₓ':'x'\n};\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Strings:replace\n */\n\n/**\n * Offers similar functionality to PHP's str_replace or ES2021's replaceAll and avoids RegExps for this task.\n * Replaces occurrences of search in subject with replace. search and replace may be arrays.\n * If search is an array and replace is a string, all phrases in the array will be replaced with one string.\n * If replace is an array itself, phrases and replacements are matched by index.\n * Missing replacements are treated as an empty string (for example: if your array lengths do not match).\n *\n * Uses String.prototype.replaceAll internally, if available.\n *\n * @param {String} subject - the string to replace in\n * @param {(String|String[])} search - the string(s) to replace\n * @param {String|String[]} replace - the string(s) to replace the search string(s)\n * @returns {String} the modified string\n *\n * @memberof Strings:replace\n * @alias replace\n * @example\n * const sanitizedString = replace([':', '#', '-'], '_', exampleString);\n */\nexport function replace(subject, search, replace){\n\tsubject = `${subject}`;\n\tsearch = [].concat(search);\n\treplace = [].concat(replace);\n\n\tlet tmp = '';\n\n\tsearch.forEach((searchTerm, index) => {\n\t\ttmp = (replace.length > 1) ? ((replace[index] !== undefined) ? replace[index] : '') : replace[0];\n\n\t\tif( isFunction(String.prototype.replaceAll) ){\n\t\t\tsubject = subject.replaceAll(`${searchTerm}`, `${tmp}`);\n\t\t} else {\n\t\t\tsubject = subject.split(`${searchTerm}`).join(`${tmp}`);\n\t\t}\n\t});\n\n\treturn subject;\n}\n\n\n\n/**\n * @namespace Strings:truncate\n */\n\n/**\n * Truncates a given string after a certain number of characters to enforce length restrictions.\n *\n * @param {String} subject - the string to check and truncate\n * @param {?Number} [maxLength=30] - the maximum allowed character length for the string\n * @param {?String} [suffix='...'] - the trailing string to end a truncated string with\n * @throws error if suffix length is bigger than defined maxLength\n * @returns {String} the (truncated) subject\n *\n * @memberof Strings:truncate\n * @alias truncate\n * @example\n * const truncatedString = truncate(string, 10, '...');\n */\nexport function truncate(subject, maxLength=30, suffix='...'){\n\tsubject = `${subject}`;\n\tmaxLength = orDefault(maxLength, 30, 'int');\n\tsuffix = orDefault(suffix, '...', 'str');\n\n\tif( suffix.length > maxLength ){\n\t\tthrow new Error(`${MODULE_NAME}:truncate | suffix cannot be longer than maxLength`);\n\t}\n\n\tif( subject.length > maxLength ){\n\t\tsubject = `${subject.slice(0, maxLength - suffix.length)}${suffix}`;\n\t}\n\n\treturn subject;\n}\n\n\n/**\n * @namespace Strings:pad\n */\n\n/**\n * Adds characters to strings, which are not yet of a defined expected length.\n *\n * A usual use-case for this would be, to add zeroes to a number, to fit a format like ISO dates.\n *\n * @param {String} subject - the string to pad\n * @param {String} paddingCharacter - the character to use for padding, only first character is used\n * @param {Number} expectedLength - the number of characters, the result has to have at least\n * @param {String} [from='left'] - the number of characters, the result has to have at least\n * @returns {String} the padded value, will always be cast to a string\n *\n * @memberof Strings:pad\n * @alias pad\n * @example\n * pad(1, '0', 4, 'right')\n * => '1000'\n */\nexport function pad(subject, paddingCharacter, expectedLength, from='left'){\n\tsubject = `${subject}`;\n\tpaddingCharacter = `${paddingCharacter}`[0];\n\texpectedLength = orDefault(expectedLength, 2, 'int');\n\tfrom = ['left', 'right'].includes(`${from}`) ? `${from}` : 'left';\n\n\tconst difference = expectedLength - subject.length;\n\tif( difference > 0 ){\n\t\tfor( let i = 0; i < difference; i++ ){\n\t\t\tsubject = (from === 'right') ? `${subject}${paddingCharacter}` : `${paddingCharacter}${subject}`;\n\t\t}\n\t}\n\n\treturn subject;\n}\n\n\n/**\n * @namespace Strings:trim\n */\n\n/**\n * Removes whitespace or characters from the beginning and the end (or just one side) of a string.\n *\n * This is usually used to sanitize values and remove leading or trailing whitespace in user input.\n *\n * @param {String} subject - the string to trim\n * @param {?String|Array} [characters=null] - defines which character(s) to trim; will trim whitespace if nullish (or '\\\\s'); if you want to trim whitespace and something else, define an array including a nullish value (or '\\\\s') as well as the other characters; this parameter uses regex definitions\n * @param {?String} [from='both'] - the side(s) from which to trim, either \"both\", \"left\" or \"right\"\n * @returns {String} the trimmed subject\n *\n * @memberof Strings:trim\n * @alias trim\n * @example\n * trim(' foo ')\n * => 'foo'\n * trim(' foo ', null, 'right')\n * => ' foo'\n * trim('abcdefghijklmnopqrstuvwxyz', ['[a-f]', '[u-z]', 'l'], 'both')\n * => 'ghijklmnopqrst'\n */\nexport function trim(subject, characters=null, from='both'){\n\tsubject = `${subject}`;\n\tcharacters = [].concat(characters).map(char => !!char ? `${char}` : '\\\\s');\n\tfrom = ['both', 'left', 'right'].includes(`${from}`) ? `${from}` : 'both';\n\n\tif( ['both', 'left'].includes(from) ){\n\t\tsubject = subject.replace(new RegExp(`^(${characters.join('|')})+`, 'g'), '');\n\t}\n\n\tif( ['both', 'right'].includes(from) ){\n\t\tsubject = subject.replace(new RegExp(`(${characters.join('|')})+$`, 'g'), '');\n\t}\n\n\treturn subject;\n}\n\n\n\n/**\n * @namespace Strings:concat\n */\n\n/**\n * Simply concatenates strings with a glue part using array.join in a handy notation.\n * You can also provide arguments to glue as a prepared array as the second parameter,\n * in that case other parameters will be ignored.\n *\n * @param {?String} [glue=''] - the separator to use between single strings\n * @param {?String[]} strings - list of strings to concatenate, either comma-separated or as single array\n * @returns {String} the concatenated string\n *\n * @memberof Strings:concat\n * @alias concat\n * @example\n * const finalCountdown = concat(' ... ', 10, 9, 8, 7, 6, '5', '4', '3', '2', '1', 'ZERO!');\n * const finalCountdown = concat(' ... ', [10, 9, 8, 7, 6, '5', '4', '3', '2', '1', 'ZERO!']);\n */\nexport function concat(glue='', ...strings){\n\tglue = orDefault(glue, '', 'str');\n\n\tif( (strings.length > 0) && isArray(strings[0]) ){\n\t\treturn strings[0].join(glue);\n\t} else {\n\t\treturn strings.join(glue);\n\t}\n}\n\n\n\n/**\n * @namespace Strings:format\n */\n\n/**\n * This is a pythonesque string format implementation.\n * Apply formatted values to a string template, in which replacements are marked with curly braces.\n *\n * Display literal curly brace with {{ and }}.\n *\n * Unknown keys/indexes will be ignored.\n *\n * This solution is adapted from:\n * https://github.com/davidchambers/string-format\n *\n * @param {String} template -\n * @param {(String[]|Object)} replacements - arguments to insert into template, either as a dictionary, an array or a parameter sequence\n * @throws general exception on syntax errors\n * @returns {String} the formatted string\n *\n * @memberof Strings:format\n * @alias format\n * @example\n * format('An elephant is {times:float(0.00)} times smarter than a {animal}', {times : 5.5555, animal : 'lion'})\n * => 'An elephant is 5.56 times smarter than a lion'\n * format('{0}{0}{0} ... {{BATMAN!}}', 'Nana')\n * => 'NanaNanaNana ... {BATMAN!}'\n * format('{} {} {} starts the alphabet.', 'A', 'B', 'C')\n * => 'A B C starts the alphabet.'\n * format('{0:int}, {1:int}, {2:int}: details are for wankers', '1a', 2.222, 3)\n * => '1, 2, 3: details are for wankers'\n */\nexport function format(template, ...replacements){\n\ttemplate = `${template}`;\n\n\tlet\n\t\tidx = 0,\n\t\texplicit = false,\n\t\timplicit = false\n\t;\n\n\tconst fResolve = function(object, key){\n\t\tconst value = object[key];\n\n\t\tif( isFunction(value) ){\n\t\t\treturn value.call(object);\n\t\t} else {\n\t\t\treturn value;\n\t\t}\n\t};\n\n\tconst fLookup = function(object, key){\n\t\tif( !/^(\\d+)([.]|$)/.test(key) ){\n\t\t\tkey = `0.${key}`;\n\t\t}\n\n\t\tlet match = /(.+?)[.](.+)/.exec(key);\n\t\twhile( match ){\n\t\t\tobject = fResolve(object, match[1]);\n\t\t\tkey = match[2];\n\t\t\tmatch = /(.+?)[.](.+)/.exec(key);\n\t\t}\n\n\t\treturn fResolve(object, key);\n\t};\n\n\tconst formatters = {\n\t\tint(value, radix){\n\t\t\tradix = orDefault(radix, 10, 'int');\n\t\t\tconst res = parseInt(value, radix);\n\t\t\treturn !isNaN(res) ? `${res}` : '';\n\t\t},\n\t\tfloat(value, format){\n\t\t\tformat = orDefault(format, null, 'str');\n\n\t\t\tlet res = null;\n\n\t\t\tif( hasValue(format) ){\n\t\t\t\tlet precision = 0;\n\n\t\t\t\ttry {\n\t\t\t\t\tprecision = format.split('.')[1].length;\n\t\t\t\t} catch(ex) {\n\t\t\t\t\tthrow new Error(`${MODULE_NAME}:format | float precision arg malformed`);\n\t\t\t\t}\n\n\t\t\t\tres = round(value, precision)\n\t\t\t} else {\n\t\t\t\tres = parseFloat(value);\n\t\t\t}\n\n\t\t\treturn !isNaN(res) ? `${res}` : '';\n\t\t}\n\t};\n\n\treturn template.replace(/([{}])\\1|[{](.*?)(?:!(.+?))?[}]/g, function(match, literal, key){\n\t\tlet\n\t\t\tref = null,\n\t\t\tvalue = '',\n\t\t\tformatter = function(value){ return value; },\n\t\t\tformatterArg = null\n\t\t;\n\n\t\tif( literal ){\n\t\t\treturn literal;\n\t\t}\n\n\t\tif( key.length ){\n\t\t\tconst keyParts = key.split(':');\n\n\t\t\tif( keyParts.length > 1 ){\n\t\t\t\tkey = keyParts[0];\n\n\t\t\t\tconst\n\t\t\t\t\tformatterParts = keyParts[1].split('('),\n\t\t\t\t\tformatterName = formatterParts[0]\n\t\t\t\t;\n\n\t\t\t\tif( formatterParts.length > 1 ){\n\t\t\t\t\tformatterArg = formatterParts[1].replace(')', '');\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tformatter = formatters[formatterName];\n\t\t\t\t} catch(ex) {\n\t\t\t\t\tthrow new Error(`${MODULE_NAME}:format | unknown formatter`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif( implicit ){\n\t\t\t\tthrow new Error(`${MODULE_NAME}:format | cannot switch from implicit to explicit numbering`);\n\t\t\t} else {\n\t\t\t\texplicit = true;\n\t\t\t}\n\n\t\t\tref = fLookup(replacements, key);\n\t\t\tvalue = orDefault(ref, '');\n\t\t} else {\n\t\t\tif( explicit ){\n\t\t\t\tthrow new Error (`${MODULE_NAME}:format | cannot switch from explicit to implicit numbering`);\n\t\t\t} else {\n\t\t\t\timplicit = true;\n\t\t\t}\n\n\t\t\tref = replacements[idx];\n\t\t\tvalue = orDefault(ref, '');\n\t\t\tidx++;\n\t\t}\n\n\t\treturn formatter(value, formatterArg);\n\t});\n}\n\n\n\n/**\n * @namespace Strings:slugify\n */\n\n/**\n * Slugifies a text for use in a URL or id/class/attribute.\n * Transforms accented characters to non-accented ones.\n * Throws out everything except basic A-Z characters and numbers after replacements have taken place.\n * Provide own replacements, supplementing or overriding the default replacement map to cover special cases\n * (will take precedence over the default map).\n *\n * @param {String} text - the text to slugify\n * @param {?String} [additionalMap=null] - optional character map to supplement/override the default map, having the form {'[search character]' : '[replacement]', ...}\n * @param {?Boolean} [toLowerCase=true] - set this to false, to keep character casing\n * @returns {String} the slugified string\n *\n * @memberof Strings:slugify\n * @alias slugify\n * @example\n * slugify('This is a cömplicated ßtring for URLs!')\n * => 'this-is-a-coemplicated-sstring-for-urls'\n */\nexport function slugify(text, additionalMap=null, toLowerCase=true){\n\tif( !isPlainObject(additionalMap) ){\n\t\tadditionalMap = {};\n\t}\n\ttoLowerCase = orDefault(toLowerCase, true, 'bool');\n\n\ttext = `${text}`;\n\tif( toLowerCase ){\n\t\ttext = text.toLowerCase();\n\t}\n\n\treturn text\n\t\t.replace(\n\t\t\t/[^\\-]/g, // replace accented chars with plain ones via map and/or apply additionalMap\n\t\t\tchar => additionalMap[char] ?? SLUGIFY_LATINMAP[char] ?? char\n\t\t)\n\t\t.replace(/\\s+|_+/g, '-') // replace spaces and underscores with \"-\"\n\t\t.replace(/[^\\w\\-]+/g, '') // remove all non-word, non-dash chars\n\t\t.replace(/--+/g, '-') // replace multiple \"-\" with single \"-\"\n\t\t.replace(/^-+/, '') // trim \"-\" from start of text\n\t\t.replace(/-+$/, '') // trim \"-\" from end of text\n\t;\n}\n\n\n\n/**\n * @namespace Strings:maskForSelector\n */\n\n/**\n * Masks all selector-special-characters, to allow selecting elements with special characters in selector using\n * querySelector and querySelectorAll (also works for jQuery and Cash).\n *\n * @param {String} str - the string to mask for use in a selector\n * @returns {String} the masked string\n *\n * @memberof Strings:maskForSelector\n * @alias maskForSelector\n * @example\n * document.querySelector(`#element_${maskForSelector(elementName)}`).classList.remove('test');\n */\nexport function maskForSelector(str){\n\treturn `${str}`.replace(/([#;&,.+*~':\"!^$\\[\\]()=>|\\/@])/g, '\\\\$&');\n}\n\n\n\n/**\n * @namespace Strings:maskForRegEx\n */\n\n/**\n * Masks all regex special characters, to test or match a string using a regex, that contains\n * characters used in regexes themselves.\n *\n * @param {String} str - the string to mask for use in a regexp\n * @returns {String} the masked string\n *\n * @memberof Strings:maskForRegEx\n * @alias maskForRegEx\n * @example\n * if( (new RegExp(`^${maskForRegEx(arbitraryString)}$')).test('abc') ){\n * alert('are identical!');\n * }\n */\nexport function maskForRegEx(str){\n\treturn `${str}`.replace(/([\\-\\[\\]\\/{}()*+?.\\\\^$|])/g, \"\\\\$&\");\n}\n\n\n\n/**\n * @namespace Strings:maskForHtml\n */\n\n/**\n * Masks a string possibly containing reserved HTML chars for HTML output as is\n * (so a < actually reads on the page).\n *\n * Only replaces critical chars like <>& with entities, but\n * keeps non-critical unicode chars like »/.\n *\n * @param {String} text - the string to mask for use in HTML\n * @returns {String} the masked string\n *\n * @memberof Strings:maskForHtml\n * @alias maskForHtml\n * @see unmaskFromHtml\n * @example\n * maskForHtml('&;üäöÜÄÖß– »')\n * => '</>&;üäöÜÄÖß– »'\n */\nexport function maskForHtml(text){\n\tconst escape = document.createElement('textarea');\n\tescape.textContent = `${text}`;\n\treturn escape.innerHTML;\n}\n\n\n\n/**\n * @namespace Strings:unmaskFromHtml\n */\n\n/**\n * Replaces entities in a html-masked string with the vanilla characters\n * thereby returning a real HTML string, which could, for example, be used\n * to construct new elements with tag markup.\n *\n * @param {String} html - the string to unmask entities in\n * @returns {String} the unmasked string\n *\n * @memberof Strings:unmaskFromHtml\n * @alias unmaskFromHtml\n * @see maskForHtml\n * @example\n * unmaskFromHtml('</>&;üäöÜÄÖß– »')\n * => '&;üäöÜÄÖß– »'\n */\nexport function unmaskFromHtml(html){\n\tconst escape = document.createElement('textarea');\n\tescape.innerHTML = `${html}`;\n\treturn escape.textContent;\n}\n"]} \ No newline at end of file +{"version":3,"file":"strings.js","names":["MODULE_NAME","isFunction","isArray","orDefault","isNaN","hasValue","isPlainObject","round","SLUGIFY_LATINMAP","replace","subject","search","concat","tmp","forEach","searchTerm","index","length","undefined","String","prototype","replaceAll","split","join","truncate","maxLength","suffix","Error","slice","pad","paddingCharacter","expectedLength","from","includes","difference","i","trim","characters","map","char","RegExp","glue","strings","format","template","replacements","idx","explicit","implicit","fResolve","object","key","value","call","formatters","int","radix","res","parseInt","float","precision","ex","parseFloat","match","literal","ref","formatter","formatterArg","keyParts","formatterParts","formatterName","test","exec","fLookup","slugify","text","additionalMap","toLowerCase","maskForSelector","str","maskForRegEx","maskForHtml","escape","document","createElement","textContent","innerHTML","unmaskFromHtml","html"],"sources":["strings.js"],"mappings":";;;AAQA,MAAMA,YAAc,iBAMZC,WAAYC,QAASC,UAAWC,MAAOC,SAAUC,cAAeC,UAAY,aAMpF,MAAMC,iBAAmB,CACxB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,IACrG,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC/G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAC5G,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAC3G,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAC/G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC7G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC5G,IAAI,KAAK,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAC9G,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI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","ignoreList":[],"sourcesContent":["/*!\n * Module Strings\n */\n\n/**\n * @namespace Strings\n */\n\nconst MODULE_NAME = 'Strings';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {isFunction, isArray, orDefault, isNaN, hasValue, isPlainObject, round} from './basic.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst SLUGIFY_LATINMAP = {\n\t'Á':'A','Ă':'A','Ắ':'A','Ặ':'A','Ằ':'A','Ẳ':'A','Ẵ':'A','Ǎ':'A','Â':'A','Ấ':'A','Ậ':'A','Ầ':'A','Ẩ':'A','Ẫ':'A',\n\t'Ä':'Ae','Ǟ':'A','Ȧ':'A','Ǡ':'A','Ạ':'A','Ȁ':'A','À':'A','Ả':'A','Ȃ':'A','Ā':'A','Ą':'A','Å':'A','Ǻ':'A','Ḁ':'A',\n\t'Ⱥ':'A','Ã':'A','Ꜳ':'AA','Æ':'AE','Ǽ':'AE','Ǣ':'AE','Ꜵ':'AO','Ꜷ':'AU','Ꜹ':'AV','Ꜻ':'AV','Ꜽ':'AY','Ḃ':'B',\n\t'Ḅ':'B','Ɓ':'B','Ḇ':'B','Ƀ':'B','Ƃ':'B','Ć':'C','Č':'C','Ç':'C','Ḉ':'C','Ĉ':'C','Ċ':'C','Ƈ':'C','Ȼ':'C','Ď':'D',\n\t'Ḑ':'D','Ḓ':'D','Ḋ':'D','Ḍ':'D','Ɗ':'D','Ḏ':'D','Dz':'D','Dž':'D','Đ':'D','Ƌ':'D','DZ':'DZ','DŽ':'DZ','É':'E','Ĕ':'E',\n\t'Ě':'E','Ȩ':'E','Ḝ':'E','Ê':'E','Ế':'E','Ệ':'E','Ề':'E','Ể':'E','Ễ':'E','Ḙ':'E','Ë':'E','Ė':'E','Ẹ':'E','Ȅ':'E',\n\t'È':'E','Ẻ':'E','Ȇ':'E','Ē':'E','Ḗ':'E','Ḕ':'E','Ę':'E','Ɇ':'E','Ẽ':'E','Ḛ':'E','Ꝫ':'ET','Ḟ':'F','Ƒ':'F','Ǵ':'G',\n\t'Ğ':'G','Ǧ':'G','Ģ':'G','Ĝ':'G','Ġ':'G','Ɠ':'G','Ḡ':'G','Ǥ':'G','Ḫ':'H','Ȟ':'H','Ḩ':'H','Ĥ':'H','Ⱨ':'H','Ḧ':'H',\n\t'Ḣ':'H','Ḥ':'H','Ħ':'H','Í':'I','Ĭ':'I','Ǐ':'I','Î':'I','Ï':'I','Ḯ':'I','İ':'I','Ị':'I','Ȉ':'I','Ì':'I','Ỉ':'I',\n\t'Ȋ':'I','Ī':'I','Į':'I','Ɨ':'I','Ĩ':'I','Ḭ':'I','Ꝺ':'D','Ꝼ':'F','Ᵹ':'G','Ꞃ':'R','Ꞅ':'S','Ꞇ':'T','Ꝭ':'IS','Ĵ':'J',\n\t'Ɉ':'J','Ḱ':'K','Ǩ':'K','Ķ':'K','Ⱪ':'K','Ꝃ':'K','Ḳ':'K','Ƙ':'K','Ḵ':'K','Ꝁ':'K','Ꝅ':'K','Ĺ':'L','Ƚ':'L','Ľ':'L',\n\t'Ļ':'L','Ḽ':'L','Ḷ':'L','Ḹ':'L','Ⱡ':'L','Ꝉ':'L','Ḻ':'L','Ŀ':'L','Ɫ':'L','Lj':'L','Ł':'L','LJ':'LJ','Ḿ':'M','Ṁ':'M',\n\t'Ṃ':'M','Ɱ':'M','Ń':'N','Ň':'N','Ņ':'N','Ṋ':'N','Ṅ':'N','Ṇ':'N','Ǹ':'N','Ɲ':'N','Ṉ':'N','Ƞ':'N','Nj':'N','Ñ':'N',\n\t'NJ':'NJ','Ó':'O','Ŏ':'O','Ǒ':'O','Ô':'O','Ố':'O','Ộ':'O','Ồ':'O','Ổ':'O','Ỗ':'O','Ö':'Oe','Ȫ':'O','Ȯ':'O','Ȱ':'O',\n\t'Ọ':'O','Ő':'O','Ȍ':'O','Ò':'O','Ỏ':'O','Ơ':'O','Ớ':'O','Ợ':'O','Ờ':'O','Ở':'O','Ỡ':'O','Ȏ':'O','Ꝋ':'O','Ꝍ':'O',\n\t'Ō':'O','Ṓ':'O','Ṑ':'O','Ɵ':'O','Ǫ':'O','Ǭ':'O','Ø':'O','Ǿ':'O','Õ':'O','Ṍ':'O','Ṏ':'O','Ȭ':'O','Ƣ':'OI','Ꝏ':'OO',\n\t'Ɛ':'E','Ɔ':'O','Ȣ':'OU','Ṕ':'P','Ṗ':'P','Ꝓ':'P','Ƥ':'P','Ꝕ':'P','Ᵽ':'P','Ꝑ':'P','Ꝙ':'Q','Ꝗ':'Q','Ŕ':'R','Ř':'R',\n\t'Ŗ':'R','Ṙ':'R','Ṛ':'R','Ṝ':'R','Ȑ':'R','Ȓ':'R','Ṟ':'R','Ɍ':'R','Ɽ':'R','Ꜿ':'C','Ǝ':'E','Ś':'S','Ṥ':'S','Š':'S',\n\t'Ṧ':'S','Ş':'S','Ŝ':'S','Ș':'S','Ṡ':'S','Ṣ':'S','Ṩ':'S','ẞ':'Ss','Ť':'T','Ţ':'T','Ṱ':'T','Ț':'T','Ⱦ':'T','Ṫ':'T',\n\t'Ṭ':'T','Ƭ':'T','Ṯ':'T','Ʈ':'T','Ŧ':'T','Ɐ':'A','Ꞁ':'L','Ɯ':'M','Ʌ':'V','Ꜩ':'TZ','Ú':'U','Ŭ':'U','Ǔ':'U','Û':'U',\n\t'Ṷ':'U','Ü':'Ue','Ǘ':'U','Ǚ':'U','Ǜ':'U','Ǖ':'U','Ṳ':'U','Ụ':'U','Ű':'U','Ȕ':'U','Ù':'U','Ủ':'U','Ư':'U','Ứ':'U',\n\t'Ự':'U','Ừ':'U','Ử':'U','Ữ':'U','Ȗ':'U','Ū':'U','Ṻ':'U','Ų':'U','Ů':'U','Ũ':'U','Ṹ':'U','Ṵ':'U','Ꝟ':'V','Ṿ':'V',\n\t'Ʋ':'V','Ṽ':'V','Ꝡ':'VY','Ẃ':'W','Ŵ':'W','Ẅ':'W','Ẇ':'W','Ẉ':'W','Ẁ':'W','Ⱳ':'W','Ẍ':'X','Ẋ':'X','Ý':'Y','Ŷ':'Y',\n\t'Ÿ':'Y','Ẏ':'Y','Ỵ':'Y','Ỳ':'Y','Ƴ':'Y','Ỷ':'Y','Ỿ':'Y','Ȳ':'Y','Ɏ':'Y','Ỹ':'Y','Ź':'Z','Ž':'Z','Ẑ':'Z','Ⱬ':'Z',\n\t'Ż':'Z','Ẓ':'Z','Ȥ':'Z','Ẕ':'Z','Ƶ':'Z','IJ':'IJ','Œ':'OE','ᴀ':'A','ᴁ':'AE','ʙ':'B','ᴃ':'B','ᴄ':'C','ᴅ':'D','ᴇ':'E',\n\t'ꜰ':'F','ɢ':'G','ʛ':'G','ʜ':'H','ɪ':'I','ʁ':'R','ᴊ':'J','ᴋ':'K','ʟ':'L','ᴌ':'L','ᴍ':'M','ɴ':'N','ᴏ':'O','ɶ':'OE',\n\t'ᴐ':'O','ᴕ':'OU','ᴘ':'P','ʀ':'R','ᴎ':'N','ᴙ':'R','ꜱ':'S','ᴛ':'T','ⱻ':'E','ᴚ':'R','ᴜ':'U','ᴠ':'V','ᴡ':'W','ʏ':'Y',\n\t'ᴢ':'Z','á':'a','ă':'a','ắ':'a','ặ':'a','ằ':'a','ẳ':'a','ẵ':'a','ǎ':'a','â':'a','ấ':'a','ậ':'a','ầ':'a','ẩ':'a',\n\t'ẫ':'a','ä':'ae','ǟ':'a','ȧ':'a','ǡ':'a','ạ':'a','ȁ':'a','à':'a','ả':'a','ȃ':'a','ā':'a','ą':'a','ᶏ':'a','ẚ':'a',\n\t'å':'a','ǻ':'a','ḁ':'a','ⱥ':'a','ã':'a','ꜳ':'aa','æ':'ae','ǽ':'ae','ǣ':'ae','ꜵ':'ao','ꜷ':'au','ꜹ':'av','ꜻ':'av',\n\t'ꜽ':'ay','ḃ':'b','ḅ':'b','ɓ':'b','ḇ':'b','ᵬ':'b','ᶀ':'b','ƀ':'b','ƃ':'b','ɵ':'o','ć':'c','č':'c','ç':'c','ḉ':'c',\n\t'ĉ':'c','ɕ':'c','ċ':'c','ƈ':'c','ȼ':'c','ď':'d','ḑ':'d','ḓ':'d','ȡ':'d','ḋ':'d','ḍ':'d','ɗ':'d','ᶑ':'d','ḏ':'d',\n\t'ᵭ':'d','ᶁ':'d','đ':'d','ɖ':'d','ƌ':'d','ı':'i','ȷ':'j','ɟ':'j','ʄ':'j','dz':'dz','dž':'dz','é':'e','ĕ':'e','ě':'e',\n\t'ȩ':'e','ḝ':'e','ê':'e','ế':'e','ệ':'e','ề':'e','ể':'e','ễ':'e','ḙ':'e','ë':'e','ė':'e','ẹ':'e','ȅ':'e','è':'e',\n\t'ẻ':'e','ȇ':'e','ē':'e','ḗ':'e','ḕ':'e','ⱸ':'e','ę':'e','ᶒ':'e','ɇ':'e','ẽ':'e','ḛ':'e','ꝫ':'et','ḟ':'f','ƒ':'f',\n\t'ᵮ':'f','ᶂ':'f','ǵ':'g','ğ':'g','ǧ':'g','ģ':'g','ĝ':'g','ġ':'g','ɠ':'g','ḡ':'g','ᶃ':'g','ǥ':'g','ḫ':'h','ȟ':'h',\n\t'ḩ':'h','ĥ':'h','ⱨ':'h','ḧ':'h','ḣ':'h','ḥ':'h','ɦ':'h','ẖ':'h','ħ':'h','ƕ':'hv','í':'i','ĭ':'i','ǐ':'i','î':'i',\n\t'ï':'i','ḯ':'i','ị':'i','ȉ':'i','ì':'i','ỉ':'i','ȋ':'i','ī':'i','į':'i','ᶖ':'i','ɨ':'i','ĩ':'i','ḭ':'i','ꝺ':'d',\n\t'ꝼ':'f','ᵹ':'g','ꞃ':'r','ꞅ':'s','ꞇ':'t','ꝭ':'is','ǰ':'j','ĵ':'j','ʝ':'j','ɉ':'j','ḱ':'k','ǩ':'k','ķ':'k','ⱪ':'k',\n\t'ꝃ':'k','ḳ':'k','ƙ':'k','ḵ':'k','ᶄ':'k','ꝁ':'k','ꝅ':'k','ĺ':'l','ƚ':'l','ɬ':'l','ľ':'l','ļ':'l','ḽ':'l','ȴ':'l',\n\t'ḷ':'l','ḹ':'l','ⱡ':'l','ꝉ':'l','ḻ':'l','ŀ':'l','ɫ':'l','ᶅ':'l','ɭ':'l','ł':'l','lj':'lj','ſ':'s','ẜ':'s','ẛ':'s',\n\t'ẝ':'s','ḿ':'m','ṁ':'m','ṃ':'m','ɱ':'m','ᵯ':'m','ᶆ':'m','ń':'n','ň':'n','ņ':'n','ṋ':'n','ȵ':'n','ṅ':'n','ṇ':'n',\n\t'ǹ':'n','ɲ':'n','ṉ':'n','ƞ':'n','ᵰ':'n','ᶇ':'n','ɳ':'n','ñ':'n','nj':'nj','ó':'o','ŏ':'o','ǒ':'o','ô':'o','ố':'o',\n\t'ộ':'o','ồ':'o','ổ':'o','ỗ':'o','ö':'oe','ȫ':'o','ȯ':'o','ȱ':'o','ọ':'o','ő':'o','ȍ':'o','ò':'o','ỏ':'o','ơ':'o',\n\t'ớ':'o','ợ':'o','ờ':'o','ở':'o','ỡ':'o','ȏ':'o','ꝋ':'o','ꝍ':'o','ⱺ':'o','ō':'o','ṓ':'o','ṑ':'o','ǫ':'o','ǭ':'o',\n\t'ø':'o','ǿ':'o','õ':'o','ṍ':'o','ṏ':'o','ȭ':'o','ƣ':'oi','ꝏ':'oo','ɛ':'e','ᶓ':'e','ɔ':'o','ᶗ':'o','ȣ':'ou','ṕ':'p',\n\t'ṗ':'p','ꝓ':'p','ƥ':'p','ᵱ':'p','ᶈ':'p','ꝕ':'p','ᵽ':'p','ꝑ':'p','ꝙ':'q','ʠ':'q','ɋ':'q','ꝗ':'q','ŕ':'r','ř':'r',\n\t'ŗ':'r','ṙ':'r','ṛ':'r','ṝ':'r','ȑ':'r','ɾ':'r','ᵳ':'r','ȓ':'r','ṟ':'r','ɼ':'r','ᵲ':'r','ᶉ':'r','ɍ':'r','ɽ':'r',\n\t'ↄ':'c','ꜿ':'c','ɘ':'e','ɿ':'r','ś':'s','ṥ':'s','š':'s','ṧ':'s','ş':'s','ŝ':'s','ș':'s','ṡ':'s','ṣ':'s','ṩ':'s',\n\t'ʂ':'s','ᵴ':'s','ᶊ':'s','ȿ':'s','ɡ':'g','ß':'ss','ᴑ':'o','ᴓ':'o','ᴝ':'u','ť':'t','ţ':'t','ṱ':'t','ț':'t','ȶ':'t',\n\t'ẗ':'t','ⱦ':'t','ṫ':'t','ṭ':'t','ƭ':'t','ṯ':'t','ᵵ':'t','ƫ':'t','ʈ':'t','ŧ':'t','ᵺ':'th','ɐ':'a','ᴂ':'ae','ǝ':'e',\n\t'ᵷ':'g','ɥ':'h','ʮ':'h','ʯ':'h','ᴉ':'i','ʞ':'k','ꞁ':'l','ɯ':'m','ɰ':'m','ᴔ':'oe','ɹ':'r','ɻ':'r','ɺ':'r','ⱹ':'r',\n\t'ʇ':'t','ʌ':'v','ʍ':'w','ʎ':'y','ꜩ':'tz','ú':'u','ŭ':'u','ǔ':'u','û':'u','ṷ':'u','ü':'ue','ǘ':'u','ǚ':'u','ǜ':'u',\n\t'ǖ':'u','ṳ':'u','ụ':'u','ű':'u','ȕ':'u','ù':'u','ủ':'u','ư':'u','ứ':'u','ự':'u','ừ':'u','ử':'u','ữ':'u','ȗ':'u',\n\t'ū':'u','ṻ':'u','ų':'u','ᶙ':'u','ů':'u','ũ':'u','ṹ':'u','ṵ':'u','ᵫ':'ue','ꝸ':'um','ⱴ':'v','ꝟ':'v','ṿ':'v','ʋ':'v',\n\t'ᶌ':'v','ⱱ':'v','ṽ':'v','ꝡ':'vy','ẃ':'w','ŵ':'w','ẅ':'w','ẇ':'w','ẉ':'w','ẁ':'w','ⱳ':'w','ẘ':'w','ẍ':'x','ẋ':'x',\n\t'ᶍ':'x','ý':'y','ŷ':'y','ÿ':'y','ẏ':'y','ỵ':'y','ỳ':'y','ƴ':'y','ỷ':'y','ỿ':'y','ȳ':'y','ẙ':'y','ɏ':'y','ỹ':'y',\n\t'ź':'z','ž':'z','ẑ':'z','ʑ':'z','ⱬ':'z','ż':'z','ẓ':'z','ȥ':'z','ẕ':'z','ᵶ':'z','ᶎ':'z','ʐ':'z','ƶ':'z','ɀ':'z',\n\t'ff':'ff','ffi':'ffi','ffl':'ffl','fi':'fi','fl':'fl','ij':'ij','œ':'oe','st':'st','ₐ':'a','ₑ':'e','ᵢ':'i','ⱼ':'j','ₒ':'o',\n\t'ᵣ':'r','ᵤ':'u','ᵥ':'v','ₓ':'x'\n};\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Strings:replace\n */\n\n/**\n * Offers similar functionality to PHP's str_replace or ES2021's replaceAll and avoids RegExps for this task.\n * Replaces occurrences of search in subject with replace. search and replace may be arrays.\n * If search is an array and replace is a string, all phrases in the array will be replaced with one string.\n * If replace is an array itself, phrases and replacements are matched by index.\n * Missing replacements are treated as an empty string (for example: if your array lengths do not match).\n *\n * Uses String.prototype.replaceAll internally, if available.\n *\n * @param {String} subject - the string to replace in\n * @param {(String|String[])} search - the string(s) to replace\n * @param {String|String[]} replace - the string(s) to replace the search string(s)\n * @returns {String} the modified string\n *\n * @memberof Strings:replace\n * @alias replace\n * @example\n * const sanitizedString = replace([':', '#', '-'], '_', exampleString);\n */\nexport function replace(subject, search, replace){\n\tsubject = `${subject}`;\n\tsearch = [].concat(search);\n\treplace = [].concat(replace);\n\n\tlet tmp = '';\n\n\tsearch.forEach((searchTerm, index) => {\n\t\ttmp = (replace.length > 1) ? ((replace[index] !== undefined) ? replace[index] : '') : replace[0];\n\n\t\tif( isFunction(String.prototype.replaceAll) ){\n\t\t\tsubject = subject.replaceAll(`${searchTerm}`, `${tmp}`);\n\t\t} else {\n\t\t\tsubject = subject.split(`${searchTerm}`).join(`${tmp}`);\n\t\t}\n\t});\n\n\treturn subject;\n}\n\n\n\n/**\n * @namespace Strings:truncate\n */\n\n/**\n * Truncates a given string after a certain number of characters to enforce length restrictions.\n *\n * @param {String} subject - the string to check and truncate\n * @param {?Number} [maxLength=30] - the maximum allowed character length for the string\n * @param {?String} [suffix='...'] - the trailing string to end a truncated string with\n * @throws error if suffix length is bigger than defined maxLength\n * @returns {String} the (truncated) subject\n *\n * @memberof Strings:truncate\n * @alias truncate\n * @example\n * const truncatedString = truncate(string, 10, '...');\n */\nexport function truncate(subject, maxLength=30, suffix='...'){\n\tsubject = `${subject}`;\n\tmaxLength = orDefault(maxLength, 30, 'int');\n\tsuffix = orDefault(suffix, '...', 'str');\n\n\tif( suffix.length > maxLength ){\n\t\tthrow new Error(`${MODULE_NAME}:truncate | suffix cannot be longer than maxLength`);\n\t}\n\n\tif( subject.length > maxLength ){\n\t\tsubject = `${subject.slice(0, maxLength - suffix.length)}${suffix}`;\n\t}\n\n\treturn subject;\n}\n\n\n/**\n * @namespace Strings:pad\n */\n\n/**\n * Adds characters to strings, which are not yet of a defined expected length.\n *\n * A usual use-case for this would be, to add zeroes to a number, to fit a format like ISO dates.\n *\n * @param {String} subject - the string to pad\n * @param {String} paddingCharacter - the character to use for padding, only first character is used\n * @param {Number} expectedLength - the number of characters, the result has to have at least\n * @param {String} [from='left'] - the number of characters, the result has to have at least\n * @returns {String} the padded value, will always be cast to a string\n *\n * @memberof Strings:pad\n * @alias pad\n * @example\n * pad(1, '0', 4, 'right')\n * => '1000'\n */\nexport function pad(subject, paddingCharacter, expectedLength, from='left'){\n\tsubject = `${subject}`;\n\tpaddingCharacter = `${paddingCharacter}`[0];\n\texpectedLength = orDefault(expectedLength, 2, 'int');\n\tfrom = ['left', 'right'].includes(`${from}`) ? `${from}` : 'left';\n\n\tconst difference = expectedLength - subject.length;\n\tif( difference > 0 ){\n\t\tfor( let i = 0; i < difference; i++ ){\n\t\t\tsubject = (from === 'right') ? `${subject}${paddingCharacter}` : `${paddingCharacter}${subject}`;\n\t\t}\n\t}\n\n\treturn subject;\n}\n\n\n/**\n * @namespace Strings:trim\n */\n\n/**\n * Removes whitespace or characters from the beginning and the end (or just one side) of a string.\n *\n * This is usually used to sanitize values and remove leading or trailing whitespace in user input.\n *\n * @param {String} subject - the string to trim\n * @param {?String|Array} [characters=null] - defines which character(s) to trim; will trim whitespace if nullish (or '\\\\s'); if you want to trim whitespace and something else, define an array including a nullish value (or '\\\\s') as well as the other characters; this parameter uses regex definitions\n * @param {?String} [from='both'] - the side(s) from which to trim, either \"both\", \"left\" or \"right\"\n * @returns {String} the trimmed subject\n *\n * @memberof Strings:trim\n * @alias trim\n * @example\n * trim(' foo ')\n * => 'foo'\n * trim(' foo ', null, 'right')\n * => ' foo'\n * trim('abcdefghijklmnopqrstuvwxyz', ['[a-f]', '[u-z]', 'l'], 'both')\n * => 'ghijklmnopqrst'\n */\nexport function trim(subject, characters=null, from='both'){\n\tsubject = `${subject}`;\n\tcharacters = [].concat(characters).map(char => !!char ? `${char}` : '\\\\s');\n\tfrom = ['both', 'left', 'right'].includes(`${from}`) ? `${from}` : 'both';\n\n\tif( ['both', 'left'].includes(from) ){\n\t\tsubject = subject.replace(new RegExp(`^(${characters.join('|')})+`, 'g'), '');\n\t}\n\n\tif( ['both', 'right'].includes(from) ){\n\t\tsubject = subject.replace(new RegExp(`(${characters.join('|')})+$`, 'g'), '');\n\t}\n\n\treturn subject;\n}\n\n\n\n/**\n * @namespace Strings:concat\n */\n\n/**\n * Simply concatenates strings with a glue part using array.join in a handy notation.\n * You can also provide arguments to glue as a prepared array as the second parameter,\n * in that case other parameters will be ignored.\n *\n * @param {?String} [glue=''] - the separator to use between single strings\n * @param {?String[]} strings - list of strings to concatenate, either comma-separated or as single array\n * @returns {String} the concatenated string\n *\n * @memberof Strings:concat\n * @alias concat\n * @example\n * const finalCountdown = concat(' ... ', 10, 9, 8, 7, 6, '5', '4', '3', '2', '1', 'ZERO!');\n * const finalCountdown = concat(' ... ', [10, 9, 8, 7, 6, '5', '4', '3', '2', '1', 'ZERO!']);\n */\nexport function concat(glue='', ...strings){\n\tglue = orDefault(glue, '', 'str');\n\n\tif( (strings.length > 0) && isArray(strings[0]) ){\n\t\treturn strings[0].join(glue);\n\t} else {\n\t\treturn strings.join(glue);\n\t}\n}\n\n\n\n/**\n * @namespace Strings:format\n */\n\n/**\n * This is a pythonesque string format implementation.\n * Apply formatted values to a string template, in which replacements are marked with curly braces.\n *\n * Display literal curly brace with {{ and }}.\n *\n * Unknown keys/indexes will be ignored.\n *\n * This solution is adapted from:\n * https://github.com/davidchambers/string-format\n *\n * @param {String} template -\n * @param {(String[]|Object)} replacements - arguments to insert into template, either as a dictionary, an array or a parameter sequence\n * @throws general exception on syntax errors\n * @returns {String} the formatted string\n *\n * @memberof Strings:format\n * @alias format\n * @example\n * format('An elephant is {times:float(0.00)} times smarter than a {animal}', {times : 5.5555, animal : 'lion'})\n * => 'An elephant is 5.56 times smarter than a lion'\n * format('{0}{0}{0} ... {{BATMAN!}}', 'Nana')\n * => 'NanaNanaNana ... {BATMAN!}'\n * format('{} {} {} starts the alphabet.', 'A', 'B', 'C')\n * => 'A B C starts the alphabet.'\n * format('{0:int}, {1:int}, {2:int}: details are for wankers', '1a', 2.222, 3)\n * => '1, 2, 3: details are for wankers'\n */\nexport function format(template, ...replacements){\n\ttemplate = `${template}`;\n\n\tlet\n\t\tidx = 0,\n\t\texplicit = false,\n\t\timplicit = false\n\t;\n\n\tconst fResolve = function(object, key){\n\t\tconst value = object[key];\n\n\t\tif( isFunction(value) ){\n\t\t\treturn value.call(object);\n\t\t} else {\n\t\t\treturn value;\n\t\t}\n\t};\n\n\tconst fLookup = function(object, key){\n\t\tif( !/^(\\d+)([.]|$)/.test(key) ){\n\t\t\tkey = `0.${key}`;\n\t\t}\n\n\t\tlet match = /(.+?)[.](.+)/.exec(key);\n\t\twhile( match ){\n\t\t\tobject = fResolve(object, match[1]);\n\t\t\tkey = match[2];\n\t\t\tmatch = /(.+?)[.](.+)/.exec(key);\n\t\t}\n\n\t\treturn fResolve(object, key);\n\t};\n\n\tconst formatters = {\n\t\tint(value, radix){\n\t\t\tradix = orDefault(radix, 10, 'int');\n\t\t\tconst res = parseInt(value, radix);\n\t\t\treturn !isNaN(res) ? `${res}` : '';\n\t\t},\n\t\tfloat(value, format){\n\t\t\tformat = orDefault(format, null, 'str');\n\n\t\t\tlet res = null;\n\n\t\t\tif( hasValue(format) ){\n\t\t\t\tlet precision = 0;\n\n\t\t\t\ttry {\n\t\t\t\t\tprecision = format.split('.')[1].length;\n\t\t\t\t} catch(ex) {\n\t\t\t\t\tthrow new Error(`${MODULE_NAME}:format | float precision arg malformed`);\n\t\t\t\t}\n\n\t\t\t\tres = round(value, precision)\n\t\t\t} else {\n\t\t\t\tres = parseFloat(value);\n\t\t\t}\n\n\t\t\treturn !isNaN(res) ? `${res}` : '';\n\t\t}\n\t};\n\n\treturn template.replace(/([{}])\\1|[{](.*?)(?:!(.+?))?[}]/g, function(match, literal, key){\n\t\tlet\n\t\t\tref = null,\n\t\t\tvalue = '',\n\t\t\tformatter = function(value){ return value; },\n\t\t\tformatterArg = null\n\t\t;\n\n\t\tif( literal ){\n\t\t\treturn literal;\n\t\t}\n\n\t\tif( key.length ){\n\t\t\tconst keyParts = key.split(':');\n\n\t\t\tif( keyParts.length > 1 ){\n\t\t\t\tkey = keyParts[0];\n\n\t\t\t\tconst\n\t\t\t\t\tformatterParts = keyParts[1].split('('),\n\t\t\t\t\tformatterName = formatterParts[0]\n\t\t\t\t;\n\n\t\t\t\tif( formatterParts.length > 1 ){\n\t\t\t\t\tformatterArg = formatterParts[1].replace(')', '');\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tformatter = formatters[formatterName];\n\t\t\t\t} catch(ex) {\n\t\t\t\t\tthrow new Error(`${MODULE_NAME}:format | unknown formatter`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif( implicit ){\n\t\t\t\tthrow new Error(`${MODULE_NAME}:format | cannot switch from implicit to explicit numbering`);\n\t\t\t} else {\n\t\t\t\texplicit = true;\n\t\t\t}\n\n\t\t\tref = fLookup(replacements, key);\n\t\t\tvalue = orDefault(ref, '');\n\t\t} else {\n\t\t\tif( explicit ){\n\t\t\t\tthrow new Error (`${MODULE_NAME}:format | cannot switch from explicit to implicit numbering`);\n\t\t\t} else {\n\t\t\t\timplicit = true;\n\t\t\t}\n\n\t\t\tref = replacements[idx];\n\t\t\tvalue = orDefault(ref, '');\n\t\t\tidx++;\n\t\t}\n\n\t\treturn formatter(value, formatterArg);\n\t});\n}\n\n\n\n/**\n * @namespace Strings:slugify\n */\n\n/**\n * Slugifies a text for use in a URL or id/class/attribute.\n * Transforms accented characters to non-accented ones.\n * Throws out everything except basic A-Z characters and numbers after replacements have taken place.\n * Provide own replacements, supplementing or overriding the default replacement map to cover special cases\n * (will take precedence over the default map).\n *\n * @param {String} text - the text to slugify\n * @param {?String} [additionalMap=null] - optional character map to supplement/override the default map, having the form {'[search character]' : '[replacement]', ...}\n * @param {?Boolean} [toLowerCase=true] - set this to false, to keep character casing\n * @returns {String} the slugified string\n *\n * @memberof Strings:slugify\n * @alias slugify\n * @example\n * slugify('This is a cömplicated ßtring for URLs!')\n * => 'this-is-a-coemplicated-sstring-for-urls'\n */\nexport function slugify(text, additionalMap=null, toLowerCase=true){\n\tif( !isPlainObject(additionalMap) ){\n\t\tadditionalMap = {};\n\t}\n\ttoLowerCase = orDefault(toLowerCase, true, 'bool');\n\n\ttext = `${text}`;\n\tif( toLowerCase ){\n\t\ttext = text.toLowerCase();\n\t}\n\n\treturn text\n\t\t.replace(\n\t\t\t/[^\\-]/g, // replace accented chars with plain ones via map and/or apply additionalMap\n\t\t\tchar => additionalMap[char] ?? SLUGIFY_LATINMAP[char] ?? char\n\t\t)\n\t\t.replace(/\\s+|_+/g, '-') // replace spaces and underscores with \"-\"\n\t\t.replace(/[^\\w\\-]+/g, '') // remove all non-word, non-dash chars\n\t\t.replace(/--+/g, '-') // replace multiple \"-\" with single \"-\"\n\t\t.replace(/^-+/, '') // trim \"-\" from start of text\n\t\t.replace(/-+$/, '') // trim \"-\" from end of text\n\t;\n}\n\n\n\n/**\n * @namespace Strings:maskForSelector\n */\n\n/**\n * Masks all selector-special-characters, to allow selecting elements with special characters in selector using\n * querySelector and querySelectorAll (also works for jQuery and Cash).\n *\n * @param {String} str - the string to mask for use in a selector\n * @returns {String} the masked string\n *\n * @memberof Strings:maskForSelector\n * @alias maskForSelector\n * @example\n * document.querySelector(`#element_${maskForSelector(elementName)}`).classList.remove('test');\n */\nexport function maskForSelector(str){\n\treturn `${str}`.replace(/([#;&,.+*~':\"!^$\\[\\]()=>|\\/@])/g, '\\\\$&');\n}\n\n\n\n/**\n * @namespace Strings:maskForRegEx\n */\n\n/**\n * Masks all regex special characters, to test or match a string using a regex, that contains\n * characters used in regexes themselves.\n *\n * @param {String} str - the string to mask for use in a regexp\n * @returns {String} the masked string\n *\n * @memberof Strings:maskForRegEx\n * @alias maskForRegEx\n * @example\n * if( (new RegExp(`^${maskForRegEx(arbitraryString)}$')).test('abc') ){\n * alert('are identical!');\n * }\n */\nexport function maskForRegEx(str){\n\treturn `${str}`.replace(/([\\-\\[\\]\\/{}()*+?.\\\\^$|])/g, \"\\\\$&\");\n}\n\n\n\n/**\n * @namespace Strings:maskForHtml\n */\n\n/**\n * Masks a string possibly containing reserved HTML chars for HTML output as is\n * (so a < actually reads on the page).\n *\n * Only replaces critical chars like <>& with entities, but\n * keeps non-critical unicode chars like »/.\n *\n * @param {String} text - the string to mask for use in HTML\n * @returns {String} the masked string\n *\n * @memberof Strings:maskForHtml\n * @alias maskForHtml\n * @see unmaskFromHtml\n * @example\n * maskForHtml('&;üäöÜÄÖß– »')\n * => '</>&;üäöÜÄÖß– »'\n */\nexport function maskForHtml(text){\n\tconst escape = document.createElement('textarea');\n\tescape.textContent = `${text}`;\n\treturn escape.innerHTML;\n}\n\n\n\n/**\n * @namespace Strings:unmaskFromHtml\n */\n\n/**\n * Replaces entities in a html-masked string with the vanilla characters\n * thereby returning a real HTML string, which could, for example, be used\n * to construct new elements with tag markup.\n *\n * @param {String} html - the string to unmask entities in\n * @returns {String} the unmasked string\n *\n * @memberof Strings:unmaskFromHtml\n * @alias unmaskFromHtml\n * @see maskForHtml\n * @example\n * unmaskFromHtml('</>&;üäöÜÄÖß– »')\n * => '&;üäöÜÄÖß– »'\n */\nexport function unmaskFromHtml(html){\n\tconst escape = document.createElement('textarea');\n\tescape.innerHTML = `${html}`;\n\treturn escape.textContent;\n}\n"]} \ No newline at end of file diff --git a/dist/timers.js b/dist/timers.js index 649f9a96..31c98e23 100644 --- a/dist/timers.js +++ b/dist/timers.js @@ -1,8 +1,8 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Timers */ -const MODULE_NAME="Timers";import{orDefault,isFunction,assert,hasValue,hasMembers}from"./basic.js";export function schedule(e,t,n=null){return e=orDefault(e,1,"int"),assert(e>=0,"Timers:schedule | ms must be positive"),assert(isFunction(t),"Timers:schedule | callback must be a function"),hasValue(n)&&countermand(n),{id:window.setTimeout(t,e),type:"timeout"}}export function pschedule(e,t,n=null){e=orDefault(e,1,"int"),assert(e>=0,"Timers:pschedule | ms must be positive"),assert(isFunction(t),"Timers:pschedule | callback must be a function"),hasValue(n)&&hasMembers(n,["id","type"])?(countermand(n),n.precise=!0):n={id:-1,type:"timeout",precise:!0};const i=Date.now();let o=e;const s=function(){o>0?(o-=Date.now()-i,n.id=window.setTimeout(s,o>10?o:10)):t()};return n.id=window.setTimeout(s,o),n}export function reschedule(e,t,n){return t=orDefault(t,1,"int"),assert(t>=0,"Timers:reschedule | ms must be positive"),assert(isFunction(n),"Timers:reschedule | callback must be a function"),hasValue(e)&&hasValue(e.precise)&&e.precise?pschedule(t,n,e):schedule(t,n,e)}export function loop(e,t,n=null){return e=orDefault(e,1,"int"),assert(e>=0,"Timers:loop | ms must be positive"),assert(isFunction(t),"Timers:loop | callback must be a function"),hasValue(n)&&countermand(n,!0),{id:window.setInterval(t,e),type:"interval"}}export function ploop(e,t,n=null){e=orDefault(e,1,"int"),assert(e>=0,"Timers:ploop | ms must be positive"),assert(isFunction(t),"Timers:ploop | callback must be a function"),hasValue(n)&&hasMembers(n,["id","type"])?(countermand(n,!0),n.precise=!0):n={id:-1,type:"interval",precise:!0};let i=Date.now(),o=e;const s=function(){o>0?(o-=Date.now()-i,n.id=window.setTimeout(s,o>10?o:10)):(t(),i=Date.now(),o=e,n.id=window.setTimeout(s,o))};return n.id=window.setTimeout(s,o),n}export function countermand(e,t=!1){t=orDefault(t,!1,"bool"),hasValue(e)&&(hasMembers(e,["id","type"])?"interval"===e.type?window.clearInterval(e.id):window.clearTimeout(e.id):t?window.clearInterval(e):window.clearTimeout(e))}export function requestAnimationFrame(e){assert(isFunction(e),"Timers:requestAnimationFrame | callback is no function");const t=window.requestAnimationFrame??window.webkitRequestAnimationFrame??window.mozRequestAnimationFrame??window.msRequestAnimationFrame??function(e){return schedule(16,e)};return t(e)}export function cancelAnimationFrame(e){const t=window.requestAnimationFrame??window.webkitRequestAnimationFrame??window.mozRequestAnimationFrame??window.msRequestAnimationFrame;let n=window.cancelAnimationFrame??window.mozCancelAnimationFrame;return hasValue(t)||(n=countermand),n(e)}export function waitForRepaint(e){assert(isFunction(e),"Timers:waitForRepaint | callback is no function");const t={};return t.outer=requestAnimationFrame((function(){t.inner=requestAnimationFrame(e)})),t} +const MODULE_NAME="Timers";import{orDefault,isFunction,assert,hasValue,hasMembers}from"./basic.js";export function schedule(e,t,n=null){return e=orDefault(e,1,"int"),assert(e>=0,`${MODULE_NAME}:schedule | ms must be positive`),assert(isFunction(t),`${MODULE_NAME}:schedule | callback must be a function`),hasValue(n)&&countermand(n),{id:window.setTimeout(t,e),type:"timeout"}}export function pschedule(e,t,n=null){e=orDefault(e,1,"int"),assert(e>=0,`${MODULE_NAME}:pschedule | ms must be positive`),assert(isFunction(t),`${MODULE_NAME}:pschedule | callback must be a function`),hasValue(n)&&hasMembers(n,["id","type"])?(countermand(n),n.precise=!0):n={id:-1,type:"timeout",precise:!0};const i=Date.now();let o=e;const s=function(){o>0?(o-=Date.now()-i,n.id=window.setTimeout(s,o>10?o:10)):t()};return n.id=window.setTimeout(s,o),n}export function reschedule(e,t,n){return t=orDefault(t,1,"int"),assert(t>=0,`${MODULE_NAME}:reschedule | ms must be positive`),assert(isFunction(n),`${MODULE_NAME}:reschedule | callback must be a function`),hasValue(e)&&hasValue(e.precise)&&e.precise?pschedule(t,n,e):schedule(t,n,e)}export function loop(e,t,n=null){return e=orDefault(e,1,"int"),assert(e>=0,`${MODULE_NAME}:loop | ms must be positive`),assert(isFunction(t),`${MODULE_NAME}:loop | callback must be a function`),hasValue(n)&&countermand(n,!0),{id:window.setInterval(t,e),type:"interval"}}export function ploop(e,t,n=null){e=orDefault(e,1,"int"),assert(e>=0,`${MODULE_NAME}:ploop | ms must be positive`),assert(isFunction(t),`${MODULE_NAME}:ploop | callback must be a function`),hasValue(n)&&hasMembers(n,["id","type"])?(countermand(n,!0),n.precise=!0):n={id:-1,type:"interval",precise:!0};let i=Date.now(),o=e;const s=function(){o>0?(o-=Date.now()-i,n.id=window.setTimeout(s,o>10?o:10)):(t(),i=Date.now(),o=e,n.id=window.setTimeout(s,o))};return n.id=window.setTimeout(s,o),n}export function countermand(e,t=!1){t=orDefault(t,!1,"bool"),hasValue(e)&&(hasMembers(e,["id","type"])?"interval"===e.type?window.clearInterval(e.id):window.clearTimeout(e.id):t?window.clearInterval(e):window.clearTimeout(e))}export function requestAnimationFrame(e){assert(isFunction(e),`${MODULE_NAME}:requestAnimationFrame | callback is no function`);const t=window.requestAnimationFrame??window.webkitRequestAnimationFrame??window.mozRequestAnimationFrame??window.msRequestAnimationFrame??function(e){return schedule(16,e)};return t(e)}export function cancelAnimationFrame(e){const t=window.requestAnimationFrame??window.webkitRequestAnimationFrame??window.mozRequestAnimationFrame??window.msRequestAnimationFrame;let n=window.cancelAnimationFrame??window.mozCancelAnimationFrame;return hasValue(t)||(n=countermand),n(e)}export function waitForRepaint(e){assert(isFunction(e),`${MODULE_NAME}:waitForRepaint | callback is no function`);const t={};return t.outer=requestAnimationFrame((function(){t.inner=requestAnimationFrame(e)})),t} //# sourceMappingURL=timers.js.map diff --git a/dist/timers.js.map b/dist/timers.js.map index 8fdd9beb..16f38b2e 100644 --- a/dist/timers.js.map +++ b/dist/timers.js.map @@ -1 +1 @@ -{"version":3,"file":"timers.js","names":["MODULE_NAME","orDefault","isFunction","assert","hasValue","hasMembers","schedule","ms","callback","oldTimer","countermand","id","window","setTimeout","type","pschedule","precise","waitStart","Date","now","waitMilliSecs","fAdjustWait","reschedule","timer","loop","oldLoop","setInterval","ploop","isInterval","clearInterval","clearTimeout","requestAnimationFrame","raf","webkitRequestAnimationFrame","mozRequestAnimationFrame","msRequestAnimationFrame","cancelAnimationFrame","caf","mozCancelAnimationFrame","waitForRepaint","ids","outer","inner"],"sources":["timers.js"],"mappings":"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","sourcesContent":["/*!\n * Module Timers\n */\n\n/**\n * @namespace Timers\n */\n\nconst MODULE_NAME = 'Timers';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {orDefault, isFunction, assert, hasValue, hasMembers} from './basic.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Timers:schedule\n */\n\n/**\n * Setup a timer for one-time execution of a callback, kills old timer if given\n * to prevent overlapping timers.\n *\n * @param {Number} ms - time in milliseconds until execution\n * @param {Function} callback - callback function to execute after ms\n * @param {?(Object|Number)} [oldTimer=null] - if set, kills the timer before setting up new one\n * @throws error if ms is negative or callback is not a function\n * @returns {Object} new timer\n *\n * @memberof Timers:schedule\n * @alias schedule\n * @see pschedule\n * @see countermand\n * @example\n * const timer = schedule(1000, function(){ alert('time for tea'); });\n * const timer = schedule(2000, function(){ alert('traffic jam, tea has to wait'); }, timer);\n */\nexport function schedule(ms, callback, oldTimer=null){\n\tms = orDefault(ms, 1, 'int');\n\n\tassert(ms >= 0, `${MODULE_NAME}:schedule | ms must be positive`);\n\tassert(isFunction(callback), `${MODULE_NAME}:schedule | callback must be a function`);\n\n\tif( hasValue(oldTimer) ){\n\t\tcountermand(oldTimer);\n\t}\n\n\treturn {id : window.setTimeout(callback, ms), type : 'timeout'};\n}\n\n\n\n/**\n * @namespace Timers:pschedule\n */\n\n/**\n * Setup a timer for one-time execution of a callback, kills old timer if given\n * to prevent overlapping timers.\n * This implementation uses Date.now()/Date.getTime() to improve on timer precision for long\n * running timers. The timers of this method can also be used in countermand().\n *\n * Warning: these timers are more precise than normal timer for _long_ time spans and less precise for short ones,\n * if you are dealing with times at least above 30s (or minutes and hours) this the right choice, if you look to\n * use precise timers in the second and millisecond range, definitely use schedule/loop instead!\n *\n * @param {Number} ms - time in milliseconds until execution\n * @param {Function} callback - callback function to execute after ms\n * @param {?(Object|Number)} [oldTimer=null] - if set, kills the timer before setting up new one\n * @throws error if ms is not positive or if callback is not a function\n * @returns {Object} timer (does not create new timer object if oldTimer given, but returns old one)\n *\n * @memberof Timers:pschedule\n * @alias pschedule\n * @see schedule\n * @see countermand\n * @example\n * const timer = pschedule(1000, function(){ alert('time for tea'); });\n * const timer = pschedule(2000, function(){ alert('traffic jam, tea has to wait'); }, timer);\n */\nexport function pschedule(ms, callback, oldTimer=null){\n\tms = orDefault(ms, 1, 'int');\n\n\tassert(ms >= 0, `${MODULE_NAME}:pschedule | ms must be positive`);\n\tassert(isFunction(callback), `${MODULE_NAME}:pschedule | callback must be a function`);\n\n\tif(\n\t\thasValue(oldTimer)\n\t\t&& hasMembers(oldTimer, ['id', 'type'])\n\t){\n\t\tcountermand(oldTimer);\n\t\toldTimer.precise = true;\n\t} else {\n\t\toldTimer = {id : -1, type : 'timeout', precise : true};\n\t}\n\n\tconst waitStart = Date.now();\n\tlet waitMilliSecs = ms;\n\n\tconst fAdjustWait = function(){\n\t\tif( waitMilliSecs > 0 ){\n\t\t\twaitMilliSecs -= (Date.now() - waitStart);\n\t\t\toldTimer.id = window.setTimeout(fAdjustWait, (waitMilliSecs > 10) ? waitMilliSecs : 10);\n\t\t} else {\n\t\t\tcallback();\n\t\t}\n\t};\n\n\toldTimer.id = window.setTimeout(fAdjustWait, waitMilliSecs);\n\n\treturn oldTimer;\n}\n\n\n\n/**\n * @namespace Timers:reschedule\n */\n\n/**\n * Alias for schedule() with more natural param-order for rescheduling.\n *\n * @param {(Object|Number)} timer - the timer to refresh/reset\n * @param {Number} ms - time in milliseconds until execution\n * @param {Function} callback - callback function to execute after ms\n * @throws error if ms is not positive or if callback is not a function\n * @returns {Object} timer (may be the original timer, if given timer is precise from pschedule or ploop)\n *\n * @memberof Timers:reschedule\n * @alias reschedule\n * @see schedule\n * @example\n * const timer = reschedule(timer, 3000, function(){ alert('taking even more time'); });\n */\nexport function reschedule(timer, ms, callback){\n\tms = orDefault(ms, 1, 'int');\n\n\tassert(ms >= 0, `${MODULE_NAME}:reschedule | ms must be positive`);\n\tassert(isFunction(callback), `${MODULE_NAME}:reschedule | callback must be a function`);\n\n\tif( hasValue(timer) && hasValue(timer.precise) && !!timer.precise ){\n\t\treturn pschedule(ms, callback, timer);\n\t} else {\n\t\treturn schedule(ms, callback, timer);\n\t}\n}\n\n\n\n/**\n * @namespace Timers:loop\n */\n\n/**\n * Setup a loop for repeated execution of a callback, kills old loop if wished\n * to prevent overlapping loops.\n *\n * @param {Number} ms - time in milliseconds until execution\n * @param {Function} callback - callback function to execute after ms\n * @param {?(Object|Number)} [oldLoop=null] - if set, kills the loop before setting up new one\n * @throws error if ms is not positive or if callback is not a function\n * @returns {Object} new loop\n *\n * @memberof Timers:loop\n * @alias loop\n * @see ploop\n * @see countermand\n * @example\n * const loop = loop(250, function(){ document.body.classList.add('brightred'); });\n * const loop = loop(100, function(){ document.body.classList.add('brightgreen'); }, loop);\n */\nexport function loop(ms, callback, oldLoop=null){\n\tms = orDefault(ms, 1, 'int');\n\n\tassert(ms >= 0, `${MODULE_NAME}:loop | ms must be positive`);\n\tassert(isFunction(callback), `${MODULE_NAME}:loop | callback must be a function`);\n\n\tif( hasValue(oldLoop) ){\n\t\tcountermand(oldLoop, true);\n\t}\n\n\treturn {id : window.setInterval(callback, ms), type : 'interval'};\n}\n\n\n\n/**\n * @namespace Timers:ploop\n */\n\n/**\n * Setup a loop for repeated execution of a callback, kills old loop if wished\n * to prevent overlapping loops.\n * This implementation uses Date.now()/Date.getTime() to improve on timer precision for long running loops.\n *\n * Warning: these timers are more precise than normal timer for _long_ time spans and less precise for short ones,\n * if you are dealing with times at least above 30s (or minutes and hours) this the right choice, if you look to\n * use precise timers in the second and millisecond range, definitely use schedule/loop instead!\n *\n * The loops of this method can also be used in countermand().\n * This method does not actually use intervals internally but timeouts,\n * so don't wonder if you can't find the ids in JS.\n *\n * @param {Number} ms - time in milliseconds until execution\n * @param {Function} callback - callback function to execute after ms\n * @param {?(Object|Number)} [oldLoop=null] - if set, kills the loop before setting up new one\n * @throws error if ms is not positive or if callback is not a function\n * @returns {Object} loop (if you give an old loop into the function the same reference will be returned)\n *\n * @memberof Timers:ploop\n * @alias ploop\n * @see loop\n * @see countermand\n * @example\n * const loop = ploop(250, function(){ document.body.classList.add('brightred'); });\n * const loop = ploop(100, function(){ document.body.classList.add('brightgreen'); }, loop);\n */\nexport function ploop(ms, callback, oldLoop=null){\n\tms = orDefault(ms, 1, 'int');\n\n\tassert(ms >= 0, `${MODULE_NAME}:ploop | ms must be positive`);\n\tassert(isFunction(callback), `${MODULE_NAME}:ploop | callback must be a function`);\n\n\tif(\n\t\thasValue(oldLoop)\n\t\t&& hasMembers(oldLoop, ['id', 'type'])\n\t){\n\t\tcountermand(oldLoop, true);\n\t\toldLoop.precise = true;\n\t} else {\n\t\toldLoop = {id : -1, type : 'interval', precise : true};\n\t}\n\n\tlet\n\t\twaitStart = Date.now(),\n\t\twaitMilliSecs = ms\n\t;\n\n\tconst fAdjustWait = function(){\n\t\tif( waitMilliSecs > 0 ){\n\t\t\twaitMilliSecs -= (Date.now() - waitStart);\n\t\t\toldLoop.id = window.setTimeout(fAdjustWait, (waitMilliSecs > 10) ? waitMilliSecs : 10);\n\t\t} else {\n\t\t\tcallback();\n\t\t\twaitStart = Date.now();\n\t\t\twaitMilliSecs = ms;\n\t\t\toldLoop.id = window.setTimeout(fAdjustWait, waitMilliSecs);\n\t\t}\n\t};\n\n\toldLoop.id = window.setTimeout(fAdjustWait, waitMilliSecs);\n\n\treturn oldLoop;\n}\n\n\n\n/**\n * @namespace Timers:countermand\n */\n\n/**\n * Cancel a timer or loop immediately.\n *\n * @param {(Object|Number)} timer - the timer or loop to end\n * @param {?Boolean} [isInterval=false] - defines if a timer or a loop is to be stopped, set in case timer is a GUID\n *\n * @memberof Timers:countermand\n * @alias countermand\n * @see schedule\n * @see pschedule\n * @see loop\n * @see ploop\n * @example\n * countermand(timer);\n * countermand(loop);\n */\nexport function countermand(timer, isInterval=false){\n\tisInterval = orDefault(isInterval, false, 'bool');\n\n\tif( hasValue(timer) ){\n\t\tif( hasMembers(timer, ['id', 'type']) ){\n\t\t\tif( timer.type === 'interval' ){\n\t\t\t\twindow.clearInterval(timer.id);\n\t\t\t} else {\n\t\t\t\twindow.clearTimeout(timer.id);\n\t\t\t}\n\t\t} else {\n\t\t\tif( !isInterval ){\n\t\t\t\twindow.clearTimeout(timer);\n\t\t\t} else {\n\t\t\t\twindow.clearInterval(timer);\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n\n/**\n * @namespace Timers:requestAnimationFrame\n */\n\n/**\n * This is a simple streamlined, vendor-cascading version of window.requestAnimationFrame with a timeout fallback in\n * case the functionality is missing from the browser.\n *\n * @param {Function} callback - the code to execute once the browser has assigned an execution slot for it\n * @throws error if callback is not a function\n * @return {Number} either the id of the requestAnimationFrame or the internal timeout, both are cancellable via cancelAnimationFrame\n *\n * @memberof Timers:requestAnimationFrame\n * @alias requestAnimationFrame\n * @see raf\n * @see cancelAnimationFrame\n * @see caf\n * @example\n * const requestId = requestAnimationFrame(function(){ window.body.style.opacity = 0; });\n */\nexport function requestAnimationFrame(callback){\n\tassert(isFunction(callback), `${MODULE_NAME}:requestAnimationFrame | callback is no function`);\n\n\tconst raf = window.requestAnimationFrame\n\t\t?? window.webkitRequestAnimationFrame\n\t\t?? window.mozRequestAnimationFrame\n\t\t?? window.msRequestAnimationFrame\n\t\t?? function(callback){ return schedule(16, callback); }\n\t;\n\n\treturn raf(callback);\n}\n\n\n\n/**\n * @namespace Timers:cancelAnimationFrame\n */\n\n/**\n * This is a simple streamlined, vendor-cascading version of window.cancelAnimationFrame.\n *\n * @param {Number} id - either the id of the requestAnimationFrame or its timeout fallback\n *\n * @memberof Timers:cancelAnimationFrame\n * @alias cancelAnimationFrame\n * @see requestAnimationFrame\n * @see raf\n * @see caf\n * @example\n * cancelAnimationFrame(requestAnimationFrame(function(){ window.body.style.opacity = 0; }));\n */\nexport function cancelAnimationFrame(id){\n\tconst raf = window.requestAnimationFrame\n\t\t?? window.webkitRequestAnimationFrame\n\t\t?? window.mozRequestAnimationFrame\n\t\t?? window.msRequestAnimationFrame\n\t;\n\n\tlet caf = window.cancelAnimationFrame\n\t\t?? window.mozCancelAnimationFrame\n\t;\n\n\tif( !hasValue(raf) ){\n\t\tcaf = countermand;\n\t}\n\n\treturn caf(id);\n}\n\n\n\n/**\n * @namespace Timers:waitForRepaint\n */\n\n/**\n * This function has the purpose to offer a safe execution slot for code depending on an up-to-date rendering state of\n * the DOM after a change to styles for example. Let's say you add a class to an element and right in the next line\n * you'll want to read a layout attribute like width or height from it. This might fail, because there is no guarantee\n * the browser actually already applied the new styles to be read from the DOM.\n *\n * To wait safely for the new DOM state this method works with two stacked requestAnimationFrame calls.\n *\n * Since requestAnimationFrame always happens _before_ a repaint, two stacked calls ensure, that there has to be a\n * repaint between them.\n *\n * @param {Function} callback - the code to execute once the browser performed a repaint\n * @throws error if callback is not a function\n * @return {Object} dictionary of ids for the inner and outer request ids, outer gets assigned right away, while inner gets assigned after first callback => {outer : 1, inner : 2}\n *\n * @memberof Timers:waitForRepaint\n * @alias waitForRepaint\n * @see requestAnimationFrame\n * @see raf\n * @example\n * element.classList.add('special-stuff');\n * waitForRepaint(function(){ alert(`the new dimensions after class change are: ${element.offsetWidth}x${element.offsetHeight}`); });\n */\nexport function waitForRepaint(callback){\n\tassert(isFunction(callback), `${MODULE_NAME}:waitForRepaint | callback is no function`);\n\n\tconst ids = {};\n\n\tids.outer = requestAnimationFrame(function(){\n\t\tids.inner = requestAnimationFrame(callback);\n\t});\n\n\treturn ids;\n}\n"]} \ No newline at end of file +{"version":3,"file":"timers.js","names":["MODULE_NAME","orDefault","isFunction","assert","hasValue","hasMembers","schedule","ms","callback","oldTimer","countermand","id","window","setTimeout","type","pschedule","precise","waitStart","Date","now","waitMilliSecs","fAdjustWait","reschedule","timer","loop","oldLoop","setInterval","ploop","isInterval","clearInterval","clearTimeout","requestAnimationFrame","raf","webkitRequestAnimationFrame","mozRequestAnimationFrame","msRequestAnimationFrame","cancelAnimationFrame","caf","mozCancelAnimationFrame","waitForRepaint","ids","outer","inner"],"sources":["timers.js"],"mappings":"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","ignoreList":[],"sourcesContent":["/*!\n * Module Timers\n */\n\n/**\n * @namespace Timers\n */\n\nconst MODULE_NAME = 'Timers';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {orDefault, isFunction, assert, hasValue, hasMembers} from './basic.js';\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Timers:schedule\n */\n\n/**\n * Setup a timer for one-time execution of a callback, kills old timer if given\n * to prevent overlapping timers.\n *\n * @param {Number} ms - time in milliseconds until execution\n * @param {Function} callback - callback function to execute after ms\n * @param {?(Object|Number)} [oldTimer=null] - if set, kills the timer before setting up new one\n * @throws error if ms is negative or callback is not a function\n * @returns {Object} new timer\n *\n * @memberof Timers:schedule\n * @alias schedule\n * @see pschedule\n * @see countermand\n * @example\n * const timer = schedule(1000, function(){ alert('time for tea'); });\n * const timer = schedule(2000, function(){ alert('traffic jam, tea has to wait'); }, timer);\n */\nexport function schedule(ms, callback, oldTimer=null){\n\tms = orDefault(ms, 1, 'int');\n\n\tassert(ms >= 0, `${MODULE_NAME}:schedule | ms must be positive`);\n\tassert(isFunction(callback), `${MODULE_NAME}:schedule | callback must be a function`);\n\n\tif( hasValue(oldTimer) ){\n\t\tcountermand(oldTimer);\n\t}\n\n\treturn {id : window.setTimeout(callback, ms), type : 'timeout'};\n}\n\n\n\n/**\n * @namespace Timers:pschedule\n */\n\n/**\n * Setup a timer for one-time execution of a callback, kills old timer if given\n * to prevent overlapping timers.\n * This implementation uses Date.now()/Date.getTime() to improve on timer precision for long\n * running timers. The timers of this method can also be used in countermand().\n *\n * Warning: these timers are more precise than normal timer for _long_ time spans and less precise for short ones,\n * if you are dealing with times at least above 30s (or minutes and hours) this the right choice, if you look to\n * use precise timers in the second and millisecond range, definitely use schedule/loop instead!\n *\n * @param {Number} ms - time in milliseconds until execution\n * @param {Function} callback - callback function to execute after ms\n * @param {?(Object|Number)} [oldTimer=null] - if set, kills the timer before setting up new one\n * @throws error if ms is not positive or if callback is not a function\n * @returns {Object} timer (does not create new timer object if oldTimer given, but returns old one)\n *\n * @memberof Timers:pschedule\n * @alias pschedule\n * @see schedule\n * @see countermand\n * @example\n * const timer = pschedule(1000, function(){ alert('time for tea'); });\n * const timer = pschedule(2000, function(){ alert('traffic jam, tea has to wait'); }, timer);\n */\nexport function pschedule(ms, callback, oldTimer=null){\n\tms = orDefault(ms, 1, 'int');\n\n\tassert(ms >= 0, `${MODULE_NAME}:pschedule | ms must be positive`);\n\tassert(isFunction(callback), `${MODULE_NAME}:pschedule | callback must be a function`);\n\n\tif(\n\t\thasValue(oldTimer)\n\t\t&& hasMembers(oldTimer, ['id', 'type'])\n\t){\n\t\tcountermand(oldTimer);\n\t\toldTimer.precise = true;\n\t} else {\n\t\toldTimer = {id : -1, type : 'timeout', precise : true};\n\t}\n\n\tconst waitStart = Date.now();\n\tlet waitMilliSecs = ms;\n\n\tconst fAdjustWait = function(){\n\t\tif( waitMilliSecs > 0 ){\n\t\t\twaitMilliSecs -= (Date.now() - waitStart);\n\t\t\toldTimer.id = window.setTimeout(fAdjustWait, (waitMilliSecs > 10) ? waitMilliSecs : 10);\n\t\t} else {\n\t\t\tcallback();\n\t\t}\n\t};\n\n\toldTimer.id = window.setTimeout(fAdjustWait, waitMilliSecs);\n\n\treturn oldTimer;\n}\n\n\n\n/**\n * @namespace Timers:reschedule\n */\n\n/**\n * Alias for schedule() with more natural param-order for rescheduling.\n *\n * @param {(Object|Number)} timer - the timer to refresh/reset\n * @param {Number} ms - time in milliseconds until execution\n * @param {Function} callback - callback function to execute after ms\n * @throws error if ms is not positive or if callback is not a function\n * @returns {Object} timer (may be the original timer, if given timer is precise from pschedule or ploop)\n *\n * @memberof Timers:reschedule\n * @alias reschedule\n * @see schedule\n * @example\n * const timer = reschedule(timer, 3000, function(){ alert('taking even more time'); });\n */\nexport function reschedule(timer, ms, callback){\n\tms = orDefault(ms, 1, 'int');\n\n\tassert(ms >= 0, `${MODULE_NAME}:reschedule | ms must be positive`);\n\tassert(isFunction(callback), `${MODULE_NAME}:reschedule | callback must be a function`);\n\n\tif( hasValue(timer) && hasValue(timer.precise) && !!timer.precise ){\n\t\treturn pschedule(ms, callback, timer);\n\t} else {\n\t\treturn schedule(ms, callback, timer);\n\t}\n}\n\n\n\n/**\n * @namespace Timers:loop\n */\n\n/**\n * Setup a loop for repeated execution of a callback, kills old loop if wished\n * to prevent overlapping loops.\n *\n * @param {Number} ms - time in milliseconds until execution\n * @param {Function} callback - callback function to execute after ms\n * @param {?(Object|Number)} [oldLoop=null] - if set, kills the loop before setting up new one\n * @throws error if ms is not positive or if callback is not a function\n * @returns {Object} new loop\n *\n * @memberof Timers:loop\n * @alias loop\n * @see ploop\n * @see countermand\n * @example\n * const loop = loop(250, function(){ document.body.classList.add('brightred'); });\n * const loop = loop(100, function(){ document.body.classList.add('brightgreen'); }, loop);\n */\nexport function loop(ms, callback, oldLoop=null){\n\tms = orDefault(ms, 1, 'int');\n\n\tassert(ms >= 0, `${MODULE_NAME}:loop | ms must be positive`);\n\tassert(isFunction(callback), `${MODULE_NAME}:loop | callback must be a function`);\n\n\tif( hasValue(oldLoop) ){\n\t\tcountermand(oldLoop, true);\n\t}\n\n\treturn {id : window.setInterval(callback, ms), type : 'interval'};\n}\n\n\n\n/**\n * @namespace Timers:ploop\n */\n\n/**\n * Setup a loop for repeated execution of a callback, kills old loop if wished\n * to prevent overlapping loops.\n * This implementation uses Date.now()/Date.getTime() to improve on timer precision for long running loops.\n *\n * Warning: these timers are more precise than normal timer for _long_ time spans and less precise for short ones,\n * if you are dealing with times at least above 30s (or minutes and hours) this the right choice, if you look to\n * use precise timers in the second and millisecond range, definitely use schedule/loop instead!\n *\n * The loops of this method can also be used in countermand().\n * This method does not actually use intervals internally but timeouts,\n * so don't wonder if you can't find the ids in JS.\n *\n * @param {Number} ms - time in milliseconds until execution\n * @param {Function} callback - callback function to execute after ms\n * @param {?(Object|Number)} [oldLoop=null] - if set, kills the loop before setting up new one\n * @throws error if ms is not positive or if callback is not a function\n * @returns {Object} loop (if you give an old loop into the function the same reference will be returned)\n *\n * @memberof Timers:ploop\n * @alias ploop\n * @see loop\n * @see countermand\n * @example\n * const loop = ploop(250, function(){ document.body.classList.add('brightred'); });\n * const loop = ploop(100, function(){ document.body.classList.add('brightgreen'); }, loop);\n */\nexport function ploop(ms, callback, oldLoop=null){\n\tms = orDefault(ms, 1, 'int');\n\n\tassert(ms >= 0, `${MODULE_NAME}:ploop | ms must be positive`);\n\tassert(isFunction(callback), `${MODULE_NAME}:ploop | callback must be a function`);\n\n\tif(\n\t\thasValue(oldLoop)\n\t\t&& hasMembers(oldLoop, ['id', 'type'])\n\t){\n\t\tcountermand(oldLoop, true);\n\t\toldLoop.precise = true;\n\t} else {\n\t\toldLoop = {id : -1, type : 'interval', precise : true};\n\t}\n\n\tlet\n\t\twaitStart = Date.now(),\n\t\twaitMilliSecs = ms\n\t;\n\n\tconst fAdjustWait = function(){\n\t\tif( waitMilliSecs > 0 ){\n\t\t\twaitMilliSecs -= (Date.now() - waitStart);\n\t\t\toldLoop.id = window.setTimeout(fAdjustWait, (waitMilliSecs > 10) ? waitMilliSecs : 10);\n\t\t} else {\n\t\t\tcallback();\n\t\t\twaitStart = Date.now();\n\t\t\twaitMilliSecs = ms;\n\t\t\toldLoop.id = window.setTimeout(fAdjustWait, waitMilliSecs);\n\t\t}\n\t};\n\n\toldLoop.id = window.setTimeout(fAdjustWait, waitMilliSecs);\n\n\treturn oldLoop;\n}\n\n\n\n/**\n * @namespace Timers:countermand\n */\n\n/**\n * Cancel a timer or loop immediately.\n *\n * @param {(Object|Number)} timer - the timer or loop to end\n * @param {?Boolean} [isInterval=false] - defines if a timer or a loop is to be stopped, set in case timer is a GUID\n *\n * @memberof Timers:countermand\n * @alias countermand\n * @see schedule\n * @see pschedule\n * @see loop\n * @see ploop\n * @example\n * countermand(timer);\n * countermand(loop);\n */\nexport function countermand(timer, isInterval=false){\n\tisInterval = orDefault(isInterval, false, 'bool');\n\n\tif( hasValue(timer) ){\n\t\tif( hasMembers(timer, ['id', 'type']) ){\n\t\t\tif( timer.type === 'interval' ){\n\t\t\t\twindow.clearInterval(timer.id);\n\t\t\t} else {\n\t\t\t\twindow.clearTimeout(timer.id);\n\t\t\t}\n\t\t} else {\n\t\t\tif( !isInterval ){\n\t\t\t\twindow.clearTimeout(timer);\n\t\t\t} else {\n\t\t\t\twindow.clearInterval(timer);\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n\n/**\n * @namespace Timers:requestAnimationFrame\n */\n\n/**\n * This is a simple streamlined, vendor-cascading version of window.requestAnimationFrame with a timeout fallback in\n * case the functionality is missing from the browser.\n *\n * @param {Function} callback - the code to execute once the browser has assigned an execution slot for it\n * @throws error if callback is not a function\n * @return {Number} either the id of the requestAnimationFrame or the internal timeout, both are cancellable via cancelAnimationFrame\n *\n * @memberof Timers:requestAnimationFrame\n * @alias requestAnimationFrame\n * @see raf\n * @see cancelAnimationFrame\n * @see caf\n * @example\n * const requestId = requestAnimationFrame(function(){ window.body.style.opacity = 0; });\n */\nexport function requestAnimationFrame(callback){\n\tassert(isFunction(callback), `${MODULE_NAME}:requestAnimationFrame | callback is no function`);\n\n\tconst raf = window.requestAnimationFrame\n\t\t?? window.webkitRequestAnimationFrame\n\t\t?? window.mozRequestAnimationFrame\n\t\t?? window.msRequestAnimationFrame\n\t\t?? function(callback){ return schedule(16, callback); }\n\t;\n\n\treturn raf(callback);\n}\n\n\n\n/**\n * @namespace Timers:cancelAnimationFrame\n */\n\n/**\n * This is a simple streamlined, vendor-cascading version of window.cancelAnimationFrame.\n *\n * @param {Number} id - either the id of the requestAnimationFrame or its timeout fallback\n *\n * @memberof Timers:cancelAnimationFrame\n * @alias cancelAnimationFrame\n * @see requestAnimationFrame\n * @see raf\n * @see caf\n * @example\n * cancelAnimationFrame(requestAnimationFrame(function(){ window.body.style.opacity = 0; }));\n */\nexport function cancelAnimationFrame(id){\n\tconst raf = window.requestAnimationFrame\n\t\t?? window.webkitRequestAnimationFrame\n\t\t?? window.mozRequestAnimationFrame\n\t\t?? window.msRequestAnimationFrame\n\t;\n\n\tlet caf = window.cancelAnimationFrame\n\t\t?? window.mozCancelAnimationFrame\n\t;\n\n\tif( !hasValue(raf) ){\n\t\tcaf = countermand;\n\t}\n\n\treturn caf(id);\n}\n\n\n\n/**\n * @namespace Timers:waitForRepaint\n */\n\n/**\n * This function has the purpose to offer a safe execution slot for code depending on an up-to-date rendering state of\n * the DOM after a change to styles for example. Let's say you add a class to an element and right in the next line\n * you'll want to read a layout attribute like width or height from it. This might fail, because there is no guarantee\n * the browser actually already applied the new styles to be read from the DOM.\n *\n * To wait safely for the new DOM state this method works with two stacked requestAnimationFrame calls.\n *\n * Since requestAnimationFrame always happens _before_ a repaint, two stacked calls ensure, that there has to be a\n * repaint between them.\n *\n * @param {Function} callback - the code to execute once the browser performed a repaint\n * @throws error if callback is not a function\n * @return {Object} dictionary of ids for the inner and outer request ids, outer gets assigned right away, while inner gets assigned after first callback => {outer : 1, inner : 2}\n *\n * @memberof Timers:waitForRepaint\n * @alias waitForRepaint\n * @see requestAnimationFrame\n * @see raf\n * @example\n * element.classList.add('special-stuff');\n * waitForRepaint(function(){ alert(`the new dimensions after class change are: ${element.offsetWidth}x${element.offsetHeight}`); });\n */\nexport function waitForRepaint(callback){\n\tassert(isFunction(callback), `${MODULE_NAME}:waitForRepaint | callback is no function`);\n\n\tconst ids = {};\n\n\tids.outer = requestAnimationFrame(function(){\n\t\tids.inner = requestAnimationFrame(callback);\n\t});\n\n\treturn ids;\n}\n"]} \ No newline at end of file diff --git a/dist/units.js b/dist/units.js index 3efad59f..b132e139 100644 --- a/dist/units.js +++ b/dist/units.js @@ -1,5 +1,5 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Units diff --git a/dist/units.js.map b/dist/units.js.map index f1075752..aa2146a4 100644 --- a/dist/units.js.map +++ b/dist/units.js.map @@ -1 +1 @@ -{"version":3,"file":"units.js","names":["MODULE_NAME","orDefault","assert","isNaN","isArray","round","LOCAL_FLOAT_SEPARATOR","toLocaleString","replace","slice","LOCAL_THOUSAND_SEPARATOR","asFileSize","bytes","separator","precision","useBinaryBase","parseInt","thresh","units","unitIndex","length","asCurrency","number","locale","currency","currencyDisplay","parseFloat","includes","concat","Intl","NumberFormat","style","format","asDecimal","minPrecision","maxPrecision","useGrouping","minimumFractionDigits","maximumFractionDigits"],"sources":["units.js"],"mappings":";;;AAQA,MAAMA,YAAc,eAMZC,UAAWC,OAAQC,MAAOC,QAASC,UAAY,oBAMhD,MACNC,sBAAwB,GAAMC,iBAAiBC,QAAQ,SAAU,IAAIC,MAAM,EAAG,GAC9EC,yBAA2B,IAAOH,iBAAiBC,QAAQ,SAAU,IAAIC,MAAM,EAAG,UAkC5E,SAASE,WAAWC,EAAOC,EAAUP,sBAAuBQ,EAAU,EAAGC,GAAc,GAG7FH,EAAQI,SAASJ,EAAO,IACxBV,QACEC,MAAMS,IAAWA,GAAS,EAC3B,mDAGDC,EAAYZ,UAAUY,EAAWP,sBAAuB,OACxDQ,EAAYb,UAAUa,EAAW,EAAG,OAEpC,MACCG,EAAWF,EAAgB,KAAO,IAClCG,EAAUH,EACP,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,OAC3C,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MAGxC,GAAIH,EAAQK,EACX,MAAO,GAAGL,MAGX,IAAIO,GAAa,EACjB,GACCP,GAASK,EACTE,UAECP,GAASK,GACNE,EAAaD,EAAME,OAAS,GAIjC,MAAO,GADPR,EAAQ,GAAGP,MAAMO,EAAOE,KAAaN,QAAQ,IAAKK,MAC/BK,EAAMC,IAC1B,QA2BO,SAASE,WAAWC,EAAQC,EAAO,QAASC,EAAS,MAAOC,EAAgB,UAclF,OAbAH,EAASI,WAAWJ,GAEpBC,EAAStB,UAAUsB,EAAQ,WAExBnB,QAAQmB,IAAuB,UAAXA,GAClBnB,QAAQmB,KAAYA,EAAOI,SAAS,YAExCJ,EAAS,GAAGK,OAAOL,GAAQK,OAAO,UAGnCJ,EAAWvB,UAAUuB,EAAU,MAAO,OACtCC,EAAkBxB,UAAUwB,EAAiB,SAAU,OAEhD,IAAII,KAAKC,aACfP,EACA,CACCQ,MAAQ,WACRP,WACAC,oBAEAO,OAAOV,EACV,QA0BO,SAASW,UAAUX,EAAQC,EAAO,QAASW,EAAa,EAAGC,EAAa,MAc9E,OAbAb,EAASI,WAAWJ,GAEpBC,EAAStB,UAAUsB,EAAQ,WAExBnB,QAAQmB,IAAuB,UAAXA,GAClBnB,QAAQmB,KAAYA,EAAOI,SAAS,YAExCJ,EAAS,GAAGK,OAAOL,GAAQK,OAAO,UAGnCM,EAAejC,UAAUiC,EAAc,EAAG,OAC1CC,EAAelC,UAAUkC,EAAcD,EAAc,OAE9C,IAAIL,KAAKC,aACfP,EACA,CACCQ,MAAQ,UACRK,aAAc,EACdC,sBAAwBH,EACxBI,sBAAwBH,IAExBH,OAAOV,EACV","sourcesContent":["/*!\n * Module Units\n */\n\n/**\n * @namespace Units\n */\n\nconst MODULE_NAME = 'Units';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {orDefault, assert, isNaN, isArray, round} from './basic.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const\n\tLOCAL_FLOAT_SEPARATOR = (0.1).toLocaleString().replace(/[0-9]/g, '').slice(0, 1),\n\tLOCAL_THOUSAND_SEPARATOR = (1000).toLocaleString().replace(/[0-9]/g, '').slice(0, 1)\n;\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Units:asFileSize\n */\n\n/**\n * Renders a byte number as a human-readable file size with the correct unit.\n *\n * Switch calculation base by setting useBinaryBase to true.\n * Today, file sizes are usually calculated against a decimal base of 1000, while in the\n * past, a binary base of 1024 was commonly used (and still is today by some software such as Microsoft Windows).\n * In 1998 the IEC standardized byte units to be metric in nature, which is the base assumption of this method.\n *\n * @param {Number} bytes - file size in bytes to render as string\n * @param {?String} [separator=LOCAL_FLOAT_SEPARATOR] - the character to separate the fraction in float numbers, will default to the current browser's default for local strings\n * @param {?Number} [precision=1] - the floating point precision to use for the size\n * @param {?Boolean} [useBinaryBase=false] - set to true to activate binary calculation and units\n * @returns {String} the formatted file size\n *\n * @memberof Units:asFileSize\n * @alias asFileSize\n * @see https://en.wikipedia.org/wiki/Kilobyte\n * @example\n * asFileSize(1_500_000, ',')\n * => '1,5 MB'\n * asFileSize(1024, '.', 0, true)\n * => '1 KiB'\n */\nexport function asFileSize(bytes, separator=LOCAL_FLOAT_SEPARATOR, precision=1, useBinaryBase=false){\n\tconst __methodName__ = 'asFileSize';\n\n\tbytes = parseInt(bytes, 10);\n\tassert(\n\t\t!isNaN(bytes) && (bytes >= 0),\n\t\t`${MODULE_NAME}:${__methodName__} | bytes not usable or negative`\n\t);\n\n\tseparator = orDefault(separator, LOCAL_FLOAT_SEPARATOR, 'str');\n\tprecision = orDefault(precision, 1, 'int');\n\n\tconst\n\t\tthresh = !!useBinaryBase ? 1024 : 1000,\n\t\tunits = !!useBinaryBase\n\t\t\t? ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB']\n\t\t\t: ['kB','MB','GB','TB','PB','EB','ZB','YB']\n\t;\n\n\tif( bytes < thresh ){\n\t\treturn `${bytes} B`;\n\t}\n\n\tlet unitIndex = -1;\n\tdo {\n\t\tbytes /= thresh;\n\t\tunitIndex++;\n\t} while(\n\t\t(bytes >= thresh)\n\t\t&& (unitIndex < (units.length - 1))\n\t);\n\n\tbytes = `${round(bytes, precision)}`.replace('.', separator);\n\treturn `${bytes} ${units[unitIndex]}`;\n}\n\n\n\n/**\n * @namespace Units:asCurrency\n */\n\n/**\n * Renders a number as a currency value, using native Intl.NumberFormat functionality.\n *\n * @param {Number} number - the number to use as a currency amount\n * @param {?String|Array} [locale='en-US'] - locale to use, use array to define fallback; always falls back to en-US if nothing else works\n * @param {?String} [currency='USD'] - a ISO4217 currency code, such as EUR for Euro\n * @param {?String} [currencyDisplay='symbol'] - one of \"symbol\", \"narrowSymbol\", \"code\" or \"name\", defining, how the currency should be displayed in the result\n * @returns {String} the formatted currency amount\n *\n * @memberof Units:asCurrency\n * @alias asCurrency\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat\n * @see https://en.wikipedia.org/wiki/ISO_4217#List_of_ISO_4217_currency_codes\n * @example\n * asCurrency(42.666)\n * => '42.67 $'\n * asCurrency(42.666, 'de-DE', 'EUR')\n * => '42,67 €'\n */\nexport function asCurrency(number, locale='en-US', currency='USD', currencyDisplay='symbol'){\n\tnumber = parseFloat(number);\n\n\tlocale = orDefault(locale, 'en-US');\n\tif(\n\t\t(!isArray(locale) && (locale !== 'en-US'))\n\t\t|| (isArray(locale) && !locale.includes('en-US'))\n\t){\n\t\tlocale = [].concat(locale).concat('en-US');\n\t}\n\n\tcurrency = orDefault(currency, 'USD', 'str');\n\tcurrencyDisplay = orDefault(currencyDisplay, 'symbol', 'str');\n\n\treturn new Intl.NumberFormat(\n\t\tlocale,\n\t\t{\n\t\t\tstyle : 'currency',\n\t\t\tcurrency,\n\t\t\tcurrencyDisplay,\n\t\t}\n\t).format(number);\n}\n\n\n\n/**\n * @namespace Units:asDecimal\n */\n\n/**\n * Renders a number as a decimal value, using native Intl.NumberFormat functionality.\n *\n * @param {Number} number - the number to use as a decimal amount\n * @param {?String|Array} [locale='en-US'] - locale to use, use array to define fallback; always falls back to en-US if nothing else works\n * @param {?Number} [minPrecision=2] - the minimal precision to use in decimal display\n * @param {?Number} [maxPrecision=null] - the minimal precision to use in decimal display; if nullish, will be set to minPrecision\n * @returns {String} the formatted decimal amount\n *\n * @memberof Units:asDecimal\n * @alias asDecimal\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat\n * @example\n * asDecimal(42.666)\n * => '42.67'\n * asDecimal(42.666, 'de-DE', 1)\n * => '42,7'\n */\nexport function asDecimal(number, locale='en-US', minPrecision=2, maxPrecision=null){\n\tnumber = parseFloat(number);\n\n\tlocale = orDefault(locale, 'en-US');\n\tif(\n\t\t(!isArray(locale) && (locale !== 'en-US'))\n\t\t|| (isArray(locale) && !locale.includes('en-US'))\n\t){\n\t\tlocale = [].concat(locale).concat('en-US');\n\t}\n\n\tminPrecision = orDefault(minPrecision, 2, 'int');\n\tmaxPrecision = orDefault(maxPrecision, minPrecision, 'int');\n\n\treturn new Intl.NumberFormat(\n\t\tlocale,\n\t\t{\n\t\t\tstyle : 'decimal',\n\t\t\tuseGrouping : false,\n\t\t\tminimumFractionDigits : minPrecision,\n\t\t\tmaximumFractionDigits : maxPrecision\n\t\t}\n\t).format(number);\n}\n"]} \ No newline at end of file +{"version":3,"file":"units.js","names":["MODULE_NAME","orDefault","assert","isNaN","isArray","round","LOCAL_FLOAT_SEPARATOR","toLocaleString","replace","slice","LOCAL_THOUSAND_SEPARATOR","asFileSize","bytes","separator","precision","useBinaryBase","parseInt","thresh","units","unitIndex","length","asCurrency","number","locale","currency","currencyDisplay","parseFloat","includes","concat","Intl","NumberFormat","style","format","asDecimal","minPrecision","maxPrecision","useGrouping","minimumFractionDigits","maximumFractionDigits"],"sources":["units.js"],"mappings":";;;AAQA,MAAMA,YAAc,eAMZC,UAAWC,OAAQC,MAAOC,QAASC,UAAY,oBAMhD,MACNC,sBAAwB,GAAMC,iBAAiBC,QAAQ,SAAU,IAAIC,MAAM,EAAG,GAC9EC,yBAA2B,IAAOH,iBAAiBC,QAAQ,SAAU,IAAIC,MAAM,EAAG,UAkC5E,SAASE,WAAWC,EAAOC,EAAUP,sBAAuBQ,EAAU,EAAGC,GAAc,GAG7FH,EAAQI,SAASJ,EAAO,IACxBV,QACEC,MAAMS,IAAWA,GAAS,EAC3B,mDAGDC,EAAYZ,UAAUY,EAAWP,sBAAuB,OACxDQ,EAAYb,UAAUa,EAAW,EAAG,OAEpC,MACCG,EAAWF,EAAgB,KAAO,IAClCG,EAAUH,EACP,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,OAC3C,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MAGxC,GAAIH,EAAQK,EACX,MAAO,GAAGL,MAGX,IAAIO,GAAa,EACjB,GACCP,GAASK,EACTE,UAECP,GAASK,GACNE,EAAaD,EAAME,OAAS,GAIjC,MAAO,GADPR,EAAQ,GAAGP,MAAMO,EAAOE,KAAaN,QAAQ,IAAKK,MAC/BK,EAAMC,IAC1B,QA2BO,SAASE,WAAWC,EAAQC,EAAO,QAASC,EAAS,MAAOC,EAAgB,UAclF,OAbAH,EAASI,WAAWJ,GAEpBC,EAAStB,UAAUsB,EAAQ,WAExBnB,QAAQmB,IAAuB,UAAXA,GAClBnB,QAAQmB,KAAYA,EAAOI,SAAS,YAExCJ,EAAS,GAAGK,OAAOL,GAAQK,OAAO,UAGnCJ,EAAWvB,UAAUuB,EAAU,MAAO,OACtCC,EAAkBxB,UAAUwB,EAAiB,SAAU,OAEhD,IAAII,KAAKC,aACfP,EACA,CACCQ,MAAQ,WACRP,WACAC,oBAEAO,OAAOV,EACV,QA0BO,SAASW,UAAUX,EAAQC,EAAO,QAASW,EAAa,EAAGC,EAAa,MAc9E,OAbAb,EAASI,WAAWJ,GAEpBC,EAAStB,UAAUsB,EAAQ,WAExBnB,QAAQmB,IAAuB,UAAXA,GAClBnB,QAAQmB,KAAYA,EAAOI,SAAS,YAExCJ,EAAS,GAAGK,OAAOL,GAAQK,OAAO,UAGnCM,EAAejC,UAAUiC,EAAc,EAAG,OAC1CC,EAAelC,UAAUkC,EAAcD,EAAc,OAE9C,IAAIL,KAAKC,aACfP,EACA,CACCQ,MAAQ,UACRK,aAAc,EACdC,sBAAwBH,EACxBI,sBAAwBH,IAExBH,OAAOV,EACV","ignoreList":[],"sourcesContent":["/*!\n * Module Units\n */\n\n/**\n * @namespace Units\n */\n\nconst MODULE_NAME = 'Units';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {orDefault, assert, isNaN, isArray, round} from './basic.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const\n\tLOCAL_FLOAT_SEPARATOR = (0.1).toLocaleString().replace(/[0-9]/g, '').slice(0, 1),\n\tLOCAL_THOUSAND_SEPARATOR = (1000).toLocaleString().replace(/[0-9]/g, '').slice(0, 1)\n;\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Units:asFileSize\n */\n\n/**\n * Renders a byte number as a human-readable file size with the correct unit.\n *\n * Switch calculation base by setting useBinaryBase to true.\n * Today, file sizes are usually calculated against a decimal base of 1000, while in the\n * past, a binary base of 1024 was commonly used (and still is today by some software such as Microsoft Windows).\n * In 1998 the IEC standardized byte units to be metric in nature, which is the base assumption of this method.\n *\n * @param {Number} bytes - file size in bytes to render as string\n * @param {?String} [separator=LOCAL_FLOAT_SEPARATOR] - the character to separate the fraction in float numbers, will default to the current browser's default for local strings\n * @param {?Number} [precision=1] - the floating point precision to use for the size\n * @param {?Boolean} [useBinaryBase=false] - set to true to activate binary calculation and units\n * @returns {String} the formatted file size\n *\n * @memberof Units:asFileSize\n * @alias asFileSize\n * @see https://en.wikipedia.org/wiki/Kilobyte\n * @example\n * asFileSize(1_500_000, ',')\n * => '1,5 MB'\n * asFileSize(1024, '.', 0, true)\n * => '1 KiB'\n */\nexport function asFileSize(bytes, separator=LOCAL_FLOAT_SEPARATOR, precision=1, useBinaryBase=false){\n\tconst __methodName__ = 'asFileSize';\n\n\tbytes = parseInt(bytes, 10);\n\tassert(\n\t\t!isNaN(bytes) && (bytes >= 0),\n\t\t`${MODULE_NAME}:${__methodName__} | bytes not usable or negative`\n\t);\n\n\tseparator = orDefault(separator, LOCAL_FLOAT_SEPARATOR, 'str');\n\tprecision = orDefault(precision, 1, 'int');\n\n\tconst\n\t\tthresh = !!useBinaryBase ? 1024 : 1000,\n\t\tunits = !!useBinaryBase\n\t\t\t? ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB']\n\t\t\t: ['kB','MB','GB','TB','PB','EB','ZB','YB']\n\t;\n\n\tif( bytes < thresh ){\n\t\treturn `${bytes} B`;\n\t}\n\n\tlet unitIndex = -1;\n\tdo {\n\t\tbytes /= thresh;\n\t\tunitIndex++;\n\t} while(\n\t\t(bytes >= thresh)\n\t\t&& (unitIndex < (units.length - 1))\n\t);\n\n\tbytes = `${round(bytes, precision)}`.replace('.', separator);\n\treturn `${bytes} ${units[unitIndex]}`;\n}\n\n\n\n/**\n * @namespace Units:asCurrency\n */\n\n/**\n * Renders a number as a currency value, using native Intl.NumberFormat functionality.\n *\n * @param {Number} number - the number to use as a currency amount\n * @param {?String|Array} [locale='en-US'] - locale to use, use array to define fallback; always falls back to en-US if nothing else works\n * @param {?String} [currency='USD'] - a ISO4217 currency code, such as EUR for Euro\n * @param {?String} [currencyDisplay='symbol'] - one of \"symbol\", \"narrowSymbol\", \"code\" or \"name\", defining, how the currency should be displayed in the result\n * @returns {String} the formatted currency amount\n *\n * @memberof Units:asCurrency\n * @alias asCurrency\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat\n * @see https://en.wikipedia.org/wiki/ISO_4217#List_of_ISO_4217_currency_codes\n * @example\n * asCurrency(42.666)\n * => '42.67 $'\n * asCurrency(42.666, 'de-DE', 'EUR')\n * => '42,67 €'\n */\nexport function asCurrency(number, locale='en-US', currency='USD', currencyDisplay='symbol'){\n\tnumber = parseFloat(number);\n\n\tlocale = orDefault(locale, 'en-US');\n\tif(\n\t\t(!isArray(locale) && (locale !== 'en-US'))\n\t\t|| (isArray(locale) && !locale.includes('en-US'))\n\t){\n\t\tlocale = [].concat(locale).concat('en-US');\n\t}\n\n\tcurrency = orDefault(currency, 'USD', 'str');\n\tcurrencyDisplay = orDefault(currencyDisplay, 'symbol', 'str');\n\n\treturn new Intl.NumberFormat(\n\t\tlocale,\n\t\t{\n\t\t\tstyle : 'currency',\n\t\t\tcurrency,\n\t\t\tcurrencyDisplay,\n\t\t}\n\t).format(number);\n}\n\n\n\n/**\n * @namespace Units:asDecimal\n */\n\n/**\n * Renders a number as a decimal value, using native Intl.NumberFormat functionality.\n *\n * @param {Number} number - the number to use as a decimal amount\n * @param {?String|Array} [locale='en-US'] - locale to use, use array to define fallback; always falls back to en-US if nothing else works\n * @param {?Number} [minPrecision=2] - the minimal precision to use in decimal display\n * @param {?Number} [maxPrecision=null] - the minimal precision to use in decimal display; if nullish, will be set to minPrecision\n * @returns {String} the formatted decimal amount\n *\n * @memberof Units:asDecimal\n * @alias asDecimal\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat\n * @example\n * asDecimal(42.666)\n * => '42.67'\n * asDecimal(42.666, 'de-DE', 1)\n * => '42,7'\n */\nexport function asDecimal(number, locale='en-US', minPrecision=2, maxPrecision=null){\n\tnumber = parseFloat(number);\n\n\tlocale = orDefault(locale, 'en-US');\n\tif(\n\t\t(!isArray(locale) && (locale !== 'en-US'))\n\t\t|| (isArray(locale) && !locale.includes('en-US'))\n\t){\n\t\tlocale = [].concat(locale).concat('en-US');\n\t}\n\n\tminPrecision = orDefault(minPrecision, 2, 'int');\n\tmaxPrecision = orDefault(maxPrecision, minPrecision, 'int');\n\n\treturn new Intl.NumberFormat(\n\t\tlocale,\n\t\t{\n\t\t\tstyle : 'decimal',\n\t\t\tuseGrouping : false,\n\t\t\tminimumFractionDigits : minPrecision,\n\t\t\tmaximumFractionDigits : maxPrecision\n\t\t}\n\t).format(number);\n}\n"]} \ No newline at end of file diff --git a/dist/urls.js b/dist/urls.js index 107ade9a..2fdb4708 100644 --- a/dist/urls.js +++ b/dist/urls.js @@ -1,8 +1,8 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Urls */ -const MODULE_NAME="Urls";import{hasValue,orDefault,size,assert,isFunction,isString,isArray,isObject,isPlainObject,isNaN,isEmpty}from"./basic.js";import{log}from"./logging.js";import{replace}from"./strings.js";export const COMMON_TOP_LEVEL_DOMAINS=["aero","biz","cat","com","coop","edu","gov","info","int","jobs","mil","mobi","museum","name","net","org","travel","ac","ad","ae","af","ag","ai","al","am","an","ao","aq","ar","as","at","au","aw","az","ba","bb","bd","be","bf","bg","bh","bi","bj","bm","bn","bo","br","bs","bt","bv","bw","by","bz","ca","cc","cd","cf","cg","ch","ci","ck","cl","cm","cn","co","cr","cs","cu","cv","cx","cy","cz","de","dj","dk","dm","do","dz","ec","ee","eg","eh","er","es","et","eu","fi","fj","fk","fm","fo","fr","ga","gb","gd","ge","gf","gg","gh","gi","gl","gm","gn","gp","gq","gr","gs","gt","gu","gw","gy","hk","hm","hn","hr","ht","hu","id","ie","il","im","in","io","iq","ir","is","it","je","jm","jo","jp","ke","kg","kh","ki","km","kn","kp","kr","kw","ky","kz","la","lb","lc","li","lk","lr","ls","lt","lu","lv","ly","ma","mc","md","mg","mh","mk","ml","mm","mn","mo","mp","mq","mr","ms","mt","mu","mv","mw","mx","my","mz","na","nc","ne","nf","ng","ni","nl","no","np","nr","nu","nz","om","pa","pe","pf","pg","ph","pk","pl","pm","pn","pr","ps","pt","pw","py","qa","re","ro","ru","rw","sa","sb","sc","sd","se","sg","sh","si","sj","sk","sl","sm","sn","so","sr","st","su","sv","sy","sz","tc","td","tf","tg","th","tj","tk","tm","tn","to","tp","tr","tt","tv","tw","tz","ua","ug","uk","um","us","uy","uz","va","vc","ve","vg","vi","vn","vu","wf","ws","ye","yt","yu","za","zm","zr","zw","local"];const URISON_VALUE_FORMAT="[^-0123456789 '!:(),*@$][^ '!:(),*@$]*",URISON_VALUE_REX=new RegExp(`^${URISON_VALUE_FORMAT}$`),URISON_NEXT_VALUE_REX=new RegExp(URISON_VALUE_FORMAT,"g");class UrisonParser{#e="UrisonParser";#t;#r="";#n=0;#s=null;#i;#o;constructor(e=null){const t=this;this.#t=isFunction(e)?e:null,this.#i={t:!0,f:!1,n:null,"(":this.#a},this.#o={"!":function(){const e=t.#r.charAt(t.#n++);if(""===e)return t.#l('"!" at end of input');const r=t.#i[e];return void 0===r?t.#l(`unknown literal: "!${e}"`):isFunction(r)?r.call(this):r},"(":function(){const e={};let r,n=!0;for(;")"!==(r=t.#c());){if(n){if(","===r)return t.#l('extra ","');t.#n--}else if(","!==r)return t.#l('missing ","');const s=t.#u();if(void 0===s)return;if(":"!==t.#c())return t.#l('missing ":"');const i=t.#u();if(void 0===i)return;e[s]=i,n=!1}return e},"'":function(){const e=[];let r,n=t.#n,s=t.#n;for(;"'"!==(r=t.#r.charAt(n++));){if(""===r)return t.#l('unmatched "\'"');if("!"===r){if(s="0"&&e<="9"||(o.includes(e)?o="":(i=r[`${i}+${e.toLowerCase()}`],"exp"===i&&(o="-")))}while(void 0!==i);return s--,t.#n=s,n=n.slice(e,s),"-"===n?t.#l("invalid number"):Number(n)}},function(e){for(let t=0;t<=9;t++)e[`${t}`]=e["-"]}(this.#o)}parse(e){this.#r=`${e}`,this.#n=0,this.#s=null;let t=this.#u();const r=this.#c();if(!this.#s&&void 0!==r){let n;n=/\s/.test(r)?"whitespace detected":`trailing char "${r}"`,t=this.#l(`unable to parse string "${e}", ${n}`)}return this.#s&&this.#t&&this.#t(this.#s,this.#n),t}#a(){const e=[];let t;for(;")"!==(t=this.#c());){if(""===t)return this.#l('unmatched "!("');if(isEmpty(e)){if(","===t)return this.#l('extra ","');this.#n--}else if(","!==t)return this.#l('missing ","');const r=this.#u();if(void 0===r)return;e.push(r)}return e}#u(){const e=this.#c(),t=this.#o[e];if(isFunction(t))return t.apply(this);const r=this.#n-1;URISON_NEXT_VALUE_REX.lastIndex=r;const n=URISON_NEXT_VALUE_REX.exec(this.#r);if(!isEmpty(n)){const e=n[0];return this.#n=r+e.length,e}return hasValue(e)&&""!==e?this.#l(`invalid character "${e}"`):this.#l("empty expression")}#c(){let e,t=this.#n;if(!(t>=this.#r.length))return e=this.#r.charAt(t++),this.#n=t,e}#l(e){console.error(`${this.#e} error: `,e),this.#s=e}}export function urlHref(e=null,t=null,r=null,n=!1,s=!1){if(e=orDefault(e,window.location.href,"str"),t=isPlainObject(t)?t:null,r=orDefault(r,null,"str"),n=orDefault(n,!1,"bool"),"about:blank"===e)return e;if(""===e.trim()&&(e=window.location.href),e.startsWith("//"))e=`${window.location.protocol}${e}`;else if(e.startsWith("/"))e=`${window.location.origin}${e}`;else if(e.startsWith("?")){const t=e.includes("#")?null:window.location.href.split("#")[1];e=`${window.location.href.split("?")[0]}${e}${hasValue(t)?"#"+t:""}`}else e.startsWith("#")&&(e=`${window.location.href.split("#")[0]}${e}`);let i;/^https?:\/\//.test(e)||(e=`${window.location.protocol}//${e}`);try{i=new URL(e)}catch(t){throw new Error(`Urls:urlHref | unusable URL "${e}" [${t}]`)}hasValue(r)&&(i.hash=r.startsWith("#")?r:`#${r}`);const o=i.searchParams;if(hasValue(t))for(let e in t){let r=e;e.startsWith("!")&&(r=e.slice(1)),r!==e&&o.delete(r),[].concat(t[e]).forEach((e=>{o.append(r,`${e}`)}))}if(n)for(let e of o.keys()){const t=e.replace(/\[]$/,"");let r=[].concat(o.getAll(e));e.endsWith("[]")&&(r=r.concat(o.getAll(t))),r.length>1&&(o.delete(e),o.delete(t),r.forEach((e=>{o.append(`${t}[]`,e)})))}let a=i.search.replace(/\+/g,"%20").replace(/=&/g,"&").replace(/=$/g,"");s||(a=a.replaceAll("%2B","+").replaceAll("%5B","[").replaceAll("%5D","]"));let l,c=a.startsWith("?")?a.slice(1).split("&"):[];return isEmpty(c)||(c.sort(((e,t)=>{const r=e.split("=")[0],n=t.split("=")[0];return rn?1:0})),c=c.filter(((e,t)=>!(t>=1)||c.indexOf(e)===t)),a=`?${c.join("&")}`),l=isEmpty(a)?!isEmpty(i.hash)&&isEmpty(a)?`${i.href.split("#")[0]}${i.hash}`.replace("/#","#"):i.href.replace(/\/$/,""):`${i.href.split("?")[0]}${a}${i.hash}`.replace("/?","?"),s?l:replace(l,["%2C","%3A","%40","%24","%2F","%2B"],[",",":","@","$","/","+"])}export function urlParameter(e=null,t=null){e=urlHref(e,null,null,!1,!0),t=orDefault(t,null,"str");const r=new URL(e).searchParams,n=e=>""===e||e;if(hasValue(t)){const e=r.getAll(t);return 0===e.length?null:1===e.length?n(e[0]):Array.from(new Set(e.map(n)))}{const e={};return Array.from(r.keys()).forEach((t=>{const s=r.getAll(t);s.length>0&&(e[t]=1===s.length?n(s[0]):Array.from(new Set(s.map(n))))})),size(e)>0?e:null}}export function urlParameters(e=null){return urlParameter(e)}export function urlAnchor(e=null,t=!1){e=urlHref(e),t=orDefault(t,!1,"bool");const r=e.split("#");let n=r.length>1?decodeURIComponent(r[1].trim()):null;return""===n&&(n=null),t&&hasValue(n)&&(n=`#${n}`),n}export function addNextParameter(e,t,r="next",n=!1,s=null){const i="addNextParameter";e=urlHref(e),t=urlHref(t),r=orDefault(r,"next","str"),(n=orDefault(n,!0,"bool"))&&assert(evaluateBaseDomain(new URL(e).hostname,s)===evaluateBaseDomain(new URL(t).hostname,s),`Urls:${i} | different base domains in url and next`);const o=new URL(e).searchParams;return o.has(r)&&log().info(`Urls:${i} | replaced "${r}" value "${o.get(r)}" with "${t}"`),urlHref(e,{[`!${r}`]:t})}export function addCacheBuster(e=null,t="_"){e=urlHref(e);const r=new URL(e).searchParams,n=Date.now();return r.has(t)&&log().info(`Urls:addCacheBuster | replaced "${t}" value "${r.get(t)}" with "${n}"`),urlHref(e,{[`!${t}`]:n})}export function evaluateBaseDomain(e,t=null){let r;e=orDefault(e,window.location.hostname,"str"),t=orDefault(t,null,"arr");try{r=new URL(e)}catch(e){r=null}hasValue(r)&&(e=r.hostname);const n=new Set([...COMMON_TOP_LEVEL_DOMAINS,...hasValue(t)?t.map((e=>`${e}`)):[]]),s=e.split(".").reverse();let i=e;if(s.length>2){let e;for(e=0;ee,this.#p=e?decodeURIComponent:e=>e,this.#d={array(e){const r=[];for(let n of e){const e=t.encode(n);isString(e)&&r.push(e)}return`!(${r.join(",")})`},boolean:e=>e?"!t":"!f",null:()=>"!n",number:e=>isFinite(e)?`${e}`.replace(/\+/,""):"!n",object(e){if(hasValue(e)){if(isArray(e))return this.array(e);const r=Object.keys(e);r.sort();const n=[];for(let s of r){const r=t.encode(e[s]);if(isString(r)){const e=isNaN(parseInt(s,10))?this.string(s):this.number(s);n.push(`${e}:${r}`)}}return`(${n.join(",")})`}return"!n"},string:e=>""===e?"''":URISON_VALUE_REX.test(e)?e:`'${e=e.replace(/(['!])/g,(function(e,t){return`!${t}`}))}'`},this.#f=new UrisonParser(((e,t)=>{throw Error(`decoding error [${e}] at string index ${t}`)}))}encode(e){const t="encode";isFunction(e?.toJson)&&(e=e.toJson()),isFunction(e?.toJSON)&&(e=e.toJSON());const r=this.#d[typeof e];if(!isFunction(r))throw new Error(`${this.#e}.${t} | invalid data type`);let n;try{n=r.call(this.#d,e)}catch(e){throw new Error(`${this.#e}.${t} | encoding error [${e}]`)}return this.#h(this.#p(n))}encodeObject(e){if(!isObject(e))throw new Error(`${this.#e}.encodeObject | value is not an object`);const t=this.#d.object(e);return this.#h(this.#p(t.substring(1,t.length-1)))}encodeArray(e){if(!isArray(e))throw new Error(`${this.#e}.encodeArray | value is not an array`);const t=this.#d.array(e);return this.#h(this.#p(t.substring(2,t.length-1)))}decode(e){return this.#f.parse(this.#p(e))}decodeObject(e){return this.decode(`(${e})`)}decodeArray(e){return this.decode(`!(${e})`)}escape(e){return/^[\-A-Za-z0-9~!*()_.',:@$\/+]*$/.test(e=`${e}`)?e:replace(encodeURIComponent(e),["%2C","%3A","%40","%24","%2F","%2B"],[",",":","@","$","/","+"])}}export{Urison}; +const MODULE_NAME="Urls";import{hasValue,orDefault,size,assert,isFunction,isString,isArray,isObject,isPlainObject,isNaN,isEmpty}from"./basic.js";import{log}from"./logging.js";import{replace}from"./strings.js";export const COMMON_TOP_LEVEL_DOMAINS=["aero","biz","cat","com","coop","edu","gov","info","int","jobs","mil","mobi","museum","name","net","org","travel","ac","ad","ae","af","ag","ai","al","am","an","ao","aq","ar","as","at","au","aw","az","ba","bb","bd","be","bf","bg","bh","bi","bj","bm","bn","bo","br","bs","bt","bv","bw","by","bz","ca","cc","cd","cf","cg","ch","ci","ck","cl","cm","cn","co","cr","cs","cu","cv","cx","cy","cz","de","dj","dk","dm","do","dz","ec","ee","eg","eh","er","es","et","eu","fi","fj","fk","fm","fo","fr","ga","gb","gd","ge","gf","gg","gh","gi","gl","gm","gn","gp","gq","gr","gs","gt","gu","gw","gy","hk","hm","hn","hr","ht","hu","id","ie","il","im","in","io","iq","ir","is","it","je","jm","jo","jp","ke","kg","kh","ki","km","kn","kp","kr","kw","ky","kz","la","lb","lc","li","lk","lr","ls","lt","lu","lv","ly","ma","mc","md","mg","mh","mk","ml","mm","mn","mo","mp","mq","mr","ms","mt","mu","mv","mw","mx","my","mz","na","nc","ne","nf","ng","ni","nl","no","np","nr","nu","nz","om","pa","pe","pf","pg","ph","pk","pl","pm","pn","pr","ps","pt","pw","py","qa","re","ro","ru","rw","sa","sb","sc","sd","se","sg","sh","si","sj","sk","sl","sm","sn","so","sr","st","su","sv","sy","sz","tc","td","tf","tg","th","tj","tk","tm","tn","to","tp","tr","tt","tv","tw","tz","ua","ug","uk","um","us","uy","uz","va","vc","ve","vg","vi","vn","vu","wf","ws","ye","yt","yu","za","zm","zr","zw","local"];const URISON_VALUE_FORMAT="[^-0123456789 '!:(),*@$][^ '!:(),*@$]*",URISON_VALUE_REX=new RegExp(`^${URISON_VALUE_FORMAT}$`),URISON_NEXT_VALUE_REX=new RegExp(URISON_VALUE_FORMAT,"g");class UrisonParser{#e="UrisonParser";#t;#r="";#n=0;#s=null;#i;#o;constructor(e=null){const t=this;this.#t=isFunction(e)?e:null,this.#i={t:!0,f:!1,n:null,"(":this.#a},this.#o={"!":function(){const e=t.#r.charAt(t.#n++);if(""===e)return t.#l('"!" at end of input');const r=t.#i[e];return void 0===r?t.#l(`unknown literal: "!${e}"`):isFunction(r)?r.call(this):r},"(":function(){const e={};let r,n=!0;for(;")"!==(r=t.#c());){if(n){if(","===r)return t.#l('extra ","');t.#n--}else if(","!==r)return t.#l('missing ","');const s=t.#u();if(void 0===s)return;if(":"!==t.#c())return t.#l('missing ":"');const i=t.#u();if(void 0===i)return;e[s]=i,n=!1}return e},"'":function(){const e=[];let r,n=t.#n,s=t.#n;for(;"'"!==(r=t.#r.charAt(n++));){if(""===r)return t.#l('unmatched "\'"');if("!"===r){if(s="0"&&e<="9"||(o.includes(e)?o="":(i=r[`${i}+${e.toLowerCase()}`],"exp"===i&&(o="-")))}while(void 0!==i);return s--,t.#n=s,n=n.slice(e,s),"-"===n?t.#l("invalid number"):Number(n)}},function(e){for(let t=0;t<=9;t++)e[`${t}`]=e["-"]}(this.#o)}parse(e){this.#r=`${e}`,this.#n=0,this.#s=null;let t=this.#u();const r=this.#c();if(!this.#s&&void 0!==r){let n;n=/\s/.test(r)?"whitespace detected":`trailing char "${r}"`,t=this.#l(`unable to parse string "${e}", ${n}`)}return this.#s&&this.#t&&this.#t(this.#s,this.#n),t}#a(){const e=[];let t;for(;")"!==(t=this.#c());){if(""===t)return this.#l('unmatched "!("');if(isEmpty(e)){if(","===t)return this.#l('extra ","');this.#n--}else if(","!==t)return this.#l('missing ","');const r=this.#u();if(void 0===r)return;e.push(r)}return e}#u(){const e=this.#c(),t=this.#o[e];if(isFunction(t))return t.apply(this);const r=this.#n-1;URISON_NEXT_VALUE_REX.lastIndex=r;const n=URISON_NEXT_VALUE_REX.exec(this.#r);if(!isEmpty(n)){const e=n[0];return this.#n=r+e.length,e}return hasValue(e)&&""!==e?this.#l(`invalid character "${e}"`):this.#l("empty expression")}#c(){let e,t=this.#n;if(!(t>=this.#r.length))return e=this.#r.charAt(t++),this.#n=t,e}#l(e){console.error(`${this.#e} error: `,e),this.#s=e}}export function urlHref(e=null,t=null,r=null,n=!1,s=!1){if(e=orDefault(e,window.location.href,"str"),t=isPlainObject(t)?t:null,r=orDefault(r,null,"str"),n=orDefault(n,!1,"bool"),"about:blank"===e)return e;if(""===e.trim()&&(e=window.location.href),e.startsWith("//"))e=`${window.location.protocol}${e}`;else if(e.startsWith("/"))e=`${window.location.origin}${e}`;else if(e.startsWith("?")){const t=e.includes("#")?null:window.location.href.split("#")[1];e=`${window.location.href.split("?")[0]}${e}${hasValue(t)?"#"+t:""}`}else e.startsWith("#")&&(e=`${window.location.href.split("#")[0]}${e}`);let i;/^https?:\/\//.test(e)||(e=`${window.location.protocol}//${e}`);try{i=new URL(e)}catch(t){throw new Error(`${MODULE_NAME}:urlHref | unusable URL "${e}" [${t}]`)}hasValue(r)&&(i.hash=r.startsWith("#")?r:`#${r}`);const o=i.searchParams;if(hasValue(t))for(let e in t){let r=e;e.startsWith("!")&&(r=e.slice(1)),r!==e&&o.delete(r),[].concat(t[e]).forEach((e=>{o.append(r,`${e}`)}))}if(n)for(let e of o.keys()){const t=e.replace(/\[]$/,"");let r=[].concat(o.getAll(e));e.endsWith("[]")&&(r=r.concat(o.getAll(t))),r.length>1&&(o.delete(e),o.delete(t),r.forEach((e=>{o.append(`${t}[]`,e)})))}let a=i.search.replace(/\+/g,"%20").replace(/=&/g,"&").replace(/=$/g,"");s||(a=a.replaceAll("%2B","+").replaceAll("%5B","[").replaceAll("%5D","]"));let l,c=a.startsWith("?")?a.slice(1).split("&"):[];return isEmpty(c)||(c.sort(((e,t)=>{const r=e.split("=")[0],n=t.split("=")[0];return rn?1:0})),c=c.filter(((e,t)=>!(t>=1)||c.indexOf(e)===t)),a=`?${c.join("&")}`),l=isEmpty(a)?!isEmpty(i.hash)&&isEmpty(a)?`${i.href.split("#")[0]}${i.hash}`.replace("/#","#"):i.href.replace(/\/$/,""):`${i.href.split("?")[0]}${a}${i.hash}`.replace("/?","?"),s?l:replace(l,["%2C","%3A","%40","%24","%2F","%2B"],[",",":","@","$","/","+"])}export function urlParameter(e=null,t=null){e=urlHref(e,null,null,!1,!0),t=orDefault(t,null,"str");const r=new URL(e).searchParams,n=e=>""===e||e;if(hasValue(t)){const e=r.getAll(t);return 0===e.length?null:1===e.length?n(e[0]):Array.from(new Set(e.map(n)))}{const e={};return Array.from(r.keys()).forEach((t=>{const s=r.getAll(t);s.length>0&&(e[t]=1===s.length?n(s[0]):Array.from(new Set(s.map(n))))})),size(e)>0?e:null}}export function urlParameters(e=null){return urlParameter(e)}export function urlAnchor(e=null,t=!1){e=urlHref(e),t=orDefault(t,!1,"bool");const r=e.split("#");let n=r.length>1?decodeURIComponent(r[1].trim()):null;return""===n&&(n=null),t&&hasValue(n)&&(n=`#${n}`),n}export function addNextParameter(e,t,r="next",n=!1,s=null){const i="addNextParameter";e=urlHref(e),t=urlHref(t),r=orDefault(r,"next","str"),(n=orDefault(n,!0,"bool"))&&assert(evaluateBaseDomain(new URL(e).hostname,s)===evaluateBaseDomain(new URL(t).hostname,s),`${MODULE_NAME}:${i} | different base domains in url and next`);const o=new URL(e).searchParams;return o.has(r)&&log().info(`${MODULE_NAME}:${i} | replaced "${r}" value "${o.get(r)}" with "${t}"`),urlHref(e,{[`!${r}`]:t})}export function addCacheBuster(e=null,t="_"){e=urlHref(e);const r=new URL(e).searchParams,n=Date.now();return r.has(t)&&log().info(`${MODULE_NAME}:addCacheBuster | replaced "${t}" value "${r.get(t)}" with "${n}"`),urlHref(e,{[`!${t}`]:n})}export function evaluateBaseDomain(e,t=null){let r;e=orDefault(e,window.location.hostname,"str"),t=orDefault(t,null,"arr");try{r=new URL(e)}catch(e){r=null}hasValue(r)&&(e=r.hostname);const n=new Set([...COMMON_TOP_LEVEL_DOMAINS,...hasValue(t)?t.map((e=>`${e}`)):[]]),s=e.split(".").reverse();let i=e;if(s.length>2){let e;for(e=0;ee,this.#p=e?decodeURIComponent:e=>e,this.#d={array(e){const r=[];for(let n of e){const e=t.encode(n);isString(e)&&r.push(e)}return`!(${r.join(",")})`},boolean:e=>e?"!t":"!f",null:()=>"!n",number:e=>isFinite(e)?`${e}`.replace(/\+/,""):"!n",object(e){if(hasValue(e)){if(isArray(e))return this.array(e);const r=Object.keys(e);r.sort();const n=[];for(let s of r){const r=t.encode(e[s]);if(isString(r)){const e=isNaN(parseInt(s,10))?this.string(s):this.number(s);n.push(`${e}:${r}`)}}return`(${n.join(",")})`}return"!n"},string:e=>""===e?"''":URISON_VALUE_REX.test(e)?e:`'${e=e.replace(/(['!])/g,(function(e,t){return`!${t}`}))}'`},this.#f=new UrisonParser(((e,t)=>{throw Error(`decoding error [${e}] at string index ${t}`)}))}encode(e){const t="encode";isFunction(e?.toJson)&&(e=e.toJson()),isFunction(e?.toJSON)&&(e=e.toJSON());const r=this.#d[typeof e];if(!isFunction(r))throw new Error(`${this.#e}.${t} | invalid data type`);let n;try{n=r.call(this.#d,e)}catch(e){throw new Error(`${this.#e}.${t} | encoding error [${e}]`)}return this.#h(this.#p(n))}encodeObject(e){if(!isObject(e))throw new Error(`${this.#e}.encodeObject | value is not an object`);const t=this.#d.object(e);return this.#h(this.#p(t.substring(1,t.length-1)))}encodeArray(e){if(!isArray(e))throw new Error(`${this.#e}.encodeArray | value is not an array`);const t=this.#d.array(e);return this.#h(this.#p(t.substring(2,t.length-1)))}decode(e){return this.#f.parse(this.#p(e))}decodeObject(e){return this.decode(`(${e})`)}decodeArray(e){return this.decode(`!(${e})`)}escape(e){return/^[\-A-Za-z0-9~!*()_.',:@$\/+]*$/.test(e=`${e}`)?e:replace(encodeURIComponent(e),["%2C","%3A","%40","%24","%2F","%2B"],[",",":","@","$","/","+"])}}export{Urison}; //# sourceMappingURL=urls.js.map diff --git a/dist/urls.js.map b/dist/urls.js.map index 1374e256..3be32662 100644 --- a/dist/urls.js.map +++ b/dist/urls.js.map @@ -1 +1 @@ -{"version":3,"file":"urls.js","names":["MODULE_NAME","hasValue","orDefault","size","assert","isFunction","isString","isArray","isObject","isPlainObject","isNaN","isEmpty","log","replace","COMMON_TOP_LEVEL_DOMAINS","URISON_VALUE_FORMAT","URISON_VALUE_REX","RegExp","URISON_NEXT_VALUE_REX","UrisonParser","__className__","errorHandler","string","index","message","bangTokens","tokenMap","constructor","instance","this","t","f","n","parseArray","char","charAt","error","value","undefined","call","res","first","next","key","readValue","segments","i","start","push","slice","includes","length","join","numberTypeMap","s","numberType","permittedSigns","toLowerCase","Number","parse","risonString","trailingChar","detailMessage","test","mapper","apply","lastIndex","matches","exec","id","console","urlHref","url","params","anchor","markListParams","keepEncodedUrlSafeChars","window","location","href","trim","startsWith","protocol","origin","anchorPart","split","urlObj","URL","ex","Error","hash","urlParams","searchParams","paramName","overrideName","delete","concat","forEach","paramValue","append","k","keys","cleanKey","presentValues","getAll","endsWith","v","query","search","replaceAll","finalUrl","queryParts","sort","a","b","aKey","bKey","filter","part","indexOf","urlParameter","parameter","fMapParameterValue","parameterValue","parameterValues","Array","from","Set","map","parameters","parameterName","urlParameters","urlAnchor","withCaret","urlParts","decodeURIComponent","addNextParameter","assertSameBaseDomain","additionalTopLevelDomains","__methodName__","evaluateBaseDomain","hostname","has","info","get","addCacheBuster","buster","Date","now","domain","topLevelDomains","tld","domainParts","reverse","baseDomain","Urison","autoEscape","autoUnescape","encoders","parser","escape","val","array","encodedValue","encode","boolean","null","number","isFinite","object","Object","parseInt","_","quotedChar","toJson","toJSON","encoder","encodeObject","substring","encodeArray","decode","decodeObject","decodeArray","encodeURIComponent"],"sources":["urls.js"],"mappings":"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","sourcesContent":["/*!\n * Module Urls\n */\n\n/**\n * @namespace Urls\n */\n\nconst MODULE_NAME = 'Urls';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {\n\thasValue,\n\torDefault,\n\tsize,\n\tassert,\n\tisFunction,\n\tisString,\n\tisArray,\n\tisObject,\n\tisPlainObject,\n\tisNaN,\n\tisEmpty\n} from './basic.js';\nimport {log} from './logging.js';\nimport {replace} from './strings.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const COMMON_TOP_LEVEL_DOMAINS = [\n\t'aero', 'biz', 'cat', 'com', 'coop', 'edu', 'gov', 'info', 'int', 'jobs', 'mil', 'mobi', 'museum', 'name', 'net',\n\t'org', 'travel', 'ac', 'ad', 'ae', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao', 'aq', 'ar', 'as', 'at', 'au', 'aw',\n\t'az', 'ba', 'bb', 'bd', 'be', 'bf', 'bg', 'bh', 'bi', 'bj', 'bm', 'bn', 'bo', 'br', 'bs', 'bt', 'bv', 'bw', 'by',\n\t'bz', 'ca', 'cc', 'cd', 'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'cr', 'cs', 'cu', 'cv', 'cx', 'cy',\n\t'cz', 'de', 'dj', 'dk', 'dm', 'do', 'dz', 'ec', 'ee', 'eg', 'eh', 'er', 'es', 'et', 'eu', 'fi', 'fj', 'fk', 'fm',\n\t'fo', 'fr', 'ga', 'gb', 'gd', 'ge', 'gf', 'gg', 'gh', 'gi', 'gl', 'gm', 'gn', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu',\n\t'gw', 'gy', 'hk', 'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il', 'im', 'in', 'io', 'iq', 'ir', 'is', 'it', 'je',\n\t'jm', 'jo', 'jp', 'ke', 'kg', 'kh', 'ki', 'km', 'kn', 'kp', 'kr', 'kw', 'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk',\n\t'lr', 'ls', 'lt', 'lu', 'lv', 'ly', 'ma', 'mc', 'md', 'mg', 'mh', 'mk', 'ml', 'mm', 'mn', 'mo', 'mp', 'mq', 'mr',\n\t'ms', 'mt', 'mu', 'mv', 'mw', 'mx', 'my', 'mz', 'na', 'nc', 'ne', 'nf', 'ng', 'ni', 'nl', 'no', 'np', 'nr', 'nu',\n\t'nz', 'om', 'pa', 'pe', 'pf', 'pg', 'ph', 'pk', 'pl', 'pm', 'pn', 'pr', 'ps', 'pt', 'pw', 'py', 'qa', 're', 'ro',\n\t'ru', 'rw', 'sa', 'sb', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sl', 'sm', 'sn', 'so', 'sr', 'st', 'su',\n\t'sv', 'sy', 'sz', 'tc', 'td', 'tf', 'tg', 'th', 'tj', 'tk', 'tm', 'tn', 'to', 'tp', 'tr', 'tt', 'tv', 'tw', 'tz',\n\t'ua', 'ug', 'uk', 'um', 'us', 'uy', 'uz', 'va', 'vc', 've', 'vg', 'vi', 'vn', 'vu', 'wf', 'ws', 'ye', 'yt', 'yu',\n\t'za', 'zm', 'zr', 'zw', 'local'\n];\n\nconst\n\tURISON_VALUE_FORMAT = `[^\\-0123456789 '!:(),*@$][^ '!:(),*@$]*`,\n\tURISON_VALUE_REX = new RegExp(`^${URISON_VALUE_FORMAT}$`),\n\tURISON_NEXT_VALUE_REX = new RegExp(URISON_VALUE_FORMAT, 'g')\n;\n\n\n\n//###[ HELPERS ]########################################################################################################\n\n/**\n * A parser to translate a Rison string such as `'(key1:value,key2:!t,key3:!(!f,42,!n))'` into its\n * JSON object/array representation `{key1 : 'value', key2 : true, key3 : [false, 42, null]}`. This is a helper class\n * for the public Urison class below.\n *\n * @protected\n * @memberof Urls\n * @name UrisonParser\n *\n * @see https://github.com/Nanonid/rison\n * @example\n * new UrisonParser(error => { console.error(error); });\n */\nclass UrisonParser {\n\n\t#__className__ = 'UrisonParser';\n\t#errorHandler;\n\t#string = '';\n\t#index = 0;\n\t#message = null;\n\t#bangTokens;\n\t#tokenMap;\n\n\t/**\n\t * Creates a new UrisonParser instance.\n\t *\n\t * All errors in this class result in a console error message rather than an exception. To work with occurring\n\t * errors, define an errorCallback for the constructor and throw errors from there if needed.\n\t *\n\t * @param {Function} [errorHandler=null] - function to call in case parsing fails, receives the error message and the character index as parameters\n\t */\n\tconstructor(errorHandler=null){\n\t\tconst instance = this;\n\n\t\tthis.#errorHandler = isFunction(errorHandler) ? errorHandler : null;\n\n\t\t// syntax tokens preceded with a \"!\" and the values they represent in JSON\n\t\tthis.#bangTokens = {\n\t\t\t't' : true,\n\t\t\t'f' : false,\n\t\t\t'n' : null,\n\t\t\t'(' : this.#parseArray\n\t\t};\n\n\t\t// syntax structure tokens and the procedures, that transform these tokens into json structure\n\t\tthis.#tokenMap = {\n\t\t\t'!' : function(){\n\t\t\t\tconst char = instance.#string.charAt(instance.#index++);\n\t\t\t\tif( char === '' ) return instance.#error('\"!\" at end of input');\n\n\t\t\t\tconst value = instance.#bangTokens[char];\n\t\t\t\tif( value === undefined ) return instance.#error(`unknown literal: \"!${char}\"`);\n\t\t\t\tif( isFunction(value) ) return value.call(this);\n\n\t\t\t\treturn value;\n\t\t\t},\n\n\t\t\t'(' : function(){\n\t\t\t\tconst res = {};\n\t\t\t\tlet\n\t\t\t\t\tfirst = true,\n\t\t\t\t\tchar\n\t\t\t\t;\n\n\t\t\t\twhile( (char = instance.#next()) !== ')' ){\n\t\t\t\t\tif( !first ){\n\t\t\t\t\t\tif( char !== ',' ){\n\t\t\t\t\t\t\treturn instance.#error('missing \",\"');\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if( char === ',' ){\n\t\t\t\t\t\treturn instance.#error('extra \",\"');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tinstance.#index--;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst key = instance.#readValue();\n\t\t\t\t\tif( key === undefined ) return undefined;\n\t\t\t\t\tif( instance.#next() !== ':' ) return instance.#error('missing \":\"');\n\n\t\t\t\t\tconst value = instance.#readValue();\n\t\t\t\t\tif( value === undefined ) return undefined;\n\t\t\t\t\tres[key] = value;\n\n\t\t\t\t\tfirst = false;\n\t\t\t\t}\n\n\t\t\t\treturn res;\n\t\t\t},\n\n\t\t\t\"'\" : function(){\n\t\t\t\tconst segments = [];\n\t\t\t\tlet\n\t\t\t\t\ti = instance.#index,\n\t\t\t\t\tstart = instance.#index,\n\t\t\t\t\tchar\n\t\t\t\t;\n\n\t\t\t\twhile( (char = instance.#string.charAt(i++)) !== \"'\" ){\n\t\t\t\t\tif( char === '' ) return instance.#error(`unmatched \"'\"`);\n\t\t\t\t\tif( char === '!' ){\n\t\t\t\t\t\tif( start < (i - 1) ){\n\t\t\t\t\t\t\tsegments.push(instance.#string.slice(start, i - 1));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchar = instance.#string.charAt(i++);\n\t\t\t\t\t\tif( ['!', \"'\"].includes(char) ){\n\t\t\t\t\t\t\tsegments.push(char);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn instance.#error(`invalid string escape: \"!${char}\"`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstart = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif( start < (i - 1) ){\n\t\t\t\t\tsegments.push(instance.#string.slice(start, i - 1));\n\t\t\t\t}\n\t\t\t\tinstance.#index = i;\n\n\t\t\t\treturn (segments.length === 1) ? segments[0] : segments.join('');\n\t\t\t},\n\n\t\t\t'-' : function(){\n\t\t\t\tconst\n\t\t\t\t\tstart = instance.#index - 1,\n\t\t\t\t\tnumberTypeMap = {\n\t\t\t\t\t\t'int+.' : 'frac',\n\t\t\t\t\t\t'int+e' : 'exp',\n\t\t\t\t\t\t'frac+e' : 'exp'\n\t\t\t\t\t}\n\t\t\t\t;\n\t\t\t\tlet\n\t\t\t\t\ts = instance.#string,\n\t\t\t\t\ti = instance.#index,\n\t\t\t\t\tnumberType = 'int',\n\t\t\t\t\tpermittedSigns = '-'\n\t\t\t\t;\n\n\t\t\t\tdo {\n\t\t\t\t\tconst char = s.charAt(i++);\n\t\t\t\t\tif( char === '' ) break;\n\t\t\t\t\tif( (char >= '0') && (char <= '9') ) continue;\n\t\t\t\t\tif( permittedSigns.includes(char) ){\n\t\t\t\t\t\tpermittedSigns = '';\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tnumberType = numberTypeMap[`${numberType}+${char.toLowerCase()}`];\n\t\t\t\t\tif( numberType === 'exp' ){\n\t\t\t\t\t\tpermittedSigns = '-';\n\t\t\t\t\t}\n\t\t\t\t} while( numberType !== undefined );\n\n\t\t\t\ti--;\n\t\t\t\tinstance.#index = i;\n\t\t\t\ts = s.slice(start, i);\n\t\t\t\tif( s === '-' ) return instance.#error('invalid number');\n\t\t\t\treturn Number(s);\n\t\t\t}\n\t\t};\n\n\t\t(function(tokenMap){\n\t\t\tfor( let i = 0; i <= 9; i++ ){\n\t\t\t\ttokenMap[`${i}`] = tokenMap['-'];\n\t\t\t}\n\t\t})(this.#tokenMap);\n\t}\n\n\n\n\t/**\n\t * Parses a Rison string into a JSON object.\n\t * Resets internal parsing info, like parsing index, to start new parsing process.\n\t *\n\t * @param {String} risonString - the string to parse\n\t * @returns {Object|Array|undefined} the parsed JSON object or undefined, in case parsing failed\n\t *\n\t * @example\n\t * (new UrisonParser()).parse('(key1:value,key2:!t,key3:!(!f,42,!n))')\n\t * => {key1 : 'value', key2 : true, key3 : [false, 42, null]}\n\t */\n\tparse(risonString){\n\t\tthis.#string = `${risonString}`;\n\t\tthis.#index = 0;\n\t\tthis.#message = null;\n\n\t\tlet value = this.#readValue();\n\n\t\tconst trailingChar = this.#next();\n\t\tif( !this.#message && (trailingChar !== undefined) ){\n\t\t\tlet detailMessage;\n\t\t\tif( /\\s/.test(trailingChar) ){\n\t\t\t\tdetailMessage = 'whitespace detected';\n\t\t\t} else {\n\t\t\t\tdetailMessage = `trailing char \"${trailingChar}\"`;\n\t\t\t}\n\t\t\tvalue = this.#error(`unable to parse string \"${risonString}\", ${detailMessage}`);\n\t\t}\n\n\t\tif( this.#message && this.#errorHandler ){\n\t\t\tthis.#errorHandler(this.#message, this.#index);\n\t\t}\n\n\t\treturn value;\n\t}\n\n\n\n\t/**\n\t * Parses the structure of an array. Is a helper function for #parse/#readValue.\n\t * Works with previously set internal parsing info such as string and parsing index.\n\t *\n\t * @returns {Array|undefined} the parsed array or undefined, in case parsing failed\n\t *\n\t * @private\n\t * @example\n\t * this.#parseArray()\n\t * => [true, null, 'value']\n\t */\n\t#parseArray(){\n\t\tconst res = [];\n\t\tlet char;\n\n\t\twhile( (char = this.#next()) !== ')' ){\n\t\t\tif( char === '' ) return this.#error('unmatched \"!(\"');\n\n\t\t\tif( !isEmpty(res) ){\n\t\t\t\tif( char !== ',' ){\n\t\t\t\t\treturn this.#error('missing \",\"');\n\t\t\t\t}\n\t\t\t} else if( char === ',' ){\n\t\t\t\treturn this.#error('extra \",\"');\n\t\t\t} else {\n\t\t\t\tthis.#index--;\n\t\t\t}\n\n\t\t\tconst value = this.#readValue();\n\t\t\tif( value === undefined ) return undefined;\n\t\t\tres.push(value);\n\t\t}\n\n\t\treturn res;\n\t}\n\n\n\n\t/**\n\t * Either reads the next value or key in the current parser string or triggers recursive handling of syntax tokens.\n\t * Progresses parsing to the next section so to speak.\n\t *\n\t * @returns {Object|Array|String|Number|Boolean|null|undefined} the parsed value or undefined if parsing failed\n\t *\n\t * @private\n\t * @example\n\t * this.#readValue()\n\t * => 'valueorkeyorstructure'\n\t */\n\t#readValue(){\n\t\tconst\n\t\t\tchar = this.#next(),\n\t\t\tmapper = this.#tokenMap[char]\n\t\t;\n\n\t\tif( isFunction(mapper) ) return mapper.apply(this);\n\n\t\tconst i = this.#index - 1;\n\t\tURISON_NEXT_VALUE_REX.lastIndex = i;\n\t\tconst matches = URISON_NEXT_VALUE_REX.exec(this.#string);\n\t\tif( !isEmpty(matches) ){\n\t\t\tconst id = matches[0];\n\t\t\tthis.#index = i + id.length;\n\t\t\treturn id;\n\t\t}\n\n\t\tif( hasValue(char) && (char !== '') ) return this.#error(`invalid character \"${char}\"`);\n\t\treturn this.#error('empty expression');\n\t}\n\n\n\n\t/**\n\t * Reads the next character of the currently given Rison string, increments the index\n\t * and returns the character.\n\t *\n\t * @returns {String|undefined} the next character or undefined if there is none\n\t *\n\t * @private\n\t * @example\n\t * this.#next()\n\t * => '!'\n\t */\n\t#next(){\n\t\tlet\n\t\t\ti = this.#index,\n\t\t\tchar\n\t\t;\n\n\t\tif( i >= this.#string.length ) return undefined;\n\t\tchar = this.#string.charAt(i++);\n\t\tthis.#index = i;\n\n\t\treturn char;\n\t}\n\n\n\n\t/**\n\t * Sets the error message and writes it to `console.error()` for info purposes.\n\t * This method does _not_ throw an exception, for this, please set an error handler\n\t * in the constructor and throw it externally.\n\t *\n\t * @param {String} message - the error message\n\t * @returns {undefined} is always undefined to be uniform return value for failed value parsing in case of error\n\t *\n\t * @private\n\t * @example\n\t * this.#error('oh noez')\n\t * => undefined\n\t */\n\t#error(message){\n\t\tconsole.error(`${this.#__className__} error: `, message);\n\t\tthis.#message = message;\n\t\treturn undefined;\n\t}\n\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Urls:urlHref\n */\n\n/**\n * Will return a fully qualified URL based on the given URL base string for use as a href/source-value\n * or navigation target.\n *\n * Provide a base URL or leave the URL out, to use the current URL.\n * Add GET-parameters (adding to those already present in the URL), define an anchor (or automatically get the one\n * defined in the URL).\n *\n * Provided URLs are handled with some automagic:\n * - a URL starting with \"//\" will receive the current page protocol\n * - a URL starting with a single \"/\" will be seen as relative and will be expanded to an absolute URL, based\n * on the current URL\n * - a URL starting with \"?\" will be treated as a singular query string, resulting in the query being added to the\n * current URL, replacing any present query\n * - a URL starting with \"#\" will be treated as a singular hash string, resulting in the hash being added to the\n * current URL, replacing any present hash\n * - if, after all automagic applied, the URL still does not start with a http-protocol, the current page's protocol\n * will be added\n *\n * Provided params have to be a flat plain object, with ordinal values or arrays of ordinal values on the first level.\n * Everything else will be stringified and url-encoded as is. Usually, parameters defined here add to present\n * parameters in the URL. To force-override present values, declare the param name with a \"!\" prefix\n * (`{'!presentparam' : 'new'}`).\n *\n * This method implements some quality-of-life improvements, that differ from the native result of `new URL().href`:\n * - `+`-encoding for whitespace is replaced with `%20`, while `+` will stay what it is, a verbatim URL-safe character\n * with repeating keys (`tags=1&tags=2&tags=3`)\n * - empty parameters are rendered without \"=\". So, \"?test=&foo\" will be \"?test&foo\"\n * - `path/?` will become just `path?`\n * - `path/#` will become just `path#`\n * - trailing slashes will be removed\n * - parameters will be sorted alphabetically by keys\n * (value order will be kept if possible, might change, when using markListParams)\n * - identical key/value pairs will be reduced to one occurrence, so `?q=a&q=a` will become `?q=a`\n *\n * @param {?String|URL} [url=null] - the base URL to use, if nullish current location is used\n * @param {?Object} [params=null] - plain object of GET-parameters to add to the url\n * @param {?String} [anchor=null] - anchor/hash to set, has precedence over URL hash\n * @param {?Boolean} [markListParams=false] - if true, params with more than one value will be marked with \"[]\" preceding the param name\n * @param {?Boolean} [keepEncodedUrlSafeChars=false] - if true, encoded chars, which are URL-safe, are kept encoded, instead of being returned raw\n * @throws error if url is not usable\n * @returns {String} the created URL including parameters and anchor\n *\n * @memberof Urls:urlHref\n * @alias urlHref\n * @example\n * buildUrl('https://test.com', {search : 'kittens', order : 'asc'}, 'fluffykittens');\n * => 'https://test.com?search=kittens&order=asc#fluffykittens'\n * buildUrl(null, {order : 'desc'});\n * => 'https://current.url?order=desc'\n */\nexport function urlHref(url=null, params=null, anchor=null, markListParams=false, keepEncodedUrlSafeChars=false){\n\tconst __methodName__ = 'urlHref';\n\n\turl = orDefault(url, window.location.href, 'str');\n\tparams = isPlainObject(params) ? params : null;\n\tanchor = orDefault(anchor, null, 'str');\n\tmarkListParams = orDefault(markListParams, false, 'bool');\n\n\tif( url === 'about:blank' ) return url;\n\tif( url.trim() === '' ){\n\t\turl = window.location.href;\n\t}\n\tif( url.startsWith('//') ){\n\t\turl = `${window.location.protocol}${url}`;\n\t} else if( url.startsWith('/') ){\n\t\turl = `${window.location.origin}${url}`;\n\t} else if( url.startsWith('?') ){\n\t\tconst anchorPart = !url.includes('#') ? window.location.href.split('#')[1] : null;\n\t\turl = `${window.location.href.split('?')[0]}${url}${hasValue(anchorPart) ? '#'+anchorPart : ''}`;\n\t} else if( url.startsWith('#') ){\n\t\turl = `${window.location.href.split('#')[0]}${url}`;\n\t}\n\tif( !(/^https?:\\/\\//.test(url)) ){\n\t\turl = `${window.location.protocol}//${url}`;\n\t}\n\n\tlet urlObj;\n\ttry {\n\t\turlObj = new URL(url);\n\t} catch(ex){\n\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | unusable URL \"${url}\" [${ex}]`);\n\t}\n\n\tif( hasValue(anchor) ){\n\t\turlObj.hash = anchor.startsWith('#') ? anchor : `#${anchor}`;\n\t}\n\n\tconst urlParams = urlObj.searchParams;\n\n\tif( hasValue(params) ){\n\t\tfor( let paramName in params ){\n\t\t\tlet overrideName = paramName;\n\t\t\tif( paramName.startsWith('!') ){\n\t\t\t\toverrideName = paramName.slice(1);\n\t\t\t}\n\n\t\t\tif( overrideName !== paramName ){\n\t\t\t\turlParams.delete(overrideName);\n\t\t\t}\n\n\t\t\t[].concat(params[paramName]).forEach(paramValue => {\n\t\t\t\turlParams.append(overrideName, `${paramValue}`);\n\t\t\t});\n\t\t}\n\t}\n\n\tif( markListParams ){\n\t\tfor( let k of urlParams.keys() ){\n\t\t\tconst cleanKey = k.replace(/\\[]$/, '');\n\n\t\t\tlet presentValues = [].concat(urlParams.getAll(k));\n\t\t\tif( k.endsWith('[]') ){\n\t\t\t\tpresentValues = presentValues.concat(urlParams.getAll(cleanKey));\n\t\t\t}\n\n\t\t\tif( (presentValues.length > 1) ){\n\t\t\t\turlParams.delete(k);\n\t\t\t\turlParams.delete(cleanKey);\n\t\t\t\tpresentValues.forEach(v => {\n\t\t\t\t\turlParams.append(`${cleanKey}[]`, v);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tlet\tquery = urlObj.search\n\t\t.replace(/\\+/g, '%20')\n\t\t.replace(/=&/g, '&')\n\t\t.replace(/=$/g, '')\n\t;\n\n\tif( !keepEncodedUrlSafeChars ){\n\t\tquery = query\n\t\t\t.replaceAll('%2B', '+')\n\t\t\t.replaceAll('%5B', '[')\n\t\t\t.replaceAll('%5D', ']')\n\t\t;\n\t}\n\n\tlet queryParts = query.startsWith('?') ? query.slice(1).split('&') : []\n\tif( !isEmpty(queryParts) ){\n\t\tqueryParts.sort((a, b) => {\n\t\t\tconst\n\t\t\t\taKey = a.split('=')[0],\n\t\t\t\tbKey = b.split('=')[0]\n\t\t\t;\n\t\t\treturn (aKey < bKey) ? -1 : ((aKey > bKey) ? 1 : 0 );\n\t\t});\n\t\tqueryParts = queryParts.filter((part, index) => {\n\t\t\tif( index >= 1 ){\n\t\t\t\treturn queryParts.indexOf(part) === index;\n\t\t\t} else {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t});\n\t\tquery = `?${queryParts.join('&')}`;\n\t}\n\n\tlet finalUrl;\n\tif( !isEmpty(query) ){\n\t\tfinalUrl = `${urlObj.href.split('?')[0]}${query}${urlObj.hash}`.replace('/?', '?');\n\t} else if( !isEmpty(urlObj.hash) && isEmpty(query) ){\n\t\tfinalUrl = `${urlObj.href.split('#')[0]}${urlObj.hash}`.replace('/#', '#');\n\t} else {\n\t\tfinalUrl = urlObj.href.replace(/\\/$/, '');\n\t}\n\n\treturn keepEncodedUrlSafeChars ? finalUrl : replace(\n\t\tfinalUrl,\n\t\t['%2C', '%3A', '%40', '%24', '%2F', '%2B'],\n\t\t[',', ':', '@', '$', '/', '+']\n\t);\n}\n\n\n\n/**\n * @namespace Urls:urlParameter\n */\n\n/**\n * Searches for and returns parameters embedded in the provided url containing a query string\n * (make sure all values are url encoded).\n *\n * You may also just provide the query string.\n *\n * Returns a single parameter's value if a parameter name is given, otherwise returns dictionary with all parameters\n * as keys and the associated parameter value.\n *\n * If a parameter has more than one value the values are returned as an array, whether being requested by name\n * or in the dictionary containing all params.\n *\n * If a parameter is set, but has no defined value (name present, but no = before next param)\n * the value is returned as boolean true.\n *\n * @param {?String|URL} [url=null] - the url containing the parameter string, will use current URL if nullish\n * @param {?String} [parameter=null] - the name of the parameter to extract\n * @throws error if given url is not usable\n * @returns {null|true|String|Array|Object} null in case the parameter doesn't exist, true in case it exists but has no value, a string in case the parameter has one value, or an array of values, or a dictionary object of all available parameters with corresponding values\n *\n * @memberof Urls:urlParameter\n * @alias urlParameter\n * @see urlHref\n * @example\n * const hasKittens = urlParameter('//foobar.com/bar?has_kittens', 'has_kittens');\n * => true\n * const hasDoggies = urlParameter('has_doggies=yes&has_doggies', 'has_doggies');\n * => ['yes', true]\n * const allTheData = urlParameter('?foo=foo&bar=bar&bar=barbar&bar');\n * => {foo : 'foo', bar : ['bar', 'barbar', true]}\n */\nexport function urlParameter(url=null, parameter=null){\n\turl = urlHref(url, null, null, false, true);\n\tparameter = orDefault(parameter, null, 'str');\n\n\tconst\n\t\tsearchParams = new URL(url).searchParams,\n\t\tfMapParameterValue = parameterValue => ((parameterValue === '') ? true : parameterValue)\n\t;\n\n\tif( hasValue(parameter) ){\n\t\tconst parameterValues = searchParams.getAll(parameter);\n\t\tif( parameterValues.length === 0 ){\n\t\t\treturn null;\n\t\t} else if( parameterValues.length === 1 ){\n\t\t\treturn fMapParameterValue(parameterValues[0]);\n\t\t} else {\n\t\t\treturn Array.from(new Set(parameterValues.map(fMapParameterValue)));\n\t\t}\n\t} else {\n\t\tconst parameters = {};\n\t\tArray.from(searchParams.keys()).forEach(parameterName => {\n\t\t\tconst parameterValues = searchParams.getAll(parameterName);\n\t\t\tif( parameterValues.length > 0 ){\n\t\t\t\tparameters[parameterName] =\n\t\t\t\t\t(parameterValues.length === 1)\n\t\t\t\t\t? fMapParameterValue(parameterValues[0])\n\t\t\t\t\t: Array.from(new Set(parameterValues.map(fMapParameterValue)))\n\t\t\t\t;\n\t\t\t}\n\t\t});\n\t\treturn (size(parameters) > 0) ? parameters : null;\n\t}\n}\n\n\n\n/**\n * @namespace Urls:urlParameters\n */\n\n/**\n * Searches for and returns parameters embedded in provided url with a parameter string.\n *\n * Semantic shortcut version of urlParameter without any given parameter.\n *\n * @param {?String|URL} [url=null] - the url containing the parameter string, will use current URL if nullish\n * @throws error if given url is not usable\n * @returns {Object|null} dictionary object of all parameters or null if url has no parameters\n *\n * @memberof Urls:urlParameters\n * @alias urlParameters\n * @see urlParameter\n * @example\n * const allParams = urlParameters('http://www.foobar.com?foo=foo&bar=bar&bar=barbar&bar');\n * => {foo : 'foo', bar : ['bar', 'barbar', true]}\n */\nexport function urlParameters(url=null){\n\treturn urlParameter(url);\n}\n\n\n\n/**\n * @namespace Urls:urlAnchor\n */\n\n/**\n * Returns the currently set URL-Anchor on given URL.\n *\n * Theoretically, this function also works with any other string containing a hash (as long as there is \"#\" included),\n * since this implementation does not lean on \"new URL()\", but is a simple string operation.\n *\n * In comparison to \"location.hash\", this function actually decodes the hash automatically.\n *\n * @param {?String|URL} [url=null] - the url, in which to search for a hash, uses current url if nullish\n * @param {?Boolean} [withCaret=false] - defines if the returned anchor value should contain leading \"#\"\n * @throws error if given url is not usable\n * @returns {String|null} current anchor value or null if no anchor was found\n *\n * @memberof Urls:urlAnchor\n * @alias urlAnchor\n * @example\n * const anchorWithoutCaret = urlAnchor('https://foobar.com#test');\n * => 'test'\n * const hrefAnchorWithCaret = urlAnchor(linkElement.getAttribute('href'), true);\n * => '#test'\n * const decodedAnchorFromLocation = urlAnchor(window.location.hash);\n */\nexport function urlAnchor(url=null, withCaret=false){\n\turl = urlHref(url);\n\twithCaret = orDefault(withCaret, false, 'bool');\n\n\tconst urlParts = url.split('#');\n\n\tlet anchor = (urlParts.length > 1) ? decodeURIComponent(urlParts[1].trim()) : null;\n\tif( anchor === '' ){\n\t\tanchor = null;\n\t}\n\tif( withCaret && hasValue(anchor) ){\n\t\tanchor = `#${anchor}`;\n\t}\n\n\treturn anchor;\n}\n\n\n\n/**\n * @namespace Urls:addNextParameter\n */\n\n/**\n * Adds a \"next\"-parameter to a given URL. If there is already a parameter of that name, it will be replaced.\n *\n * A \"next\"-parameter is usually used to relay a second URL, which should be redirected to after something happens,\n * such as a login or another (possibly automatic) action.\n *\n * @param {?String} [url=''] - the URL to add the next parameter to, if left empty, will be \"\", which is synonymous with the current URL\n * @param {?String} [next=''] - the next URL to add as parameter to the given URL (will automatically be URL-encoded)\n * @param {?String} [paramName='next'] - the name of the next parameter\n * @param {?Boolean} [assertSameBaseDomain=false] - if true, url and next must have the same base domain (ignoring subdomains), to prevent injections\n * @param {?Array} [additionalTopLevelDomains=null] - this function uses a list of common TLDs (if assertSameBaseDomain is true), if yours is missing, you may provide it, using this parameter\n * @throws error if url or next are not usable URLs\n * @throws error if assertBaseDomain is true an the base domains of url and next differ\n * @returns {String} the transformed URL with the added next parameter\n *\n * @memberof Urls:addNextParameter\n * @alias addNextParameter\n * @see urlHref\n * @example\n * addNextParameter('https://foobar.com', 'https://foo.bar', 'redirect');\n * => 'https://foobar.com?redirect=https%3A%2F%2Ffoo.bar'\n * addNextParameter('https://foobar.com?next=https%3A%2F%2Ffoo.bar', 'https://kittens.com');\n * => 'https://foobar.com?next=https%3A%2F%2Fkittens.com'\n */\nexport function addNextParameter(url, next, paramName='next', assertSameBaseDomain=false, additionalTopLevelDomains=null){\n\tconst __methodName__ = 'addNextParameter';\n\n\turl = urlHref(url);\n\tnext = urlHref(next);\n\tparamName = orDefault(paramName, 'next', 'str');\n\tassertSameBaseDomain = orDefault(assertSameBaseDomain, true, 'bool');\n\n\tif( assertSameBaseDomain ){\n\t\tassert(\n\t\t\tevaluateBaseDomain(new URL(url).hostname, additionalTopLevelDomains) === evaluateBaseDomain(new URL(next).hostname, additionalTopLevelDomains),\n\t\t\t`${MODULE_NAME}:${__methodName__} | different base domains in url and next`\n\t\t);\n\t}\n\n\tconst params = new URL(url).searchParams;\n\tif( params.has(paramName) ){\n\t\tlog().info(`${MODULE_NAME}:${__methodName__} | replaced \"${paramName}\" value \"${params.get(paramName)}\" with \"${next}\"`);\n\t}\n\n\treturn urlHref(url, {[`!${paramName}`] : next});\n}\n\n\n\n/**\n * @namespace Urls:addCacheBuster\n */\n\n/**\n * Adds a cache busting parameter to a given URL. If there is already a parameter of that name, it will be replaced.\n * This prevents legacy browsers from caching requests by changing the request URL dynamically, based on current time.\n *\n * @param {?String|URL} [url=null] - the URL to add the cache busting parameter to, if nullish, the current URL will be used\n * @param {?String} [paramName='_'] - the name of the cache busting parameter\n * @throws error if url is not a usable URL\n * @returns {String} the transformed URL with the added cache busting parameter\n *\n * @memberof Urls:addCacheBuster\n * @alias addCacheBuster\n * @see urlHref\n * @example\n * addCacheBuster('https://foobar.com');\n * => 'https://foobar.com?_=1648121948009'\n * addCacheBuster('https://foobar.com?next=https%3A%2F%2Ffoo.bar', 'nocache');\n * => 'https://foobar.com?next=https%3A%2F%2Ffoo.bar&nocache=1648121948009'\n */\nexport function addCacheBuster(url=null, paramName='_'){\n\tconst __methodName__ = 'addCacheBuster';\n\n\turl = urlHref(url);\n\n\tconst\n\t\tparams = new URL(url).searchParams,\n\t\tbuster = Date.now()\n\t;\n\n\tif( params.has(paramName) ){\n\t\tlog().info(`${MODULE_NAME}:${__methodName__} | replaced \"${paramName}\" value \"${params.get(paramName)}\" with \"${buster}\"`);\n\t}\n\n\treturn urlHref(url, {[`!${paramName}`] : buster})\n}\n\n\n\n/**\n * @namespace Urls:evaluateBaseDomain\n */\n\n/**\n * Walks a domain string (e.g. foobar.barfoo.co.uk) backwards, separated by dots, skips over all top level\n * domains it finds and includes the first non-TLD value to retrieve the base domain without any subdomains\n * (e.g. barfoo.co.uk).\n *\n * This is not completely fool-proof in case of very exotic TLDs, but quite robust in most cases.\n *\n * This method is particularly helpful if you want to set a domain cookie while being on a subdomain.\n *\n * @param {String} domain - the domain string (hostname), which should be evaluated; you may also provide a full, parsable URL, from which to extract the hostname\n * @param {?Array} [additionalTopLevelDomains=null] - this function uses a list of common TLDs, if yours is missing, you may provide it, using this parameter\n * @returns {String} the evaluated base domain string\n *\n * @memberof Urls:evaluateBaseDomain\n * @alias evaluateBaseDomain\n * @example\n * evaluateBaseDomain('foobar.barfoo.co.uk');\n * => 'barfoo.co.uk'\n * evaluateBaseDomain('https://foobar.barfoo.co.uk/?foo=bar');\n * => 'barfoo.co.uk'\n */\nexport function evaluateBaseDomain(domain, additionalTopLevelDomains=null){\n\tdomain = orDefault(domain, window.location.hostname, 'str');\n\tadditionalTopLevelDomains = orDefault(additionalTopLevelDomains, null, 'arr');\n\n\tlet url;\n\ttry {\n\t\turl = new URL(domain);\n\t} catch(error){\n\t\turl = null;\n\t}\n\tif( hasValue(url) ){\n\t\tdomain = url.hostname;\n\t}\n\n\tconst\n\t\ttopLevelDomains = new Set([\n\t\t\t...COMMON_TOP_LEVEL_DOMAINS,\n\t\t\t...(hasValue(additionalTopLevelDomains) ? additionalTopLevelDomains.map(tld => `${tld}`) : [])\n\t\t]),\n\t\tdomainParts = domain.split('.').reverse()\n\t;\n\n\tlet baseDomain = domain;\n\n\tif( domainParts.length > 2 ){\n\t\tlet i;\n\n\t\tfor( i = 0; i < domainParts.length; i++ ){\n\t\t\tif( !topLevelDomains.has(domainParts[i]) ){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tbaseDomain = domainParts.slice(0, i + 1).reverse().join('.');\n\t}\n\n\treturn baseDomain;\n}\n\n\n\n/**\n * @namespace Urls:Urison\n */\n\n/**\n * A class, which (re)implements the \"Rison\" standard of en- and decoding JSON structures to and from URL-safe strings,\n * which can be used as parameter or hash values, while staying readable and avoiding characters, which are not meant\n * to be used inside a URL.\n *\n * This is a renamed reimplementation of ES5 Rison, which has not gotten an update for years and should be fully\n * compatible with other available parsers for that standard.\n *\n * The basic idea is this:\n * We have some kind of complex data structure we want to serialize to a URL, to represent a current search and filter\n * setup for example. This structure should also be retrievable easily after a reload, to be able to use that config\n * as a starting point again for the page's search and filter widgets. A big plus here would be readability, which,\n * for instance, gets lost, if we just were to url-encode JSON as-is.\n *\n * This class provides the means to en- and decode JSON structures for usage in URLs. Additionally, it provides methods\n * to explicitly work with objects and array, for the en- and decoding process, removing the necessity to include\n * brackets into the result, making the string even leaner.\n *\n * See class documentation below for details.\n *\n * @memberof Urls:Urison\n * @name Urison\n *\n * @see Urison\n * @see https://github.com/Nanonid/rison\n * @example\n * (new Urison()).encode({key1 : 'value', key2 : true, key3 : [false, 42, null]})\n * => '(key1:value,key2:!t,key3:!(!f,42,!n))'\n * (new Urison()).decode('(key1:value,key2:!t,key3:!(!f,42,!n))')\n * => {key1 : 'value', key2 : true, key3 : [false, 42, null]}\n * (new Urison()).encodeObject({key1 : 'value', key2 : true, key3 : [false, 42, null]})\n * => 'key1:value,key2:!t,key3:!(!f,42,!n)'\n * (new Urison()).decodeObject('key1:value,key2:!t,key3:!(!f,42,!n)')\n * => {key1 : 'value', key2 : true, key3 : [false, 42, null]}\n * (new Urison()).encodeArray([false, 42, null])\n * => '!f,42,!n'\n * (new Urison()).decodeArray('!f,42,!n')\n * => [false, 42, null]\n */\nclass Urison {\n\n\t#__className__ = 'Urison';\n\t#autoEscape;\n\t#autoUnescape;\n\t#encoders;\n\t#parser;\n\n\t/**\n\t * Creates a new Urison en- and decoder.\n\t *\n\t * @param {Boolean} [autoEscape=true] - if true, all keys and values are automatically uri-encoded and decoded if necessary, set this to false to keep values as is\n\t */\n\tconstructor(autoEscape=true){\n\t\tconst instance = this;\n\n\t\tautoEscape = orDefault(autoEscape, true, 'bool');\n\t\tthis.#autoEscape = autoEscape ? this.escape : val => val;\n\t\tthis.#autoUnescape = autoEscape ? decodeURIComponent : val => val;\n\n\t\t// procedure map, defining how data types are string-represented in Rison\n\t\tthis.#encoders = {\n\t\t\tarray(value){\n\t\t\t\tconst res = [];\n\n\t\t\t\tfor( let v of value ){\n\t\t\t\t\tconst encodedValue = instance.encode(v);\n\t\t\t\t\tif( isString(encodedValue) ){\n\t\t\t\t\t\tres.push(encodedValue);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn `!(${res.join(',')})`;\n\t\t\t},\n\n\t\t\tboolean(value){\n\t\t\t\treturn !!value ? '!t' : '!f';\n\t\t\t},\n\n\t\t\tnull(){\n\t\t\t\treturn '!n';\n\t\t\t},\n\n\t\t\tnumber(value){\n\t\t\t\tif( !isFinite(value) ) return '!n';\n\t\t\t\treturn `${value}`.replace(/\\+/, '');\n\t\t\t},\n\n\t\t\tobject(value){\n\t\t\t\tif( hasValue(value) ){\n\t\t\t\t\tif( isArray(value) ){\n\t\t\t\t\t\treturn this.array(value);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst keys = Object.keys(value);\n\t\t\t\t\tkeys.sort();\n\n\t\t\t\t\tconst res = [];\n\t\t\t\t\tfor( let key of keys ){\n\t\t\t\t\t\tconst v = instance.encode(value[key]);\n\t\t\t\t\t\tif( isString(v) ){\n\t\t\t\t\t\t\tconst k = isNaN(parseInt(key, 10)) ? this.string(key) : this.number(key);\n\t\t\t\t\t\t\tres.push(`${k}:${v}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn `(${res.join(',')})`;\n\t\t\t\t}\n\n\t\t\t\treturn '!n';\n\t\t\t},\n\n\t\t\tstring(value){\n\t\t\t\tif( value === '' ) return \"''\";\n\t\t\t\tif( URISON_VALUE_REX.test(value) ) return value;\n\n\t\t\t\tvalue = value.replace(/(['!])/g, function(_, quotedChar){\n\t\t\t\t\treturn `!${quotedChar}`;\n\t\t\t\t});\n\n\t\t\t\treturn `'${value}'`;\n\t\t\t}\n\t\t};\n\n\t\tthis.#parser = (new UrisonParser((error, index) => {\n\t\t\tthrow Error(`decoding error [${error}] at string index ${index}`);\n\t\t}));\n\t}\n\n\n\n\t/**\n\t * Encodes a JSON value to a Rison string.\n\t *\n\t * @param {Array|Object|String|Number|Boolean|null} value - the value to encode\n\t * @throws error if encoding fails or value is not usable JSON\n\t * @returns {String|undefined} the encoded Rison string or undefined if value cannot be encoded\n\t *\n\t * @example\n\t * (new Urison()).encode({key1 : 'value', key2 : true, key3 : [false, 42, null]})\n\t * => '(key1:value,key2:!t,key3:!(!f,42,!n))'\n\t */\n\tencode(value){\n\t\tconst __methodName__ = 'encode';\n\n\t\tif( isFunction(value?.toJson) ){\n\t\t\tvalue = value.toJson();\n\t\t}\n\n\t\tif( isFunction(value?.toJSON) ){\n\t\t\tvalue = value.toJSON();\n\t\t}\n\n\t\tconst encoder = this.#encoders[typeof value];\n\t\tif( !isFunction(encoder) ){\n\t\t\tthrow new Error(`${this.#__className__}.${__methodName__} | invalid data type`);\n\t\t}\n\n\t\tlet res;\n\t\ttry {\n\t\t\tres = encoder.call(this.#encoders, value);\n\t\t} catch(ex){\n\t\t\tthrow new Error(`${this.#__className__}.${__methodName__} | encoding error [${ex}]`);\n\t\t}\n\n\t\treturn this.#autoEscape(this.#autoUnescape(res));\n\t}\n\n\n\n\t/**\n\t * Encodes a JSON value to a Rison string.\n\t *\n\t * @param {Object} value - the object to encode\n\t * @returns {String|undefined} the encoded Rison string or undefined if value cannot be encoded\n\t * @throws error if value is not an object\n\t *\n\t * @example\n\t * (new Urison()).encodeObject({key1 : 'value', key2 : true, key3 : [false, 42, null]})\n\t * => 'key1:value,key2:!t,key3:!(!f,42,!n)'\n\t */\n\tencodeObject(value){\n\t\tconst __methodName__ = 'encodeObject';\n\n\t\tif( !isObject(value) ){\n\t\t\tthrow new Error(`${this.#__className__}.${__methodName__} | value is not an object`);\n\t\t}\n\n\t\tconst res = this.#encoders.object(value);\n\t\treturn this.#autoEscape(this.#autoUnescape(res.substring(1, res.length - 1)));\n\t}\n\n\n\n\t/**\n\t * Encodes a JSON array to a Rison string.\n\t *\n\t * @param {Array} value - the array to encode\n\t * @returns {String|undefined} the encoded Rison string or undefined if value cannot be encoded\n\t * @throws error if value is not an array\n\t *\n\t * @example\n\t * (new Urison()).encodeArray([false, 42, null])\n\t * => '!f,42,!n'\n\t */\n\tencodeArray(value){\n\t\tconst __methodName__ = 'encodeArray';\n\n\t\tif( !isArray(value) ){\n\t\t\tthrow new Error(`${this.#__className__}.${__methodName__} | value is not an array`);\n\t\t}\n\n\t\tconst res = this.#encoders.array(value);\n\t\treturn this.#autoEscape(this.#autoUnescape(res.substring(2, res.length - 1)));\n\t}\n\n\n\n\t/**\n\t * Decodes a Rison string to a JSON value.\n\t *\n\t * @param {String} risonString - the Rison string to decode\n\t * @returns {Object|Array|String|Number|Boolean|null} the decoded JSON value\n\t * @throws error if decoding fails\n\t *\n\t * @example\n\t * (new Urison()).decode('(key1:value,key2:!t,key3:!(!f,42,!n))')\n\t * => {key1 : 'value', key2 : true, key3 : [false, 42, null]}\n\t */\n\tdecode(risonString){\n\t\treturn this.#parser.parse(this.#autoUnescape(risonString));\n\t}\n\n\n\n\t/**\n\t * Decodes a shortened Rison object string to a JSON object.\n\t *\n\t * @param {String} risonString - the Rison object string to decode\n\t * @returns {Object} the decoded JSON object\n\t * @throws error if decoding fails\n\t *\n\t * @example\n\t * (new Urison()).decodeObject('key1:value,key2:!t,key3:!(!f,42,!n)')\n\t * => {key1 : 'value', key2 : true, key3 : [false, 42, null]}\n\t */\n\tdecodeObject(risonString){\n\t\treturn this.decode(`(${risonString})`);\n\t}\n\n\n\n\t/**\n\t * Decodes a shortened Rison array string to a JSON array.\n\t *\n\t * @param {String} risonString - the Rison array string to decode\n\t * @returns {Array} the decoded JSON array\n\t * @throws error if decoding fails\n\t *\n\t * @example\n\t * (new Urison()).decodeArray('!f,42,!n')\n\t * => [false, 42, null]\n\t */\n\tdecodeArray(risonString){\n\t\treturn this.decode(`!(${risonString})`);\n\t}\n\n\n\n\t/**\n\t * URI-Escapes a value, if necessary, according to the rules of Rison, which is a little bit\n\t * more lax than native uri encoding (allows [,:@$/+]).\n\t *\n\t * This method has one difference to the reference implementation:\n\t * We do _not_ encode whitespace as \"+\", but as \"%20\". This is done, because \"+\"-encoding is not\n\t * compatible with `decodeURIComponent` and makes working with URL-encoded values manually painful.\n\t * So here, \"+\" is just a normal, allowed URL-safe character and whitespace becomes \"%20\".\n\t * Since `encode_uri` was never automatically applied in Rison, this should not break anything.\n\t *\n\t * @param {String} value - the value to escape problematic chars in\n\t * @returns {String} uri-encoded string\n\t *\n\t * @example\n\t * (new Urison()).escape('abc,:@')\n\t * => 'abc%2C%3A%40'\n\t */\n\tescape(value){\n\t\tvalue = `${value}`;\n\n\t\tif( /^[\\-A-Za-z0-9~!*()_.',:@$\\/+]*$/.test(value) ) return value;\n\n\t\treturn replace(\n\t\t\tencodeURIComponent(value),\n\t\t\t['%2C', '%3A', '%40', '%24', '%2F', '%2B'],\n\t\t\t[',', ':', '@', '$', '/', '+']\n\t\t);\n\t}\n\n}\n\nexport {Urison};\n"]} \ No newline at end of file +{"version":3,"file":"urls.js","names":["MODULE_NAME","hasValue","orDefault","size","assert","isFunction","isString","isArray","isObject","isPlainObject","isNaN","isEmpty","log","replace","COMMON_TOP_LEVEL_DOMAINS","URISON_VALUE_FORMAT","URISON_VALUE_REX","RegExp","URISON_NEXT_VALUE_REX","UrisonParser","__className__","errorHandler","string","index","message","bangTokens","tokenMap","constructor","instance","this","t","f","n","parseArray","char","charAt","error","value","undefined","call","res","first","next","key","readValue","segments","i","start","push","slice","includes","length","join","numberTypeMap","s","numberType","permittedSigns","toLowerCase","Number","parse","risonString","trailingChar","detailMessage","test","mapper","apply","lastIndex","matches","exec","id","console","urlHref","url","params","anchor","markListParams","keepEncodedUrlSafeChars","window","location","href","trim","startsWith","protocol","origin","anchorPart","split","urlObj","URL","ex","Error","hash","urlParams","searchParams","paramName","overrideName","delete","concat","forEach","paramValue","append","k","keys","cleanKey","presentValues","getAll","endsWith","v","query","search","replaceAll","finalUrl","queryParts","sort","a","b","aKey","bKey","filter","part","indexOf","urlParameter","parameter","fMapParameterValue","parameterValue","parameterValues","Array","from","Set","map","parameters","parameterName","urlParameters","urlAnchor","withCaret","urlParts","decodeURIComponent","addNextParameter","assertSameBaseDomain","additionalTopLevelDomains","__methodName__","evaluateBaseDomain","hostname","has","info","get","addCacheBuster","buster","Date","now","domain","topLevelDomains","tld","domainParts","reverse","baseDomain","Urison","autoEscape","autoUnescape","encoders","parser","escape","val","array","encodedValue","encode","boolean","null","number","isFinite","object","Object","parseInt","_","quotedChar","toJson","toJSON","encoder","encodeObject","substring","encodeArray","decode","decodeObject","decodeArray","encodeURIComponent"],"sources":["urls.js"],"mappings":";;;AAQA,MAAMA,YAAc,cAOnBC,SACAC,UACAC,KACAC,OACAC,WACAC,SACAC,QACAC,SACAC,cACAC,MACAC,YACM,oBACCC,QAAU,sBACVC,YAAc,sBAMf,MAAMC,yBAA2B,CACvC,OAAQ,MAAO,MAAO,MAAO,OAAQ,MAAO,MAAO,OAAQ,MAAO,OAAQ,MAAO,OAAQ,SAAU,OAAQ,MAC3G,MAAO,SAAU,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAC3G,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAC5G,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAC5G,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAC5G,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAC5G,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAC5G,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAC5G,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAC5G,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAC5G,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAC5G,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAC5G,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAC5G,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAC5G,KAAM,KAAM,KAAM,KAAM,SAGzB,MACCC,oBAAsB,yCACtBC,iBAAmB,IAAIC,OAAO,IAAIF,wBAClCG,sBAAwB,IAAID,OAAOF,oBAAqB,KAoBzD,MAAMI,aAELC,GAAiB,eACjBC,GACAC,GAAU,GACVC,GAAS,EACTC,GAAW,KACXC,GACAC,GAUA,WAAAC,CAAYN,EAAa,MACxB,MAAMO,EAAWC,KAEjBA,MAAKR,EAAgBhB,WAAWgB,GAAgBA,EAAe,KAG/DQ,MAAKJ,EAAc,CAClBK,GAAM,EACNC,GAAM,EACNC,EAAM,KACN,IAAMH,MAAKI,GAIZJ,MAAKH,EAAY,CAChB,IAAM,WACL,MAAMQ,EAAON,GAASN,EAAQa,OAAOP,GAASL,KAC9C,GAAa,KAATW,EAAc,OAAON,GAASQ,EAAO,uBAEzC,MAAMC,EAAQT,GAASH,EAAYS,GACnC,YAAcI,IAAVD,EAA6BT,GAASQ,EAAO,sBAAsBF,MACnE7B,WAAWgC,GAAgBA,EAAME,KAAKV,MAEnCQ,CACR,EAEA,IAAM,WACL,MAAMG,EAAM,CAAC,EACb,IAECN,EADAO,GAAQ,EAIT,KAAqC,OAA7BP,EAAON,GAASc,MAAkB,CACzC,GAAKD,EAIE,IAAa,MAATP,EACV,OAAON,GAASQ,EAAO,aAEvBR,GAASL,GACV,MAPC,GAAa,MAATW,EACH,OAAON,GAASQ,EAAO,eAQzB,MAAMO,EAAMf,GAASgB,IACrB,QAAYN,IAARK,EAAoB,OACxB,GAAyB,MAArBf,GAASc,IAAkB,OAAOd,GAASQ,EAAO,eAEtD,MAAMC,EAAQT,GAASgB,IACvB,QAAcN,IAAVD,EAAsB,OAC1BG,EAAIG,GAAON,EAEXI,GAAQ,CACT,CAEA,OAAOD,CACR,EAEA,IAAM,WACL,MAAMK,EAAW,GACjB,IAGCX,EAFAY,EAAIlB,GAASL,EACbwB,EAAQnB,GAASL,EAIlB,KAAiD,OAAzCW,EAAON,GAASN,EAAQa,OAAOW,OAAe,CACrD,GAAa,KAATZ,EAAc,OAAON,GAASQ,EAAO,kBACzC,GAAa,MAATF,EAAc,CAKjB,GAJIa,EAASD,EAAI,GAChBD,EAASG,KAAKpB,GAASN,EAAQ2B,MAAMF,EAAOD,EAAI,IAEjDZ,EAAON,GAASN,EAAQa,OAAOW,MAC3B,CAAC,IAAK,KAAKI,SAAShB,GAGvB,OAAON,GAASQ,EAAO,4BAA4BF,MAFnDW,EAASG,KAAKd,GAIfa,EAAQD,CACT,CACD,CAMA,OALIC,EAASD,EAAI,GAChBD,EAASG,KAAKpB,GAASN,EAAQ2B,MAAMF,EAAOD,EAAI,IAEjDlB,GAASL,EAASuB,EAEU,IAApBD,EAASM,OAAgBN,EAAS,GAAKA,EAASO,KAAK,GAC9D,EAEA,IAAM,WACL,MACCL,EAAQnB,GAASL,EAAS,EAC1B8B,EAAgB,CACf,QAAU,OACV,QAAU,MACV,SAAW,OAGb,IACCC,EAAI1B,GAASN,EACbwB,EAAIlB,GAASL,EACbgC,EAAa,MACbC,EAAiB,IAGlB,EAAG,CACF,MAAMtB,EAAOoB,EAAEnB,OAAOW,KACtB,GAAa,KAATZ,EAAc,MACbA,GAAQ,KAASA,GAAQ,MAC1BsB,EAAeN,SAAShB,GAC3BsB,EAAiB,IAIlBD,EAAaF,EAAc,GAAGE,KAAcrB,EAAKuB,iBAC9B,QAAfF,IACHC,EAAiB,MAEnB,YAAwBlB,IAAfiB,GAKT,OAHAT,IACAlB,GAASL,EAASuB,EAClBQ,EAAIA,EAAEL,MAAMF,EAAOD,GACT,MAANQ,EAAmB1B,GAASQ,EAAO,kBAChCsB,OAAOJ,EACf,GAGD,SAAU5B,GACT,IAAK,IAAIoB,EAAI,EAAGA,GAAK,EAAGA,IACvBpB,EAAS,GAAGoB,KAAOpB,EAAS,IAE7B,CAJD,CAIGG,MAAKH,EACT,CAeA,KAAAiC,CAAMC,GACL/B,MAAKP,EAAU,GAAGsC,IAClB/B,MAAKN,EAAS,EACdM,MAAKL,EAAW,KAEhB,IAAIa,EAAQR,MAAKe,IAEjB,MAAMiB,EAAehC,MAAKa,IAC1B,IAAKb,MAAKL,QAA8Bc,IAAjBuB,EAA6B,CACnD,IAAIC,EAEHA,EADG,KAAKC,KAAKF,GACG,sBAEA,kBAAkBA,KAEnCxB,EAAQR,MAAKO,EAAO,2BAA2BwB,OAAiBE,IACjE,CAMA,OAJIjC,MAAKL,GAAYK,MAAKR,GACzBQ,MAAKR,EAAcQ,MAAKL,EAAUK,MAAKN,GAGjCc,CACR,CAeA,EAAAJ,GACC,MAAMO,EAAM,GACZ,IAAIN,EAEJ,KAAiC,OAAzBA,EAAOL,MAAKa,MAAkB,CACrC,GAAa,KAATR,EAAc,OAAOL,MAAKO,EAAO,kBAErC,GAAKzB,QAAQ6B,GAIN,IAAa,MAATN,EACV,OAAOL,MAAKO,EAAO,aAEnBP,MAAKN,GACN,MAPC,GAAa,MAATW,EACH,OAAOL,MAAKO,EAAO,eAQrB,MAAMC,EAAQR,MAAKe,IACnB,QAAcN,IAAVD,EAAsB,OAC1BG,EAAIQ,KAAKX,EACV,CAEA,OAAOG,CACR,CAeA,EAAAI,GACC,MACCV,EAAOL,MAAKa,IACZsB,EAASnC,MAAKH,EAAUQ,GAGzB,GAAI7B,WAAW2D,GAAU,OAAOA,EAAOC,MAAMpC,MAE7C,MAAMiB,EAAIjB,MAAKN,EAAS,EACxBL,sBAAsBgD,UAAYpB,EAClC,MAAMqB,EAAUjD,sBAAsBkD,KAAKvC,MAAKP,GAChD,IAAKX,QAAQwD,GAAU,CACtB,MAAME,EAAKF,EAAQ,GAEnB,OADAtC,MAAKN,EAASuB,EAAIuB,EAAGlB,OACdkB,CACR,CAEA,OAAIpE,SAASiC,IAAmB,KAATA,EAAsBL,MAAKO,EAAO,sBAAsBF,MACxEL,MAAKO,EAAO,mBACpB,CAeA,EAAAM,GACC,IAECR,EADAY,EAAIjB,MAAKN,EAIV,KAAIuB,GAAKjB,MAAKP,EAAQ6B,QAItB,OAHAjB,EAAOL,MAAKP,EAAQa,OAAOW,KAC3BjB,MAAKN,EAASuB,EAEPZ,CACR,CAiBA,EAAAE,CAAOZ,GACN8C,QAAQlC,MAAM,GAAGP,MAAKT,YAA0BI,GAChDK,MAAKL,EAAWA,CAEjB,SA+DM,SAAS+C,QAAQC,EAAI,KAAMC,EAAO,KAAMC,EAAO,KAAMC,GAAe,EAAOC,GAAwB,GAQzG,GALAJ,EAAMtE,UAAUsE,EAAKK,OAAOC,SAASC,KAAM,OAC3CN,EAAShE,cAAcgE,GAAUA,EAAS,KAC1CC,EAASxE,UAAUwE,EAAQ,KAAM,OACjCC,EAAiBzE,UAAUyE,GAAgB,EAAO,QAEtC,gBAARH,EAAwB,OAAOA,EAInC,GAHmB,KAAfA,EAAIQ,SACPR,EAAMK,OAAOC,SAASC,MAEnBP,EAAIS,WAAW,MAClBT,EAAM,GAAGK,OAAOC,SAASI,WAAWV,SAC9B,GAAIA,EAAIS,WAAW,KACzBT,EAAM,GAAGK,OAAOC,SAASK,SAASX,SAC5B,GAAIA,EAAIS,WAAW,KAAM,CAC/B,MAAMG,EAAcZ,EAAItB,SAAS,KAA4C,KAArC2B,OAAOC,SAASC,KAAKM,MAAM,KAAK,GACxEb,EAAM,GAAGK,OAAOC,SAASC,KAAKM,MAAM,KAAK,KAAKb,IAAMvE,SAASmF,GAAc,IAAIA,EAAa,IAC7F,MAAWZ,EAAIS,WAAW,OACzBT,EAAM,GAAGK,OAAOC,SAASC,KAAKM,MAAM,KAAK,KAAKb,KAM/C,IAAIc,EAJE,eAAevB,KAAKS,KACzBA,EAAM,GAAGK,OAAOC,SAASI,aAAaV,KAIvC,IACCc,EAAS,IAAIC,IAAIf,EAClB,CAAE,MAAMgB,GACP,MAAM,IAAIC,MAAM,GAAGzF,uCAAiDwE,OAASgB,KAC9E,CAEIvF,SAASyE,KACZY,EAAOI,KAAOhB,EAAOO,WAAW,KAAOP,EAAS,IAAIA,KAGrD,MAAMiB,EAAYL,EAAOM,aAEzB,GAAI3F,SAASwE,GACZ,IAAK,IAAIoB,KAAapB,EAAQ,CAC7B,IAAIqB,EAAeD,EACfA,EAAUZ,WAAW,OACxBa,EAAeD,EAAU5C,MAAM,IAG5B6C,IAAiBD,GACpBF,EAAUI,OAAOD,GAGlB,GAAGE,OAAOvB,EAAOoB,IAAYI,SAAQC,IACpCP,EAAUQ,OAAOL,EAAc,GAAGI,IAAa,GAEjD,CAGD,GAAIvB,EACH,IAAK,IAAIyB,KAAKT,EAAUU,OAAQ,CAC/B,MAAMC,EAAWF,EAAEvF,QAAQ,OAAQ,IAEnC,IAAI0F,EAAgB,GAAGP,OAAOL,EAAUa,OAAOJ,IAC3CA,EAAEK,SAAS,QACdF,EAAgBA,EAAcP,OAAOL,EAAUa,OAAOF,KAGlDC,EAAcpD,OAAS,IAC3BwC,EAAUI,OAAOK,GACjBT,EAAUI,OAAOO,GACjBC,EAAcN,SAAQS,IACrBf,EAAUQ,OAAO,GAAGG,MAAcI,EAAE,IAGvC,CAGD,IAAIC,EAAQrB,EAAOsB,OACjB/F,QAAQ,MAAO,OACfA,QAAQ,MAAO,KACfA,QAAQ,MAAO,IAGZ+D,IACJ+B,EAAQA,EACNE,WAAW,MAAO,KAClBA,WAAW,MAAO,KAClBA,WAAW,MAAO,MAIrB,IAmBIC,EAnBAC,EAAaJ,EAAM1B,WAAW,KAAO0B,EAAM1D,MAAM,GAAGoC,MAAM,KAAO,GA4BrE,OA3BK1E,QAAQoG,KACZA,EAAWC,MAAK,CAACC,EAAGC,KACnB,MACCC,EAAOF,EAAE5B,MAAM,KAAK,GACpB+B,EAAOF,EAAE7B,MAAM,KAAK,GAErB,OAAQ8B,EAAOC,GAAS,EAAMD,EAAOC,EAAQ,EAAI,CAAG,IAErDL,EAAaA,EAAWM,QAAO,CAACC,EAAM/F,MACjCA,GAAS,IACLwF,EAAWQ,QAAQD,KAAU/F,IAKtCoF,EAAQ,IAAII,EAAW3D,KAAK,QAO5B0D,EAHInG,QAAQgG,IAEDhG,QAAQ2E,EAAOI,OAAS/E,QAAQgG,GAChC,GAAGrB,EAAOP,KAAKM,MAAM,KAAK,KAAKC,EAAOI,OAAO7E,QAAQ,KAAM,KAE3DyE,EAAOP,KAAKlE,QAAQ,MAAO,IAJ3B,GAAGyE,EAAOP,KAAKM,MAAM,KAAK,KAAKsB,IAAQrB,EAAOI,OAAO7E,QAAQ,KAAM,KAOxE+D,EAA0BkC,EAAWjG,QAC3CiG,EACA,CAAC,MAAO,MAAO,MAAO,MAAO,MAAO,OACpC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,KAE5B,QAuCO,SAASU,aAAahD,EAAI,KAAMiD,EAAU,MAChDjD,EAAMD,QAAQC,EAAK,KAAM,MAAM,GAAO,GACtCiD,EAAYvH,UAAUuH,EAAW,KAAM,OAEvC,MACC7B,EAAe,IAAIL,IAAIf,GAAKoB,aAC5B8B,EAAqBC,GAAuC,KAAnBA,GAAgCA,EAG1E,GAAI1H,SAASwH,GAAY,CACxB,MAAMG,EAAkBhC,EAAaY,OAAOiB,GAC5C,OAA+B,IAA3BG,EAAgBzE,OACZ,KAC8B,IAA3ByE,EAAgBzE,OACnBuE,EAAmBE,EAAgB,IAEnCC,MAAMC,KAAK,IAAIC,IAAIH,EAAgBI,IAAIN,IAEhD,CAAO,CACN,MAAMO,EAAa,CAAC,EAWpB,OAVAJ,MAAMC,KAAKlC,EAAaS,QAAQJ,SAAQiC,IACvC,MAAMN,EAAkBhC,EAAaY,OAAO0B,GACxCN,EAAgBzE,OAAS,IAC5B8E,EAAWC,GACkB,IAA3BN,EAAgBzE,OACfuE,EAAmBE,EAAgB,IACnCC,MAAMC,KAAK,IAAIC,IAAIH,EAAgBI,IAAIN,KAE3C,IAEOvH,KAAK8H,GAAc,EAAKA,EAAa,IAC9C,CACD,QAwBO,SAASE,cAAc3D,EAAI,MACjC,OAAOgD,aAAahD,EACrB,QA8BO,SAAS4D,UAAU5D,EAAI,KAAM6D,GAAU,GAC7C7D,EAAMD,QAAQC,GACd6D,EAAYnI,UAAUmI,GAAW,EAAO,QAExC,MAAMC,EAAW9D,EAAIa,MAAM,KAE3B,IAAIX,EAAU4D,EAASnF,OAAS,EAAKoF,mBAAmBD,EAAS,GAAGtD,QAAU,KAQ9E,MAPe,KAAXN,IACHA,EAAS,MAEN2D,GAAapI,SAASyE,KACzBA,EAAS,IAAIA,KAGPA,CACR,QAgCO,SAAS8D,iBAAiBhE,EAAK9B,EAAMmD,EAAU,OAAQ4C,GAAqB,EAAOC,EAA0B,MACnH,MAAMC,EAAiB,mBAEvBnE,EAAMD,QAAQC,GACd9B,EAAO6B,QAAQ7B,GACfmD,EAAY3F,UAAU2F,EAAW,OAAQ,QACzC4C,EAAuBvI,UAAUuI,GAAsB,EAAM,UAG5DrI,OACCwI,mBAAmB,IAAIrD,IAAIf,GAAKqE,SAAUH,KAA+BE,mBAAmB,IAAIrD,IAAI7C,GAAMmG,SAAUH,GACpH,GAAG1I,eAAe2I,8CAIpB,MAAMlE,EAAS,IAAIc,IAAIf,GAAKoB,aAK5B,OAJInB,EAAOqE,IAAIjD,IACdjF,MAAMmI,KAAK,GAAG/I,eAAe2I,iBAA8B9C,aAAqBpB,EAAOuE,IAAInD,aAAqBnD,MAG1G6B,QAAQC,EAAK,CAAC,CAAC,IAAIqB,KAAenD,GAC1C,QA0BO,SAASuG,eAAezE,EAAI,KAAMqB,EAAU,KAGlDrB,EAAMD,QAAQC,GAEd,MACCC,EAAS,IAAIc,IAAIf,GAAKoB,aACtBsD,EAASC,KAAKC,MAOf,OAJI3E,EAAOqE,IAAIjD,IACdjF,MAAMmI,KAAK,GAAG/I,0CAA6C6F,aAAqBpB,EAAOuE,IAAInD,aAAqBqD,MAG1G3E,QAAQC,EAAK,CAAC,CAAC,IAAIqB,KAAeqD,GAC1C,QA6BO,SAASN,mBAAmBS,EAAQX,EAA0B,MAIpE,IAAIlE,EAHJ6E,EAASnJ,UAAUmJ,EAAQxE,OAAOC,SAAS+D,SAAU,OACrDH,EAA4BxI,UAAUwI,EAA2B,KAAM,OAGvE,IACClE,EAAM,IAAIe,IAAI8D,EACf,CAAE,MAAMjH,GACPoC,EAAM,IACP,CACIvE,SAASuE,KACZ6E,EAAS7E,EAAIqE,UAGd,MACCS,EAAkB,IAAIvB,IAAI,IACtBjH,4BACCb,SAASyI,GAA6BA,EAA0BV,KAAIuB,GAAO,GAAGA,MAAS,KAE5FC,EAAcH,EAAOhE,MAAM,KAAKoE,UAGjC,IAAIC,EAAaL,EAEjB,GAAIG,EAAYrG,OAAS,EAAG,CAC3B,IAAIL,EAEJ,IAAKA,EAAI,EAAGA,EAAI0G,EAAYrG,QACtBmG,EAAgBR,IAAIU,EAAY1G,IADFA,KAMpC4G,EAAaF,EAAYvG,MAAM,EAAGH,EAAI,GAAG2G,UAAUrG,KAAK,IACzD,CAEA,OAAOsG,CACR,CA+CA,MAAMC,OAELvI,GAAiB,SACjBwI,GACAC,GACAC,GACAC,GAOA,WAAApI,CAAYiI,GAAW,GACtB,MAAMhI,EAAWC,KAEjB+H,EAAa1J,UAAU0J,GAAY,EAAM,QACzC/H,MAAK+H,EAAcA,EAAa/H,KAAKmI,OAASC,GAAOA,EACrDpI,MAAKgI,EAAgBD,EAAarB,mBAAqB0B,GAAOA,EAG9DpI,MAAKiI,EAAY,CAChB,KAAAI,CAAM7H,GACL,MAAMG,EAAM,GAEZ,IAAK,IAAIkE,KAAKrE,EAAO,CACpB,MAAM8H,EAAevI,EAASwI,OAAO1D,GACjCpG,SAAS6J,IACZ3H,EAAIQ,KAAKmH,EAEX,CAEA,MAAO,KAAK3H,EAAIY,KAAK,OACtB,EAEAiH,QAAQhI,GACEA,EAAQ,KAAO,KAGzBiI,KAAI,IACI,KAGRC,OAAOlI,GACDmI,SAASnI,GACP,GAAGA,IAAQxB,QAAQ,KAAM,IADF,KAI/B,MAAA4J,CAAOpI,GACN,GAAIpC,SAASoC,GAAQ,CACpB,GAAI9B,QAAQ8B,GACX,OAAOR,KAAKqI,MAAM7H,GAGnB,MAAMgE,EAAOqE,OAAOrE,KAAKhE,GACzBgE,EAAKW,OAEL,MAAMxE,EAAM,GACZ,IAAK,IAAIG,KAAO0D,EAAM,CACrB,MAAMK,EAAI9E,EAASwI,OAAO/H,EAAMM,IAChC,GAAIrC,SAASoG,GAAI,CAChB,MAAMN,EAAI1F,MAAMiK,SAAShI,EAAK,KAAOd,KAAKP,OAAOqB,GAAOd,KAAK0I,OAAO5H,GACpEH,EAAIQ,KAAK,GAAGoD,KAAKM,IAClB,CACD,CAEA,MAAO,IAAIlE,EAAIY,KAAK,OACrB,CAEA,MAAO,IACR,EAEA9B,OAAOe,GACQ,KAAVA,EAAsB,KACtBrB,iBAAiB+C,KAAK1B,GAAgBA,EAMnC,IAJPA,EAAQA,EAAMxB,QAAQ,WAAW,SAAS+J,EAAGC,GAC5C,MAAO,IAAIA,GACZ,QAMFhJ,MAAKkI,EAAU,IAAK5I,cAAa,CAACiB,EAAOb,KACxC,MAAMkE,MAAM,mBAAmBrD,sBAA0Bb,IAAQ,GAEnE,CAeA,MAAA6I,CAAO/H,GACN,MAAMsG,EAAiB,SAEnBtI,WAAWgC,GAAOyI,UACrBzI,EAAQA,EAAMyI,UAGXzK,WAAWgC,GAAO0I,UACrB1I,EAAQA,EAAM0I,UAGf,MAAMC,EAAUnJ,MAAKiI,SAAiBzH,GACtC,IAAKhC,WAAW2K,GACf,MAAM,IAAIvF,MAAM,GAAG5D,MAAKT,KAAkBuH,yBAG3C,IAAInG,EACJ,IACCA,EAAMwI,EAAQzI,KAAKV,MAAKiI,EAAWzH,EACpC,CAAE,MAAMmD,GACP,MAAM,IAAIC,MAAM,GAAG5D,MAAKT,KAAkBuH,uBAAoCnD,KAC/E,CAEA,OAAO3D,MAAK+H,EAAY/H,MAAKgI,EAAcrH,GAC5C,CAeA,YAAAyI,CAAa5I,GAGZ,IAAK7B,SAAS6B,GACb,MAAM,IAAIoD,MAAM,GAAG5D,MAAKT,2CAGzB,MAAMoB,EAAMX,MAAKiI,EAAUW,OAAOpI,GAClC,OAAOR,MAAK+H,EAAY/H,MAAKgI,EAAcrH,EAAI0I,UAAU,EAAG1I,EAAIW,OAAS,IAC1E,CAeA,WAAAgI,CAAY9I,GAGX,IAAK9B,QAAQ8B,GACZ,MAAM,IAAIoD,MAAM,GAAG5D,MAAKT,yCAGzB,MAAMoB,EAAMX,MAAKiI,EAAUI,MAAM7H,GACjC,OAAOR,MAAK+H,EAAY/H,MAAKgI,EAAcrH,EAAI0I,UAAU,EAAG1I,EAAIW,OAAS,IAC1E,CAeA,MAAAiI,CAAOxH,GACN,OAAO/B,MAAKkI,EAAQpG,MAAM9B,MAAKgI,EAAcjG,GAC9C,CAeA,YAAAyH,CAAazH,GACZ,OAAO/B,KAAKuJ,OAAO,IAAIxH,KACxB,CAeA,WAAA0H,CAAY1H,GACX,OAAO/B,KAAKuJ,OAAO,KAAKxH,KACzB,CAqBA,MAAAoG,CAAO3H,GAGN,MAAI,kCAAkC0B,KAFtC1B,EAAQ,GAAGA,KAEgDA,EAEpDxB,QACN0K,mBAAmBlJ,GACnB,CAAC,MAAO,MAAO,MAAO,MAAO,MAAO,OACpC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,KAE5B,SAIOsH","ignoreList":[],"sourcesContent":["/*!\n * Module Urls\n */\n\n/**\n * @namespace Urls\n */\n\nconst MODULE_NAME = 'Urls';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {\n\thasValue,\n\torDefault,\n\tsize,\n\tassert,\n\tisFunction,\n\tisString,\n\tisArray,\n\tisObject,\n\tisPlainObject,\n\tisNaN,\n\tisEmpty\n} from './basic.js';\nimport {log} from './logging.js';\nimport {replace} from './strings.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nexport const COMMON_TOP_LEVEL_DOMAINS = [\n\t'aero', 'biz', 'cat', 'com', 'coop', 'edu', 'gov', 'info', 'int', 'jobs', 'mil', 'mobi', 'museum', 'name', 'net',\n\t'org', 'travel', 'ac', 'ad', 'ae', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao', 'aq', 'ar', 'as', 'at', 'au', 'aw',\n\t'az', 'ba', 'bb', 'bd', 'be', 'bf', 'bg', 'bh', 'bi', 'bj', 'bm', 'bn', 'bo', 'br', 'bs', 'bt', 'bv', 'bw', 'by',\n\t'bz', 'ca', 'cc', 'cd', 'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'cr', 'cs', 'cu', 'cv', 'cx', 'cy',\n\t'cz', 'de', 'dj', 'dk', 'dm', 'do', 'dz', 'ec', 'ee', 'eg', 'eh', 'er', 'es', 'et', 'eu', 'fi', 'fj', 'fk', 'fm',\n\t'fo', 'fr', 'ga', 'gb', 'gd', 'ge', 'gf', 'gg', 'gh', 'gi', 'gl', 'gm', 'gn', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu',\n\t'gw', 'gy', 'hk', 'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il', 'im', 'in', 'io', 'iq', 'ir', 'is', 'it', 'je',\n\t'jm', 'jo', 'jp', 'ke', 'kg', 'kh', 'ki', 'km', 'kn', 'kp', 'kr', 'kw', 'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk',\n\t'lr', 'ls', 'lt', 'lu', 'lv', 'ly', 'ma', 'mc', 'md', 'mg', 'mh', 'mk', 'ml', 'mm', 'mn', 'mo', 'mp', 'mq', 'mr',\n\t'ms', 'mt', 'mu', 'mv', 'mw', 'mx', 'my', 'mz', 'na', 'nc', 'ne', 'nf', 'ng', 'ni', 'nl', 'no', 'np', 'nr', 'nu',\n\t'nz', 'om', 'pa', 'pe', 'pf', 'pg', 'ph', 'pk', 'pl', 'pm', 'pn', 'pr', 'ps', 'pt', 'pw', 'py', 'qa', 're', 'ro',\n\t'ru', 'rw', 'sa', 'sb', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sl', 'sm', 'sn', 'so', 'sr', 'st', 'su',\n\t'sv', 'sy', 'sz', 'tc', 'td', 'tf', 'tg', 'th', 'tj', 'tk', 'tm', 'tn', 'to', 'tp', 'tr', 'tt', 'tv', 'tw', 'tz',\n\t'ua', 'ug', 'uk', 'um', 'us', 'uy', 'uz', 'va', 'vc', 've', 'vg', 'vi', 'vn', 'vu', 'wf', 'ws', 'ye', 'yt', 'yu',\n\t'za', 'zm', 'zr', 'zw', 'local'\n];\n\nconst\n\tURISON_VALUE_FORMAT = `[^\\-0123456789 '!:(),*@$][^ '!:(),*@$]*`,\n\tURISON_VALUE_REX = new RegExp(`^${URISON_VALUE_FORMAT}$`),\n\tURISON_NEXT_VALUE_REX = new RegExp(URISON_VALUE_FORMAT, 'g')\n;\n\n\n\n//###[ HELPERS ]########################################################################################################\n\n/**\n * A parser to translate a Rison string such as `'(key1:value,key2:!t,key3:!(!f,42,!n))'` into its\n * JSON object/array representation `{key1 : 'value', key2 : true, key3 : [false, 42, null]}`. This is a helper class\n * for the public Urison class below.\n *\n * @protected\n * @memberof Urls\n * @name UrisonParser\n *\n * @see https://github.com/Nanonid/rison\n * @example\n * new UrisonParser(error => { console.error(error); });\n */\nclass UrisonParser {\n\n\t#__className__ = 'UrisonParser';\n\t#errorHandler;\n\t#string = '';\n\t#index = 0;\n\t#message = null;\n\t#bangTokens;\n\t#tokenMap;\n\n\t/**\n\t * Creates a new UrisonParser instance.\n\t *\n\t * All errors in this class result in a console error message rather than an exception. To work with occurring\n\t * errors, define an errorCallback for the constructor and throw errors from there if needed.\n\t *\n\t * @param {Function} [errorHandler=null] - function to call in case parsing fails, receives the error message and the character index as parameters\n\t */\n\tconstructor(errorHandler=null){\n\t\tconst instance = this;\n\n\t\tthis.#errorHandler = isFunction(errorHandler) ? errorHandler : null;\n\n\t\t// syntax tokens preceded with a \"!\" and the values they represent in JSON\n\t\tthis.#bangTokens = {\n\t\t\t't' : true,\n\t\t\t'f' : false,\n\t\t\t'n' : null,\n\t\t\t'(' : this.#parseArray\n\t\t};\n\n\t\t// syntax structure tokens and the procedures, that transform these tokens into json structure\n\t\tthis.#tokenMap = {\n\t\t\t'!' : function(){\n\t\t\t\tconst char = instance.#string.charAt(instance.#index++);\n\t\t\t\tif( char === '' ) return instance.#error('\"!\" at end of input');\n\n\t\t\t\tconst value = instance.#bangTokens[char];\n\t\t\t\tif( value === undefined ) return instance.#error(`unknown literal: \"!${char}\"`);\n\t\t\t\tif( isFunction(value) ) return value.call(this);\n\n\t\t\t\treturn value;\n\t\t\t},\n\n\t\t\t'(' : function(){\n\t\t\t\tconst res = {};\n\t\t\t\tlet\n\t\t\t\t\tfirst = true,\n\t\t\t\t\tchar\n\t\t\t\t;\n\n\t\t\t\twhile( (char = instance.#next()) !== ')' ){\n\t\t\t\t\tif( !first ){\n\t\t\t\t\t\tif( char !== ',' ){\n\t\t\t\t\t\t\treturn instance.#error('missing \",\"');\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if( char === ',' ){\n\t\t\t\t\t\treturn instance.#error('extra \",\"');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tinstance.#index--;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst key = instance.#readValue();\n\t\t\t\t\tif( key === undefined ) return undefined;\n\t\t\t\t\tif( instance.#next() !== ':' ) return instance.#error('missing \":\"');\n\n\t\t\t\t\tconst value = instance.#readValue();\n\t\t\t\t\tif( value === undefined ) return undefined;\n\t\t\t\t\tres[key] = value;\n\n\t\t\t\t\tfirst = false;\n\t\t\t\t}\n\n\t\t\t\treturn res;\n\t\t\t},\n\n\t\t\t\"'\" : function(){\n\t\t\t\tconst segments = [];\n\t\t\t\tlet\n\t\t\t\t\ti = instance.#index,\n\t\t\t\t\tstart = instance.#index,\n\t\t\t\t\tchar\n\t\t\t\t;\n\n\t\t\t\twhile( (char = instance.#string.charAt(i++)) !== \"'\" ){\n\t\t\t\t\tif( char === '' ) return instance.#error(`unmatched \"'\"`);\n\t\t\t\t\tif( char === '!' ){\n\t\t\t\t\t\tif( start < (i - 1) ){\n\t\t\t\t\t\t\tsegments.push(instance.#string.slice(start, i - 1));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchar = instance.#string.charAt(i++);\n\t\t\t\t\t\tif( ['!', \"'\"].includes(char) ){\n\t\t\t\t\t\t\tsegments.push(char);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn instance.#error(`invalid string escape: \"!${char}\"`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstart = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif( start < (i - 1) ){\n\t\t\t\t\tsegments.push(instance.#string.slice(start, i - 1));\n\t\t\t\t}\n\t\t\t\tinstance.#index = i;\n\n\t\t\t\treturn (segments.length === 1) ? segments[0] : segments.join('');\n\t\t\t},\n\n\t\t\t'-' : function(){\n\t\t\t\tconst\n\t\t\t\t\tstart = instance.#index - 1,\n\t\t\t\t\tnumberTypeMap = {\n\t\t\t\t\t\t'int+.' : 'frac',\n\t\t\t\t\t\t'int+e' : 'exp',\n\t\t\t\t\t\t'frac+e' : 'exp'\n\t\t\t\t\t}\n\t\t\t\t;\n\t\t\t\tlet\n\t\t\t\t\ts = instance.#string,\n\t\t\t\t\ti = instance.#index,\n\t\t\t\t\tnumberType = 'int',\n\t\t\t\t\tpermittedSigns = '-'\n\t\t\t\t;\n\n\t\t\t\tdo {\n\t\t\t\t\tconst char = s.charAt(i++);\n\t\t\t\t\tif( char === '' ) break;\n\t\t\t\t\tif( (char >= '0') && (char <= '9') ) continue;\n\t\t\t\t\tif( permittedSigns.includes(char) ){\n\t\t\t\t\t\tpermittedSigns = '';\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tnumberType = numberTypeMap[`${numberType}+${char.toLowerCase()}`];\n\t\t\t\t\tif( numberType === 'exp' ){\n\t\t\t\t\t\tpermittedSigns = '-';\n\t\t\t\t\t}\n\t\t\t\t} while( numberType !== undefined );\n\n\t\t\t\ti--;\n\t\t\t\tinstance.#index = i;\n\t\t\t\ts = s.slice(start, i);\n\t\t\t\tif( s === '-' ) return instance.#error('invalid number');\n\t\t\t\treturn Number(s);\n\t\t\t}\n\t\t};\n\n\t\t(function(tokenMap){\n\t\t\tfor( let i = 0; i <= 9; i++ ){\n\t\t\t\ttokenMap[`${i}`] = tokenMap['-'];\n\t\t\t}\n\t\t})(this.#tokenMap);\n\t}\n\n\n\n\t/**\n\t * Parses a Rison string into a JSON object.\n\t * Resets internal parsing info, like parsing index, to start new parsing process.\n\t *\n\t * @param {String} risonString - the string to parse\n\t * @returns {Object|Array|undefined} the parsed JSON object or undefined, in case parsing failed\n\t *\n\t * @example\n\t * (new UrisonParser()).parse('(key1:value,key2:!t,key3:!(!f,42,!n))')\n\t * => {key1 : 'value', key2 : true, key3 : [false, 42, null]}\n\t */\n\tparse(risonString){\n\t\tthis.#string = `${risonString}`;\n\t\tthis.#index = 0;\n\t\tthis.#message = null;\n\n\t\tlet value = this.#readValue();\n\n\t\tconst trailingChar = this.#next();\n\t\tif( !this.#message && (trailingChar !== undefined) ){\n\t\t\tlet detailMessage;\n\t\t\tif( /\\s/.test(trailingChar) ){\n\t\t\t\tdetailMessage = 'whitespace detected';\n\t\t\t} else {\n\t\t\t\tdetailMessage = `trailing char \"${trailingChar}\"`;\n\t\t\t}\n\t\t\tvalue = this.#error(`unable to parse string \"${risonString}\", ${detailMessage}`);\n\t\t}\n\n\t\tif( this.#message && this.#errorHandler ){\n\t\t\tthis.#errorHandler(this.#message, this.#index);\n\t\t}\n\n\t\treturn value;\n\t}\n\n\n\n\t/**\n\t * Parses the structure of an array. Is a helper function for #parse/#readValue.\n\t * Works with previously set internal parsing info such as string and parsing index.\n\t *\n\t * @returns {Array|undefined} the parsed array or undefined, in case parsing failed\n\t *\n\t * @private\n\t * @example\n\t * this.#parseArray()\n\t * => [true, null, 'value']\n\t */\n\t#parseArray(){\n\t\tconst res = [];\n\t\tlet char;\n\n\t\twhile( (char = this.#next()) !== ')' ){\n\t\t\tif( char === '' ) return this.#error('unmatched \"!(\"');\n\n\t\t\tif( !isEmpty(res) ){\n\t\t\t\tif( char !== ',' ){\n\t\t\t\t\treturn this.#error('missing \",\"');\n\t\t\t\t}\n\t\t\t} else if( char === ',' ){\n\t\t\t\treturn this.#error('extra \",\"');\n\t\t\t} else {\n\t\t\t\tthis.#index--;\n\t\t\t}\n\n\t\t\tconst value = this.#readValue();\n\t\t\tif( value === undefined ) return undefined;\n\t\t\tres.push(value);\n\t\t}\n\n\t\treturn res;\n\t}\n\n\n\n\t/**\n\t * Either reads the next value or key in the current parser string or triggers recursive handling of syntax tokens.\n\t * Progresses parsing to the next section so to speak.\n\t *\n\t * @returns {Object|Array|String|Number|Boolean|null|undefined} the parsed value or undefined if parsing failed\n\t *\n\t * @private\n\t * @example\n\t * this.#readValue()\n\t * => 'valueorkeyorstructure'\n\t */\n\t#readValue(){\n\t\tconst\n\t\t\tchar = this.#next(),\n\t\t\tmapper = this.#tokenMap[char]\n\t\t;\n\n\t\tif( isFunction(mapper) ) return mapper.apply(this);\n\n\t\tconst i = this.#index - 1;\n\t\tURISON_NEXT_VALUE_REX.lastIndex = i;\n\t\tconst matches = URISON_NEXT_VALUE_REX.exec(this.#string);\n\t\tif( !isEmpty(matches) ){\n\t\t\tconst id = matches[0];\n\t\t\tthis.#index = i + id.length;\n\t\t\treturn id;\n\t\t}\n\n\t\tif( hasValue(char) && (char !== '') ) return this.#error(`invalid character \"${char}\"`);\n\t\treturn this.#error('empty expression');\n\t}\n\n\n\n\t/**\n\t * Reads the next character of the currently given Rison string, increments the index\n\t * and returns the character.\n\t *\n\t * @returns {String|undefined} the next character or undefined if there is none\n\t *\n\t * @private\n\t * @example\n\t * this.#next()\n\t * => '!'\n\t */\n\t#next(){\n\t\tlet\n\t\t\ti = this.#index,\n\t\t\tchar\n\t\t;\n\n\t\tif( i >= this.#string.length ) return undefined;\n\t\tchar = this.#string.charAt(i++);\n\t\tthis.#index = i;\n\n\t\treturn char;\n\t}\n\n\n\n\t/**\n\t * Sets the error message and writes it to `console.error()` for info purposes.\n\t * This method does _not_ throw an exception, for this, please set an error handler\n\t * in the constructor and throw it externally.\n\t *\n\t * @param {String} message - the error message\n\t * @returns {undefined} is always undefined to be uniform return value for failed value parsing in case of error\n\t *\n\t * @private\n\t * @example\n\t * this.#error('oh noez')\n\t * => undefined\n\t */\n\t#error(message){\n\t\tconsole.error(`${this.#__className__} error: `, message);\n\t\tthis.#message = message;\n\t\treturn undefined;\n\t}\n\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Urls:urlHref\n */\n\n/**\n * Will return a fully qualified URL based on the given URL base string for use as a href/source-value\n * or navigation target.\n *\n * Provide a base URL or leave the URL out, to use the current URL.\n * Add GET-parameters (adding to those already present in the URL), define an anchor (or automatically get the one\n * defined in the URL).\n *\n * Provided URLs are handled with some automagic:\n * - a URL starting with \"//\" will receive the current page protocol\n * - a URL starting with a single \"/\" will be seen as relative and will be expanded to an absolute URL, based\n * on the current URL\n * - a URL starting with \"?\" will be treated as a singular query string, resulting in the query being added to the\n * current URL, replacing any present query\n * - a URL starting with \"#\" will be treated as a singular hash string, resulting in the hash being added to the\n * current URL, replacing any present hash\n * - if, after all automagic applied, the URL still does not start with a http-protocol, the current page's protocol\n * will be added\n *\n * Provided params have to be a flat plain object, with ordinal values or arrays of ordinal values on the first level.\n * Everything else will be stringified and url-encoded as is. Usually, parameters defined here add to present\n * parameters in the URL. To force-override present values, declare the param name with a \"!\" prefix\n * (`{'!presentparam' : 'new'}`).\n *\n * This method implements some quality-of-life improvements, that differ from the native result of `new URL().href`:\n * - `+`-encoding for whitespace is replaced with `%20`, while `+` will stay what it is, a verbatim URL-safe character\n * with repeating keys (`tags=1&tags=2&tags=3`)\n * - empty parameters are rendered without \"=\". So, \"?test=&foo\" will be \"?test&foo\"\n * - `path/?` will become just `path?`\n * - `path/#` will become just `path#`\n * - trailing slashes will be removed\n * - parameters will be sorted alphabetically by keys\n * (value order will be kept if possible, might change, when using markListParams)\n * - identical key/value pairs will be reduced to one occurrence, so `?q=a&q=a` will become `?q=a`\n *\n * @param {?String|URL} [url=null] - the base URL to use, if nullish current location is used\n * @param {?Object} [params=null] - plain object of GET-parameters to add to the url\n * @param {?String} [anchor=null] - anchor/hash to set, has precedence over URL hash\n * @param {?Boolean} [markListParams=false] - if true, params with more than one value will be marked with \"[]\" preceding the param name\n * @param {?Boolean} [keepEncodedUrlSafeChars=false] - if true, encoded chars, which are URL-safe, are kept encoded, instead of being returned raw\n * @throws error if url is not usable\n * @returns {String} the created URL including parameters and anchor\n *\n * @memberof Urls:urlHref\n * @alias urlHref\n * @example\n * buildUrl('https://test.com', {search : 'kittens', order : 'asc'}, 'fluffykittens');\n * => 'https://test.com?search=kittens&order=asc#fluffykittens'\n * buildUrl(null, {order : 'desc'});\n * => 'https://current.url?order=desc'\n */\nexport function urlHref(url=null, params=null, anchor=null, markListParams=false, keepEncodedUrlSafeChars=false){\n\tconst __methodName__ = 'urlHref';\n\n\turl = orDefault(url, window.location.href, 'str');\n\tparams = isPlainObject(params) ? params : null;\n\tanchor = orDefault(anchor, null, 'str');\n\tmarkListParams = orDefault(markListParams, false, 'bool');\n\n\tif( url === 'about:blank' ) return url;\n\tif( url.trim() === '' ){\n\t\turl = window.location.href;\n\t}\n\tif( url.startsWith('//') ){\n\t\turl = `${window.location.protocol}${url}`;\n\t} else if( url.startsWith('/') ){\n\t\turl = `${window.location.origin}${url}`;\n\t} else if( url.startsWith('?') ){\n\t\tconst anchorPart = !url.includes('#') ? window.location.href.split('#')[1] : null;\n\t\turl = `${window.location.href.split('?')[0]}${url}${hasValue(anchorPart) ? '#'+anchorPart : ''}`;\n\t} else if( url.startsWith('#') ){\n\t\turl = `${window.location.href.split('#')[0]}${url}`;\n\t}\n\tif( !(/^https?:\\/\\//.test(url)) ){\n\t\turl = `${window.location.protocol}//${url}`;\n\t}\n\n\tlet urlObj;\n\ttry {\n\t\turlObj = new URL(url);\n\t} catch(ex){\n\t\tthrow new Error(`${MODULE_NAME}:${__methodName__} | unusable URL \"${url}\" [${ex}]`);\n\t}\n\n\tif( hasValue(anchor) ){\n\t\turlObj.hash = anchor.startsWith('#') ? anchor : `#${anchor}`;\n\t}\n\n\tconst urlParams = urlObj.searchParams;\n\n\tif( hasValue(params) ){\n\t\tfor( let paramName in params ){\n\t\t\tlet overrideName = paramName;\n\t\t\tif( paramName.startsWith('!') ){\n\t\t\t\toverrideName = paramName.slice(1);\n\t\t\t}\n\n\t\t\tif( overrideName !== paramName ){\n\t\t\t\turlParams.delete(overrideName);\n\t\t\t}\n\n\t\t\t[].concat(params[paramName]).forEach(paramValue => {\n\t\t\t\turlParams.append(overrideName, `${paramValue}`);\n\t\t\t});\n\t\t}\n\t}\n\n\tif( markListParams ){\n\t\tfor( let k of urlParams.keys() ){\n\t\t\tconst cleanKey = k.replace(/\\[]$/, '');\n\n\t\t\tlet presentValues = [].concat(urlParams.getAll(k));\n\t\t\tif( k.endsWith('[]') ){\n\t\t\t\tpresentValues = presentValues.concat(urlParams.getAll(cleanKey));\n\t\t\t}\n\n\t\t\tif( (presentValues.length > 1) ){\n\t\t\t\turlParams.delete(k);\n\t\t\t\turlParams.delete(cleanKey);\n\t\t\t\tpresentValues.forEach(v => {\n\t\t\t\t\turlParams.append(`${cleanKey}[]`, v);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tlet\tquery = urlObj.search\n\t\t.replace(/\\+/g, '%20')\n\t\t.replace(/=&/g, '&')\n\t\t.replace(/=$/g, '')\n\t;\n\n\tif( !keepEncodedUrlSafeChars ){\n\t\tquery = query\n\t\t\t.replaceAll('%2B', '+')\n\t\t\t.replaceAll('%5B', '[')\n\t\t\t.replaceAll('%5D', ']')\n\t\t;\n\t}\n\n\tlet queryParts = query.startsWith('?') ? query.slice(1).split('&') : []\n\tif( !isEmpty(queryParts) ){\n\t\tqueryParts.sort((a, b) => {\n\t\t\tconst\n\t\t\t\taKey = a.split('=')[0],\n\t\t\t\tbKey = b.split('=')[0]\n\t\t\t;\n\t\t\treturn (aKey < bKey) ? -1 : ((aKey > bKey) ? 1 : 0 );\n\t\t});\n\t\tqueryParts = queryParts.filter((part, index) => {\n\t\t\tif( index >= 1 ){\n\t\t\t\treturn queryParts.indexOf(part) === index;\n\t\t\t} else {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t});\n\t\tquery = `?${queryParts.join('&')}`;\n\t}\n\n\tlet finalUrl;\n\tif( !isEmpty(query) ){\n\t\tfinalUrl = `${urlObj.href.split('?')[0]}${query}${urlObj.hash}`.replace('/?', '?');\n\t} else if( !isEmpty(urlObj.hash) && isEmpty(query) ){\n\t\tfinalUrl = `${urlObj.href.split('#')[0]}${urlObj.hash}`.replace('/#', '#');\n\t} else {\n\t\tfinalUrl = urlObj.href.replace(/\\/$/, '');\n\t}\n\n\treturn keepEncodedUrlSafeChars ? finalUrl : replace(\n\t\tfinalUrl,\n\t\t['%2C', '%3A', '%40', '%24', '%2F', '%2B'],\n\t\t[',', ':', '@', '$', '/', '+']\n\t);\n}\n\n\n\n/**\n * @namespace Urls:urlParameter\n */\n\n/**\n * Searches for and returns parameters embedded in the provided url containing a query string\n * (make sure all values are url encoded).\n *\n * You may also just provide the query string.\n *\n * Returns a single parameter's value if a parameter name is given, otherwise returns dictionary with all parameters\n * as keys and the associated parameter value.\n *\n * If a parameter has more than one value the values are returned as an array, whether being requested by name\n * or in the dictionary containing all params.\n *\n * If a parameter is set, but has no defined value (name present, but no = before next param)\n * the value is returned as boolean true.\n *\n * @param {?String|URL} [url=null] - the url containing the parameter string, will use current URL if nullish\n * @param {?String} [parameter=null] - the name of the parameter to extract\n * @throws error if given url is not usable\n * @returns {null|true|String|Array|Object} null in case the parameter doesn't exist, true in case it exists but has no value, a string in case the parameter has one value, or an array of values, or a dictionary object of all available parameters with corresponding values\n *\n * @memberof Urls:urlParameter\n * @alias urlParameter\n * @see urlHref\n * @example\n * const hasKittens = urlParameter('//foobar.com/bar?has_kittens', 'has_kittens');\n * => true\n * const hasDoggies = urlParameter('has_doggies=yes&has_doggies', 'has_doggies');\n * => ['yes', true]\n * const allTheData = urlParameter('?foo=foo&bar=bar&bar=barbar&bar');\n * => {foo : 'foo', bar : ['bar', 'barbar', true]}\n */\nexport function urlParameter(url=null, parameter=null){\n\turl = urlHref(url, null, null, false, true);\n\tparameter = orDefault(parameter, null, 'str');\n\n\tconst\n\t\tsearchParams = new URL(url).searchParams,\n\t\tfMapParameterValue = parameterValue => ((parameterValue === '') ? true : parameterValue)\n\t;\n\n\tif( hasValue(parameter) ){\n\t\tconst parameterValues = searchParams.getAll(parameter);\n\t\tif( parameterValues.length === 0 ){\n\t\t\treturn null;\n\t\t} else if( parameterValues.length === 1 ){\n\t\t\treturn fMapParameterValue(parameterValues[0]);\n\t\t} else {\n\t\t\treturn Array.from(new Set(parameterValues.map(fMapParameterValue)));\n\t\t}\n\t} else {\n\t\tconst parameters = {};\n\t\tArray.from(searchParams.keys()).forEach(parameterName => {\n\t\t\tconst parameterValues = searchParams.getAll(parameterName);\n\t\t\tif( parameterValues.length > 0 ){\n\t\t\t\tparameters[parameterName] =\n\t\t\t\t\t(parameterValues.length === 1)\n\t\t\t\t\t? fMapParameterValue(parameterValues[0])\n\t\t\t\t\t: Array.from(new Set(parameterValues.map(fMapParameterValue)))\n\t\t\t\t;\n\t\t\t}\n\t\t});\n\t\treturn (size(parameters) > 0) ? parameters : null;\n\t}\n}\n\n\n\n/**\n * @namespace Urls:urlParameters\n */\n\n/**\n * Searches for and returns parameters embedded in provided url with a parameter string.\n *\n * Semantic shortcut version of urlParameter without any given parameter.\n *\n * @param {?String|URL} [url=null] - the url containing the parameter string, will use current URL if nullish\n * @throws error if given url is not usable\n * @returns {Object|null} dictionary object of all parameters or null if url has no parameters\n *\n * @memberof Urls:urlParameters\n * @alias urlParameters\n * @see urlParameter\n * @example\n * const allParams = urlParameters('http://www.foobar.com?foo=foo&bar=bar&bar=barbar&bar');\n * => {foo : 'foo', bar : ['bar', 'barbar', true]}\n */\nexport function urlParameters(url=null){\n\treturn urlParameter(url);\n}\n\n\n\n/**\n * @namespace Urls:urlAnchor\n */\n\n/**\n * Returns the currently set URL-Anchor on given URL.\n *\n * Theoretically, this function also works with any other string containing a hash (as long as there is \"#\" included),\n * since this implementation does not lean on \"new URL()\", but is a simple string operation.\n *\n * In comparison to \"location.hash\", this function actually decodes the hash automatically.\n *\n * @param {?String|URL} [url=null] - the url, in which to search for a hash, uses current url if nullish\n * @param {?Boolean} [withCaret=false] - defines if the returned anchor value should contain leading \"#\"\n * @throws error if given url is not usable\n * @returns {String|null} current anchor value or null if no anchor was found\n *\n * @memberof Urls:urlAnchor\n * @alias urlAnchor\n * @example\n * const anchorWithoutCaret = urlAnchor('https://foobar.com#test');\n * => 'test'\n * const hrefAnchorWithCaret = urlAnchor(linkElement.getAttribute('href'), true);\n * => '#test'\n * const decodedAnchorFromLocation = urlAnchor(window.location.hash);\n */\nexport function urlAnchor(url=null, withCaret=false){\n\turl = urlHref(url);\n\twithCaret = orDefault(withCaret, false, 'bool');\n\n\tconst urlParts = url.split('#');\n\n\tlet anchor = (urlParts.length > 1) ? decodeURIComponent(urlParts[1].trim()) : null;\n\tif( anchor === '' ){\n\t\tanchor = null;\n\t}\n\tif( withCaret && hasValue(anchor) ){\n\t\tanchor = `#${anchor}`;\n\t}\n\n\treturn anchor;\n}\n\n\n\n/**\n * @namespace Urls:addNextParameter\n */\n\n/**\n * Adds a \"next\"-parameter to a given URL. If there is already a parameter of that name, it will be replaced.\n *\n * A \"next\"-parameter is usually used to relay a second URL, which should be redirected to after something happens,\n * such as a login or another (possibly automatic) action.\n *\n * @param {?String} [url=''] - the URL to add the next parameter to, if left empty, will be \"\", which is synonymous with the current URL\n * @param {?String} [next=''] - the next URL to add as parameter to the given URL (will automatically be URL-encoded)\n * @param {?String} [paramName='next'] - the name of the next parameter\n * @param {?Boolean} [assertSameBaseDomain=false] - if true, url and next must have the same base domain (ignoring subdomains), to prevent injections\n * @param {?Array} [additionalTopLevelDomains=null] - this function uses a list of common TLDs (if assertSameBaseDomain is true), if yours is missing, you may provide it, using this parameter\n * @throws error if url or next are not usable URLs\n * @throws error if assertBaseDomain is true an the base domains of url and next differ\n * @returns {String} the transformed URL with the added next parameter\n *\n * @memberof Urls:addNextParameter\n * @alias addNextParameter\n * @see urlHref\n * @example\n * addNextParameter('https://foobar.com', 'https://foo.bar', 'redirect');\n * => 'https://foobar.com?redirect=https%3A%2F%2Ffoo.bar'\n * addNextParameter('https://foobar.com?next=https%3A%2F%2Ffoo.bar', 'https://kittens.com');\n * => 'https://foobar.com?next=https%3A%2F%2Fkittens.com'\n */\nexport function addNextParameter(url, next, paramName='next', assertSameBaseDomain=false, additionalTopLevelDomains=null){\n\tconst __methodName__ = 'addNextParameter';\n\n\turl = urlHref(url);\n\tnext = urlHref(next);\n\tparamName = orDefault(paramName, 'next', 'str');\n\tassertSameBaseDomain = orDefault(assertSameBaseDomain, true, 'bool');\n\n\tif( assertSameBaseDomain ){\n\t\tassert(\n\t\t\tevaluateBaseDomain(new URL(url).hostname, additionalTopLevelDomains) === evaluateBaseDomain(new URL(next).hostname, additionalTopLevelDomains),\n\t\t\t`${MODULE_NAME}:${__methodName__} | different base domains in url and next`\n\t\t);\n\t}\n\n\tconst params = new URL(url).searchParams;\n\tif( params.has(paramName) ){\n\t\tlog().info(`${MODULE_NAME}:${__methodName__} | replaced \"${paramName}\" value \"${params.get(paramName)}\" with \"${next}\"`);\n\t}\n\n\treturn urlHref(url, {[`!${paramName}`] : next});\n}\n\n\n\n/**\n * @namespace Urls:addCacheBuster\n */\n\n/**\n * Adds a cache busting parameter to a given URL. If there is already a parameter of that name, it will be replaced.\n * This prevents legacy browsers from caching requests by changing the request URL dynamically, based on current time.\n *\n * @param {?String|URL} [url=null] - the URL to add the cache busting parameter to, if nullish, the current URL will be used\n * @param {?String} [paramName='_'] - the name of the cache busting parameter\n * @throws error if url is not a usable URL\n * @returns {String} the transformed URL with the added cache busting parameter\n *\n * @memberof Urls:addCacheBuster\n * @alias addCacheBuster\n * @see urlHref\n * @example\n * addCacheBuster('https://foobar.com');\n * => 'https://foobar.com?_=1648121948009'\n * addCacheBuster('https://foobar.com?next=https%3A%2F%2Ffoo.bar', 'nocache');\n * => 'https://foobar.com?next=https%3A%2F%2Ffoo.bar&nocache=1648121948009'\n */\nexport function addCacheBuster(url=null, paramName='_'){\n\tconst __methodName__ = 'addCacheBuster';\n\n\turl = urlHref(url);\n\n\tconst\n\t\tparams = new URL(url).searchParams,\n\t\tbuster = Date.now()\n\t;\n\n\tif( params.has(paramName) ){\n\t\tlog().info(`${MODULE_NAME}:${__methodName__} | replaced \"${paramName}\" value \"${params.get(paramName)}\" with \"${buster}\"`);\n\t}\n\n\treturn urlHref(url, {[`!${paramName}`] : buster})\n}\n\n\n\n/**\n * @namespace Urls:evaluateBaseDomain\n */\n\n/**\n * Walks a domain string (e.g. foobar.barfoo.co.uk) backwards, separated by dots, skips over all top level\n * domains it finds and includes the first non-TLD value to retrieve the base domain without any subdomains\n * (e.g. barfoo.co.uk).\n *\n * This is not completely fool-proof in case of very exotic TLDs, but quite robust in most cases.\n *\n * This method is particularly helpful if you want to set a domain cookie while being on a subdomain.\n *\n * @param {String} domain - the domain string (hostname), which should be evaluated; you may also provide a full, parsable URL, from which to extract the hostname\n * @param {?Array} [additionalTopLevelDomains=null] - this function uses a list of common TLDs, if yours is missing, you may provide it, using this parameter\n * @returns {String} the evaluated base domain string\n *\n * @memberof Urls:evaluateBaseDomain\n * @alias evaluateBaseDomain\n * @example\n * evaluateBaseDomain('foobar.barfoo.co.uk');\n * => 'barfoo.co.uk'\n * evaluateBaseDomain('https://foobar.barfoo.co.uk/?foo=bar');\n * => 'barfoo.co.uk'\n */\nexport function evaluateBaseDomain(domain, additionalTopLevelDomains=null){\n\tdomain = orDefault(domain, window.location.hostname, 'str');\n\tadditionalTopLevelDomains = orDefault(additionalTopLevelDomains, null, 'arr');\n\n\tlet url;\n\ttry {\n\t\turl = new URL(domain);\n\t} catch(error){\n\t\turl = null;\n\t}\n\tif( hasValue(url) ){\n\t\tdomain = url.hostname;\n\t}\n\n\tconst\n\t\ttopLevelDomains = new Set([\n\t\t\t...COMMON_TOP_LEVEL_DOMAINS,\n\t\t\t...(hasValue(additionalTopLevelDomains) ? additionalTopLevelDomains.map(tld => `${tld}`) : [])\n\t\t]),\n\t\tdomainParts = domain.split('.').reverse()\n\t;\n\n\tlet baseDomain = domain;\n\n\tif( domainParts.length > 2 ){\n\t\tlet i;\n\n\t\tfor( i = 0; i < domainParts.length; i++ ){\n\t\t\tif( !topLevelDomains.has(domainParts[i]) ){\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tbaseDomain = domainParts.slice(0, i + 1).reverse().join('.');\n\t}\n\n\treturn baseDomain;\n}\n\n\n\n/**\n * @namespace Urls:Urison\n */\n\n/**\n * A class, which (re)implements the \"Rison\" standard of en- and decoding JSON structures to and from URL-safe strings,\n * which can be used as parameter or hash values, while staying readable and avoiding characters, which are not meant\n * to be used inside a URL.\n *\n * This is a renamed reimplementation of ES5 Rison, which has not gotten an update for years and should be fully\n * compatible with other available parsers for that standard.\n *\n * The basic idea is this:\n * We have some kind of complex data structure we want to serialize to a URL, to represent a current search and filter\n * setup for example. This structure should also be retrievable easily after a reload, to be able to use that config\n * as a starting point again for the page's search and filter widgets. A big plus here would be readability, which,\n * for instance, gets lost, if we just were to url-encode JSON as-is.\n *\n * This class provides the means to en- and decode JSON structures for usage in URLs. Additionally, it provides methods\n * to explicitly work with objects and array, for the en- and decoding process, removing the necessity to include\n * brackets into the result, making the string even leaner.\n *\n * See class documentation below for details.\n *\n * @memberof Urls:Urison\n * @name Urison\n *\n * @see Urison\n * @see https://github.com/Nanonid/rison\n * @example\n * (new Urison()).encode({key1 : 'value', key2 : true, key3 : [false, 42, null]})\n * => '(key1:value,key2:!t,key3:!(!f,42,!n))'\n * (new Urison()).decode('(key1:value,key2:!t,key3:!(!f,42,!n))')\n * => {key1 : 'value', key2 : true, key3 : [false, 42, null]}\n * (new Urison()).encodeObject({key1 : 'value', key2 : true, key3 : [false, 42, null]})\n * => 'key1:value,key2:!t,key3:!(!f,42,!n)'\n * (new Urison()).decodeObject('key1:value,key2:!t,key3:!(!f,42,!n)')\n * => {key1 : 'value', key2 : true, key3 : [false, 42, null]}\n * (new Urison()).encodeArray([false, 42, null])\n * => '!f,42,!n'\n * (new Urison()).decodeArray('!f,42,!n')\n * => [false, 42, null]\n */\nclass Urison {\n\n\t#__className__ = 'Urison';\n\t#autoEscape;\n\t#autoUnescape;\n\t#encoders;\n\t#parser;\n\n\t/**\n\t * Creates a new Urison en- and decoder.\n\t *\n\t * @param {Boolean} [autoEscape=true] - if true, all keys and values are automatically uri-encoded and decoded if necessary, set this to false to keep values as is\n\t */\n\tconstructor(autoEscape=true){\n\t\tconst instance = this;\n\n\t\tautoEscape = orDefault(autoEscape, true, 'bool');\n\t\tthis.#autoEscape = autoEscape ? this.escape : val => val;\n\t\tthis.#autoUnescape = autoEscape ? decodeURIComponent : val => val;\n\n\t\t// procedure map, defining how data types are string-represented in Rison\n\t\tthis.#encoders = {\n\t\t\tarray(value){\n\t\t\t\tconst res = [];\n\n\t\t\t\tfor( let v of value ){\n\t\t\t\t\tconst encodedValue = instance.encode(v);\n\t\t\t\t\tif( isString(encodedValue) ){\n\t\t\t\t\t\tres.push(encodedValue);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn `!(${res.join(',')})`;\n\t\t\t},\n\n\t\t\tboolean(value){\n\t\t\t\treturn !!value ? '!t' : '!f';\n\t\t\t},\n\n\t\t\tnull(){\n\t\t\t\treturn '!n';\n\t\t\t},\n\n\t\t\tnumber(value){\n\t\t\t\tif( !isFinite(value) ) return '!n';\n\t\t\t\treturn `${value}`.replace(/\\+/, '');\n\t\t\t},\n\n\t\t\tobject(value){\n\t\t\t\tif( hasValue(value) ){\n\t\t\t\t\tif( isArray(value) ){\n\t\t\t\t\t\treturn this.array(value);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst keys = Object.keys(value);\n\t\t\t\t\tkeys.sort();\n\n\t\t\t\t\tconst res = [];\n\t\t\t\t\tfor( let key of keys ){\n\t\t\t\t\t\tconst v = instance.encode(value[key]);\n\t\t\t\t\t\tif( isString(v) ){\n\t\t\t\t\t\t\tconst k = isNaN(parseInt(key, 10)) ? this.string(key) : this.number(key);\n\t\t\t\t\t\t\tres.push(`${k}:${v}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn `(${res.join(',')})`;\n\t\t\t\t}\n\n\t\t\t\treturn '!n';\n\t\t\t},\n\n\t\t\tstring(value){\n\t\t\t\tif( value === '' ) return \"''\";\n\t\t\t\tif( URISON_VALUE_REX.test(value) ) return value;\n\n\t\t\t\tvalue = value.replace(/(['!])/g, function(_, quotedChar){\n\t\t\t\t\treturn `!${quotedChar}`;\n\t\t\t\t});\n\n\t\t\t\treturn `'${value}'`;\n\t\t\t}\n\t\t};\n\n\t\tthis.#parser = (new UrisonParser((error, index) => {\n\t\t\tthrow Error(`decoding error [${error}] at string index ${index}`);\n\t\t}));\n\t}\n\n\n\n\t/**\n\t * Encodes a JSON value to a Rison string.\n\t *\n\t * @param {Array|Object|String|Number|Boolean|null} value - the value to encode\n\t * @throws error if encoding fails or value is not usable JSON\n\t * @returns {String|undefined} the encoded Rison string or undefined if value cannot be encoded\n\t *\n\t * @example\n\t * (new Urison()).encode({key1 : 'value', key2 : true, key3 : [false, 42, null]})\n\t * => '(key1:value,key2:!t,key3:!(!f,42,!n))'\n\t */\n\tencode(value){\n\t\tconst __methodName__ = 'encode';\n\n\t\tif( isFunction(value?.toJson) ){\n\t\t\tvalue = value.toJson();\n\t\t}\n\n\t\tif( isFunction(value?.toJSON) ){\n\t\t\tvalue = value.toJSON();\n\t\t}\n\n\t\tconst encoder = this.#encoders[typeof value];\n\t\tif( !isFunction(encoder) ){\n\t\t\tthrow new Error(`${this.#__className__}.${__methodName__} | invalid data type`);\n\t\t}\n\n\t\tlet res;\n\t\ttry {\n\t\t\tres = encoder.call(this.#encoders, value);\n\t\t} catch(ex){\n\t\t\tthrow new Error(`${this.#__className__}.${__methodName__} | encoding error [${ex}]`);\n\t\t}\n\n\t\treturn this.#autoEscape(this.#autoUnescape(res));\n\t}\n\n\n\n\t/**\n\t * Encodes a JSON value to a Rison string.\n\t *\n\t * @param {Object} value - the object to encode\n\t * @returns {String|undefined} the encoded Rison string or undefined if value cannot be encoded\n\t * @throws error if value is not an object\n\t *\n\t * @example\n\t * (new Urison()).encodeObject({key1 : 'value', key2 : true, key3 : [false, 42, null]})\n\t * => 'key1:value,key2:!t,key3:!(!f,42,!n)'\n\t */\n\tencodeObject(value){\n\t\tconst __methodName__ = 'encodeObject';\n\n\t\tif( !isObject(value) ){\n\t\t\tthrow new Error(`${this.#__className__}.${__methodName__} | value is not an object`);\n\t\t}\n\n\t\tconst res = this.#encoders.object(value);\n\t\treturn this.#autoEscape(this.#autoUnescape(res.substring(1, res.length - 1)));\n\t}\n\n\n\n\t/**\n\t * Encodes a JSON array to a Rison string.\n\t *\n\t * @param {Array} value - the array to encode\n\t * @returns {String|undefined} the encoded Rison string or undefined if value cannot be encoded\n\t * @throws error if value is not an array\n\t *\n\t * @example\n\t * (new Urison()).encodeArray([false, 42, null])\n\t * => '!f,42,!n'\n\t */\n\tencodeArray(value){\n\t\tconst __methodName__ = 'encodeArray';\n\n\t\tif( !isArray(value) ){\n\t\t\tthrow new Error(`${this.#__className__}.${__methodName__} | value is not an array`);\n\t\t}\n\n\t\tconst res = this.#encoders.array(value);\n\t\treturn this.#autoEscape(this.#autoUnescape(res.substring(2, res.length - 1)));\n\t}\n\n\n\n\t/**\n\t * Decodes a Rison string to a JSON value.\n\t *\n\t * @param {String} risonString - the Rison string to decode\n\t * @returns {Object|Array|String|Number|Boolean|null} the decoded JSON value\n\t * @throws error if decoding fails\n\t *\n\t * @example\n\t * (new Urison()).decode('(key1:value,key2:!t,key3:!(!f,42,!n))')\n\t * => {key1 : 'value', key2 : true, key3 : [false, 42, null]}\n\t */\n\tdecode(risonString){\n\t\treturn this.#parser.parse(this.#autoUnescape(risonString));\n\t}\n\n\n\n\t/**\n\t * Decodes a shortened Rison object string to a JSON object.\n\t *\n\t * @param {String} risonString - the Rison object string to decode\n\t * @returns {Object} the decoded JSON object\n\t * @throws error if decoding fails\n\t *\n\t * @example\n\t * (new Urison()).decodeObject('key1:value,key2:!t,key3:!(!f,42,!n)')\n\t * => {key1 : 'value', key2 : true, key3 : [false, 42, null]}\n\t */\n\tdecodeObject(risonString){\n\t\treturn this.decode(`(${risonString})`);\n\t}\n\n\n\n\t/**\n\t * Decodes a shortened Rison array string to a JSON array.\n\t *\n\t * @param {String} risonString - the Rison array string to decode\n\t * @returns {Array} the decoded JSON array\n\t * @throws error if decoding fails\n\t *\n\t * @example\n\t * (new Urison()).decodeArray('!f,42,!n')\n\t * => [false, 42, null]\n\t */\n\tdecodeArray(risonString){\n\t\treturn this.decode(`!(${risonString})`);\n\t}\n\n\n\n\t/**\n\t * URI-Escapes a value, if necessary, according to the rules of Rison, which is a little bit\n\t * more lax than native uri encoding (allows [,:@$/+]).\n\t *\n\t * This method has one difference to the reference implementation:\n\t * We do _not_ encode whitespace as \"+\", but as \"%20\". This is done, because \"+\"-encoding is not\n\t * compatible with `decodeURIComponent` and makes working with URL-encoded values manually painful.\n\t * So here, \"+\" is just a normal, allowed URL-safe character and whitespace becomes \"%20\".\n\t * Since `encode_uri` was never automatically applied in Rison, this should not break anything.\n\t *\n\t * @param {String} value - the value to escape problematic chars in\n\t * @returns {String} uri-encoded string\n\t *\n\t * @example\n\t * (new Urison()).escape('abc,:@')\n\t * => 'abc%2C%3A%40'\n\t */\n\tescape(value){\n\t\tvalue = `${value}`;\n\n\t\tif( /^[\\-A-Za-z0-9~!*()_.',:@$\\/+]*$/.test(value) ) return value;\n\n\t\treturn replace(\n\t\t\tencodeURIComponent(value),\n\t\t\t['%2C', '%3A', '%40', '%24', '%2F', '%2B'],\n\t\t\t[',', ':', '@', '$', '/', '+']\n\t\t);\n\t}\n\n}\n\nexport {Urison};\n"]} \ No newline at end of file diff --git a/dist/viewport.js b/dist/viewport.js index 590d315c..ae1ddcf0 100644 --- a/dist/viewport.js +++ b/dist/viewport.js @@ -1,8 +1,8 @@ /*! - * @oktarintentakel/annex v0.1.18-beta + * @oktarintentakel/annex v0.1.19-beta */ /*! * Module Viewport */ -const MODULE_NAME="Viewport";import{hasValue,orDefault,isWindow,isPlainObject,isArray,isFunction,isElement,isBoolean,isNumber,Deferred,Observable,assert,min,minMax,round}from"./basic.js";import{isInDom}from"./elements.js";import{EasingFunctions}from"./animation.js";import{requestAnimationFrame,cancelAnimationFrame}from"./timers.js";import{throttle,defer}from"./functions.js";import{warn}from"./logging.js";import{fire}from"./events.js";const VISIBILITY_BASE_FPS=15,DISTANCE_BASE_FPS=4,BREAKPOINT_BASE_FPS=4;function getBoundingClientRect(t){let e;try{e=t.getBoundingClientRect()}catch(t){e=window.DOMRect?new DOMRect(0,0,0,0):{top:0,right:0,bottom:0,left:0,width:0,height:0}}return e}class SimplePollingObserver{#t="SimplePollingObserver";#e;#i;#s;#r;constructor(t,e){this.#e=t,this.#i=new Set,this.#s=e?.targetFps??15,this.connect()}connect(){this.disconnect();const t=round(1e3/this.#s),e=throttle(t,(()=>{this.#e(Array.from(this.#i).map((t=>{const e=getBoundingClientRect(t),i=window.innerWidth,s=window.innerHeight,r=e.top<0?Math.abs(e.top):0,n=e.top+e.height>s?e.top+e.height-s:0,o=minMax(0,e.height-r-n,round(e.height)),l={target:t,rootBounds:isInDom(t)?{top:0,right:i,bottom:s,left:0,width:i,height:s}:null,boundingClientRect:e,intersectionRect:{height:o}};return l.intersectionRatio=o/l.boundingClientRect.height,l})))})).bind(this),i=()=>{e(),this.#r=requestAnimationFrame(i)};return this.#r=requestAnimationFrame(i),this}disconnect(){return cancelAnimationFrame(this.#r),this.#r=null,this.#i.clear(),this}observe(t){return this.#i.add(t),this}unobserve(t){return this.#i.delete(t),this}}class VisibilityState{#t="VisibilityState";#n="visibilitystate";#o;#l=!1;#a=!1;#h=!1;#u=!1;#d=0;#c=0;calculateScrolled=!1;#p=0;#b=null;#w=null;calculateDistance=!1;#g=Number.POSITIVE_INFINITY;#v=Number.POSITIVE_INFINITY;#f=null;#m=null;autoHandleTooLargeElements=!0;#I=null;#V=null;#S=null;constructor(t,e=!1,i=!1,s=!0){this.#o=t,this.calculateScrolled=!!e,this.calculateDistance=!!i,this.autoHandleTooLargeElements=!!s}inViewport(t=null){if(hasValue(t)){const e=this.#l;this.#l=!!t,this.#B(e,this.#l,"enteredviewport","leftviewport")}return this.#l}fullyInViewport(t=null){if(hasValue(t)){const e=this.#a;this.#a=!!t,this.#B(e,this.#a,"fullyenteredviewport","fullyleftviewport")}return this.#a}upperBoundInViewport(t=null){if(hasValue(t)){const e=this.#h;this.#h=!!t,this.#B(e,this.#h,"upperboundenteredviewport","upperboundleftviewport")}return this.#h}lowerBoundInViewport(t=null){if(hasValue(t)){const e=this.#u;this.#u=!!t,this.#B(e,this.#u,"lowerboundenteredviewport","lowerboundleftviewport")}return this.#u}visiblePercent(t=null){if(hasValue(t)){const e=this.#d;this.#d=minMax(0,round(parseFloat(t),2),100),this.#B(e,this.#d,"visiblepercent")}return this.#d}visiblePixels(t=null){if(hasValue(t)){const e=this.#c;this.#c=minMax(0,round(parseFloat(t)),round(this.#o.scrollHeight)),this.#B(e,this.#c,"visiblepixels")}return this.#c}scrolledPercent(t=null){if(hasValue(t)){const e=this.#p;this.#p=minMax(0,round(parseFloat(t),2),100),this.#B(e,this.#p,"scrolledpercent")}return this.#p}distancePixels(t=null){if(hasValue(t)){const e=this.#g;this.#g=round(parseFloat(t)),this.#B(e,this.#g,"distancepixels")}return this.#g}distanceViewports(t=null){if(hasValue(t)){const e=this.#v;this.#v=round(parseFloat(t),2),this.#B(e,this.#v,"distanceviewports")}return this.#v}startAutoScrolledPercentUpdates(t,e=15,i=!0){if(this.calculateScrolled&&!hasValue(this.#b)){this.#b=t;const s=round(1e3/e);this.#w=this.#b.subscribe(throttle(s,(()=>{const t=getBoundingClientRect(this.#o),e=window.innerHeight;this.scrolledPercent((t.top-e)/(-t.height-e)*100),i&&this.#O()})))}return this}stopAutoScrolledPercentUpdates(){return hasValue(this.#b)&&this.#b.unsubscribe(this.#w),this.#w=null,this.#b=null,this}startAutoDistanceUpdates(t,e=15){if(this.calculateDistance&&!hasValue(this.#f)){this.#f=t;const i=round(1e3/e);this.#m=this.#f.subscribe(throttle(i,(()=>{const t=getBoundingClientRect(this.#o),e=window.innerHeight,i=t.top-e,s=t.bottom,r=Math.abs(i){this.#O()})))}return this}stopAutoTooLargeUpdates(){return hasValue(this.#I)&&this.#I.unsubscribe(this.#V),this.#V=null,this.#I=null,this}toJson(){const t={inViewport:this.inViewport(),fullyInViewport:this.fullyInViewport(),upperBoundInViewport:this.upperBoundInViewport(),lowerBoundInViewport:this.lowerBoundInViewport(),visiblePercent:this.visiblePercent(),visiblePixels:this.visiblePixels()};return this.calculateScrolled&&(t.scrolledPercent=this.scrolledPercent()),this.calculateDistance&&(t.distancePixels=this.distancePixels(),t.distanceViewports=this.distanceViewports()),t}#E(t,e=null){return this.#o.dispatchEvent(new CustomEvent(`${t}.${this.#n}`,{detail:e??{}})),fire(this.#o,`${t}.${this.#n}`,e??{}),this}#P(){return hasValue(this.#S)||(this.#S=defer((()=>{this.#S=null,this.#E("changed")})),this.#S()),this}#B(t,e,i,s){return hasValue(e)&&(isBoolean(e)?e&&!t?(this.#E(i),this.#P()):!e&&t&&(this.#E(s),this.#P()):isNumber(e)&&e!==t&&(this.#E(i??s,e),this.#P())),this}#O(){const t=getBoundingClientRect(this.#o),e=window.innerHeight,i=t.top<0?Math.abs(t.top):0,s=t.top+t.height>e?t.top+t.height-e:0;return this.upperBoundInViewport(t.top>=0&&t.top<=e),this.lowerBoundInViewport(t.bottom>=0&&t.bottom<=e),this.visiblePixels(t.height-i-s),this.visiblePercent(this.visiblePixels()/t.height*100),this}}export function isInViewport(t,e=!1){if(e=orDefault(e,!1,"bool"),!isInDom(t))return!1;const i=t.getBoundingClientRect(),s=window.innerWidth,r=window.innerHeight;let n;return n=e?{top:0,right:s,bottom:r,left:0}:{top:1-(i.bottom-i.top),right:s+(i.right-i.left)+1,bottom:r+(i.bottom-i.top)+1,left:1-(i.right-i.left)},i.top>=n.top&&i.right<=n.right&&i.left>=n.left&&i.bottom<=n.bottom}export function scrollTo(t,e=1e3,i=0,s="easeInOutCubic",r=!1,n=!1){const o="scrollTo";e=orDefault(e,1e3,"int"),i=orDefault(i,0,"int"),s=orDefault(s,"easeInOutCubic","str"),r=orDefault(r,!1,"bool"),n=orDefault(n,!1,"bool"),assert(isElement(t)||isWindow(t),`Viewport:${o} | element unusable`),assert(e>0,`Viewport:${o} | durationMs must be > 0`),s=isFunction(EasingFunctions[s])?EasingFunctions[s]:EasingFunctions.easeInOutCubic;const l=new Deferred,a=t.self===t,h=!a&&isInDom(t),u=!(a||!h)&&isInViewport(t,!0);if((h||a)&&(r||!u)){let r,o,h=!1;const u=window.scrollY??window.pageYOffset;o=a?i:u+getBoundingClientRect(t).top-round(window.innerHeight/2)+i;const d=o-u,c=function(t){if(!h){hasValue(r)||(r=t);const i=t-r,n=s(Math.min(i/e,1));window.scrollTo(0,u+d*n),ithis.#N.scrollTop?this.#N.scrollDirection="down":sthis.#x+10?(this.#N.fuzzyScrollDirection="down",this.#x=s):s{if(hasValue(t.rootBounds)){const e=this.#_.get(t.target);e.inViewport(t.intersectionRatio>0),e.fullyInViewport(t.intersectionRatio>=1),e.upperBoundInViewport(t.boundingClientRect.top>=t.rootBounds.top&&t.boundingClientRect.top<=t.rootBounds.bottom),e.lowerBoundInViewport(t.boundingClientRect.bottom>=t.rootBounds.top&&t.boundingClientRect.bottom<=t.rootBounds.bottom),e.visiblePercent(100*t.intersectionRatio),e.visiblePixels(t.intersectionRect.height),e.calculateScrolled&&(e.scrolledPercent((t.boundingClientRect.top-t.rootBounds.height)/(-t.boundingClientRect.height-t.rootBounds.height)*100),e.fullyInViewport()?e.startAutoScrolledPercentUpdates(this.#A,this.#s):e.stopAutoScrolledPercentUpdates()),e.calculateDistance&&(e.inViewport()?(e.stopAutoDistanceUpdates(),e.distancePixels(0),e.distanceViewports(0)):e.startAutoDistanceUpdates(this.#A,4)),e.autoHandleTooLargeElements&&t.boundingClientRect.height>t.rootBounds.height&&(e.inViewport()?(e.startAutoTooLargeUpdates(this.#A,this.#s),e.calculateScrolled&&e.startAutoScrolledPercentUpdates(this.#A,this.#s,!1)):(e.stopAutoTooLargeUpdates(),e.calculateScrolled&&e.stopAutoScrolledPercentUpdates()))}})),this.#D||(this.#D=!0,this.#E("initialized")),this.#k("updated"),this}#E(t,e=null){return document.body.dispatchEvent(new CustomEvent(`${t}.${this.#n}`,{detail:e??{}})),fire(document.body,`${t}.${this.#n}`,e??{}),this}#K(){window.addEventListener("scroll",this.#R),window.addEventListener("resize",this.#y),this.#L=new MutationObserver(this.#M),this.#L.observe(document.body,{attributes:!0,childList:!0,subtree:!0});const t=round(1e3/this.#s),e=round(t/10);return this.#C=window.setInterval(this.#X.bind(this),e),this}#G(){return window.clearInterval(this.#C),window.removeEventListener("scroll",this.#R),window.removeEventListener("resize",this.#y),hasValue(this.#L)&&(this.#L.disconnect(),this.#L=null),this}}export{VisibilityObserver};class BreakpointObserver{#t="BreakpointObserver";#Z="handler must be function";#e;#tt;#et;#it;#st;#y;constructor(t=null,e=4){hasValue(t)&&(assert(isFunction(t),`Viewport:${this.#t}.constructor | ${this.#Z}`),this.#e=t),this.#tt=(t,e)=>{Object.keys(this.#et).length>0&&this.#e?.(t,e)},e=minMax(1,orDefault(e,15,"int"),120);const i=round(1e3/e);this.#y=throttle(i,this.#j,!0,!0).bind(this),this.connect(t)}connect(t=null){return this.disconnect(),hasValue(t)&&(assert(isFunction(t),`Viewport:${this.#t}.connect | ${this.#Z}`),this.#e=t),this.#it.subscribe(this.#tt),this.#it.subscribe((t=>{this.#st.setValue(t)})),this.#K(),this}disconnect(){return this.#et={},this.#it=new Observable,this.#st=new Observable,this.#G(),this}getBreakpoint(t){if(isNumber(t)){let e=null;for(const i in this.#et)if(t===this.#et[i]){e=i;break}return e}return this.#et[`${t}`]??null}getBreakpoints(){return{...this.#et}}getCurrentBreakpoint(){return this.#it.getValue()}getCurrentBreakpointObservable(){return this.#st}observe(...t){const e=this.#rt(t);return this.#et={...this.#et,...e},this.#nt(),this}unobserve(...t){const e=this.#rt(t,!0);return Object.keys(e).forEach((t=>{delete this.#et[t]})),this.#nt(),this}#rt(t,e=!1){const i="#parseBreakpointList",s="unusable breakpoint";let r={};return Array.from(t).forEach((t=>{if(isPlainObject(t)){for(const e in t)t[e]=parseInt(t[e],10),assert(!isNaN(t[e])&&t[e]>=0,`Viewport:${this.#t}.${i} | ${s} "${e}"`);r={...r,...t}}else if(isArray(t))if(2!==t.length||isPlainObject(t[0])||isArray(t[0])||isPlainObject(t[1])||isArray(t[1]))r={...r,...this.#rt(t,e)};else{const e=`${t[0]}`;r[e]=parseInt(t[1],10),assert(!isNaN(r[e])&&r[e]>=0,`Viewport:${this.#t}.${i} | ${s} "${e}"`)}else e&&(r[`${t}`]=null)})),r}#nt(){const t=window.innerWidth,e=Object.entries(this.#et).sort(((t,e)=>t[1]===e[1]?0:t[1]>e[1]?1:-1));let i=null;return e.forEach((([e,s])=>{t>=s&&(i=e)})),this.#it.setValue(i),this}#j(){return this.#nt(),this}#K(){return window.addEventListener("resize",this.#y),this}#G(){return window.removeEventListener("resize",this.#y),this}}export{BreakpointObserver}; +const MODULE_NAME="Viewport";import{hasValue,orDefault,isWindow,isPlainObject,isArray,isFunction,isElement,isBoolean,isNumber,Deferred,Observable,assert,min,minMax,round}from"./basic.js";import{isInDom}from"./elements.js";import{EasingFunctions}from"./animation.js";import{requestAnimationFrame,cancelAnimationFrame}from"./timers.js";import{throttle,defer}from"./functions.js";import{warn}from"./logging.js";import{fire}from"./events.js";const VISIBILITY_BASE_FPS=15,DISTANCE_BASE_FPS=4,BREAKPOINT_BASE_FPS=4;function getBoundingClientRect(e){let t;try{t=e.getBoundingClientRect()}catch(e){t=window.DOMRect?new DOMRect(0,0,0,0):{top:0,right:0,bottom:0,left:0,width:0,height:0}}return t}class SimplePollingObserver{#e="SimplePollingObserver";#t;#i;#s;#r;constructor(e,t){this.#t=e,this.#i=new Set,this.#s=t?.targetFps??15,this.connect()}connect(){this.disconnect();const e=round(1e3/this.#s),t=throttle(e,(()=>{this.#t(Array.from(this.#i).map((e=>{const t=getBoundingClientRect(e),i=window.innerWidth,s=window.innerHeight,r=t.top<0?Math.abs(t.top):0,n=t.top+t.height>s?t.top+t.height-s:0,o=minMax(0,t.height-r-n,round(t.height)),l={target:e,rootBounds:isInDom(e)?{top:0,right:i,bottom:s,left:0,width:i,height:s}:null,boundingClientRect:t,intersectionRect:{height:o}};return l.intersectionRatio=o/l.boundingClientRect.height,l})))})).bind(this),i=()=>{t(),this.#r=requestAnimationFrame(i)};return this.#r=requestAnimationFrame(i),this}disconnect(){return cancelAnimationFrame(this.#r),this.#r=null,this.#i.clear(),this}observe(e){return this.#i.add(e),this}unobserve(e){return this.#i.delete(e),this}}class VisibilityState{#e="VisibilityState";#n="visibilitystate";#o;#l=!1;#a=!1;#h=!1;#u=!1;#d=0;#c=0;calculateScrolled=!1;#p=0;#b=null;#w=null;calculateDistance=!1;#g=Number.POSITIVE_INFINITY;#v=Number.POSITIVE_INFINITY;#f=null;#m=null;autoHandleTooLargeElements=!0;#I=null;#V=null;#S=null;constructor(e,t=!1,i=!1,s=!0){this.#o=e,this.calculateScrolled=!!t,this.calculateDistance=!!i,this.autoHandleTooLargeElements=!!s}inViewport(e=null){if(hasValue(e)){const t=this.#l;this.#l=!!e,this.#B(t,this.#l,"enteredviewport","leftviewport")}return this.#l}fullyInViewport(e=null){if(hasValue(e)){const t=this.#a;this.#a=!!e,this.#B(t,this.#a,"fullyenteredviewport","fullyleftviewport")}return this.#a}upperBoundInViewport(e=null){if(hasValue(e)){const t=this.#h;this.#h=!!e,this.#B(t,this.#h,"upperboundenteredviewport","upperboundleftviewport")}return this.#h}lowerBoundInViewport(e=null){if(hasValue(e)){const t=this.#u;this.#u=!!e,this.#B(t,this.#u,"lowerboundenteredviewport","lowerboundleftviewport")}return this.#u}visiblePercent(e=null){if(hasValue(e)){const t=this.#d;this.#d=minMax(0,round(parseFloat(e),2),100),this.#B(t,this.#d,"visiblepercent")}return this.#d}visiblePixels(e=null){if(hasValue(e)){const t=this.#c;this.#c=minMax(0,round(parseFloat(e)),round(this.#o.scrollHeight)),this.#B(t,this.#c,"visiblepixels")}return this.#c}scrolledPercent(e=null){if(hasValue(e)){const t=this.#p;this.#p=minMax(0,round(parseFloat(e),2),100),this.#B(t,this.#p,"scrolledpercent")}return this.#p}distancePixels(e=null){if(hasValue(e)){const t=this.#g;this.#g=round(parseFloat(e)),this.#B(t,this.#g,"distancepixels")}return this.#g}distanceViewports(e=null){if(hasValue(e)){const t=this.#v;this.#v=round(parseFloat(e),2),this.#B(t,this.#v,"distanceviewports")}return this.#v}startAutoScrolledPercentUpdates(e,t=15,i=!0){if(this.calculateScrolled&&!hasValue(this.#b)){this.#b=e;const s=round(1e3/t);this.#w=this.#b.subscribe(throttle(s,(()=>{const e=getBoundingClientRect(this.#o),t=window.innerHeight;this.scrolledPercent((e.top-t)/(-e.height-t)*100),i&&this.#O()})))}return this}stopAutoScrolledPercentUpdates(){return hasValue(this.#b)&&this.#b.unsubscribe(this.#w),this.#w=null,this.#b=null,this}startAutoDistanceUpdates(e,t=15){if(this.calculateDistance&&!hasValue(this.#f)){this.#f=e;const i=round(1e3/t);this.#m=this.#f.subscribe(throttle(i,(()=>{const e=getBoundingClientRect(this.#o),t=window.innerHeight,i=e.top-t,s=e.bottom,r=Math.abs(i){this.#O()})))}return this}stopAutoTooLargeUpdates(){return hasValue(this.#I)&&this.#I.unsubscribe(this.#V),this.#V=null,this.#I=null,this}toJson(){const e={inViewport:this.inViewport(),fullyInViewport:this.fullyInViewport(),upperBoundInViewport:this.upperBoundInViewport(),lowerBoundInViewport:this.lowerBoundInViewport(),visiblePercent:this.visiblePercent(),visiblePixels:this.visiblePixels()};return this.calculateScrolled&&(e.scrolledPercent=this.scrolledPercent()),this.calculateDistance&&(e.distancePixels=this.distancePixels(),e.distanceViewports=this.distanceViewports()),e}#E(e,t=null){return this.#o.dispatchEvent(new CustomEvent(`${e}.${this.#n}`,{detail:t??{}})),fire(this.#o,`${e}.${this.#n}`,t??{}),this}#P(){return hasValue(this.#S)||(this.#S=defer((()=>{this.#S=null,this.#E("changed")})),this.#S()),this}#B(e,t,i,s){return hasValue(t)&&(isBoolean(t)?t&&!e?(this.#E(i),this.#P()):!t&&e&&(this.#E(s),this.#P()):isNumber(t)&&t!==e&&(this.#E(i??s,t),this.#P())),this}#O(){const e=getBoundingClientRect(this.#o),t=window.innerHeight,i=e.top<0?Math.abs(e.top):0,s=e.top+e.height>t?e.top+e.height-t:0;return this.upperBoundInViewport(e.top>=0&&e.top<=t),this.lowerBoundInViewport(e.bottom>=0&&e.bottom<=t),this.visiblePixels(e.height-i-s),this.visiblePercent(this.visiblePixels()/e.height*100),this}}export function isInViewport(e,t=!1){if(t=orDefault(t,!1,"bool"),!isInDom(e))return!1;const i=e.getBoundingClientRect(),s=window.innerWidth,r=window.innerHeight;let n;return n=t?{top:0,right:s,bottom:r,left:0}:{top:1-(i.bottom-i.top),right:s+(i.right-i.left)+1,bottom:r+(i.bottom-i.top)+1,left:1-(i.right-i.left)},i.top>=n.top&&i.right<=n.right&&i.left>=n.left&&i.bottom<=n.bottom}export function scrollTo(e,t=1e3,i=0,s="easeInOutCubic",r=!1,n=!1){const o="scrollTo";t=orDefault(t,1e3,"int"),i=orDefault(i,0,"int"),s=orDefault(s,"easeInOutCubic","str"),r=orDefault(r,!1,"bool"),n=orDefault(n,!1,"bool"),assert(isElement(e)||isWindow(e),`Viewport:${o} | element unusable`),assert(t>0,`Viewport:${o} | durationMs must be > 0`),s=isFunction(EasingFunctions[s])?EasingFunctions[s]:EasingFunctions.easeInOutCubic;const l=new Deferred,a=e.self===e,h=!a&&isInDom(e),u=!(a||!h)&&isInViewport(e,!0);if((h||a)&&(r||!u)){let r,o,h=!1;const u=window.scrollY??window.pageYOffset;o=a?i:u+getBoundingClientRect(e).top-round(window.innerHeight/2)+i;const d=o-u,c=function(e){if(!h){hasValue(r)||(r=e);const i=e-r,n=s(Math.min(i/t,1));window.scrollTo(0,u+d*n),ithis.#N.scrollTop?this.#N.scrollDirection="down":sthis.#x+10?(this.#N.fuzzyScrollDirection="down",this.#x=s):s{if(hasValue(e.rootBounds)){const t=this.#_.get(e.target);hasValue(t)&&(t.inViewport(e.intersectionRatio>0),t.fullyInViewport(e.intersectionRatio>=1),t.upperBoundInViewport(e.boundingClientRect.top>=e.rootBounds.top&&e.boundingClientRect.top<=e.rootBounds.bottom),t.lowerBoundInViewport(e.boundingClientRect.bottom>=e.rootBounds.top&&e.boundingClientRect.bottom<=e.rootBounds.bottom),t.visiblePercent(100*e.intersectionRatio),t.visiblePixels(e.intersectionRect.height),t.calculateScrolled&&(t.scrolledPercent((e.boundingClientRect.top-e.rootBounds.height)/(-e.boundingClientRect.height-e.rootBounds.height)*100),t.fullyInViewport()?t.startAutoScrolledPercentUpdates(this.#A,this.#s):t.stopAutoScrolledPercentUpdates()),t.calculateDistance&&(t.inViewport()?(t.stopAutoDistanceUpdates(),t.distancePixels(0),t.distanceViewports(0)):t.startAutoDistanceUpdates(this.#A,4)),t.autoHandleTooLargeElements&&e.boundingClientRect.height>e.rootBounds.height&&(t.inViewport()?(t.startAutoTooLargeUpdates(this.#A,this.#s),t.calculateScrolled&&t.startAutoScrolledPercentUpdates(this.#A,this.#s,!1)):(t.stopAutoTooLargeUpdates(),t.calculateScrolled&&t.stopAutoScrolledPercentUpdates())))}})),this.#D||(this.#D=!0,this.#E("initialized")),this.#k("updated"),this}#E(e,t=null){return document.body.dispatchEvent(new CustomEvent(`${e}.${this.#n}`,{detail:t??{}})),fire(document.body,`${e}.${this.#n}`,t??{}),this}#K(){window.addEventListener("scroll",this.#R),window.addEventListener("resize",this.#y),this.#L=new MutationObserver(this.#M),this.#L.observe(document.body,{attributes:!0,childList:!0,subtree:!0});const e=round(1e3/this.#s),t=round(e/10);return this.#C=window.setInterval(this.#X.bind(this),t),this}#G(){return window.clearInterval(this.#C),window.removeEventListener("scroll",this.#R),window.removeEventListener("resize",this.#y),hasValue(this.#L)&&(this.#L.disconnect(),this.#L=null),this}}export{VisibilityObserver};class BreakpointObserver{#e="BreakpointObserver";#Z="handler must be function";#t;#ee;#te;#ie;#se;#y;constructor(e=null,t=4){hasValue(e)&&(assert(isFunction(e),`Viewport:${this.#e}.constructor | ${this.#Z}`),this.#t=e),this.#ee=(e,t)=>{Object.keys(this.#te).length>0&&this.#t?.(e,t)},t=minMax(1,orDefault(t,15,"int"),120);const i=round(1e3/t);this.#y=throttle(i,this.#j,!0,!0).bind(this),this.connect(e)}connect(e=null){return this.disconnect(),hasValue(e)&&(assert(isFunction(e),`Viewport:${this.#e}.connect | ${this.#Z}`),this.#t=e),this.#ie.subscribe(this.#ee),this.#ie.subscribe((e=>{this.#se.setValue(e)})),this.#K(),this}disconnect(){return this.#te={},this.#ie=new Observable,this.#se=new Observable,this.#G(),this}getBreakpoint(e){if(isNumber(e)){let t=null;for(const i in this.#te)if(e===this.#te[i]){t=i;break}return t}return this.#te[`${e}`]??null}getBreakpoints(){return{...this.#te}}getCurrentBreakpoint(){return this.#ie.getValue()}getCurrentBreakpointObservable(){return this.#se}observe(...e){const t=this.#re(e);return this.#te={...this.#te,...t},this.#ne(),this}unobserve(...e){const t=this.#re(e,!0);return Object.keys(t).forEach((e=>{delete this.#te[e]})),this.#ne(),this}#re(e,t=!1){const i="#parseBreakpointList",s="unusable breakpoint";let r={};return Array.from(e).forEach((e=>{if(isPlainObject(e)){for(const t in e)e[t]=parseInt(e[t],10),assert(!isNaN(e[t])&&e[t]>=0,`Viewport:${this.#e}.${i} | ${s} "${t}"`);r={...r,...e}}else if(isArray(e))if(2!==e.length||isPlainObject(e[0])||isArray(e[0])||isPlainObject(e[1])||isArray(e[1]))r={...r,...this.#re(e,t)};else{const t=`${e[0]}`;r[t]=parseInt(e[1],10),assert(!isNaN(r[t])&&r[t]>=0,`Viewport:${this.#e}.${i} | ${s} "${t}"`)}else t&&(r[`${e}`]=null)})),r}#ne(){const e=window.innerWidth,t=Object.entries(this.#te).sort(((e,t)=>e[1]===t[1]?0:e[1]>t[1]?1:-1));let i=null;return t.forEach((([t,s])=>{e>=s&&(i=t)})),this.#ie.setValue(i),this}#j(){return this.#ne(),this}#K(){return window.addEventListener("resize",this.#y),this}#G(){return window.removeEventListener("resize",this.#y),this}}export{BreakpointObserver}; //# sourceMappingURL=viewport.js.map diff --git a/dist/viewport.js.map b/dist/viewport.js.map index baaa63f0..17a9bd10 100644 --- a/dist/viewport.js.map +++ b/dist/viewport.js.map @@ -1 +1 @@ -{"version":3,"file":"viewport.js","names":["MODULE_NAME","hasValue","orDefault","isWindow","isPlainObject","isArray","isFunction","isElement","isBoolean","isNumber","Deferred","Observable","assert","min","minMax","round","isInDom","EasingFunctions","requestAnimationFrame","cancelAnimationFrame","throttle","defer","warn","fire","VISIBILITY_BASE_FPS","DISTANCE_BASE_FPS","BREAKPOINT_BASE_FPS","getBoundingClientRect","element","boundingClientRect","ex","window","DOMRect","top","right","bottom","left","width","height","SimplePollingObserver","__className__","handler","elements","targetFps","pollTimer","constructor","options","this","Set","connect","disconnect","fpsMs","throttledUpdate","Array","from","map","viewportWidth","innerWidth","viewportHeight","innerHeight","upperCut","Math","abs","lowerCut","visiblePixels","entry","target","rootBounds","intersectionRect","intersectionRatio","bind","step","clear","observe","add","unobserve","delete","VisibilityState","eventNameSpace","inViewport","fullyInViewport","upperBoundInViewport","lowerBoundInViewport","visiblePercent","calculateScrolled","scrolledPercent","autoScrolledUpdateObservable","autoScrolledUpdateSubscription","calculateDistance","distancePixels","Number","POSITIVE_INFINITY","distanceViewports","autoDistanceUpdateObservable","autoDistanceUpdateSubscription","autoHandleTooLargeElements","autoHandleTooLargeUpdatesObservable","autoHandleTooLargeUpdatesSubscription","deferredChange","value","oldValue","triggerUpdateEvents","parseFloat","scrollHeight","startAutoScrolledPercentUpdates","viewportHashObservable","precisionUpdate","subscribe","calculatePreciseUpdate","stopAutoScrolledPercentUpdates","unsubscribe","startAutoDistanceUpdates","distancePxToTop","distancePxToBottom","distancePx","stopAutoDistanceUpdates","startAutoTooLargeUpdates","stopAutoTooLargeUpdates","toJson","info","triggerEvent","eventName","payload","dispatchEvent","CustomEvent","detail","triggerChanged","newValue","enterEventName","leaveEventName","isInViewport","mustBeFullyInside","bb","viewportBounds","scrollTo","durationMs","offset","easing","scrollEvenIfFullyInViewport","cancelOnUserScroll","__methodName__","easeInOutCubic","res","elementIsWindow","self","elementInDom","elementInViewport","start","targetY","cancelled","startY","scrollY","pageYOffset","diff","fScroll","timestamp","time","progress","resolve","fCancelScroll","reject","Error","removeEventListener","addEventListener","VisibilityObserver","htmlElementRequiredMessage","states","started","initialized","granularity","throttledHandleScroll","throttledHandleResize","throttledHandleMutation","throttledTriggerEvent","thresholds","observer","refreshPoll","documentMutationObserver","viewportInfo","viewportInfoReferenceScrollTop","viewportInfoHash","forcePollingObserver","Map","ObserverImplementation","handleScroll","handleResize","handleMutation","IntersectionObserver","buildThresholds","handleIntersections","threshold","refreshViewportInfo","registerEvents","unregisterEvents","startedSafeguard","set","has","getViewportInfo","getViewportObservable","getState","get","i","push","onlyScroll","newScrollTop","scrollTop","scrollDirection","fuzzyScrollDirection","bounds","getValue","setValue","handlePoll","entries","forEach","state","document","body","MutationObserver","attributes","childList","subtree","lazyFpsMs","setInterval","clearInterval","BreakpointObserver","handlerMustBeFunctionMessage","securedHandler","breakpoints","currentBreakpoint","currentBreakpointReadOnly","to","Object","keys","length","getBreakpoint","breakpoint","name","breakpointName","getBreakpoints","getCurrentBreakpoint","getCurrentBreakpointObservable","additionalBreakpoints","parseBreakpointList","refreshCurrentBreakpoint","obsoleteBreakpoints","obsoleteBreakpointName","list","acceptOnlyNames","unusableBreakpointMessage","parseInt","isNaN","sort","a","b","breakpointWidth"],"sources":["viewport.js"],"mappings":"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","sourcesContent":["/*!\n * Module Viewport\n */\n\n/**\n * @namespace Viewport\n */\n\nconst MODULE_NAME = 'Viewport';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {\n\thasValue,\n\torDefault,\n\tisWindow,\n\tisPlainObject,\n\tisArray,\n\tisFunction,\n\tisElement,\n\tisBoolean,\n\tisNumber,\n\tDeferred,\n\tObservable,\n\tassert,\n\tmin,\n\tminMax,\n\tround\n} from './basic.js';\nimport {isInDom} from './elements.js';\nimport {EasingFunctions} from './animation.js';\nimport {requestAnimationFrame, cancelAnimationFrame} from './timers.js';\nimport {throttle, defer} from './functions.js';\nimport {warn} from './logging.js';\nimport {fire} from './events.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst\n\tVISIBILITY_BASE_FPS = 15,\n\tDISTANCE_BASE_FPS = 4,\n\tBREAKPOINT_BASE_FPS = 4\n;\n\n\n\n//###[ HELPERS ]########################################################################################################\n\n/**\n * Returns the boundingClientRect of an HTML element. Falls back to zero-valued default rect if retrieval fails\n * (as in IE11 with an element, which is not in the DOM).\n *\n * @param {HTMLElement} element - the element of which we want to retrieve the bounding client rect\n * @returns {DOMRect} the element's bounding client rect\n *\n * @private\n */\nfunction getBoundingClientRect(element){\n\tlet boundingClientRect;\n\ttry {\n\t\tboundingClientRect = element.getBoundingClientRect();\n\t} catch(ex){\n\t\tboundingClientRect = !!window.DOMRect ?\n\t\t\tnew DOMRect(0, 0, 0, 0)\n\t\t\t: {top : 0, right : 0, bottom : 0, left : 0, width : 0, height : 0}\n\t\t;\n\t}\n\n\treturn boundingClientRect;\n}\n\n\n\n/**\n * A very simple polling-based implementation of the IntersectionObserver interface to replace a missing native\n * implementation for the VisibilityObserver. This is _not_ a polyfill, and it lacks a lot of implementation depth,\n * since it is tailored towards interoperability with VisibilityObserver.\n *\n * At its core, this implementation replaces real intersection events with stupid, brute-force, throttled polling\n * of all observed element's bounding boxes in respect to the viewport box.\n *\n * Be aware, that this is a very CPU/GPU intensive way of doing things and that using an IntersectionObserver is much\n * preferred. Only use this, if you have to support browsers like IE11 and you cannot leave out scroll animations there.\n * Also try to keep the number of observed elements to a minimum in that cases.\n *\n * @protected\n * @memberof Viewport\n * @name SimplePollingObserver\n *\n * @example\n * new SimplePollingObserver(entries => { ... , {targetFps : 60}});\n */\nclass SimplePollingObserver {\n\n\t#__className__ = 'SimplePollingObserver';\n\t#handler;\n\t#elements;\n\t#targetFps;\n\t#pollTimer;\n\n\t/**\n\t * Creates a new SimplePollingObserver, and starts observation.\n\t *\n\t * @param {Function} handler - the intersection handler function, that works with given entries\n\t * @param {Object} options - in IntersectionObserver, this would hold the threshold(s), which we do not need here, but, optionally, you may define the targetFps here, to define polling precision in detail\n\t */\n\tconstructor(handler, options){\n\t\tthis.#handler = handler;\n\t\tthis.#elements = new Set();\n\t\tthis.#targetFps = options?.targetFps ?? VISIBILITY_BASE_FPS;\n\n\t\tthis.connect();\n\t}\n\n\n\n\t/**\n\t * Starts polling elements and calls the intersection handler periodically with newly created entries.\n\t *\n\t * @returns {SimplePollingObserver} the observer instance\n\t *\n\t * @example\n\t * simplePollingObserver.connect();\n\t */\n\tconnect(){\n\t\tthis.disconnect();\n\n\t\tconst\n\t\t\tfpsMs = round(1000 / this.#targetFps),\n\t\t\tthrottledUpdate = throttle(fpsMs, () => {\n\t\t\t\tthis.#handler(Array.from(this.#elements).map(element => {\n\t\t\t\t\tconst\n\t\t\t\t\t\tboundingClientRect = getBoundingClientRect(element),\n\t\t\t\t\t\tviewportWidth = window.innerWidth,\n\t\t\t\t\t\tviewportHeight = window.innerHeight,\n\t\t\t\t\t\tupperCut = (boundingClientRect.top < 0) ? Math.abs(boundingClientRect.top) : 0,\n\t\t\t\t\t\tlowerCut = ((boundingClientRect.top + boundingClientRect.height) > viewportHeight)\n\t\t\t\t\t\t\t? (boundingClientRect.top + boundingClientRect.height) - viewportHeight\n\t\t\t\t\t\t\t: 0\n\t\t\t\t\t\t,\n\t\t\t\t\t\tvisiblePixels = minMax(\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\tboundingClientRect.height - upperCut - lowerCut,\n\t\t\t\t\t\t\tround(boundingClientRect.height)\n\t\t\t\t\t\t),\n\t\t\t\t\t\tentry = {\n\t\t\t\t\t\t\ttarget : element,\n\t\t\t\t\t\t\trootBounds : isInDom(element) ? {\n\t\t\t\t\t\t\t\ttop : 0,\n\t\t\t\t\t\t\t\tright : viewportWidth,\n\t\t\t\t\t\t\t\tbottom : viewportHeight,\n\t\t\t\t\t\t\t\tleft : 0,\n\t\t\t\t\t\t\t\twidth : viewportWidth,\n\t\t\t\t\t\t\t\theight : viewportHeight\n\t\t\t\t\t\t\t} : null,\n\t\t\t\t\t\t\tboundingClientRect : boundingClientRect,\n\t\t\t\t\t\t\tintersectionRect : {\n\t\t\t\t\t\t\t\theight : visiblePixels\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t;\n\n\t\t\t\t\tentry.intersectionRatio = visiblePixels / entry.boundingClientRect.height;\n\n\t\t\t\t\treturn entry;\n\t\t\t\t}));\n\t\t\t}).bind(this),\n\t\t\tstep = () => {\n\t\t\t\tthrottledUpdate();\n\t\t\t\tthis.#pollTimer = requestAnimationFrame(step);\n\t\t\t}\n\t\t;\n\n\t\tthis.#pollTimer = requestAnimationFrame(step);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops polling and removes all observed elements from the observer.\n\t *\n\t * @returns {SimplePollingObserver} the observer instance\n\t *\n\t * @example\n\t * simplePollingObserver.disconnect();\n\t */\n\tdisconnect(){\n\t\tcancelAnimationFrame(this.#pollTimer);\n\t\tthis.#pollTimer = null;\n\t\tthis.#elements.clear();\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Adds the element to the set of observed elements, for which entries are created, that are, in-term,\n\t * given to the intersection handler.\n\t *\n\t * @param {HTMLElement} element - the element to observe\n\t * @returns {SimplePollingObserver} the observer instance\n\t *\n\t * @example\n\t * simplePollingObserver.observe(teaserElement);\n\t */\n\tobserve(element){\n\t\tthis.#elements.add(element);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Removes the element from the set of observed elements.\n\t *\n\t * @param {HTMLElement} element - the element to unobserve\n\t * @returns {SimplePollingObserver} the observer instance\n\t *\n\t * @example\n\t * simplePollingObserver.unobserve(teaserElement);\n\t */\n\tunobserve(element){\n\t\tthis.#elements.delete(element);\n\n\t\treturn this;\n\t}\n\n}\n\n\n\n/**\n * A class to manage the visibility of an element in respect to the viewport.\n * A VisibilityState contains information such as if the element is currently (fully) inside the viewport and if so,\n * how many pixels are currently visible. There's a whole bunch of information to be found here, that aims to allow\n * for flexible usage in scenarios that require visibility-based effects.\n *\n * @protected\n * @memberof Viewport\n * @name VisibilityState\n * @example\n * (new VisibilityState(teaserElement, true)).visiblePixels(42);\n */\nclass VisibilityState {\n\n\t#__className__ = 'VisibilityState';\n\t#eventNameSpace = 'visibilitystate';\n\t#element;\n\t#inViewport = false;\n\t#fullyInViewport = false;\n\t#upperBoundInViewport = false;\n\t#lowerBoundInViewport = false;\n\t#visiblePercent = 0;\n\t#visiblePixels = 0;\n\tcalculateScrolled = false;\n\t#scrolledPercent = 0;\n\t#autoScrolledUpdateObservable = null;\n\t#autoScrolledUpdateSubscription = null;\n\tcalculateDistance = false;\n\t#distancePixels = Number.POSITIVE_INFINITY;\n\t#distanceViewports = Number.POSITIVE_INFINITY;\n\t#autoDistanceUpdateObservable = null;\n\t#autoDistanceUpdateSubscription = null;\n\tautoHandleTooLargeElements = true;\n\t#autoHandleTooLargeUpdatesObservable = null;\n\t#autoHandleTooLargeUpdatesSubscription = null;\n\t#deferredChange = null;\n\n\t/**\n\t * Creates a new VisibilityState object.\n\t *\n\t * @param {HTMLElement} element - the element being described by this state\n\t * @param {?Boolean} [calculateScrolled=false] - defines if the state should have scroll information, not available by default due to performance impact (such as scrolledPercent); scrolled information covers the question of how far the element has been scrolled through the viewport starting with the first pixel entering and ending with the last pixel leaving\n\t * @param {?Boolean} [calculateDistance=false] - defines if the state should have distance information, not available by default due to performance impact (such as distanceViewports); distance information covers the question of how far away an element currently is from the viewport\n\t * @param {?Boolean} [autoHandleTooLargeElements=true] - defines if element, which are larger/higher than the viewport, should be automatically handled, by adding additional means to update values without an interception taking place, because no edge is inside the viewport; this has a performance impact, but beware that setting this to false, will stop updates if no edge is inside the viewport\n\t */\n\tconstructor(element, calculateScrolled=false, calculateDistance=false, autoHandleTooLargeElements=true){\n\t\tthis.#element = element;\n\t\tthis.calculateScrolled = !!calculateScrolled;\n\t\tthis.calculateDistance = !!calculateDistance;\n\t\tthis.autoHandleTooLargeElements = !!autoHandleTooLargeElements;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the element currently being in the viewport or not.\n\t *\n\t * @param {?Boolean} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"enteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"leftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Boolean} true if element is currently in the viewport by any degree\n\t *\n\t * @example\n\t * state.inViewport()\n\t * => true/false\n\t * state.inViewport(true)\n\t * => true\n\t */\n\tinViewport(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#inViewport;\n\t\t\tthis.#inViewport = !!value;\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#inViewport,\n\t\t\t\t'enteredviewport', 'leftviewport'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#inViewport;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the element currently being _fully_ in the viewport or not.\n\t *\n\t * @param {?Boolean} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"fullyenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"fullyleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Boolean} true if element is currently in the viewport completely\n\t *\n\t * @example\n\t * state.fullyInViewport()\n\t * => true/false\n\t * state.fullyInViewport(true)\n\t * => true\n\t */\n\tfullyInViewport(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#fullyInViewport;\n\t\t\tthis.#fullyInViewport = !!value;\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#fullyInViewport,\n\t\t\t\t'fullyenteredviewport', 'fullyleftviewport'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#fullyInViewport;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the element's upper bound currently being in the viewport or not.\n\t *\n\t * @param {?Boolean} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"upperboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"upperboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Boolean} true if element's upper bound is currently in the viewport\n\t *\n\t * @example\n\t * state.upperBoundInViewport()\n\t * => true/false\n\t * state.upperBoundInViewport(true)\n\t * => true\n\t */\n\tupperBoundInViewport(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#upperBoundInViewport;\n\t\t\tthis.#upperBoundInViewport = !!value;\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#upperBoundInViewport,\n\t\t\t\t'upperboundenteredviewport', 'upperboundleftviewport'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#upperBoundInViewport;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the element's lower bound currently being in the viewport or not.\n\t *\n\t * @param {?Boolean} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"lowerboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Boolean} true if element's lower bound is currently in the viewport\n\t *\n\t * @example\n\t * state.lowerBoundInViewport()\n\t * => true/false\n\t * state.lowerBoundInViewport(true)\n\t * => true\n\t */\n\tlowerBoundInViewport(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#lowerBoundInViewport;\n\t\t\tthis.#lowerBoundInViewport = !!value;\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#lowerBoundInViewport,\n\t\t\t\t'lowerboundenteredviewport', 'lowerboundleftviewport'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#lowerBoundInViewport;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the percentage of the element currently being inside the viewport.\n\t *\n\t * @param {?Number} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"visiblepercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Number} the visible percentage between 0.00 and 100.00\n\t *\n\t * @example\n\t * state.visiblePercent()\n\t * => 0.00 ... 100.00\n\t * state.visiblePercent(66.6)\n\t * => 66.6\n\t */\n\tvisiblePercent(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#visiblePercent;\n\t\t\tthis.#visiblePercent = minMax(0, round(parseFloat(value), 2), 100);\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#visiblePercent,\n\t\t\t\t'visiblepercent'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#visiblePercent;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the number of vertical pixels of the element currently being inside the viewport.\n\t *\n\t * @param {?Number} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"visiblepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Number} the visible pixels between 0 and element height\n\t *\n\t * @example\n\t * state.visiblePixels()\n\t * => 0 ... element height\n\t * state.visiblePixels(66)\n\t * => 66\n\t */\n\tvisiblePixels(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#visiblePixels;\n\t\t\tthis.#visiblePixels = minMax(0, round(parseFloat(value)), round(this.#element.scrollHeight));\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#visiblePixels,\n\t\t\t\t'visiblepixels'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#visiblePixels;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the percentage the element has already been scrolled through the entirety of the\n\t * viewport, starting with the first pixel entering from below and ending with the last pixel leaving at the top.\n\t *\n\t * @param {?Number} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"scrolledpercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Number} the percentage scrolled between 0.00 and 100.00\n\t *\n\t * @example\n\t * state.scrolledPercent()\n\t * => 0.00 ... 100.00\n\t * state.scrolledPercent(66.6)\n\t * => 66.6\n\t */\n\tscrolledPercent(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#scrolledPercent;\n\t\t\tthis.#scrolledPercent = minMax(0, round(parseFloat(value), 2), 100);\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#scrolledPercent,\n\t\t\t\t'scrolledpercent'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#scrolledPercent;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the pixel distance of the element from the viewport, describing how long we still\n\t * need to scroll, until the first pixel hits the viewport bounds. This value may also be negative, if so, it\n\t * indicates distance from the top.\n\t *\n\t * @param {?Number} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"distancepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Number} the amount of pixels to scroll until the element hits the viewport bounds\n\t *\n\t * @example\n\t * state.distancePixels()\n\t * => -document height ... document height\n\t * state.distancePixels(66)\n\t * => 66\n\t */\n\tdistancePixels(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#distancePixels;\n\t\t\tthis.#distancePixels = round(parseFloat(value));\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#distancePixels,\n\t\t\t\t'distancepixels'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#distancePixels;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the distance of the element from the viewport, measured in viewport heights as a\n\t * floating point number, describing how long we still need to scroll, until the first pixel hits the viewport\n\t * bounds. This value may also be negative, if so, it indicates distance from the top.\n\t *\n\t * @param {?Number} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"distanceviewports.visibilitystate\" - {detail : viewportNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Number} the amount of viewports to scroll until the element hits the viewport bounds\n\t *\n\t * @example\n\t * state.distanceViewports()\n\t * => -document height in viewports ... document height in viewports\n\t * state.distanceViewports(6.6)\n\t * => 6.6\n\t */\n\tdistanceViewports(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#distanceViewports;\n\t\t\tthis.#distanceViewports = round(parseFloat(value), 2);\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#distanceViewports,\n\t\t\t\t'distanceviewports'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#distanceViewports;\n\t}\n\n\n\n\t/**\n\t * Starts the measurement of scrolledPercent for an element, which cannot be measured by just evaluating\n\t * interceptions (since we do not have any, if element is not intersecting a viewport edge).\n\t *\n\t * This is a feature, that should specifically be activated, since it is a CPU-intensive operation and should\n\t * only be used for elements, that really need this information.\n\t *\n\t * The range during which this updates should take place is: as long as the element is fully inside the viewport.\n\t *\n\t * @param {Basic.Observable} viewportHashObservable - observable, which changes on any change to the viewport, indicating that a new calculation is necessary\n\t * @param {Number} [targetFps=VISIBILITY_BASE_FPS] - the target amount of frames per second we are aiming for with these updates\n\t * @param {Boolean} [precisionUpdate=true] - since this operation is running a high-precision update to scrolledPercent anyway, we can also update the other properties as well, using the timer precision here, this is especially helpful for effects with positioning, that need razor-sharp in-sync information; set to false to save a few cpu-cycles\n\t * @fires CustomEvent#\"scrolledpercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"upperboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"upperboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"visiblepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"visiblepercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @see Basic.Observable\n\t * @example\n\t * state.startAutoScrolledPercentUpdates(new Observable('hash'), 30);\n\t */\n\tstartAutoScrolledPercentUpdates(viewportHashObservable, targetFps=VISIBILITY_BASE_FPS, precisionUpdate=true){\n\t\tif( this.calculateScrolled && !hasValue(this.#autoScrolledUpdateObservable) ){\n\t\t\tthis.#autoScrolledUpdateObservable = viewportHashObservable;\n\t\t\tconst fpsMs = round(1000 / targetFps);\n\t\t\tthis.#autoScrolledUpdateSubscription = this.#autoScrolledUpdateObservable.subscribe(throttle(fpsMs, () => {\n\t\t\t\tconst\n\t\t\t\t\tboundingClientRect = getBoundingClientRect(this.#element),\n\t\t\t\t\tviewportHeight = window.innerHeight\n\t\t\t\t;\n\n\t\t\t\tthis.scrolledPercent(\n\t\t\t\t\t(boundingClientRect.top - viewportHeight)\n\t\t\t\t\t/ (-boundingClientRect.height - viewportHeight) * 100\n\t\t\t\t);\n\n\t\t\t\tif( precisionUpdate ){\n\t\t\t\t\tthis.#calculatePreciseUpdate();\n\t\t\t\t}\n\t\t\t}));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops the measurement of scrolledPercent for an element.\n\t *\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @example\n\t * state.stopAutoScrolledPercentUpdates();\n\t */\n\tstopAutoScrolledPercentUpdates(){\n\t\tif( hasValue(this.#autoScrolledUpdateObservable) ){\n\t\t\tthis.#autoScrolledUpdateObservable.unsubscribe(this.#autoScrolledUpdateSubscription);\n\t\t}\n\n\t\tthis.#autoScrolledUpdateSubscription = null;\n\t\tthis.#autoScrolledUpdateObservable = null;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Starts the measurement of pixel and viewport distance for an element, which cannot be measured by just evaluating\n\t * interceptions (since we do not have any, if element is not intersecting a viewport edge, while off-screen).\n\t *\n\t * This is a feature, that should specifically be activated, since it is a CPU-intensive operation and should\n\t * only be used for elements, that really need this information.\n\t *\n\t * The range during which this updates should take place is: as long as the element is completely outside of the\n\t * viewport.\n\t *\n\t * @param {Basic.Observable} viewportHashObservable - observable, which changes on any change to the viewport, indicating that a new calculation is necessary\n\t * @param {Number} [targetFps=VISIBILITY_BASE_FPS] - the target amount of frames per second we are aiming for with these updates\n\t * @fires CustomEvent#\"distancepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"distancepercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @see Basic.Observable\n\t * @example\n\t * state.startAutoDistanceUpdates(new Observable('hash'), 30);\n\t */\n\tstartAutoDistanceUpdates(viewportHashObservable, targetFps=VISIBILITY_BASE_FPS){\n\t\tif( this.calculateDistance && !hasValue(this.#autoDistanceUpdateObservable) ){\n\t\t\tthis.#autoDistanceUpdateObservable = viewportHashObservable;\n\t\t\tconst fpsMs = round(1000 / targetFps);\n\t\t\tthis.#autoDistanceUpdateSubscription = this.#autoDistanceUpdateObservable.subscribe(throttle(fpsMs, () => {\n\t\t\t\tconst\n\t\t\t\t\tboundingClientRect = getBoundingClientRect(this.#element),\n\t\t\t\t\tviewportHeight = window.innerHeight,\n\t\t\t\t\tdistancePxToTop = boundingClientRect.top - viewportHeight,\n\t\t\t\t\tdistancePxToBottom = boundingClientRect.bottom,\n\t\t\t\t\tdistancePx = (Math.abs(distancePxToTop) < Math.abs(distancePxToBottom))\n\t\t\t\t\t\t? distancePxToTop\n\t\t\t\t\t\t: distancePxToBottom\n\t\t\t\t;\n\n\t\t\t\tthis.distancePixels(distancePx);\n\t\t\t\tthis.distanceViewports(distancePx / viewportHeight);\n\t\t\t}));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops the measurement of pixel and viewport distance for an element.\n\t *\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @example\n\t * state.stopAutoDistanceUpdates();\n\t */\n\tstopAutoDistanceUpdates(){\n\t\tif( hasValue(this.#autoDistanceUpdateObservable) ){\n\t\t\tthis.#autoDistanceUpdateObservable.unsubscribe(this.#autoDistanceUpdateSubscription);\n\t\t}\n\n\t\tthis.#autoDistanceUpdateSubscription = null;\n\t\tthis.#autoDistanceUpdateObservable = null;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Starts the measurement of properties for an element larger than the viewport itself, which are not measured,\n\t * if no intersection is taking place at the moment, because both element bounds are outside the viewport.\n\t * The is especially necessary, because very large elements also tend to need enormous amounts of thresholds to\n\t * precisely update values, which, at the end, quickly gets worse, then using a poll in that case. So, using this\n\t * feature keeps values precise and lets you define a reasonable granularity for all elements, no matter the size.\n\t *\n\t * This is a feature, that should specifically be activated, since it is a CPU-intensive operation and should\n\t * only be used for elements, that really need this information.\n\t *\n\t * The range during which this updates should take place is: the element is larger than the viewport height and\n\t * it is currently inside the viewport by any degree.\n\t *\n\t * @param {Basic.Observable} viewportHashObservable - observable, which changes on any change to the viewport, indicating that a new calculation is necessary\n\t * @param {Number} [targetFps=VISIBILITY_BASE_FPS] - the target amount of frames per second we are aiming for with these updates\n\t * @fires CustomEvent#\"upperboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"upperboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"visiblepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"visiblepercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @see Basic.Observable\n\t * @example\n\t * state.startAutoTooLargeUpdates(new Observable('hash'), 30);\n\t */\n\tstartAutoTooLargeUpdates(viewportHashObservable, targetFps=VISIBILITY_BASE_FPS){\n\t\tif( this.autoHandleTooLargeElements && !hasValue(this.#autoHandleTooLargeUpdatesObservable) ){\n\t\t\tthis.#autoHandleTooLargeUpdatesObservable = viewportHashObservable;\n\t\t\tconst fpsMs = round(1000 / targetFps);\n\t\t\tthis.#autoHandleTooLargeUpdatesSubscription = this.#autoHandleTooLargeUpdatesObservable.subscribe(throttle(fpsMs, () => {\n\t\t\t\tthis.#calculatePreciseUpdate();\n\t\t\t}));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops the measurement of properties for an element larger than the viewport itself, which are not measured,\n\t * if no intersection is taking place at the moment, because both element bounds are outside the viewport.\n\t *\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @example\n\t * state.stopAutoTooLargeUpdates();\n\t */\n\tstopAutoTooLargeUpdates(){\n\t\tif( hasValue(this.#autoHandleTooLargeUpdatesObservable) ){\n\t\t\tthis.#autoHandleTooLargeUpdatesObservable.unsubscribe(this.#autoHandleTooLargeUpdatesSubscription);\n\t\t}\n\n\t\tthis.#autoHandleTooLargeUpdatesSubscription = null;\n\t\tthis.#autoHandleTooLargeUpdatesObservable = null;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Returns a JSON snapshot of the element's current visibility state.\n\t *\n\t * @returns {Object} with active, inViewport, fullyInViewport, upperBoundInViewport, lowerBoundInViewport, visiblePercent, visiblePixels and (optionally) scrolledPercent, distancePixels and distanceViewports\n\t *\n\t * @example\n\t * state.toJson()\n\t * => {\n\t * active : true,\n\t * inViewport : true,\n\t * fullyInViewport : false,\n\t * upperBoundInViewport : true,\n\t * lowerBoundInViewport : false,\n\t * visiblePercent : 10.11,\n\t * visiblePixels : 42\n\t * }\n\t */\n\ttoJson(){\n\t\tconst info = {\n\t\t\tinViewport : this.inViewport(),\n\t\t\tfullyInViewport : this.fullyInViewport(),\n\t\t\tupperBoundInViewport : this.upperBoundInViewport(),\n\t\t\tlowerBoundInViewport : this.lowerBoundInViewport(),\n\t\t\tvisiblePercent : this.visiblePercent(),\n\t\t\tvisiblePixels : this.visiblePixels(),\n\t\t};\n\n\t\tif( this.calculateScrolled ){\n\t\t\tinfo.scrolledPercent = this.scrolledPercent()\n\t\t}\n\n\t\tif( this.calculateDistance ){\n\t\t\tinfo.distancePixels = this.distancePixels();\n\t\t\tinfo.distanceViewports = this.distanceViewports();\n\t\t}\n\n\t\treturn info;\n\t}\n\n\n\n\t/**\n\t * Triggers a named custom event of the state's element.\n\t * The primary reason for doing this, is to notify the DOM about visibility changes, that happened on the element.\n\t *\n\t * This method always constructs an eventname with a namespace attached after the event name, separated by a dot.\n\t * So, \"eventname.visibilitystate\" for example.\n\t *\n\t * @param {String} eventName - the name of the event\n\t * @param {?*} [payload=null] - payload to attach to the event's \"detail\" property\n\t * @fires CustomEvent#\"eventName.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @private\n\t * @example\n\t * this.#triggerEvent('foobar', {foo : 'bar'})\n\t * => CustomEvent('foobar.visibilitystate', {detail : {foo : 'bar'}})\n\t */\n\t#triggerEvent(eventName, payload=null){\n\t\tthis.#element.dispatchEvent(new CustomEvent(\n\t\t\t`${eventName}.${this.#eventNameSpace}`,\n\t\t\t{detail : payload ?? {}}\n\t\t));\n\n\t\tfire(\n\t\t\tthis.#element,\n\t\t\t`${eventName}.${this.#eventNameSpace}`,\n\t\t\tpayload ?? {}\n\t\t);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Triggers a general change event, notifying the dom about the fact, that something/anything has changed on\n\t * the element's visibility state.\n\t *\n\t * This event is triggered in a deferred way and not strictly synchronous to gather change events of several\n\t * changes in one event at the end of the change chain, the idea being, that changing five props only results in\n\t * one deferred change event. This means, that code, that relies on being executed synchronously at the exact moment\n\t * the change occurs, should use the precise property event instead.\n\t *\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @private\n\t * @example\n\t * this.#triggerChanged()\n\t * => CustomEvent('changed.visibilitystate')\n\t */\n\t#triggerChanged(){\n\t\tif( !hasValue(this.#deferredChange) ){\n\t\t\tthis.#deferredChange = defer(() => {\n\t\t\t\tthis.#deferredChange = null;\n\t\t\t\tthis.#triggerEvent('changed');\n\t\t\t});\n\t\t\tthis.#deferredChange();\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Triggers standardized update events for a property change.\n\t * Boolean values get specific enter and leave events, since they signify something starting and ending, while\n\t * numbers get a general change event.\n\t *\n\t * @param {Boolean|Number} oldValue - the old value, before the change\n\t * @param {Boolean|Number} newValue - the new value, after the change\n\t * @param {String} enterEventName - the event name for something starting/becoming true or the event name for number changes\n\t * @param {String} leaveEventName - the event name for something ending/becoming false; optional for number values\n\t * @fires CustomEvent#\"enterOrLeaveEventname.visibilitystate\"\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @private\n\t * @example\n\t * this.#triggerUpdateEvents(42, 66.6, 'propertyupdated');\n\t * this.#triggerUpdateEvents(true, false, 'somethingappeared', 'somethingdisappeared');\n\t */\n\t#triggerUpdateEvents(oldValue, newValue, enterEventName, leaveEventName){\n\t\tif( hasValue(newValue) ){\n\t\t\tif( isBoolean(newValue) ){\n\t\t\t\tif( newValue && !oldValue ){\n\t\t\t\t\tthis.#triggerEvent(enterEventName);\n\t\t\t\t\tthis.#triggerChanged();\n\t\t\t\t} else if( !newValue && oldValue ){\n\t\t\t\t\tthis.#triggerEvent(leaveEventName);\n\t\t\t\t\tthis.#triggerChanged();\n\t\t\t\t}\n\t\t\t} else if( isNumber(newValue) ){\n\t\t\t\tif( newValue !== oldValue ){\n\t\t\t\t\tthis.#triggerEvent(enterEventName ?? leaveEventName, newValue);\n\t\t\t\t\tthis.#triggerChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Calculates properties on-the-fly, which might not get updated precisely in certain scenarios, such as with\n\t * elements larger than the viewport itself.\n\t *\n\t * @fires CustomEvent#\"upperboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"upperboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"visiblepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"visiblepercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @private\n\t * @example\n\t * this.#calculatePreciseUpdate()\n\t */\n\t#calculatePreciseUpdate(){\n\t\tconst\n\t\t\tboundingClientRect = getBoundingClientRect(this.#element),\n\t\t\tviewportHeight = window.innerHeight,\n\t\t\tupperCut = (boundingClientRect.top < 0) ? Math.abs(boundingClientRect.top) : 0,\n\t\t\tlowerCut = ((boundingClientRect.top + boundingClientRect.height) > viewportHeight)\n\t\t\t\t? (boundingClientRect.top + boundingClientRect.height) - viewportHeight\n\t\t\t\t: 0\n\t\t;\n\n\t\tthis.upperBoundInViewport(\n\t\t\t(boundingClientRect.top >= 0)\n\t\t\t&& (boundingClientRect.top <= viewportHeight)\n\t\t);\n\n\t\tthis.lowerBoundInViewport(\n\t\t\t(boundingClientRect.bottom >= 0)\n\t\t\t&& (boundingClientRect.bottom <= viewportHeight)\n\t\t);\n\n\t\tthis.visiblePixels(boundingClientRect.height - upperCut - lowerCut);\n\n\t\tthis.visiblePercent((this.visiblePixels() / boundingClientRect.height) * 100);\n\n\t\treturn this;\n\t}\n\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Viewport:isInViewport\n */\n\n/**\n * Returns if the current element is visible in the window's viewport at the moment.\n *\n * @param {HTMLElement} element - the element to check\n * @param {?Boolean} [mustBeFullyInside=false] - defines if the element has to be fully enclosed in the viewport, default is false\n * @returns {Boolean} true if in viewport\n *\n * @memberof Viewport:isInViewport\n * @alias isInViewport\n * @example\n * if( isInViewport(document.querySelector('div.moving'), true) ){\n * ...\n * }\n */\nexport function isInViewport(element, mustBeFullyInside=false){\n\tmustBeFullyInside = orDefault(mustBeFullyInside, false, 'bool');\n\n\tif( !isInDom(element) ) return false;\n\n\tconst\n\t\tbb = element.getBoundingClientRect(),\n\t\tviewportWidth = window.innerWidth,\n\t\tviewportHeight = window.innerHeight\n\t;\n\n\tlet viewportBounds;\n\tif( mustBeFullyInside ){\n\t\tviewportBounds = {\n\t\t\ttop: 0,\n\t\t\tright : viewportWidth,\n\t\t\tbottom : viewportHeight,\n\t\t\tleft : 0\n\t\t};\n\t} else {\n\t\tviewportBounds = {\n\t\t\ttop : -(bb.bottom - bb.top) + 1,\n\t\t\tright : (viewportWidth + (bb.right - bb.left)) + 1,\n\t\t\tbottom : (viewportHeight + (bb.bottom - bb.top)) + 1,\n\t\t\tleft : -(bb.right - bb.left) + 1\n\t\t};\n\t}\n\n\treturn (\n\t\tbb.top >= viewportBounds.top &&\n\t\tbb.right <= viewportBounds.right &&\n\t\tbb.left >= viewportBounds.left &&\n\t\tbb.bottom <= viewportBounds.bottom\n\t);\n}\n\n\n\n/**\n * @namespace Viewport:scrollTo\n */\n\n/**\n * Scrolls the viewport to the element's position (first pixel at half viewport height).\n * Does not do anything if target element is already fully in viewport, unless scrollEvenIfFullyInViewport is set to\n * true. Uses getBoundingClientRect to measure viewport check, scrolls always if missing.\n *\n * If you use this function on a window, the offset is directly used as scrollTop, so this function may also be used for\n * things like back to top buttons.\n *\n * Scrolls may be cancelled by setting cancelOnUserScroll to true, but keep in mind, that this will only work\n * with mousewheels and (maybe) touchpads on modern browsers. No keyboard or scrollbar support yet.\n * The root of the problem is that a user scroll is indistinguishable from a js-triggered scroll,\n * since both trigger the scroll event and look exactly the same. So we have to use exotic\n * and specific events like mousewheel and DOMMouseScroll. So, please, use cancelOnUserScroll only\n * as a convenience option and not as a must.\n *\n * @param {HTMLElement|Window} element - the element to scroll to or the window to scroll within\n * @param {?Number} [durationMs=1000] - duration of the scrolling animation\n * @param {?Number} [offset=0] - offset from the viewport center to apply to the end position\n * @param {?String} [easing='easeInOutCubic'] - easing function to use, can be any of Animation.EasingFunctions\n * @param {?Boolean} [scrollEvenIfFullyInViewport=false] - if true, forces method to always scroll no matter the element's position\n * @param {?Boolean} [cancelOnUserScroll=false] - if true, scrolling animation will immediately be canceled on manual user scroll, return value will not resolve in that case\n * @throws error if element is not usable or if durationMs is <= 0\n * @returns {Basic.Deferred} resolves when scroll complete, rejects if scroll fails or is cancelled\n *\n * @memberof Viewport:scrollTo\n * @alias scrollTo\n * @see EasingFunctions\n * @example\n * document.querySelector('a.jumpitem').addEventListener('click', function(){ scrollTo(document.querySelector('.jumptarget'), function(){ alert('scrolled!'); }, 500, -100, true); });\n * scrollTo(document.querySelector('.jumptarget'), function(){ alert('Not triggered if user uses mousewheel.'); }, 5000, -0, false, true);\n * scrollTo(window, null, 500, 0, false, true);\n */\nexport function scrollTo(\n\telement,\n\tdurationMs=1000,\n\toffset=0,\n\teasing='easeInOutCubic',\n\tscrollEvenIfFullyInViewport=false,\n\tcancelOnUserScroll=false\n){\n\tconst __methodName__ = 'scrollTo';\n\n\tdurationMs = orDefault(durationMs, 1000, 'int');\n\toffset = orDefault(offset, 0, 'int');\n\teasing = orDefault(easing, 'easeInOutCubic', 'str');\n\tscrollEvenIfFullyInViewport = orDefault(scrollEvenIfFullyInViewport, false, 'bool');\n\tcancelOnUserScroll = orDefault(cancelOnUserScroll, false, 'bool');\n\n\tassert(isElement(element) || isWindow(element), `${MODULE_NAME}:${__methodName__} | element unusable`);\n\tassert(durationMs > 0, `${MODULE_NAME}:${__methodName__} | durationMs must be > 0`);\n\n\tif( !isFunction(EasingFunctions[easing]) ){\n\t\teasing = EasingFunctions.easeInOutCubic;\n\t} else {\n\t\teasing = EasingFunctions[easing];\n\t}\n\n\tconst\n\t\tres = new Deferred(),\n\t\telementIsWindow = (element.self === element),\n\t\telementInDom = !elementIsWindow && isInDom(element),\n\t\telementInViewport = (elementIsWindow || !elementInDom) ? false : isInViewport(element, true)\n\t;\n\n\tif( (elementInDom || elementIsWindow) && (scrollEvenIfFullyInViewport || !elementInViewport) ){\n\t\tlet start, targetY, cancelled = false;\n\t\tconst startY = window.scrollY ?? window.pageYOffset;\n\n\t\tif( elementIsWindow ){\n\t\t\ttargetY = offset;\n\t\t} else {\n\t\t\ttargetY = startY + getBoundingClientRect(element).top - round(window.innerHeight / 2) + offset;\n\t\t}\n\n\t\tconst\n\t\t\tdiff = targetY - startY,\n\t\t\tfScroll = function(timestamp){\n\t\t\t\tif( !cancelled ){\n\t\t\t\t\tif( !hasValue(start) ){\n\t\t\t\t\t\tstart = timestamp;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst\n\t\t\t\t\t\ttime = timestamp - start,\n\t\t\t\t\t\tprogress = easing(Math.min(time / durationMs, 1))\n\t\t\t\t\t;\n\n\t\t\t\t\twindow.scrollTo(0, startY + (diff * progress));\n\n\t\t\t\t\tif( (time < durationMs) && (progress < 1) ){\n\t\t\t\t\t\trequestAnimationFrame(fScroll)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tres.resolve();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t;\n\n\t\tif( cancelOnUserScroll ){\n\t\t\tconst fCancelScroll = function(){\n\t\t\t\tcancelled = true;\n\t\t\t\tres.reject(new Error('cancelled'));\n\t\t\t\twindow.removeEventListener('DOMMouseScroll', fCancelScroll);\n\t\t\t\twindow.removeEventListener('mousewheel', fCancelScroll);\n\t\t\t};\n\n\t\t\twindow.addEventListener('DOMMouseScroll', fCancelScroll);\n\t\t\twindow.addEventListener('mousewheel', fCancelScroll);\n\t\t}\n\n\t\tif( diff !== 0 ){\n\t\t\trequestAnimationFrame(fScroll);\n\t\t}\n\t}\n\n\treturn res;\n}\n\n\n\n/**\n * @namespace Viewport:VisibilityObserver\n */\n\n/**\n * @typedef ViewportInfo\n * @type Object\n *\n * @property {Number} scrollTop - scroll distance of the window/document in pixels to the upper bound of the viewport\n * @property {String} scrollDirection - either \"down\" or \"up\", depending on the last scroll movement\n * @property {String} fuzzyScrollDirection - either \"down\" or \"up\", depending on the last scroll movement; the user needs to scroll at least a small distance in the opposite direction for this to change, minimal changes will not change this\n * @property {Number} width - inner width of the window/viewport\n * @property {Number} height - inner height of the window/viewport\n * @property {Object} bounds - the viewport bound rectangle\n * @property {Number} bounds.top - upper bound of the viewport (typically 0)\n * @property {Number} bounds.right - right edge of the viewport (typically equals width)\n * @property {Number} bounds.bottom - bottom edge of the viewport (typically equals height)\n * @property {Number} bounds.left - left bound of the viewport (typically 0)\n * @property {Number} bounds.width - inner width of the window/viewport\n * @property {Number} bounds.height - inner height of the window/viewport\n *\n * @memberof Viewport\n */\n\n/**\n * A class offering extended visibility information about elements in regard to their positioning to the viewport\n * (bounds). An intersection observer is nice and concise, but if you want to build scroll-based effects or control\n * lazy loading a little bit more in detail, you are out of luck, since the intersection observer does not offer much\n * to help you in these cases.\n *\n * The VisibilityObserver offers tailor-fit information to build visibility-based effects, such as \"pixels visible\",\n * \"percent scrolled\" or \"distance in viewports\". Additionally, the VisibilityObserver handles edge-cases like\n * elements, which are bigger than the viewport itself, which results in intersections not being recognized is bounds\n * are not visible.\n *\n * This class aims to do the heavy lifting using an IntersectionObservers, to keep CPU usage down, but cover the edge\n * cases, if needed, with polling and precise calculations. Features, that are not achievable with intersections alone,\n * are very likely opt-in features.\n *\n * In case there is no native IntersectionObserver available, this implementation falls back to a SimplePollingObserver,\n * which replaces the IntersectionObserver and brute-forces the functionality with CPU-intensive polling. This should\n * be avoided if possible, but guarantees interoperability with older ES5 environments.\n *\n * This class roughly follows the interface defined by things like MutationObserver and IntersectionObserver.\n *\n * See class documentation below for details.\n *\n * @memberof Viewport:VisibilityObserver\n * @name VisibilityObserver\n *\n * @see VisibilityObserver\n * @see VisibilityState\n * @see SimplePollingObserver\n * @example\n * (new VisibilityObserver(100, 30))\n * .observe(element1, false, true)\n * .observe(element2, true, true)\n * .observe(element4, true, true)\n * .observe(element5)\n * .unobserve(element5)\n * ;\n * element1.addEventListener(\n * 'visiblepixels.visibilityobserver',\n * e => { console.log(`${e.detail} vertical pixels of element1 are visible`); }\n * );\n */\nclass VisibilityObserver {\n\n\t#__className__ = 'VisibilityObserver';\n\t#eventNameSpace = 'visibilityobserver';\n\t#htmlElementRequiredMessage = 'html element required';\n\t#states;\n\t#started = false;\n\t#initialized = false;\n\t#granularity;\n\t#targetFps;\n\t#throttledHandleScroll;\n\t#throttledHandleResize;\n\t#throttledHandleMutation;\n\t#throttledTriggerEvent;\n\t#thresholds;\n\t#observer;\n\t#refreshPoll;\n\t#documentMutationObserver;\n\t#viewportInfo;\n\t#viewportInfoReferenceScrollTop;\n\t#viewportInfoHash;\n\n\t/**\n\t * Creates a new VisibilityObserver and starts the observation of elements.\n\t *\n\t * @param {?Number} [granularity=10] - the number of intersection thresholds to use for each element (see IntersectionObserver threshold documentation) -> 2: just the outer bounds - 10: 10% steps - 100: one intersection every visible percent; make sure this number fits you needs and maybe think about using multiple observers with different granularities to cover different use cases\n\t * @param {?Number} [targetFps=VISIBILITY_BASE_FPS] - target frames per second to target with polls (be aware, that higher values put more stress on the CPU)\n\t * @param {?Boolean} [forcePollingObserver=false] - set this to true, if you want to skip usage of IntersectionObserver and, instead, just use polling all the time (this is a brute-force method putting stress on the CPU, only do this for a good reason)\n\t *\n\t * @see https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver\n\t */\n\tconstructor(granularity=10, targetFps=VISIBILITY_BASE_FPS, forcePollingObserver=false){\n\t\tthis.#states = new Map();\n\n\t\tthis.connect(granularity, targetFps, forcePollingObserver);\n\t}\n\n\n\n\t/**\n\t * Starts the observation of observed elements, which produces all visibility-related events.\n\t *\n\t * Be sure, that the observer is started before using any detail functions (these should be safe-guarded and warn\n\t * about the fact, that the observer is not connected).\n\t *\n\t * @param {?Number} [granularity=10] - the number of intersection thresholds to use for each element (see IntersectionObserver threshold documentation) -> 2: just the outer bounds - 10: 10% steps - 100: one intersection every visible percent; make sure this number fits you needs and maybe think about using multiple observers with different granularities to cover different use cases\n\t * @param {?Number} [targetFps=VISIBILITY_BASE_FPS] - target frames per second to target with polls (be aware, that higher values put more stress on the CPU)\n\t * @param {?Boolean} [forcePollingObserver=false] - set this to true, if you want to skip usage of IntersectionObserver and, instead, just use polling all the time (this is a brute-force method putting stress on the CPU, only do this for a good reason)\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @see disconnect\n\t * @example\n\t * visibilityObserver.connect(100, 50);\n\t */\n\tconnect(granularity=10, targetFps=VISIBILITY_BASE_FPS, forcePollingObserver=false){\n\t\tconst __methodName__ = 'connect';\n\n\t\tthis.disconnect();\n\n\t\tthis.#granularity = min(orDefault(granularity, 10, 'int'), 1);\n\t\tthis.#targetFps = minMax(1, orDefault(targetFps, VISIBILITY_BASE_FPS, 'int'), 120);\n\n\t\tconst fpsMs = round(1000 / targetFps);\n\t\tthis.#throttledHandleScroll = throttle(fpsMs, this.#handleScroll, true, true).bind(this);\n\t\tthis.#throttledHandleResize = throttle(fpsMs, this.#handleResize, true, true).bind(this);\n\t\tthis.#throttledHandleMutation = throttle(fpsMs, this.#handleMutation, true, true).bind(this);\n\t\tthis.#throttledTriggerEvent = throttle(fpsMs, this.#triggerEvent, true, true).bind(this);\n\n\t\tlet ObserverImplementation;\n\t\ttry {\n\t\t\tObserverImplementation = !forcePollingObserver ? IntersectionObserver : SimplePollingObserver;\n\t\t} catch(ex){\n\t\t\twarn(`${MODULE_NAME}:${this.#__className__}.${__methodName__} | IntersectionObserver not available, falling back to SimplePollingObserver`);\n\t\t\tObserverImplementation = SimplePollingObserver;\n\t\t}\n\n\t\tthis.#buildThresholds();\n\t\tthis.#observer = new ObserverImplementation(this.#handleIntersections.bind(this), {\n\t\t\tthreshold : this.#thresholds,\n\t\t\ttargetFps : this.#targetFps,\n\t\t});\n\n\t\tthis.#refreshViewportInfo();\n\t\tthis.#registerEvents();\n\n\t\tthis.#started = true;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops the observation of observed elements.\n\t *\n\t * Be sure to use this method before removing a VisibilityObserver to prevent trailing event registrations\n\t * and timers.\n\t *\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @see connect\n\t * @example\n\t * visibilityObserver.disconnect();\n\t */\n\tdisconnect(){\n\t\tthis.#unregisterEvents();\n\t\tif( hasValue(this.#observer) ){\n\t\t\tthis.#observer.disconnect();\n\t\t\tthis.#observer = null;\n\t\t}\n\t\tthis.#states.clear();\n\n\t\tthis.#started = false;\n\t\tthis.#initialized = false;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Adds an element to the set of observed elements.\n\t *\n\t * @param {HTMLElement} element - the element to observe\n\t * @param {?Boolean} [calculateScrolled=false] - defines if the element should be observed in terms of scrolled distance inside the viewport (which is not possible by watching intersections alone), setting this to true adds the property \"scrolledPercent\" to the visibility state\n\t * @param {?Boolean} [calculateDistance=false] - defines if the element should be observed in terms of distance from the viewport (which is not possible by watching intersections alone), setting this to true adds the properties \"distancePixels\" and \"distanceViewports\" to the visibility state\n\t * @param {?Boolean} [autoHandleTooLargeElements=true] - defines if elements, that are larger than the viewport should automatically be handled differently, to keep property updates consistent, if no element bounds are in the viewport (this is CPU-intensive, but normally something you'll expect, set this to false, if you are sure, that you do not need continuous updates during scrolling)\n\t * @throws error if element is not an HTML element\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @see unobserve\n\t * @example\n\t * visibilityObserver.observe(teaserElement);\n\t * visibilityObserver.observe(anotherTeaserElement, true, true);\n\t */\n\tobserve(element, calculateScrolled=false, calculateDistance=false, autoHandleTooLargeElements=true){\n\t\tif( this.#startedSafeguard() ){\n\t\t\tconst __methodName__ = 'addElement';\n\n\t\t\tassert(\n\t\t\t\tisElement(element),\n\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#htmlElementRequiredMessage}`\n\t\t\t);\n\n\t\t\tif( !isInDom(element) ){\n\t\t\t\twarn(`${MODULE_NAME}:${this.#__className__}.${__methodName__} | element not in DOM`);\n\t\t\t}\n\n\t\t\tthis.#states.set(element, new VisibilityState(\n\t\t\t\telement,\n\t\t\t\tcalculateScrolled,\n\t\t\t\tcalculateDistance,\n\t\t\t\tautoHandleTooLargeElements\n\t\t\t));\n\n\t\t\tthis.#observer.observe(element);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Removes an element from the set of observed elements.\n\t *\n\t * @param {HTMLElement} element - the element to unobserve\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @see observe\n\t * @example\n\t * visibilityObserver.unobserve(teaserElement);\n\t */\n\tunobserve(element){\n\t\tif( this.#states.has(element) ){\n\t\t\tthis.#states.delete(element);\n\t\t\tthis.#observer.unobserve(element);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Returns information about the current state of the viewport.\n\t *\n\t * This includes dimensions as well as scroll state.\n\t *\n\t * @returns {Viewport.ViewportInfo|null} the current viewport info or null if observer is not running\n\t *\n\t * @example\n\t * visibilityObserver.getViewportInfo().scrollTop;\n\t */\n\tgetViewportInfo(){\n\t\tif( this.#startedSafeguard() ){\n\t\t\treturn this.#viewportInfo;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\n\n\t/**\n\t * Returns an Observable, which changes on every update of the viewport.\n\t *\n\t * Subscribing to this value, allows you to programmatically react to every relevant viewport change.\n\t *\n\t * @returns {Basic.Observable|null} the observable or null if observer is not running\n\t *\n\t * @see Basic.Observable\n\t * @example\n\t * visibilityObserver.getViewportObservable().subscribe(() => { console.log(visibilityObserver.getViewportInfo().scrollTop); });\n\t */\n\tgetViewportObservable(){\n\t\tif( this.#startedSafeguard() ){\n\t\t\treturn this.#viewportInfoHash;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\n\n\t/**\n\t * Returns the current visibility state of an element.\n\t *\n\t * @param {HTMLElement} element - the element of which to retrieve the current visibility state\n\t * @returns {VisibilityState|null} the element's visibility state or null if observer is not running\n\t *\n\t * @example\n\t * if( visibilityObserver.getState(teaserElement).inViewport() ){ ... }\n\t */\n\tgetState(element){\n\t\tif( this.#startedSafeguard() ){\n\t\t\tif( this.#states.has(element) ){\n\t\t\t\treturn this.#states.get(element);\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\n\n\t/**\n\t * This is a guard method for public instance methods, which makes sure, that the observer is actually running,\n\t * automatically producing a warning, if this is not the case.\n\t *\n\t * @returns {Boolean} true if observer is running\n\t *\n\t * @private\n\t * @example\n\t * if( this.#startedSafeguard() ){ ... }\n\t */\n\t#startedSafeguard(){\n\t\tif( !this.#started ){\n\t\t\twarn(`${MODULE_NAME}:${this.#__className__}.${__methodName__} | not running, call connect() before`);\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\n\n\t/**\n\t * Builds InterceptionObserver thresholds based on the currently defined granularity, by dividing the range between\n\t * 0.0 and 1.0 into n + 1 equally distanced values.\n\t *\n\t * E.g.: granularity=10 -> 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0\n\t *\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#buildThresholds();\n\t */\n\t#buildThresholds(){\n\t\tconst thresholds = [];\n\n\t\tfor( let i = 0.0; i <= this.#granularity; i++ ){\n\t\t\tthresholds.push(round(i / this.#granularity, 2));\n\t\t}\n\n\t\tthis.#thresholds = thresholds;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Updates the viewport info object with the latest state, based on width, height and scrollTop.\n\t *\n\t * @param {?Boolean} [onlyScroll=false] - if true, only scrolling values are updated, which prevents some reflow-relevant calls; this is primarily used to connect \"scroll\" event to property updates, that might actually change\n\t * @fires CustomEvent#\"viewportchanged.visibilityobserver\"\n\t * @returns {Viewport.ViewportInfo} the updated viewport information\n\t *\n\t * @private\n\t * @example\n\t * this.#refreshViewportInfo(true);\n\t */\n\t#refreshViewportInfo(onlyScroll=false){\n\t\tconst\n\t\t\tviewportWidth = window.innerWidth,\n\t\t\tviewportHeight = window.innerHeight\n\t\t;\n\n\t\tif( !hasValue(this.#viewportInfo) ){\n\t\t\tthis.#viewportInfo = {\n\t\t\t\tscrollTop : window.scrollY ?? window.pageYOffset,\n\t\t\t\tscrollDirection : 'down',\n\t\t\t\tfuzzyScrollDirection : 'down',\n\t\t\t\twidth : viewportWidth,\n\t\t\t\theight : viewportHeight,\n\t\t\t\tbounds : {\n\t\t\t\t\ttop : 0,\n\t\t\t\t\tright : viewportWidth,\n\t\t\t\t\tbottom : viewportHeight,\n\t\t\t\t\tleft : 0,\n\t\t\t\t\twidth : viewportWidth,\n\t\t\t\t\theight : viewportHeight,\n\t\t\t\t}\n\t\t\t};\n\t\t\tthis.#viewportInfoReferenceScrollTop = this.#viewportInfo.scrollTop;\n\t\t\tthis.#viewportInfoHash = new Observable(\n\t\t\t\t`${this.#viewportInfo.scrollTop}${this.#viewportInfo.width}${this.#viewportInfo.height}`\n\t\t\t);\n\t\t} else {\n\t\t\tconst newScrollTop = window.scrollY ?? window.pageYOffset;\n\n\t\t\tif( newScrollTop > this.#viewportInfo.scrollTop ){\n\t\t\t\tthis.#viewportInfo.scrollDirection = 'down';\n\t\t\t} else if( newScrollTop < this.#viewportInfo.scrollTop ){\n\t\t\t\tthis.#viewportInfo.scrollDirection = 'up';\n\t\t\t}\n\n\t\t\tif( newScrollTop > (this.#viewportInfoReferenceScrollTop + 10) ){\n\t\t\t\tthis.#viewportInfo.fuzzyScrollDirection = 'down';\n\t\t\t\tthis.#viewportInfoReferenceScrollTop = newScrollTop;\n\t\t\t} else if( newScrollTop < (this.#viewportInfoReferenceScrollTop - 10) ){\n\t\t\t\tthis.#viewportInfo.fuzzyScrollDirection = 'up';\n\t\t\t\tthis.#viewportInfoReferenceScrollTop = newScrollTop;\n\t\t\t}\n\n\t\t\tthis.#viewportInfo.scrollTop = newScrollTop;\n\n\t\t\tif( !onlyScroll ){\n\t\t\t\tthis.#viewportInfo.width = viewportWidth;\n\t\t\t\tthis.#viewportInfo.height = viewportHeight;\n\t\t\t\tthis.#viewportInfo.bounds.right = viewportWidth;\n\t\t\t\tthis.#viewportInfo.bounds.bottom = viewportHeight;\n\t\t\t\tthis.#viewportInfo.bounds.width = viewportWidth;\n\t\t\t\tthis.#viewportInfo.bounds.height = viewportHeight;\n\t\t\t}\n\t\t}\n\n\t\tconst viewportInfoHash = `${this.#viewportInfo.scrollTop}${this.#viewportInfo.width}${this.#viewportInfo.height}`;\n\t\tif( viewportInfoHash !== this.#viewportInfoHash.getValue() ){\n\t\t\tthis.#viewportInfoHash.setValue(viewportInfoHash);\n\t\t\tthis.#throttledTriggerEvent('viewportchanged', this.#viewportInfo);\n\t\t}\n\n\t\treturn this.#viewportInfo;\n\t}\n\n\n\n\t/**\n\t * The event handler for scroll events, updating the viewport information.\n\t *\n\t * @fires CustomEvent#\"viewportchanged.visibilityobserver\"\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * window.addEventListener('scroll', this.#handleScroll);\n\t */\n\t#handleScroll(){\n\t\tthis.#refreshViewportInfo(true);\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * The event handler for resize events, updating the viewport information.\n\t *\n\t * @fires CustomEvent#\"viewportchanged.visibilityobserver\"\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * window.addEventListener('resize', this.#handleResize);\n\t */\n\t#handleResize(){\n\t\tthis.#refreshViewportInfo();\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * The event handler for document mutation events, updating the viewport information.\n\t *\n\t * @fires CustomEvent#\"viewportchanged.visibilityobserver\"\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * new MutationObserver(this.#handleMutation);\n\t */\n\t#handleMutation(){\n\t\tthis.#refreshViewportInfo();\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * The event handler for polling events, updating the viewport information.\n\t *\n\t * @fires CustomEvent#\"viewportchanged.visibilityobserver\"\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * const pollTimer = window.setInterval(this.#handlePoll, 100);\n\t */\n\t#handlePoll(){\n\t\tthis.#refreshViewportInfo();\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * The event handler for intersection events, updating VisibilityStates of all involved elements.\n\t *\n\t * This is the primary method for visibility logic, containing compilation, management and updates of\n\t * visibility information for all observed elements.\n\t *\n\t * @param {Array} entries - all elements with intersections currently happening\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @see https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver\n\t * @example\n\t * new IntersectionObserver(this.#handleIntersections);\n\t */\n\t#handleIntersections(entries){\n\t\tentries.forEach(entry => {\n\t\t\tif( hasValue(entry.rootBounds) ){\n\t\t\t\tconst state = this.#states.get(entry.target);\n\n\t\t\t\tstate.inViewport(entry.intersectionRatio > 0);\n\t\t\t\tstate.fullyInViewport(entry.intersectionRatio >= 1);\n\n\t\t\t\tstate.upperBoundInViewport(\n\t\t\t\t\t(entry.boundingClientRect.top >= entry.rootBounds.top)\n\t\t\t\t\t&& (entry.boundingClientRect.top <= entry.rootBounds.bottom)\n\t\t\t\t);\n\t\t\t\tstate.lowerBoundInViewport(\n\t\t\t\t\t(entry.boundingClientRect.bottom >= entry.rootBounds.top)\n\t\t\t\t\t&& (entry.boundingClientRect.bottom <= entry.rootBounds.bottom)\n\t\t\t\t);\n\n\t\t\t\tstate.visiblePercent(entry.intersectionRatio * 100);\n\t\t\t\tstate.visiblePixels(entry.intersectionRect.height);\n\n\t\t\t\tif( state.calculateScrolled ){\n\t\t\t\t\tstate.scrolledPercent(\n\t\t\t\t\t\t(entry.boundingClientRect.top - entry.rootBounds.height)\n\t\t\t\t\t\t/ (-entry.boundingClientRect.height - entry.rootBounds.height) * 100\n\t\t\t\t\t);\n\n\t\t\t\t\tif( state.fullyInViewport() ){\n\t\t\t\t\t\tstate.startAutoScrolledPercentUpdates(this.#viewportInfoHash, this.#targetFps);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate.stopAutoScrolledPercentUpdates();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif( state.calculateDistance ){\n\t\t\t\t\tif( !state.inViewport() ){\n\t\t\t\t\t\tstate.startAutoDistanceUpdates(this.#viewportInfoHash, DISTANCE_BASE_FPS);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate.stopAutoDistanceUpdates();\n\t\t\t\t\t\tstate.distancePixels(0);\n\t\t\t\t\t\tstate.distanceViewports(0);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(\n\t\t\t\t\tstate.autoHandleTooLargeElements\n\t\t\t\t\t&& (entry.boundingClientRect.height > entry.rootBounds.height)\n\t\t\t\t){\n\t\t\t\t\tif( state.inViewport() ){\n\t\t\t\t\t\tstate.startAutoTooLargeUpdates(this.#viewportInfoHash, this.#targetFps);\n\t\t\t\t\t\tif( state.calculateScrolled ){\n\t\t\t\t\t\t\tstate.startAutoScrolledPercentUpdates(this.#viewportInfoHash, this.#targetFps, false);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate.stopAutoTooLargeUpdates();\n\t\t\t\t\t\tif( state.calculateScrolled ){\n\t\t\t\t\t\t\tstate.stopAutoScrolledPercentUpdates();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tif( !this.#initialized ){\n\t\t\tthis.#initialized = true;\n\t\t\tthis.#triggerEvent('initialized');\n\t\t}\n\n\t\tthis.#throttledTriggerEvent('updated');\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Dispatches a custom event on document.body, signifying a global viewport/visibility event or update.\n\t *\n\t * Every event is automatically namespaced with a dotted postfix.\n\t *\n\t * @param {String} eventName - the name of the event\n\t * @param {?*} [payload=null] -\n\t * @fires CustomEvent#\"eventName.visibilityobserver\"\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#triggerEvent('foobar', {foo : 'bar'});\n\t */\n\t#triggerEvent(eventName, payload=null){\n\t\tdocument.body.dispatchEvent(new CustomEvent(\n\t\t\t`${eventName}.${this.#eventNameSpace}`,\n\t\t\t{detail : payload ?? {}}\n\t\t));\n\n\t\tfire(\n\t\t\tdocument.body,\n\t\t\t`${eventName}.${this.#eventNameSpace}`,\n\t\t\tpayload ?? {}\n\t\t);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Sets up all global events, which are necessary to track viewport updates.\n\t *\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#registerEvents();\n\t */\n\t#registerEvents(){\n\t\twindow.addEventListener('scroll', this.#throttledHandleScroll);\n\t\twindow.addEventListener('resize', this.#throttledHandleResize);\n\t\tthis.#documentMutationObserver = new MutationObserver(this.#throttledHandleMutation);\n\t\tthis.#documentMutationObserver.observe(document.body, {attributes : true, childList : true, subtree : true});\n\t\tconst\n\t\t\tfpsMs = round(1000 / this.#targetFps),\n\t\t\tlazyFpsMs = round(fpsMs / 10)\n\t\t;\n\t\tthis.#refreshPoll = window.setInterval(this.#handlePoll.bind(this), lazyFpsMs);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Removes all global events, which are necessary to track viewport updates.\n\t *\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#registerEvents();\n\t */\n\t#unregisterEvents(){\n\t\twindow.clearInterval(this.#refreshPoll);\n\t\twindow.removeEventListener('scroll', this.#throttledHandleScroll);\n\t\twindow.removeEventListener('resize', this.#throttledHandleResize);\n\t\tif( hasValue(this.#documentMutationObserver) ){\n\t\t\tthis.#documentMutationObserver.disconnect();\n\t\t\tthis.#documentMutationObserver = null;\n\t\t}\n\n\t\treturn this;\n\t}\n\n}\n\nexport {VisibilityObserver};\n\n\n\n/**\n * @namespace Viewport:BreakpointObserver\n */\n\n/**\n * A class observing a defined list of breakpoints, notifying subscribers, if the breakpoint changes for whatever\n * reason (viewport resizes or device orientation changes mostly).\n *\n * See class documentation below for details.\n *\n * @memberof Viewport:BreakpointObserver\n * @name BreakpointObserver\n *\n * @see BreakpointObserver\n * @example\n * (new BreakpointObserver((to, from) => {\n * alert(`breakpoint changed from \"${from}\" to \"${to}\"`);\n * })).observe({\n * small : 0,\n * medium : 768,\n * large : 1024,\n * xlarge : 1440\n * });\n * (new BreakpointObserver())\n * .observe(\n * {small : 0},\n * ['medium', 768],\n * [\n * {large : 1024},\n * ['xlarge', 1440]\n * ]\n * )\n * .unobserve('xlarge')\n * .getCurrentBreakpoint()\n * ;\n * => 'medium'\n */\nclass BreakpointObserver {\n\n\t#__className__ = 'BreakpointObserver';\n\t#handlerMustBeFunctionMessage = 'handler must be function';\n\t#handler;\n\t#securedHandler;\n\t#breakpoints;\n\t#currentBreakpoint;\n\t#currentBreakpointReadOnly;\n\t#throttledHandleResize;\n\n\t/**\n\t * Creates a new BreakpointObserver and, optionally, sets a handler for breakpoint changes.\n\t *\n\t * @param {?Function} [handler=null] - the function to call on breakpoint change, receives two parameters: newBreakpointName, oldBreakpointName (if there is no old breakpoint, the parameter will be undefined)\n\t * @param {?Number} [targetFps=BREAKPOINT_BASE_FPS] - the max amount of updates per second we are aiming for in the observer; since breakpoints are not changing very regularly, low FPS should be alright here for most cases\n\t * @throws error if handler is set, but is not a function\n\t */\n\tconstructor(handler=null, targetFps=BREAKPOINT_BASE_FPS){\n\t\tconst __methodName__ = 'constructor';\n\n\t\tif( hasValue(handler) ){\n\t\t\tassert(isFunction(handler), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#handlerMustBeFunctionMessage}`);\n\t\t\tthis.#handler = handler;\n\t\t}\n\n\t\tthis.#securedHandler = (to, from) => {\n\t\t\tif( Object.keys(this.#breakpoints).length > 0 ){\n\t\t\t\tthis.#handler?.(to, from);\n\t\t\t}\n\t\t};\n\n\t\ttargetFps = minMax(1, orDefault(targetFps, VISIBILITY_BASE_FPS, 'int'), 120);\n\t\tconst fpsMs = round(1000 / targetFps);\n\t\tthis.#throttledHandleResize = throttle(fpsMs, this.#handleResize, true, true).bind(this);\n\n\t\tthis.connect(handler);\n\t}\n\n\n\n\t/**\n\t * (Re)starts breakpoint observation (resetting all data and states before) and, optionally, sets a new handler.\n\t *\n\t * @param {?Function} [handler=null] - the function to call on breakpoint change, receives two parameters: newBreakpointName, oldBreakpointName (if there is no old breakpoint, the parameter will be undefined)\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @see disconnect\n\t * @example\n\t * observer\n\t * .connect((to, from) => {\n\t * alert(`breakpoint changed from \"${from}\" to \"${to}\"`);\n\t * })\n\t * .observe(\n\t * ['small', 0],\n\t * ['medium', 768],\n\t * ['large', 1024]\n\t * )\n\t * ;\n\t */\n\tconnect(handler=null){\n\t\tconst __methodName__ = 'connect';\n\n\t\tthis.disconnect();\n\n\t\tif( hasValue(handler) ){\n\t\t\tassert(isFunction(handler), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#handlerMustBeFunctionMessage}`);\n\t\t\tthis.#handler = handler;\n\t\t}\n\n\t\tthis.#currentBreakpoint.subscribe(this.#securedHandler);\n\t\tthis.#currentBreakpoint.subscribe(to => { this.#currentBreakpointReadOnly.setValue(to); });\n\n\t\tthis.#registerEvents();\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops the observation of breakpoints and resets all data and states.\n\t *\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @see connect\n\t * @example\n\t * observer.disconnect().getCurrentBreakpoint();\n\t * => null\n\t */\n\tdisconnect(){\n\t\tthis.#breakpoints = {};\n\t\tthis.#currentBreakpoint = new Observable();\n\t\tthis.#currentBreakpointReadOnly = new Observable();\n\n\t\tthis.#unregisterEvents();\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Returns either the width to a breakpoint name or the name to a breakpoint width.\n\t *\n\t * @param {String|Number} breakpoint - if a number, tries to return a corresponding breakpoint name, else we'll try to find a width to the given name\n\t * @returns {String|Number|null} - either a breakpoint name, a breakpoint width or null, if nothing was found\n\t *\n\t * @example\n\t * observer.getBreakpoint('large')\n\t * => 1024\n\t * observer.getBreakpoint(1024)\n\t * => 'large'\n\t */\n\tgetBreakpoint(breakpoint){\n\t\tif( isNumber(breakpoint) ){\n\t\t\tlet name = null;\n\n\t\t\tfor( const breakpointName in this.#breakpoints ){\n\t\t\t\tif( breakpoint === this.#breakpoints[breakpointName] ){\n\t\t\t\t\tname = breakpointName;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn name;\n\t\t} else {\n\t\t\treturn this.#breakpoints[`${breakpoint}`] ?? null;\n\t\t}\n\t}\n\n\n\n\t/**\n\t * Returns the currently configured breakpoints of the observer as a dictionary.\n\t *\n\t * The return value is a copy, changing values or names in this value will not change the observer's data.\n\t *\n\t * @returns {Object} the observer's configured breakpoints\n\t */\n\tgetBreakpoints(){\n\t\treturn {...this.#breakpoints};\n\t}\n\n\n\n\t/**\n\t * Returns the current breakpoint's name.\n\t *\n\t * If you need the width, use this value in .getBreakpoint().\n\t *\n\t * @returns {String} the current breakpoint's name\n\t *\n\t * @see getBreakpoint\n\t */\n\tgetCurrentBreakpoint(){\n\t\treturn this.#currentBreakpoint.getValue();\n\t}\n\n\n\n\t/**\n\t * Returns an observable, that notifies subscribers of breakpoint changes.\n\t *\n\t * Use this, if you need more than one handler or want a little bit more flexibility.\n\t *\n\t * This observable is read-only, setting its values will not influence breakpoint evaluation in the observer.\n\t *\n\t * @returns {Basic.Observable} the breakpoint observable\n\t *\n\t * @example\n\t * observer.getCurrentBreakpointObservable().subscribe((to, from) => {\n\t * alert(`breakpoint changed from \"${from}\" to \"${to}\"`);\n\t * });\n\t */\n\tgetCurrentBreakpointObservable(){\n\t\treturn this.#currentBreakpointReadOnly;\n\t}\n\n\n\n\t/**\n\t * Adds breakpoint(s) to observe.\n\t *\n\t * @param {Object|Array|Array|Array} breakpoints - the breakpoint definition, either as a simple dictionary ({breakPointName : breakpointWidth, ...}) with 1 to n props, or as an entry array (['breakpointname', breakpointWidth]); both definitions can also be provided as a list of parameters or an array\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @see unobserve\n\t * @example\n\t * observer.observe({\n\t * small : 0,\n\t * medium : 768,\n\t * large : 1024,\n\t * xlarge : 1440\n\t * });\n\t * observer.observe(\n\t * {small : 0},\n\t * ['medium', 768],\n\t * [\n\t * {large : 1024},\n\t * ['xlarge', 1440]\n\t * ]\n\t * );\n\t */\n\tobserve(...breakpoints){\n\t\tconst additionalBreakpoints = this.#parseBreakpointList(breakpoints);\n\t\tthis.#breakpoints = {\n\t\t\t...this.#breakpoints,\n\t\t\t...additionalBreakpoints\n\t\t};\n\n\t\tthis.#refreshCurrentBreakpoint();\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Removes breakpoint(s) from observation.\n\t *\n\t * @param {Array|Object|Array|Array|Array} breakpoints - this can either be a definition, as used in observe() or just a list of breakpoint names to remove\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @see observe\n\t * @example\n\t * observer.unobserve('small', 'xlarge');\n\t * observer.unobserve(['small', 'xlarge']);\n\t * observer.unobserve({\n\t * small : 0,\n\t * xlarge : 1440\n\t * });\n\t */\n\tunobserve(...breakpoints){\n\t\tconst obsoleteBreakpoints = this.#parseBreakpointList(breakpoints, true);\n\t\tObject.keys(obsoleteBreakpoints).forEach(obsoleteBreakpointName => {\n\t\t\tdelete this.#breakpoints[obsoleteBreakpointName];\n\t\t});\n\n\t\tthis.#refreshCurrentBreakpoint();\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Takes an iterable list of breakpoint definitions and recursively parses this into a plain object of\n\t * key-value pairs, where keys are breakpoint names and values are breakpoint width integers.\n\t *\n\t * @param {Array|Array} list - the breakpoint definition lists, containing either a simple dictionaries ({breakPointName : breakpointWidth, ...}) with 1 to n props, or entry arrays (['breakpointname', breakpointWidth])\n\t * @param {Boolean} [acceptOnlyNames=false] - if true, will accept breakpoint names without widths and return these entries with a null width\n\t * @throws error if breakpoint width is not usable as an integer or width is negative\n\t * @returns {Object} dictionary of parsed breakpoints\n\t *\n\t * @private\n\t * @example\n\t * this.#parseBreakpointList([\n\t * {small : 0},\n\t * ['medium', 768],\n\t * [\n\t * {large : 1024},\n\t * ['xlarge', 1440]\n\t * ]\n\t * ])\n\t * => {\n\t * small : 0,\n\t * medium : 768,\n\t * large : 1024,\n\t * xlarge : 1440\n\t * }\n\t * this.#parseBreakpointList(['xlarge', {small : 0}, ['medium', ['large', 1024]]], true)\n\t * => {\n\t * xlarge : null,\n\t * small : 0,\n\t * medium : null,\n\t * large : 1024\n\t * }\n\t */\n\t#parseBreakpointList(list, acceptOnlyNames=false){\n\t\tconst\n\t\t\t__methodName__ = '#parseBreakpointList',\n\t\t\tunusableBreakpointMessage = 'unusable breakpoint'\n\t\t;\n\n\t\tlet breakpoints = {};\n\n\t\tArray.from(list).forEach(breakpoint => {\n\t\t\tif( isPlainObject(breakpoint) ){\n\t\t\t\tfor( const breakpointName in breakpoint ){\n\t\t\t\t\tbreakpoint[breakpointName] = parseInt(breakpoint[breakpointName], 10);\n\t\t\t\t\tassert(\n\t\t\t\t\t\t!isNaN(breakpoint[breakpointName]) && (breakpoint[breakpointName] >= 0),\n\t\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${unusableBreakpointMessage} \"${breakpointName}\"`\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tbreakpoints = {...breakpoints, ...breakpoint};\n\t\t\t} else if( isArray(breakpoint) ){\n\t\t\t\tif(\n\t\t\t\t\t(breakpoint.length === 2)\n\t\t\t\t\t&& !isPlainObject(breakpoint[0]) && !isArray(breakpoint[0])\n\t\t\t\t\t&& !isPlainObject(breakpoint[1]) && !isArray(breakpoint[1])\n\t\t\t\t){\n\t\t\t\t\tconst breakpointName = `${breakpoint[0]}`;\n\t\t\t\t\tbreakpoints[breakpointName] = parseInt(breakpoint[1], 10);\n\t\t\t\t\tassert(\n\t\t\t\t\t\t!isNaN(breakpoints[breakpointName]) && (breakpoints[breakpointName] >= 0),\n\t\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${unusableBreakpointMessage} \"${breakpointName}\"`\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tbreakpoints = {\n\t\t\t\t\t\t...breakpoints,\n\t\t\t\t\t\t...this.#parseBreakpointList(breakpoint, acceptOnlyNames)\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} else if( acceptOnlyNames ){\n\t\t\t\tbreakpoints[`${breakpoint}`] = null;\n\t\t\t}\n\t\t});\n\n\t\treturn breakpoints;\n\t}\n\n\n\n\t/**\n\t * Updates the current breakpoint value, based on the current breakpoint configuration in regard to the current\n\t * viewport width.\n\t *\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#refreshCurrentBreakpoint();\n\t */\n\t#refreshCurrentBreakpoint(){\n\t\tconst\n\t\t\tviewportWidth = window.innerWidth,\n\t\t\tbreakpoints = Object.entries(this.#breakpoints).sort((a, b) => {\n\t\t\t\treturn (a[1] === b[1])\n\t\t\t\t\t? 0\n\t\t\t\t\t: (\n\t\t\t\t\t\t(a[1] > b[1])\n\t\t\t\t\t\t? 1\n\t\t\t\t\t\t: -1\n\t\t\t\t\t)\n\t\t\t\t;\n\t\t\t})\n\t\t;\n\n\t\tlet currentBreakpoint = null;\n\t\tbreakpoints.forEach(([breakpointName, breakpointWidth]) => {\n\t\t\tif( viewportWidth >= breakpointWidth ){\n\t\t\t\tcurrentBreakpoint = breakpointName;\n\t\t\t}\n\t\t});\n\n\t\tthis.#currentBreakpoint.setValue(currentBreakpoint);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Event handler for resize events. Updates the current breakpoint if necessary.\n\t *\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * window.addEventListener('resize', this.#handleResize);\n\t */\n\t#handleResize(){\n\t\tthis.#refreshCurrentBreakpoint();\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Registers all (global) events, such as the resize event, that are needed for breakpoint observation.\n\t *\n\t * Be sure to unregister trailing handlers before destructing the observer, by using disconnect().\n\t *\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#registerEvents()\n\t */\n\t#registerEvents(){\n\t\twindow.addEventListener('resize', this.#throttledHandleResize);\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Unregisters all (global) events, such as the resize event, to prevent trailing event handlers after destruction.\n\t *\n\t * Be sure to unregister trailing handlers before destructing the observer, by using disconnect().\n\t *\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#unregisterEvents()\n\t */\n\t#unregisterEvents(){\n\t\twindow.removeEventListener('resize', this.#throttledHandleResize);\n\t\treturn this;\n\t}\n\n}\n\nexport {BreakpointObserver};\n"]} \ No newline at end of file +{"version":3,"file":"viewport.js","names":["MODULE_NAME","hasValue","orDefault","isWindow","isPlainObject","isArray","isFunction","isElement","isBoolean","isNumber","Deferred","Observable","assert","min","minMax","round","isInDom","EasingFunctions","requestAnimationFrame","cancelAnimationFrame","throttle","defer","warn","fire","VISIBILITY_BASE_FPS","DISTANCE_BASE_FPS","BREAKPOINT_BASE_FPS","getBoundingClientRect","element","boundingClientRect","ex","window","DOMRect","top","right","bottom","left","width","height","SimplePollingObserver","__className__","handler","elements","targetFps","pollTimer","constructor","options","this","Set","connect","disconnect","fpsMs","throttledUpdate","Array","from","map","viewportWidth","innerWidth","viewportHeight","innerHeight","upperCut","Math","abs","lowerCut","visiblePixels","entry","target","rootBounds","intersectionRect","intersectionRatio","bind","step","clear","observe","add","unobserve","delete","VisibilityState","eventNameSpace","inViewport","fullyInViewport","upperBoundInViewport","lowerBoundInViewport","visiblePercent","calculateScrolled","scrolledPercent","autoScrolledUpdateObservable","autoScrolledUpdateSubscription","calculateDistance","distancePixels","Number","POSITIVE_INFINITY","distanceViewports","autoDistanceUpdateObservable","autoDistanceUpdateSubscription","autoHandleTooLargeElements","autoHandleTooLargeUpdatesObservable","autoHandleTooLargeUpdatesSubscription","deferredChange","value","oldValue","triggerUpdateEvents","parseFloat","scrollHeight","startAutoScrolledPercentUpdates","viewportHashObservable","precisionUpdate","subscribe","calculatePreciseUpdate","stopAutoScrolledPercentUpdates","unsubscribe","startAutoDistanceUpdates","distancePxToTop","distancePxToBottom","distancePx","stopAutoDistanceUpdates","startAutoTooLargeUpdates","stopAutoTooLargeUpdates","toJson","info","triggerEvent","eventName","payload","dispatchEvent","CustomEvent","detail","triggerChanged","newValue","enterEventName","leaveEventName","isInViewport","mustBeFullyInside","bb","viewportBounds","scrollTo","durationMs","offset","easing","scrollEvenIfFullyInViewport","cancelOnUserScroll","__methodName__","easeInOutCubic","res","elementIsWindow","self","elementInDom","elementInViewport","start","targetY","cancelled","startY","scrollY","pageYOffset","diff","fScroll","timestamp","time","progress","resolve","fCancelScroll","reject","Error","removeEventListener","addEventListener","VisibilityObserver","htmlElementRequiredMessage","states","started","initialized","granularity","throttledHandleScroll","throttledHandleResize","throttledHandleMutation","throttledTriggerEvent","thresholds","observer","refreshPoll","documentMutationObserver","viewportInfo","viewportInfoReferenceScrollTop","viewportInfoHash","forcePollingObserver","Map","ObserverImplementation","handleScroll","handleResize","handleMutation","IntersectionObserver","buildThresholds","handleIntersections","threshold","refreshViewportInfo","registerEvents","unregisterEvents","startedSafeguard","set","has","getViewportInfo","getViewportObservable","getState","get","i","push","onlyScroll","newScrollTop","scrollTop","scrollDirection","fuzzyScrollDirection","bounds","getValue","setValue","handlePoll","entries","forEach","state","document","body","MutationObserver","attributes","childList","subtree","lazyFpsMs","setInterval","clearInterval","BreakpointObserver","handlerMustBeFunctionMessage","securedHandler","breakpoints","currentBreakpoint","currentBreakpointReadOnly","to","Object","keys","length","getBreakpoint","breakpoint","name","breakpointName","getBreakpoints","getCurrentBreakpoint","getCurrentBreakpointObservable","additionalBreakpoints","parseBreakpointList","refreshCurrentBreakpoint","obsoleteBreakpoints","obsoleteBreakpointName","list","acceptOnlyNames","unusableBreakpointMessage","parseInt","isNaN","sort","a","b","breakpointWidth"],"sources":["viewport.js"],"mappings":"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","ignoreList":[],"sourcesContent":["/*!\n * Module Viewport\n */\n\n/**\n * @namespace Viewport\n */\n\nconst MODULE_NAME = 'Viewport';\n\n\n\n//###[ IMPORTS ]########################################################################################################\n\nimport {\n\thasValue,\n\torDefault,\n\tisWindow,\n\tisPlainObject,\n\tisArray,\n\tisFunction,\n\tisElement,\n\tisBoolean,\n\tisNumber,\n\tDeferred,\n\tObservable,\n\tassert,\n\tmin,\n\tminMax,\n\tround\n} from './basic.js';\nimport {isInDom} from './elements.js';\nimport {EasingFunctions} from './animation.js';\nimport {requestAnimationFrame, cancelAnimationFrame} from './timers.js';\nimport {throttle, defer} from './functions.js';\nimport {warn} from './logging.js';\nimport {fire} from './events.js';\n\n\n\n//###[ DATA ]###########################################################################################################\n\nconst\n\tVISIBILITY_BASE_FPS = 15,\n\tDISTANCE_BASE_FPS = 4,\n\tBREAKPOINT_BASE_FPS = 4\n;\n\n\n\n//###[ HELPERS ]########################################################################################################\n\n/**\n * Returns the boundingClientRect of an HTML element. Falls back to zero-valued default rect if retrieval fails\n * (as in IE11 with an element, which is not in the DOM).\n *\n * @param {HTMLElement} element - the element of which we want to retrieve the bounding client rect\n * @returns {DOMRect} the element's bounding client rect\n *\n * @private\n */\nfunction getBoundingClientRect(element){\n\tlet boundingClientRect;\n\ttry {\n\t\tboundingClientRect = element.getBoundingClientRect();\n\t} catch(ex){\n\t\tboundingClientRect = !!window.DOMRect ?\n\t\t\tnew DOMRect(0, 0, 0, 0)\n\t\t\t: {top : 0, right : 0, bottom : 0, left : 0, width : 0, height : 0}\n\t\t;\n\t}\n\n\treturn boundingClientRect;\n}\n\n\n\n/**\n * A very simple polling-based implementation of the IntersectionObserver interface to replace a missing native\n * implementation for the VisibilityObserver. This is _not_ a polyfill, and it lacks a lot of implementation depth,\n * since it is tailored towards interoperability with VisibilityObserver.\n *\n * At its core, this implementation replaces real intersection events with stupid, brute-force, throttled polling\n * of all observed element's bounding boxes in respect to the viewport box.\n *\n * Be aware, that this is a very CPU/GPU intensive way of doing things and that using an IntersectionObserver is much\n * preferred. Only use this, if you have to support browsers like IE11 and you cannot leave out scroll animations there.\n * Also try to keep the number of observed elements to a minimum in that cases.\n *\n * @protected\n * @memberof Viewport\n * @name SimplePollingObserver\n *\n * @example\n * new SimplePollingObserver(entries => { ... , {targetFps : 60}});\n */\nclass SimplePollingObserver {\n\n\t#__className__ = 'SimplePollingObserver';\n\t#handler;\n\t#elements;\n\t#targetFps;\n\t#pollTimer;\n\n\t/**\n\t * Creates a new SimplePollingObserver, and starts observation.\n\t *\n\t * @param {Function} handler - the intersection handler function, that works with given entries\n\t * @param {Object} options - in IntersectionObserver, this would hold the threshold(s), which we do not need here, but, optionally, you may define the targetFps here, to define polling precision in detail\n\t */\n\tconstructor(handler, options){\n\t\tthis.#handler = handler;\n\t\tthis.#elements = new Set();\n\t\tthis.#targetFps = options?.targetFps ?? VISIBILITY_BASE_FPS;\n\n\t\tthis.connect();\n\t}\n\n\n\n\t/**\n\t * Starts polling elements and calls the intersection handler periodically with newly created entries.\n\t *\n\t * @returns {SimplePollingObserver} the observer instance\n\t *\n\t * @example\n\t * simplePollingObserver.connect();\n\t */\n\tconnect(){\n\t\tthis.disconnect();\n\n\t\tconst\n\t\t\tfpsMs = round(1000 / this.#targetFps),\n\t\t\tthrottledUpdate = throttle(fpsMs, () => {\n\t\t\t\tthis.#handler(Array.from(this.#elements).map(element => {\n\t\t\t\t\tconst\n\t\t\t\t\t\tboundingClientRect = getBoundingClientRect(element),\n\t\t\t\t\t\tviewportWidth = window.innerWidth,\n\t\t\t\t\t\tviewportHeight = window.innerHeight,\n\t\t\t\t\t\tupperCut = (boundingClientRect.top < 0) ? Math.abs(boundingClientRect.top) : 0,\n\t\t\t\t\t\tlowerCut = ((boundingClientRect.top + boundingClientRect.height) > viewportHeight)\n\t\t\t\t\t\t\t? (boundingClientRect.top + boundingClientRect.height) - viewportHeight\n\t\t\t\t\t\t\t: 0\n\t\t\t\t\t\t,\n\t\t\t\t\t\tvisiblePixels = minMax(\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\tboundingClientRect.height - upperCut - lowerCut,\n\t\t\t\t\t\t\tround(boundingClientRect.height)\n\t\t\t\t\t\t),\n\t\t\t\t\t\tentry = {\n\t\t\t\t\t\t\ttarget : element,\n\t\t\t\t\t\t\trootBounds : isInDom(element) ? {\n\t\t\t\t\t\t\t\ttop : 0,\n\t\t\t\t\t\t\t\tright : viewportWidth,\n\t\t\t\t\t\t\t\tbottom : viewportHeight,\n\t\t\t\t\t\t\t\tleft : 0,\n\t\t\t\t\t\t\t\twidth : viewportWidth,\n\t\t\t\t\t\t\t\theight : viewportHeight\n\t\t\t\t\t\t\t} : null,\n\t\t\t\t\t\t\tboundingClientRect : boundingClientRect,\n\t\t\t\t\t\t\tintersectionRect : {\n\t\t\t\t\t\t\t\theight : visiblePixels\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t;\n\n\t\t\t\t\tentry.intersectionRatio = visiblePixels / entry.boundingClientRect.height;\n\n\t\t\t\t\treturn entry;\n\t\t\t\t}));\n\t\t\t}).bind(this),\n\t\t\tstep = () => {\n\t\t\t\tthrottledUpdate();\n\t\t\t\tthis.#pollTimer = requestAnimationFrame(step);\n\t\t\t}\n\t\t;\n\n\t\tthis.#pollTimer = requestAnimationFrame(step);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops polling and removes all observed elements from the observer.\n\t *\n\t * @returns {SimplePollingObserver} the observer instance\n\t *\n\t * @example\n\t * simplePollingObserver.disconnect();\n\t */\n\tdisconnect(){\n\t\tcancelAnimationFrame(this.#pollTimer);\n\t\tthis.#pollTimer = null;\n\t\tthis.#elements.clear();\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Adds the element to the set of observed elements, for which entries are created, that are, in-term,\n\t * given to the intersection handler.\n\t *\n\t * @param {HTMLElement} element - the element to observe\n\t * @returns {SimplePollingObserver} the observer instance\n\t *\n\t * @example\n\t * simplePollingObserver.observe(teaserElement);\n\t */\n\tobserve(element){\n\t\tthis.#elements.add(element);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Removes the element from the set of observed elements.\n\t *\n\t * @param {HTMLElement} element - the element to unobserve\n\t * @returns {SimplePollingObserver} the observer instance\n\t *\n\t * @example\n\t * simplePollingObserver.unobserve(teaserElement);\n\t */\n\tunobserve(element){\n\t\tthis.#elements.delete(element);\n\n\t\treturn this;\n\t}\n\n}\n\n\n\n/**\n * A class to manage the visibility of an element in respect to the viewport.\n * A VisibilityState contains information such as if the element is currently (fully) inside the viewport and if so,\n * how many pixels are currently visible. There's a whole bunch of information to be found here, that aims to allow\n * for flexible usage in scenarios that require visibility-based effects.\n *\n * @protected\n * @memberof Viewport\n * @name VisibilityState\n * @example\n * (new VisibilityState(teaserElement, true)).visiblePixels(42);\n */\nclass VisibilityState {\n\n\t#__className__ = 'VisibilityState';\n\t#eventNameSpace = 'visibilitystate';\n\t#element;\n\t#inViewport = false;\n\t#fullyInViewport = false;\n\t#upperBoundInViewport = false;\n\t#lowerBoundInViewport = false;\n\t#visiblePercent = 0;\n\t#visiblePixels = 0;\n\tcalculateScrolled = false;\n\t#scrolledPercent = 0;\n\t#autoScrolledUpdateObservable = null;\n\t#autoScrolledUpdateSubscription = null;\n\tcalculateDistance = false;\n\t#distancePixels = Number.POSITIVE_INFINITY;\n\t#distanceViewports = Number.POSITIVE_INFINITY;\n\t#autoDistanceUpdateObservable = null;\n\t#autoDistanceUpdateSubscription = null;\n\tautoHandleTooLargeElements = true;\n\t#autoHandleTooLargeUpdatesObservable = null;\n\t#autoHandleTooLargeUpdatesSubscription = null;\n\t#deferredChange = null;\n\n\t/**\n\t * Creates a new VisibilityState object.\n\t *\n\t * @param {HTMLElement} element - the element being described by this state\n\t * @param {?Boolean} [calculateScrolled=false] - defines if the state should have scroll information, not available by default due to performance impact (such as scrolledPercent); scrolled information covers the question of how far the element has been scrolled through the viewport starting with the first pixel entering and ending with the last pixel leaving\n\t * @param {?Boolean} [calculateDistance=false] - defines if the state should have distance information, not available by default due to performance impact (such as distanceViewports); distance information covers the question of how far away an element currently is from the viewport\n\t * @param {?Boolean} [autoHandleTooLargeElements=true] - defines if element, which are larger/higher than the viewport, should be automatically handled, by adding additional means to update values without an interception taking place, because no edge is inside the viewport; this has a performance impact, but beware that setting this to false, will stop updates if no edge is inside the viewport\n\t */\n\tconstructor(element, calculateScrolled=false, calculateDistance=false, autoHandleTooLargeElements=true){\n\t\tthis.#element = element;\n\t\tthis.calculateScrolled = !!calculateScrolled;\n\t\tthis.calculateDistance = !!calculateDistance;\n\t\tthis.autoHandleTooLargeElements = !!autoHandleTooLargeElements;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the element currently being in the viewport or not.\n\t *\n\t * @param {?Boolean} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"enteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"leftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Boolean} true if element is currently in the viewport by any degree\n\t *\n\t * @example\n\t * state.inViewport()\n\t * => true/false\n\t * state.inViewport(true)\n\t * => true\n\t */\n\tinViewport(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#inViewport;\n\t\t\tthis.#inViewport = !!value;\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#inViewport,\n\t\t\t\t'enteredviewport', 'leftviewport'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#inViewport;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the element currently being _fully_ in the viewport or not.\n\t *\n\t * @param {?Boolean} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"fullyenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"fullyleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Boolean} true if element is currently in the viewport completely\n\t *\n\t * @example\n\t * state.fullyInViewport()\n\t * => true/false\n\t * state.fullyInViewport(true)\n\t * => true\n\t */\n\tfullyInViewport(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#fullyInViewport;\n\t\t\tthis.#fullyInViewport = !!value;\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#fullyInViewport,\n\t\t\t\t'fullyenteredviewport', 'fullyleftviewport'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#fullyInViewport;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the element's upper bound currently being in the viewport or not.\n\t *\n\t * @param {?Boolean} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"upperboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"upperboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Boolean} true if element's upper bound is currently in the viewport\n\t *\n\t * @example\n\t * state.upperBoundInViewport()\n\t * => true/false\n\t * state.upperBoundInViewport(true)\n\t * => true\n\t */\n\tupperBoundInViewport(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#upperBoundInViewport;\n\t\t\tthis.#upperBoundInViewport = !!value;\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#upperBoundInViewport,\n\t\t\t\t'upperboundenteredviewport', 'upperboundleftviewport'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#upperBoundInViewport;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the element's lower bound currently being in the viewport or not.\n\t *\n\t * @param {?Boolean} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"lowerboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Boolean} true if element's lower bound is currently in the viewport\n\t *\n\t * @example\n\t * state.lowerBoundInViewport()\n\t * => true/false\n\t * state.lowerBoundInViewport(true)\n\t * => true\n\t */\n\tlowerBoundInViewport(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#lowerBoundInViewport;\n\t\t\tthis.#lowerBoundInViewport = !!value;\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#lowerBoundInViewport,\n\t\t\t\t'lowerboundenteredviewport', 'lowerboundleftviewport'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#lowerBoundInViewport;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the percentage of the element currently being inside the viewport.\n\t *\n\t * @param {?Number} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"visiblepercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Number} the visible percentage between 0.00 and 100.00\n\t *\n\t * @example\n\t * state.visiblePercent()\n\t * => 0.00 ... 100.00\n\t * state.visiblePercent(66.6)\n\t * => 66.6\n\t */\n\tvisiblePercent(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#visiblePercent;\n\t\t\tthis.#visiblePercent = minMax(0, round(parseFloat(value), 2), 100);\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#visiblePercent,\n\t\t\t\t'visiblepercent'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#visiblePercent;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the number of vertical pixels of the element currently being inside the viewport.\n\t *\n\t * @param {?Number} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"visiblepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Number} the visible pixels between 0 and element height\n\t *\n\t * @example\n\t * state.visiblePixels()\n\t * => 0 ... element height\n\t * state.visiblePixels(66)\n\t * => 66\n\t */\n\tvisiblePixels(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#visiblePixels;\n\t\t\tthis.#visiblePixels = minMax(0, round(parseFloat(value)), round(this.#element.scrollHeight));\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#visiblePixels,\n\t\t\t\t'visiblepixels'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#visiblePixels;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the percentage the element has already been scrolled through the entirety of the\n\t * viewport, starting with the first pixel entering from below and ending with the last pixel leaving at the top.\n\t *\n\t * @param {?Number} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"scrolledpercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Number} the percentage scrolled between 0.00 and 100.00\n\t *\n\t * @example\n\t * state.scrolledPercent()\n\t * => 0.00 ... 100.00\n\t * state.scrolledPercent(66.6)\n\t * => 66.6\n\t */\n\tscrolledPercent(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#scrolledPercent;\n\t\t\tthis.#scrolledPercent = minMax(0, round(parseFloat(value), 2), 100);\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#scrolledPercent,\n\t\t\t\t'scrolledpercent'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#scrolledPercent;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the pixel distance of the element from the viewport, describing how long we still\n\t * need to scroll, until the first pixel hits the viewport bounds. This value may also be negative, if so, it\n\t * indicates distance from the top.\n\t *\n\t * @param {?Number} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"distancepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Number} the amount of pixels to scroll until the element hits the viewport bounds\n\t *\n\t * @example\n\t * state.distancePixels()\n\t * => -document height ... document height\n\t * state.distancePixels(66)\n\t * => 66\n\t */\n\tdistancePixels(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#distancePixels;\n\t\t\tthis.#distancePixels = round(parseFloat(value));\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#distancePixels,\n\t\t\t\t'distancepixels'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#distancePixels;\n\t}\n\n\n\n\t/**\n\t * Gets/sets information about the distance of the element from the viewport, measured in viewport heights as a\n\t * floating point number, describing how long we still need to scroll, until the first pixel hits the viewport\n\t * bounds. This value may also be negative, if so, it indicates distance from the top.\n\t *\n\t * @param {?Number} [value=null] - the value to set, if left out or nullish, the method will just return the current value\n\t * @fires CustomEvent#\"distanceviewports.visibilitystate\" - {detail : viewportNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {Number} the amount of viewports to scroll until the element hits the viewport bounds\n\t *\n\t * @example\n\t * state.distanceViewports()\n\t * => -document height in viewports ... document height in viewports\n\t * state.distanceViewports(6.6)\n\t * => 6.6\n\t */\n\tdistanceViewports(value=null){\n\t\tif( hasValue(value) ){\n\t\t\tconst oldValue = this.#distanceViewports;\n\t\t\tthis.#distanceViewports = round(parseFloat(value), 2);\n\t\t\tthis.#triggerUpdateEvents(\n\t\t\t\toldValue, this.#distanceViewports,\n\t\t\t\t'distanceviewports'\n\t\t\t);\n\t\t}\n\n\t\treturn this.#distanceViewports;\n\t}\n\n\n\n\t/**\n\t * Starts the measurement of scrolledPercent for an element, which cannot be measured by just evaluating\n\t * interceptions (since we do not have any, if element is not intersecting a viewport edge).\n\t *\n\t * This is a feature, that should specifically be activated, since it is a CPU-intensive operation and should\n\t * only be used for elements, that really need this information.\n\t *\n\t * The range during which this updates should take place is: as long as the element is fully inside the viewport.\n\t *\n\t * @param {Basic.Observable} viewportHashObservable - observable, which changes on any change to the viewport, indicating that a new calculation is necessary\n\t * @param {Number} [targetFps=VISIBILITY_BASE_FPS] - the target amount of frames per second we are aiming for with these updates\n\t * @param {Boolean} [precisionUpdate=true] - since this operation is running a high-precision update to scrolledPercent anyway, we can also update the other properties as well, using the timer precision here, this is especially helpful for effects with positioning, that need razor-sharp in-sync information; set to false to save a few cpu-cycles\n\t * @fires CustomEvent#\"scrolledpercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"upperboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"upperboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"visiblepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"visiblepercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @see Basic.Observable\n\t * @example\n\t * state.startAutoScrolledPercentUpdates(new Observable('hash'), 30);\n\t */\n\tstartAutoScrolledPercentUpdates(viewportHashObservable, targetFps=VISIBILITY_BASE_FPS, precisionUpdate=true){\n\t\tif( this.calculateScrolled && !hasValue(this.#autoScrolledUpdateObservable) ){\n\t\t\tthis.#autoScrolledUpdateObservable = viewportHashObservable;\n\t\t\tconst fpsMs = round(1000 / targetFps);\n\t\t\tthis.#autoScrolledUpdateSubscription = this.#autoScrolledUpdateObservable.subscribe(throttle(fpsMs, () => {\n\t\t\t\tconst\n\t\t\t\t\tboundingClientRect = getBoundingClientRect(this.#element),\n\t\t\t\t\tviewportHeight = window.innerHeight\n\t\t\t\t;\n\n\t\t\t\tthis.scrolledPercent(\n\t\t\t\t\t(boundingClientRect.top - viewportHeight)\n\t\t\t\t\t/ (-boundingClientRect.height - viewportHeight) * 100\n\t\t\t\t);\n\n\t\t\t\tif( precisionUpdate ){\n\t\t\t\t\tthis.#calculatePreciseUpdate();\n\t\t\t\t}\n\t\t\t}));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops the measurement of scrolledPercent for an element.\n\t *\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @example\n\t * state.stopAutoScrolledPercentUpdates();\n\t */\n\tstopAutoScrolledPercentUpdates(){\n\t\tif( hasValue(this.#autoScrolledUpdateObservable) ){\n\t\t\tthis.#autoScrolledUpdateObservable.unsubscribe(this.#autoScrolledUpdateSubscription);\n\t\t}\n\n\t\tthis.#autoScrolledUpdateSubscription = null;\n\t\tthis.#autoScrolledUpdateObservable = null;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Starts the measurement of pixel and viewport distance for an element, which cannot be measured by just evaluating\n\t * interceptions (since we do not have any, if element is not intersecting a viewport edge, while off-screen).\n\t *\n\t * This is a feature, that should specifically be activated, since it is a CPU-intensive operation and should\n\t * only be used for elements, that really need this information.\n\t *\n\t * The range during which this updates should take place is: as long as the element is completely outside of the\n\t * viewport.\n\t *\n\t * @param {Basic.Observable} viewportHashObservable - observable, which changes on any change to the viewport, indicating that a new calculation is necessary\n\t * @param {Number} [targetFps=VISIBILITY_BASE_FPS] - the target amount of frames per second we are aiming for with these updates\n\t * @fires CustomEvent#\"distancepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"distancepercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @see Basic.Observable\n\t * @example\n\t * state.startAutoDistanceUpdates(new Observable('hash'), 30);\n\t */\n\tstartAutoDistanceUpdates(viewportHashObservable, targetFps=VISIBILITY_BASE_FPS){\n\t\tif( this.calculateDistance && !hasValue(this.#autoDistanceUpdateObservable) ){\n\t\t\tthis.#autoDistanceUpdateObservable = viewportHashObservable;\n\t\t\tconst fpsMs = round(1000 / targetFps);\n\t\t\tthis.#autoDistanceUpdateSubscription = this.#autoDistanceUpdateObservable.subscribe(throttle(fpsMs, () => {\n\t\t\t\tconst\n\t\t\t\t\tboundingClientRect = getBoundingClientRect(this.#element),\n\t\t\t\t\tviewportHeight = window.innerHeight,\n\t\t\t\t\tdistancePxToTop = boundingClientRect.top - viewportHeight,\n\t\t\t\t\tdistancePxToBottom = boundingClientRect.bottom,\n\t\t\t\t\tdistancePx = (Math.abs(distancePxToTop) < Math.abs(distancePxToBottom))\n\t\t\t\t\t\t? distancePxToTop\n\t\t\t\t\t\t: distancePxToBottom\n\t\t\t\t;\n\n\t\t\t\tthis.distancePixels(distancePx);\n\t\t\t\tthis.distanceViewports(distancePx / viewportHeight);\n\t\t\t}));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops the measurement of pixel and viewport distance for an element.\n\t *\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @example\n\t * state.stopAutoDistanceUpdates();\n\t */\n\tstopAutoDistanceUpdates(){\n\t\tif( hasValue(this.#autoDistanceUpdateObservable) ){\n\t\t\tthis.#autoDistanceUpdateObservable.unsubscribe(this.#autoDistanceUpdateSubscription);\n\t\t}\n\n\t\tthis.#autoDistanceUpdateSubscription = null;\n\t\tthis.#autoDistanceUpdateObservable = null;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Starts the measurement of properties for an element larger than the viewport itself, which are not measured,\n\t * if no intersection is taking place at the moment, because both element bounds are outside the viewport.\n\t * The is especially necessary, because very large elements also tend to need enormous amounts of thresholds to\n\t * precisely update values, which, at the end, quickly gets worse, then using a poll in that case. So, using this\n\t * feature keeps values precise and lets you define a reasonable granularity for all elements, no matter the size.\n\t *\n\t * This is a feature, that should specifically be activated, since it is a CPU-intensive operation and should\n\t * only be used for elements, that really need this information.\n\t *\n\t * The range during which this updates should take place is: the element is larger than the viewport height and\n\t * it is currently inside the viewport by any degree.\n\t *\n\t * @param {Basic.Observable} viewportHashObservable - observable, which changes on any change to the viewport, indicating that a new calculation is necessary\n\t * @param {Number} [targetFps=VISIBILITY_BASE_FPS] - the target amount of frames per second we are aiming for with these updates\n\t * @fires CustomEvent#\"upperboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"upperboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"visiblepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"visiblepercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @see Basic.Observable\n\t * @example\n\t * state.startAutoTooLargeUpdates(new Observable('hash'), 30);\n\t */\n\tstartAutoTooLargeUpdates(viewportHashObservable, targetFps=VISIBILITY_BASE_FPS){\n\t\tif( this.autoHandleTooLargeElements && !hasValue(this.#autoHandleTooLargeUpdatesObservable) ){\n\t\t\tthis.#autoHandleTooLargeUpdatesObservable = viewportHashObservable;\n\t\t\tconst fpsMs = round(1000 / targetFps);\n\t\t\tthis.#autoHandleTooLargeUpdatesSubscription = this.#autoHandleTooLargeUpdatesObservable.subscribe(throttle(fpsMs, () => {\n\t\t\t\tthis.#calculatePreciseUpdate();\n\t\t\t}));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops the measurement of properties for an element larger than the viewport itself, which are not measured,\n\t * if no intersection is taking place at the moment, because both element bounds are outside the viewport.\n\t *\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @example\n\t * state.stopAutoTooLargeUpdates();\n\t */\n\tstopAutoTooLargeUpdates(){\n\t\tif( hasValue(this.#autoHandleTooLargeUpdatesObservable) ){\n\t\t\tthis.#autoHandleTooLargeUpdatesObservable.unsubscribe(this.#autoHandleTooLargeUpdatesSubscription);\n\t\t}\n\n\t\tthis.#autoHandleTooLargeUpdatesSubscription = null;\n\t\tthis.#autoHandleTooLargeUpdatesObservable = null;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Returns a JSON snapshot of the element's current visibility state.\n\t *\n\t * @returns {Object} with active, inViewport, fullyInViewport, upperBoundInViewport, lowerBoundInViewport, visiblePercent, visiblePixels and (optionally) scrolledPercent, distancePixels and distanceViewports\n\t *\n\t * @example\n\t * state.toJson()\n\t * => {\n\t * active : true,\n\t * inViewport : true,\n\t * fullyInViewport : false,\n\t * upperBoundInViewport : true,\n\t * lowerBoundInViewport : false,\n\t * visiblePercent : 10.11,\n\t * visiblePixels : 42\n\t * }\n\t */\n\ttoJson(){\n\t\tconst info = {\n\t\t\tinViewport : this.inViewport(),\n\t\t\tfullyInViewport : this.fullyInViewport(),\n\t\t\tupperBoundInViewport : this.upperBoundInViewport(),\n\t\t\tlowerBoundInViewport : this.lowerBoundInViewport(),\n\t\t\tvisiblePercent : this.visiblePercent(),\n\t\t\tvisiblePixels : this.visiblePixels(),\n\t\t};\n\n\t\tif( this.calculateScrolled ){\n\t\t\tinfo.scrolledPercent = this.scrolledPercent()\n\t\t}\n\n\t\tif( this.calculateDistance ){\n\t\t\tinfo.distancePixels = this.distancePixels();\n\t\t\tinfo.distanceViewports = this.distanceViewports();\n\t\t}\n\n\t\treturn info;\n\t}\n\n\n\n\t/**\n\t * Triggers a named custom event of the state's element.\n\t * The primary reason for doing this, is to notify the DOM about visibility changes, that happened on the element.\n\t *\n\t * This method always constructs an eventname with a namespace attached after the event name, separated by a dot.\n\t * So, \"eventname.visibilitystate\" for example.\n\t *\n\t * @param {String} eventName - the name of the event\n\t * @param {?*} [payload=null] - payload to attach to the event's \"detail\" property\n\t * @fires CustomEvent#\"eventName.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @private\n\t * @example\n\t * this.#triggerEvent('foobar', {foo : 'bar'})\n\t * => CustomEvent('foobar.visibilitystate', {detail : {foo : 'bar'}})\n\t */\n\t#triggerEvent(eventName, payload=null){\n\t\tthis.#element.dispatchEvent(new CustomEvent(\n\t\t\t`${eventName}.${this.#eventNameSpace}`,\n\t\t\t{detail : payload ?? {}}\n\t\t));\n\n\t\tfire(\n\t\t\tthis.#element,\n\t\t\t`${eventName}.${this.#eventNameSpace}`,\n\t\t\tpayload ?? {}\n\t\t);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Triggers a general change event, notifying the dom about the fact, that something/anything has changed on\n\t * the element's visibility state.\n\t *\n\t * This event is triggered in a deferred way and not strictly synchronous to gather change events of several\n\t * changes in one event at the end of the change chain, the idea being, that changing five props only results in\n\t * one deferred change event. This means, that code, that relies on being executed synchronously at the exact moment\n\t * the change occurs, should use the precise property event instead.\n\t *\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @private\n\t * @example\n\t * this.#triggerChanged()\n\t * => CustomEvent('changed.visibilitystate')\n\t */\n\t#triggerChanged(){\n\t\tif( !hasValue(this.#deferredChange) ){\n\t\t\tthis.#deferredChange = defer(() => {\n\t\t\t\tthis.#deferredChange = null;\n\t\t\t\tthis.#triggerEvent('changed');\n\t\t\t});\n\t\t\tthis.#deferredChange();\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Triggers standardized update events for a property change.\n\t * Boolean values get specific enter and leave events, since they signify something starting and ending, while\n\t * numbers get a general change event.\n\t *\n\t * @param {Boolean|Number} oldValue - the old value, before the change\n\t * @param {Boolean|Number} newValue - the new value, after the change\n\t * @param {String} enterEventName - the event name for something starting/becoming true or the event name for number changes\n\t * @param {String} leaveEventName - the event name for something ending/becoming false; optional for number values\n\t * @fires CustomEvent#\"enterOrLeaveEventname.visibilitystate\"\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @private\n\t * @example\n\t * this.#triggerUpdateEvents(42, 66.6, 'propertyupdated');\n\t * this.#triggerUpdateEvents(true, false, 'somethingappeared', 'somethingdisappeared');\n\t */\n\t#triggerUpdateEvents(oldValue, newValue, enterEventName, leaveEventName){\n\t\tif( hasValue(newValue) ){\n\t\t\tif( isBoolean(newValue) ){\n\t\t\t\tif( newValue && !oldValue ){\n\t\t\t\t\tthis.#triggerEvent(enterEventName);\n\t\t\t\t\tthis.#triggerChanged();\n\t\t\t\t} else if( !newValue && oldValue ){\n\t\t\t\t\tthis.#triggerEvent(leaveEventName);\n\t\t\t\t\tthis.#triggerChanged();\n\t\t\t\t}\n\t\t\t} else if( isNumber(newValue) ){\n\t\t\t\tif( newValue !== oldValue ){\n\t\t\t\t\tthis.#triggerEvent(enterEventName ?? leaveEventName, newValue);\n\t\t\t\t\tthis.#triggerChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Calculates properties on-the-fly, which might not get updated precisely in certain scenarios, such as with\n\t * elements larger than the viewport itself.\n\t *\n\t * @fires CustomEvent#\"upperboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"upperboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundenteredviewport.visibilitystate\"\n\t * @fires CustomEvent#\"lowerboundleftviewport.visibilitystate\"\n\t * @fires CustomEvent#\"visiblepixels.visibilitystate\" - {detail : pixelNumber}\n\t * @fires CustomEvent#\"visiblepercent.visibilitystate\" - {detail : percentNumber}\n\t * @fires CustomEvent#\"changed.visibilitystate\"\n\t * @returns {VisibilityState} the current state\n\t *\n\t * @private\n\t * @example\n\t * this.#calculatePreciseUpdate()\n\t */\n\t#calculatePreciseUpdate(){\n\t\tconst\n\t\t\tboundingClientRect = getBoundingClientRect(this.#element),\n\t\t\tviewportHeight = window.innerHeight,\n\t\t\tupperCut = (boundingClientRect.top < 0) ? Math.abs(boundingClientRect.top) : 0,\n\t\t\tlowerCut = ((boundingClientRect.top + boundingClientRect.height) > viewportHeight)\n\t\t\t\t? (boundingClientRect.top + boundingClientRect.height) - viewportHeight\n\t\t\t\t: 0\n\t\t;\n\n\t\tthis.upperBoundInViewport(\n\t\t\t(boundingClientRect.top >= 0)\n\t\t\t&& (boundingClientRect.top <= viewportHeight)\n\t\t);\n\n\t\tthis.lowerBoundInViewport(\n\t\t\t(boundingClientRect.bottom >= 0)\n\t\t\t&& (boundingClientRect.bottom <= viewportHeight)\n\t\t);\n\n\t\tthis.visiblePixels(boundingClientRect.height - upperCut - lowerCut);\n\n\t\tthis.visiblePercent((this.visiblePixels() / boundingClientRect.height) * 100);\n\n\t\treturn this;\n\t}\n\n}\n\n\n\n//###[ EXPORTS ]########################################################################################################\n\n/**\n * @namespace Viewport:isInViewport\n */\n\n/**\n * Returns if the current element is visible in the window's viewport at the moment.\n *\n * @param {HTMLElement} element - the element to check\n * @param {?Boolean} [mustBeFullyInside=false] - defines if the element has to be fully enclosed in the viewport, default is false\n * @returns {Boolean} true if in viewport\n *\n * @memberof Viewport:isInViewport\n * @alias isInViewport\n * @example\n * if( isInViewport(document.querySelector('div.moving'), true) ){\n * ...\n * }\n */\nexport function isInViewport(element, mustBeFullyInside=false){\n\tmustBeFullyInside = orDefault(mustBeFullyInside, false, 'bool');\n\n\tif( !isInDom(element) ) return false;\n\n\tconst\n\t\tbb = element.getBoundingClientRect(),\n\t\tviewportWidth = window.innerWidth,\n\t\tviewportHeight = window.innerHeight\n\t;\n\n\tlet viewportBounds;\n\tif( mustBeFullyInside ){\n\t\tviewportBounds = {\n\t\t\ttop: 0,\n\t\t\tright : viewportWidth,\n\t\t\tbottom : viewportHeight,\n\t\t\tleft : 0\n\t\t};\n\t} else {\n\t\tviewportBounds = {\n\t\t\ttop : -(bb.bottom - bb.top) + 1,\n\t\t\tright : (viewportWidth + (bb.right - bb.left)) + 1,\n\t\t\tbottom : (viewportHeight + (bb.bottom - bb.top)) + 1,\n\t\t\tleft : -(bb.right - bb.left) + 1\n\t\t};\n\t}\n\n\treturn (\n\t\tbb.top >= viewportBounds.top &&\n\t\tbb.right <= viewportBounds.right &&\n\t\tbb.left >= viewportBounds.left &&\n\t\tbb.bottom <= viewportBounds.bottom\n\t);\n}\n\n\n\n/**\n * @namespace Viewport:scrollTo\n */\n\n/**\n * Scrolls the viewport to the element's position (first pixel at half viewport height).\n * Does not do anything if target element is already fully in viewport, unless scrollEvenIfFullyInViewport is set to\n * true. Uses getBoundingClientRect to measure viewport check, scrolls always if missing.\n *\n * If you use this function on a window, the offset is directly used as scrollTop, so this function may also be used for\n * things like back to top buttons.\n *\n * Scrolls may be cancelled by setting cancelOnUserScroll to true, but keep in mind, that this will only work\n * with mousewheels and (maybe) touchpads on modern browsers. No keyboard or scrollbar support yet.\n * The root of the problem is that a user scroll is indistinguishable from a js-triggered scroll,\n * since both trigger the scroll event and look exactly the same. So we have to use exotic\n * and specific events like mousewheel and DOMMouseScroll. So, please, use cancelOnUserScroll only\n * as a convenience option and not as a must.\n *\n * @param {HTMLElement|Window} element - the element to scroll to or the window to scroll within\n * @param {?Number} [durationMs=1000] - duration of the scrolling animation\n * @param {?Number} [offset=0] - offset from the viewport center to apply to the end position\n * @param {?String} [easing='easeInOutCubic'] - easing function to use, can be any of Animation.EasingFunctions\n * @param {?Boolean} [scrollEvenIfFullyInViewport=false] - if true, forces method to always scroll no matter the element's position\n * @param {?Boolean} [cancelOnUserScroll=false] - if true, scrolling animation will immediately be canceled on manual user scroll, return value will not resolve in that case\n * @throws error if element is not usable or if durationMs is <= 0\n * @returns {Basic.Deferred} resolves when scroll complete, rejects if scroll fails or is cancelled\n *\n * @memberof Viewport:scrollTo\n * @alias scrollTo\n * @see EasingFunctions\n * @example\n * document.querySelector('a.jumpitem').addEventListener('click', function(){ scrollTo(document.querySelector('.jumptarget'), function(){ alert('scrolled!'); }, 500, -100, true); });\n * scrollTo(document.querySelector('.jumptarget'), function(){ alert('Not triggered if user uses mousewheel.'); }, 5000, -0, false, true);\n * scrollTo(window, null, 500, 0, false, true);\n */\nexport function scrollTo(\n\telement,\n\tdurationMs=1000,\n\toffset=0,\n\teasing='easeInOutCubic',\n\tscrollEvenIfFullyInViewport=false,\n\tcancelOnUserScroll=false\n){\n\tconst __methodName__ = 'scrollTo';\n\n\tdurationMs = orDefault(durationMs, 1000, 'int');\n\toffset = orDefault(offset, 0, 'int');\n\teasing = orDefault(easing, 'easeInOutCubic', 'str');\n\tscrollEvenIfFullyInViewport = orDefault(scrollEvenIfFullyInViewport, false, 'bool');\n\tcancelOnUserScroll = orDefault(cancelOnUserScroll, false, 'bool');\n\n\tassert(isElement(element) || isWindow(element), `${MODULE_NAME}:${__methodName__} | element unusable`);\n\tassert(durationMs > 0, `${MODULE_NAME}:${__methodName__} | durationMs must be > 0`);\n\n\tif( !isFunction(EasingFunctions[easing]) ){\n\t\teasing = EasingFunctions.easeInOutCubic;\n\t} else {\n\t\teasing = EasingFunctions[easing];\n\t}\n\n\tconst\n\t\tres = new Deferred(),\n\t\telementIsWindow = (element.self === element),\n\t\telementInDom = !elementIsWindow && isInDom(element),\n\t\telementInViewport = (elementIsWindow || !elementInDom) ? false : isInViewport(element, true)\n\t;\n\n\tif( (elementInDom || elementIsWindow) && (scrollEvenIfFullyInViewport || !elementInViewport) ){\n\t\tlet start, targetY, cancelled = false;\n\t\tconst startY = window.scrollY ?? window.pageYOffset;\n\n\t\tif( elementIsWindow ){\n\t\t\ttargetY = offset;\n\t\t} else {\n\t\t\ttargetY = startY + getBoundingClientRect(element).top - round(window.innerHeight / 2) + offset;\n\t\t}\n\n\t\tconst\n\t\t\tdiff = targetY - startY,\n\t\t\tfScroll = function(timestamp){\n\t\t\t\tif( !cancelled ){\n\t\t\t\t\tif( !hasValue(start) ){\n\t\t\t\t\t\tstart = timestamp;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst\n\t\t\t\t\t\ttime = timestamp - start,\n\t\t\t\t\t\tprogress = easing(Math.min(time / durationMs, 1))\n\t\t\t\t\t;\n\n\t\t\t\t\twindow.scrollTo(0, startY + (diff * progress));\n\n\t\t\t\t\tif( (time < durationMs) && (progress < 1) ){\n\t\t\t\t\t\trequestAnimationFrame(fScroll)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tres.resolve();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t;\n\n\t\tif( cancelOnUserScroll ){\n\t\t\tconst fCancelScroll = function(){\n\t\t\t\tcancelled = true;\n\t\t\t\tres.reject(new Error('cancelled'));\n\t\t\t\twindow.removeEventListener('DOMMouseScroll', fCancelScroll);\n\t\t\t\twindow.removeEventListener('mousewheel', fCancelScroll);\n\t\t\t};\n\n\t\t\twindow.addEventListener('DOMMouseScroll', fCancelScroll);\n\t\t\twindow.addEventListener('mousewheel', fCancelScroll);\n\t\t}\n\n\t\tif( diff !== 0 ){\n\t\t\trequestAnimationFrame(fScroll);\n\t\t}\n\t}\n\n\treturn res;\n}\n\n\n\n/**\n * @namespace Viewport:VisibilityObserver\n */\n\n/**\n * @typedef ViewportInfo\n * @type Object\n *\n * @property {Number} scrollTop - scroll distance of the window/document in pixels to the upper bound of the viewport\n * @property {String} scrollDirection - either \"down\" or \"up\", depending on the last scroll movement\n * @property {String} fuzzyScrollDirection - either \"down\" or \"up\", depending on the last scroll movement; the user needs to scroll at least a small distance in the opposite direction for this to change, minimal changes will not change this\n * @property {Number} width - inner width of the window/viewport\n * @property {Number} height - inner height of the window/viewport\n * @property {Object} bounds - the viewport bound rectangle\n * @property {Number} bounds.top - upper bound of the viewport (typically 0)\n * @property {Number} bounds.right - right edge of the viewport (typically equals width)\n * @property {Number} bounds.bottom - bottom edge of the viewport (typically equals height)\n * @property {Number} bounds.left - left bound of the viewport (typically 0)\n * @property {Number} bounds.width - inner width of the window/viewport\n * @property {Number} bounds.height - inner height of the window/viewport\n *\n * @memberof Viewport\n */\n\n/**\n * A class offering extended visibility information about elements in regard to their positioning to the viewport\n * (bounds). An intersection observer is nice and concise, but if you want to build scroll-based effects or control\n * lazy loading a little bit more in detail, you are out of luck, since the intersection observer does not offer much\n * to help you in these cases.\n *\n * The VisibilityObserver offers tailor-fit information to build visibility-based effects, such as \"pixels visible\",\n * \"percent scrolled\" or \"distance in viewports\". Additionally, the VisibilityObserver handles edge-cases like\n * elements, which are bigger than the viewport itself, which results in intersections not being recognized is bounds\n * are not visible.\n *\n * This class aims to do the heavy lifting using an IntersectionObservers, to keep CPU usage down, but cover the edge\n * cases, if needed, with polling and precise calculations. Features, that are not achievable with intersections alone,\n * are very likely opt-in features.\n *\n * In case there is no native IntersectionObserver available, this implementation falls back to a SimplePollingObserver,\n * which replaces the IntersectionObserver and brute-forces the functionality with CPU-intensive polling. This should\n * be avoided if possible, but guarantees interoperability with older ES5 environments.\n *\n * This class roughly follows the interface defined by things like MutationObserver and IntersectionObserver.\n *\n * See class documentation below for details.\n *\n * @memberof Viewport:VisibilityObserver\n * @name VisibilityObserver\n *\n * @see VisibilityObserver\n * @see VisibilityState\n * @see SimplePollingObserver\n * @example\n * (new VisibilityObserver(100, 30))\n * .observe(element1, false, true)\n * .observe(element2, true, true)\n * .observe(element4, true, true)\n * .observe(element5)\n * .unobserve(element5)\n * ;\n * element1.addEventListener(\n * 'visiblepixels.visibilityobserver',\n * e => { console.log(`${e.detail} vertical pixels of element1 are visible`); }\n * );\n */\nclass VisibilityObserver {\n\n\t#__className__ = 'VisibilityObserver';\n\t#eventNameSpace = 'visibilityobserver';\n\t#htmlElementRequiredMessage = 'html element required';\n\t#states;\n\t#started = false;\n\t#initialized = false;\n\t#granularity;\n\t#targetFps;\n\t#throttledHandleScroll;\n\t#throttledHandleResize;\n\t#throttledHandleMutation;\n\t#throttledTriggerEvent;\n\t#thresholds;\n\t#observer;\n\t#refreshPoll;\n\t#documentMutationObserver;\n\t#viewportInfo;\n\t#viewportInfoReferenceScrollTop;\n\t#viewportInfoHash;\n\n\t/**\n\t * Creates a new VisibilityObserver and starts the observation of elements.\n\t *\n\t * @param {?Number} [granularity=10] - the number of intersection thresholds to use for each element (see IntersectionObserver threshold documentation) -> 2: just the outer bounds - 10: 10% steps - 100: one intersection every visible percent; make sure this number fits you needs and maybe think about using multiple observers with different granularities to cover different use cases\n\t * @param {?Number} [targetFps=VISIBILITY_BASE_FPS] - target frames per second to target with polls (be aware, that higher values put more stress on the CPU)\n\t * @param {?Boolean} [forcePollingObserver=false] - set this to true, if you want to skip usage of IntersectionObserver and, instead, just use polling all the time (this is a brute-force method putting stress on the CPU, only do this for a good reason)\n\t *\n\t * @see https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver\n\t */\n\tconstructor(granularity=10, targetFps=VISIBILITY_BASE_FPS, forcePollingObserver=false){\n\t\tthis.#states = new Map();\n\n\t\tthis.connect(granularity, targetFps, forcePollingObserver);\n\t}\n\n\n\n\t/**\n\t * Starts the observation of observed elements, which produces all visibility-related events.\n\t *\n\t * Be sure, that the observer is started before using any detail functions (these should be safe-guarded and warn\n\t * about the fact, that the observer is not connected).\n\t *\n\t * @param {?Number} [granularity=10] - the number of intersection thresholds to use for each element (see IntersectionObserver threshold documentation) -> 2: just the outer bounds - 10: 10% steps - 100: one intersection every visible percent; make sure this number fits you needs and maybe think about using multiple observers with different granularities to cover different use cases\n\t * @param {?Number} [targetFps=VISIBILITY_BASE_FPS] - target frames per second to target with polls (be aware, that higher values put more stress on the CPU)\n\t * @param {?Boolean} [forcePollingObserver=false] - set this to true, if you want to skip usage of IntersectionObserver and, instead, just use polling all the time (this is a brute-force method putting stress on the CPU, only do this for a good reason)\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @see disconnect\n\t * @example\n\t * visibilityObserver.connect(100, 50);\n\t */\n\tconnect(granularity=10, targetFps=VISIBILITY_BASE_FPS, forcePollingObserver=false){\n\t\tconst __methodName__ = 'connect';\n\n\t\tthis.disconnect();\n\n\t\tthis.#granularity = min(orDefault(granularity, 10, 'int'), 1);\n\t\tthis.#targetFps = minMax(1, orDefault(targetFps, VISIBILITY_BASE_FPS, 'int'), 120);\n\n\t\tconst fpsMs = round(1000 / targetFps);\n\t\tthis.#throttledHandleScroll = throttle(fpsMs, this.#handleScroll, true, true).bind(this);\n\t\tthis.#throttledHandleResize = throttle(fpsMs, this.#handleResize, true, true).bind(this);\n\t\tthis.#throttledHandleMutation = throttle(fpsMs, this.#handleMutation, true, true).bind(this);\n\t\tthis.#throttledTriggerEvent = throttle(fpsMs, this.#triggerEvent, true, true).bind(this);\n\n\t\tlet ObserverImplementation;\n\t\ttry {\n\t\t\tObserverImplementation = !forcePollingObserver ? IntersectionObserver : SimplePollingObserver;\n\t\t} catch(ex){\n\t\t\twarn(`${MODULE_NAME}:${this.#__className__}.${__methodName__} | IntersectionObserver not available, falling back to SimplePollingObserver`);\n\t\t\tObserverImplementation = SimplePollingObserver;\n\t\t}\n\n\t\tthis.#buildThresholds();\n\t\tthis.#observer = new ObserverImplementation(this.#handleIntersections.bind(this), {\n\t\t\tthreshold : this.#thresholds,\n\t\t\ttargetFps : this.#targetFps,\n\t\t});\n\n\t\tthis.#refreshViewportInfo();\n\t\tthis.#registerEvents();\n\n\t\tthis.#started = true;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops the observation of observed elements.\n\t *\n\t * Be sure to use this method before removing a VisibilityObserver to prevent trailing event registrations\n\t * and timers.\n\t *\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @see connect\n\t * @example\n\t * visibilityObserver.disconnect();\n\t */\n\tdisconnect(){\n\t\tthis.#unregisterEvents();\n\t\tif( hasValue(this.#observer) ){\n\t\t\tthis.#observer.disconnect();\n\t\t\tthis.#observer = null;\n\t\t}\n\t\tthis.#states.clear();\n\n\t\tthis.#started = false;\n\t\tthis.#initialized = false;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Adds an element to the set of observed elements.\n\t *\n\t * @param {HTMLElement} element - the element to observe\n\t * @param {?Boolean} [calculateScrolled=false] - defines if the element should be observed in terms of scrolled distance inside the viewport (which is not possible by watching intersections alone), setting this to true adds the property \"scrolledPercent\" to the visibility state\n\t * @param {?Boolean} [calculateDistance=false] - defines if the element should be observed in terms of distance from the viewport (which is not possible by watching intersections alone), setting this to true adds the properties \"distancePixels\" and \"distanceViewports\" to the visibility state\n\t * @param {?Boolean} [autoHandleTooLargeElements=true] - defines if elements, that are larger than the viewport should automatically be handled differently, to keep property updates consistent, if no element bounds are in the viewport (this is CPU-intensive, but normally something you'll expect, set this to false, if you are sure, that you do not need continuous updates during scrolling)\n\t * @throws error if element is not an HTML element\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @see unobserve\n\t * @example\n\t * visibilityObserver.observe(teaserElement);\n\t * visibilityObserver.observe(anotherTeaserElement, true, true);\n\t */\n\tobserve(element, calculateScrolled=false, calculateDistance=false, autoHandleTooLargeElements=true){\n\t\tif( this.#startedSafeguard() ){\n\t\t\tconst __methodName__ = 'addElement';\n\n\t\t\tassert(\n\t\t\t\tisElement(element),\n\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#htmlElementRequiredMessage}`\n\t\t\t);\n\n\t\t\tif( !isInDom(element) ){\n\t\t\t\twarn(`${MODULE_NAME}:${this.#__className__}.${__methodName__} | element not in DOM`);\n\t\t\t}\n\n\t\t\tthis.#states.set(element, new VisibilityState(\n\t\t\t\telement,\n\t\t\t\tcalculateScrolled,\n\t\t\t\tcalculateDistance,\n\t\t\t\tautoHandleTooLargeElements\n\t\t\t));\n\n\t\t\tthis.#observer.observe(element);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Removes an element from the set of observed elements.\n\t *\n\t * @param {HTMLElement} element - the element to unobserve\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @see observe\n\t * @example\n\t * visibilityObserver.unobserve(teaserElement);\n\t */\n\tunobserve(element){\n\t\tif( this.#states.has(element) ){\n\t\t\tthis.#states.delete(element);\n\t\t\tthis.#observer.unobserve(element);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Returns information about the current state of the viewport.\n\t *\n\t * This includes dimensions as well as scroll state.\n\t *\n\t * @returns {Viewport.ViewportInfo|null} the current viewport info or null if observer is not running\n\t *\n\t * @example\n\t * visibilityObserver.getViewportInfo().scrollTop;\n\t */\n\tgetViewportInfo(){\n\t\tif( this.#startedSafeguard() ){\n\t\t\treturn this.#viewportInfo;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\n\n\t/**\n\t * Returns an Observable, which changes on every update of the viewport.\n\t *\n\t * Subscribing to this value, allows you to programmatically react to every relevant viewport change.\n\t *\n\t * @returns {Basic.Observable|null} the observable or null if observer is not running\n\t *\n\t * @see Basic.Observable\n\t * @example\n\t * visibilityObserver.getViewportObservable().subscribe(() => { console.log(visibilityObserver.getViewportInfo().scrollTop); });\n\t */\n\tgetViewportObservable(){\n\t\tif( this.#startedSafeguard() ){\n\t\t\treturn this.#viewportInfoHash;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\n\n\t/**\n\t * Returns the current visibility state of an element.\n\t *\n\t * @param {HTMLElement} element - the element of which to retrieve the current visibility state\n\t * @returns {VisibilityState|null} the element's visibility state or null if observer is not running\n\t *\n\t * @example\n\t * if( visibilityObserver.getState(teaserElement).inViewport() ){ ... }\n\t */\n\tgetState(element){\n\t\tif( this.#startedSafeguard() ){\n\t\t\tif( this.#states.has(element) ){\n\t\t\t\treturn this.#states.get(element);\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\n\n\t/**\n\t * This is a guard method for public instance methods, which makes sure, that the observer is actually running,\n\t * automatically producing a warning, if this is not the case.\n\t *\n\t * @returns {Boolean} true if observer is running\n\t *\n\t * @private\n\t * @example\n\t * if( this.#startedSafeguard() ){ ... }\n\t */\n\t#startedSafeguard(){\n\t\tif( !this.#started ){\n\t\t\twarn(`${MODULE_NAME}:${this.#__className__}.${__methodName__} | not running, call connect() before`);\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\n\n\t/**\n\t * Builds InterceptionObserver thresholds based on the currently defined granularity, by dividing the range between\n\t * 0.0 and 1.0 into n + 1 equally distanced values.\n\t *\n\t * E.g.: granularity=10 -> 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0\n\t *\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#buildThresholds();\n\t */\n\t#buildThresholds(){\n\t\tconst thresholds = [];\n\n\t\tfor( let i = 0.0; i <= this.#granularity; i++ ){\n\t\t\tthresholds.push(round(i / this.#granularity, 2));\n\t\t}\n\n\t\tthis.#thresholds = thresholds;\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Updates the viewport info object with the latest state, based on width, height and scrollTop.\n\t *\n\t * @param {?Boolean} [onlyScroll=false] - if true, only scrolling values are updated, which prevents some reflow-relevant calls; this is primarily used to connect \"scroll\" event to property updates, that might actually change\n\t * @fires CustomEvent#\"viewportchanged.visibilityobserver\"\n\t * @returns {Viewport.ViewportInfo} the updated viewport information\n\t *\n\t * @private\n\t * @example\n\t * this.#refreshViewportInfo(true);\n\t */\n\t#refreshViewportInfo(onlyScroll=false){\n\t\tconst\n\t\t\tviewportWidth = window.innerWidth,\n\t\t\tviewportHeight = window.innerHeight\n\t\t;\n\n\t\tif( !hasValue(this.#viewportInfo) ){\n\t\t\tthis.#viewportInfo = {\n\t\t\t\tscrollTop : window.scrollY ?? window.pageYOffset,\n\t\t\t\tscrollDirection : 'down',\n\t\t\t\tfuzzyScrollDirection : 'down',\n\t\t\t\twidth : viewportWidth,\n\t\t\t\theight : viewportHeight,\n\t\t\t\tbounds : {\n\t\t\t\t\ttop : 0,\n\t\t\t\t\tright : viewportWidth,\n\t\t\t\t\tbottom : viewportHeight,\n\t\t\t\t\tleft : 0,\n\t\t\t\t\twidth : viewportWidth,\n\t\t\t\t\theight : viewportHeight,\n\t\t\t\t}\n\t\t\t};\n\t\t\tthis.#viewportInfoReferenceScrollTop = this.#viewportInfo.scrollTop;\n\t\t\tthis.#viewportInfoHash = new Observable(\n\t\t\t\t`${this.#viewportInfo.scrollTop}${this.#viewportInfo.width}${this.#viewportInfo.height}`\n\t\t\t);\n\t\t} else {\n\t\t\tconst newScrollTop = window.scrollY ?? window.pageYOffset;\n\n\t\t\tif( newScrollTop > this.#viewportInfo.scrollTop ){\n\t\t\t\tthis.#viewportInfo.scrollDirection = 'down';\n\t\t\t} else if( newScrollTop < this.#viewportInfo.scrollTop ){\n\t\t\t\tthis.#viewportInfo.scrollDirection = 'up';\n\t\t\t}\n\n\t\t\tif( newScrollTop > (this.#viewportInfoReferenceScrollTop + 10) ){\n\t\t\t\tthis.#viewportInfo.fuzzyScrollDirection = 'down';\n\t\t\t\tthis.#viewportInfoReferenceScrollTop = newScrollTop;\n\t\t\t} else if( newScrollTop < (this.#viewportInfoReferenceScrollTop - 10) ){\n\t\t\t\tthis.#viewportInfo.fuzzyScrollDirection = 'up';\n\t\t\t\tthis.#viewportInfoReferenceScrollTop = newScrollTop;\n\t\t\t}\n\n\t\t\tthis.#viewportInfo.scrollTop = newScrollTop;\n\n\t\t\tif( !onlyScroll ){\n\t\t\t\tthis.#viewportInfo.width = viewportWidth;\n\t\t\t\tthis.#viewportInfo.height = viewportHeight;\n\t\t\t\tthis.#viewportInfo.bounds.right = viewportWidth;\n\t\t\t\tthis.#viewportInfo.bounds.bottom = viewportHeight;\n\t\t\t\tthis.#viewportInfo.bounds.width = viewportWidth;\n\t\t\t\tthis.#viewportInfo.bounds.height = viewportHeight;\n\t\t\t}\n\t\t}\n\n\t\tconst viewportInfoHash = `${this.#viewportInfo.scrollTop}${this.#viewportInfo.width}${this.#viewportInfo.height}`;\n\t\tif( viewportInfoHash !== this.#viewportInfoHash.getValue() ){\n\t\t\tthis.#viewportInfoHash.setValue(viewportInfoHash);\n\t\t\tthis.#throttledTriggerEvent('viewportchanged', this.#viewportInfo);\n\t\t}\n\n\t\treturn this.#viewportInfo;\n\t}\n\n\n\n\t/**\n\t * The event handler for scroll events, updating the viewport information.\n\t *\n\t * @fires CustomEvent#\"viewportchanged.visibilityobserver\"\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * window.addEventListener('scroll', this.#handleScroll);\n\t */\n\t#handleScroll(){\n\t\tthis.#refreshViewportInfo(true);\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * The event handler for resize events, updating the viewport information.\n\t *\n\t * @fires CustomEvent#\"viewportchanged.visibilityobserver\"\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * window.addEventListener('resize', this.#handleResize);\n\t */\n\t#handleResize(){\n\t\tthis.#refreshViewportInfo();\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * The event handler for document mutation events, updating the viewport information.\n\t *\n\t * @fires CustomEvent#\"viewportchanged.visibilityobserver\"\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * new MutationObserver(this.#handleMutation);\n\t */\n\t#handleMutation(){\n\t\tthis.#refreshViewportInfo();\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * The event handler for polling events, updating the viewport information.\n\t *\n\t * @fires CustomEvent#\"viewportchanged.visibilityobserver\"\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * const pollTimer = window.setInterval(this.#handlePoll, 100);\n\t */\n\t#handlePoll(){\n\t\tthis.#refreshViewportInfo();\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * The event handler for intersection events, updating VisibilityStates of all involved elements.\n\t *\n\t * This is the primary method for visibility logic, containing compilation, management and updates of\n\t * visibility information for all observed elements.\n\t *\n\t * @param {Array} entries - all elements with intersections currently happening\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @see https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver\n\t * @example\n\t * new IntersectionObserver(this.#handleIntersections);\n\t */\n\t#handleIntersections(entries){\n\t\tentries.forEach(entry => {\n\t\t\tif( hasValue(entry.rootBounds) ){\n\t\t\t\tconst state = this.#states.get(entry.target);\n\t\t\t\t// normally, this should not be necessary, since #states\n\t\t\t\t// observer are always set in tandem, but somehow, sometimes\n\t\t\t\t// the observer still triggers an intersection with a non-state target\n\t\t\t\t// this could be a browser but, which needs to be handled here\n\t\t\t\tif( hasValue(state) ){\n\t\t\t\t\tstate.inViewport(entry.intersectionRatio > 0);\n\t\t\t\t\tstate.fullyInViewport(entry.intersectionRatio >= 1);\n\n\t\t\t\t\tstate.upperBoundInViewport(\n\t\t\t\t\t\t(entry.boundingClientRect.top >= entry.rootBounds.top)\n\t\t\t\t\t\t&& (entry.boundingClientRect.top <= entry.rootBounds.bottom)\n\t\t\t\t\t);\n\t\t\t\t\tstate.lowerBoundInViewport(\n\t\t\t\t\t\t(entry.boundingClientRect.bottom >= entry.rootBounds.top)\n\t\t\t\t\t\t&& (entry.boundingClientRect.bottom <= entry.rootBounds.bottom)\n\t\t\t\t\t);\n\n\t\t\t\t\tstate.visiblePercent(entry.intersectionRatio * 100);\n\t\t\t\t\tstate.visiblePixels(entry.intersectionRect.height);\n\n\t\t\t\t\tif( state.calculateScrolled ){\n\t\t\t\t\t\tstate.scrolledPercent(\n\t\t\t\t\t\t\t(entry.boundingClientRect.top - entry.rootBounds.height)\n\t\t\t\t\t\t\t/ (-entry.boundingClientRect.height - entry.rootBounds.height) * 100\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif( state.fullyInViewport() ){\n\t\t\t\t\t\t\tstate.startAutoScrolledPercentUpdates(this.#viewportInfoHash, this.#targetFps);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstate.stopAutoScrolledPercentUpdates();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif( state.calculateDistance ){\n\t\t\t\t\t\tif( !state.inViewport() ){\n\t\t\t\t\t\t\tstate.startAutoDistanceUpdates(this.#viewportInfoHash, DISTANCE_BASE_FPS);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstate.stopAutoDistanceUpdates();\n\t\t\t\t\t\t\tstate.distancePixels(0);\n\t\t\t\t\t\t\tstate.distanceViewports(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(\n\t\t\t\t\t\tstate.autoHandleTooLargeElements\n\t\t\t\t\t\t&& (entry.boundingClientRect.height > entry.rootBounds.height)\n\t\t\t\t\t){\n\t\t\t\t\t\tif( state.inViewport() ){\n\t\t\t\t\t\t\tstate.startAutoTooLargeUpdates(this.#viewportInfoHash, this.#targetFps);\n\t\t\t\t\t\t\tif( state.calculateScrolled ){\n\t\t\t\t\t\t\t\tstate.startAutoScrolledPercentUpdates(this.#viewportInfoHash, this.#targetFps, false);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstate.stopAutoTooLargeUpdates();\n\t\t\t\t\t\t\tif( state.calculateScrolled ){\n\t\t\t\t\t\t\t\tstate.stopAutoScrolledPercentUpdates();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tif( !this.#initialized ){\n\t\t\tthis.#initialized = true;\n\t\t\tthis.#triggerEvent('initialized');\n\t\t}\n\n\t\tthis.#throttledTriggerEvent('updated');\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Dispatches a custom event on document.body, signifying a global viewport/visibility event or update.\n\t *\n\t * Every event is automatically namespaced with a dotted postfix.\n\t *\n\t * @param {String} eventName - the name of the event\n\t * @param {?*} [payload=null] -\n\t * @fires CustomEvent#\"eventName.visibilityobserver\"\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#triggerEvent('foobar', {foo : 'bar'});\n\t */\n\t#triggerEvent(eventName, payload=null){\n\t\tdocument.body.dispatchEvent(new CustomEvent(\n\t\t\t`${eventName}.${this.#eventNameSpace}`,\n\t\t\t{detail : payload ?? {}}\n\t\t));\n\n\t\tfire(\n\t\t\tdocument.body,\n\t\t\t`${eventName}.${this.#eventNameSpace}`,\n\t\t\tpayload ?? {}\n\t\t);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Sets up all global events, which are necessary to track viewport updates.\n\t *\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#registerEvents();\n\t */\n\t#registerEvents(){\n\t\twindow.addEventListener('scroll', this.#throttledHandleScroll);\n\t\twindow.addEventListener('resize', this.#throttledHandleResize);\n\t\tthis.#documentMutationObserver = new MutationObserver(this.#throttledHandleMutation);\n\t\tthis.#documentMutationObserver.observe(document.body, {attributes : true, childList : true, subtree : true});\n\t\tconst\n\t\t\tfpsMs = round(1000 / this.#targetFps),\n\t\t\tlazyFpsMs = round(fpsMs / 10)\n\t\t;\n\t\tthis.#refreshPoll = window.setInterval(this.#handlePoll.bind(this), lazyFpsMs);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Removes all global events, which are necessary to track viewport updates.\n\t *\n\t * @returns {VisibilityObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#registerEvents();\n\t */\n\t#unregisterEvents(){\n\t\twindow.clearInterval(this.#refreshPoll);\n\t\twindow.removeEventListener('scroll', this.#throttledHandleScroll);\n\t\twindow.removeEventListener('resize', this.#throttledHandleResize);\n\t\tif( hasValue(this.#documentMutationObserver) ){\n\t\t\tthis.#documentMutationObserver.disconnect();\n\t\t\tthis.#documentMutationObserver = null;\n\t\t}\n\n\t\treturn this;\n\t}\n\n}\n\nexport {VisibilityObserver};\n\n\n\n/**\n * @namespace Viewport:BreakpointObserver\n */\n\n/**\n * A class observing a defined list of breakpoints, notifying subscribers, if the breakpoint changes for whatever\n * reason (viewport resizes or device orientation changes mostly).\n *\n * See class documentation below for details.\n *\n * @memberof Viewport:BreakpointObserver\n * @name BreakpointObserver\n *\n * @see BreakpointObserver\n * @example\n * (new BreakpointObserver((to, from) => {\n * alert(`breakpoint changed from \"${from}\" to \"${to}\"`);\n * })).observe({\n * small : 0,\n * medium : 768,\n * large : 1024,\n * xlarge : 1440\n * });\n * (new BreakpointObserver())\n * .observe(\n * {small : 0},\n * ['medium', 768],\n * [\n * {large : 1024},\n * ['xlarge', 1440]\n * ]\n * )\n * .unobserve('xlarge')\n * .getCurrentBreakpoint()\n * ;\n * => 'medium'\n */\nclass BreakpointObserver {\n\n\t#__className__ = 'BreakpointObserver';\n\t#handlerMustBeFunctionMessage = 'handler must be function';\n\t#handler;\n\t#securedHandler;\n\t#breakpoints;\n\t#currentBreakpoint;\n\t#currentBreakpointReadOnly;\n\t#throttledHandleResize;\n\n\t/**\n\t * Creates a new BreakpointObserver and, optionally, sets a handler for breakpoint changes.\n\t *\n\t * @param {?Function} [handler=null] - the function to call on breakpoint change, receives two parameters: newBreakpointName, oldBreakpointName (if there is no old breakpoint, the parameter will be undefined)\n\t * @param {?Number} [targetFps=BREAKPOINT_BASE_FPS] - the max amount of updates per second we are aiming for in the observer; since breakpoints are not changing very regularly, low FPS should be alright here for most cases\n\t * @throws error if handler is set, but is not a function\n\t */\n\tconstructor(handler=null, targetFps=BREAKPOINT_BASE_FPS){\n\t\tconst __methodName__ = 'constructor';\n\n\t\tif( hasValue(handler) ){\n\t\t\tassert(isFunction(handler), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#handlerMustBeFunctionMessage}`);\n\t\t\tthis.#handler = handler;\n\t\t}\n\n\t\tthis.#securedHandler = (to, from) => {\n\t\t\tif( Object.keys(this.#breakpoints).length > 0 ){\n\t\t\t\tthis.#handler?.(to, from);\n\t\t\t}\n\t\t};\n\n\t\ttargetFps = minMax(1, orDefault(targetFps, VISIBILITY_BASE_FPS, 'int'), 120);\n\t\tconst fpsMs = round(1000 / targetFps);\n\t\tthis.#throttledHandleResize = throttle(fpsMs, this.#handleResize, true, true).bind(this);\n\n\t\tthis.connect(handler);\n\t}\n\n\n\n\t/**\n\t * (Re)starts breakpoint observation (resetting all data and states before) and, optionally, sets a new handler.\n\t *\n\t * @param {?Function} [handler=null] - the function to call on breakpoint change, receives two parameters: newBreakpointName, oldBreakpointName (if there is no old breakpoint, the parameter will be undefined)\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @see disconnect\n\t * @example\n\t * observer\n\t * .connect((to, from) => {\n\t * alert(`breakpoint changed from \"${from}\" to \"${to}\"`);\n\t * })\n\t * .observe(\n\t * ['small', 0],\n\t * ['medium', 768],\n\t * ['large', 1024]\n\t * )\n\t * ;\n\t */\n\tconnect(handler=null){\n\t\tconst __methodName__ = 'connect';\n\n\t\tthis.disconnect();\n\n\t\tif( hasValue(handler) ){\n\t\t\tassert(isFunction(handler), `${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${this.#handlerMustBeFunctionMessage}`);\n\t\t\tthis.#handler = handler;\n\t\t}\n\n\t\tthis.#currentBreakpoint.subscribe(this.#securedHandler);\n\t\tthis.#currentBreakpoint.subscribe(to => { this.#currentBreakpointReadOnly.setValue(to); });\n\n\t\tthis.#registerEvents();\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Stops the observation of breakpoints and resets all data and states.\n\t *\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @see connect\n\t * @example\n\t * observer.disconnect().getCurrentBreakpoint();\n\t * => null\n\t */\n\tdisconnect(){\n\t\tthis.#breakpoints = {};\n\t\tthis.#currentBreakpoint = new Observable();\n\t\tthis.#currentBreakpointReadOnly = new Observable();\n\n\t\tthis.#unregisterEvents();\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Returns either the width to a breakpoint name or the name to a breakpoint width.\n\t *\n\t * @param {String|Number} breakpoint - if a number, tries to return a corresponding breakpoint name, else we'll try to find a width to the given name\n\t * @returns {String|Number|null} - either a breakpoint name, a breakpoint width or null, if nothing was found\n\t *\n\t * @example\n\t * observer.getBreakpoint('large')\n\t * => 1024\n\t * observer.getBreakpoint(1024)\n\t * => 'large'\n\t */\n\tgetBreakpoint(breakpoint){\n\t\tif( isNumber(breakpoint) ){\n\t\t\tlet name = null;\n\n\t\t\tfor( const breakpointName in this.#breakpoints ){\n\t\t\t\tif( breakpoint === this.#breakpoints[breakpointName] ){\n\t\t\t\t\tname = breakpointName;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn name;\n\t\t} else {\n\t\t\treturn this.#breakpoints[`${breakpoint}`] ?? null;\n\t\t}\n\t}\n\n\n\n\t/**\n\t * Returns the currently configured breakpoints of the observer as a dictionary.\n\t *\n\t * The return value is a copy, changing values or names in this value will not change the observer's data.\n\t *\n\t * @returns {Object} the observer's configured breakpoints\n\t */\n\tgetBreakpoints(){\n\t\treturn {...this.#breakpoints};\n\t}\n\n\n\n\t/**\n\t * Returns the current breakpoint's name.\n\t *\n\t * If you need the width, use this value in .getBreakpoint().\n\t *\n\t * @returns {String} the current breakpoint's name\n\t *\n\t * @see getBreakpoint\n\t */\n\tgetCurrentBreakpoint(){\n\t\treturn this.#currentBreakpoint.getValue();\n\t}\n\n\n\n\t/**\n\t * Returns an observable, that notifies subscribers of breakpoint changes.\n\t *\n\t * Use this, if you need more than one handler or want a little bit more flexibility.\n\t *\n\t * This observable is read-only, setting its values will not influence breakpoint evaluation in the observer.\n\t *\n\t * @returns {Basic.Observable} the breakpoint observable\n\t *\n\t * @example\n\t * observer.getCurrentBreakpointObservable().subscribe((to, from) => {\n\t * alert(`breakpoint changed from \"${from}\" to \"${to}\"`);\n\t * });\n\t */\n\tgetCurrentBreakpointObservable(){\n\t\treturn this.#currentBreakpointReadOnly;\n\t}\n\n\n\n\t/**\n\t * Adds breakpoint(s) to observe.\n\t *\n\t * @param {Object|Array|Array|Array} breakpoints - the breakpoint definition, either as a simple dictionary ({breakPointName : breakpointWidth, ...}) with 1 to n props, or as an entry array (['breakpointname', breakpointWidth]); both definitions can also be provided as a list of parameters or an array\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @see unobserve\n\t * @example\n\t * observer.observe({\n\t * small : 0,\n\t * medium : 768,\n\t * large : 1024,\n\t * xlarge : 1440\n\t * });\n\t * observer.observe(\n\t * {small : 0},\n\t * ['medium', 768],\n\t * [\n\t * {large : 1024},\n\t * ['xlarge', 1440]\n\t * ]\n\t * );\n\t */\n\tobserve(...breakpoints){\n\t\tconst additionalBreakpoints = this.#parseBreakpointList(breakpoints);\n\t\tthis.#breakpoints = {\n\t\t\t...this.#breakpoints,\n\t\t\t...additionalBreakpoints\n\t\t};\n\n\t\tthis.#refreshCurrentBreakpoint();\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Removes breakpoint(s) from observation.\n\t *\n\t * @param {Array|Object|Array|Array|Array} breakpoints - this can either be a definition, as used in observe() or just a list of breakpoint names to remove\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @see observe\n\t * @example\n\t * observer.unobserve('small', 'xlarge');\n\t * observer.unobserve(['small', 'xlarge']);\n\t * observer.unobserve({\n\t * small : 0,\n\t * xlarge : 1440\n\t * });\n\t */\n\tunobserve(...breakpoints){\n\t\tconst obsoleteBreakpoints = this.#parseBreakpointList(breakpoints, true);\n\t\tObject.keys(obsoleteBreakpoints).forEach(obsoleteBreakpointName => {\n\t\t\tdelete this.#breakpoints[obsoleteBreakpointName];\n\t\t});\n\n\t\tthis.#refreshCurrentBreakpoint();\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Takes an iterable list of breakpoint definitions and recursively parses this into a plain object of\n\t * key-value pairs, where keys are breakpoint names and values are breakpoint width integers.\n\t *\n\t * @param {Array|Array} list - the breakpoint definition lists, containing either a simple dictionaries ({breakPointName : breakpointWidth, ...}) with 1 to n props, or entry arrays (['breakpointname', breakpointWidth])\n\t * @param {Boolean} [acceptOnlyNames=false] - if true, will accept breakpoint names without widths and return these entries with a null width\n\t * @throws error if breakpoint width is not usable as an integer or width is negative\n\t * @returns {Object} dictionary of parsed breakpoints\n\t *\n\t * @private\n\t * @example\n\t * this.#parseBreakpointList([\n\t * {small : 0},\n\t * ['medium', 768],\n\t * [\n\t * {large : 1024},\n\t * ['xlarge', 1440]\n\t * ]\n\t * ])\n\t * => {\n\t * small : 0,\n\t * medium : 768,\n\t * large : 1024,\n\t * xlarge : 1440\n\t * }\n\t * this.#parseBreakpointList(['xlarge', {small : 0}, ['medium', ['large', 1024]]], true)\n\t * => {\n\t * xlarge : null,\n\t * small : 0,\n\t * medium : null,\n\t * large : 1024\n\t * }\n\t */\n\t#parseBreakpointList(list, acceptOnlyNames=false){\n\t\tconst\n\t\t\t__methodName__ = '#parseBreakpointList',\n\t\t\tunusableBreakpointMessage = 'unusable breakpoint'\n\t\t;\n\n\t\tlet breakpoints = {};\n\n\t\tArray.from(list).forEach(breakpoint => {\n\t\t\tif( isPlainObject(breakpoint) ){\n\t\t\t\tfor( const breakpointName in breakpoint ){\n\t\t\t\t\tbreakpoint[breakpointName] = parseInt(breakpoint[breakpointName], 10);\n\t\t\t\t\tassert(\n\t\t\t\t\t\t!isNaN(breakpoint[breakpointName]) && (breakpoint[breakpointName] >= 0),\n\t\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${unusableBreakpointMessage} \"${breakpointName}\"`\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tbreakpoints = {...breakpoints, ...breakpoint};\n\t\t\t} else if( isArray(breakpoint) ){\n\t\t\t\tif(\n\t\t\t\t\t(breakpoint.length === 2)\n\t\t\t\t\t&& !isPlainObject(breakpoint[0]) && !isArray(breakpoint[0])\n\t\t\t\t\t&& !isPlainObject(breakpoint[1]) && !isArray(breakpoint[1])\n\t\t\t\t){\n\t\t\t\t\tconst breakpointName = `${breakpoint[0]}`;\n\t\t\t\t\tbreakpoints[breakpointName] = parseInt(breakpoint[1], 10);\n\t\t\t\t\tassert(\n\t\t\t\t\t\t!isNaN(breakpoints[breakpointName]) && (breakpoints[breakpointName] >= 0),\n\t\t\t\t\t\t`${MODULE_NAME}:${this.#__className__}.${__methodName__} | ${unusableBreakpointMessage} \"${breakpointName}\"`\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tbreakpoints = {\n\t\t\t\t\t\t...breakpoints,\n\t\t\t\t\t\t...this.#parseBreakpointList(breakpoint, acceptOnlyNames)\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} else if( acceptOnlyNames ){\n\t\t\t\tbreakpoints[`${breakpoint}`] = null;\n\t\t\t}\n\t\t});\n\n\t\treturn breakpoints;\n\t}\n\n\n\n\t/**\n\t * Updates the current breakpoint value, based on the current breakpoint configuration in regard to the current\n\t * viewport width.\n\t *\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#refreshCurrentBreakpoint();\n\t */\n\t#refreshCurrentBreakpoint(){\n\t\tconst\n\t\t\tviewportWidth = window.innerWidth,\n\t\t\tbreakpoints = Object.entries(this.#breakpoints).sort((a, b) => {\n\t\t\t\treturn (a[1] === b[1])\n\t\t\t\t\t? 0\n\t\t\t\t\t: (\n\t\t\t\t\t\t(a[1] > b[1])\n\t\t\t\t\t\t? 1\n\t\t\t\t\t\t: -1\n\t\t\t\t\t)\n\t\t\t\t;\n\t\t\t})\n\t\t;\n\n\t\tlet currentBreakpoint = null;\n\t\tbreakpoints.forEach(([breakpointName, breakpointWidth]) => {\n\t\t\tif( viewportWidth >= breakpointWidth ){\n\t\t\t\tcurrentBreakpoint = breakpointName;\n\t\t\t}\n\t\t});\n\n\t\tthis.#currentBreakpoint.setValue(currentBreakpoint);\n\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Event handler for resize events. Updates the current breakpoint if necessary.\n\t *\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * window.addEventListener('resize', this.#handleResize);\n\t */\n\t#handleResize(){\n\t\tthis.#refreshCurrentBreakpoint();\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Registers all (global) events, such as the resize event, that are needed for breakpoint observation.\n\t *\n\t * Be sure to unregister trailing handlers before destructing the observer, by using disconnect().\n\t *\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#registerEvents()\n\t */\n\t#registerEvents(){\n\t\twindow.addEventListener('resize', this.#throttledHandleResize);\n\t\treturn this;\n\t}\n\n\n\n\t/**\n\t * Unregisters all (global) events, such as the resize event, to prevent trailing event handlers after destruction.\n\t *\n\t * Be sure to unregister trailing handlers before destructing the observer, by using disconnect().\n\t *\n\t * @returns {BreakpointObserver} the observer instance\n\t *\n\t * @private\n\t * @example\n\t * this.#unregisterEvents()\n\t */\n\t#unregisterEvents(){\n\t\twindow.removeEventListener('resize', this.#throttledHandleResize);\n\t\treturn this;\n\t}\n\n}\n\nexport {BreakpointObserver};\n"]} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 6f37f74f..12f7924c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: "3" - services: annex: container_name: annex__dev @@ -15,5 +13,6 @@ services: working_dir: /project environment: - TERM=xterm-256color - - YARN_CACHE_FOLDER=/tmp - command: bash -c "yarn install; gulp --color examples" + - LANG=C.UTF-8 + - NODE_ENV=development + command: bash -c "yarn run examples" diff --git a/docker/annex/dockerfile b/docker/annex/dockerfile index 269c1997..9b1324f0 100644 --- a/docker/annex/dockerfile +++ b/docker/annex/dockerfile @@ -1,15 +1,16 @@ -FROM node:16.19 - -ENV TERM=xterm-256color +FROM node:16.20 RUN apt-get update RUN apt-get upgrade -y +RUN apt-get install -y bc ed nano fonts-powerline RUN apt-get clean RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +WORKDIR /root +RUN touch build_marker +RUN git clone --recursive https://github.com/andresgongora/synth-shell.git +RUN chmod +x synth-shell/setup.sh +RUN yes | synth-shell/setup.sh + RUN yarn global add gulp-cli@2.3.0 RUN yarn global add jsdoc@3.6.11 - -WORKDIR /project - -COPY docker/bash/bashrc /root/.bashrc diff --git a/docker/bash/bashrc b/docker/bash/bashrc deleted file mode 100644 index a6c739c8..00000000 --- a/docker/bash/bashrc +++ /dev/null @@ -1,303 +0,0 @@ -# --------------------------------------------------------------------------- -# -# Description: This file holds all my BASH configurations and aliases -# -# Sections: -# 1. Environment Configuration -# 2. Make Terminal Better (remapping defaults and adding functionality) -# 3. File and Folder Management -# 4. Searching -# 5. Process Management -# 6. Networking -# 7. System Operations & Information -# 8. Web Development -# 9. Reminders & Notes -# -# --------------------------------------------------------------------------- - -# ------------------------------- -# 1. ENVIRONMENT CONFIGURATION -# ------------------------------- - -# Change Prompt -# ------------------------------------------------------------ - export PS1="________________________________________________________________________________\n| \w @ \h (\u) \n| => " - export PS2="| => " - -# Set Paths -# ------------------------------------------------------------ - export PATH="$PATH:/usr/local/bin/" - export PATH="/usr/local/git/bin:/sw/bin/:/usr/local/bin:/usr/local/:/usr/local/sbin:/usr/local/mysql/bin:$PATH" - -# Set Default Editor (change 'Nano' to the editor of your choice) -# ------------------------------------------------------------ - export EDITOR=/usr/bin/nano - -# Set default blocksize for ls, df, du -# from this: http://hints.macworld.com/comment.php?mode=view&cid=24491 -# ------------------------------------------------------------ - export BLOCKSIZE=1k - -# Add color to terminal -# (this is all commented out as I use Mac Terminal Profiles) -# from http://osxdaily.com/2012/02/21/add-color-to-the-terminal-in-mac-os-x/ -# ------------------------------------------------------------ - export CLICOLOR=1 - export LSCOLORS=ExFxBxDxCxegedabagacad - - -# ----------------------------- -# 2. MAKE TERMINAL BETTER -# ----------------------------- - -alias ls='ls --color=auto' -alias grep='grep --color=auto' -alias fgrep='fgrep --color=auto' -alias egrep='egrep --color=auto' - -alias cp='cp -iv' # Preferred 'cp' implementation -alias mv='mv -iv' # Preferred 'mv' implementation -alias mkdir='mkdir -pv' # Preferred 'mkdir' implementation -alias ll='ls -FGlAhp' # Preferred 'ls' implementation -alias la='ls -la' -alias less='less -FSRXc' # Preferred 'less' implementation -cd() { builtin cd "$@"; ll; } # Always list directory contents upon 'cd' -alias cd..='cd ../' # Go back 1 directory level (for fast typers) -alias ..='cd ../' # Go back 1 directory level -alias ...='cd ../../' # Go back 2 directory levels -alias .3='cd ../../../' # Go back 3 directory levels -alias .4='cd ../../../../' # Go back 4 directory levels -alias .5='cd ../../../../../' # Go back 5 directory levels -alias .6='cd ../../../../../../' # Go back 6 directory levels -alias edit='subl' # edit: Opens any file in sublime editor -alias f='open -a Finder ./' # f: Opens current directory in MacOS Finder -alias ~="cd ~" # ~: Go Home -alias c='clear' # c: Clear terminal display -alias which='type -all' # which: Find executables -alias path='echo -e ${PATH//:/\\n}' # path: Echo all executable Paths -alias show_options='shopt' # Show_options: display bash options settings -alias fix_stty='stty sane' # fix_stty: Restore terminal settings when screwed up -alias cic='set completion-ignore-case On' # cic: Make tab-completion case-insensitive -mcd () { mkdir -p "$1" && cd "$1"; } # mcd: Makes new Dir and jumps inside -trash () { command mv "$@" ~/.Trash ; } # trash: Moves a file to the MacOS trash -ql () { qlmanage -p "$*" >& /dev/null; } # ql: Opens any file in MacOS Quicklook Preview -alias DT='tee ~/Desktop/terminalOut.txt' # DT: Pipe content to file on MacOS Desktop - -# lr: Full Recursive Directory Listing -# ------------------------------------------ -alias lr='ls -R | grep ":$" | sed -e '\''s/:$//'\'' -e '\''s/[^-][^\/]*\//--/g'\'' -e '\''s/^/ /'\'' -e '\''s/-/|/'\'' | less' - -# mans: Search manpage given in agument '1' for term given in argument '2' (case insensitive) -# displays paginated result with colored search terms and two lines surrounding each hit. Example: mans mplayer codec -# -------------------------------------------------------------------- - mans () { - man $1 | grep -iC2 --color=always $2 | less - } - -# showa: to remind yourself of an alias (given some part of it) -# ------------------------------------------------------------ - showa () { /usr/bin/grep --color=always -i -a1 $@ ~/Library/init/bash/aliases.bash | grep -v '^\s*$' | less -FSRXc ; } - - -# ------------------------------- -# 3. FILE AND FOLDER MANAGEMENT -# ------------------------------- - -zipf () { zip -r "$1".zip "$1" ; } # zipf: To create a ZIP archive of a folder -alias numFiles='echo $(ls -1 | wc -l)' # numFiles: Count of non-hidden files in current dir -alias make1mb='mkfile 1m ./1MB.dat' # make1mb: Creates a file of 1mb size (all zeros) -alias make5mb='mkfile 5m ./5MB.dat' # make5mb: Creates a file of 5mb size (all zeros) -alias make10mb='mkfile 10m ./10MB.dat' # make10mb: Creates a file of 10mb size (all zeros) - -# cdf: 'Cd's to frontmost window of MacOS Finder -# ------------------------------------------------------ - cdf () { - currFolderPath=$( /usr/bin/osascript <