From e473e7899d8f4e3b30854df439d92f3f5b69bf06 Mon Sep 17 00:00:00 2001 From: Clemens Schwaighofer Date: Thu, 27 Nov 2025 17:54:28 +0900 Subject: [PATCH] Fix logging line and call method information The logging line number and file was for the previous call position, not for where the actual log entry was called Also fix for ErrorMessage class calls with shifting the start position up depending on which method is called. Output shows file and line where the message/log call was done and the function/class method where the log call was done --- www/admin/class_test.error_msg.php | 8 ++ www/admin/class_test.logging.php | 6 ++ www/admin/layout/javascript/utils.js | 45 ++++++-- www/admin/layout/javascript/utils.min.js | 4 +- www/admin/layout/javascript/utils.min.js.map | 8 +- www/lib/CoreLibs/Convert/Byte.php | 2 +- www/lib/CoreLibs/Logging/ErrorMessage.php | 2 + www/lib/CoreLibs/Logging/Logging.php | 108 +++++++++++++++---- 8 files changed, 149 insertions(+), 34 deletions(-) diff --git a/www/admin/class_test.error_msg.php b/www/admin/class_test.error_msg.php index 61401575..3ce5173d 100644 --- a/www/admin/class_test.error_msg.php +++ b/www/admin/class_test.error_msg.php @@ -58,6 +58,14 @@ $em->setErrorMsg('100-2', 'error', 'Input wring', jump_target:['target' => 'foo- $em->setMessage('error', 'I have no id set', jump_target:['target' => 'bar-123', 'info' => 'Jump Bar']); $em->setMessage('error', 'Jump empty', jump_target:['target' => 'bar-empty']); +function inLine(\CoreLibs\Logging\ErrorMessage $em): void +{ + $em->log->error('Direct log before from ', context:['function' => __FUNCTION__]); + $em->setMessage('error', 'Inline call', context:['test' => 'inLine Function']); + $em->log->error('Direct log from ', context:['function' => __FUNCTION__]); +} +inLine($em); + print "ErrorsLast:
" . $log->prAr($em->getLastErrorMsg()) . "
"; print "ErrorsIds:
" . $log->prAr($em->getErrorIds()) . "
"; print "Errors:
" . $log->prAr($em->getErrorMsg()) . "
"; diff --git a/www/admin/class_test.logging.php b/www/admin/class_test.logging.php index 77a47426..f5a2d852 100644 --- a/www/admin/class_test.logging.php +++ b/www/admin/class_test.logging.php @@ -121,6 +121,12 @@ Class TestP public function test(): void { $this->log->info('TestL::test call'); + $this->subCall(); + } + + public function subCall(): void + { + $this->log->info('TestL::sub_call call'); } } diff --git a/www/admin/layout/javascript/utils.js b/www/admin/layout/javascript/utils.js index c6c46618..f7ba2a86 100644 --- a/www/admin/layout/javascript/utils.js +++ b/www/admin/layout/javascript/utils.js @@ -46,10 +46,15 @@ function runFunctionArgsArray(name, args) { fn.apply(window, args); } function isObject(val) { - if (val === null) { - return false; - } - return typeof val === "function" || typeof val === "object"; + return val !== null && typeof val === "object" && !Array.isArray(val); +} +function isArray(val) { + return val !== null && Array.isArray(val); +} +function isIterable(val) { + if (val == null) return false; + if (typeof val[Symbol.iterator] === "function" && typeof val !== "string") return true; + return typeof val === "object" && val.constructor === Object; } function getObjectCount(object) { if (!isObject(object)) { @@ -158,7 +163,7 @@ var HtmlElementCreator = class { if (base.id == id) { base.sub.push(deepCopyFunction(attach)); } else { - if (isObject(base.sub) && base.sub.length > 0) { + if (isArray(base.sub) && base.sub.length > 0) { for (var i = 0; i < base.sub.length; i++) { this.ael(base.sub[i], attach, id); } @@ -297,7 +302,7 @@ var HtmlElementCreator = class { line += ' name="' + (tree.name ? tree.name : tree.id) + '"'; } } - if (isObject(tree.css) && tree.css.length > 0) { + if (isArray(tree.css) && tree.css.length > 0) { line += ' class="'; for (i = 0; i < tree.css.length; i++) { line += tree.css[i] + " "; @@ -314,7 +319,7 @@ var HtmlElementCreator = class { } line += ">"; content.push(line); - if (isObject(tree.sub) && tree.sub.length > 0) { + if (isArray(tree.sub) && tree.sub.length > 0) { if (tree.content) { content.push(tree.content); } @@ -1331,6 +1336,17 @@ var LoginNavMenu = class { } }; +// src/utils/BrowserDetect.mjs +function isWebkit() { + return "GestureEvent" in window; +} +function isMobileWebKit() { + return "ongesturechange" in window; +} +function isDesktopWebKit() { + return typeof window !== "undefined" && "safari" in window && "pushNotification" in window.safari; +} + // src/utils.mjs var aiob = new ActionIndicatorOverlayBox(); var hec = new HtmlElementCreator(); @@ -1433,6 +1449,12 @@ function executeFunctionByName2(functionName, context) { function isObject2(val) { return isObject(val); } +function isArray2(val) { + return isArray(val); +} +function isIterable2(val) { + return isIterable(val); +} function getObjectCount2(object) { return getObjectCount(object); } @@ -1613,3 +1635,12 @@ function createActionBox(target_id = "actionBox", title = "", contents = {}, hea function adjustActionBoxHeight(target_id = "actionBox", override = 0, content_override = 0) { ab.adjustActionBoxHeight(target_id, override, content_override); } +function isWebkit2() { + return isWebkit(); +} +function isMobileWebKit2() { + return isMobileWebKit(); +} +function isDesktopWebKit2() { + return isDesktopWebKit(); +} diff --git a/www/admin/layout/javascript/utils.min.js b/www/admin/layout/javascript/utils.min.js index 062537e4..553bb81f 100644 --- a/www/admin/layout/javascript/utils.min.js +++ b/www/admin/layout/javascript/utils.min.js @@ -1,3 +1,3 @@ -function errorCatch(err){err.stack?err.lineNumber?console.error("ERROR[%s:%s] ",err.name,err.lineNumber,err):err.line?console.error("ERROR[%s:%s] ",err.name,err.line,err):console.error("ERROR[%s] ",err.name,err):err.number?(console.error("ERROR[%s:%s] %s",err.name,err.number,err.message),console.error("ERROR[description] %s",err.description)):console.error("ERROR[%s] %s",err.name,err.message)}function isFunction(name){return typeof window[name]<"u"&&typeof window[name]=="function"}function executeFunctionByName(functionName,context){var args=Array.prototype.slice.call(arguments,2),namespaces=functionName.split("."),func=namespaces.pop();if(func==null)throw new Error("Cannot get function from namespaces: "+functionName);for(var i=0;iobject[key]===value)??""}function valueInObject(object,value){return objectValueExists(object,value)}function objectValueExists(object,value){return!!Object.keys(object).find(key=>object[key]===value)}function deepCopyFunction(inObject){var outObject,value,key;if(typeof inObject!="object"||inObject===null)return inObject;outObject=Array.isArray(inObject)?[]:{};for(key in inObject)value=inObject[key],outObject[key]=deepCopyFunction(value);return outObject}function loadEl(el_id){let el=document.getElementById(el_id);if(el===null)throw new Error("Cannot find: "+el_id);return el}function pop(theURL,winName,features){let __winName=window.open(theURL,winName,features);__winName?.focus()}function expandTA(ta_id){let ta=this.loadEl(ta_id);if(ta instanceof HTMLElement&&ta.getAttribute("type")!=="textarea")throw new Error("Element is not a textarea: "+ta_id);let maxChars=parseInt(ta.getAttribute("cols")??"0"),ta_value=ta.getAttribute("value"),theRows=[];ta_value!=null&&(theRows=ta_value.split(` -`));for(var numNewRows=0,i=0;imaxChars&&(numNewRows+=Math.ceil((theRows[i].length+2)/maxChars));ta.setAttribute("row",(numNewRows+theRows.length).toString())}function exists(id){return $("#"+id).length>0}var HtmlElementCreator=class{cel(tag,id="",content="",css=[],options={}){return{tag,id,name:options.name,content,css,options,sub:[]}}ael(base,attach,id=""){if(id){if(base.id==id)base.sub.push(deepCopyFunction(attach));else if(isObject(base.sub)&&base.sub.length>0)for(var i=0;i-1&&_element.css.splice(css_index,1),_element}acssel(_element,css){var css_index=_element.css.indexOf(css);return css_index==-1&&_element.css.push(css),_element}scssel(_element,rcss,acss){return this.rcssel(_element,rcss),this.acssel(_element,acss),_element}phfo(tree){let name_elements=["button","fieldset","form","iframe","input","map","meta","object","output","param","select","textarea"],skip_options=["id","name","class"],no_close=["input","br","img","hr","area","col","keygen","wbr","track","source","param","command","base","meta","link","embed"];var content=[],line="<"+tree.tag,i;if(tree.id&&(line+=' id="'+tree.id+'"',name_elements.includes(tree.tag)&&(line+=' name="'+(tree.name?tree.name:tree.id)+'"')),isObject(tree.css)&&tree.css.length>0){for(line+=' class="',i=0;i0)for(tree.content&&content.push(tree.content),i=0;i"),content.join("")}phfa(list){for(var content=[],i=0;i"'/]/g,function(s){var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return entityMap[s]})}function unescapeHtml(string){return string.replace(/&[#\w]+;/g,function(s){var entityMap={"&":"&","<":"<",">":">",""":'"',"'":"'","/":"/"};return entityMap[s]})}function html_options(name,data,selected="",options_only=!1,return_string=!1,sort=""){return this.html_options_block(name,data,selected,0,options_only,return_string,sort)}function html_options_block(name,data,selected="",multiple=0,options_only=!1,return_string=!1,sort="",onchange=""){var content=[],element_select,select_options={},element_option,data_list=[],value,options={};multiple>0&&(select_options.multiple="",multiple>1&&(select_options.size=multiple)),onchange&&(select_options.OnChange=onchange),element_select=dom.cel("select",name,"",[],select_options),sort=="keys"?data_list=Object.keys(data).sort():sort=="values"?data_list=Object.keys(data).sort((a,b)=>(""+data[a]).localeCompare(data[b])):data_list=Object.keys(data);for(let key of data_list)value=data[key],options={label:value,value:key,selected:""},multiple==0&&!Array.isArray(selected)&&selected==key&&(options.selected=""),multiple==1&&Array.isArray(selected)&&selected.indexOf(key)!=-1&&(options.selected=""),element_option=dom.cel("option","",value,[],options),dom.ael(element_select,element_option);if(options_only)if(return_string){for(var i=0;i(""+data[a]).localeCompare(data[b])):data_list=Object.keys(data),[].forEach.call(document.querySelectorAll("#"+name+" :checked"),function(elm){option_selected=elm.value}),loadEl(name).innerHTML="";for(let key of data_list)value=data[key],element_option=document.createElement("option"),element_option.label=value,element_option.value=key,element_option.innerHTML=value,key==option_selected&&(element_option.selected=!0),loadEl(name).appendChild(element_option)}}function dec2hex(dec){return("0x"+dec.toString(16)).substring(-2)}function getRandomIntInclusive(min,max){return min=Math.ceil(min),max=Math.floor(max),Math.floor(Math.random()*(max-min+1)+min)}function roundPrecision(number,precision){return isNaN(number)||isNaN(precision)?number:Math.round(number*Math.pow(10,precision))/Math.pow(10,precision)}function formatString(string,...args){return string.replace(/{(\d+)}/g,function(match,number){return typeof args[number]<"u"?args[number]:match})}function numberWithCommas(number){var parts=number.toString().split(".");return parts[0]=parts[0].replace(/\B(?=(\d{3})+(?!\d))/g,","),parts.join(".")}function convertLBtoBR(string){return string.replace(/(?:\r\n|\r|\n)/g,"
")}function getTimestamp(){var date=new Date;return date.getTime()}function generateId(len){var arr=new Uint8Array((len||40)/2);return(window.crypto||window.msCrypto).getRandomValues(arr),Array.from(arr,self.dec2hex).join("")}function randomIdF(){return Math.random().toString(36).substring(2)}function getWindowSize(){var width,height;return width=window.innerWidth||window.document.documentElement.clientWidth||window.document.body.clientWidth,height=window.innerHeight||window.document.documentElement.clientHeight||window.document.body.clientHeight,{width,height}}function getScrollOffset(){var left,top;return left=window.pageXOffset||window.document.documentElement.scrollLeft||window.document.body.scrollLeft,top=window.pageYOffset||window.document.documentElement.scrollTop||window.document.body.scrollTop,{left,top}}function getScrollOffsetOpener(){var left,top;return left=opener.window.pageXOffset||opener.document.documentElement.scrollLeft||opener.document.body.scrollLeft,top=opener.window.pageYOffset||opener.document.documentElement.scrollTop||opener.document.body.scrollTop,{left,top}}function setCenter(id,left,top){var dimensions={height:$("#"+id).height()??0,width:$("#"+id).width()??0},type=$("#"+id).css("position"),viewport=this.getWindowSize(),offset=this.getScrollOffset();if(left&&$("#"+id).css({left:viewport.width/2-dimensions.width/2+offset.left+"px"}),top){var top_pos=type=="fixed"?viewport.height/2-dimensions.height/2:viewport.height/2-dimensions.height/2+offset.top;$("#"+id).css({top:top_pos+"px"})}}function goToPos(element,offset=0,duration=500,base="body,html"){try{let element_offset=$("#"+element).offset();if(element_offset==null)return;$("#"+element).length&&$(base).animate({scrollTop:element_offset.top-offset},duration)}catch(err){errorCatch(err)}}function goTo(target){loadEl(target).scrollIntoView({behavior:"smooth"})}function formatBytes(bytes){var i=-1;if(typeof bytes=="bigint"&&(bytes=Number(bytes)),isNaN(bytes))return bytes.toString();do bytes=bytes/1024,i++;while(bytes>99);return Math.round(bytes*Math.pow(10,2))/Math.pow(10,2)+["kB","MB","GB","TB","PB","EB"][i]}function formatBytesLong(bytes){if(typeof bytes=="bigint"&&(bytes=Number(bytes)),isNaN(bytes))return bytes.toString();let negative=!1;bytes<0&&(negative=!0,bytes*=-1);var i=Math.floor(Math.log(bytes)/Math.log(1024)),sizes=["B","KB","MB","GB","TB","PB","EB","ZB","YB"];return(negative?"-":"")+((bytes/Math.pow(1024,i)).toFixed(2)+" "+sizes[i]).toString()}function stringByteFormat(bytes,raw=!1){if(!(typeof bytes=="string"||bytes instanceof String))return bytes.toString();let valid_units="bkmgtpezy",regex=/([\d.,]*)\s?(eb|pb|tb|gb|mb|kb|e|p|t|g|m|k|b)$/i,matches=bytes.match(regex);if(matches!==null){let m1=parseFloat(matches[1].replace(/[^0-9.]/,"")),m2=matches[2].replace(/[^bkmgtpezy]/i,"").charAt(0).toLowerCase();m2&&(bytes=m1*Math.pow(1024,valid_units.indexOf(m2)))}return raw?bytes:Math.round(bytes)}function parseQueryString(query="",return_key="",single=!1){return getQueryStringParam(return_key,query,single)}function getQueryStringParam(search="",query="",single=!1){query||(query=window.location.href);let url=new URL(query),param=null;if(search){let _params=url.searchParams.getAll(search);_params.length==1||single===!0?param=_params[0]:_params.length>1&&(param=_params)}else{param={};for(let[key]of url.searchParams.entries())if(typeof param[key]>"u"){let _params=url.searchParams.getAll(key);param[key]=_params.length<2||single===!0?_params[0]:_params}}return param}function hasUrlParameter(key){var urlParams=new URLSearchParams(window.location.search);return urlParams.has(key)}function getUrlParameter(key){var urlParams=new URLSearchParams(window.location.search);return urlParams.get(key)}function updateUrlParameter(key,value,reload=!1){let url=new URL(window.location.href);url.searchParams.set(key,value);let newUrl=url.toString();window.history.pushState({path:newUrl},"",newUrl),reload&&window.location.reload()}function removeUrlParameter(key,reload=!1){let url=new URL(window.location.href);url.searchParams.delete(key),window.history.pushState({},"",url.toString()),reload&&window.location.reload()}function loginLogout(){let form=document.createElement("form");form.method="post";let hiddenField=document.createElement("input");hiddenField.type="hidden",hiddenField.name="login_logout",hiddenField.value="Logout",form.appendChild(hiddenField),document.body.appendChild(form),form.submit()}function actionIndicator(loc,overlay=!0){$("#indicator").is(":visible")?this.actionIndicatorHide(loc,overlay):this.actionIndicatorShow(loc,overlay)}function actionIndicatorShow(loc,overlay=!0){$("#indicator").is(":visible")||($("#indicator").hasClass("progress")||$("#indicator").addClass("progress"),setCenter("indicator",!0,!0),$("#indicator").show()),overlay===!0&&this.overlayBoxShow()}function actionIndicatorHide(loc,overlay=!0){$("#indicator").hide(),overlay===!0&&overlayBoxHide()}function overlayBoxShow(){$("#overlayBox").is(":visible")?$("#overlayBox").css("zIndex","100"):($("#overlayBox").show(),$("#overlayBox").css("zIndex","98"))}function overlayBoxHide(){parseInt($("#overlayBox").css("zIndex"))>=100?$("#overlayBox").css("zIndex","98"):$("#overlayBox").hide()}function setOverlayBox(){$("#overlayBox").is(":visible")||$("#overlayBox").show()}function hideOverlayBox(){$("#overlayBox").is(":visible")&&$("#overlayBox").hide()}function ClearCall(){$("#actionBox").html(""),$("#actionBox").hide(),$("#overlayBox").hide()}var ActionIndicatorOverlayBox=class{#GL_OB_S=100;#GL_OB_BASE=100;showActionIndicator(loc){if($("#indicator").length==0){var el=document.createElement("div");el.className="progress hide",el.id="indicator",$("body").append(el)}else $("#indicator").hasClass("progress")||$("#indicator").addClass("progress").hide();$("#indicator").is(":visible")||(this.checkOverlayExists(),$("#overlayBox").is(":visible")||$("#overlayBox").show(),$("#overlayBox").css("zIndex",1e3),$("#indicator").show(),setCenter("indicator",!0,!0))}hideActionIndicator(loc){$("#indicator").is(":visible")&&($("#indicator").hide(),this.#GL_OB_S>this.#GL_OB_BASE?$("#overlayBox").css("zIndex",this.#GL_OB_S):($("#overlayBox").hide(),$("#overlayBox").css("zIndex",this.#GL_OB_BASE)))}checkOverlayExists(){if($("#overlayBox").length==0){var el=document.createElement("div");el.className="overlayBoxElement hide",el.id="overlayBox",$("body").append(el)}}showOverlayBoxLayers(el_id){$("#overlayBox").is(":visible")||($("#overlayBox").show(),$("#overlayBox").css("zIndex",this.#GL_OB_BASE),this.#GL_OB_S=this.#GL_OB_BASE),this.#GL_OB_S++,$("#overlayBox").css("zIndex",this.#GL_OB_S),el_id&&$("#"+el_id).length>0&&($("#"+el_id).css("zIndex",this.#GL_OB_S+1),$("#"+el_id).show())}hideOverlayBoxLayers(el_id=""){this.#GL_OB_S--,this.#GL_OB_S<=this.#GL_OB_BASE?(this.#GL_OB_S=this.#GL_OB_BASE,$("#overlayBox").hide(),$("#overlayBox").css("zIndex",this.#GL_OB_BASE)):$("#overlayBox").css("zIndex",this.#GL_OB_S),el_id&&($("#"+el_id).hide(),$("#"+el_id).css("zIndex",0))}clearCallActionBox(){$("#actionBox").html(""),$("#actionBox").hide(),this.hideOverlayBoxLayers()}};var l10nTranslation=class{#i18n={};constructor(i18n2){this.#i18n=i18n2}__(string){return typeof this.#i18n<"u"&&isObject(this.#i18n)&&this.#i18n[string]?this.#i18n[string]:string}};var ActionBox=class{zIndex={base:100,max:110,indicator:0,boxes:{},active:[],top:""};action_box_storage={};action_box_cache_timeout=10*60*1e3;hec;l10n;constructor(hec2,l10n2){this.hec=hec2,this.l10n=l10n2}showFillActionBox(target_id="actionBox",content="",action_box_css=[],override=0,content_override=0){this.fillActionBox(target_id,content,action_box_css),this.showActionBox(target_id,override,content_override)}fillActionBox(target_id="actionBox",content="",action_box_css=[]){exists(target_id)||$("#mainContainer").after(this.hec.phfo(this.hec.cel("div",target_id,"",["actionBoxElement","hide"].concat(action_box_css)))),$("#"+target_id).html(content)}adjustActionBox(target_id="actionBox",override=0,content_override=0){this.adjustActionBoxHeight(target_id,override,content_override),setCenter(target_id,!0,!0)}hideAllActionBoxes(){$('#actionBox, div[id^="actionBox-"].actionBoxElement').hide(),$("#overlayBox").hide()}hideActionBox(target_id="actionBox"){this.closeActionBoxFloat(target_id,!1)}showActionBox(target_id="actionBox",override=0,content_override=0,hide_all=!0){this.showActionBoxFloat(target_id,override,content_override,hide_all)}closeActionBox(target_id="actionBox",clean=!0){this.closeActionBoxFloat(target_id,clean)}showActionBoxFloat(target_id="actionBox",override=0,content_override=0,hide_all=!1){hide_all===!0&&this.hideAllActionBoxes(),exists("overlayBox")||($("body").prepend(this.hec.phfo(this.hec.cel("div","overlayBox","",["overlayBoxElement"]))),$("#overlayBox").css("zIndex",this.zIndex.base)),$("#overlayBox").show(),objectKeyExists(this.zIndex.boxes,target_id)?this.zIndex.boxes[target_id]+10({id:el.id,zIndex:$("#"+el.id).css("zIndex")})).get();if(visible_zIndexes.length>0){let max_zIndex=0,max_el_id="";for(let zIndex_el of visible_zIndexes)parseInt(zIndex_el.zIndex)>max_zIndex&&(max_zIndex=parseInt(zIndex_el.zIndex),max_el_id=zIndex_el.id);$("#overlayBox").css("zIndex",max_zIndex-1),this.zIndex.top=max_el_id}else $("#overlayBox").hide()}createActionBox(target_id="actionBox",title="",contents={},headers={},settings={},show_close=!0){objectKeyExists(this.action_box_storage,target_id)||(this.action_box_storage[target_id]={});let header_css=[];objectKeyExists(settings,"header_css")&&(header_css=settings.header_css);let action_box_css=[];objectKeyExists(settings,"action_box_css")&&(action_box_css=settings.action_box_css);let elements=[];elements.push(this.hec.phfo(this.hec.aelx(this.hec.cel("div",target_id+"_title","",["actionBoxTitle","flx-spbt"].concat(header_css)),...show_close===!0?[this.hec.cel("div","",title,["fs-b","w-80"]),this.hec.aelx(this.hec.cel("div",target_id+"_title_close_button","",["w-20","tar"]),this.hec.cel("input",target_id+"_title_close","",["button-close","fs-s"],{type:"button",value:this.l10n.__("Close"),OnClick:"closeActionBox('"+target_id+"', false);"}))]:[this.hec.cel("div","",title,["fs-b","w-100"])]))),getObjectCount(headers)>0&&(objectKeyExists(headers,"raw_string")?elements.push(headers.raw_string):elements.push(this.hec.phfo(headers))),getObjectCount(contents)>0?objectKeyExists(contents,"raw_string")?elements.push(contents.raw_string):elements.push(this.hec.phfo(contents)):elements.push(this.hec.phfo(this.hec.cel("div",target_id+"_content","",[]))),elements.push(this.hec.phfo(this.hec.aelx(this.hec.cel("div",target_id+"_footer","",["pd-5","flx-spbt"]),...show_close===!0?[this.hec.cel("div","","",["fs-b","w-80"]),this.hec.aelx(this.hec.cel("div",target_id+"_footer_close_button","",["tar","w-20"]),this.hec.cel("input",target_id+"_footer_close","",["button-close","fs-s"],{type:"button",value:this.l10n.__("Close"),OnClick:"closeActionBox('"+target_id+"', false);"}))]:[this.hec.cel("div","","",["fs-b","w-100"])]))),elements.push(this.hec.phfo(this.hec.cel("input",target_id+"-cache_time","",[],{type:"hidden",value:Date.now()}))),this.fillActionBox(target_id,elements.join(""),action_box_css)}adjustActionBoxHeight(target_id="actionBox",override=0,content_override=0){var new_height=0,dim={},abc_dim={},content_id="";switch(isNaN(override)&&(override=0),isNaN(content_override)&&(content_override=0),target_id){case"actionBox":content_id="action_box";break;case"actionBoxSub":content_id="action_box_sub";break;default:content_id=target_id;break}$.each([target_id,content_id+"_content"],function(i,v){$("#"+v).css({height:"",width:""})}),exists(content_id+"_title")&&(dim.height=$("#"+content_id+"_title").outerHeight(),console.log("Target: %s, Action box Title: %s",target_id,dim.height),new_height+=dim.height??0),exists(content_id+"_header")&&(dim.height=$("#"+content_id+"_header").outerHeight(),console.log("Target: %s, Action box Header: %s",target_id,dim.height),new_height+=dim.height??0),exists(content_id+"_content")&&(content_override>0?(console.log("Target: %s, Action box Content Override: %s",target_id,content_override),new_height+=content_override):(abc_dim.height=$("#"+content_id+"_content").outerHeight(),console.log("Target: %s, Action box Content: %s",target_id,abc_dim.height),new_height+=abc_dim.height??0)),exists(content_id+"_footer")&&(dim.height=$("#"+content_id+"_footer").outerHeight(),console.log("Target: %s, Action box Footer: %s",target_id,dim.height),new_height+=dim.height??0),new_height+=override;var viewport=getWindowSize();if(new_height>=viewport.height){exists(content_id+"_content")&&($("#"+content_id+"_content").hasClass("of-s-y")||$("#"+content_id+"_content").addClass("of-s-y")),console.log("Target: %s, Viewport: %s, ActionBox (NH): %s, ABcontent: %s, ABouter: %s",target_id,viewport.height,new_height,abc_dim.height,$("#"+target_id).outerHeight());var m_height=viewport.height-(new_height-(abc_dim.height??0));console.log("Target: %s, New ABcontent: %s",target_id,m_height),$("#"+content_id+"_content").css("height",m_height+"px"),new_height=new_height-(abc_dim.height??0)+m_height,console.log("Target: %s, New Hight: %s",target_id,new_height)}else exists(content_id+"_content")&&$("#"+content_id+"_content").hasClass("of-s-y")&&$("#"+content_id+"_content").removeClass("of-s-y");console.log("Target: %s, Action Box new height: %s px (override %s px, content override %s px), window height: %s px, Visible Height: %s px",target_id,new_height,override,content_override,viewport.height,$("#"+content_id).outerHeight()),$("#"+target_id).css("height",new_height+"px")}};var LoginNavMenu=class{hec;l10n;constructor(hec2,l10n2){this.hec=hec2,this.l10n=l10n2}createLoginRow(login_string,header_id="mainHeader"){exists(header_id)&&(exists("loginRow")||$("#"+header_id).html(this.hec.phfo(this.hec.cel("div","loginRow","",["loginRow","flx-spbt"]))),$("#loginRow").html(this.hec.phfo(this.hec.cel("div","loginRow-name",login_string))),$("#loginRow").append(this.hec.phfo(this.hec.cel("div","loginRow-info",""))),$("#loginRow").append(this.hec.phfo(this.hec.aelx(this.hec.cel("div","loginRow-logout"),this.hec.cel("input","logout","",[],{value:this.l10n.__("Logout"),type:"button",onClick:"loginLogout()"})))))}createNavMenu(nav_menu,header_id="mainHeader"){if(isObject(nav_menu)&&getObjectCount(nav_menu)>1){exists("menuRow")||$("#"+header_id).html(this.hec.phfo(this.hec.cel("div","menuRow","",["menuRow","flx-s"])));var content=[];$.each(nav_menu,function(key,item){key!=0&&content.push(this.hec.phfo(this.hec.cel("div","","·",["pd-2"]))),item.enabled&&(window.location.href.indexOf(item.url)!=-1&&(item.selected=1),content.push(this.hec.phfo(this.hec.aelx(this.hec.cel("div"),this.hec.cel("a","",item.name,["pd-2"].concat(item.selected?"highlight":""),{href:item.url})))))}),$("#menuRow").html(content.join(""))}else $("#menuRow").hide()}};var aiob=new ActionIndicatorOverlayBox,hec=new HtmlElementCreator,l10n=new l10nTranslation(typeof i18n>"u"?{}:i18n),ab=new ActionBox(hec,l10n),lnm=new LoginNavMenu(hec,l10n);String.prototype.format||(String.prototype.format=function(){return console.error("[DEPRECATED] use StringHelpers.formatString"),formatString(this,arguments)}),Number.prototype.round&&(Number.prototype.round=function(prec){return console.error("[DEPRECATED] use MathHelpers.roundPrecision"),roundPrecision(this,prec)}),String.prototype.escapeHTML||(String.prototype.escapeHTML=function(){return console.error("[DEPRECATED] use HtmlHelpers.escapeHtml"),escapeHtml(this)}),String.prototype.unescapeHTML||(String.prototype.unescapeHTML=function(){return console.error("[DEPRECATED] use HtmlHelpers.unescapeHtml"),unescapeHtml(this)});function escapeHtml2(string){return escapeHtml(string)}function roundPrecision2(number,prec){return roundPrecision(number,prec)}function formatString2(string,...args){return formatString(string,...args)}function unescapeHtml2(string){return unescapeHtml(string)}function loadEl2(el_id){return loadEl(el_id)}function pop2(theURL,winName,features){pop(theURL,winName,features)}function expandTA2(ta_id){expandTA(ta_id)}function getWindowSize2(){return getWindowSize()}function getScrollOffset2(){return getScrollOffset()}function getScrollOffsetOpener2(){return getScrollOffsetOpener()}function setCenter2(id,left,top){setCenter(id,left,top)}function goToPos2(element,offset=0,duration=500,base="body,html"){goToPos(element,offset,duration,base)}function goTo2(target){goTo(target)}function __(string){return l10n.__(string)}function numberWithCommas2(x){return numberWithCommas(x)}function convertLBtoBR2(string){return convertLBtoBR(string)}function getTimestamp2(){return getTimestamp()}function dec2hex2(dec){return dec2hex(dec)}function generateId2(len){return generateId(len)}function randomIdF2(){return randomIdF()}function getRandomIntInclusive2(min,max){return getRandomIntInclusive(min,max)}function isFunction2(name){return isFunction(name)}function executeFunctionByName2(functionName,context){return executeFunctionByName(functionName,context)}function isObject2(val){return isObject(val)}function getObjectCount2(object){return getObjectCount(object)}function keyInObject2(key,object){return keyInObject(key,object)}function getKeyByValue2(object,value){return getKeyByValue(object,value)}function valueInObject2(object,value){return valueInObject(object,value)}function deepCopyFunction2(inObject){return deepCopyFunction(inObject)}function exists2(id){return exists(id)}function formatBytes2(bytes){return formatBytes(bytes)}function formatBytesLong2(bytes){return formatBytesLong(bytes)}function stringByteFormat2(bytes){return stringByteFormat(bytes)}function errorCatch2(err){errorCatch(err)}function actionIndicator2(loc,overlay=!0){actionIndicator(loc,overlay)}function actionIndicatorShow2(loc,overlay=!0){actionIndicatorShow(loc,overlay)}function actionIndicatorHide2(loc,overlay=!0){actionIndicatorHide(loc,overlay)}function overlayBoxShow2(){overlayBoxShow()}function overlayBoxHide2(){overlayBoxHide()}function setOverlayBox2(){setOverlayBox()}function hideOverlayBox2(){hideOverlayBox()}function ClearCall2(){ClearCall()}function showActionIndicator(loc){aiob.showActionIndicator(loc)}function hideActionIndicator(loc){aiob.hideActionIndicator(loc)}function checkOverlayExists(){aiob.checkOverlayExists()}function showOverlayBoxLayers(el_id){aiob.showOverlayBoxLayers(el_id)}function hideOverlayBoxLayers(el_id=""){aiob.hideOverlayBoxLayers(el_id)}function clearCallActionBox(){aiob.clearCallActionBox()}function cel(tag,id="",content="",css=[],options={}){return hec.cel(tag,id,content,css,options)}function ael(base,attach,id=""){return hec.ael(base,attach,id)}function aelx(base,...attach){return hec.aelx(base,...attach)}function aelxar(base,attach){return hec.aelxar(base,attach)}function rel(base){return hec.rel(base)}function rcssel(_element,css){return hec.rcssel(_element,css)}function acssel(_element,css){return hec.acssel(_element,css)}function scssel(_element,rcss,acss){hec.scssel(_element,rcss,acss)}function phfo(tree){return hec.phfo(tree)}function phfa(list){return hec.phfa(list)}function html_options2(name,data,selected="",options_only=!1,return_string=!1,sort=""){return html_options(name,data,selected,options_only,return_string,sort)}function html_options_block2(name,data,selected="",multiple=0,options_only=!1,return_string=!1,sort="",onchange=""){return html_options_block(name,data,selected,multiple,options_only,return_string,sort,onchange)}function html_options_refill2(name,data,sort=""){html_options_refill(name,data,sort)}function parseQueryString2(query="",return_key="",single=!1){return parseQueryString(query,return_key,single)}function getQueryStringParam2(search="",query="",single=!1){return getQueryStringParam(search,query,single)}function updateUrlParameter2(key,value,reload=!1){return updateUrlParameter(key,value,reload)}function removeUrlParameter2(key,reload=!1){return removeUrlParameter(key,reload)}function hasUrlParameter2(key){return hasUrlParameter(key)}function getUrlParameter2(key){return getUrlParameter(key)}function loginLogout2(){loginLogout()}function createLoginRow(login_string,header_id="mainHeader"){lnm.createLoginRow(login_string,header_id)}function createNavMenu(nav_menu,header_id="mainHeader"){lnm.createNavMenu(nav_menu,header_id)}function showFillActionBox(target_id="actionBox",content="",action_box_css=[],override=0,content_override=0){ab.showFillActionBox(target_id,content,action_box_css,override,content_override)}function fillActionBox(target_id="actionBox",content="",action_box_css=[]){ab.fillActionBox(target_id,content,action_box_css)}function adjustActionBox(target_id="actionBox",override=0,content_override=0){ab.adjustActionBox(target_id,override,content_override)}function hideAllActionBoxes(){ab.hideAllActionBoxes()}function hideActionBox(target_id="actionBox"){ab.hideActionBox(target_id)}function showActionBox(target_id="actionBox",override=0,content_override=0,hide_all=!0){ab.showActionBox(target_id,override,content_override,hide_all)}function closeActionBox(target_id="actionBox",clean=!0){ab.closeActionBox(target_id,clean)}function showActionBoxFloat(target_id="actionBox",override=0,content_override=0,hide_all=!1){ab.showActionBoxFloat(target_id,override,content_override,hide_all)}function closeActionBoxFloat(target_id="actionBox",clean=!0){ab.closeActionBoxFloat(target_id,clean)}function createActionBox(target_id="actionBox",title="",contents={},headers={},settings={},show_close=!0){ab.createActionBox(target_id,title,contents,headers,settings,show_close)}function adjustActionBoxHeight(target_id="actionBox",override=0,content_override=0){ab.adjustActionBoxHeight(target_id,override,content_override)} +function errorCatch(err){err.stack?err.lineNumber?console.error("ERROR[%s:%s] ",err.name,err.lineNumber,err):err.line?console.error("ERROR[%s:%s] ",err.name,err.line,err):console.error("ERROR[%s] ",err.name,err):err.number?(console.error("ERROR[%s:%s] %s",err.name,err.number,err.message),console.error("ERROR[description] %s",err.description)):console.error("ERROR[%s] %s",err.name,err.message)}function isFunction(name){return typeof window[name]<"u"&&typeof window[name]=="function"}function executeFunctionByName(functionName,context){var args=Array.prototype.slice.call(arguments,2),namespaces=functionName.split("."),func=namespaces.pop();if(func==null)throw new Error("Cannot get function from namespaces: "+functionName);for(var i=0;iobject[key]===value)??""}function valueInObject(object,value){return objectValueExists(object,value)}function objectValueExists(object,value){return!!Object.keys(object).find(key=>object[key]===value)}function deepCopyFunction(inObject){var outObject,value,key;if(typeof inObject!="object"||inObject===null)return inObject;outObject=Array.isArray(inObject)?[]:{};for(key in inObject)value=inObject[key],outObject[key]=deepCopyFunction(value);return outObject}function loadEl(el_id){let el=document.getElementById(el_id);if(el===null)throw new Error("Cannot find: "+el_id);return el}function pop(theURL,winName,features){let __winName=window.open(theURL,winName,features);__winName?.focus()}function expandTA(ta_id){let ta=this.loadEl(ta_id);if(ta instanceof HTMLElement&&ta.getAttribute("type")!=="textarea")throw new Error("Element is not a textarea: "+ta_id);let maxChars=parseInt(ta.getAttribute("cols")??"0"),ta_value=ta.getAttribute("value"),theRows=[];ta_value!=null&&(theRows=ta_value.split(` +`));for(var numNewRows=0,i=0;imaxChars&&(numNewRows+=Math.ceil((theRows[i].length+2)/maxChars));ta.setAttribute("row",(numNewRows+theRows.length).toString())}function exists(id){return $("#"+id).length>0}var HtmlElementCreator=class{cel(tag,id="",content="",css=[],options={}){return{tag,id,name:options.name,content,css,options,sub:[]}}ael(base,attach,id=""){if(id){if(base.id==id)base.sub.push(deepCopyFunction(attach));else if(isArray(base.sub)&&base.sub.length>0)for(var i=0;i-1&&_element.css.splice(css_index,1),_element}acssel(_element,css){var css_index=_element.css.indexOf(css);return css_index==-1&&_element.css.push(css),_element}scssel(_element,rcss,acss){return this.rcssel(_element,rcss),this.acssel(_element,acss),_element}phfo(tree){let name_elements=["button","fieldset","form","iframe","input","map","meta","object","output","param","select","textarea"],skip_options=["id","name","class"],no_close=["input","br","img","hr","area","col","keygen","wbr","track","source","param","command","base","meta","link","embed"];var content=[],line="<"+tree.tag,i;if(tree.id&&(line+=' id="'+tree.id+'"',name_elements.includes(tree.tag)&&(line+=' name="'+(tree.name?tree.name:tree.id)+'"')),isArray(tree.css)&&tree.css.length>0){for(line+=' class="',i=0;i0)for(tree.content&&content.push(tree.content),i=0;i"),content.join("")}phfa(list){for(var content=[],i=0;i"'/]/g,function(s){var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return entityMap[s]})}function unescapeHtml(string){return string.replace(/&[#\w]+;/g,function(s){var entityMap={"&":"&","<":"<",">":">",""":'"',"'":"'","/":"/"};return entityMap[s]})}function html_options(name,data,selected="",options_only=!1,return_string=!1,sort=""){return this.html_options_block(name,data,selected,0,options_only,return_string,sort)}function html_options_block(name,data,selected="",multiple=0,options_only=!1,return_string=!1,sort="",onchange=""){var content=[],element_select,select_options={},element_option,data_list=[],value,options={};multiple>0&&(select_options.multiple="",multiple>1&&(select_options.size=multiple)),onchange&&(select_options.OnChange=onchange),element_select=dom.cel("select",name,"",[],select_options),sort=="keys"?data_list=Object.keys(data).sort():sort=="values"?data_list=Object.keys(data).sort((a,b)=>(""+data[a]).localeCompare(data[b])):data_list=Object.keys(data);for(let key of data_list)value=data[key],options={label:value,value:key,selected:""},multiple==0&&!Array.isArray(selected)&&selected==key&&(options.selected=""),multiple==1&&Array.isArray(selected)&&selected.indexOf(key)!=-1&&(options.selected=""),element_option=dom.cel("option","",value,[],options),dom.ael(element_select,element_option);if(options_only)if(return_string){for(var i=0;i(""+data[a]).localeCompare(data[b])):data_list=Object.keys(data),[].forEach.call(document.querySelectorAll("#"+name+" :checked"),function(elm){option_selected=elm.value}),loadEl(name).innerHTML="";for(let key of data_list)value=data[key],element_option=document.createElement("option"),element_option.label=value,element_option.value=key,element_option.innerHTML=value,key==option_selected&&(element_option.selected=!0),loadEl(name).appendChild(element_option)}}function dec2hex(dec){return("0x"+dec.toString(16)).substring(-2)}function getRandomIntInclusive(min,max){return min=Math.ceil(min),max=Math.floor(max),Math.floor(Math.random()*(max-min+1)+min)}function roundPrecision(number,precision){return isNaN(number)||isNaN(precision)?number:Math.round(number*Math.pow(10,precision))/Math.pow(10,precision)}function formatString(string,...args){return string.replace(/{(\d+)}/g,function(match,number){return typeof args[number]<"u"?args[number]:match})}function numberWithCommas(number){var parts=number.toString().split(".");return parts[0]=parts[0].replace(/\B(?=(\d{3})+(?!\d))/g,","),parts.join(".")}function convertLBtoBR(string){return string.replace(/(?:\r\n|\r|\n)/g,"
")}function getTimestamp(){var date=new Date;return date.getTime()}function generateId(len){var arr=new Uint8Array((len||40)/2);return(window.crypto||window.msCrypto).getRandomValues(arr),Array.from(arr,self.dec2hex).join("")}function randomIdF(){return Math.random().toString(36).substring(2)}function getWindowSize(){var width,height;return width=window.innerWidth||window.document.documentElement.clientWidth||window.document.body.clientWidth,height=window.innerHeight||window.document.documentElement.clientHeight||window.document.body.clientHeight,{width,height}}function getScrollOffset(){var left,top;return left=window.pageXOffset||window.document.documentElement.scrollLeft||window.document.body.scrollLeft,top=window.pageYOffset||window.document.documentElement.scrollTop||window.document.body.scrollTop,{left,top}}function getScrollOffsetOpener(){var left,top;return left=opener.window.pageXOffset||opener.document.documentElement.scrollLeft||opener.document.body.scrollLeft,top=opener.window.pageYOffset||opener.document.documentElement.scrollTop||opener.document.body.scrollTop,{left,top}}function setCenter(id,left,top){var dimensions={height:$("#"+id).height()??0,width:$("#"+id).width()??0},type=$("#"+id).css("position"),viewport=this.getWindowSize(),offset=this.getScrollOffset();if(left&&$("#"+id).css({left:viewport.width/2-dimensions.width/2+offset.left+"px"}),top){var top_pos=type=="fixed"?viewport.height/2-dimensions.height/2:viewport.height/2-dimensions.height/2+offset.top;$("#"+id).css({top:top_pos+"px"})}}function goToPos(element,offset=0,duration=500,base="body,html"){try{let element_offset=$("#"+element).offset();if(element_offset==null)return;$("#"+element).length&&$(base).animate({scrollTop:element_offset.top-offset},duration)}catch(err){errorCatch(err)}}function goTo(target){loadEl(target).scrollIntoView({behavior:"smooth"})}function formatBytes(bytes){var i=-1;if(typeof bytes=="bigint"&&(bytes=Number(bytes)),isNaN(bytes))return bytes.toString();do bytes=bytes/1024,i++;while(bytes>99);return Math.round(bytes*Math.pow(10,2))/Math.pow(10,2)+["kB","MB","GB","TB","PB","EB"][i]}function formatBytesLong(bytes){if(typeof bytes=="bigint"&&(bytes=Number(bytes)),isNaN(bytes))return bytes.toString();let negative=!1;bytes<0&&(negative=!0,bytes*=-1);var i=Math.floor(Math.log(bytes)/Math.log(1024)),sizes=["B","KB","MB","GB","TB","PB","EB","ZB","YB"];return(negative?"-":"")+((bytes/Math.pow(1024,i)).toFixed(2)+" "+sizes[i]).toString()}function stringByteFormat(bytes,raw=!1){if(!(typeof bytes=="string"||bytes instanceof String))return bytes.toString();let valid_units="bkmgtpezy",regex=/([\d.,]*)\s?(eb|pb|tb|gb|mb|kb|e|p|t|g|m|k|b)$/i,matches=bytes.match(regex);if(matches!==null){let m1=parseFloat(matches[1].replace(/[^0-9.]/,"")),m2=matches[2].replace(/[^bkmgtpezy]/i,"").charAt(0).toLowerCase();m2&&(bytes=m1*Math.pow(1024,valid_units.indexOf(m2)))}return raw?bytes:Math.round(bytes)}function parseQueryString(query="",return_key="",single=!1){return getQueryStringParam(return_key,query,single)}function getQueryStringParam(search="",query="",single=!1){query||(query=window.location.href);let url=new URL(query),param=null;if(search){let _params=url.searchParams.getAll(search);_params.length==1||single===!0?param=_params[0]:_params.length>1&&(param=_params)}else{param={};for(let[key]of url.searchParams.entries())if(typeof param[key]>"u"){let _params=url.searchParams.getAll(key);param[key]=_params.length<2||single===!0?_params[0]:_params}}return param}function hasUrlParameter(key){var urlParams=new URLSearchParams(window.location.search);return urlParams.has(key)}function getUrlParameter(key){var urlParams=new URLSearchParams(window.location.search);return urlParams.get(key)}function updateUrlParameter(key,value,reload=!1){let url=new URL(window.location.href);url.searchParams.set(key,value);let newUrl=url.toString();window.history.pushState({path:newUrl},"",newUrl),reload&&window.location.reload()}function removeUrlParameter(key,reload=!1){let url=new URL(window.location.href);url.searchParams.delete(key),window.history.pushState({},"",url.toString()),reload&&window.location.reload()}function loginLogout(){let form=document.createElement("form");form.method="post";let hiddenField=document.createElement("input");hiddenField.type="hidden",hiddenField.name="login_logout",hiddenField.value="Logout",form.appendChild(hiddenField),document.body.appendChild(form),form.submit()}function actionIndicator(loc,overlay=!0){$("#indicator").is(":visible")?this.actionIndicatorHide(loc,overlay):this.actionIndicatorShow(loc,overlay)}function actionIndicatorShow(loc,overlay=!0){$("#indicator").is(":visible")||($("#indicator").hasClass("progress")||$("#indicator").addClass("progress"),setCenter("indicator",!0,!0),$("#indicator").show()),overlay===!0&&this.overlayBoxShow()}function actionIndicatorHide(loc,overlay=!0){$("#indicator").hide(),overlay===!0&&overlayBoxHide()}function overlayBoxShow(){$("#overlayBox").is(":visible")?$("#overlayBox").css("zIndex","100"):($("#overlayBox").show(),$("#overlayBox").css("zIndex","98"))}function overlayBoxHide(){parseInt($("#overlayBox").css("zIndex"))>=100?$("#overlayBox").css("zIndex","98"):$("#overlayBox").hide()}function setOverlayBox(){$("#overlayBox").is(":visible")||$("#overlayBox").show()}function hideOverlayBox(){$("#overlayBox").is(":visible")&&$("#overlayBox").hide()}function ClearCall(){$("#actionBox").html(""),$("#actionBox").hide(),$("#overlayBox").hide()}var ActionIndicatorOverlayBox=class{#GL_OB_S=100;#GL_OB_BASE=100;showActionIndicator(loc){if($("#indicator").length==0){var el=document.createElement("div");el.className="progress hide",el.id="indicator",$("body").append(el)}else $("#indicator").hasClass("progress")||$("#indicator").addClass("progress").hide();$("#indicator").is(":visible")||(this.checkOverlayExists(),$("#overlayBox").is(":visible")||$("#overlayBox").show(),$("#overlayBox").css("zIndex",1e3),$("#indicator").show(),setCenter("indicator",!0,!0))}hideActionIndicator(loc){$("#indicator").is(":visible")&&($("#indicator").hide(),this.#GL_OB_S>this.#GL_OB_BASE?$("#overlayBox").css("zIndex",this.#GL_OB_S):($("#overlayBox").hide(),$("#overlayBox").css("zIndex",this.#GL_OB_BASE)))}checkOverlayExists(){if($("#overlayBox").length==0){var el=document.createElement("div");el.className="overlayBoxElement hide",el.id="overlayBox",$("body").append(el)}}showOverlayBoxLayers(el_id){$("#overlayBox").is(":visible")||($("#overlayBox").show(),$("#overlayBox").css("zIndex",this.#GL_OB_BASE),this.#GL_OB_S=this.#GL_OB_BASE),this.#GL_OB_S++,$("#overlayBox").css("zIndex",this.#GL_OB_S),el_id&&$("#"+el_id).length>0&&($("#"+el_id).css("zIndex",this.#GL_OB_S+1),$("#"+el_id).show())}hideOverlayBoxLayers(el_id=""){this.#GL_OB_S--,this.#GL_OB_S<=this.#GL_OB_BASE?(this.#GL_OB_S=this.#GL_OB_BASE,$("#overlayBox").hide(),$("#overlayBox").css("zIndex",this.#GL_OB_BASE)):$("#overlayBox").css("zIndex",this.#GL_OB_S),el_id&&($("#"+el_id).hide(),$("#"+el_id).css("zIndex",0))}clearCallActionBox(){$("#actionBox").html(""),$("#actionBox").hide(),this.hideOverlayBoxLayers()}};var l10nTranslation=class{#i18n={};constructor(i18n2){this.#i18n=i18n2}__(string){return typeof this.#i18n<"u"&&isObject(this.#i18n)&&this.#i18n[string]?this.#i18n[string]:string}};var ActionBox=class{zIndex={base:100,max:110,indicator:0,boxes:{},active:[],top:""};action_box_storage={};action_box_cache_timeout=600*1e3;hec;l10n;constructor(hec2,l10n2){this.hec=hec2,this.l10n=l10n2}showFillActionBox(target_id="actionBox",content="",action_box_css=[],override=0,content_override=0){this.fillActionBox(target_id,content,action_box_css),this.showActionBox(target_id,override,content_override)}fillActionBox(target_id="actionBox",content="",action_box_css=[]){exists(target_id)||$("#mainContainer").after(this.hec.phfo(this.hec.cel("div",target_id,"",["actionBoxElement","hide"].concat(action_box_css)))),$("#"+target_id).html(content)}adjustActionBox(target_id="actionBox",override=0,content_override=0){this.adjustActionBoxHeight(target_id,override,content_override),setCenter(target_id,!0,!0)}hideAllActionBoxes(){$('#actionBox, div[id^="actionBox-"].actionBoxElement').hide(),$("#overlayBox").hide()}hideActionBox(target_id="actionBox"){this.closeActionBoxFloat(target_id,!1)}showActionBox(target_id="actionBox",override=0,content_override=0,hide_all=!0){this.showActionBoxFloat(target_id,override,content_override,hide_all)}closeActionBox(target_id="actionBox",clean=!0){this.closeActionBoxFloat(target_id,clean)}showActionBoxFloat(target_id="actionBox",override=0,content_override=0,hide_all=!1){hide_all===!0&&this.hideAllActionBoxes(),exists("overlayBox")||($("body").prepend(this.hec.phfo(this.hec.cel("div","overlayBox","",["overlayBoxElement"]))),$("#overlayBox").css("zIndex",this.zIndex.base)),$("#overlayBox").show(),objectKeyExists(this.zIndex.boxes,target_id)?this.zIndex.boxes[target_id]+10({id:el.id,zIndex:$("#"+el.id).css("zIndex")})).get();if(visible_zIndexes.length>0){let max_zIndex=0,max_el_id="";for(let zIndex_el of visible_zIndexes)parseInt(zIndex_el.zIndex)>max_zIndex&&(max_zIndex=parseInt(zIndex_el.zIndex),max_el_id=zIndex_el.id);$("#overlayBox").css("zIndex",max_zIndex-1),this.zIndex.top=max_el_id}else $("#overlayBox").hide()}createActionBox(target_id="actionBox",title="",contents={},headers={},settings={},show_close=!0){objectKeyExists(this.action_box_storage,target_id)||(this.action_box_storage[target_id]={});let header_css=[];objectKeyExists(settings,"header_css")&&(header_css=settings.header_css);let action_box_css=[];objectKeyExists(settings,"action_box_css")&&(action_box_css=settings.action_box_css);let elements=[];elements.push(this.hec.phfo(this.hec.aelx(this.hec.cel("div",target_id+"_title","",["actionBoxTitle","flx-spbt"].concat(header_css)),...show_close===!0?[this.hec.cel("div","",title,["fs-b","w-80"]),this.hec.aelx(this.hec.cel("div",target_id+"_title_close_button","",["w-20","tar"]),this.hec.cel("input",target_id+"_title_close","",["button-close","fs-s"],{type:"button",value:this.l10n.__("Close"),OnClick:"closeActionBox('"+target_id+"', false);"}))]:[this.hec.cel("div","",title,["fs-b","w-100"])]))),getObjectCount(headers)>0&&(objectKeyExists(headers,"raw_string")?elements.push(headers.raw_string):elements.push(this.hec.phfo(headers))),getObjectCount(contents)>0?objectKeyExists(contents,"raw_string")?elements.push(contents.raw_string):elements.push(this.hec.phfo(contents)):elements.push(this.hec.phfo(this.hec.cel("div",target_id+"_content","",[]))),elements.push(this.hec.phfo(this.hec.aelx(this.hec.cel("div",target_id+"_footer","",["pd-5","flx-spbt"]),...show_close===!0?[this.hec.cel("div","","",["fs-b","w-80"]),this.hec.aelx(this.hec.cel("div",target_id+"_footer_close_button","",["tar","w-20"]),this.hec.cel("input",target_id+"_footer_close","",["button-close","fs-s"],{type:"button",value:this.l10n.__("Close"),OnClick:"closeActionBox('"+target_id+"', false);"}))]:[this.hec.cel("div","","",["fs-b","w-100"])]))),elements.push(this.hec.phfo(this.hec.cel("input",target_id+"-cache_time","",[],{type:"hidden",value:Date.now()}))),this.fillActionBox(target_id,elements.join(""),action_box_css)}adjustActionBoxHeight(target_id="actionBox",override=0,content_override=0){var new_height=0,dim={},abc_dim={},content_id="";switch(isNaN(override)&&(override=0),isNaN(content_override)&&(content_override=0),target_id){case"actionBox":content_id="action_box";break;case"actionBoxSub":content_id="action_box_sub";break;default:content_id=target_id;break}$.each([target_id,content_id+"_content"],function(i,v){$("#"+v).css({height:"",width:""})}),exists(content_id+"_title")&&(dim.height=$("#"+content_id+"_title").outerHeight(),console.log("Target: %s, Action box Title: %s",target_id,dim.height),new_height+=dim.height??0),exists(content_id+"_header")&&(dim.height=$("#"+content_id+"_header").outerHeight(),console.log("Target: %s, Action box Header: %s",target_id,dim.height),new_height+=dim.height??0),exists(content_id+"_content")&&(content_override>0?(console.log("Target: %s, Action box Content Override: %s",target_id,content_override),new_height+=content_override):(abc_dim.height=$("#"+content_id+"_content").outerHeight(),console.log("Target: %s, Action box Content: %s",target_id,abc_dim.height),new_height+=abc_dim.height??0)),exists(content_id+"_footer")&&(dim.height=$("#"+content_id+"_footer").outerHeight(),console.log("Target: %s, Action box Footer: %s",target_id,dim.height),new_height+=dim.height??0),new_height+=override;var viewport=getWindowSize();if(new_height>=viewport.height){exists(content_id+"_content")&&($("#"+content_id+"_content").hasClass("of-s-y")||$("#"+content_id+"_content").addClass("of-s-y")),console.log("Target: %s, Viewport: %s, ActionBox (NH): %s, ABcontent: %s, ABouter: %s",target_id,viewport.height,new_height,abc_dim.height,$("#"+target_id).outerHeight());var m_height=viewport.height-(new_height-(abc_dim.height??0));console.log("Target: %s, New ABcontent: %s",target_id,m_height),$("#"+content_id+"_content").css("height",m_height+"px"),new_height=new_height-(abc_dim.height??0)+m_height,console.log("Target: %s, New Hight: %s",target_id,new_height)}else exists(content_id+"_content")&&$("#"+content_id+"_content").hasClass("of-s-y")&&$("#"+content_id+"_content").removeClass("of-s-y");console.log("Target: %s, Action Box new height: %s px (override %s px, content override %s px), window height: %s px, Visible Height: %s px",target_id,new_height,override,content_override,viewport.height,$("#"+content_id).outerHeight()),$("#"+target_id).css("height",new_height+"px")}};var LoginNavMenu=class{hec;l10n;constructor(hec2,l10n2){this.hec=hec2,this.l10n=l10n2}createLoginRow(login_string,header_id="mainHeader"){exists(header_id)&&(exists("loginRow")||$("#"+header_id).html(this.hec.phfo(this.hec.cel("div","loginRow","",["loginRow","flx-spbt"]))),$("#loginRow").html(this.hec.phfo(this.hec.cel("div","loginRow-name",login_string))),$("#loginRow").append(this.hec.phfo(this.hec.cel("div","loginRow-info",""))),$("#loginRow").append(this.hec.phfo(this.hec.aelx(this.hec.cel("div","loginRow-logout"),this.hec.cel("input","logout","",[],{value:this.l10n.__("Logout"),type:"button",onClick:"loginLogout()"})))))}createNavMenu(nav_menu,header_id="mainHeader"){if(isObject(nav_menu)&&getObjectCount(nav_menu)>1){exists("menuRow")||$("#"+header_id).html(this.hec.phfo(this.hec.cel("div","menuRow","",["menuRow","flx-s"])));var content=[];$.each(nav_menu,function(key,item){key!=0&&content.push(this.hec.phfo(this.hec.cel("div","","·",["pd-2"]))),item.enabled&&(window.location.href.indexOf(item.url)!=-1&&(item.selected=1),content.push(this.hec.phfo(this.hec.aelx(this.hec.cel("div"),this.hec.cel("a","",item.name,["pd-2"].concat(item.selected?"highlight":""),{href:item.url})))))}),$("#menuRow").html(content.join(""))}else $("#menuRow").hide()}};function isWebkit(){return"GestureEvent"in window}function isMobileWebKit(){return"ongesturechange"in window}function isDesktopWebKit(){return typeof window<"u"&&"safari"in window&&"pushNotification"in window.safari}var aiob=new ActionIndicatorOverlayBox,hec=new HtmlElementCreator,l10n=new l10nTranslation(typeof i18n>"u"?{}:i18n),ab=new ActionBox(hec,l10n),lnm=new LoginNavMenu(hec,l10n);String.prototype.format||(String.prototype.format=function(){return console.error("[DEPRECATED] use StringHelpers.formatString"),formatString(this,arguments)}),Number.prototype.round&&(Number.prototype.round=function(prec){return console.error("[DEPRECATED] use MathHelpers.roundPrecision"),roundPrecision(this,prec)}),String.prototype.escapeHTML||(String.prototype.escapeHTML=function(){return console.error("[DEPRECATED] use HtmlHelpers.escapeHtml"),escapeHtml(this)}),String.prototype.unescapeHTML||(String.prototype.unescapeHTML=function(){return console.error("[DEPRECATED] use HtmlHelpers.unescapeHtml"),unescapeHtml(this)});function escapeHtml2(string){return escapeHtml(string)}function roundPrecision2(number,prec){return roundPrecision(number,prec)}function formatString2(string,...args){return formatString(string,...args)}function unescapeHtml2(string){return unescapeHtml(string)}function loadEl2(el_id){return loadEl(el_id)}function pop2(theURL,winName,features){pop(theURL,winName,features)}function expandTA2(ta_id){expandTA(ta_id)}function getWindowSize2(){return getWindowSize()}function getScrollOffset2(){return getScrollOffset()}function getScrollOffsetOpener2(){return getScrollOffsetOpener()}function setCenter2(id,left,top){setCenter(id,left,top)}function goToPos2(element,offset=0,duration=500,base="body,html"){goToPos(element,offset,duration,base)}function goTo2(target){goTo(target)}function __(string){return l10n.__(string)}function numberWithCommas2(x){return numberWithCommas(x)}function convertLBtoBR2(string){return convertLBtoBR(string)}function getTimestamp2(){return getTimestamp()}function dec2hex2(dec){return dec2hex(dec)}function generateId2(len){return generateId(len)}function randomIdF2(){return randomIdF()}function getRandomIntInclusive2(min,max){return getRandomIntInclusive(min,max)}function isFunction2(name){return isFunction(name)}function executeFunctionByName2(functionName,context){return executeFunctionByName(functionName,context)}function isObject2(val){return isObject(val)}function isArray2(val){return isArray(val)}function isIterable2(val){return isIterable(val)}function getObjectCount2(object){return getObjectCount(object)}function keyInObject2(key,object){return keyInObject(key,object)}function getKeyByValue2(object,value){return getKeyByValue(object,value)}function valueInObject2(object,value){return valueInObject(object,value)}function deepCopyFunction2(inObject){return deepCopyFunction(inObject)}function exists2(id){return exists(id)}function formatBytes2(bytes){return formatBytes(bytes)}function formatBytesLong2(bytes){return formatBytesLong(bytes)}function stringByteFormat2(bytes){return stringByteFormat(bytes)}function errorCatch2(err){errorCatch(err)}function actionIndicator2(loc,overlay=!0){actionIndicator(loc,overlay)}function actionIndicatorShow2(loc,overlay=!0){actionIndicatorShow(loc,overlay)}function actionIndicatorHide2(loc,overlay=!0){actionIndicatorHide(loc,overlay)}function overlayBoxShow2(){overlayBoxShow()}function overlayBoxHide2(){overlayBoxHide()}function setOverlayBox2(){setOverlayBox()}function hideOverlayBox2(){hideOverlayBox()}function ClearCall2(){ClearCall()}function showActionIndicator(loc){aiob.showActionIndicator(loc)}function hideActionIndicator(loc){aiob.hideActionIndicator(loc)}function checkOverlayExists(){aiob.checkOverlayExists()}function showOverlayBoxLayers(el_id){aiob.showOverlayBoxLayers(el_id)}function hideOverlayBoxLayers(el_id=""){aiob.hideOverlayBoxLayers(el_id)}function clearCallActionBox(){aiob.clearCallActionBox()}function cel(tag,id="",content="",css=[],options={}){return hec.cel(tag,id,content,css,options)}function ael(base,attach,id=""){return hec.ael(base,attach,id)}function aelx(base,...attach){return hec.aelx(base,...attach)}function aelxar(base,attach){return hec.aelxar(base,attach)}function rel(base){return hec.rel(base)}function rcssel(_element,css){return hec.rcssel(_element,css)}function acssel(_element,css){return hec.acssel(_element,css)}function scssel(_element,rcss,acss){hec.scssel(_element,rcss,acss)}function phfo(tree){return hec.phfo(tree)}function phfa(list){return hec.phfa(list)}function html_options2(name,data,selected="",options_only=!1,return_string=!1,sort=""){return html_options(name,data,selected,options_only,return_string,sort)}function html_options_block2(name,data,selected="",multiple=0,options_only=!1,return_string=!1,sort="",onchange=""){return html_options_block(name,data,selected,multiple,options_only,return_string,sort,onchange)}function html_options_refill2(name,data,sort=""){html_options_refill(name,data,sort)}function parseQueryString2(query="",return_key="",single=!1){return parseQueryString(query,return_key,single)}function getQueryStringParam2(search="",query="",single=!1){return getQueryStringParam(search,query,single)}function updateUrlParameter2(key,value,reload=!1){return updateUrlParameter(key,value,reload)}function removeUrlParameter2(key,reload=!1){return removeUrlParameter(key,reload)}function hasUrlParameter2(key){return hasUrlParameter(key)}function getUrlParameter2(key){return getUrlParameter(key)}function loginLogout2(){loginLogout()}function createLoginRow(login_string,header_id="mainHeader"){lnm.createLoginRow(login_string,header_id)}function createNavMenu(nav_menu,header_id="mainHeader"){lnm.createNavMenu(nav_menu,header_id)}function showFillActionBox(target_id="actionBox",content="",action_box_css=[],override=0,content_override=0){ab.showFillActionBox(target_id,content,action_box_css,override,content_override)}function fillActionBox(target_id="actionBox",content="",action_box_css=[]){ab.fillActionBox(target_id,content,action_box_css)}function adjustActionBox(target_id="actionBox",override=0,content_override=0){ab.adjustActionBox(target_id,override,content_override)}function hideAllActionBoxes(){ab.hideAllActionBoxes()}function hideActionBox(target_id="actionBox"){ab.hideActionBox(target_id)}function showActionBox(target_id="actionBox",override=0,content_override=0,hide_all=!0){ab.showActionBox(target_id,override,content_override,hide_all)}function closeActionBox(target_id="actionBox",clean=!0){ab.closeActionBox(target_id,clean)}function showActionBoxFloat(target_id="actionBox",override=0,content_override=0,hide_all=!1){ab.showActionBoxFloat(target_id,override,content_override,hide_all)}function closeActionBoxFloat(target_id="actionBox",clean=!0){ab.closeActionBoxFloat(target_id,clean)}function createActionBox(target_id="actionBox",title="",contents={},headers={},settings={},show_close=!0){ab.createActionBox(target_id,title,contents,headers,settings,show_close)}function adjustActionBoxHeight(target_id="actionBox",override=0,content_override=0){ab.adjustActionBoxHeight(target_id,override,content_override)}function isWebkit2(){return isWebkit()}function isMobileWebKit2(){return isMobileWebKit()}function isDesktopWebKit2(){return isDesktopWebKit()} //# sourceMappingURL=utils.min.js.map diff --git a/www/admin/layout/javascript/utils.min.js.map b/www/admin/layout/javascript/utils.min.js.map index b31f6436..637093f0 100644 --- a/www/admin/layout/javascript/utils.min.js.map +++ b/www/admin/layout/javascript/utils.min.js.map @@ -1,7 +1,7 @@ { "version": 3, - "sources": ["../../../src/utils/JavaScriptHelpers.mjs", "../../../src/utils/DomHelpers.mjs", "../../../src/utils/HtmlElementCreator.mjs", "../../../src/utils/HtmlHelpers.mjs", "../../../src/utils/MathHelpers.mjs", "../../../src/utils/StringHelpers.mjs", "../../../src/utils/DateTimeHelpers.mjs", "../../../src/utils/UniqIdGenerators.mjs", "../../../src/utils/ResizingAndMove.mjs", "../../../src/utils/FormatBytes.mjs", "../../../src/utils/UrlParser.mjs", "../../../src/utils/LoginLogout.mjs", "../../../src/utils/ActionIndicatorOverlayBox.mjs", "../../../src/utils/l10nTranslation.mjs", "../../../src/utils/ActionBox.mjs", "../../../src/utils/LoginNavMenu.mjs", "../../../src/utils.mjs"], - "sourcesContent": ["/*\nDescription: JavaScript Helpers\nDate: 2025//3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport {\n\terrorCatch, isFunction,\n\texecuteFunctionByName, runFunction, runFunctionArgsArray,\n\tisObject, getObjectCount,\n\tkeyInObject, objectKeyExists,\n\tgetKeyByValue, valueInObject, objectValueExists,\n\tdeepCopyFunction\n};\n\n/**\n * prints out error messages based on data available from the browser\n * @param {Object} err error from try/catch block\n */\nfunction errorCatch(err)\n{\n\t// for FF & Chrome\n\tif (err.stack) {\n\t\t// only FF\n\t\tif (err.lineNumber) {\n\t\t\tconsole.error('ERROR[%s:%s] ', err.name, err.lineNumber, err);\n\t\t} else if (err.line) {\n\t\t\t// only Safari\n\t\t\tconsole.error('ERROR[%s:%s] ', err.name, err.line, err);\n\t\t} else {\n\t\t\tconsole.error('ERROR[%s] ', err.name, err);\n\t\t}\n\t} else if (err.number) {\n\t\t// IE\n\t\tconsole.error('ERROR[%s:%s] %s', err.name, err.number, err.message);\n\t\tconsole.error('ERROR[description] %s', err.description);\n\t} else {\n\t\t// the rest\n\t\tconsole.error('ERROR[%s] %s', err.name, err.message);\n\t}\n}\n\n/**\n * check if name is a function\n * @param {string} name Name of function to check if exists\n * @return {Boolean} true/false\n */\nfunction isFunction(name)\n{\n\tif (typeof window[name] !== 'undefined' &&\n\t\ttypeof window[name] === 'function') {\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n}\n\n/**\n * call a function by its string name\n * https://stackoverflow.com/a/359910\n * example: executeFunctionByName(\"My.Namespace.functionName\", window, arguments);\n * @param {string} functionName The function name or namespace + function\n * @param {any} context context (window or first namespace)\n * hidden next are all the arguments\n * @return {any} Return values from functon\n */\nfunction executeFunctionByName(functionName, context /*, args */)\n{\n\tvar args = Array.prototype.slice.call(arguments, 2);\n\tvar namespaces = functionName.split('.');\n\tvar func = namespaces.pop();\n\tif (func == undefined) {\n\t\tthrow new Error(\"Cannot get function from namespaces: \" + functionName);\n\t}\n\tfor (var i = 0; i < namespaces.length; i++) {\n\t\tcontext = context[namespaces[i]];\n\t}\n\treturn context[func].apply(context, args);\n}\n\n/**\n * call a function by string\n * call runFunctionArgArray\n * @param {string} name Function name to call\n * @param {Array} arguments all next function arguments are passed on as argument to the function\n * @returns void\n */\nfunction runFunction(name)\n{\n\tvar args = Array.prototype.slice.call(arguments, 1);\n\trunFunctionArgsArray(name, args);\n}\n\n/**\n * call a function with a string, argumens as array\n * @param {string} name Function name to call\n * @param {array} args function arguments as arry\n * @returns void\n */\nfunction runFunctionArgsArray(name, args)\n{\n\tvar fn = window[name];\n\tif(typeof fn !== 'function') {\n\t\treturn;\n\t}\n\n\tfn.apply(window, args);\n}\n\n/**\n * checks if a variable is an object\n * @param {any} val possible object\n * @return {Boolean} true/false if it is an object or not\n */\nfunction isObject(val)\n{\n\tif (val === null) {\n\t\treturn false;\n\t}\n\treturn ((typeof val === 'function') || (typeof val === 'object'));\n}\n\n/**\n * get the length of an object (entries)\n * @param {Object} object object to check\n * @return {Number} number of entry, or -1 if not object\n */\nfunction getObjectCount(object)\n{\n\tif (!isObject(object)) {\n\t\treturn -1;\n\t}\n\treturn Object.keys(object).length;\n}\n\n/**\n * checks if a key exists in a given object\n * @param {String} key key name\n * @param {Object} object object to search key in\n * @return {Boolean} true/false if key exists in object\n * @deprecated Use objectKeyExists\n */\nfunction keyInObject(key, object)\n{\n\treturn objectKeyExists(object, key);\n}\n\n/**\n * This is the correct order and will superseed keyInObject\n * @param {Object} object object to search key in\n * @param {String} key key name\n * @returns {Boolean} true/false if key exists in object\n */\nfunction objectKeyExists(object, key)\n{\n\treturn Object.prototype.hasOwnProperty.call(object, key) ? true : false;\n}\n\n/**\n * returns matching key of value\n * @param {Object} object object to search value in\n * @param {any} value any value (String, Number, etc)\n * @return {String} the key found for the first matching value\n */\nfunction getKeyByValue(object, value)\n{\n\treturn Object.keys(object).find(key => object[key] === value) ?? '';\n}\n\n/**\n * returns true if value is found in object with a key\n * @param {Object} object object to search value in\n * @param {any} value any value (String, Number, etc)\n * @return {Boolean} true on value found, false on not found\n * @deprecated use objectValueExists\n */\nfunction valueInObject(object, value)\n{\n\treturn objectValueExists(object, value);\n}\n\n/**\n * returns true if value is found in object with a key\n * @param {Object} object object to search value in\n * @param {any} value any value (String, Number, etc)\n * @return {Boolean} true on value found, false on not found\n */\nfunction objectValueExists(object, value)\n{\n\treturn Object.keys(object).find(key => object[key] === value) ? true : false;\n}\n\n/**\n * true deep copy for Javascript objects\n * if Object.assign({}, obj) is not working (shallow)\n * or if JSON.parse(JSON.stringify(obj)) is failing\n * @param {Object} inObject Object to copy\n * @return {Object} Copied Object\n */\nfunction deepCopyFunction(inObject)\n{\n\tvar outObject, value, key;\n\tif (typeof inObject !== 'object' || inObject === null) {\n\t\t// Return the value if inObject is not an object\n\t\treturn inObject;\n\t}\n\t// Create an array or object to hold the values\n\toutObject = Array.isArray(inObject) ? [] : {};\n\t// loop over ech entry in object\n\tfor (key in inObject) {\n\t\tvalue = inObject[key];\n\t\t// Recursively (deep) copy for nested objects, including arrays\n\t\toutObject[key] = deepCopyFunction(value);\n\t}\n\n\treturn outObject;\n}\n\n// __END__\n", "/*\nDescription: DOM Helpers\nDate: 2025//3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { loadEl, pop, expandTA, exists };\n\n/**\n * Gets html element or throws an error\n * @param {string} el_id Element ID to get\n * @returns {HTMLElement}\n * @throws Error\n */\nfunction loadEl(el_id)\n{\n\tlet el = document.getElementById(el_id);\n\tif (el === null) {\n\t\tthrow new Error('Cannot find: ' + el_id);\n\t}\n\treturn el;\n}\n\n/**\n * opens a popup window with winName and given features (string)\n * @param {String} theURL the url\n * @param {String} winName window name\n * @param {Object} features popup features\n */\nfunction pop(theURL, winName, features)\n{\n\tlet __winName = window.open(theURL, winName, features);\n\tif (__winName == null) {\n\t\treturn;\n\t}\n\t__winName.focus();\n}\n\n/**\n * automatically resize a text area based on the amount of lines in it\n * @param {string} ta_id element id\n */\nfunction expandTA(ta_id)\n{\n\tlet ta = this.loadEl(ta_id);\n\tif (ta instanceof HTMLElement && ta.getAttribute('type') !== \"textarea\") {\n\t\tthrow new Error(\"Element is not a textarea: \" + ta_id);\n\t}\n\tlet maxChars = parseInt(ta.getAttribute('cols') ?? \"0\");\n\tlet ta_value = ta.getAttribute('value');\n\tlet theRows = [];\n\tif (ta_value != null) {\n\t\ttheRows = ta_value.split('\\n');\n\t}\n\tvar numNewRows = 0;\n\n\tfor ( var i = 0; i < theRows.length; i++ ) {\n\t\tif ((theRows[i].length+2) > maxChars) {\n\t\t\tnumNewRows += Math.ceil( (theRows[i].length+2) / maxChars ) ;\n\t\t}\n\t}\n\tta.setAttribute('row', (numNewRows + theRows.length).toString());\n}\n\n/**\n * checks if a DOM element actually exists\n * @param {String} id Element id to check for\n * @return {Boolean} true if element exists, false on failure\n */\nfunction exists(id)\n{\n\treturn $('#' + id).length > 0 ? true : false;\n}\n\n// __END__\n", "/*\nDescription: DOM Management and HTML builder\nDate: 2025//3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport {\n\tHtmlElementCreator,\n\t// deprecated name\n\tHtmlElementCreator as DomManagement\n};\nimport { deepCopyFunction, isObject } from './JavaScriptHelpers.mjs';\n\nclass HtmlElementCreator {\n\t/**\n\t * reates object for DOM element creation flow\n\t * @param {String} tag must set tag (div, span, etc)\n\t * @param {String} [id=''] optional set for id, if input, select will be used for name\n\t * @param {String} [content=''] text content inside, is skipped if sub elements exist\n\t * @param {Array} [css=[]] array for css tags\n\t * @param {Object} [options={}] anything else (value, placeholder, OnClick, style)\n\t * @return {Object} created element as an object\n\t */\n\tcel(tag, id = '', content = '', css = [], options = {})\n\t{\n\t\treturn {\n\t\t\ttag: tag,\n\t\t\tid: id,\n\t\t\t// override name if set, else id is used. Only for input/button\n\t\t\tname: options.name,\n\t\t\tcontent: content,\n\t\t\tcss: css,\n\t\t\toptions: options,\n\t\t\tsub: []\n\t\t};\n\t}\n\n\t/**\n\t * attach a cel created object to another to create a basic DOM tree\n\t * @param {Object} base object where to attach/search\n\t * @param {Object} attach the object to be attached\n\t * @param {String} [id=''] optional id, if given search in base for this id and attach there\n\t * @return {Object} \"none\", technically there is no return needed as it is global attach\n\t */\n\tael(base, attach, id = '')\n\t{\n\t\tif (id) {\n\t\t\t// base id match already\n\t\t\tif (base.id == id) {\n\t\t\t\tbase.sub.push(deepCopyFunction(attach));\n\t\t\t} else {\n\t\t\t\t// sub check\n\t\t\t\tif (isObject(base.sub) && base.sub.length > 0) {\n\t\t\t\t\tfor (var i = 0; i < base.sub.length; i ++) {\n\t\t\t\t\t\t// recursive call to sub element\n\t\t\t\t\t\tthis.ael(base.sub[i], attach, id);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tbase.sub.push(deepCopyFunction(attach));\n\t\t}\n\t\treturn base;\n\t}\n\n\t/**\n\t * directly attach n elements to one master base element\n\t * this type does not support attach with optional id\n\t * @param {Object} base object to where we attach the elements\n\t * @param {...Object} attach attach 1..n: attach directly to the base element those attachments\n\t * @return {Object} \"none\", technically there is no return needed, global attach\n\t */\n\taelx(base, ...attach)\n\t{\n\t\tfor (var i = 0; i < attach.length; i ++) {\n\t\t\tbase.sub.push(deepCopyFunction(attach[i]));\n\t\t}\n\t\treturn base;\n\t}\n\n\t/**\n\t * same as aelx, but instead of using objects as parameters\n\t * get an array of objects to attach\n\t * @param {Object} base object to where we attach the elements\n\t * @param {Array} attach array of objects to attach\n\t * @return {Object} \"none\", technically there is no return needed, global attach\n\t */\n\taelxar(base, attach)\n\t{\n\t\tfor (var i = 0; i < attach.length; i ++) {\n\t\t\tbase.sub.push(deepCopyFunction(attach[i]));\n\t\t}\n\t\treturn base;\n\t}\n\n\t/**\n\t * resets the sub elements of the base element given\n\t * @param {Object} base cel created element\n\t * @return {Object} returns reset base element\n\t */\n\trel(base)\n\t{\n\t\tbase.sub = [];\n\t\treturn base;\n\t}\n\n\t/**\n\t * searches and removes style from css array\n\t * @param {Object} _element element to work one\n\t * @param {String} css style sheet to remove (name)\n\t * @return {Object} returns full element\n\t */\n\trcssel(_element, css)\n\t{\n\t\tvar css_index = _element.css.indexOf(css);\n\t\tif (css_index > -1) {\n\t\t\t_element.css.splice(css_index, 1);\n\t\t}\n\t\treturn _element;\n\t}\n\n\t/**\n\t * adds a new style sheet to the element given\n\t * @param {Object} _element element to work on\n\t * @param {String} css style sheet to add (name)\n\t * @return {Object} returns full element\n\t */\n\tacssel(_element, css)\n\t{\n\t\tvar css_index = _element.css.indexOf(css);\n\t\tif (css_index == -1) {\n\t\t\t_element.css.push(css);\n\t\t}\n\t\treturn _element;\n\t}\n\n\t/**\n\t * removes one css and adds another\n\t * is a wrapper around rcssel/acssel\n\t * @param {Object} _element element to work on\n\t * @param {String} rcss style to remove (name)\n\t * @param {String} acss style to add (name)\n\t * @return {Object} returns full element\n\t */\n\tscssel(_element, rcss, acss)\n\t{\n\t\tthis.rcssel(_element, rcss);\n\t\tthis.acssel(_element, acss);\n\t\treturn _element;\n\t}\n\n\t/**\n\t * parses the object tree created with cel/ael and converts it into an HTML string\n\t * that can be inserted into the page\n\t * @param {Object} tree object tree with dom element declarations\n\t * @return {String} HTML string that can be used as innerHTML\n\t */\n\tphfo(tree)\n\t{\n\t\tlet name_elements = [\n\t\t\t'button',\n\t\t\t'fieldset',\n\t\t\t'form',\n\t\t\t'iframe',\n\t\t\t'input',\n\t\t\t'map',\n\t\t\t'meta',\n\t\t\t'object',\n\t\t\t'output',\n\t\t\t'param',\n\t\t\t'select',\n\t\t\t'textarea',\n\t\t];\n\t\tlet skip_options = [\n\t\t\t'id',\n\t\t\t'name',\n\t\t\t'class',\n\t\t];\n\t\tlet no_close = [\n\t\t\t'input',\n\t\t\t'br',\n\t\t\t'img',\n\t\t\t'hr',\n\t\t\t'area',\n\t\t\t'col',\n\t\t\t'keygen',\n\t\t\t'wbr',\n\t\t\t'track',\n\t\t\t'source',\n\t\t\t'param',\n\t\t\t'command',\n\t\t\t// only in header\n\t\t\t'base',\n\t\t\t'meta',\n\t\t\t'link',\n\t\t\t'embed',\n\t\t];\n\t\t// holds the elements\n\t\tvar content = [];\n\t\t// main part line\n\t\tvar line = '<' + tree.tag;\n\t\tvar i;\n\t\t// first id, if set\n\t\tif (tree.id) {\n\t\t\tline += ' id=\"' + tree.id + '\"';\n\t\t\t// if anything input (input, textarea, select then add name too)\n\t\t\tif (name_elements.includes(tree.tag)) {\n\t\t\t\tline += ' name=\"' + (tree.name ? tree.name : tree.id) + '\"';\n\t\t\t}\n\t\t}\n\t\t// second CSS\n\t\tif (isObject(tree.css) && tree.css.length > 0) {\n\t\t\tline += ' class=\"';\n\t\t\tfor (i = 0; i < tree.css.length; i ++) {\n\t\t\t\tline += tree.css[i] + ' ';\n\t\t\t}\n\t\t\t// strip last space\n\t\t\tline = line.slice(0, -1);\n\t\t\tline += '\"';\n\t\t}\n\t\t// options is anything key = \"data\"\n\t\tif (isObject(tree.options)) {\n\t\t\t// ignores id, name, class as key\n\t\t\tfor (const [key, item] of Object.entries(tree.options)) {\n\t\t\t\tif (!skip_options.includes(key)) {\n\t\t\t\t\tline += ' ' + key + '=\"' + item + '\"';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// finish open tag\n\t\tline += '>';\n\t\t// push finished line\n\t\tcontent.push(line);\n\t\t// dive into sub tree to attach sub nodes\n\t\t// NOTES: we can have content (text) AND sub nodes at the same level\n\t\t// CONTENT (TEXT) takes preference over SUB NODE in order\n\t\tif (isObject(tree.sub) && tree.sub.length > 0) {\n\t\t\tif (tree.content) {\n\t\t\t\tcontent.push(tree.content);\n\t\t\t}\n\t\t\tfor (i = 0; i < tree.sub.length; i ++) {\n\t\t\t\tcontent.push(this.phfo(tree.sub[i]));\n\t\t\t}\n\t\t} else if (tree.content) {\n\t\t\tcontent.push(tree.content);\n\t\t}\n\t\t// if not input, image or br, then close\n\t\tif (\n\t\t\t!no_close.includes(tree.tag)\n\t\t) {\n\t\t\tcontent.push('');\n\t\t}\n\t\t// combine to string\n\t\treturn content.join('');\n\t}\n\n\t/**\n\t * Create HTML elements from array list\n\t * as a flat element without master object file\n\t * Is like tree.sub call\n\t * @param {Array} list Array of cel created objects\n\t * @return {String} HTML String\n\t */\n\tphfa(list)\n\t{\n\t\tvar content = [];\n\t\tfor (var i = 0; i < list.length; i ++) {\n\t\t\tcontent.push(this.phfo(list[i]));\n\t\t}\n\t\treturn content.join('');\n\t}\n}\n\n// __EMD__\n", "/*\nDescription: HTML Helpers\nDate: 2025//3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { escapeHtml, unescapeHtml, html_options, html_options_block, html_options_refill };\nimport { loadEl} from './DomHelpers.mjs';\nimport { DomManagement } from './HtmlElementCreator.mjs';\nlet dom = new DomManagement();\n\n/**\n * Escapes HTML in string\n * @param {String} string Text to escape HTML in\n * @returns {String}\n */\nfunction escapeHtml(string)\n{\n\treturn string.replace(/[&<>\"'/]/g, function (s) {\n\t\tvar entityMap = {\n\t\t\t'&': '&',\n\t\t\t'<': '<',\n\t\t\t'>': '>',\n\t\t\t'\"': '"',\n\t\t\t'\\'': ''',\n\t\t\t'/': '/'\n\t\t};\n\n\t\treturn entityMap[s];\n\t});\n}\n\n/**\n * Unescape a HTML encoded string\n * @param {String} string Text to unescape HTML in\n * @returns {String}\n */\nfunction unescapeHtml(string)\n{\n\treturn string.replace(/&[#\\w]+;/g, function (s) {\n\t\tvar entityMap = {\n\t\t\t'&': '&',\n\t\t\t'<': '<',\n\t\t\t'>': '>',\n\t\t\t'"': '\"',\n\t\t\t''': '\\'',\n\t\t\t'/': '/'\n\t\t};\n\n\t\treturn entityMap[s];\n\t});\n}\n\n// BLOCK: html wrappers for quickly creating html data blocks\n\n/**\n * NOTE: OLD FORMAT which misses multiple block set\n * creates an select/options drop down block.\n * the array needs to be key -> value format.\n * key is for the option id and value is for the data output\n * @param {String} name name/id\n * @param {Object} data array for the options\n * @param {String} [selected=''] selected item uid\n * @param {Boolean} [options_only=false] if this is true, it will not print the select part\n * @param {Boolean} [return_string=false] return as string and not as element\n * @param {String} [sort=''] if empty as is, else allowed 'keys',\n * 'values' all others are ignored\n * @return {String} html with build options block\n * @deprecated html_options_block\n */\nfunction html_options(name, data, selected = '', options_only = false, return_string = false, sort = '')\n{\n\t// wrapper to new call\n\treturn this.html_options_block(\n\t\tname, data, selected, 0, options_only, return_string, sort\n\t);\n}\n\n/**\n * NOTE: USE THIS CALL, the above one is deprecated\n * creates an select/options drop down block.\n * the array needs to be key -> value format.\n * key is for the option id and value is for the data output\n * @param {String} name name/id\n * @param {Object} data array for the options\n * @param {String} [selected=''] selected item uid\n * @param {Number} [multiple=0] if this is 1 or larger, the drop down\n * will be turned into multiple select\n * the number sets the size value unless it is 1,\n * then it is default\n * @param {Boolean} [options_only=false] if this is true, it will not print the select part\n * @param {Boolean} [return_string=false] return as string and not as element\n * @param {String} [sort=''] if empty as is, else allowed 'keys',\n * 'values' all others are ignored\n * @param {String} [onchange=''] onchange trigger call, default unset\n * @return {String} html with build options block\n */\nfunction html_options_block(\n\tname, data, selected = '', multiple = 0, options_only = false, return_string = false, sort = '', onchange = ''\n) {\n\tvar content = [];\n\tvar element_select;\n\tvar select_options = {};\n\tvar element_option;\n\tvar data_list = []; // for sorted output\n\tvar value;\n\tvar options = {};\n\t// var option;\n\tif (multiple > 0) {\n\t\tselect_options.multiple = '';\n\t\tif (multiple > 1) {\n\t\t\tselect_options.size = multiple;\n\t\t}\n\t}\n\tif (onchange) {\n\t\tselect_options.OnChange = onchange;\n\t}\n\t// set outside select, gets stripped on return if options only is true\n\telement_select = dom.cel('select', name, '', [], select_options);\n\t// console.log('Call for %s, options: %s', name, options_only);\n\tif (sort == 'keys') {\n\t\tdata_list = Object.keys(data).sort();\n\t} else if (sort == 'values') {\n\t\tdata_list = Object.keys(data).sort((a, b) => ('' + data[a]).localeCompare(data[b]));\n\t} else {\n\t\tdata_list = Object.keys(data);\n\t}\n\t// console.log('ORDER: %s', data_list);\n\t// use the previously sorted list\n\t// for (const [key, value] of Object.entries(data)) {\n\tfor (const key of data_list) {\n\t\tvalue = data[key];\n\t\t// console.log('create [%s] options: key: %s, value: %s', name, key, value);\n\t\t// basic options init\n\t\toptions = {\n\t\t\t'label': value,\n\t\t\t'value': key,\n\t\t\t'selected': ''\n\t\t};\n\t\t// add selected if matching\n\t\tif (multiple == 0 && !Array.isArray(selected) && selected == key) {\n\t\t\toptions.selected = '';\n\t\t}\n\t\t// for multiple, we match selected as array\n\t\tif (multiple == 1 && Array.isArray(selected) && selected.indexOf(key) != -1) {\n\t\t\toptions.selected = '';\n\t\t}\n\t\t// create the element option\n\t\telement_option = dom.cel('option', '', value, [], options);\n\t\t// attach it to the select element\n\t\tdom.ael(element_select, element_option);\n\t}\n\t// if with select part, convert to text\n\tif (!options_only) {\n\t\tif (return_string) {\n\t\t\tcontent.push(dom.phfo(element_select));\n\t\t\treturn content.join('');\n\t\t} else {\n\t\t\treturn element_select;\n\t\t}\n\t} else {\n\t\t// strip select part\n\t\tif (return_string) {\n\t\t\tfor (var i = 0; i < element_select.sub.length; i ++) {\n\t\t\t\tcontent.push(dom.phfo(element_select.sub[i]));\n\t\t\t}\n\t\t\treturn content.join('');\n\t\t} else {\n\t\t\treturn element_select.sub;\n\t\t}\n\t}\n}\n\n/**\n * refills a select box with options and keeps the selected\n * @param {String} name name/id\n * @param {Object} data array of options\n * @param {String} [sort=''] if empty as is, else allowed 'keys', 'values'\n * all others are ignored\n */\nfunction html_options_refill(name, data, sort = '')\n{\n\tvar element_option;\n\tvar option_selected;\n\tvar data_list = []; // for sorted output\n\tvar value;\n\t// skip if not exists\n\tif (document.getElementById(name)) {\n\t\t// console.log('Call for %s, options: %s', name, options_only);\n\t\tif (sort == 'keys') {\n\t\t\tdata_list = Object.keys(data).sort();\n\t\t} else if (sort == 'values') {\n\t\t\tdata_list = Object.keys(data).sort((a, b) => ('' + data[a]).localeCompare(data[b]));\n\t\t} else {\n\t\t\tdata_list = Object.keys(data);\n\t\t}\n\t\t// first read in existing ones from the options and get the selected one\n\t\t[].forEach.call(document.querySelectorAll('#' + name + ' :checked'), function(elm) {\n\t\t\toption_selected = elm.value;\n\t\t});\n\t\tloadEl(name).innerHTML = '';\n\t\tfor (const key of data_list) {\n\t\t\tvalue = data[key];\n\t\t\t// console.log('add [%s] options: key: %s, value: %s', name, key, value);\n\t\t\telement_option = document.createElement('option');\n\t\t\telement_option.label = value;\n\t\t\telement_option.value = key;\n\t\t\telement_option.innerHTML = value;\n\t\t\tif (key == option_selected) {\n\t\t\t\telement_option.selected = true;\n\t\t\t}\n\t\t\tloadEl(name).appendChild(element_option);\n\t\t}\n\t}\n}\n\n// __EMD__\n", "/*\nDescription: Math Helpers\nDate: 2025/3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { dec2hex, getRandomIntInclusive, roundPrecision };\n\n/**\n * dec2hex :: Integer -> String\n * i.e. 0-255 -> '00'-'ff'\n * @param {Number} dec decimal string\n * @return {String} hex encdoded number, prefix with 0x\n */\nfunction dec2hex(dec)\n{\n\treturn ('0x' + dec.toString(16)).substring(-2);\n}\n\n/**\n * generate a number between min/max\n * with min/max inclusive.\n * eg: 1,5 will create a number ranging from 1 o 5\n * @param {Number} min minimum int number inclusive\n * @param {Number} max maximum int number inclusive\n * @return {Number} Random number\n */\nfunction getRandomIntInclusive(min, max)\n{\n\tmin = Math.ceil(min);\n\tmax = Math.floor(max);\n\t// The maximum is inclusive and the minimum is inclusive\n\treturn Math.floor(Math.random() * (max - min + 1) + min);\n}\n\n/**\n * Round a number to precision\n * @param {Number} number Number to round\n * @param {Number} precision Precision value\n * @returns {Number}\n */\nfunction roundPrecision(number, precision)\n{\n\tif (isNaN(number) || isNaN(precision)) {\n\t\treturn number;\n\t}\n\treturn Math.round(number * Math.pow(10, precision)) / Math.pow(10, precision);\n}\n\n// __END__\n", "/*\nDescription: String Helpers\nDate: 2025//3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { formatString, numberWithCommas, convertLBtoBR };\n\n/**\n * simple sprintf formater for replace\n * usage: formatString(\"{0} is cool, {1} is not\", \"Alpha\", \"Beta\");\n * First, checks if it isn't implemented yet.\n * @param {String} string String with {..} entries\n * @param {...any} args List of replacement\n * @returns {String} Escaped string\n */\nfunction formatString(string, ...args)\n{\n\treturn string.replace(/{(\\d+)}/g, function(match, number)\n\t{\n\t\treturn typeof args[number] != 'undefined' ?\n\t\t\targs[number] :\n\t\t\tmatch\n\t\t;\n\t});\n}\n/**\n * formats flat number 123456 to 123,456\n * @param {Number} number number to be formated\n * @return {String} formatted with , in thousands\n */\nfunction numberWithCommas(number)\n{\n\tvar parts = number.toString().split('.');\n\tparts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\treturn parts.join('.');\n}\n\n/**\n * converts line breaks to br\n * @param {String} string any string\n * @return {String} string with
\n */\nfunction convertLBtoBR(string)\n{\n\treturn string.replace(/(?:\\r\\n|\\r|\\n)/g, '
');\n}\n\n// __END__\n", "/*\nDescription: Date Time functions\nDate: 2025//3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { getTimestamp };\n\n/**\n * returns current timestamp (unix timestamp)\n * @return {Number} timestamp (in milliseconds)\n */\nfunction getTimestamp()\n{\n\tvar date = new Date();\n\treturn date.getTime();\n}\n\n// __END__\n", "/*\nDescription: Generate unique ids\nDate: 2025/3/7\nCreator: Clemens Schwaighofer\n*/\n\nexport { generateId, randomIdF };\n\n\n/**\n * generateId :: Integer -> String\n * only works on mondern browsers\n * @param {Number} len length of unique id string\n * @return {String} random string in length of len\n */\nfunction generateId(len)\n{\n\tvar arr = new Uint8Array((len || 40) / 2);\n\t(\n\t\twindow.crypto ||\n\t\t// @ts-ignore\n\t\twindow.msCrypto\n\t).getRandomValues(arr);\n\treturn Array.from(arr, self.dec2hex).join('');\n}\n\n/**\n * creates a pseudo random string of 10 or 11 characters\n * works on all browsers\n * after many runs it will create duplicates\n * NOTE: no idea why this sometimes returns 10 or 11\n * @return {String} not true random string\n */\nfunction randomIdF()\n{\n\treturn Math.random().toString(36).substring(2);\n}\n", "/*\nDescription: Resize and Move Javascript\nDate: 2025//3/6\nCreator: Clemens Schwaighofer\n*/\n\nimport { errorCatch} from './JavaScriptHelpers.mjs';\nimport { loadEl } from './DomHelpers.mjs';\nexport { getWindowSize, getScrollOffset, getScrollOffsetOpener, setCenter, goToPos, goTo };\n\n/**\n * wrapper to get the real window size for the current browser window\n * @return {Object} object with width/height\n */\nfunction getWindowSize()\n{\n\tvar width, height;\n\twidth = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth);\n\theight = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);\n\treturn {\n\t\twidth: width,\n\t\theight: height\n\t};\n}\n\n/**\n * wrapper to get the correct scroll offset\n * @return {Object} object with x/y px\n */\nfunction getScrollOffset()\n{\n\tvar left, top;\n\tleft = window.pageXOffset || (window.document.documentElement.scrollLeft || window.document.body.scrollLeft);\n\ttop = window.pageYOffset || (window.document.documentElement.scrollTop || window.document.body.scrollTop);\n\treturn {\n\t\tleft: left,\n\t\ttop: top\n\t};\n}\n\n/**\n * wrapper to get the correct scroll offset for opener page (from popup)\n * @return {Object} object with x/y px\n */\nfunction getScrollOffsetOpener()\n{\n\tvar left, top;\n\tleft = opener.window.pageXOffset || (opener.document.documentElement.scrollLeft || opener.document.body.scrollLeft);\n\ttop = opener.window.pageYOffset || (opener.document.documentElement.scrollTop || opener.document.body.scrollTop);\n\treturn {\n\t\tleft: left,\n\t\ttop: top\n\t};\n}\n\n/**\n * centers div to current window size middle\n * @param {String} id element to center\n * @param {Boolean} left if true centers to the middle from the left\n * @param {Boolean} top if true centers to the middle from the top\n */\nfunction setCenter(id, left, top)\n{\n\t// get size of id\n\tvar dimensions = {\n\t\theight: $('#' + id).height() ?? 0,\n\t\twidth: $('#' + id).width() ?? 0\n\t};\n\tvar type = $('#' + id).css('position');\n\tvar viewport = this.getWindowSize();\n\tvar offset = this.getScrollOffset();\n\n\t// console.log('Id %s, type: %s, dimensions %s x %s, viewport %s x %s', id, type, dimensions.width, dimensions.height, viewport.width, viewport.height);\n\t// console.log('Scrolloffset left: %s, top: %s', offset.left, offset.top);\n\t// console.log('Left: %s, Top: %s (%s)', parseInt((viewport.width / 2) - (dimensions.width / 2) + offset.left), parseInt((viewport.height / 2) - (dimensions.height / 2) + offset.top), parseInt((viewport.height / 2) - (dimensions.height / 2)));\n\tif (left) {\n\t\t$('#' + id).css({\n\t\t\tleft: (viewport.width / 2) - (dimensions.width / 2) + offset.left + 'px'\n\t\t});\n\t}\n\tif (top) {\n\t\t// if we have fixed, we do not add the offset, else it moves out of the screen\n\t\tvar top_pos = type == 'fixed' ?\n\t\t\t(viewport.height / 2) - (dimensions.height / 2) :\n\t\t\t(viewport.height / 2) - (dimensions.height / 2) + offset.top;\n\t\t$('#' + id).css({\n\t\t\ttop: top_pos + 'px'\n\t\t});\n\t}\n}\n\n/**\n * goes to an element id position\n * @param {String} element element id to move to\n * @param {Number} [offset=0] offset from top, default is 0 (px)\n * @param {Number} [duration=500] animation time, default 500ms\n * @param {String} [base='body,html'] base element for offset scroll\n */\nfunction goToPos(element, offset = 0, duration = 500, base = 'body,html')\n{\n\ttry {\n\t\tlet element_offset = $('#' + element).offset();\n\t\tif (element_offset == undefined) {\n\t\t\treturn;\n\t\t}\n\t\tif ($('#' + element).length) {\n\t\t\t$(base).animate({\n\t\t\t\tscrollTop: element_offset.top - offset\n\t\t\t}, duration);\n\t\t}\n\t} catch (err) {\n\t\terrorCatch(err);\n\t}\n}\n\n/**\n * go to element, scroll\n * non jquery\n * @param {string} target\n*/\nfunction goTo(target)\n{\n\tloadEl(target).scrollIntoView({\n\t\tbehavior: 'smooth'\n\t});\n}\n\n// __END__\n", "/*\nDescription: Byte string formatting\nDate: 2025//3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { formatBytes, formatBytesLong, stringByteFormat };\n\n/**\n * converts a int number into bytes with prefix in two decimals precision\n * currently precision is fixed, if dynamic needs check for max/min precision\n * @param {Number|BigInt} bytes bytes in int\n * @return {String} string in GB/MB/KB\n */\nfunction formatBytes(bytes)\n{\n\tvar i = -1;\n\t// If this ia bigint -> convert to number, we need the decimals\n\tif (typeof bytes === \"bigint\") {\n\t\tbytes = Number(bytes);\n\t}\n\tif (isNaN(bytes)) {\n\t\treturn bytes.toString();\n\t}\n\tdo {\n\t\tbytes = bytes / 1024;\n\t\ti++;\n\t} while (bytes > 99);\n\treturn (\n\t\tMath.round(bytes * Math.pow(10, 2)) / Math.pow(10, 2)\n\t) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];\n}\n\n/**\n * like formatBytes, but returns bytes for <1KB and not 0.n KB\n * @param {Number|BigInt} bytes bytes in int\n * @return {String} string in GB/MB/KB\n */\nfunction formatBytesLong(bytes)\n{\n\t// If this ia bigint -> convert to number, we need the decimals\n\tif (typeof bytes === \"bigint\") {\n\t\tbytes = Number(bytes);\n\t}\n\tif (isNaN(bytes)) {\n\t\treturn bytes.toString();\n\t}\n\tlet negative = false;\n\tif (bytes < 0) {\n\t\tnegative = true;\n\t\tbytes *= -1;\n\t}\n\tvar i = Math.floor(Math.log(bytes) / Math.log(1024));\n\tvar sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n\treturn (negative ? '-' : '') + (\n\t\t(\n\t\t\tbytes /\n\t\t\tMath.pow(1024, i)\n\t\t).toFixed(2)\n\t\t// * 1 + ' ' + sizes[i]\n\t\t+ ' ' + sizes[i]\n\t).toString();\n}\n\n/**\n * Convert a string with B/K/M/etc into a byte number\n * @param {String|Number|Object} bytes Any string with B/K/M/etc\n * @param {Boolean} raw [default=false] Return not rounded values\n * @return {String|Number} A byte number, or original string as is\n */\nfunction stringByteFormat(bytes, raw=false)\n{\n\t// if anything not string return\n\tif (!(typeof bytes === 'string' || bytes instanceof String)) {\n\t\treturn bytes.toString();\n\t}\n\t// for pow exponent list\n\tlet valid_units = 'bkmgtpezy';\n\t// valid string that can be converted\n\tlet regex = /([\\d.,]*)\\s?(eb|pb|tb|gb|mb|kb|e|p|t|g|m|k|b)$/i;\n\tlet matches = bytes.match(regex);\n\t// if nothing found, return original input\n\tif (matches !== null) {\n\t\t// remove all non valid entries outside numbers and .\n\t\t// convert to float number\n\t\tlet m1 = parseFloat(matches[1].replace(/[^0-9.]/,''));\n\t\t// only get the FIRST letter from the size, convert it to lower case\n\t\tlet m2 = matches[2].replace(/[^bkmgtpezy]/i, '').charAt(0).toLowerCase();\n\t\tif (m2) {\n\t\t\t// use the position in the valid unit list to do the math conversion\n\t\t\tbytes = m1 * Math.pow(1024, valid_units.indexOf(m2));\n\t\t}\n\t}\n\t// if we want to have the raw data returned\n\tif (raw) {\n\t\treturn bytes;\n\t}\n\treturn Math.round(bytes);\n}\n\n// __END__\n", "/*\nDescription: HTML Helpers\nDate: 2025//3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { parseQueryString, getQueryStringParam, hasUrlParameter, getUrlParameter, updateUrlParameter, removeUrlParameter };\n\n/**\n * NOTE: this original code was wrong, now using URL and parsing through\n * getQueryStringParam\n * parses a query string from window.location.search.substring(1)\n * ALTERNATIVE CODE\n * var url = new URL(window.location.href);\n * param_uid = url.searchParams.get('uid');\n * @param {String} [query=''] the query string to parse, if not set will auto fill\n * @param {String} [return_key=''] if set only returns this key entry or empty for none\n * @param {Boolean} [single=false] if set to true then only the first found will be returned\n * @return {Object|String} parameter entry list\n */\nfunction parseQueryString(query = '', return_key = '', single = false)\n{\n\treturn getQueryStringParam(return_key, query, single);\n}\n\n/**\n * searches query parameters for entry and returns data either as string or array\n * if no search is given the whole parameters are returned as an object\n * if a parameter is set several times it will be returned as an array\n * if search parameter set and nothing found and empty string is returned\n * if no parametes exist and no serach is set and empty object is returned\n * @param {String} [search=''] if set searches for this entry, if empty all parameters are returned\n * @param {String} [query=''] different query string to parse, if not set (default) the current window href is used\n * @param {Boolean} [single=false] if set to true then only the first found will be returned\n * @return {Object|Array|String} if search is empty, object, if search is set\n * and only one entry, then string, else array\n * unless single is true\n */\nfunction getQueryStringParam(search = '', query = '', single = false)\n{\n\tif (!query) {\n\t\tquery = window.location.href;\n\t}\n\tconst url = new URL(query);\n\tlet param = null;\n\tif (search) {\n\t\tlet _params = url.searchParams.getAll(search);\n\t\tif (_params.length == 1 || single === true) {\n\t\t\tparam = _params[0];\n\t\t} else if (_params.length > 1) {\n\t\t\tparam = _params;\n\t\t}\n\t} else {\n\t\t// will be object, so declare it one\n\t\tparam = {};\n\t\t// loop over paramenters\n\t\tfor (const [key] of url.searchParams.entries()) {\n\t\t\t// check if not yet set\n\t\t\tif (typeof param[key] === 'undefined') {\n\t\t\t\t// get the parameters multiple\n\t\t\t\tlet _params = url.searchParams.getAll(key);\n\t\t\t\t// if 1 set as string, else attach array as is\n\t\t\t\tparam[key] = _params.length < 2 || single === true ?\n\t\t\t\t\t_params[0] :\n\t\t\t\t\t_params;\n\t\t\t}\n\t\t}\n\t}\n\treturn param;\n}\n\n/**\n * Check if key exists as URL parameter\n * @param {String} key URL parameter to search\n * @returns {Boolean} True if key exists\n */\nfunction hasUrlParameter(key)\n{\n\tvar urlParams = new URLSearchParams(window.location.search);\n\treturn urlParams.has(key);\n}\n\n/**\n * Return one value for a URL paramter or null if not found\n * @param {String} key Which URL parameter to get\n * @returns {String|Null} URL parameter content\n */\nfunction getUrlParameter(key)\n{\n\tvar urlParams = new URLSearchParams(window.location.search);\n\treturn urlParams.get(key);\n}\n\n/**\n * Add or update a query parameter in the current URL and update the browser's address bar\n * @param {string} key - The parameter name to add or update\n * @param {string} value - The value to set for the parameter\n * @param {boolean} [reload=false] - Whether to reload the page after updating the URL\n */\nfunction updateUrlParameter(key, value, reload = false)\n{\n\t// Create a URL object from the current URL\n\tconst url = new URL(window.location.href);\n\n\t// Set or update the parameter\n\turl.searchParams.set(key, value);\n\n\tconst newUrl = url.toString();\n\n\t// Update the browser's address bar without reloading the page\n\twindow.history.pushState({ path: newUrl }, '', newUrl);\n\n\t// Optionally reload the page\n\tif (reload) {\n\t\t// window.location.href = newUrl;\n\t\twindow.location.reload();\n\t}\n}\n\n/**\n * Remove a parameter from the current URL and update the browser's address bar\n * @param {string} key - The parameter name to remove\n * @param {boolean} [reload=false] - Whether to reload the page after updating the URL\n */\nfunction removeUrlParameter(key, reload = false)\n{\n\t// Create a URL object from the current URL\n\tconst url = new URL(window.location.href);\n\n\t// Remove the parameter if it exists\n\turl.searchParams.delete(key);\n\n\t// Update the browser's address bar without reloading the page\n\twindow.history.pushState({}, '', url.toString());\n\n\t// Optionally reload the page\n\tif (reload) {\n\t\twindow.location.reload();\n\t}\n}\n\n// __EMD__\n", "/*\nDescription: Login access and menu\nDate: 2025//3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { loginLogout };\n\n/**\n * submits basic data for form logout\n */\nfunction loginLogout()\n{\n\tconst form = document.createElement('form');\n\tform.method = 'post';\n\tconst hiddenField = document.createElement('input');\n\thiddenField.type = 'hidden';\n\thiddenField.name = 'login_logout';\n\thiddenField.value = 'Logout';\n\tform.appendChild(hiddenField);\n\tdocument.body.appendChild(form);\n\tform.submit();\n}\n\n// __END__\n", "/*\nDescription: Action Indicator and Overlay\nDate: 2025/2/7\nCreator: Clemens Schwaighofer\n*/\n\nimport { setCenter } from './ResizingAndMove.mjs';\nexport {\n\tActionIndicatorOverlayBox,\n\tactionIndicator, actionIndicatorShow, actionIndicatorHide, overlayBoxShow,\n\toverlayBoxHide, setOverlayBox, hideOverlayBox, ClearCall\n};\n\n/*************************************************************\n * OLD action indicator and overlay boxes calls\n * DO NOT USE\n * actionIndicator -> showActionIndicator\n * actionIndicator -> hideActionIndicator\n * actionIndicatorShow -> showActionIndicator\n * actionIndicatorHide -> hideActionIndicator\n * overlayBoxShow -> showOverlayBoxLayers\n * overlayBoxHide -> hideOverlayBoxLayers\n * setOverlayBox -> showOverlayBoxLayers\n * hideOverlayBox -> hideOverlayBoxLayers\n * ClearCall -> clearCallActionBox\n * ***********************************************************/\n\n/**\n * show or hide the \"do\" overlay\n * @param {String} loc location name for action indicator\n * default empty. for console.log\n * @param {Boolean} [overlay=true] override the auto hide/show over the overlay div block\n * @deprecated showActionIndicator, hideActionIndicator\n */\nfunction actionIndicator(loc, overlay = true)\n{\n\tif ($('#indicator').is(':visible')) {\n\t\tthis.actionIndicatorHide(loc, overlay);\n\t} else {\n\t\tthis.actionIndicatorShow(loc, overlay);\n\t}\n}\n\n/**\n * explicit show for action Indicator\n * instead of automatically show or hide, do on command show\n * @param {String} loc location name for action indicator\n * default empty. for console.log\n * @param {Boolean} [overlay=true] override the auto hide/show over the overlay div block\n * @deprecated showActionIndicator, hideActionIndicator\n */\nfunction actionIndicatorShow(loc, overlay = true)\n{\n\t// console.log('{Indicator}: SHOW [%s]', loc);\n\tif (!$('#indicator').is(':visible')) {\n\t\tif (!$('#indicator').hasClass('progress')) {\n\t\t\t$('#indicator').addClass('progress');\n\t\t}\n\t\tsetCenter('indicator', true, true);\n\t\t$('#indicator').show();\n\t}\n\tif (overlay === true) {\n\t\tthis.overlayBoxShow();\n\t}\n}\n\n/**\n * explicit hide for action Indicator\n * instead of automatically show or hide, do on command hide\n * @param {String} loc location name for action indicator\n * default empty. for console.log\n * @param {Boolean} [overlay=true] override the auto hide/show over the overlay div block\n * @deprecated hideActionIndicator\n */\nfunction actionIndicatorHide(loc, overlay = true)\n{\n\t// console.log('{Indicator}: HIDE [%s]', loc);\n\t$('#indicator').hide();\n\tif (overlay === true) {\n\t\toverlayBoxHide();\n\t}\n}\n\n/**\n * shows the overlay box or if already visible, bumps the zIndex to 100\n * @deprecated showOverlayBoxLayers\n */\nfunction overlayBoxShow()\n{\n\t// check if overlay box exists and if yes set the z-index to 100\n\tif ($('#overlayBox').is(':visible')) {\n\t\t$('#overlayBox').css('zIndex', '100');\n\t} else {\n\t\t$('#overlayBox').show();\n\t\t$('#overlayBox').css('zIndex', '98');\n\t}\n}\n\n/**\n * hides the overlay box or if zIndex is 100 bumps it down to previous level\n * @deprecated hideOverlayBoxLayers\n */\nfunction overlayBoxHide()\n{\n\t// if the overlay box z-index is 100, do no hide, but set to 98\n\tif (parseInt($('#overlayBox').css('zIndex')) >= 100) {\n\t\t$('#overlayBox').css('zIndex', '98');\n\t} else {\n\t\t$('#overlayBox').hide();\n\t}\n}\n\n/**\n * position the overlay block box and shows it\n * @deprecated showOverlayBoxLayers\n */\nfunction setOverlayBox()\n{\n\tif (!$('#overlayBox').is(':visible')) {\n\t\t$('#overlayBox').show();\n\t}\n}\n\n/**\n * opposite of set, always hides overlay box\n * @deprecated hideOverlayBoxLayers\n */\nfunction hideOverlayBox()\n{\n\tif ($('#overlayBox').is(':visible')) {\n\t\t$('#overlayBox').hide();\n\t}\n}\n\n/**\n * the abort call, clears the action box and hides it and the overlay box\n * @deprecated clearCallActionBox\n */\nfunction ClearCall()\n{\n\t$('#actionBox').html('');\n\t$('#actionBox').hide();\n\t$('#overlayBox').hide();\n}\n\n/*\nThe below class will need the following CSS set\n\nProgress indicator (#indicator):\n.progress {\n\twidth: 100px;\n\theight: 100px;\n\tbackground: rgba(255, 255, 255, 0.6);\n\tborder: 20px solid rgba(255, 255, 255 ,0.25);\n\tborder-left-color: rgba(3, 155, 229 ,1);\n\tborder-top-color: rgba(3, 155, 229 ,1);\n\tborder-radius: 50%;\n\tdisplay: inline-block;\n\tanimation: progress-move 600ms infinite linear;\n\tleft: 0;\n\ttop: 0;\n\tposition: absolute;\n\tz-index: 1000;\n}\n@keyframes progress-move {\n\tto {\n\t\ttransform: rotate(1turn)\n\t}\n}\n\nOverlay box darken background (#overlayBox):\n.overlayBoxElement {\n\tbackground-color: rgba(0, 0, 0, 0.3);\n\theight: 100%;\n\tleft: 0;\n\tposition: fixed;\n\ttop: 0;\n\twidth: 100%;\n\tz-index: 98;\n}\n*/\n\nclass ActionIndicatorOverlayBox {\n\n\t// open overlay boxes counter for z-index\n\t#GL_OB_S = 100;\n\t#GL_OB_BASE = 100;\n\n\t/**\n\t * show action indicator\n\t * - checks if not existing and add\n\t * - only shows if not visible (else ignore)\n\t * - overlaybox check is called and shown on a fixzed\n\t * zIndex of 1000\n\t * - indicator is page centered\n\t * @param {String} loc ID string, only used for console log\n\t */\n\tshowActionIndicator(loc) // eslint-disable-line no-unused-vars\n\t{\n\t\t// console.log('{Indicator}: SHOW [%s]', loc);\n\t\t// check if indicator element exists\n\t\tif ($('#indicator').length == 0) {\n\t\t\tvar el = document.createElement('div');\n\t\t\tel.className = 'progress hide';\n\t\t\tel.id = 'indicator';\n\t\t\t$('body').append(el);\n\t\t} else if (!$('#indicator').hasClass('progress')) {\n\t\t\t// if I add a class it will not be hidden anymore\n\t\t\t// hide it\n\t\t\t$('#indicator').addClass('progress').hide();\n\t\t}\n\t\t// indicator not visible\n\t\tif (!$('#indicator').is(':visible')) {\n\t\t\t// check if overlay box element exits\n\t\t\tthis.checkOverlayExists();\n\t\t\t// if not visible show\n\t\t\tif (!$('#overlayBox').is(':visible')) {\n\t\t\t\t$('#overlayBox').show();\n\t\t\t}\n\t\t\t// always set to 1000 zIndex to be top\n\t\t\t$('#overlayBox').css('zIndex', 1000);\n\t\t\t// show indicator\n\t\t\t$('#indicator').show();\n\t\t\t// center it\n\t\t\tsetCenter('indicator', true, true);\n\t\t}\n\t}\n\n\t/**\n\t * hide action indicator, if it is visiable\n\t * If the global variable GL_OB_S is > GL_OB_BASE then\n\t * the overlayBox is not hidden but the zIndex\n\t * is set to this value\n\t * @param {String} loc ID string, only used for console log\n\t */\n\thideActionIndicator(loc) // eslint-disable-line no-unused-vars\n\t{\n\t\t// console.log('{Indicator}: HIDE [%s]', loc);\n\t\t// check if indicator is visible\n\t\tif ($('#indicator').is(':visible')) {\n\t\t\t// hide indicator\n\t\t\t$('#indicator').hide();\n\t\t\t// if global overlay box count is > 0\n\t\t\t// then set it to this level and keep\n\t\t\tif (this.#GL_OB_S > this.#GL_OB_BASE) {\n\t\t\t\t$('#overlayBox').css('zIndex', this.#GL_OB_S);\n\t\t\t} else {\n\t\t\t\t// else hide overlay box and set zIndex to 0\n\t\t\t\t$('#overlayBox').hide();\n\t\t\t\t$('#overlayBox').css('zIndex', this.#GL_OB_BASE);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * checks if overlayBox exists, if not it is\n\t * added as hidden item at the body end\n\t */\n\tcheckOverlayExists()\n\t{\n\t\t// check if overlay box exists, if not create it\n\t\tif ($('#overlayBox').length == 0) {\n\t\t\tvar el = document.createElement('div');\n\t\t\tel.className = 'overlayBoxElement hide';\n\t\t\tel.id = 'overlayBox';\n\t\t\t$('body').append(el);\n\t\t}\n\t}\n\n\t/**\n\t * show overlay box\n\t * if not visible show and set zIndex to 10 (GL_OB_BASE)\n\t * if visible, add +1 to the GL_OB_S variable and\n\t * up zIndex by this value\n\t */\n\tshowOverlayBoxLayers(el_id)\n\t{\n\t\t// console.log('SHOW overlaybox: %s', GL_OB_S);\n\t\t// if overlay box is not visible show and set zIndex to 0\n\t\tif (!$('#overlayBox').is(':visible')) {\n\t\t\t$('#overlayBox').show();\n\t\t\t$('#overlayBox').css('zIndex', this.#GL_OB_BASE);\n\t\t\t// also set start variable to 0\n\t\t\tthis.#GL_OB_S = this.#GL_OB_BASE;\n\t\t}\n\t\t// up the overlay box counter by 1\n\t\tthis.#GL_OB_S ++;\n\t\t// set zIndex\n\t\t$('#overlayBox').css('zIndex', this.#GL_OB_S);\n\t\t// if element given raise zIndex and show\n\t\tif (el_id) {\n\t\t\tif ($('#' + el_id).length > 0) {\n\t\t\t\t$('#' + el_id).css('zIndex', this.#GL_OB_S + 1);\n\t\t\t\t$('#' + el_id).show();\n\t\t\t}\n\t\t}\n\t\t// console.log('SHOW overlaybox NEW zIndex: %s', $('#overlayBox').css('zIndex'));\n\t}\n\n\t/**\n\t * hide overlay box\n\t * lower GL_OB_S value by -1\n\t * if we are 10 (GL_OB_BASE) or below hide the overlayIndex\n\t * and set zIndex and GL_OB_S to 0\n\t * else just set zIndex to the new GL_OB_S value\n\t * @param {String} el_id Target to hide layer\n\t */\n\thideOverlayBoxLayers(el_id='')\n\t{\n\t\t// console.log('HIDE overlaybox: %s', GL_OB_S);\n\t\t// remove on layer\n\t\tthis.#GL_OB_S --;\n\t\t// if 0 or lower (overflow) hide it and\n\t\t// set zIndex to 0\n\t\tif (this.#GL_OB_S <= this.#GL_OB_BASE) {\n\t\t\tthis.#GL_OB_S = this.#GL_OB_BASE;\n\t\t\t$('#overlayBox').hide();\n\t\t\t$('#overlayBox').css('zIndex', this.#GL_OB_BASE);\n\t\t} else {\n\t\t\t// if OB_S > 0 then set new zIndex\n\t\t\t$('#overlayBox').css('zIndex', this.#GL_OB_S);\n\t\t}\n\t\tif (el_id) {\n\t\t\t$('#' + el_id).hide();\n\t\t\t$('#' + el_id).css('zIndex', 0);\n\t\t}\n\t\t// console.log('HIDE overlaybox NEW zIndex: %s', $('#overlayBox').css('zIndex'));\n\t}\n\n\t/**\n\t * only for single action box\n\t */\n\tclearCallActionBox()\n\t{\n\t\t$('#actionBox').html('');\n\t\t$('#actionBox').hide();\n\t\tthis.hideOverlayBoxLayers();\n\t}\n}\n\n\n// __END__\n", "/*\nDescription: Translation call\nDate: 2025//3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { l10nTranslation };\nimport { isObject } from './JavaScriptHelpers.mjs';\n\nclass l10nTranslation {\n\n\t#i18n = {};\n\n\tconstructor(i18n) {\n\t\tthis.#i18n = i18n;\n\n\t}\n\t/**\n\t * uses the i18n object created in the translation template\n\t * that is filled from gettext in PHP\n\t * @param {String} string text to translate\n\t * @return {String} translated text (based on PHP selected language)\n\t */\n\t__(string)\n\t{\n\t\tif (typeof this.#i18n !== 'undefined' && isObject(this.#i18n) && this.#i18n[string]) {\n\t\t\treturn this.#i18n[string];\n\t\t} else {\n\t\t\treturn string;\n\t\t}\n\t}\n}\n\n// __END__\n", "/*\nDescription: Action Box handling\nDate: 2025/3/7\nCreator: Clemens Schwaighofer\n*/\n\nexport { ActionBox };\nimport { objectKeyExists, getObjectCount } from './JavaScriptHelpers.mjs';\nimport { exists } from './DomHelpers.mjs';\nimport { setCenter, getWindowSize } from './ResizingAndMove.mjs';\n\nclass ActionBox {\n\n\t// open overlay boxes counter for z-index\n\tzIndex = {\n\t\tbase: 100,\n\t\tmax: 110,\n\t\tindicator: 0,\n\t\tboxes: {},\n\t\tactive: [],\n\t\ttop: ''\n\t};\n\t// general action box storage\n\taction_box_storage = {};\n\t// set to 10 min (*60 for seconds, *1000 for microseconds)\n\taction_box_cache_timeout = 10 * 60 * 1000;\n\n\thec;\n\tl10n;\n\n\t/**\n\t * action box creator\n\t * @param {Object} hec HtmlElementCreator\n\t * @param {Object} l10n l10nTranslation\n\t */\n\tconstructor(hec, l10n)\n\t{\n\t\tthis.hec = hec;\n\t\tthis.l10n = l10n;\n\t}\n\n\t/**\n\t * Show an action box\n\t * @param {string} [target_id='actionBox'] where to attach content to, if not exists, create new\n\t * @param {string} [content=''] content to add to the box\n\t * @param {array} [action_box_css=[]] additional css elements for the action box\n\t * @param {number} [override=0] override size adjust\n\t * @param {number} [content_override=0] override content size adjust\n\t */\n\tshowFillActionBox(target_id = 'actionBox', content = '', action_box_css = [], override = 0, content_override = 0)\n\t{\n\t\t// fill content\n\t\tthis.fillActionBox(target_id, content, action_box_css);\n\t\t// show the box\n\t\tthis.showActionBox(target_id, override, content_override);\n\t}\n\n\t/**\n\t * Fill action box with content, create it if it does not existgs\n\t * @param {string} [target_id='actionBox'] where to attach content to, if not exists, create new\n\t * @param {string} [content=''] content to add to the box\n\t * @param {array} [action_box_css=[]] additional css elements for the action box\n\t */\n\tfillActionBox(target_id = 'actionBox', content = '', action_box_css = [])\n\t{\n\t\t// show action box, calc height + center\n\t\tif (!exists(target_id)) {\n\t\t\t// add at the bottom\n\t\t\t$('#mainContainer').after(\n\t\t\t\tthis.hec.phfo(this.hec.cel('div', target_id, '', ['actionBoxElement', 'hide'].concat(action_box_css)))\n\t\t\t);\n\t\t}\n\t\t// add the info box\n\t\t$('#' + target_id).html(content);\n\t}\n\n\t/**\n\t * Adjust the size of the action box\n\t * @param {string} [target_id='actionBox'] which actionBox to work on\n\t * @param {number} [override=0] override size adjust\n\t * @param {number} [content_override=0] override content size adjust\n\t */\n\tadjustActionBox(target_id = 'actionBox', override = 0, content_override = 0)\n\t{\n\t\t// adjust box size\n\t\tthis.adjustActionBoxHeight(target_id, override, content_override);\n\t\t// center the alert box\n\t\tsetCenter(target_id, true, true);\n\t}\n\n\t/**\n\t * hide any open action boxes and hide overlay\n\t */\n\thideAllActionBoxes()\n\t{\n\t\t// hide all action boxes that might exist\n\t\t$('#actionBox, div[id^=\"actionBox-\"].actionBoxElement').hide();\n\t\t// hideOverlayBoxLayers();\n\t\t$('#overlayBox').hide();\n\t}\n\n\t/**\n\t * hide action box, but do not clear content\n\t * DEPRECATED\n\t * @param {string} [target_id='actionBox']\n\t */\n\thideActionBox(target_id = 'actionBox')\n\t{\n\t\tthis.closeActionBoxFloat(target_id, false);\n\t}\n\n\t/**\n\t * Just show and adjust the box\n\t * DEPRECAED\n\t * @param {string} [target_id='actionBox'] which actionBox to work on\n\t * @param {number} [override=0] override size adjust\n\t * @param {number} [content_override=0] override content size adjust\n\t * @param {Boolean} [hide_all=false] if set to true, hide all other action boxes\n\t */\n\tshowActionBox(target_id = 'actionBox', override = 0, content_override = 0, hide_all = true)\n\t{\n\t\tthis.showActionBoxFloat(target_id, override, content_override, hide_all);\n\t}\n\n\t/**\n\t * close an action box with default clear content\n\t * for just hide use hideActionBox\n\t * DEPRECATED\n\t * @param {String} [target_id='actionBox'] which action box to close, default is set\n\t * @param {Boolean} [clean=true] if set to false will not remove html content, just hide\n\t */\n\tcloseActionBox(target_id = 'actionBox', clean = true)\n\t{\n\t\t// set the target/content ids\n\t\tthis.closeActionBoxFloat(target_id, clean);\n\t}\n\n\t/**\n\t * TODO: better stacked action box: OPEN\n\t * @param {string} [target_id='actionBox'] which actionBox to work on\n\t * @param {number} [override=0] override size adjust\n\t * @param {number} [content_override=0] override content size adjust\n\t * @param {boolean} [hide_all=false] if set to true, hide all other action boxes\n\t */\n\tshowActionBoxFloat(target_id = 'actionBox', override = 0, content_override = 0, hide_all = false)\n\t{\n\t\tif (hide_all === true) {\n\t\t\t// hide all action boxes if they are currently open\n\t\t\tthis.hideAllActionBoxes();\n\t\t}\n\t\t// if no box, created if\n\t\tif (!exists('overlayBox')) {\n\t\t\t$('body').prepend(this.hec.phfo(this.hec.cel('div', 'overlayBox', '', ['overlayBoxElement'])));\n\t\t\t$('#overlayBox').css('zIndex', this.zIndex.base);\n\t\t}\n\t\t// adjust zIndex so its above all other and set action box zindex +1\n\t\t$('#overlayBox').show();\n\t\tif (!objectKeyExists(this.zIndex.boxes, target_id)) {\n\t\t\tthis.zIndex.boxes[target_id] = this.zIndex.max;\n\t\t\t// increase by ten\n\t\t\tthis.zIndex.max += 10;\n\t\t} else if (this.zIndex.boxes[target_id] + 10 < this.zIndex.max) {\n\t\t\t// see if this is the highest level, if not move up and write no max zIndex\n\t\t\t// move it up to be the new top and move the others down\n\t\t\t// [loop, order by value]\n\t\t\t// current hack, increase max\n\t\t\tthis.zIndex.boxes[target_id] = this.zIndex.max;\n\t\t\tthis.zIndex.max += 10;\n\t\t}\n\t\t// make sure the overlayBox is one level below this\n\t\t// unless there is an active \"indicator\" index\n\t\tif (!this.zIndex.indicator) {\n\t\t\t$('#overlayBox').css('zIndex', this.zIndex.boxes[target_id] - 1);\n\t\t}\n\t\t$('#' + target_id).css('zIndex', this.zIndex.boxes[target_id]).show();\n\t\t// set target to this new level\n\t\t// @ts-ignore\n\t\tif (this.zIndex.active.indexOf(target_id) == -1) {\n\t\t\t// @ts-ignore\n\t\t\tthis.zIndex.active.push(target_id);\n\t\t}\n\t\tthis.zIndex.top = target_id;\n\t\t// adjust size\n\t\tthis.adjustActionBox(target_id, override, content_override);\n\t}\n\n\t/**\n\t * TODO: better stacked action box: CLOSE\n\t * @param {String} [target_id='actionBox'] which action box to close, default is set\n\t * @param {Boolean} [clean=true] if set to false will not remove html content, just hide\n\t */\n\tcloseActionBoxFloat(target_id = 'actionBox', clean = true)\n\t{\n\t\t// do nothing if this does not exist\n\t\tif (!exists(target_id)) {\n\t\t\treturn;\n\t\t}\n\t\t// clear storage object\n\t\tif (\n\t\t\tobjectKeyExists(this.action_box_storage, target_id) && clean === true\n\t\t) {\n\t\t\tthis.action_box_storage[target_id] = {};\n\t\t}\n\t\tif (clean === true) {\n\t\t\t$('#' + target_id).html('');\n\t\t}\n\t\t$('#' + target_id).hide();\n\t\t// remove from active list\n\t\t// @ts-ignore\n\t\tlet idx = this.zIndex.active.indexOf(target_id);\n\t\tthis.zIndex.active.splice(idx, 1);\n\t\t// do we have any visible action boxes.\n\t\t// find the highest zIndex and set overlayBox to this -1\n\t\t// @ts-ignore\n\t\tlet visible_zIndexes = $('#actionBox:visible, div[id^=\"actionBox-\"].actionBoxElement:visible').map((i, el) => ({\n\t\t\tid: el.id,\n\t\t\tzIndex: $('#' + el.id).css('zIndex')\n\t\t})).get();\n\t\tif (visible_zIndexes.length > 0) {\n\t\t\tlet max_zIndex = 0;\n\t\t\tlet max_el_id = '';\n\t\t\tfor (let zIndex_el of visible_zIndexes) {\n\t\t\t\tif (parseInt(zIndex_el.zIndex) > max_zIndex) {\n\t\t\t\t\tmax_zIndex = parseInt(zIndex_el.zIndex);\n\t\t\t\t\tmax_el_id = zIndex_el.id;\n\t\t\t\t}\n\t\t\t}\n\t\t\t$('#overlayBox').css('zIndex', max_zIndex - 1);\n\t\t\tthis.zIndex.top = max_el_id;\n\t\t} else {\n\t\t\t$('#overlayBox').hide();\n\t\t}\n\t}\n\n\t/**\n\t * create a new action box and fill it with basic elements\n\t * @param {String} [target_id='actionBox']\n\t * @param {String} [title='']\n\t * @param {Object} [contents={}]\n\t * @param {Object} [headers={}]\n\t * @param {Boolean} [show_close=true]\n\t * @param {Object} [settings={}] Optional settings, eg style sheets\n\t */\n\tcreateActionBox(\n\t\ttarget_id = 'actionBox',\n\t\ttitle = '',\n\t\tcontents = {},\n\t\theaders = {},\n\t\tsettings = {},\n\t\tshow_close = true\n\t) {\n\t\tif (!objectKeyExists(this.action_box_storage, target_id)) {\n\t\t\tthis.action_box_storage[target_id] = {};\n\t\t}\n\t\t// settings can have the following\n\t\t// : header_css:[]\n\t\t// : action_box_css:[]\n\t\tlet header_css = [];\n\t\tif (objectKeyExists(settings, 'header_css')) {\n\t\t\theader_css = settings.header_css;\n\t\t}\n\t\tlet action_box_css = [];\n\t\tif (objectKeyExists(settings, 'action_box_css')) {\n\t\t\taction_box_css = settings.action_box_css;\n\t\t}\n\t\tlet elements = [];\n\t\t// add title + close button to actionBox\n\t\telements.push(this.hec.phfo(\n\t\t\tthis.hec.aelx(this.hec.cel('div', target_id + '_title', '', ['actionBoxTitle', 'flx-spbt'].concat(header_css)),\n\t\t\t\t...show_close === true ? [\n\t\t\t\t\t// title\n\t\t\t\t\tthis.hec.cel('div', '', title, ['fs-b', 'w-80']),\n\t\t\t\t\t// close button\n\t\t\t\t\tthis.hec.aelx(this.hec.cel('div', target_id + '_title_close_button', '', ['w-20', 'tar']),\n\t\t\t\t\t\tthis.hec.cel('input', target_id + '_title_close', '', ['button-close', 'fs-s'],\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: 'button',\n\t\t\t\t\t\t\t\tvalue: this.l10n.__('Close'),\n\t\t\t\t\t\t\t\tOnClick: 'closeActionBox(\\'' + target_id + '\\', false);'\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\t\tthis.hec.cel('div', '', title, ['fs-b', 'w-100'])\n\t\t\t\t]\n\t\t\t)\n\t\t));\n\t\t// if we have header content, add that here\n\t\tif (getObjectCount(headers) > 0) {\n\t\t\t// if the element has an entry called \"raw_string\" then this does not need to be converted\n\t\t\tif (objectKeyExists(headers, 'raw_string')) {\n\t\t\t\telements.push(headers.raw_string);\n\t\t\t} else {\n\t\t\t\telements.push(this.hec.phfo(headers));\n\t\t\t}\n\t\t}\n\t\t// main content part (this should NOT be empty), if empty, add empty _content block\n\t\tif (getObjectCount(contents) > 0) {\n\t\t\t// if the element has an entry called \"raw_string\" then this does not need to be converted\n\t\t\tif (objectKeyExists(contents, 'raw_string')) {\n\t\t\t\telements.push(contents.raw_string);\n\t\t\t} else {\n\t\t\t\telements.push(this.hec.phfo(contents));\n\t\t\t}\n\t\t} else {\n\t\t\telements.push(this.hec.phfo(this.hec.cel('div', target_id + '_content', '', [])));\n\t\t}\n\t\t// footer clear call\n\t\telements.push(this.hec.phfo(\n\t\t\tthis.hec.aelx(this.hec.cel('div', target_id + '_footer', '', ['pd-5', 'flx-spbt']),\n\t\t\t\t...show_close === true ? [\n\t\t\t\t\t// dummy spacer\n\t\t\t\t\tthis.hec.cel('div', '', '', ['fs-b', 'w-80']),\n\t\t\t\t\t// close button\n\t\t\t\t\tthis.hec.aelx(this.hec.cel('div', target_id + '_footer_close_button', '', ['tar', 'w-20']),\n\t\t\t\t\t\tthis.hec.cel('input', target_id + '_footer_close', '', ['button-close', 'fs-s'],\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: 'button',\n\t\t\t\t\t\t\t\tvalue: this.l10n.__('Close'),\n\t\t\t\t\t\t\t\tOnClick: 'closeActionBox(\\'' + target_id + '\\', false);'\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\t\tthis.hec.cel('div', '', '', ['fs-b', 'w-100'])\n\t\t\t\t]\n\t\t\t)\n\t\t));\n\t\telements.push(this.hec.phfo(this.hec.cel('input', target_id + '-cache_time', '', [], {\n\t\t\ttype: 'hidden',\n\t\t\tvalue: Date.now()\n\t\t})));\n\t\tthis.fillActionBox(target_id, elements.join(''), action_box_css);\n\t}\n\n\t/**\n\t * adjusts the action box height based on content and window height of browser\n\t * TODO: border on outside/and other margin things need to be added in overall adjustment\n\t * @param {String} [target_id='actionBox'] target id, if not set, fall back to default\n\t * @param {Number} [override=0] override value to add to the actionBox height\n\t * @param {Number} [content_override=0] override the value from _content block if it exists\n\t */\n\tadjustActionBoxHeight(target_id = 'actionBox', override = 0, content_override = 0)\n\t{\n\t\tvar new_height = 0;\n\t\tvar dim = {};\n\t\tvar abc_dim = {};\n\t\tvar content_id = '';\n\t\t// make sure it is a number\n\t\tif (isNaN(override)) {\n\t\t\toverride = 0;\n\t\t}\n\t\tif (isNaN(content_override)) {\n\t\t\tcontent_override = 0;\n\t\t}\n\t\t// set the target/content ids\n\t\tswitch (target_id) {\n\t\t\tcase 'actionBox':\n\t\t\t\tcontent_id = 'action_box';\n\t\t\t\tbreak;\n\t\t\tcase 'actionBoxSub':\n\t\t\t\tcontent_id ='action_box_sub';\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tcontent_id = target_id;\n\t\t\t\tbreak;\n\t\t}\n\t\t// first remove any height, left, top style entris from target and content blocks\n\t\t// @ts-ignore\n\t\t$.each([target_id, content_id + '_content'], function(i, v) {\n\t\t\t$('#' + v).css({\n\t\t\t\t'height': '',\n\t\t\t\t'width': ''\n\t\t\t});\n\t\t});\n\t\tif (exists(content_id + '_title')) {\n\t\t\tdim.height = $('#' + content_id + '_title').outerHeight();\n\t\t\tconsole.log('Target: %s, Action box Title: %s', target_id, dim.height);\n\t\t\tnew_height += dim.height ?? 0;\n\t\t}\n\t\tif (exists(content_id + '_header')) {\n\t\t\tdim.height = $('#' + content_id + '_header').outerHeight();\n\t\t\tconsole.log('Target: %s, Action box Header: %s', target_id, dim.height);\n\t\t\tnew_height += dim.height ?? 0;\n\t\t}\n\t\tif (exists(content_id + '_content')) {\n\t\t\tif (content_override > 0) {\n\t\t\t\tconsole.log('Target: %s, Action box Content Override: %s', target_id, content_override);\n\t\t\t\tnew_height += content_override;\n\t\t\t} else {\n\t\t\t\tabc_dim.height = $('#' + content_id + '_content').outerHeight();\n\t\t\t\tconsole.log('Target: %s, Action box Content: %s', target_id, abc_dim.height);\n\t\t\t\tnew_height += abc_dim.height ?? 0;\n\t\t\t}\n\t\t}\n\t\t// always there sets\n\t\tif (exists(content_id + '_footer')) {\n\t\t\tdim.height = $('#' + content_id + '_footer').outerHeight();\n\t\t\tconsole.log('Target: %s, Action box Footer: %s', target_id, dim.height);\n\t\t\tnew_height += dim.height ?? 0;\n\t\t}\n\t\t// get difference for the rest from outer box\n\t\t// console.log('Target: %s, Action box outer: %s, Content: %s, New: %s', target_id, $('#' + target_id).outerHeight(), $('#' + content_id + '_content').outerHeight(), new_height);\n\t\t// new_height += ($('#' + target_id).outerHeight() - new_height) + override;\n\t\tnew_height += override;\n\t\t// get border width top-bottom from action Box, we need to remove this from the final height\n\t\t// console.log('Target: %s, Border top: %s', target_id, $('#' + target_id).css('border-top-width'));\n\t\t// get window size and check if content is bigger\n\t\tvar viewport = getWindowSize();\n\t\tif (new_height >= viewport.height) {\n\t\t\t// resize the action box content and set overflow [of-s-y]\n\t\t\tif (exists(content_id + '_content')) {\n\t\t\t\tif (!$('#' + content_id + '_content').hasClass('of-s-y')) {\n\t\t\t\t\t$('#' + content_id + '_content').addClass('of-s-y');\n\t\t\t\t}\n\t\t\t}\n\t\t\tconsole.log('Target: %s, Viewport: %s, ActionBox (NH): %s, ABcontent: %s, ABouter: %s', target_id, viewport.height, new_height, abc_dim.height, $('#' + target_id).outerHeight());\n\t\t\t// the height off window - all - action box gives new action box height\n\t\t\tvar m_height = viewport.height - (new_height - (abc_dim.height ?? 0));\n\t\t\tconsole.log('Target: %s, New ABcontent: %s', target_id, m_height);\n\t\t\t$('#' + content_id + '_content').css('height', m_height + 'px');\n\t\t\tnew_height = new_height - (abc_dim.height ?? 0) + m_height;\n\t\t\tconsole.log('Target: %s, New Hight: %s', target_id, new_height);\n\t\t} else {\n\t\t\t// if size ok, check if overflow scoll is set, remove it\n\t\t\tif (exists(content_id + '_content')) {\n\t\t\t\tif ($('#' + content_id + '_content').hasClass('of-s-y')) {\n\t\t\t\t\t$('#' + content_id + '_content').removeClass('of-s-y');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconsole.log('Target: %s, Action Box new height: %s px (override %s px, content override %s px), window height: %s px, Visible Height: %s px', target_id, new_height, override, content_override, viewport.height, $('#' + content_id).outerHeight());\n\t\t// adjust height\n\t\t$('#' + target_id).css('height', new_height + 'px');\n\t}\n}\n\n// __EMD__\n", "/*\nDescription: Login access and menu\nDate: 2025//3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { LoginNavMenu };\nimport { isObject, getObjectCount } from './JavaScriptHelpers.mjs';\nimport { exists } from './DomHelpers.mjs';\n\nclass LoginNavMenu {\n\n\thec;\n\tl10n;\n\n\t/**\n\t * action box creator\n\t * @param {Object} hec HtmlElementCreator\n\t * @param {Object} l10n l10nTranslation\n\t */\n\tconstructor(hec, l10n)\n\t{\n\t\tthis.hec = hec;\n\t\tthis.l10n = l10n;\n\t}\n\n\t/**\n\t * create login string and logout button elements\n\t * @param {String} login_string the login string to show on the left\n\t * @param {String} [header_id='mainHeader'] the target for the main element block\n\t * if not set mainHeader is assumed\n\t * this is the target div for the \"loginRow\"\n\t */\n\tcreateLoginRow(login_string, header_id = 'mainHeader')\n\t{\n\t\t// if header does not exist, we do nothing\n\t\tif (exists(header_id)) {\n\t\t\t// that row must exist already, if not it must be the first in the \"mainHeader\"\n\t\t\tif (!exists('loginRow')) {\n\t\t\t\t$('#' + header_id).html(this.hec.phfo(this.hec.cel('div', 'loginRow', '', ['loginRow', 'flx-spbt'])));\n\t\t\t}\n\t\t\t// clear out just in case for first entry\n\t\t\t// fill with div name & login/logout button\n\t\t\t$('#loginRow').html(this.hec.phfo(this.hec.cel('div', 'loginRow-name', login_string)));\n\t\t\t$('#loginRow').append(this.hec.phfo(this.hec.cel('div', 'loginRow-info', '')));\n\t\t\t$('#loginRow').append(this.hec.phfo(\n\t\t\t\tthis.hec.aelx(\n\t\t\t\t\t// outer div\n\t\t\t\t\tthis.hec.cel('div', 'loginRow-logout'),\n\t\t\t\t\t// inner element\n\t\t\t\t\tthis.hec.cel('input', 'logout', '', [], {\n\t\t\t\t\t\tvalue: this.l10n.__('Logout'),\n\t\t\t\t\t\ttype: 'button',\n\t\t\t\t\t\tonClick: 'loginLogout()'\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t));\n\t\t}\n\t}\n\n\t/**\n\t * create the top nav menu that switches physical between pages\n\t * (edit access data based)\n\t * @param {Object} nav_menu the built nav menu with highlight info\n\t * @param {String} [header_id='mainHeader'] the target for the main element block\n\t * if not set mainHeader is assumed\n\t * this is the target div for the \"menuRow\"\n\t */\n\tcreateNavMenu(nav_menu, header_id = 'mainHeader')\n\t{\n\t\t// must be an object\n\t\tif (isObject(nav_menu) && getObjectCount(nav_menu) > 1) {\n\t\t\t// do we have more than one entry, if not, do not show (single page)\n\t\t\tif (!exists('menuRow')) {\n\t\t\t\t$('#' + header_id).html(this.hec.phfo(this.hec.cel('div', 'menuRow', '', ['menuRow', 'flx-s'])));\n\t\t\t}\n\t\t\tvar content = [];\n\t\t\t$.each(nav_menu, function(key, item) {\n\t\t\t\t// key is number\n\t\t\t\t// item is object with entries\n\t\t\t\tif (key != 0) {\n\t\t\t\t\tcontent.push(this.hec.phfo(this.hec.cel('div', '', '·', ['pd-2'])));\n\t\t\t\t}\n\t\t\t\t// ignore item.popup for now\n\t\t\t\tif (item.enabled) {\n\t\t\t\t\t// set selected based on window.location.href as the php set will not work\n\t\t\t\t\tif (window.location.href.indexOf(item.url) != -1) {\n\t\t\t\t\t\titem.selected = 1;\n\t\t\t\t\t}\n\t\t\t\t\t// create the entry\n\t\t\t\t\tcontent.push(this.hec.phfo(\n\t\t\t\t\t\tthis.hec.aelx(\n\t\t\t\t\t\t\tthis.hec.cel('div'),\n\t\t\t\t\t\t\tthis.hec.cel('a', '', item.name, ['pd-2'].concat(item.selected ? 'highlight': ''), {\n\t\t\t\t\t\t\t\thref: item.url\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\t$('#menuRow').html(content.join(''));\n\t\t} else {\n\t\t\t$('#menuRow').hide();\n\t\t}\n\t}\n\n}\n\n// __END__\n", "/*\n * general edit javascript\n * former name: edit.jq.js\n * This is the jquery version\n * NOTE: jquey parts will be deprecated\n*/\n\nimport {\n\terrorCatch as _errorCatch,\n\tisFunction as _isFunction,\n\texecuteFunctionByName as _executeFunctionByName,\n\tisObject as _isObject,\n\tgetObjectCount as _getObjectCount,\n\tkeyInObject as _keyInObject,\n\tgetKeyByValue as _getKeyByValue,\n\tvalueInObject as _valueInObject,\n\tdeepCopyFunction as _deepCopyFunction\n} from './utils/JavaScriptHelpers.mjs';\nimport {\n\tescapeHtml as _escapeHtml,\n\tunescapeHtml as _unescapeHtml,\n\thtml_options as _html_options,\n\thtml_options_block as _html_options_block,\n\thtml_options_refill as _html_options_refill\n} from './utils/HtmlHelpers.mjs';\nimport {\n\tloadEl as _loadEl,\n\tpop as _pop,\n\texpandTA as _expandTA,\n\texists as _exists\n} from './utils/DomHelpers.mjs';\nimport {\n\tdec2hex as _dec2hex,\n\tgetRandomIntInclusive as _getRandomIntInclusive,\n\troundPrecision as _roundPrecision\n} from './utils/MathHelpers.mjs';\nimport {\n\tformatString as _formatString,\n\tnumberWithCommas as _numberWithCommas,\n\tconvertLBtoBR as _convertLBtoBR\n} from './utils/StringHelpers.mjs';\nimport {\n\tgetTimestamp as _getTimestamp\n} from './utils/DateTimeHelpers.mjs';\nimport {\n\tgenerateId as _generateId,\n\trandomIdF as _randomIdF,\n} from './utils/UniqIdGenerators.mjs';\nimport {\n\tgetWindowSize as _getWindowSize,\n\tgetScrollOffset as _getScrollOffset,\n\tgetScrollOffsetOpener as _getScrollOffsetOpener,\n\tsetCenter as _setCenter,\n\tgoToPos as _goToPos,\n\tgoTo as _goTo\n} from './utils/ResizingAndMove.mjs';\nimport {\n\tformatBytes as _formatBytes,\n\tformatBytesLong as _formatBytesLong,\n\tstringByteFormat as _stringByteFormat\n} from './utils/FormatBytes.mjs';\nimport {\n\tparseQueryString as _parseQueryString,\n\tgetQueryStringParam as _getQueryStringParam,\n\thasUrlParameter as _hasUrlParameter,\n\tgetUrlParameter as _getUrlParameter,\n\tupdateUrlParameter as _updateUrlParameter,\n\tremoveUrlParameter as _removeUrlParameter,\n} from './utils/UrlParser.mjs';\nimport {\n\tloginLogout as _loginLogout,\n} from './utils/LoginLogout.mjs';\nimport {\n\tActionIndicatorOverlayBox,\n\tactionIndicator as _actionIndicator,\n\tactionIndicatorShow as _actionIndicatorShow,\n\tactionIndicatorHide as _actionIndicatorHide,\n\toverlayBoxShow as _overlayBoxShow,\n\toverlayBoxHide as _overlayBoxHide,\n\tsetOverlayBox as _setOverlayBox,\n\thideOverlayBox as _hideOverlayBox,\n\tClearCall as _ClearCall\n} from './utils/ActionIndicatorOverlayBox.mjs';\nimport { l10nTranslation } from './utils/l10nTranslation.mjs';\nimport { HtmlElementCreator } from './utils/HtmlElementCreator.mjs';\nimport { ActionBox } from './utils/ActionBox.mjs';\nimport { LoginNavMenu } from './utils/LoginNavMenu.mjs';\n\nlet aiob = new ActionIndicatorOverlayBox();\nlet hec = new HtmlElementCreator();\n// if ( undef === \"undefined\") {\n// @ts-ignore\n// eslint-disable-next-line no-undef\nlet l10n = new l10nTranslation(typeof i18n === \"undefined\" ? {} : i18n);\nlet ab = new ActionBox(hec, l10n);\nlet lnm = new LoginNavMenu(hec, l10n);\n\n// MARK: deprecated String/Number override\n\n/**\n * simple sprintf formater for replace\n * usage: \"{0} is cool, {1} is not\".format(\"Alpha\", \"Beta\");\n * First, checks if it isn't implemented yet.\n * @param {String} String.prototype.format string with elements to be replaced\n * @return {String} Formated string\n * @deprecated StringHelpers.formatString\n */\n// @ts-ignore\nif (!String.prototype.format) {\n\t// @ts-ignore\n\tString.prototype.format = function()\n\t{\n\t\tconsole.error('[DEPRECATED] use StringHelpers.formatString');\n\t\t// @ts-ignore\n\t\treturn _formatString(this, arguments);\n\t};\n}\n\n/**\n * round to digits (float)\n * @param {Number} Number.prototype.round Float type number to round\n * @param {Number} prec Precision to round to\n * @return {Float} Rounded number\n * @deprecated use MathHelpers.roundPrecision\n */\n// @ts-ignore\nif (Number.prototype.round) {\n\t// @ts-ignore\n\tNumber.prototype.round = function (prec) {\n\t\tconsole.error('[DEPRECATED] use MathHelpers.roundPrecision');\n\t\t// @ts-ignore\n\t\treturn _roundPrecision(this, prec);\n\t};\n}\n\n/**\n * escape HTML string\n * @param {String} String.prototype.escapeHTML HTML data string to be escaped\n * @return {String} escaped string\n * @deprecated use HtmlHelpers.escapeHtml\n */\n// @ts-ignore\nif (!String.prototype.escapeHTML) {\n\t// @ts-ignore\n\tString.prototype.escapeHTML = function() {\n\t\tconsole.error('[DEPRECATED] use HtmlHelpers.escapeHtml');\n\t\t// @ts-ignore\n\t\treturn _escapeHtml(this);\n\t};\n}\n\n/**\n * unescape a HTML encoded string\n * @param {String} String.prototype.unescapeHTML data with escaped entries\n * @return {String} HTML formated string\n * @deprecated use HtmlHelpers.unescapeHtml\n */\n// @ts-ignore\nif (!String.prototype.unescapeHTML) {\n\t// @ts-ignore\n\tString.prototype.unescapeHTML = function() {\n\t\tconsole.error('[DEPRECATED] use HtmlHelpers.unescapeHtml');\n\t\t// @ts-ignore\n\t\treturn _unescapeHtml(this);\n\t};\n}\n\n// MARK: general collection\n\n/**\n *\n * @param {String} string\n * @returns {String}\n */\n// @ts-ignore\nfunction escapeHtml(string) // eslint-disable-line no-unused-vars\n{\n\treturn _escapeHtml(string);\n}\n\n/**\n * round to digits (float)\n * @param {Number} number Float type number to round\n * @param {Number} prec Precision to round to\n * @return {Number} Rounded number\n */\n// @ts-ignore\nfunction roundPrecision(number, prec) // eslint-disable-line no-unused-vars\n{\n\treturn _roundPrecision(number, prec);\n}\n\n/**\n * simple sprintf formater for replace\n * usage: \"{0} is cool, {1} is not\".format(\"Alpha\", \"Beta\");\n * First, checks if it isn't implemented yet.\n * @param {String} string String with elements to be replaced\n * @return {String} Formated string\n * @deprecated StringHelpe\n */\n// @ts-ignore\nfunction formatString(string, ...args) // eslint-disable-line no-unused-vars\n{\n\treturn _formatString(string, ...args);\n}\n\n/**\n *\n * @param {String} string\n * @returns {String}\n */\n// @ts-ignore\nfunction unescapeHtml(string) // eslint-disable-line no-unused-vars\n{\n\treturn _unescapeHtml(string);\n}\n\n/**\n * Gets html element or throws an error\n * @param {string} el_id Element ID to get\n * @returns {HTMLElement}\n * @throws Error\n */\n// @ts-ignore\nfunction loadEl(el_id) // eslint-disable-line no-unused-vars\n{\n\treturn _loadEl(el_id);\n}\n\n/**\n * opens a pop_ window with winName and given features (string)\n * @param {String} theURL the url\n * @param {String} winName window name\n * @param {Object} features pop_ features\n */\n// @ts-ignore\nfunction pop(theURL, winName, features) // eslint-disable-line no-unused-vars\n{\n\t_pop(theURL, winName, features);\n}\n\n/**\n * automatically resize a text area based on the amount of lines in it\n * @param {string} ta_id element id\n */\n// @ts-ignore\nfunction expandTA(ta_id) // eslint-disable-line no-unused-vars\n{\n\t_expandTA(ta_id);\n}\n\n/**\n * wrapper to get the real window size for the current browser window\n * @return {Object} object with width/height\n */\n// @ts-ignore\nfunction getWindowSize() // eslint-disable-line no-unused-vars\n{\n\treturn _getWindowSize();\n}\n\n/**\n * wrapper to get the correct scroll offset\n * @return {Object} object with x/y px\n */\n// @ts-ignore\nfunction getScrollOffset() // eslint-disable-line no-unused-vars\n{\n\treturn _getScrollOffset();\n}\n\n/**\n * wrapper to get the correct scroll offset for opener page (from pop_)\n * @return {Object} object with x/y px\n */\n// @ts-ignore\nfunction getScrollOffsetOpener() // eslint-disable-line no-unused-vars\n{\n\treturn _getScrollOffsetOpener();\n}\n\n/**\n * centers div to current window size middle\n * @param {String} id element to center\n * @param {Boolean} left if true centers to the middle from the left\n * @param {Boolean} top if true centers to the middle from the top\n */\n// @ts-ignore\nfunction setCenter(id, left, top) // eslint-disable-line no-unused-vars\n{\n\t_setCenter(id, left, top);\n}\n\n/**\n * goes to an element id position\n * @param {String} element element id to move to\n * @param {Number} [offset=0] offset from top, default is 0 (px)\n * @param {Number} [duration=500] animation time, default 500ms\n * @param {String} [base='body,html'] base element for offset scroll\n */\n// @ts-ignore\nfunction goToPos(element, offset = 0, duration = 500, base = 'body,html') // eslint-disable-line no-unused-vars\n{\n\t_goToPos(element, offset, duration, base);\n}\n\n/**\n * go to element, scroll\n * non jquery\n * @param {string} target\n*/\n// @ts-ignore\nfunction goTo(target) // eslint-disable-line no-unused-vars\n{\n\t_goTo(target);\n}\n\n/**\n * uses the i18n object created in the translation template\n * that is filled from gettext in PHP\n * @param {String} string text to translate\n * @return {String} translated text (based on PHP selected language)\n */\n// @ts-ignore\nfunction __(string) // eslint-disable-line no-unused-vars\n{\n\treturn l10n.__(string);\n}\n\n/**\n * formats flat number 123456 to 123,456\n * @param {Number} x number to be formated\n * @return {String} formatted with , in thousands\n */\n// @ts-ignore\nfunction numberWithCommas(x) // eslint-disable-line no-unused-vars\n{\n\treturn _numberWithCommas(x);\n}\n\n/**\n * converts line breaks to br\n * @param {String} string any string\n * @return {String} string with
\n */\n// @ts-ignore\nfunction convertLBtoBR(string) // eslint-disable-line no-unused-vars\n{\n\treturn _convertLBtoBR(string);\n}\n\n/**\n * returns current timestamp (unix timestamp)\n * @return {Number} timestamp (in milliseconds)\n */\n// @ts-ignore\nfunction getTimestamp() // eslint-disable-line no-unused-vars\n{\n\treturn _getTimestamp();\n}\n\n/**\n * dec2hex :: Integer -> String\n * i.e. 0-255 -> '00'-'ff'\n * @param {Number} dec decimal string\n * @return {String} hex encdoded number\n */\n// @ts-ignore\nfunction dec2hex(dec) // eslint-disable-line no-unused-vars\n{\n\treturn _dec2hex(dec);\n}\n\n/**\n * generateId :: Integer -> String\n * only works on mondern browsers\n * @param {Number} len length of unique id string\n * @return {String} random string in length of len\n */\n// @ts-ignore\nfunction generateId(len) // eslint-disable-line no-unused-vars\n{\n\treturn _generateId(len);\n}\n\n/**\n * creates a pseudo random string of 10 characters\n * works on all browsers\n * after many runs it will create d_licates\n * @return {String} not true random string\n */\n// @ts-ignore\nfunction randomIdF() // eslint-disable-line no-unused-vars\n{\n\treturn _randomIdF();\n}\n\n/**\n * generate a number between min/max\n * with min/max inclusive.\n * eg: 1,5 will create a number ranging from 1 o 5\n * @param {Number} min minimum int number inclusive\n * @param {Number} max maximumg int number inclusive\n * @return {Number} Random number\n */\n// @ts-ignore\nfunction getRandomIntInclusive(min, max) // eslint-disable-line no-unused-vars\n{\n\treturn _getRandomIntInclusive(min, max);\n}\n\n/**\n * check if name is a function\n * @param {string} name Name of function to check if exists\n * @return {Boolean} true/false\n */\n// @ts-ignore\nfunction isFunction(name) // eslint-disable-line no-unused-vars\n{\n\treturn _isFunction(name);\n}\n\n/**\n * call a function by its string name\n * https://stackoverflow.com/a/359910\n * example: executeFunctionByName(\"My.Namespace.functionName\", window, arguments);\n * @param {string} functionName The function name or namespace + function\n * @param {any} context context (window or first namespace)\n * hidden next are all the arguments\n * @return {any} Return values from functon\n */\n// @ts-ignore\nfunction executeFunctionByName(functionName, context) // eslint-disable-line no-unused-vars\n{\n\treturn _executeFunctionByName(functionName, context);\n}\n\n/**\n * checks if a variable is an object\n * @param {any} val possible object\n * @return {Boolean} true/false if it is an object or not\n */\n// @ts-ignore\nfunction isObject(val) // eslint-disable-line no-unused-vars\n{\n\treturn _isObject(val);\n}\n\n/**\n * get the length of an object (entries)\n * @param {Object} object object to check\n * @return {Number} number of entry\n */\n// @ts-ignore\nfunction getObjectCount(object) // eslint-disable-line no-unused-vars\n{\n\treturn _getObjectCount(object);\n}\n\n/**\n * checks if a key exists in a given object\n * @param {String} key key name\n * @param {Object} object object to search key in\n * @return {Boolean} true/false if key exists in object\n */\n// @ts-ignore\nfunction keyInObject(key, object) // eslint-disable-line no-unused-vars\n{\n\treturn _keyInObject(key, object);\n}\n\n/**\n * returns matching key of value\n * @param {Object} object object to search value in\n * @param {any} value any value (String, Number, etc)\n * @return {String} the key found for the first matching value\n */\n// @ts-ignore\nfunction getKeyByValue(object, value) // eslint-disable-line no-unused-vars\n{\n\treturn _getKeyByValue(object, value);\n}\n\n/**\n * returns true if value is found in object with a key\n * @param {Object} object object to search value in\n * @param {any} value any value (String, Number, etc)\n * @return {Boolean} true on value found, false on not found\n */\n// @ts-ignore\nfunction valueInObject(object, value) // eslint-disable-line no-unused-vars\n{\n\treturn _valueInObject(object, value);\n}\n\n/**\n * true deep copy for Javascript objects\n * if Object.assign({}, obj) is not working (shallow)\n * or if JSON.parse(JSON.stringify(obj)) is failing\n * @param {Object} inObject Object to copy\n * @return {Object} Copied Object\n */\n// @ts-ignore\nfunction deepCopyFunction(inObject) // eslint-disable-line no-unused-vars\n{\n\treturn _deepCopyFunction(inObject);\n}\n\n/**\n * checks if a DOM element actually exists\n * @param {String} id Element id to check for\n * @return {Boolean} true if element exists, false on failure\n */\n// @ts-ignore\nfunction exists(id) // eslint-disable-line no-unused-vars\n{\n\treturn _exists(id);\n}\n\n/**\n * converts a int number into bytes with prefix in two decimals precision\n * currently precision is fixed, if dynamic needs check for max/min precision\n * @param {Number} bytes bytes in int\n * @return {String} string in GB/MB/KB\n */\n// @ts-ignore\nfunction formatBytes(bytes) // eslint-disable-line no-unused-vars\n{\n\treturn _formatBytes(bytes);\n}\n\n/**\n * like formatBytes, but returns bytes for <1KB and not 0.n KB\n * @param {Number} bytes bytes in int\n * @return {String} string in GB/MB/KB\n */\n// @ts-ignore\nfunction formatBytesLong(bytes) // eslint-disable-line no-unused-vars\n{\n\treturn _formatBytesLong(bytes);\n}\n\n/**\n * Convert a string with B/K/M/etc into a byte number\n * @param {String|Number} bytes Any string with B/K/M/etc\n * @return {String|Number} A byte number, or original string as is\n */\n// @ts-ignore\nfunction stringByteFormat(bytes) // eslint-disable-line no-unused-vars\n{\n\treturn _stringByteFormat(bytes);\n}\n\n/**\n * prints out error messages based on data available from the browser\n * @param {Object} err error from try/catch block\n */\n// @ts-ignore\nfunction errorCatch(err) // eslint-disable-line no-unused-vars\n{\n\t_errorCatch(err);\n}\n\n// MARK: ActionIndicatorOverlayBoxLegacy\n\n/*************************************************************\n * OLD action indicator and overlay boxes calls\n * DO NOT USE\n * actionIndicator -> showActionIndicator\n * actionIndicator -> hideActionIndicator\n * actionIndicatorShow -> showActionIndicator\n * actionIndicatorHide -> hideActionIndicator\n * overlayBoxShow -> showOverlayBoxLayers\n * overlayBoxHide -> hideOverlayBoxLayers\n * setOverlayBox -> showOverlayBoxLayers\n * hideOverlayBox -> hideOverlayBoxLayers\n * ClearCall -> ClearCallActionBox\n * ***********************************************************/\n\n/**\n * show or hide the \"do\" overlay\n * @param {String} loc location name for action indicator\n * default empty. for console.log\n * @param {Boolean} [overlay=true] override the auto hide/show over the overlay div block\n */\n// @ts-ignore\nfunction actionIndicator(loc, overlay = true) // eslint-disable-line no-unused-vars\n{\n\t_actionIndicator(loc, overlay);\n}\n\n/**\n * explicit show for action Indicator\n * instead of automatically show or hide, do on command show\n * @param {String} loc location name for action indicator\n * default empty. for console.log\n * @param {Boolean} [overlay=true] override the auto hide/show over the overlay div block\n */\n// @ts-ignore\nfunction actionIndicatorShow(loc, overlay = true) // eslint-disable-line no-unused-vars\n{\n\t_actionIndicatorShow(loc, overlay);\n}\n\n/**\n * explicit hide for action Indicator\n * instead of automatically show or hide, do on command hide\n * @param {String} loc location name for action indicator\n * default empty. for console.log\n * @param {Boolean} [overlay=true] override the auto hide/show over the overlay div block\n */\n// @ts-ignore\nfunction actionIndicatorHide(loc, overlay = true) // eslint-disable-line no-unused-vars\n{\n\t_actionIndicatorHide(loc, overlay);\n}\n\n/**\n * shows the overlay box or if already visible, bumps the zIndex to 100\n */\n// @ts-ignore\nfunction overlayBoxShow() // eslint-disable-line no-unused-vars\n{\n\t_overlayBoxShow();\n}\n\n/**\n * hides the overlay box or if zIndex is 100 bumps it down to previous level\n */\n// @ts-ignore\nfunction overlayBoxHide() // eslint-disable-line no-unused-vars\n{\n\t_overlayBoxHide();\n}\n\n/**\n * position the overlay block box and shows it\n */\n// @ts-ignore\nfunction setOverlayBox() // eslint-disable-line no-unused-vars\n{\n\t_setOverlayBox();\n}\n\n/**\n * opposite of set, always hides overlay box\n */\n// @ts-ignore\nfunction hideOverlayBox() // eslint-disable-line no-unused-vars\n{\n\t_hideOverlayBox();\n}\n\n/**\n * the abort call, clears the action box and hides it and the overlay box\n */\n// @ts-ignore\nfunction ClearCall() // eslint-disable-line no-unused-vars\n{\n\t_ClearCall();\n}\n\n// MARK: ActionIndicatorOverlayBox\n\n/*************************************************************\n * NEW action indicator and overlay box calls\n * USE THIS\n * ***********************************************************/\n\n/**\n * show action indicator\n * - checks if not existing and add\n * - only shows if not visible (else ignore)\n * - overlaybox check is called and shown on a fixzed\n * zIndex of 1000\n * - indicator is page centered\n * @param {String} loc ID string, only used for console log\n */\n// @ts-ignore\nfunction showActionIndicator(loc) // eslint-disable-line no-unused-vars\n{\n\taiob.showActionIndicator(loc);\n}\n\n/**\n * hide action indicator, if it is visiable\n * If the global variable GL_OB_S is > GL_OB_BASE then\n * the overlayBox is not hidden but the zIndex\n * is set to this value\n * @param {String} loc ID string, only used for console log\n */\n// @ts-ignore\nfunction hideActionIndicator(loc) // eslint-disable-line no-unused-vars\n{\n\taiob.hideActionIndicator(loc);\n}\n\n/**\n * checks if overlayBox exists, if not it is\n * added as hidden item at the body end\n */\n// @ts-ignore\nfunction checkOverlayExists() // eslint-disable-line no-unused-vars\n{\n\taiob.checkOverlayExists();\n}\n\n/**\n * show overlay box\n * if not visible show and set zIndex to 10 (GL_OB_BASE)\n * if visible, add +1 to the GL_OB_S variable and\n * _ zIndex by this value\n */\n// @ts-ignore\nfunction showOverlayBoxLayers(el_id) // eslint-disable-line no-unused-vars\n{\n\taiob.showOverlayBoxLayers(el_id);\n}\n\n/**\n * hide overlay box\n * lower GL_OB_S value by -1\n * if we are 10 (GL_OB_BASE) or below hide the overlayIndex\n * and set zIndex and GL_OB_S to 0\n * else just set zIndex to the new GL_OB_S value\n * @param {String} el_id Target to hide layer\n */\n// @ts-ignore\nfunction hideOverlayBoxLayers(el_id='') // eslint-disable-line no-unused-vars\n{\n\taiob.hideOverlayBoxLayers(el_id);\n}\n\n/**\n * only for single action box\n */\n// @ts-ignore\nfunction clearCallActionBox() // eslint-disable-line no-unused-vars\n{\n\taiob.clearCallActionBox();\n}\n\n// MARK: DOM MANAGEMENT FUNCTIONS\n/**\n * reates object for DOM element creation flow\n * @param {String} tag must set tag (div, span, etc)\n * @param {String} [id=''] optional set for id, if input, select will be used for name\n * @param {String} [content=''] text content inside, is skipped if sub elements exist\n * @param {Array} [css=[]] array for css tags\n * @param {Object} [options={}] anything else (value, placeholder, OnClick, style)\n * @return {Object} created element as an object\n */\n// @ts-ignore\nfunction cel(tag, id = '', content = '', css = [], options = {}) // eslint-disable-line no-unused-vars\n{\n\treturn hec.cel(tag, id, content, css, options);\n}\n\n/**\n * attach a cel created object to another to create a basic DOM tree\n * @param {Object} base object where to attach/search\n * @param {Object} attach the object to be attached\n * @param {String} [id=''] optional id, if given search in base for this id and attach there\n * @return {Object} \"none\", technically there is no return needed as it is global attach\n */\n// @ts-ignore\nfunction ael(base, attach, id = '') // eslint-disable-line no-unused-vars\n{\n\treturn hec.ael(base, attach, id);\n}\n\n/**\n * directly attach n elements to one master base element\n * this type does not s_port attach with optional id\n * @param {Object} base object to where we attach the elements\n * @param {...Object} attach attach 1..n: attach directly to the base element those attachments\n * @return {Object} \"none\", technically there is no return needed, global attach\n */\n// @ts-ignore\nfunction aelx(base, ...attach) // eslint-disable-line no-unused-vars\n{\n\treturn hec.aelx(base, ...attach);\n}\n\n/**\n * same as aelx, but instead of using objects as parameters\n * get an array of objects to attach\n * @param {Object} base object to where we attach the elements\n * @param {Array} attach array of objects to attach\n * @return {Object} \"none\", technically there is no return needed, global attach\n */\n// @ts-ignore\nfunction aelxar(base, attach) // eslint-disable-line no-unused-vars\n{\n\treturn hec.aelxar(base, attach);\n}\n\n/**\n * resets the sub elements of the base element given\n * @param {Object} base cel created element\n * @return {Object} returns reset base element\n */\n// @ts-ignore\nfunction rel(base) // eslint-disable-line no-unused-vars\n{\n\treturn hec.rel(base);\n}\n\n/**\n * searches and removes style from css array\n * @param {Object} _element element to work one\n * @param {String} css style sheet to remove (name)\n * @return {Object} returns full element\n */\n// @ts-ignore\nfunction rcssel(_element, css) // eslint-disable-line no-unused-vars\n{\n\treturn hec.rcssel(_element, css);\n}\n\n/**\n * adds a new style sheet to the element given\n * @param {Object} _element element to work on\n * @param {String} css style sheet to add (name)\n * @return {Object} returns full element\n */\n// @ts-ignore\nfunction acssel(_element, css) // eslint-disable-line no-unused-vars\n{\n\treturn hec.acssel(_element, css);\n}\n\n/**\n * removes one css and adds another\n * is a wrapper around rcssel/acssel\n * @param {Object} _element element to work on\n * @param {String} rcss style to remove (name)\n * @param {String} acss style to add (name)\n * @return {Object} returns full element\n */\n// @ts-ignore\nfunction scssel(_element, rcss, acss) // eslint-disable-line no-unused-vars\n{\n\thec.scssel(_element, rcss, acss);\n}\n\n/**\n * parses the object tree created with cel/ael and converts it into an HTML string\n * that can be inserted into the page\n * @param {Object} tree object tree with dom element declarations\n * @return {String} HTML string that can be used as innerHTML\n */\n// @ts-ignore\nfunction phfo(tree) // eslint-disable-line no-unused-vars\n{\n\treturn hec.phfo(tree);\n}\n\n/**\n * Create HTML elements from array list\n * as a flat element without master object file\n * Is like tree.sub call\n * @param {Array} list Array of cel created objects\n * @return {String} HTML String\n */\n// @ts-ignore\nfunction phfa(list) // eslint-disable-line no-unused-vars\n{\n\treturn hec.phfa(list);\n}\n// *** DOM MANAGEMENT FUNCTIONS\n\n// MARK: HTML Helpers\n// BLOCK: html wrappers for quickly creating html data blocks\n\n/**\n * NOTE: OLD FORMAT which misses multiple block set\n * creates an select/options drop down block.\n * the array needs to be key -> value format.\n * key is for the option id and value is for the data output\n * @param {String} name name/id\n * @param {Object} data array for the options\n * @param {String} [selected=''] selected item uid\n * @param {Boolean} [options_only=false] if this is true, it will not print the select part\n * @param {Boolean} [return_string=false] return as string and not as element\n * @param {String} [sort=''] if empty as is, else allowed 'keys',\n * 'values' all others are ignored\n * @return {String} html with build options block\n */\n// @ts-ignore\nfunction html_options(name, data, selected = '', options_only = false, return_string = false, sort = '') // eslint-disable-line no-unused-vars\n{\n\treturn _html_options(name, data, selected, options_only, return_string, sort);\n}\n\n/**\n * NOTE: USE THIS CALL, the above one is deprecated\n * creates an select/options drop down block.\n * the array needs to be key -> value format.\n * key is for the option id and value is for the data output\n * @param {String} name name/id\n * @param {Object} data array for the options\n * @param {String} [selected=''] selected item uid\n * @param {Number} [multiple=0] if this is 1 or larger, the drop down\n * will be turned into multiple select\n * the number sets the size value unless it is 1,\n * then it is default\n * @param {Boolean} [options_only=false] if this is true, it will not print the select part\n * @param {Boolean} [return_string=false] return as string and not as element\n * @param {String} [sort=''] if empty as is, else allowed 'keys',\n * 'values' all others are ignored\n * @param {String} [onchange=''] onchange trigger call, default unset\n * @return {String} html with build options block\n */\n// @ts-ignore\nfunction html_options_block( // eslint-disable-line no-unused-vars\n\tname, data, selected = '', multiple = 0, options_only = false, return_string = false, sort = '', onchange = ''\n) {\n\treturn _html_options_block(\n\t\tname, data, selected, multiple, options_only, return_string, sort, onchange\n\t);\n}\n\n/**\n * refills a select box with options and keeps the selected\n * @param {String} name name/id\n * @param {Object} data array of options\n * @param {String} [sort=''] if empty as is, else allowed 'keys', 'values'\n * all others are ignored\n */\n// @ts-ignore\nfunction html_options_refill(name, data, sort = '') // eslint-disable-line no-unused-vars\n{\n\t_html_options_refill(name, data, sort);\n}\n\n// MARK: URL\n\n/**\n * parses a query string from window.location.search.substring(1)\n * ALTERNATIVE CODE\n * var url = new URL(window.location.href);\n * param_uid = url.searchParams.get('uid');\n * @param {String} [query=''] the query string to parse, if not set will auto fill\n * @param {String} [return_key=''] if set only returns this key entry or empty for none\n * @param {Boolean} [single=false] if set to true then only the first found will be returned\n */\n// @ts-ignore\nfunction parseQueryString(query = '', return_key = '', single = false) // eslint-disable-line no-unused-vars\n{\n\treturn _parseQueryString(query, return_key, single);\n}\n\n/**\n * searches query parameters for entry and returns data either as string or array\n * if no search is given the whole parameters are returned as an object\n * if a parameter is set several times it will be returned as an array\n * if search parameter set and nothing found and empty string is returned\n * if no parametes exist and no serach is set and empty object is returned\n * @param {String} [search=''] if set searches for this entry, if empty all parameters are returned\n * @param {String} [query=''] different query string to parse, if not set (default) the current window href is used\n * @param {Boolean} [single=false] if set to true then only the first found will be returned\n * @return {Object|Array|String} if search is empty, object, if search is set\n * and only one entry, then string, else array\n * unless single is true\n */\n// @ts-ignore\nfunction getQueryStringParam(search = '', query = '', single = false) // eslint-disable-line no-unused-vars\n{\n\treturn _getQueryStringParam(search, query, single);\n}\n\n/**\n * Add or update a query parameter in the current URL and update the browser's address bar\n * @param {string} key - The parameter name to add or update\n * @param {string} value - The value to set for the parameter\n * @param {boolean} [reload=false] - Whether to reload the page after updating the URL\n */\n// @ts-ignore\nfunction updateUrlParameter(key, value, reload = false) // eslint-disable-line no-unused-vars\n{\n\treturn _updateUrlParameter(key, value, reload);\n}\n\n/**\n * Remove a parameter from the current URL and update the browser's address bar\n * @param {string} key - The parameter name to remove\n * @param {boolean} [reload=false] - Whether to reload the page after updating the URL\n */\n// @ts-ignore\nfunction removeUrlParameter(key, reload = false) // eslint-disable-line no-unused-vars\n{\n\treturn _removeUrlParameter(key, reload);\n}\n\n/**\n * Check if key exists as URL parameter\n * @param {String} key URL parameter to search\n * @returns {Boolean} True if key exists\n */\n// @ts-ignore\nfunction hasUrlParameter(key) // eslint-disable-line no-unused-vars\n{\n\treturn _hasUrlParameter(key);\n}\n\n/**\n * Return one value for a URL paramter or null if not found\n * @param {String} key Which URL parameter to get\n * @returns {String|Null} URL parameter content\n */\n// @ts-ignore\nfunction getUrlParameter(key) // eslint-disable-line no-unused-vars\n{\n\treturn _getUrlParameter(key);\n}\n\n// MARK: ACL LOGIN\n// *** MASTER logout call\n/**\n * submits basic data for form logout\n */\n// @ts-ignore\nfunction loginLogout() // eslint-disable-line no-unused-vars\n{\n\t_loginLogout();\n}\n\n/**\n * create login string and logout button elements\n * @param {String} login_string the login string to show on the left\n * @param {String} [header_id='mainHeader'] the target for the main element block\n * if not set mainHeader is assumed\n * this is the target div for the \"loginRow\"\n */\n// @ts-ignore\nfunction createLoginRow(login_string, header_id = 'mainHeader') // eslint-disable-line no-unused-vars\n{\n\tlnm.createLoginRow(login_string, header_id);\n}\n\n/**\n * create the top nav menu that switches physical between pages\n * (edit access data based)\n * @param {Object} nav_menu the built nav menu with highlight info\n * @param {String} [header_id='mainHeader'] the target for the main element block\n * if not set mainHeader is assumed\n * this is the target div for the \"menuRow\"\n */\n// @ts-ignore\nfunction createNavMenu(nav_menu, header_id = 'mainHeader') // eslint-disable-line no-unused-vars\n{\n\tlnm.createNavMenu(nav_menu, header_id);\n}\n\n// MARK: ACTION BOX\n\n/**\n * Show an action box\n * @param {string} [target_id='actionBox'] where to attach content to, if not exists, create new\n * @param {string} [content=''] content to add to the box\n * @param {array} [action_box_css=[]] additional css elements for the action box\n * @param {number} [override=0] override size adjust\n * @param {number} [content_override=0] override content size adjust\n */\n// @ts-ignore\nfunction showFillActionBox(target_id = 'actionBox', content = '', action_box_css = [], override = 0, content_override = 0) // eslint-disable-line no-unused-vars\n{\n\tab.showFillActionBox(target_id, content, action_box_css, override, content_override);\n}\n\n/**\n * Fill action box with content, create it if it does not existgs\n * @param {string} [target_id='actionBox'] where to attach content to, if not exists, create new\n * @param {string} [content=''] content to add to the box\n * @param {array} [action_box_css=[]] additional css elements for the action box\n */\n// @ts-ignore\nfunction fillActionBox(target_id = 'actionBox', content = '', action_box_css = []) // eslint-disable-line no-unused-vars\n{\n\t// show action box, calc height + center\n\tab.fillActionBox(target_id, content, action_box_css);\n}\n\n/**\n * Adjust the size of the action box\n * @param {string} [target_id='actionBox'] which actionBox to work on\n * @param {number} [override=0] override size adjust\n * @param {number} [content_override=0] override content size adjust\n */\n// @ts-ignore\nfunction adjustActionBox(target_id = 'actionBox', override = 0, content_override = 0) // eslint-disable-line no-unused-vars\n{\n\tab.adjustActionBox(target_id, override, content_override);\n}\n\n/**\n * hide any open action boxes and hide overlay\n */\n// @ts-ignore\nfunction hideAllActionBoxes() // eslint-disable-line no-unused-vars\n{\n\tab.hideAllActionBoxes();\n}\n\n/**\n * hide action box, but do not clear content\n * DEPRECATED\n * @param {string} [target_id='actionBox']\n */\n// @ts-ignore\nfunction hideActionBox(target_id = 'actionBox') // eslint-disable-line no-unused-vars\n{\n\tab.hideActionBox(target_id);\n}\n\n/**\n * Just show and adjust the box\n * DEPRECAED\n * @param {string} [target_id='actionBox'] which actionBox to work on\n * @param {number} [override=0] override size adjust\n * @param {number} [content_override=0] override content size adjust\n * @param {Boolean} [hide_all=false] if set to true, hide all other action boxes\n */\n// @ts-ignore\nfunction showActionBox(target_id = 'actionBox', override = 0, content_override = 0, hide_all = true) // eslint-disable-line no-unused-vars\n{\n\tab.showActionBox(target_id, override, content_override, hide_all);\n}\n\n/**\n * close an action box with default clear content\n * for just hide use hideActionBox\n * DEPRECATED\n * @param {String} [target_id='actionBox'] which action box to close, default is set\n * @param {Boolean} [clean=true] if set to false will not remove html content, just hide\n */\n// @ts-ignore\nfunction closeActionBox(target_id = 'actionBox', clean = true) // eslint-disable-line no-unused-vars\n{\n\t// set the target/content ids\n\tab.closeActionBox(target_id, clean);\n}\n\n/**\n * TODO: better stacked action box: OPEN\n * @param {string} [target_id='actionBox'] which actionBox to work on\n * @param {number} [override=0] override size adjust\n * @param {number} [content_override=0] override content size adjust\n * @param {Boolean} [hide_all=false] if set to true, hide all other action boxes\n */\n// @ts-ignore\nfunction showActionBoxFloat(target_id = 'actionBox', override = 0, content_override = 0, hide_all = false) // eslint-disable-line no-unused-vars\n{\n\tab.showActionBoxFloat(target_id, override, content_override, hide_all);\n}\n\n/**\n * TODO: better stacked action box: CLOSE\n * @param {String} [target_id='actionBox'] which action box to close, default is set\n * @param {Boolean} [clean=true] if set to false will not remove html content, just hide\n */\n// @ts-ignore\nfunction closeActionBoxFloat(target_id = 'actionBox', clean = true) // eslint-disable-line no-unused-vars\n{\n\tab.closeActionBoxFloat(target_id, clean);\n}\n\n/**\n * create a new action box and fill it with basic elements\n * @param {String} [target_id='actionBox']\n * @param {String} [title='']\n * @param {Object} [contents={}]\n * @param {Object} [headers={}]\n * @param {Boolean} [show_close=true]\n * @param {Object} [settings={}] Optional settings, eg style sheets\n */\n// @ts-ignore\nfunction createActionBox( // eslint-disable-line no-unused-vars\n\ttarget_id = 'actionBox',\n\ttitle = '',\n\tcontents = {},\n\theaders = {},\n\tsettings = {},\n\tshow_close = true\n) {\n\tab.createActionBox(target_id, title, contents, headers, settings, show_close);\n}\n\n/**\n * adjusts the action box height based on content and window height of browser\n * TODO: border on outside/and other margin things need to be added in overall adjustment\n * @param {String} [target_id='actionBox'] target id, if not set, fall back to default\n * @param {Number} [override=0] override value to add to the actionBox height\n * @param {Number} [content_override=0] override the value from _content block if it exists\n */\n// @ts-ignore\nfunction adjustActionBoxHeight(target_id = 'actionBox', override = 0, content_override = 0) // eslint-disable-line no-unused-vars\n{\n\tab.adjustActionBoxHeight(target_id, override, content_override);\n}\n\n/* END */\n"], - "mappings": "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", - "names": ["i18n", "hec", "l10n", "hec", "l10n", "escapeHtml", "roundPrecision", "formatString", "unescapeHtml", "loadEl", "pop", "expandTA", "getWindowSize", "getScrollOffset", "getScrollOffsetOpener", "setCenter", "goToPos", "goTo", "numberWithCommas", "convertLBtoBR", "getTimestamp", "dec2hex", "generateId", "randomIdF", "getRandomIntInclusive", "isFunction", "executeFunctionByName", "isObject", "getObjectCount", "keyInObject", "getKeyByValue", "valueInObject", "deepCopyFunction", "exists", "formatBytes", "formatBytesLong", "stringByteFormat", "errorCatch", "actionIndicator", "actionIndicatorShow", "actionIndicatorHide", "overlayBoxShow", "overlayBoxHide", "setOverlayBox", "hideOverlayBox", "ClearCall", "html_options", "html_options_block", "html_options_refill", "parseQueryString", "getQueryStringParam", "updateUrlParameter", "removeUrlParameter", "hasUrlParameter", "getUrlParameter", "loginLogout"] + "sources": ["../../../src/utils/JavaScriptHelpers.mjs", "../../../src/utils/DomHelpers.mjs", "../../../src/utils/HtmlElementCreator.mjs", "../../../src/utils/HtmlHelpers.mjs", "../../../src/utils/MathHelpers.mjs", "../../../src/utils/StringHelpers.mjs", "../../../src/utils/DateTimeHelpers.mjs", "../../../src/utils/UniqIdGenerators.mjs", "../../../src/utils/ResizingAndMove.mjs", "../../../src/utils/FormatBytes.mjs", "../../../src/utils/UrlParser.mjs", "../../../src/utils/LoginLogout.mjs", "../../../src/utils/ActionIndicatorOverlayBox.mjs", "../../../src/utils/l10nTranslation.mjs", "../../../src/utils/ActionBox.mjs", "../../../src/utils/LoginNavMenu.mjs", "../../../src/utils/BrowserDetect.mjs", "../../../src/utils.mjs"], + "sourcesContent": ["/*\nDescription: JavaScript Helpers\nDate: 2025/3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport {\n\terrorCatch, isFunction,\n\texecuteFunctionByName, runFunction, runFunctionArgsArray,\n\tisObject, isIterable, isArray, getObjectCount,\n\tkeyInObject, objectKeyExists,\n\tgetKeyByValue, valueInObject, objectValueExists,\n\tdeepCopyFunction\n};\n\n/**\n * prints out error messages based on data available from the browser\n * @param {Object} err error from try/catch block\n */\nfunction errorCatch(err)\n{\n\t// for FF & Chrome\n\tif (err.stack) {\n\t\t// only FF\n\t\tif (err.lineNumber) {\n\t\t\tconsole.error('ERROR[%s:%s] ', err.name, err.lineNumber, err);\n\t\t} else if (err.line) {\n\t\t\t// only Safari\n\t\t\tconsole.error('ERROR[%s:%s] ', err.name, err.line, err);\n\t\t} else {\n\t\t\tconsole.error('ERROR[%s] ', err.name, err);\n\t\t}\n\t} else if (err.number) {\n\t\t// IE\n\t\tconsole.error('ERROR[%s:%s] %s', err.name, err.number, err.message);\n\t\tconsole.error('ERROR[description] %s', err.description);\n\t} else {\n\t\t// the rest\n\t\tconsole.error('ERROR[%s] %s', err.name, err.message);\n\t}\n}\n\n/**\n * check if name is a function\n * @param {string} name Name of function to check if exists\n * @return {Boolean} true/false\n */\nfunction isFunction(name)\n{\n\tif (typeof window[name] !== 'undefined' &&\n\t\ttypeof window[name] === 'function') {\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n}\n\n/**\n * call a function by its string name\n * https://stackoverflow.com/a/359910\n * example: executeFunctionByName(\"My.Namespace.functionName\", window, arguments);\n * @param {string} functionName The function name or namespace + function\n * @param {any} context context (window or first namespace)\n * hidden next are all the arguments\n * @return {any} Return values from functon\n */\nfunction executeFunctionByName(functionName, context /*, args */)\n{\n\tvar args = Array.prototype.slice.call(arguments, 2);\n\tvar namespaces = functionName.split('.');\n\tvar func = namespaces.pop();\n\tif (func == undefined) {\n\t\tthrow new Error(\"Cannot get function from namespaces: \" + functionName);\n\t}\n\tfor (var i = 0; i < namespaces.length; i++) {\n\t\tcontext = context[namespaces[i]];\n\t}\n\treturn context[func].apply(context, args);\n}\n\n/**\n * call a function by string\n * call runFunctionArgArray\n * @param {string} name Function name to call\n * @param {Array} arguments all next function arguments are passed on as argument to the function\n * @returns void\n */\nfunction runFunction(name)\n{\n\tvar args = Array.prototype.slice.call(arguments, 1);\n\trunFunctionArgsArray(name, args);\n}\n\n/**\n * call a function with a string, argumens as array\n * @param {string} name Function name to call\n * @param {array} args function arguments as arry\n * @returns void\n */\nfunction runFunctionArgsArray(name, args)\n{\n\tvar fn = window[name];\n\tif(typeof fn !== 'function') {\n\t\treturn;\n\t}\n\n\tfn.apply(window, args);\n}\n\n/**\n * checks if a variable is an object\n * @param {any} val possible object\n * @return {Boolean} true/false if it is an object or not\n */\nfunction isObject(val)\n{\n\treturn val !== null && typeof val === 'object' && !Array.isArray(val);\n}\n\n/**\n * Check if variable is array\n * @param {any} val possible array\n * @returns {Boolean} true/false if it an array\n */\nfunction isArray(val)\n{\n\treturn val !== null && Array.isArray(val);\n}\n\n/**\n * Check if any iterable type\n * @param {any} val possible iteratable object/array\n * @returns {Boolean} true/false if it is iterable\n */\nfunction isIterable(val)\n{\n\tif (val == null) return false;\n\n\t// Check if it's iterable, but excldue strings\n\tif (typeof val[Symbol.iterator] === 'function' && typeof val !== 'string') return true;\n\n\t// Check if it's a plain object\n\treturn typeof val === 'object' && val.constructor === Object;\n}\n\n/**\n * get the length of an object (entries)\n * @param {Object} object object to check\n * @return {Number} number of entry, or -1 if not object\n */\nfunction getObjectCount(object)\n{\n\tif (!isObject(object)) {\n\t\treturn -1;\n\t}\n\treturn Object.keys(object).length;\n}\n\n/**\n * checks if a key exists in a given object\n * @param {String} key key name\n * @param {Object} object object to search key in\n * @return {Boolean} true/false if key exists in object\n * @deprecated Use objectKeyExists\n */\nfunction keyInObject(key, object)\n{\n\treturn objectKeyExists(object, key);\n}\n\n/**\n * This is the correct order and will superseed keyInObject\n * @param {Object} object object to search key in\n * @param {String} key key name\n * @returns {Boolean} true/false if key exists in object\n */\nfunction objectKeyExists(object, key)\n{\n\treturn Object.prototype.hasOwnProperty.call(object, key) ? true : false;\n}\n\n/**\n * returns matching key of value\n * @param {Object} object object to search value in\n * @param {any} value any value (String, Number, etc)\n * @return {String} the key found for the first matching value\n */\nfunction getKeyByValue(object, value)\n{\n\treturn Object.keys(object).find(key => object[key] === value) ?? '';\n}\n\n/**\n * returns true if value is found in object with a key\n * @param {Object} object object to search value in\n * @param {any} value any value (String, Number, etc)\n * @return {Boolean} true on value found, false on not found\n * @deprecated use objectValueExists\n */\nfunction valueInObject(object, value)\n{\n\treturn objectValueExists(object, value);\n}\n\n/**\n * returns true if value is found in object with a key\n * @param {Object} object object to search value in\n * @param {any} value any value (String, Number, etc)\n * @return {Boolean} true on value found, false on not found\n */\nfunction objectValueExists(object, value)\n{\n\treturn Object.keys(object).find(key => object[key] === value) ? true : false;\n}\n\n/**\n * true deep copy for Javascript objects\n * if Object.assign({}, obj) is not working (shallow)\n * or if JSON.parse(JSON.stringify(obj)) is failing\n * @param {Object} inObject Object to copy\n * @return {Object} Copied Object\n */\nfunction deepCopyFunction(inObject)\n{\n\tvar outObject, value, key;\n\tif (typeof inObject !== 'object' || inObject === null) {\n\t\t// Return the value if inObject is not an object\n\t\treturn inObject;\n\t}\n\t// Create an array or object to hold the values\n\toutObject = Array.isArray(inObject) ? [] : {};\n\t// loop over ech entry in object\n\tfor (key in inObject) {\n\t\tvalue = inObject[key];\n\t\t// Recursively (deep) copy for nested objects, including arrays\n\t\toutObject[key] = deepCopyFunction(value);\n\t}\n\n\treturn outObject;\n}\n\n// __END__\n", "/*\nDescription: DOM Helpers\nDate: 2025/3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { loadEl, pop, expandTA, exists };\n\n/**\n * Gets html element or throws an error\n * @param {string} el_id Element ID to get\n * @returns {HTMLElement}\n * @throws Error\n */\nfunction loadEl(el_id)\n{\n\tlet el = document.getElementById(el_id);\n\tif (el === null) {\n\t\tthrow new Error('Cannot find: ' + el_id);\n\t}\n\treturn el;\n}\n\n/**\n * opens a popup window with winName and given features (string)\n * @param {String} theURL the url\n * @param {String} winName window name\n * @param {Object} features popup features\n */\nfunction pop(theURL, winName, features)\n{\n\tlet __winName = window.open(theURL, winName, features);\n\tif (__winName == null) {\n\t\treturn;\n\t}\n\t__winName.focus();\n}\n\n/**\n * automatically resize a text area based on the amount of lines in it\n * @param {string} ta_id element id\n */\nfunction expandTA(ta_id)\n{\n\tlet ta = this.loadEl(ta_id);\n\tif (ta instanceof HTMLElement && ta.getAttribute('type') !== \"textarea\") {\n\t\tthrow new Error(\"Element is not a textarea: \" + ta_id);\n\t}\n\tlet maxChars = parseInt(ta.getAttribute('cols') ?? \"0\");\n\tlet ta_value = ta.getAttribute('value');\n\tlet theRows = [];\n\tif (ta_value != null) {\n\t\ttheRows = ta_value.split('\\n');\n\t}\n\tvar numNewRows = 0;\n\n\tfor ( var i = 0; i < theRows.length; i++ ) {\n\t\tif ((theRows[i].length+2) > maxChars) {\n\t\t\tnumNewRows += Math.ceil( (theRows[i].length+2) / maxChars ) ;\n\t\t}\n\t}\n\tta.setAttribute('row', (numNewRows + theRows.length).toString());\n}\n\n/**\n * checks if a DOM element actually exists\n * @param {String} id Element id to check for\n * @return {Boolean} true if element exists, false on failure\n */\nfunction exists(id)\n{\n\treturn $('#' + id).length > 0 ? true : false;\n}\n\n// __END__\n", "/*\nDescription: DOM Management and HTML builder\nDate: 2025/3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport {\n\tHtmlElementCreator,\n\t// deprecated name\n\tHtmlElementCreator as DomManagement\n};\nimport { deepCopyFunction, isObject, isArray } from './JavaScriptHelpers.mjs';\n\nclass HtmlElementCreator {\n\t/**\n\t * reates object for DOM element creation flow\n\t * @param {String} tag must set tag (div, span, etc)\n\t * @param {String} [id=''] optional set for id, if input, select will be used for name\n\t * @param {String} [content=''] text content inside, is skipped if sub elements exist\n\t * @param {Array} [css=[]] array for css tags\n\t * @param {Object} [options={}] anything else (value, placeholder, OnClick, style)\n\t * @return {Object} created element as an object\n\t */\n\tcel(tag, id = '', content = '', css = [], options = {})\n\t{\n\t\treturn {\n\t\t\ttag: tag,\n\t\t\tid: id,\n\t\t\t// override name if set, else id is used. Only for input/button\n\t\t\tname: options.name,\n\t\t\tcontent: content,\n\t\t\tcss: css,\n\t\t\toptions: options,\n\t\t\tsub: []\n\t\t};\n\t}\n\n\t/**\n\t * attach a cel created object to another to create a basic DOM tree\n\t * @param {Object} base object where to attach/search\n\t * @param {Object} attach the object to be attached\n\t * @param {String} [id=''] optional id, if given search in base for this id and attach there\n\t * @return {Object} \"none\", technically there is no return needed as it is global attach\n\t */\n\tael(base, attach, id = '')\n\t{\n\t\tif (id) {\n\t\t\t// base id match already\n\t\t\tif (base.id == id) {\n\t\t\t\tbase.sub.push(deepCopyFunction(attach));\n\t\t\t} else {\n\t\t\t\t// sub check\n\t\t\t\tif (isArray(base.sub) && base.sub.length > 0) {\n\t\t\t\t\tfor (var i = 0; i < base.sub.length; i ++) {\n\t\t\t\t\t\t// recursive call to sub element\n\t\t\t\t\t\tthis.ael(base.sub[i], attach, id);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tbase.sub.push(deepCopyFunction(attach));\n\t\t}\n\t\treturn base;\n\t}\n\n\t/**\n\t * directly attach n elements to one master base element\n\t * this type does not support attach with optional id\n\t * @param {Object} base object to where we attach the elements\n\t * @param {...Object} attach attach 1..n: attach directly to the base element those attachments\n\t * @return {Object} \"none\", technically there is no return needed, global attach\n\t */\n\taelx(base, ...attach)\n\t{\n\t\tfor (var i = 0; i < attach.length; i ++) {\n\t\t\tbase.sub.push(deepCopyFunction(attach[i]));\n\t\t}\n\t\treturn base;\n\t}\n\n\t/**\n\t * same as aelx, but instead of using objects as parameters\n\t * get an array of objects to attach\n\t * @param {Object} base object to where we attach the elements\n\t * @param {Array} attach array of objects to attach\n\t * @return {Object} \"none\", technically there is no return needed, global attach\n\t */\n\taelxar(base, attach)\n\t{\n\t\tfor (var i = 0; i < attach.length; i ++) {\n\t\t\tbase.sub.push(deepCopyFunction(attach[i]));\n\t\t}\n\t\treturn base;\n\t}\n\n\t/**\n\t * resets the sub elements of the base element given\n\t * @param {Object} base cel created element\n\t * @return {Object} returns reset base element\n\t */\n\trel(base)\n\t{\n\t\tbase.sub = [];\n\t\treturn base;\n\t}\n\n\t/**\n\t * searches and removes style from css array\n\t * @param {Object} _element element to work one\n\t * @param {String} css style sheet to remove (name)\n\t * @return {Object} returns full element\n\t */\n\trcssel(_element, css)\n\t{\n\t\tvar css_index = _element.css.indexOf(css);\n\t\tif (css_index > -1) {\n\t\t\t_element.css.splice(css_index, 1);\n\t\t}\n\t\treturn _element;\n\t}\n\n\t/**\n\t * adds a new style sheet to the element given\n\t * @param {Object} _element element to work on\n\t * @param {String} css style sheet to add (name)\n\t * @return {Object} returns full element\n\t */\n\tacssel(_element, css)\n\t{\n\t\tvar css_index = _element.css.indexOf(css);\n\t\tif (css_index == -1) {\n\t\t\t_element.css.push(css);\n\t\t}\n\t\treturn _element;\n\t}\n\n\t/**\n\t * removes one css and adds another\n\t * is a wrapper around rcssel/acssel\n\t * @param {Object} _element element to work on\n\t * @param {String} rcss style to remove (name)\n\t * @param {String} acss style to add (name)\n\t * @return {Object} returns full element\n\t */\n\tscssel(_element, rcss, acss)\n\t{\n\t\tthis.rcssel(_element, rcss);\n\t\tthis.acssel(_element, acss);\n\t\treturn _element;\n\t}\n\n\t/**\n\t * parses the object tree created with cel/ael and converts it into an HTML string\n\t * that can be inserted into the page\n\t * @param {Object} tree object tree with dom element declarations\n\t * @return {String} HTML string that can be used as innerHTML\n\t */\n\tphfo(tree)\n\t{\n\t\tlet name_elements = [\n\t\t\t'button',\n\t\t\t'fieldset',\n\t\t\t'form',\n\t\t\t'iframe',\n\t\t\t'input',\n\t\t\t'map',\n\t\t\t'meta',\n\t\t\t'object',\n\t\t\t'output',\n\t\t\t'param',\n\t\t\t'select',\n\t\t\t'textarea',\n\t\t];\n\t\tlet skip_options = [\n\t\t\t'id',\n\t\t\t'name',\n\t\t\t'class',\n\t\t];\n\t\tlet no_close = [\n\t\t\t'input',\n\t\t\t'br',\n\t\t\t'img',\n\t\t\t'hr',\n\t\t\t'area',\n\t\t\t'col',\n\t\t\t'keygen',\n\t\t\t'wbr',\n\t\t\t'track',\n\t\t\t'source',\n\t\t\t'param',\n\t\t\t'command',\n\t\t\t// only in header\n\t\t\t'base',\n\t\t\t'meta',\n\t\t\t'link',\n\t\t\t'embed',\n\t\t];\n\t\t// holds the elements\n\t\tvar content = [];\n\t\t// main part line\n\t\tvar line = '<' + tree.tag;\n\t\tvar i;\n\t\t// first id, if set\n\t\tif (tree.id) {\n\t\t\tline += ' id=\"' + tree.id + '\"';\n\t\t\t// if anything input (input, textarea, select then add name too)\n\t\t\tif (name_elements.includes(tree.tag)) {\n\t\t\t\tline += ' name=\"' + (tree.name ? tree.name : tree.id) + '\"';\n\t\t\t}\n\t\t}\n\t\t// second CSS\n\t\tif (isArray(tree.css) && tree.css.length > 0) {\n\t\t\tline += ' class=\"';\n\t\t\tfor (i = 0; i < tree.css.length; i ++) {\n\t\t\t\tline += tree.css[i] + ' ';\n\t\t\t}\n\t\t\t// strip last space\n\t\t\tline = line.slice(0, -1);\n\t\t\tline += '\"';\n\t\t}\n\t\t// options is anything key = \"data\"\n\t\tif (isObject(tree.options)) {\n\t\t\t// ignores id, name, class as key\n\t\t\tfor (const [key, item] of Object.entries(tree.options)) {\n\t\t\t\tif (!skip_options.includes(key)) {\n\t\t\t\t\tline += ' ' + key + '=\"' + item + '\"';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// finish open tag\n\t\tline += '>';\n\t\t// push finished line\n\t\tcontent.push(line);\n\t\t// dive into sub tree to attach sub nodes\n\t\t// NOTES: we can have content (text) AND sub nodes at the same level\n\t\t// CONTENT (TEXT) takes preference over SUB NODE in order\n\t\tif (isArray(tree.sub) && tree.sub.length > 0) {\n\t\t\tif (tree.content) {\n\t\t\t\tcontent.push(tree.content);\n\t\t\t}\n\t\t\tfor (i = 0; i < tree.sub.length; i ++) {\n\t\t\t\tcontent.push(this.phfo(tree.sub[i]));\n\t\t\t}\n\t\t} else if (tree.content) {\n\t\t\tcontent.push(tree.content);\n\t\t}\n\t\t// if not input, image or br, then close\n\t\tif (\n\t\t\t!no_close.includes(tree.tag)\n\t\t) {\n\t\t\tcontent.push('');\n\t\t}\n\t\t// combine to string\n\t\treturn content.join('');\n\t}\n\n\t/**\n\t * Create HTML elements from array list\n\t * as a flat element without master object file\n\t * Is like tree.sub call\n\t * @param {Array} list Array of cel created objects\n\t * @return {String} HTML String\n\t */\n\tphfa(list)\n\t{\n\t\tvar content = [];\n\t\tfor (var i = 0; i < list.length; i ++) {\n\t\t\tcontent.push(this.phfo(list[i]));\n\t\t}\n\t\treturn content.join('');\n\t}\n}\n\n// __EMD__\n", "/*\nDescription: HTML Helpers\nDate: 2025/3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { escapeHtml, unescapeHtml, html_options, html_options_block, html_options_refill };\nimport { loadEl} from './DomHelpers.mjs';\nimport { DomManagement } from './HtmlElementCreator.mjs';\nlet dom = new DomManagement();\n\n/**\n * Escapes HTML in string\n * @param {String} string Text to escape HTML in\n * @returns {String}\n */\nfunction escapeHtml(string)\n{\n\treturn string.replace(/[&<>\"'/]/g, function (s) {\n\t\tvar entityMap = {\n\t\t\t'&': '&',\n\t\t\t'<': '<',\n\t\t\t'>': '>',\n\t\t\t'\"': '"',\n\t\t\t'\\'': ''',\n\t\t\t'/': '/'\n\t\t};\n\n\t\treturn entityMap[s];\n\t});\n}\n\n/**\n * Unescape a HTML encoded string\n * @param {String} string Text to unescape HTML in\n * @returns {String}\n */\nfunction unescapeHtml(string)\n{\n\treturn string.replace(/&[#\\w]+;/g, function (s) {\n\t\tvar entityMap = {\n\t\t\t'&': '&',\n\t\t\t'<': '<',\n\t\t\t'>': '>',\n\t\t\t'"': '\"',\n\t\t\t''': '\\'',\n\t\t\t'/': '/'\n\t\t};\n\n\t\treturn entityMap[s];\n\t});\n}\n\n// BLOCK: html wrappers for quickly creating html data blocks\n\n/**\n * NOTE: OLD FORMAT which misses multiple block set\n * creates an select/options drop down block.\n * the array needs to be key -> value format.\n * key is for the option id and value is for the data output\n * @param {String} name name/id\n * @param {Object} data array for the options\n * @param {String} [selected=''] selected item uid\n * @param {Boolean} [options_only=false] if this is true, it will not print the select part\n * @param {Boolean} [return_string=false] return as string and not as element\n * @param {String} [sort=''] if empty as is, else allowed 'keys',\n * 'values' all others are ignored\n * @return {String} html with build options block\n * @deprecated html_options_block\n */\nfunction html_options(name, data, selected = '', options_only = false, return_string = false, sort = '')\n{\n\t// wrapper to new call\n\treturn this.html_options_block(\n\t\tname, data, selected, 0, options_only, return_string, sort\n\t);\n}\n\n/**\n * NOTE: USE THIS CALL, the above one is deprecated\n * creates an select/options drop down block.\n * the array needs to be key -> value format.\n * key is for the option id and value is for the data output\n * @param {String} name name/id\n * @param {Object} data array for the options\n * @param {String} [selected=''] selected item uid\n * @param {Number} [multiple=0] if this is 1 or larger, the drop down\n * will be turned into multiple select\n * the number sets the size value unless it is 1,\n * then it is default\n * @param {Boolean} [options_only=false] if this is true, it will not print the select part\n * @param {Boolean} [return_string=false] return as string and not as element\n * @param {String} [sort=''] if empty as is, else allowed 'keys',\n * 'values' all others are ignored\n * @param {String} [onchange=''] onchange trigger call, default unset\n * @return {String} html with build options block\n */\nfunction html_options_block(\n\tname, data, selected = '', multiple = 0, options_only = false, return_string = false, sort = '', onchange = ''\n) {\n\tvar content = [];\n\tvar element_select;\n\tvar select_options = {};\n\tvar element_option;\n\tvar data_list = []; // for sorted output\n\tvar value;\n\tvar options = {};\n\t// var option;\n\tif (multiple > 0) {\n\t\tselect_options.multiple = '';\n\t\tif (multiple > 1) {\n\t\t\tselect_options.size = multiple;\n\t\t}\n\t}\n\tif (onchange) {\n\t\tselect_options.OnChange = onchange;\n\t}\n\t// set outside select, gets stripped on return if options only is true\n\telement_select = dom.cel('select', name, '', [], select_options);\n\t// console.log('Call for %s, options: %s', name, options_only);\n\tif (sort == 'keys') {\n\t\tdata_list = Object.keys(data).sort();\n\t} else if (sort == 'values') {\n\t\tdata_list = Object.keys(data).sort((a, b) => ('' + data[a]).localeCompare(data[b]));\n\t} else {\n\t\tdata_list = Object.keys(data);\n\t}\n\t// console.log('ORDER: %s', data_list);\n\t// use the previously sorted list\n\t// for (const [key, value] of Object.entries(data)) {\n\tfor (const key of data_list) {\n\t\tvalue = data[key];\n\t\t// console.log('create [%s] options: key: %s, value: %s', name, key, value);\n\t\t// basic options init\n\t\toptions = {\n\t\t\t'label': value,\n\t\t\t'value': key,\n\t\t\t'selected': ''\n\t\t};\n\t\t// add selected if matching\n\t\tif (multiple == 0 && !Array.isArray(selected) && selected == key) {\n\t\t\toptions.selected = '';\n\t\t}\n\t\t// for multiple, we match selected as array\n\t\tif (multiple == 1 && Array.isArray(selected) && selected.indexOf(key) != -1) {\n\t\t\toptions.selected = '';\n\t\t}\n\t\t// create the element option\n\t\telement_option = dom.cel('option', '', value, [], options);\n\t\t// attach it to the select element\n\t\tdom.ael(element_select, element_option);\n\t}\n\t// if with select part, convert to text\n\tif (!options_only) {\n\t\tif (return_string) {\n\t\t\tcontent.push(dom.phfo(element_select));\n\t\t\treturn content.join('');\n\t\t} else {\n\t\t\treturn element_select;\n\t\t}\n\t} else {\n\t\t// strip select part\n\t\tif (return_string) {\n\t\t\tfor (var i = 0; i < element_select.sub.length; i ++) {\n\t\t\t\tcontent.push(dom.phfo(element_select.sub[i]));\n\t\t\t}\n\t\t\treturn content.join('');\n\t\t} else {\n\t\t\treturn element_select.sub;\n\t\t}\n\t}\n}\n\n/**\n * refills a select box with options and keeps the selected\n * @param {String} name name/id\n * @param {Object} data array of options\n * @param {String} [sort=''] if empty as is, else allowed 'keys', 'values'\n * all others are ignored\n */\nfunction html_options_refill(name, data, sort = '')\n{\n\tvar element_option;\n\tvar option_selected;\n\tvar data_list = []; // for sorted output\n\tvar value;\n\t// skip if not exists\n\tif (document.getElementById(name)) {\n\t\t// console.log('Call for %s, options: %s', name, options_only);\n\t\tif (sort == 'keys') {\n\t\t\tdata_list = Object.keys(data).sort();\n\t\t} else if (sort == 'values') {\n\t\t\tdata_list = Object.keys(data).sort((a, b) => ('' + data[a]).localeCompare(data[b]));\n\t\t} else {\n\t\t\tdata_list = Object.keys(data);\n\t\t}\n\t\t// first read in existing ones from the options and get the selected one\n\t\t[].forEach.call(document.querySelectorAll('#' + name + ' :checked'), function(elm) {\n\t\t\toption_selected = elm.value;\n\t\t});\n\t\tloadEl(name).innerHTML = '';\n\t\tfor (const key of data_list) {\n\t\t\tvalue = data[key];\n\t\t\t// console.log('add [%s] options: key: %s, value: %s', name, key, value);\n\t\t\telement_option = document.createElement('option');\n\t\t\telement_option.label = value;\n\t\t\telement_option.value = key;\n\t\t\telement_option.innerHTML = value;\n\t\t\tif (key == option_selected) {\n\t\t\t\telement_option.selected = true;\n\t\t\t}\n\t\t\tloadEl(name).appendChild(element_option);\n\t\t}\n\t}\n}\n\n// __EMD__\n", "/*\nDescription: Math Helpers\nDate: 2025/3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { dec2hex, getRandomIntInclusive, roundPrecision };\n\n/**\n * dec2hex :: Integer -> String\n * i.e. 0-255 -> '00'-'ff'\n * @param {Number} dec decimal string\n * @return {String} hex encdoded number, prefix with 0x\n */\nfunction dec2hex(dec)\n{\n\treturn ('0x' + dec.toString(16)).substring(-2);\n}\n\n/**\n * generate a number between min/max\n * with min/max inclusive.\n * eg: 1,5 will create a number ranging from 1 o 5\n * @param {Number} min minimum int number inclusive\n * @param {Number} max maximum int number inclusive\n * @return {Number} Random number\n */\nfunction getRandomIntInclusive(min, max)\n{\n\tmin = Math.ceil(min);\n\tmax = Math.floor(max);\n\t// The maximum is inclusive and the minimum is inclusive\n\treturn Math.floor(Math.random() * (max - min + 1) + min);\n}\n\n/**\n * Round a number to precision\n * @param {Number} number Number to round\n * @param {Number} precision Precision value\n * @returns {Number}\n */\nfunction roundPrecision(number, precision)\n{\n\tif (isNaN(number) || isNaN(precision)) {\n\t\treturn number;\n\t}\n\treturn Math.round(number * Math.pow(10, precision)) / Math.pow(10, precision);\n}\n\n// __END__\n", "/*\nDescription: String Helpers\nDate: 2025/3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { formatString, numberWithCommas, convertLBtoBR };\n\n/**\n * simple sprintf formater for replace\n * usage: formatString(\"{0} is cool, {1} is not\", \"Alpha\", \"Beta\");\n * First, checks if it isn't implemented yet.\n * @param {String} string String with {..} entries\n * @param {...any} args List of replacement\n * @returns {String} Escaped string\n */\nfunction formatString(string, ...args)\n{\n\treturn string.replace(/{(\\d+)}/g, function(match, number)\n\t{\n\t\treturn typeof args[number] != 'undefined' ?\n\t\t\targs[number] :\n\t\t\tmatch\n\t\t;\n\t});\n}\n/**\n * formats flat number 123456 to 123,456\n * @param {Number} number number to be formated\n * @return {String} formatted with , in thousands\n */\nfunction numberWithCommas(number)\n{\n\tvar parts = number.toString().split('.');\n\tparts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n\treturn parts.join('.');\n}\n\n/**\n * converts line breaks to br\n * @param {String} string any string\n * @return {String} string with
\n */\nfunction convertLBtoBR(string)\n{\n\treturn string.replace(/(?:\\r\\n|\\r|\\n)/g, '
');\n}\n\n// __END__\n", "/*\nDescription: Date Time functions\nDate: 2025/3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { getTimestamp };\n\n/**\n * returns current timestamp (unix timestamp)\n * @return {Number} timestamp (in milliseconds)\n */\nfunction getTimestamp()\n{\n\tvar date = new Date();\n\treturn date.getTime();\n}\n\n// __END__\n", "/*\nDescription: Generate unique ids\nDate: 2025/3/7\nCreator: Clemens Schwaighofer\n*/\n\nexport { generateId, randomIdF };\n\n\n/**\n * generateId :: Integer -> String\n * only works on mondern browsers\n * @param {Number} len length of unique id string\n * @return {String} random string in length of len\n */\nfunction generateId(len)\n{\n\tvar arr = new Uint8Array((len || 40) / 2);\n\t(\n\t\twindow.crypto ||\n\t\t// @ts-ignore\n\t\twindow.msCrypto\n\t).getRandomValues(arr);\n\treturn Array.from(arr, self.dec2hex).join('');\n}\n\n/**\n * creates a pseudo random string of 10 or 11 characters\n * works on all browsers\n * after many runs it will create duplicates\n * NOTE: no idea why this sometimes returns 10 or 11\n * @return {String} not true random string\n */\nfunction randomIdF()\n{\n\treturn Math.random().toString(36).substring(2);\n}\n", "/*\nDescription: Resize and Move Javascript\nDate: 2025/3/6\nCreator: Clemens Schwaighofer\n*/\n\nimport { errorCatch} from './JavaScriptHelpers.mjs';\nimport { loadEl } from './DomHelpers.mjs';\nexport { getWindowSize, getScrollOffset, getScrollOffsetOpener, setCenter, goToPos, goTo };\n\n/**\n * wrapper to get the real window size for the current browser window\n * @return {Object} object with width/height\n */\nfunction getWindowSize()\n{\n\tvar width, height;\n\twidth = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth);\n\theight = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);\n\treturn {\n\t\twidth: width,\n\t\theight: height\n\t};\n}\n\n/**\n * wrapper to get the correct scroll offset\n * @return {Object} object with x/y px\n */\nfunction getScrollOffset()\n{\n\tvar left, top;\n\tleft = window.pageXOffset || (window.document.documentElement.scrollLeft || window.document.body.scrollLeft);\n\ttop = window.pageYOffset || (window.document.documentElement.scrollTop || window.document.body.scrollTop);\n\treturn {\n\t\tleft: left,\n\t\ttop: top\n\t};\n}\n\n/**\n * wrapper to get the correct scroll offset for opener page (from popup)\n * @return {Object} object with x/y px\n */\nfunction getScrollOffsetOpener()\n{\n\tvar left, top;\n\tleft = opener.window.pageXOffset || (opener.document.documentElement.scrollLeft || opener.document.body.scrollLeft);\n\ttop = opener.window.pageYOffset || (opener.document.documentElement.scrollTop || opener.document.body.scrollTop);\n\treturn {\n\t\tleft: left,\n\t\ttop: top\n\t};\n}\n\n/**\n * centers div to current window size middle\n * @param {String} id element to center\n * @param {Boolean} left if true centers to the middle from the left\n * @param {Boolean} top if true centers to the middle from the top\n */\nfunction setCenter(id, left, top)\n{\n\t// get size of id\n\tvar dimensions = {\n\t\theight: $('#' + id).height() ?? 0,\n\t\twidth: $('#' + id).width() ?? 0\n\t};\n\tvar type = $('#' + id).css('position');\n\tvar viewport = this.getWindowSize();\n\tvar offset = this.getScrollOffset();\n\n\t// console.log('Id %s, type: %s, dimensions %s x %s, viewport %s x %s', id, type, dimensions.width, dimensions.height, viewport.width, viewport.height);\n\t// console.log('Scrolloffset left: %s, top: %s', offset.left, offset.top);\n\t// console.log('Left: %s, Top: %s (%s)', parseInt((viewport.width / 2) - (dimensions.width / 2) + offset.left), parseInt((viewport.height / 2) - (dimensions.height / 2) + offset.top), parseInt((viewport.height / 2) - (dimensions.height / 2)));\n\tif (left) {\n\t\t$('#' + id).css({\n\t\t\tleft: (viewport.width / 2) - (dimensions.width / 2) + offset.left + 'px'\n\t\t});\n\t}\n\tif (top) {\n\t\t// if we have fixed, we do not add the offset, else it moves out of the screen\n\t\tvar top_pos = type == 'fixed' ?\n\t\t\t(viewport.height / 2) - (dimensions.height / 2) :\n\t\t\t(viewport.height / 2) - (dimensions.height / 2) + offset.top;\n\t\t$('#' + id).css({\n\t\t\ttop: top_pos + 'px'\n\t\t});\n\t}\n}\n\n/**\n * goes to an element id position\n * @param {String} element element id to move to\n * @param {Number} [offset=0] offset from top, default is 0 (px)\n * @param {Number} [duration=500] animation time, default 500ms\n * @param {String} [base='body,html'] base element for offset scroll\n */\nfunction goToPos(element, offset = 0, duration = 500, base = 'body,html')\n{\n\ttry {\n\t\tlet element_offset = $('#' + element).offset();\n\t\tif (element_offset == undefined) {\n\t\t\treturn;\n\t\t}\n\t\tif ($('#' + element).length) {\n\t\t\t$(base).animate({\n\t\t\t\tscrollTop: element_offset.top - offset\n\t\t\t}, duration);\n\t\t}\n\t} catch (err) {\n\t\terrorCatch(err);\n\t}\n}\n\n/**\n * go to element, scroll\n * non jquery\n * @param {string} target\n*/\nfunction goTo(target)\n{\n\tloadEl(target).scrollIntoView({\n\t\tbehavior: 'smooth'\n\t});\n}\n\n// __END__\n", "/*\nDescription: Byte string formatting\nDate: 2025/3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { formatBytes, formatBytesLong, stringByteFormat };\n\n/**\n * converts a int number into bytes with prefix in two decimals precision\n * currently precision is fixed, if dynamic needs check for max/min precision\n * @param {Number|BigInt} bytes bytes in int\n * @return {String} string in GB/MB/KB\n */\nfunction formatBytes(bytes)\n{\n\tvar i = -1;\n\t// If this ia bigint -> convert to number, we need the decimals\n\tif (typeof bytes === \"bigint\") {\n\t\tbytes = Number(bytes);\n\t}\n\tif (isNaN(bytes)) {\n\t\treturn bytes.toString();\n\t}\n\tdo {\n\t\tbytes = bytes / 1024;\n\t\ti++;\n\t} while (bytes > 99);\n\treturn (\n\t\tMath.round(bytes * Math.pow(10, 2)) / Math.pow(10, 2)\n\t) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];\n}\n\n/**\n * like formatBytes, but returns bytes for <1KB and not 0.n KB\n * @param {Number|BigInt} bytes bytes in int\n * @return {String} string in GB/MB/KB\n */\nfunction formatBytesLong(bytes)\n{\n\t// If this ia bigint -> convert to number, we need the decimals\n\tif (typeof bytes === \"bigint\") {\n\t\tbytes = Number(bytes);\n\t}\n\tif (isNaN(bytes)) {\n\t\treturn bytes.toString();\n\t}\n\tlet negative = false;\n\tif (bytes < 0) {\n\t\tnegative = true;\n\t\tbytes *= -1;\n\t}\n\tvar i = Math.floor(Math.log(bytes) / Math.log(1024));\n\tvar sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n\treturn (negative ? '-' : '') + (\n\t\t(\n\t\t\tbytes /\n\t\t\tMath.pow(1024, i)\n\t\t).toFixed(2)\n\t\t// * 1 + ' ' + sizes[i]\n\t\t+ ' ' + sizes[i]\n\t).toString();\n}\n\n/**\n * Convert a string with B/K/M/etc into a byte number\n * @param {String|Number|Object} bytes Any string with B/K/M/etc\n * @param {Boolean} raw [default=false] Return not rounded values\n * @return {String|Number} A byte number, or original string as is\n */\nfunction stringByteFormat(bytes, raw=false)\n{\n\t// if anything not string return\n\tif (!(typeof bytes === 'string' || bytes instanceof String)) {\n\t\treturn bytes.toString();\n\t}\n\t// for pow exponent list\n\tlet valid_units = 'bkmgtpezy';\n\t// valid string that can be converted\n\tlet regex = /([\\d.,]*)\\s?(eb|pb|tb|gb|mb|kb|e|p|t|g|m|k|b)$/i;\n\tlet matches = bytes.match(regex);\n\t// if nothing found, return original input\n\tif (matches !== null) {\n\t\t// remove all non valid entries outside numbers and .\n\t\t// convert to float number\n\t\tlet m1 = parseFloat(matches[1].replace(/[^0-9.]/,''));\n\t\t// only get the FIRST letter from the size, convert it to lower case\n\t\tlet m2 = matches[2].replace(/[^bkmgtpezy]/i, '').charAt(0).toLowerCase();\n\t\tif (m2) {\n\t\t\t// use the position in the valid unit list to do the math conversion\n\t\t\tbytes = m1 * Math.pow(1024, valid_units.indexOf(m2));\n\t\t}\n\t}\n\t// if we want to have the raw data returned\n\tif (raw) {\n\t\treturn bytes;\n\t}\n\treturn Math.round(bytes);\n}\n\n// __END__\n", "/*\nDescription: HTML Helpers\nDate: 2025/3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { parseQueryString, getQueryStringParam, hasUrlParameter, getUrlParameter, updateUrlParameter, removeUrlParameter };\n\n/**\n * NOTE: this original code was wrong, now using URL and parsing through\n * getQueryStringParam\n * parses a query string from window.location.search.substring(1)\n * ALTERNATIVE CODE\n * var url = new URL(window.location.href);\n * param_uid = url.searchParams.get('uid');\n * @param {String} [query=''] the query string to parse, if not set will auto fill\n * @param {String} [return_key=''] if set only returns this key entry or empty for none\n * @param {Boolean} [single=false] if set to true then only the first found will be returned\n * @return {Object|String} parameter entry list\n */\nfunction parseQueryString(query = '', return_key = '', single = false)\n{\n\treturn getQueryStringParam(return_key, query, single);\n}\n\n/**\n * searches query parameters for entry and returns data either as string or array\n * if no search is given the whole parameters are returned as an object\n * if a parameter is set several times it will be returned as an array\n * if search parameter set and nothing found and empty string is returned\n * if no parametes exist and no serach is set and empty object is returned\n * @param {String} [search=''] if set searches for this entry, if empty all parameters are returned\n * @param {String} [query=''] different query string to parse, if not set (default) the current window href is used\n * @param {Boolean} [single=false] if set to true then only the first found will be returned\n * @return {Object|Array|String} if search is empty, object, if search is set\n * and only one entry, then string, else array\n * unless single is true\n */\nfunction getQueryStringParam(search = '', query = '', single = false)\n{\n\tif (!query) {\n\t\tquery = window.location.href;\n\t}\n\tconst url = new URL(query);\n\tlet param = null;\n\tif (search) {\n\t\tlet _params = url.searchParams.getAll(search);\n\t\tif (_params.length == 1 || single === true) {\n\t\t\tparam = _params[0];\n\t\t} else if (_params.length > 1) {\n\t\t\tparam = _params;\n\t\t}\n\t} else {\n\t\t// will be object, so declare it one\n\t\tparam = {};\n\t\t// loop over paramenters\n\t\tfor (const [key] of url.searchParams.entries()) {\n\t\t\t// check if not yet set\n\t\t\tif (typeof param[key] === 'undefined') {\n\t\t\t\t// get the parameters multiple\n\t\t\t\tlet _params = url.searchParams.getAll(key);\n\t\t\t\t// if 1 set as string, else attach array as is\n\t\t\t\tparam[key] = _params.length < 2 || single === true ?\n\t\t\t\t\t_params[0] :\n\t\t\t\t\t_params;\n\t\t\t}\n\t\t}\n\t}\n\treturn param;\n}\n\n/**\n * Check if key exists as URL parameter\n * @param {String} key URL parameter to search\n * @returns {Boolean} True if key exists\n */\nfunction hasUrlParameter(key)\n{\n\tvar urlParams = new URLSearchParams(window.location.search);\n\treturn urlParams.has(key);\n}\n\n/**\n * Return one value for a URL paramter or null if not found\n * @param {String} key Which URL parameter to get\n * @returns {String|Null} URL parameter content\n */\nfunction getUrlParameter(key)\n{\n\tvar urlParams = new URLSearchParams(window.location.search);\n\treturn urlParams.get(key);\n}\n\n/**\n * Add or update a query parameter in the current URL and update the browser's address bar\n * @param {string} key - The parameter name to add or update\n * @param {string} value - The value to set for the parameter\n * @param {boolean} [reload=false] - Whether to reload the page after updating the URL\n */\nfunction updateUrlParameter(key, value, reload = false)\n{\n\t// Create a URL object from the current URL\n\tconst url = new URL(window.location.href);\n\n\t// Set or update the parameter\n\turl.searchParams.set(key, value);\n\n\tconst newUrl = url.toString();\n\n\t// Update the browser's address bar without reloading the page\n\twindow.history.pushState({ path: newUrl }, '', newUrl);\n\n\t// Optionally reload the page\n\tif (reload) {\n\t\t// window.location.href = newUrl;\n\t\twindow.location.reload();\n\t}\n}\n\n/**\n * Remove a parameter from the current URL and update the browser's address bar\n * @param {string} key - The parameter name to remove\n * @param {boolean} [reload=false] - Whether to reload the page after updating the URL\n */\nfunction removeUrlParameter(key, reload = false)\n{\n\t// Create a URL object from the current URL\n\tconst url = new URL(window.location.href);\n\n\t// Remove the parameter if it exists\n\turl.searchParams.delete(key);\n\n\t// Update the browser's address bar without reloading the page\n\twindow.history.pushState({}, '', url.toString());\n\n\t// Optionally reload the page\n\tif (reload) {\n\t\twindow.location.reload();\n\t}\n}\n\n// __EMD__\n", "/*\nDescription: Login access and menu\nDate: 2025/3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { loginLogout };\n\n/**\n * submits basic data for form logout\n */\nfunction loginLogout()\n{\n\tconst form = document.createElement('form');\n\tform.method = 'post';\n\tconst hiddenField = document.createElement('input');\n\thiddenField.type = 'hidden';\n\thiddenField.name = 'login_logout';\n\thiddenField.value = 'Logout';\n\tform.appendChild(hiddenField);\n\tdocument.body.appendChild(form);\n\tform.submit();\n}\n\n// __END__\n", "/*\nDescription: Action Indicator and Overlay\nDate: 2025/2/7\nCreator: Clemens Schwaighofer\n*/\n\nimport { setCenter } from './ResizingAndMove.mjs';\nexport {\n\tActionIndicatorOverlayBox,\n\tactionIndicator, actionIndicatorShow, actionIndicatorHide, overlayBoxShow,\n\toverlayBoxHide, setOverlayBox, hideOverlayBox, ClearCall\n};\n\n/*************************************************************\n * OLD action indicator and overlay boxes calls\n * DO NOT USE\n * actionIndicator -> showActionIndicator\n * actionIndicator -> hideActionIndicator\n * actionIndicatorShow -> showActionIndicator\n * actionIndicatorHide -> hideActionIndicator\n * overlayBoxShow -> showOverlayBoxLayers\n * overlayBoxHide -> hideOverlayBoxLayers\n * setOverlayBox -> showOverlayBoxLayers\n * hideOverlayBox -> hideOverlayBoxLayers\n * ClearCall -> clearCallActionBox\n * ***********************************************************/\n\n/**\n * show or hide the \"do\" overlay\n * @param {String} loc location name for action indicator\n * default empty. for console.log\n * @param {Boolean} [overlay=true] override the auto hide/show over the overlay div block\n * @deprecated showActionIndicator, hideActionIndicator\n */\nfunction actionIndicator(loc, overlay = true)\n{\n\tif ($('#indicator').is(':visible')) {\n\t\tthis.actionIndicatorHide(loc, overlay);\n\t} else {\n\t\tthis.actionIndicatorShow(loc, overlay);\n\t}\n}\n\n/**\n * explicit show for action Indicator\n * instead of automatically show or hide, do on command show\n * @param {String} loc location name for action indicator\n * default empty. for console.log\n * @param {Boolean} [overlay=true] override the auto hide/show over the overlay div block\n * @deprecated showActionIndicator, hideActionIndicator\n */\nfunction actionIndicatorShow(loc, overlay = true)\n{\n\t// console.log('{Indicator}: SHOW [%s]', loc);\n\tif (!$('#indicator').is(':visible')) {\n\t\tif (!$('#indicator').hasClass('progress')) {\n\t\t\t$('#indicator').addClass('progress');\n\t\t}\n\t\tsetCenter('indicator', true, true);\n\t\t$('#indicator').show();\n\t}\n\tif (overlay === true) {\n\t\tthis.overlayBoxShow();\n\t}\n}\n\n/**\n * explicit hide for action Indicator\n * instead of automatically show or hide, do on command hide\n * @param {String} loc location name for action indicator\n * default empty. for console.log\n * @param {Boolean} [overlay=true] override the auto hide/show over the overlay div block\n * @deprecated hideActionIndicator\n */\nfunction actionIndicatorHide(loc, overlay = true)\n{\n\t// console.log('{Indicator}: HIDE [%s]', loc);\n\t$('#indicator').hide();\n\tif (overlay === true) {\n\t\toverlayBoxHide();\n\t}\n}\n\n/**\n * shows the overlay box or if already visible, bumps the zIndex to 100\n * @deprecated showOverlayBoxLayers\n */\nfunction overlayBoxShow()\n{\n\t// check if overlay box exists and if yes set the z-index to 100\n\tif ($('#overlayBox').is(':visible')) {\n\t\t$('#overlayBox').css('zIndex', '100');\n\t} else {\n\t\t$('#overlayBox').show();\n\t\t$('#overlayBox').css('zIndex', '98');\n\t}\n}\n\n/**\n * hides the overlay box or if zIndex is 100 bumps it down to previous level\n * @deprecated hideOverlayBoxLayers\n */\nfunction overlayBoxHide()\n{\n\t// if the overlay box z-index is 100, do no hide, but set to 98\n\tif (parseInt($('#overlayBox').css('zIndex')) >= 100) {\n\t\t$('#overlayBox').css('zIndex', '98');\n\t} else {\n\t\t$('#overlayBox').hide();\n\t}\n}\n\n/**\n * position the overlay block box and shows it\n * @deprecated showOverlayBoxLayers\n */\nfunction setOverlayBox()\n{\n\tif (!$('#overlayBox').is(':visible')) {\n\t\t$('#overlayBox').show();\n\t}\n}\n\n/**\n * opposite of set, always hides overlay box\n * @deprecated hideOverlayBoxLayers\n */\nfunction hideOverlayBox()\n{\n\tif ($('#overlayBox').is(':visible')) {\n\t\t$('#overlayBox').hide();\n\t}\n}\n\n/**\n * the abort call, clears the action box and hides it and the overlay box\n * @deprecated clearCallActionBox\n */\nfunction ClearCall()\n{\n\t$('#actionBox').html('');\n\t$('#actionBox').hide();\n\t$('#overlayBox').hide();\n}\n\n/*\nThe below class will need the following CSS set\n\nProgress indicator (#indicator):\n.progress {\n\twidth: 100px;\n\theight: 100px;\n\tbackground: rgba(255, 255, 255, 0.6);\n\tborder: 20px solid rgba(255, 255, 255 ,0.25);\n\tborder-left-color: rgba(3, 155, 229 ,1);\n\tborder-top-color: rgba(3, 155, 229 ,1);\n\tborder-radius: 50%;\n\tdisplay: inline-block;\n\tanimation: progress-move 600ms infinite linear;\n\tleft: 0;\n\ttop: 0;\n\tposition: absolute;\n\tz-index: 1000;\n}\n@keyframes progress-move {\n\tto {\n\t\ttransform: rotate(1turn)\n\t}\n}\n\nOverlay box darken background (#overlayBox):\n.overlayBoxElement {\n\tbackground-color: rgba(0, 0, 0, 0.3);\n\theight: 100%;\n\tleft: 0;\n\tposition: fixed;\n\ttop: 0;\n\twidth: 100%;\n\tz-index: 98;\n}\n*/\n\nclass ActionIndicatorOverlayBox {\n\n\t// open overlay boxes counter for z-index\n\t#GL_OB_S = 100;\n\t#GL_OB_BASE = 100;\n\n\t/**\n\t * show action indicator\n\t * - checks if not existing and add\n\t * - only shows if not visible (else ignore)\n\t * - overlaybox check is called and shown on a fixzed\n\t * zIndex of 1000\n\t * - indicator is page centered\n\t * @param {String} loc ID string, only used for console log\n\t */\n\tshowActionIndicator(loc) // eslint-disable-line no-unused-vars\n\t{\n\t\t// console.log('{Indicator}: SHOW [%s]', loc);\n\t\t// check if indicator element exists\n\t\tif ($('#indicator').length == 0) {\n\t\t\tvar el = document.createElement('div');\n\t\t\tel.className = 'progress hide';\n\t\t\tel.id = 'indicator';\n\t\t\t$('body').append(el);\n\t\t} else if (!$('#indicator').hasClass('progress')) {\n\t\t\t// if I add a class it will not be hidden anymore\n\t\t\t// hide it\n\t\t\t$('#indicator').addClass('progress').hide();\n\t\t}\n\t\t// indicator not visible\n\t\tif (!$('#indicator').is(':visible')) {\n\t\t\t// check if overlay box element exits\n\t\t\tthis.checkOverlayExists();\n\t\t\t// if not visible show\n\t\t\tif (!$('#overlayBox').is(':visible')) {\n\t\t\t\t$('#overlayBox').show();\n\t\t\t}\n\t\t\t// always set to 1000 zIndex to be top\n\t\t\t$('#overlayBox').css('zIndex', 1000);\n\t\t\t// show indicator\n\t\t\t$('#indicator').show();\n\t\t\t// center it\n\t\t\tsetCenter('indicator', true, true);\n\t\t}\n\t}\n\n\t/**\n\t * hide action indicator, if it is visiable\n\t * If the global variable GL_OB_S is > GL_OB_BASE then\n\t * the overlayBox is not hidden but the zIndex\n\t * is set to this value\n\t * @param {String} loc ID string, only used for console log\n\t */\n\thideActionIndicator(loc) // eslint-disable-line no-unused-vars\n\t{\n\t\t// console.log('{Indicator}: HIDE [%s]', loc);\n\t\t// check if indicator is visible\n\t\tif ($('#indicator').is(':visible')) {\n\t\t\t// hide indicator\n\t\t\t$('#indicator').hide();\n\t\t\t// if global overlay box count is > 0\n\t\t\t// then set it to this level and keep\n\t\t\tif (this.#GL_OB_S > this.#GL_OB_BASE) {\n\t\t\t\t$('#overlayBox').css('zIndex', this.#GL_OB_S);\n\t\t\t} else {\n\t\t\t\t// else hide overlay box and set zIndex to 0\n\t\t\t\t$('#overlayBox').hide();\n\t\t\t\t$('#overlayBox').css('zIndex', this.#GL_OB_BASE);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * checks if overlayBox exists, if not it is\n\t * added as hidden item at the body end\n\t */\n\tcheckOverlayExists()\n\t{\n\t\t// check if overlay box exists, if not create it\n\t\tif ($('#overlayBox').length == 0) {\n\t\t\tvar el = document.createElement('div');\n\t\t\tel.className = 'overlayBoxElement hide';\n\t\t\tel.id = 'overlayBox';\n\t\t\t$('body').append(el);\n\t\t}\n\t}\n\n\t/**\n\t * show overlay box\n\t * if not visible show and set zIndex to 10 (GL_OB_BASE)\n\t * if visible, add +1 to the GL_OB_S variable and\n\t * up zIndex by this value\n\t */\n\tshowOverlayBoxLayers(el_id)\n\t{\n\t\t// console.log('SHOW overlaybox: %s', GL_OB_S);\n\t\t// if overlay box is not visible show and set zIndex to 0\n\t\tif (!$('#overlayBox').is(':visible')) {\n\t\t\t$('#overlayBox').show();\n\t\t\t$('#overlayBox').css('zIndex', this.#GL_OB_BASE);\n\t\t\t// also set start variable to 0\n\t\t\tthis.#GL_OB_S = this.#GL_OB_BASE;\n\t\t}\n\t\t// up the overlay box counter by 1\n\t\tthis.#GL_OB_S ++;\n\t\t// set zIndex\n\t\t$('#overlayBox').css('zIndex', this.#GL_OB_S);\n\t\t// if element given raise zIndex and show\n\t\tif (el_id) {\n\t\t\tif ($('#' + el_id).length > 0) {\n\t\t\t\t$('#' + el_id).css('zIndex', this.#GL_OB_S + 1);\n\t\t\t\t$('#' + el_id).show();\n\t\t\t}\n\t\t}\n\t\t// console.log('SHOW overlaybox NEW zIndex: %s', $('#overlayBox').css('zIndex'));\n\t}\n\n\t/**\n\t * hide overlay box\n\t * lower GL_OB_S value by -1\n\t * if we are 10 (GL_OB_BASE) or below hide the overlayIndex\n\t * and set zIndex and GL_OB_S to 0\n\t * else just set zIndex to the new GL_OB_S value\n\t * @param {String} el_id Target to hide layer\n\t */\n\thideOverlayBoxLayers(el_id='')\n\t{\n\t\t// console.log('HIDE overlaybox: %s', GL_OB_S);\n\t\t// remove on layer\n\t\tthis.#GL_OB_S --;\n\t\t// if 0 or lower (overflow) hide it and\n\t\t// set zIndex to 0\n\t\tif (this.#GL_OB_S <= this.#GL_OB_BASE) {\n\t\t\tthis.#GL_OB_S = this.#GL_OB_BASE;\n\t\t\t$('#overlayBox').hide();\n\t\t\t$('#overlayBox').css('zIndex', this.#GL_OB_BASE);\n\t\t} else {\n\t\t\t// if OB_S > 0 then set new zIndex\n\t\t\t$('#overlayBox').css('zIndex', this.#GL_OB_S);\n\t\t}\n\t\tif (el_id) {\n\t\t\t$('#' + el_id).hide();\n\t\t\t$('#' + el_id).css('zIndex', 0);\n\t\t}\n\t\t// console.log('HIDE overlaybox NEW zIndex: %s', $('#overlayBox').css('zIndex'));\n\t}\n\n\t/**\n\t * only for single action box\n\t */\n\tclearCallActionBox()\n\t{\n\t\t$('#actionBox').html('');\n\t\t$('#actionBox').hide();\n\t\tthis.hideOverlayBoxLayers();\n\t}\n}\n\n\n// __END__\n", "/*\nDescription: Translation call\nDate: 2025/3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { l10nTranslation };\nimport { isObject } from './JavaScriptHelpers.mjs';\n\nclass l10nTranslation {\n\n\t#i18n = {};\n\n\tconstructor(i18n) {\n\t\tthis.#i18n = i18n;\n\n\t}\n\t/**\n\t * uses the i18n object created in the translation template\n\t * that is filled from gettext in PHP\n\t * @param {String} string text to translate\n\t * @return {String} translated text (based on PHP selected language)\n\t */\n\t__(string)\n\t{\n\t\tif (typeof this.#i18n !== 'undefined' && isObject(this.#i18n) && this.#i18n[string]) {\n\t\t\treturn this.#i18n[string];\n\t\t} else {\n\t\t\treturn string;\n\t\t}\n\t}\n}\n\n// __END__\n", "/*\nDescription: Action Box handling\nDate: 2025/3/7\nCreator: Clemens Schwaighofer\n*/\n\nexport { ActionBox };\nimport { objectKeyExists, getObjectCount } from './JavaScriptHelpers.mjs';\nimport { exists } from './DomHelpers.mjs';\nimport { setCenter, getWindowSize } from './ResizingAndMove.mjs';\n\nclass ActionBox {\n\n\t// open overlay boxes counter for z-index\n\tzIndex = {\n\t\tbase: 100,\n\t\tmax: 110,\n\t\tindicator: 0,\n\t\tboxes: {},\n\t\tactive: [],\n\t\ttop: ''\n\t};\n\t// general action box storage\n\taction_box_storage = {};\n\t// set to 10 min (*60 for seconds, *1000 for microseconds)\n\taction_box_cache_timeout = 10 * 60 * 1000;\n\n\thec;\n\tl10n;\n\n\t/**\n\t * action box creator\n\t * @param {Object} hec HtmlElementCreator\n\t * @param {Object} l10n l10nTranslation\n\t */\n\tconstructor(hec, l10n)\n\t{\n\t\tthis.hec = hec;\n\t\tthis.l10n = l10n;\n\t}\n\n\t/**\n\t * Show an action box\n\t * @param {string} [target_id='actionBox'] where to attach content to, if not exists, create new\n\t * @param {string} [content=''] content to add to the box\n\t * @param {array} [action_box_css=[]] additional css elements for the action box\n\t * @param {number} [override=0] override size adjust\n\t * @param {number} [content_override=0] override content size adjust\n\t */\n\tshowFillActionBox(target_id = 'actionBox', content = '', action_box_css = [], override = 0, content_override = 0)\n\t{\n\t\t// fill content\n\t\tthis.fillActionBox(target_id, content, action_box_css);\n\t\t// show the box\n\t\tthis.showActionBox(target_id, override, content_override);\n\t}\n\n\t/**\n\t * Fill action box with content, create it if it does not existgs\n\t * @param {string} [target_id='actionBox'] where to attach content to, if not exists, create new\n\t * @param {string} [content=''] content to add to the box\n\t * @param {array} [action_box_css=[]] additional css elements for the action box\n\t */\n\tfillActionBox(target_id = 'actionBox', content = '', action_box_css = [])\n\t{\n\t\t// show action box, calc height + center\n\t\tif (!exists(target_id)) {\n\t\t\t// add at the bottom\n\t\t\t$('#mainContainer').after(\n\t\t\t\tthis.hec.phfo(this.hec.cel('div', target_id, '', ['actionBoxElement', 'hide'].concat(action_box_css)))\n\t\t\t);\n\t\t}\n\t\t// add the info box\n\t\t$('#' + target_id).html(content);\n\t}\n\n\t/**\n\t * Adjust the size of the action box\n\t * @param {string} [target_id='actionBox'] which actionBox to work on\n\t * @param {number} [override=0] override size adjust\n\t * @param {number} [content_override=0] override content size adjust\n\t */\n\tadjustActionBox(target_id = 'actionBox', override = 0, content_override = 0)\n\t{\n\t\t// adjust box size\n\t\tthis.adjustActionBoxHeight(target_id, override, content_override);\n\t\t// center the alert box\n\t\tsetCenter(target_id, true, true);\n\t}\n\n\t/**\n\t * hide any open action boxes and hide overlay\n\t */\n\thideAllActionBoxes()\n\t{\n\t\t// hide all action boxes that might exist\n\t\t$('#actionBox, div[id^=\"actionBox-\"].actionBoxElement').hide();\n\t\t// hideOverlayBoxLayers();\n\t\t$('#overlayBox').hide();\n\t}\n\n\t/**\n\t * hide action box, but do not clear content\n\t * DEPRECATED\n\t * @param {string} [target_id='actionBox']\n\t */\n\thideActionBox(target_id = 'actionBox')\n\t{\n\t\tthis.closeActionBoxFloat(target_id, false);\n\t}\n\n\t/**\n\t * Just show and adjust the box\n\t * DEPRECAED\n\t * @param {string} [target_id='actionBox'] which actionBox to work on\n\t * @param {number} [override=0] override size adjust\n\t * @param {number} [content_override=0] override content size adjust\n\t * @param {Boolean} [hide_all=false] if set to true, hide all other action boxes\n\t */\n\tshowActionBox(target_id = 'actionBox', override = 0, content_override = 0, hide_all = true)\n\t{\n\t\tthis.showActionBoxFloat(target_id, override, content_override, hide_all);\n\t}\n\n\t/**\n\t * close an action box with default clear content\n\t * for just hide use hideActionBox\n\t * DEPRECATED\n\t * @param {String} [target_id='actionBox'] which action box to close, default is set\n\t * @param {Boolean} [clean=true] if set to false will not remove html content, just hide\n\t */\n\tcloseActionBox(target_id = 'actionBox', clean = true)\n\t{\n\t\t// set the target/content ids\n\t\tthis.closeActionBoxFloat(target_id, clean);\n\t}\n\n\t/**\n\t * TODO: better stacked action box: OPEN\n\t * @param {string} [target_id='actionBox'] which actionBox to work on\n\t * @param {number} [override=0] override size adjust\n\t * @param {number} [content_override=0] override content size adjust\n\t * @param {boolean} [hide_all=false] if set to true, hide all other action boxes\n\t */\n\tshowActionBoxFloat(target_id = 'actionBox', override = 0, content_override = 0, hide_all = false)\n\t{\n\t\tif (hide_all === true) {\n\t\t\t// hide all action boxes if they are currently open\n\t\t\tthis.hideAllActionBoxes();\n\t\t}\n\t\t// if no box, created if\n\t\tif (!exists('overlayBox')) {\n\t\t\t$('body').prepend(this.hec.phfo(this.hec.cel('div', 'overlayBox', '', ['overlayBoxElement'])));\n\t\t\t$('#overlayBox').css('zIndex', this.zIndex.base);\n\t\t}\n\t\t// adjust zIndex so its above all other and set action box zindex +1\n\t\t$('#overlayBox').show();\n\t\tif (!objectKeyExists(this.zIndex.boxes, target_id)) {\n\t\t\tthis.zIndex.boxes[target_id] = this.zIndex.max;\n\t\t\t// increase by ten\n\t\t\tthis.zIndex.max += 10;\n\t\t} else if (this.zIndex.boxes[target_id] + 10 < this.zIndex.max) {\n\t\t\t// see if this is the highest level, if not move up and write no max zIndex\n\t\t\t// move it up to be the new top and move the others down\n\t\t\t// [loop, order by value]\n\t\t\t// current hack, increase max\n\t\t\tthis.zIndex.boxes[target_id] = this.zIndex.max;\n\t\t\tthis.zIndex.max += 10;\n\t\t}\n\t\t// make sure the overlayBox is one level below this\n\t\t// unless there is an active \"indicator\" index\n\t\tif (!this.zIndex.indicator) {\n\t\t\t$('#overlayBox').css('zIndex', this.zIndex.boxes[target_id] - 1);\n\t\t}\n\t\t$('#' + target_id).css('zIndex', this.zIndex.boxes[target_id]).show();\n\t\t// set target to this new level\n\t\t// @ts-ignore\n\t\tif (this.zIndex.active.indexOf(target_id) == -1) {\n\t\t\t// @ts-ignore\n\t\t\tthis.zIndex.active.push(target_id);\n\t\t}\n\t\tthis.zIndex.top = target_id;\n\t\t// adjust size\n\t\tthis.adjustActionBox(target_id, override, content_override);\n\t}\n\n\t/**\n\t * TODO: better stacked action box: CLOSE\n\t * @param {String} [target_id='actionBox'] which action box to close, default is set\n\t * @param {Boolean} [clean=true] if set to false will not remove html content, just hide\n\t */\n\tcloseActionBoxFloat(target_id = 'actionBox', clean = true)\n\t{\n\t\t// do nothing if this does not exist\n\t\tif (!exists(target_id)) {\n\t\t\treturn;\n\t\t}\n\t\t// clear storage object\n\t\tif (\n\t\t\tobjectKeyExists(this.action_box_storage, target_id) && clean === true\n\t\t) {\n\t\t\tthis.action_box_storage[target_id] = {};\n\t\t}\n\t\tif (clean === true) {\n\t\t\t$('#' + target_id).html('');\n\t\t}\n\t\t$('#' + target_id).hide();\n\t\t// remove from active list\n\t\t// @ts-ignore\n\t\tlet idx = this.zIndex.active.indexOf(target_id);\n\t\tthis.zIndex.active.splice(idx, 1);\n\t\t// do we have any visible action boxes.\n\t\t// find the highest zIndex and set overlayBox to this -1\n\t\t// @ts-ignore\n\t\tlet visible_zIndexes = $('#actionBox:visible, div[id^=\"actionBox-\"].actionBoxElement:visible').map((i, el) => ({\n\t\t\tid: el.id,\n\t\t\tzIndex: $('#' + el.id).css('zIndex')\n\t\t})).get();\n\t\tif (visible_zIndexes.length > 0) {\n\t\t\tlet max_zIndex = 0;\n\t\t\tlet max_el_id = '';\n\t\t\tfor (let zIndex_el of visible_zIndexes) {\n\t\t\t\tif (parseInt(zIndex_el.zIndex) > max_zIndex) {\n\t\t\t\t\tmax_zIndex = parseInt(zIndex_el.zIndex);\n\t\t\t\t\tmax_el_id = zIndex_el.id;\n\t\t\t\t}\n\t\t\t}\n\t\t\t$('#overlayBox').css('zIndex', max_zIndex - 1);\n\t\t\tthis.zIndex.top = max_el_id;\n\t\t} else {\n\t\t\t$('#overlayBox').hide();\n\t\t}\n\t}\n\n\t/**\n\t * create a new action box and fill it with basic elements\n\t * @param {String} [target_id='actionBox']\n\t * @param {String} [title='']\n\t * @param {Object} [contents={}]\n\t * @param {Object} [headers={}]\n\t * @param {Boolean} [show_close=true]\n\t * @param {Object} [settings={}] Optional settings, eg style sheets\n\t */\n\tcreateActionBox(\n\t\ttarget_id = 'actionBox',\n\t\ttitle = '',\n\t\tcontents = {},\n\t\theaders = {},\n\t\tsettings = {},\n\t\tshow_close = true\n\t) {\n\t\tif (!objectKeyExists(this.action_box_storage, target_id)) {\n\t\t\tthis.action_box_storage[target_id] = {};\n\t\t}\n\t\t// settings can have the following\n\t\t// : header_css:[]\n\t\t// : action_box_css:[]\n\t\tlet header_css = [];\n\t\tif (objectKeyExists(settings, 'header_css')) {\n\t\t\theader_css = settings.header_css;\n\t\t}\n\t\tlet action_box_css = [];\n\t\tif (objectKeyExists(settings, 'action_box_css')) {\n\t\t\taction_box_css = settings.action_box_css;\n\t\t}\n\t\tlet elements = [];\n\t\t// add title + close button to actionBox\n\t\telements.push(this.hec.phfo(\n\t\t\tthis.hec.aelx(this.hec.cel('div', target_id + '_title', '', ['actionBoxTitle', 'flx-spbt'].concat(header_css)),\n\t\t\t\t...show_close === true ? [\n\t\t\t\t\t// title\n\t\t\t\t\tthis.hec.cel('div', '', title, ['fs-b', 'w-80']),\n\t\t\t\t\t// close button\n\t\t\t\t\tthis.hec.aelx(this.hec.cel('div', target_id + '_title_close_button', '', ['w-20', 'tar']),\n\t\t\t\t\t\tthis.hec.cel('input', target_id + '_title_close', '', ['button-close', 'fs-s'],\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: 'button',\n\t\t\t\t\t\t\t\tvalue: this.l10n.__('Close'),\n\t\t\t\t\t\t\t\tOnClick: 'closeActionBox(\\'' + target_id + '\\', false);'\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\t\tthis.hec.cel('div', '', title, ['fs-b', 'w-100'])\n\t\t\t\t]\n\t\t\t)\n\t\t));\n\t\t// if we have header content, add that here\n\t\tif (getObjectCount(headers) > 0) {\n\t\t\t// if the element has an entry called \"raw_string\" then this does not need to be converted\n\t\t\tif (objectKeyExists(headers, 'raw_string')) {\n\t\t\t\telements.push(headers.raw_string);\n\t\t\t} else {\n\t\t\t\telements.push(this.hec.phfo(headers));\n\t\t\t}\n\t\t}\n\t\t// main content part (this should NOT be empty), if empty, add empty _content block\n\t\tif (getObjectCount(contents) > 0) {\n\t\t\t// if the element has an entry called \"raw_string\" then this does not need to be converted\n\t\t\tif (objectKeyExists(contents, 'raw_string')) {\n\t\t\t\telements.push(contents.raw_string);\n\t\t\t} else {\n\t\t\t\telements.push(this.hec.phfo(contents));\n\t\t\t}\n\t\t} else {\n\t\t\telements.push(this.hec.phfo(this.hec.cel('div', target_id + '_content', '', [])));\n\t\t}\n\t\t// footer clear call\n\t\telements.push(this.hec.phfo(\n\t\t\tthis.hec.aelx(this.hec.cel('div', target_id + '_footer', '', ['pd-5', 'flx-spbt']),\n\t\t\t\t...show_close === true ? [\n\t\t\t\t\t// dummy spacer\n\t\t\t\t\tthis.hec.cel('div', '', '', ['fs-b', 'w-80']),\n\t\t\t\t\t// close button\n\t\t\t\t\tthis.hec.aelx(this.hec.cel('div', target_id + '_footer_close_button', '', ['tar', 'w-20']),\n\t\t\t\t\t\tthis.hec.cel('input', target_id + '_footer_close', '', ['button-close', 'fs-s'],\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: 'button',\n\t\t\t\t\t\t\t\tvalue: this.l10n.__('Close'),\n\t\t\t\t\t\t\t\tOnClick: 'closeActionBox(\\'' + target_id + '\\', false);'\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\t\tthis.hec.cel('div', '', '', ['fs-b', 'w-100'])\n\t\t\t\t]\n\t\t\t)\n\t\t));\n\t\telements.push(this.hec.phfo(this.hec.cel('input', target_id + '-cache_time', '', [], {\n\t\t\ttype: 'hidden',\n\t\t\tvalue: Date.now()\n\t\t})));\n\t\tthis.fillActionBox(target_id, elements.join(''), action_box_css);\n\t}\n\n\t/**\n\t * adjusts the action box height based on content and window height of browser\n\t * TODO: border on outside/and other margin things need to be added in overall adjustment\n\t * @param {String} [target_id='actionBox'] target id, if not set, fall back to default\n\t * @param {Number} [override=0] override value to add to the actionBox height\n\t * @param {Number} [content_override=0] override the value from _content block if it exists\n\t */\n\tadjustActionBoxHeight(target_id = 'actionBox', override = 0, content_override = 0)\n\t{\n\t\tvar new_height = 0;\n\t\tvar dim = {};\n\t\tvar abc_dim = {};\n\t\tvar content_id = '';\n\t\t// make sure it is a number\n\t\tif (isNaN(override)) {\n\t\t\toverride = 0;\n\t\t}\n\t\tif (isNaN(content_override)) {\n\t\t\tcontent_override = 0;\n\t\t}\n\t\t// set the target/content ids\n\t\tswitch (target_id) {\n\t\t\tcase 'actionBox':\n\t\t\t\tcontent_id = 'action_box';\n\t\t\t\tbreak;\n\t\t\tcase 'actionBoxSub':\n\t\t\t\tcontent_id ='action_box_sub';\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tcontent_id = target_id;\n\t\t\t\tbreak;\n\t\t}\n\t\t// first remove any height, left, top style entris from target and content blocks\n\t\t// @ts-ignore\n\t\t$.each([target_id, content_id + '_content'], function(i, v) {\n\t\t\t$('#' + v).css({\n\t\t\t\t'height': '',\n\t\t\t\t'width': ''\n\t\t\t});\n\t\t});\n\t\tif (exists(content_id + '_title')) {\n\t\t\tdim.height = $('#' + content_id + '_title').outerHeight();\n\t\t\tconsole.log('Target: %s, Action box Title: %s', target_id, dim.height);\n\t\t\tnew_height += dim.height ?? 0;\n\t\t}\n\t\tif (exists(content_id + '_header')) {\n\t\t\tdim.height = $('#' + content_id + '_header').outerHeight();\n\t\t\tconsole.log('Target: %s, Action box Header: %s', target_id, dim.height);\n\t\t\tnew_height += dim.height ?? 0;\n\t\t}\n\t\tif (exists(content_id + '_content')) {\n\t\t\tif (content_override > 0) {\n\t\t\t\tconsole.log('Target: %s, Action box Content Override: %s', target_id, content_override);\n\t\t\t\tnew_height += content_override;\n\t\t\t} else {\n\t\t\t\tabc_dim.height = $('#' + content_id + '_content').outerHeight();\n\t\t\t\tconsole.log('Target: %s, Action box Content: %s', target_id, abc_dim.height);\n\t\t\t\tnew_height += abc_dim.height ?? 0;\n\t\t\t}\n\t\t}\n\t\t// always there sets\n\t\tif (exists(content_id + '_footer')) {\n\t\t\tdim.height = $('#' + content_id + '_footer').outerHeight();\n\t\t\tconsole.log('Target: %s, Action box Footer: %s', target_id, dim.height);\n\t\t\tnew_height += dim.height ?? 0;\n\t\t}\n\t\t// get difference for the rest from outer box\n\t\t// console.log('Target: %s, Action box outer: %s, Content: %s, New: %s', target_id, $('#' + target_id).outerHeight(), $('#' + content_id + '_content').outerHeight(), new_height);\n\t\t// new_height += ($('#' + target_id).outerHeight() - new_height) + override;\n\t\tnew_height += override;\n\t\t// get border width top-bottom from action Box, we need to remove this from the final height\n\t\t// console.log('Target: %s, Border top: %s', target_id, $('#' + target_id).css('border-top-width'));\n\t\t// get window size and check if content is bigger\n\t\tvar viewport = getWindowSize();\n\t\tif (new_height >= viewport.height) {\n\t\t\t// resize the action box content and set overflow [of-s-y]\n\t\t\tif (exists(content_id + '_content')) {\n\t\t\t\tif (!$('#' + content_id + '_content').hasClass('of-s-y')) {\n\t\t\t\t\t$('#' + content_id + '_content').addClass('of-s-y');\n\t\t\t\t}\n\t\t\t}\n\t\t\tconsole.log('Target: %s, Viewport: %s, ActionBox (NH): %s, ABcontent: %s, ABouter: %s', target_id, viewport.height, new_height, abc_dim.height, $('#' + target_id).outerHeight());\n\t\t\t// the height off window - all - action box gives new action box height\n\t\t\tvar m_height = viewport.height - (new_height - (abc_dim.height ?? 0));\n\t\t\tconsole.log('Target: %s, New ABcontent: %s', target_id, m_height);\n\t\t\t$('#' + content_id + '_content').css('height', m_height + 'px');\n\t\t\tnew_height = new_height - (abc_dim.height ?? 0) + m_height;\n\t\t\tconsole.log('Target: %s, New Hight: %s', target_id, new_height);\n\t\t} else {\n\t\t\t// if size ok, check if overflow scoll is set, remove it\n\t\t\tif (exists(content_id + '_content')) {\n\t\t\t\tif ($('#' + content_id + '_content').hasClass('of-s-y')) {\n\t\t\t\t\t$('#' + content_id + '_content').removeClass('of-s-y');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconsole.log('Target: %s, Action Box new height: %s px (override %s px, content override %s px), window height: %s px, Visible Height: %s px', target_id, new_height, override, content_override, viewport.height, $('#' + content_id).outerHeight());\n\t\t// adjust height\n\t\t$('#' + target_id).css('height', new_height + 'px');\n\t}\n}\n\n// __EMD__\n", "/*\nDescription: Login access and menu\nDate: 2025/3/6\nCreator: Clemens Schwaighofer\n*/\n\nexport { LoginNavMenu };\nimport { isObject, getObjectCount } from './JavaScriptHelpers.mjs';\nimport { exists } from './DomHelpers.mjs';\n\nclass LoginNavMenu {\n\n\thec;\n\tl10n;\n\n\t/**\n\t * action box creator\n\t * @param {Object} hec HtmlElementCreator\n\t * @param {Object} l10n l10nTranslation\n\t */\n\tconstructor(hec, l10n)\n\t{\n\t\tthis.hec = hec;\n\t\tthis.l10n = l10n;\n\t}\n\n\t/**\n\t * create login string and logout button elements\n\t * @param {String} login_string the login string to show on the left\n\t * @param {String} [header_id='mainHeader'] the target for the main element block\n\t * if not set mainHeader is assumed\n\t * this is the target div for the \"loginRow\"\n\t */\n\tcreateLoginRow(login_string, header_id = 'mainHeader')\n\t{\n\t\t// if header does not exist, we do nothing\n\t\tif (exists(header_id)) {\n\t\t\t// that row must exist already, if not it must be the first in the \"mainHeader\"\n\t\t\tif (!exists('loginRow')) {\n\t\t\t\t$('#' + header_id).html(this.hec.phfo(this.hec.cel('div', 'loginRow', '', ['loginRow', 'flx-spbt'])));\n\t\t\t}\n\t\t\t// clear out just in case for first entry\n\t\t\t// fill with div name & login/logout button\n\t\t\t$('#loginRow').html(this.hec.phfo(this.hec.cel('div', 'loginRow-name', login_string)));\n\t\t\t$('#loginRow').append(this.hec.phfo(this.hec.cel('div', 'loginRow-info', '')));\n\t\t\t$('#loginRow').append(this.hec.phfo(\n\t\t\t\tthis.hec.aelx(\n\t\t\t\t\t// outer div\n\t\t\t\t\tthis.hec.cel('div', 'loginRow-logout'),\n\t\t\t\t\t// inner element\n\t\t\t\t\tthis.hec.cel('input', 'logout', '', [], {\n\t\t\t\t\t\tvalue: this.l10n.__('Logout'),\n\t\t\t\t\t\ttype: 'button',\n\t\t\t\t\t\tonClick: 'loginLogout()'\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t));\n\t\t}\n\t}\n\n\t/**\n\t * create the top nav menu that switches physical between pages\n\t * (edit access data based)\n\t * @param {Object} nav_menu the built nav menu with highlight info\n\t * @param {String} [header_id='mainHeader'] the target for the main element block\n\t * if not set mainHeader is assumed\n\t * this is the target div for the \"menuRow\"\n\t */\n\tcreateNavMenu(nav_menu, header_id = 'mainHeader')\n\t{\n\t\t// must be an object\n\t\tif (isObject(nav_menu) && getObjectCount(nav_menu) > 1) {\n\t\t\t// do we have more than one entry, if not, do not show (single page)\n\t\t\tif (!exists('menuRow')) {\n\t\t\t\t$('#' + header_id).html(this.hec.phfo(this.hec.cel('div', 'menuRow', '', ['menuRow', 'flx-s'])));\n\t\t\t}\n\t\t\tvar content = [];\n\t\t\t$.each(nav_menu, function(key, item) {\n\t\t\t\t// key is number\n\t\t\t\t// item is object with entries\n\t\t\t\tif (key != 0) {\n\t\t\t\t\tcontent.push(this.hec.phfo(this.hec.cel('div', '', '·', ['pd-2'])));\n\t\t\t\t}\n\t\t\t\t// ignore item.popup for now\n\t\t\t\tif (item.enabled) {\n\t\t\t\t\t// set selected based on window.location.href as the php set will not work\n\t\t\t\t\tif (window.location.href.indexOf(item.url) != -1) {\n\t\t\t\t\t\titem.selected = 1;\n\t\t\t\t\t}\n\t\t\t\t\t// create the entry\n\t\t\t\t\tcontent.push(this.hec.phfo(\n\t\t\t\t\t\tthis.hec.aelx(\n\t\t\t\t\t\t\tthis.hec.cel('div'),\n\t\t\t\t\t\t\tthis.hec.cel('a', '', item.name, ['pd-2'].concat(item.selected ? 'highlight': ''), {\n\t\t\t\t\t\t\t\thref: item.url\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\t$('#menuRow').html(content.join(''));\n\t\t} else {\n\t\t\t$('#menuRow').hide();\n\t\t}\n\t}\n\n}\n\n// __END__\n", "/*\nDescription: Browser detect\nDate: 2025/11.25\nCreator: Clemens Schwaighofer\n*/\n\nexport { isWebkit, isMobileWebKit, isDesktopWebKit };\n\n// Desktop Safari, all mobile WebKit browsers on iOS and webview iOS\nfunction isWebkit()\n{\n\treturn \"GestureEvent\" in window;\n}\n\n// all mobile webkit browsers and webview iOS\nfunction isMobileWebKit()\n{\n\treturn \"ongesturechange\" in window;\n}\n\n// Desktop Safari\nfunction isDesktopWebKit()\n{\n\treturn (\n\t\ttypeof window !== 'undefined' &&\n\t\t'safari' in window &&\n\t\t'pushNotification' in window.safari\n\t);\n}\n\n// __END__\n", "/*\n * general edit javascript\n * former name: edit.jq.js\n * This is the jquery version\n * NOTE: jquey parts will be deprecated\n*/\n\nimport {\n\terrorCatch as _errorCatch,\n\tisFunction as _isFunction,\n\texecuteFunctionByName as _executeFunctionByName,\n\tisObject as _isObject,\n\tisArray as _isArray,\n\tisIterable as _isIterable,\n\tgetObjectCount as _getObjectCount,\n\tkeyInObject as _keyInObject,\n\tgetKeyByValue as _getKeyByValue,\n\tvalueInObject as _valueInObject,\n\tdeepCopyFunction as _deepCopyFunction\n} from './utils/JavaScriptHelpers.mjs';\nimport {\n\tescapeHtml as _escapeHtml,\n\tunescapeHtml as _unescapeHtml,\n\thtml_options as _html_options,\n\thtml_options_block as _html_options_block,\n\thtml_options_refill as _html_options_refill\n} from './utils/HtmlHelpers.mjs';\nimport {\n\tloadEl as _loadEl,\n\tpop as _pop,\n\texpandTA as _expandTA,\n\texists as _exists\n} from './utils/DomHelpers.mjs';\nimport {\n\tdec2hex as _dec2hex,\n\tgetRandomIntInclusive as _getRandomIntInclusive,\n\troundPrecision as _roundPrecision\n} from './utils/MathHelpers.mjs';\nimport {\n\tformatString as _formatString,\n\tnumberWithCommas as _numberWithCommas,\n\tconvertLBtoBR as _convertLBtoBR\n} from './utils/StringHelpers.mjs';\nimport {\n\tgetTimestamp as _getTimestamp\n} from './utils/DateTimeHelpers.mjs';\nimport {\n\tgenerateId as _generateId,\n\trandomIdF as _randomIdF,\n} from './utils/UniqIdGenerators.mjs';\nimport {\n\tgetWindowSize as _getWindowSize,\n\tgetScrollOffset as _getScrollOffset,\n\tgetScrollOffsetOpener as _getScrollOffsetOpener,\n\tsetCenter as _setCenter,\n\tgoToPos as _goToPos,\n\tgoTo as _goTo\n} from './utils/ResizingAndMove.mjs';\nimport {\n\tformatBytes as _formatBytes,\n\tformatBytesLong as _formatBytesLong,\n\tstringByteFormat as _stringByteFormat\n} from './utils/FormatBytes.mjs';\nimport {\n\tparseQueryString as _parseQueryString,\n\tgetQueryStringParam as _getQueryStringParam,\n\thasUrlParameter as _hasUrlParameter,\n\tgetUrlParameter as _getUrlParameter,\n\tupdateUrlParameter as _updateUrlParameter,\n\tremoveUrlParameter as _removeUrlParameter,\n} from './utils/UrlParser.mjs';\nimport {\n\tloginLogout as _loginLogout,\n} from './utils/LoginLogout.mjs';\nimport {\n\tActionIndicatorOverlayBox,\n\tactionIndicator as _actionIndicator,\n\tactionIndicatorShow as _actionIndicatorShow,\n\tactionIndicatorHide as _actionIndicatorHide,\n\toverlayBoxShow as _overlayBoxShow,\n\toverlayBoxHide as _overlayBoxHide,\n\tsetOverlayBox as _setOverlayBox,\n\thideOverlayBox as _hideOverlayBox,\n\tClearCall as _ClearCall\n} from './utils/ActionIndicatorOverlayBox.mjs';\nimport { l10nTranslation } from './utils/l10nTranslation.mjs';\nimport { HtmlElementCreator } from './utils/HtmlElementCreator.mjs';\nimport { ActionBox } from './utils/ActionBox.mjs';\nimport { LoginNavMenu } from './utils/LoginNavMenu.mjs';\nimport {\n\tisWebkit as _isWebkit,\n\tisMobileWebKit as _isMobileWebKit,\n\tisDesktopWebKit as _isDesktopWebKit\n} from './utils/BrowserDetect.mjs';\n\nlet aiob = new ActionIndicatorOverlayBox();\nlet hec = new HtmlElementCreator();\n// if ( undef === \"undefined\") {\n// @ts-ignore\n// eslint-disable-next-line no-undef\nlet l10n = new l10nTranslation(typeof i18n === \"undefined\" ? {} : i18n);\nlet ab = new ActionBox(hec, l10n);\nlet lnm = new LoginNavMenu(hec, l10n);\n\n// MARK: deprecated String/Number override\n\n/**\n * simple sprintf formater for replace\n * usage: \"{0} is cool, {1} is not\".format(\"Alpha\", \"Beta\");\n * First, checks if it isn't implemented yet.\n * @param {String} String.prototype.format string with elements to be replaced\n * @return {String} Formated string\n * @deprecated StringHelpers.formatString\n */\n// @ts-ignore\nif (!String.prototype.format) {\n\t// @ts-ignore\n\tString.prototype.format = function()\n\t{\n\t\tconsole.error('[DEPRECATED] use StringHelpers.formatString');\n\t\t// @ts-ignore\n\t\treturn _formatString(this, arguments);\n\t};\n}\n\n/**\n * round to digits (float)\n * @param {Number} Number.prototype.round Float type number to round\n * @param {Number} prec Precision to round to\n * @return {Float} Rounded number\n * @deprecated use MathHelpers.roundPrecision\n */\n// @ts-ignore\nif (Number.prototype.round) {\n\t// @ts-ignore\n\tNumber.prototype.round = function (prec) {\n\t\tconsole.error('[DEPRECATED] use MathHelpers.roundPrecision');\n\t\t// @ts-ignore\n\t\treturn _roundPrecision(this, prec);\n\t};\n}\n\n/**\n * escape HTML string\n * @param {String} String.prototype.escapeHTML HTML data string to be escaped\n * @return {String} escaped string\n * @deprecated use HtmlHelpers.escapeHtml\n */\n// @ts-ignore\nif (!String.prototype.escapeHTML) {\n\t// @ts-ignore\n\tString.prototype.escapeHTML = function() {\n\t\tconsole.error('[DEPRECATED] use HtmlHelpers.escapeHtml');\n\t\t// @ts-ignore\n\t\treturn _escapeHtml(this);\n\t};\n}\n\n/**\n * unescape a HTML encoded string\n * @param {String} String.prototype.unescapeHTML data with escaped entries\n * @return {String} HTML formated string\n * @deprecated use HtmlHelpers.unescapeHtml\n */\n// @ts-ignore\nif (!String.prototype.unescapeHTML) {\n\t// @ts-ignore\n\tString.prototype.unescapeHTML = function() {\n\t\tconsole.error('[DEPRECATED] use HtmlHelpers.unescapeHtml');\n\t\t// @ts-ignore\n\t\treturn _unescapeHtml(this);\n\t};\n}\n\n// MARK: general collection\n\n/**\n *\n * @param {String} string\n * @returns {String}\n */\n// @ts-ignore\nfunction escapeHtml(string) // eslint-disable-line no-unused-vars\n{\n\treturn _escapeHtml(string);\n}\n\n/**\n * round to digits (float)\n * @param {Number} number Float type number to round\n * @param {Number} prec Precision to round to\n * @return {Number} Rounded number\n */\n// @ts-ignore\nfunction roundPrecision(number, prec) // eslint-disable-line no-unused-vars\n{\n\treturn _roundPrecision(number, prec);\n}\n\n/**\n * simple sprintf formater for replace\n * usage: \"{0} is cool, {1} is not\".format(\"Alpha\", \"Beta\");\n * First, checks if it isn't implemented yet.\n * @param {String} string String with elements to be replaced\n * @return {String} Formated string\n * @deprecated StringHelpe\n */\n// @ts-ignore\nfunction formatString(string, ...args) // eslint-disable-line no-unused-vars\n{\n\treturn _formatString(string, ...args);\n}\n\n/**\n *\n * @param {String} string\n * @returns {String}\n */\n// @ts-ignore\nfunction unescapeHtml(string) // eslint-disable-line no-unused-vars\n{\n\treturn _unescapeHtml(string);\n}\n\n/**\n * Gets html element or throws an error\n * @param {string} el_id Element ID to get\n * @returns {HTMLElement}\n * @throws Error\n */\n// @ts-ignore\nfunction loadEl(el_id) // eslint-disable-line no-unused-vars\n{\n\treturn _loadEl(el_id);\n}\n\n/**\n * opens a pop_ window with winName and given features (string)\n * @param {String} theURL the url\n * @param {String} winName window name\n * @param {Object} features pop_ features\n */\n// @ts-ignore\nfunction pop(theURL, winName, features) // eslint-disable-line no-unused-vars\n{\n\t_pop(theURL, winName, features);\n}\n\n/**\n * automatically resize a text area based on the amount of lines in it\n * @param {string} ta_id element id\n */\n// @ts-ignore\nfunction expandTA(ta_id) // eslint-disable-line no-unused-vars\n{\n\t_expandTA(ta_id);\n}\n\n/**\n * wrapper to get the real window size for the current browser window\n * @return {Object} object with width/height\n */\n// @ts-ignore\nfunction getWindowSize() // eslint-disable-line no-unused-vars\n{\n\treturn _getWindowSize();\n}\n\n/**\n * wrapper to get the correct scroll offset\n * @return {Object} object with x/y px\n */\n// @ts-ignore\nfunction getScrollOffset() // eslint-disable-line no-unused-vars\n{\n\treturn _getScrollOffset();\n}\n\n/**\n * wrapper to get the correct scroll offset for opener page (from pop_)\n * @return {Object} object with x/y px\n */\n// @ts-ignore\nfunction getScrollOffsetOpener() // eslint-disable-line no-unused-vars\n{\n\treturn _getScrollOffsetOpener();\n}\n\n/**\n * centers div to current window size middle\n * @param {String} id element to center\n * @param {Boolean} left if true centers to the middle from the left\n * @param {Boolean} top if true centers to the middle from the top\n */\n// @ts-ignore\nfunction setCenter(id, left, top) // eslint-disable-line no-unused-vars\n{\n\t_setCenter(id, left, top);\n}\n\n/**\n * goes to an element id position\n * @param {String} element element id to move to\n * @param {Number} [offset=0] offset from top, default is 0 (px)\n * @param {Number} [duration=500] animation time, default 500ms\n * @param {String} [base='body,html'] base element for offset scroll\n */\n// @ts-ignore\nfunction goToPos(element, offset = 0, duration = 500, base = 'body,html') // eslint-disable-line no-unused-vars\n{\n\t_goToPos(element, offset, duration, base);\n}\n\n/**\n * go to element, scroll\n * non jquery\n * @param {string} target\n*/\n// @ts-ignore\nfunction goTo(target) // eslint-disable-line no-unused-vars\n{\n\t_goTo(target);\n}\n\n/**\n * uses the i18n object created in the translation template\n * that is filled from gettext in PHP\n * @param {String} string text to translate\n * @return {String} translated text (based on PHP selected language)\n */\n// @ts-ignore\nfunction __(string) // eslint-disable-line no-unused-vars\n{\n\treturn l10n.__(string);\n}\n\n/**\n * formats flat number 123456 to 123,456\n * @param {Number} x number to be formated\n * @return {String} formatted with , in thousands\n */\n// @ts-ignore\nfunction numberWithCommas(x) // eslint-disable-line no-unused-vars\n{\n\treturn _numberWithCommas(x);\n}\n\n/**\n * converts line breaks to br\n * @param {String} string any string\n * @return {String} string with
\n */\n// @ts-ignore\nfunction convertLBtoBR(string) // eslint-disable-line no-unused-vars\n{\n\treturn _convertLBtoBR(string);\n}\n\n/**\n * returns current timestamp (unix timestamp)\n * @return {Number} timestamp (in milliseconds)\n */\n// @ts-ignore\nfunction getTimestamp() // eslint-disable-line no-unused-vars\n{\n\treturn _getTimestamp();\n}\n\n/**\n * dec2hex :: Integer -> String\n * i.e. 0-255 -> '00'-'ff'\n * @param {Number} dec decimal string\n * @return {String} hex encdoded number\n */\n// @ts-ignore\nfunction dec2hex(dec) // eslint-disable-line no-unused-vars\n{\n\treturn _dec2hex(dec);\n}\n\n/**\n * generateId :: Integer -> String\n * only works on mondern browsers\n * @param {Number} len length of unique id string\n * @return {String} random string in length of len\n */\n// @ts-ignore\nfunction generateId(len) // eslint-disable-line no-unused-vars\n{\n\treturn _generateId(len);\n}\n\n/**\n * creates a pseudo random string of 10 characters\n * works on all browsers\n * after many runs it will create d_licates\n * @return {String} not true random string\n */\n// @ts-ignore\nfunction randomIdF() // eslint-disable-line no-unused-vars\n{\n\treturn _randomIdF();\n}\n\n/**\n * generate a number between min/max\n * with min/max inclusive.\n * eg: 1,5 will create a number ranging from 1 o 5\n * @param {Number} min minimum int number inclusive\n * @param {Number} max maximumg int number inclusive\n * @return {Number} Random number\n */\n// @ts-ignore\nfunction getRandomIntInclusive(min, max) // eslint-disable-line no-unused-vars\n{\n\treturn _getRandomIntInclusive(min, max);\n}\n\n/**\n * check if name is a function\n * @param {string} name Name of function to check if exists\n * @return {Boolean} true/false\n */\n// @ts-ignore\nfunction isFunction(name) // eslint-disable-line no-unused-vars\n{\n\treturn _isFunction(name);\n}\n\n/**\n * call a function by its string name\n * https://stackoverflow.com/a/359910\n * example: executeFunctionByName(\"My.Namespace.functionName\", window, arguments);\n * @param {string} functionName The function name or namespace + function\n * @param {any} context context (window or first namespace)\n * hidden next are all the arguments\n * @return {any} Return values from functon\n */\n// @ts-ignore\nfunction executeFunctionByName(functionName, context) // eslint-disable-line no-unused-vars\n{\n\treturn _executeFunctionByName(functionName, context);\n}\n\n/**\n * checks if a variable is an object\n * @param {any} val possible object\n * @return {Boolean} true/false if it is an object or not\n */\n// @ts-ignore\nfunction isObject(val) // eslint-disable-line no-unused-vars\n{\n\treturn _isObject(val);\n}\n\n/**\n * Check if variable is array\n * @param {any} val possible array\n * @returns {Boolean} true/false if it an array\n */\n// @ts-ignore\nfunction isArray(val) // eslint-disable-line no-unused-vars\n{\n\treturn _isArray(val);\n}\n\n/**\n * checks if a variable is an iterable\n * @param {any} val possible iterable\n * @return {Boolean} true/false if it is an object or not\n */\n// @ts-ignore\nfunction isIterable(val) // eslint-disable-line no-unused-vars\n{\n\treturn _isIterable(val);\n}\n\n/**\n * get the length of an object (entries)\n * @param {Object} object object to check\n * @return {Number} number of entry\n */\n// @ts-ignore\nfunction getObjectCount(object) // eslint-disable-line no-unused-vars\n{\n\treturn _getObjectCount(object);\n}\n\n/**\n * checks if a key exists in a given object\n * @param {String} key key name\n * @param {Object} object object to search key in\n * @return {Boolean} true/false if key exists in object\n */\n// @ts-ignore\nfunction keyInObject(key, object) // eslint-disable-line no-unused-vars\n{\n\treturn _keyInObject(key, object);\n}\n\n/**\n * returns matching key of value\n * @param {Object} object object to search value in\n * @param {any} value any value (String, Number, etc)\n * @return {String} the key found for the first matching value\n */\n// @ts-ignore\nfunction getKeyByValue(object, value) // eslint-disable-line no-unused-vars\n{\n\treturn _getKeyByValue(object, value);\n}\n\n/**\n * returns true if value is found in object with a key\n * @param {Object} object object to search value in\n * @param {any} value any value (String, Number, etc)\n * @return {Boolean} true on value found, false on not found\n */\n// @ts-ignore\nfunction valueInObject(object, value) // eslint-disable-line no-unused-vars\n{\n\treturn _valueInObject(object, value);\n}\n\n/**\n * true deep copy for Javascript objects\n * if Object.assign({}, obj) is not working (shallow)\n * or if JSON.parse(JSON.stringify(obj)) is failing\n * @param {Object} inObject Object to copy\n * @return {Object} Copied Object\n */\n// @ts-ignore\nfunction deepCopyFunction(inObject) // eslint-disable-line no-unused-vars\n{\n\treturn _deepCopyFunction(inObject);\n}\n\n/**\n * checks if a DOM element actually exists\n * @param {String} id Element id to check for\n * @return {Boolean} true if element exists, false on failure\n */\n// @ts-ignore\nfunction exists(id) // eslint-disable-line no-unused-vars\n{\n\treturn _exists(id);\n}\n\n/**\n * converts a int number into bytes with prefix in two decimals precision\n * currently precision is fixed, if dynamic needs check for max/min precision\n * @param {Number} bytes bytes in int\n * @return {String} string in GB/MB/KB\n */\n// @ts-ignore\nfunction formatBytes(bytes) // eslint-disable-line no-unused-vars\n{\n\treturn _formatBytes(bytes);\n}\n\n/**\n * like formatBytes, but returns bytes for <1KB and not 0.n KB\n * @param {Number} bytes bytes in int\n * @return {String} string in GB/MB/KB\n */\n// @ts-ignore\nfunction formatBytesLong(bytes) // eslint-disable-line no-unused-vars\n{\n\treturn _formatBytesLong(bytes);\n}\n\n/**\n * Convert a string with B/K/M/etc into a byte number\n * @param {String|Number} bytes Any string with B/K/M/etc\n * @return {String|Number} A byte number, or original string as is\n */\n// @ts-ignore\nfunction stringByteFormat(bytes) // eslint-disable-line no-unused-vars\n{\n\treturn _stringByteFormat(bytes);\n}\n\n/**\n * prints out error messages based on data available from the browser\n * @param {Object} err error from try/catch block\n */\n// @ts-ignore\nfunction errorCatch(err) // eslint-disable-line no-unused-vars\n{\n\t_errorCatch(err);\n}\n\n// MARK: ActionIndicatorOverlayBoxLegacy\n\n/*************************************************************\n * OLD action indicator and overlay boxes calls\n * DO NOT USE\n * actionIndicator -> showActionIndicator\n * actionIndicator -> hideActionIndicator\n * actionIndicatorShow -> showActionIndicator\n * actionIndicatorHide -> hideActionIndicator\n * overlayBoxShow -> showOverlayBoxLayers\n * overlayBoxHide -> hideOverlayBoxLayers\n * setOverlayBox -> showOverlayBoxLayers\n * hideOverlayBox -> hideOverlayBoxLayers\n * ClearCall -> ClearCallActionBox\n * ***********************************************************/\n\n/**\n * show or hide the \"do\" overlay\n * @param {String} loc location name for action indicator\n * default empty. for console.log\n * @param {Boolean} [overlay=true] override the auto hide/show over the overlay div block\n */\n// @ts-ignore\nfunction actionIndicator(loc, overlay = true) // eslint-disable-line no-unused-vars\n{\n\t_actionIndicator(loc, overlay);\n}\n\n/**\n * explicit show for action Indicator\n * instead of automatically show or hide, do on command show\n * @param {String} loc location name for action indicator\n * default empty. for console.log\n * @param {Boolean} [overlay=true] override the auto hide/show over the overlay div block\n */\n// @ts-ignore\nfunction actionIndicatorShow(loc, overlay = true) // eslint-disable-line no-unused-vars\n{\n\t_actionIndicatorShow(loc, overlay);\n}\n\n/**\n * explicit hide for action Indicator\n * instead of automatically show or hide, do on command hide\n * @param {String} loc location name for action indicator\n * default empty. for console.log\n * @param {Boolean} [overlay=true] override the auto hide/show over the overlay div block\n */\n// @ts-ignore\nfunction actionIndicatorHide(loc, overlay = true) // eslint-disable-line no-unused-vars\n{\n\t_actionIndicatorHide(loc, overlay);\n}\n\n/**\n * shows the overlay box or if already visible, bumps the zIndex to 100\n */\n// @ts-ignore\nfunction overlayBoxShow() // eslint-disable-line no-unused-vars\n{\n\t_overlayBoxShow();\n}\n\n/**\n * hides the overlay box or if zIndex is 100 bumps it down to previous level\n */\n// @ts-ignore\nfunction overlayBoxHide() // eslint-disable-line no-unused-vars\n{\n\t_overlayBoxHide();\n}\n\n/**\n * position the overlay block box and shows it\n */\n// @ts-ignore\nfunction setOverlayBox() // eslint-disable-line no-unused-vars\n{\n\t_setOverlayBox();\n}\n\n/**\n * opposite of set, always hides overlay box\n */\n// @ts-ignore\nfunction hideOverlayBox() // eslint-disable-line no-unused-vars\n{\n\t_hideOverlayBox();\n}\n\n/**\n * the abort call, clears the action box and hides it and the overlay box\n */\n// @ts-ignore\nfunction ClearCall() // eslint-disable-line no-unused-vars\n{\n\t_ClearCall();\n}\n\n// MARK: ActionIndicatorOverlayBox\n\n/*************************************************************\n * NEW action indicator and overlay box calls\n * USE THIS\n * ***********************************************************/\n\n/**\n * show action indicator\n * - checks if not existing and add\n * - only shows if not visible (else ignore)\n * - overlaybox check is called and shown on a fixzed\n * zIndex of 1000\n * - indicator is page centered\n * @param {String} loc ID string, only used for console log\n */\n// @ts-ignore\nfunction showActionIndicator(loc) // eslint-disable-line no-unused-vars\n{\n\taiob.showActionIndicator(loc);\n}\n\n/**\n * hide action indicator, if it is visiable\n * If the global variable GL_OB_S is > GL_OB_BASE then\n * the overlayBox is not hidden but the zIndex\n * is set to this value\n * @param {String} loc ID string, only used for console log\n */\n// @ts-ignore\nfunction hideActionIndicator(loc) // eslint-disable-line no-unused-vars\n{\n\taiob.hideActionIndicator(loc);\n}\n\n/**\n * checks if overlayBox exists, if not it is\n * added as hidden item at the body end\n */\n// @ts-ignore\nfunction checkOverlayExists() // eslint-disable-line no-unused-vars\n{\n\taiob.checkOverlayExists();\n}\n\n/**\n * show overlay box\n * if not visible show and set zIndex to 10 (GL_OB_BASE)\n * if visible, add +1 to the GL_OB_S variable and\n * _ zIndex by this value\n */\n// @ts-ignore\nfunction showOverlayBoxLayers(el_id) // eslint-disable-line no-unused-vars\n{\n\taiob.showOverlayBoxLayers(el_id);\n}\n\n/**\n * hide overlay box\n * lower GL_OB_S value by -1\n * if we are 10 (GL_OB_BASE) or below hide the overlayIndex\n * and set zIndex and GL_OB_S to 0\n * else just set zIndex to the new GL_OB_S value\n * @param {String} el_id Target to hide layer\n */\n// @ts-ignore\nfunction hideOverlayBoxLayers(el_id='') // eslint-disable-line no-unused-vars\n{\n\taiob.hideOverlayBoxLayers(el_id);\n}\n\n/**\n * only for single action box\n */\n// @ts-ignore\nfunction clearCallActionBox() // eslint-disable-line no-unused-vars\n{\n\taiob.clearCallActionBox();\n}\n\n// MARK: DOM MANAGEMENT FUNCTIONS\n/**\n * reates object for DOM element creation flow\n * @param {String} tag must set tag (div, span, etc)\n * @param {String} [id=''] optional set for id, if input, select will be used for name\n * @param {String} [content=''] text content inside, is skipped if sub elements exist\n * @param {Array} [css=[]] array for css tags\n * @param {Object} [options={}] anything else (value, placeholder, OnClick, style)\n * @return {Object} created element as an object\n */\n// @ts-ignore\nfunction cel(tag, id = '', content = '', css = [], options = {}) // eslint-disable-line no-unused-vars\n{\n\treturn hec.cel(tag, id, content, css, options);\n}\n\n/**\n * attach a cel created object to another to create a basic DOM tree\n * @param {Object} base object where to attach/search\n * @param {Object} attach the object to be attached\n * @param {String} [id=''] optional id, if given search in base for this id and attach there\n * @return {Object} \"none\", technically there is no return needed as it is global attach\n */\n// @ts-ignore\nfunction ael(base, attach, id = '') // eslint-disable-line no-unused-vars\n{\n\treturn hec.ael(base, attach, id);\n}\n\n/**\n * directly attach n elements to one master base element\n * this type does not s_port attach with optional id\n * @param {Object} base object to where we attach the elements\n * @param {...Object} attach attach 1..n: attach directly to the base element those attachments\n * @return {Object} \"none\", technically there is no return needed, global attach\n */\n// @ts-ignore\nfunction aelx(base, ...attach) // eslint-disable-line no-unused-vars\n{\n\treturn hec.aelx(base, ...attach);\n}\n\n/**\n * same as aelx, but instead of using objects as parameters\n * get an array of objects to attach\n * @param {Object} base object to where we attach the elements\n * @param {Array} attach array of objects to attach\n * @return {Object} \"none\", technically there is no return needed, global attach\n */\n// @ts-ignore\nfunction aelxar(base, attach) // eslint-disable-line no-unused-vars\n{\n\treturn hec.aelxar(base, attach);\n}\n\n/**\n * resets the sub elements of the base element given\n * @param {Object} base cel created element\n * @return {Object} returns reset base element\n */\n// @ts-ignore\nfunction rel(base) // eslint-disable-line no-unused-vars\n{\n\treturn hec.rel(base);\n}\n\n/**\n * searches and removes style from css array\n * @param {Object} _element element to work one\n * @param {String} css style sheet to remove (name)\n * @return {Object} returns full element\n */\n// @ts-ignore\nfunction rcssel(_element, css) // eslint-disable-line no-unused-vars\n{\n\treturn hec.rcssel(_element, css);\n}\n\n/**\n * adds a new style sheet to the element given\n * @param {Object} _element element to work on\n * @param {String} css style sheet to add (name)\n * @return {Object} returns full element\n */\n// @ts-ignore\nfunction acssel(_element, css) // eslint-disable-line no-unused-vars\n{\n\treturn hec.acssel(_element, css);\n}\n\n/**\n * removes one css and adds another\n * is a wrapper around rcssel/acssel\n * @param {Object} _element element to work on\n * @param {String} rcss style to remove (name)\n * @param {String} acss style to add (name)\n * @return {Object} returns full element\n */\n// @ts-ignore\nfunction scssel(_element, rcss, acss) // eslint-disable-line no-unused-vars\n{\n\thec.scssel(_element, rcss, acss);\n}\n\n/**\n * parses the object tree created with cel/ael and converts it into an HTML string\n * that can be inserted into the page\n * @param {Object} tree object tree with dom element declarations\n * @return {String} HTML string that can be used as innerHTML\n */\n// @ts-ignore\nfunction phfo(tree) // eslint-disable-line no-unused-vars\n{\n\treturn hec.phfo(tree);\n}\n\n/**\n * Create HTML elements from array list\n * as a flat element without master object file\n * Is like tree.sub call\n * @param {Array} list Array of cel created objects\n * @return {String} HTML String\n */\n// @ts-ignore\nfunction phfa(list) // eslint-disable-line no-unused-vars\n{\n\treturn hec.phfa(list);\n}\n// *** DOM MANAGEMENT FUNCTIONS\n\n// MARK: HTML Helpers\n// BLOCK: html wrappers for quickly creating html data blocks\n\n/**\n * NOTE: OLD FORMAT which misses multiple block set\n * creates an select/options drop down block.\n * the array needs to be key -> value format.\n * key is for the option id and value is for the data output\n * @param {String} name name/id\n * @param {Object} data array for the options\n * @param {String} [selected=''] selected item uid\n * @param {Boolean} [options_only=false] if this is true, it will not print the select part\n * @param {Boolean} [return_string=false] return as string and not as element\n * @param {String} [sort=''] if empty as is, else allowed 'keys',\n * 'values' all others are ignored\n * @return {String} html with build options block\n */\n// @ts-ignore\nfunction html_options(name, data, selected = '', options_only = false, return_string = false, sort = '') // eslint-disable-line no-unused-vars\n{\n\treturn _html_options(name, data, selected, options_only, return_string, sort);\n}\n\n/**\n * NOTE: USE THIS CALL, the above one is deprecated\n * creates an select/options drop down block.\n * the array needs to be key -> value format.\n * key is for the option id and value is for the data output\n * @param {String} name name/id\n * @param {Object} data array for the options\n * @param {String} [selected=''] selected item uid\n * @param {Number} [multiple=0] if this is 1 or larger, the drop down\n * will be turned into multiple select\n * the number sets the size value unless it is 1,\n * then it is default\n * @param {Boolean} [options_only=false] if this is true, it will not print the select part\n * @param {Boolean} [return_string=false] return as string and not as element\n * @param {String} [sort=''] if empty as is, else allowed 'keys',\n * 'values' all others are ignored\n * @param {String} [onchange=''] onchange trigger call, default unset\n * @return {String} html with build options block\n */\n// @ts-ignore\nfunction html_options_block( // eslint-disable-line no-unused-vars\n\tname, data, selected = '', multiple = 0, options_only = false, return_string = false, sort = '', onchange = ''\n) {\n\treturn _html_options_block(\n\t\tname, data, selected, multiple, options_only, return_string, sort, onchange\n\t);\n}\n\n/**\n * refills a select box with options and keeps the selected\n * @param {String} name name/id\n * @param {Object} data array of options\n * @param {String} [sort=''] if empty as is, else allowed 'keys', 'values'\n * all others are ignored\n */\n// @ts-ignore\nfunction html_options_refill(name, data, sort = '') // eslint-disable-line no-unused-vars\n{\n\t_html_options_refill(name, data, sort);\n}\n\n// MARK: URL\n\n/**\n * parses a query string from window.location.search.substring(1)\n * ALTERNATIVE CODE\n * var url = new URL(window.location.href);\n * param_uid = url.searchParams.get('uid');\n * @param {String} [query=''] the query string to parse, if not set will auto fill\n * @param {String} [return_key=''] if set only returns this key entry or empty for none\n * @param {Boolean} [single=false] if set to true then only the first found will be returned\n */\n// @ts-ignore\nfunction parseQueryString(query = '', return_key = '', single = false) // eslint-disable-line no-unused-vars\n{\n\treturn _parseQueryString(query, return_key, single);\n}\n\n/**\n * searches query parameters for entry and returns data either as string or array\n * if no search is given the whole parameters are returned as an object\n * if a parameter is set several times it will be returned as an array\n * if search parameter set and nothing found and empty string is returned\n * if no parametes exist and no serach is set and empty object is returned\n * @param {String} [search=''] if set searches for this entry, if empty all parameters are returned\n * @param {String} [query=''] different query string to parse, if not set (default) the current window href is used\n * @param {Boolean} [single=false] if set to true then only the first found will be returned\n * @return {Object|Array|String} if search is empty, object, if search is set\n * and only one entry, then string, else array\n * unless single is true\n */\n// @ts-ignore\nfunction getQueryStringParam(search = '', query = '', single = false) // eslint-disable-line no-unused-vars\n{\n\treturn _getQueryStringParam(search, query, single);\n}\n\n/**\n * Add or update a query parameter in the current URL and update the browser's address bar\n * @param {string} key - The parameter name to add or update\n * @param {string} value - The value to set for the parameter\n * @param {boolean} [reload=false] - Whether to reload the page after updating the URL\n */\n// @ts-ignore\nfunction updateUrlParameter(key, value, reload = false) // eslint-disable-line no-unused-vars\n{\n\treturn _updateUrlParameter(key, value, reload);\n}\n\n/**\n * Remove a parameter from the current URL and update the browser's address bar\n * @param {string} key - The parameter name to remove\n * @param {boolean} [reload=false] - Whether to reload the page after updating the URL\n */\n// @ts-ignore\nfunction removeUrlParameter(key, reload = false) // eslint-disable-line no-unused-vars\n{\n\treturn _removeUrlParameter(key, reload);\n}\n\n/**\n * Check if key exists as URL parameter\n * @param {String} key URL parameter to search\n * @returns {Boolean} True if key exists\n */\n// @ts-ignore\nfunction hasUrlParameter(key) // eslint-disable-line no-unused-vars\n{\n\treturn _hasUrlParameter(key);\n}\n\n/**\n * Return one value for a URL paramter or null if not found\n * @param {String} key Which URL parameter to get\n * @returns {String|Null} URL parameter content\n */\n// @ts-ignore\nfunction getUrlParameter(key) // eslint-disable-line no-unused-vars\n{\n\treturn _getUrlParameter(key);\n}\n\n// MARK: ACL LOGIN\n// *** MASTER logout call\n/**\n * submits basic data for form logout\n */\n// @ts-ignore\nfunction loginLogout() // eslint-disable-line no-unused-vars\n{\n\t_loginLogout();\n}\n\n/**\n * create login string and logout button elements\n * @param {String} login_string the login string to show on the left\n * @param {String} [header_id='mainHeader'] the target for the main element block\n * if not set mainHeader is assumed\n * this is the target div for the \"loginRow\"\n */\n// @ts-ignore\nfunction createLoginRow(login_string, header_id = 'mainHeader') // eslint-disable-line no-unused-vars\n{\n\tlnm.createLoginRow(login_string, header_id);\n}\n\n/**\n * create the top nav menu that switches physical between pages\n * (edit access data based)\n * @param {Object} nav_menu the built nav menu with highlight info\n * @param {String} [header_id='mainHeader'] the target for the main element block\n * if not set mainHeader is assumed\n * this is the target div for the \"menuRow\"\n */\n// @ts-ignore\nfunction createNavMenu(nav_menu, header_id = 'mainHeader') // eslint-disable-line no-unused-vars\n{\n\tlnm.createNavMenu(nav_menu, header_id);\n}\n\n// MARK: ACTION BOX\n\n/**\n * Show an action box\n * @param {string} [target_id='actionBox'] where to attach content to, if not exists, create new\n * @param {string} [content=''] content to add to the box\n * @param {array} [action_box_css=[]] additional css elements for the action box\n * @param {number} [override=0] override size adjust\n * @param {number} [content_override=0] override content size adjust\n */\n// @ts-ignore\nfunction showFillActionBox(target_id = 'actionBox', content = '', action_box_css = [], override = 0, content_override = 0) // eslint-disable-line no-unused-vars\n{\n\tab.showFillActionBox(target_id, content, action_box_css, override, content_override);\n}\n\n/**\n * Fill action box with content, create it if it does not existgs\n * @param {string} [target_id='actionBox'] where to attach content to, if not exists, create new\n * @param {string} [content=''] content to add to the box\n * @param {array} [action_box_css=[]] additional css elements for the action box\n */\n// @ts-ignore\nfunction fillActionBox(target_id = 'actionBox', content = '', action_box_css = []) // eslint-disable-line no-unused-vars\n{\n\t// show action box, calc height + center\n\tab.fillActionBox(target_id, content, action_box_css);\n}\n\n/**\n * Adjust the size of the action box\n * @param {string} [target_id='actionBox'] which actionBox to work on\n * @param {number} [override=0] override size adjust\n * @param {number} [content_override=0] override content size adjust\n */\n// @ts-ignore\nfunction adjustActionBox(target_id = 'actionBox', override = 0, content_override = 0) // eslint-disable-line no-unused-vars\n{\n\tab.adjustActionBox(target_id, override, content_override);\n}\n\n/**\n * hide any open action boxes and hide overlay\n */\n// @ts-ignore\nfunction hideAllActionBoxes() // eslint-disable-line no-unused-vars\n{\n\tab.hideAllActionBoxes();\n}\n\n/**\n * hide action box, but do not clear content\n * DEPRECATED\n * @param {string} [target_id='actionBox']\n */\n// @ts-ignore\nfunction hideActionBox(target_id = 'actionBox') // eslint-disable-line no-unused-vars\n{\n\tab.hideActionBox(target_id);\n}\n\n/**\n * Just show and adjust the box\n * DEPRECAED\n * @param {string} [target_id='actionBox'] which actionBox to work on\n * @param {number} [override=0] override size adjust\n * @param {number} [content_override=0] override content size adjust\n * @param {Boolean} [hide_all=false] if set to true, hide all other action boxes\n */\n// @ts-ignore\nfunction showActionBox(target_id = 'actionBox', override = 0, content_override = 0, hide_all = true) // eslint-disable-line no-unused-vars\n{\n\tab.showActionBox(target_id, override, content_override, hide_all);\n}\n\n/**\n * close an action box with default clear content\n * for just hide use hideActionBox\n * DEPRECATED\n * @param {String} [target_id='actionBox'] which action box to close, default is set\n * @param {Boolean} [clean=true] if set to false will not remove html content, just hide\n */\n// @ts-ignore\nfunction closeActionBox(target_id = 'actionBox', clean = true) // eslint-disable-line no-unused-vars\n{\n\t// set the target/content ids\n\tab.closeActionBox(target_id, clean);\n}\n\n/**\n * TODO: better stacked action box: OPEN\n * @param {string} [target_id='actionBox'] which actionBox to work on\n * @param {number} [override=0] override size adjust\n * @param {number} [content_override=0] override content size adjust\n * @param {Boolean} [hide_all=false] if set to true, hide all other action boxes\n */\n// @ts-ignore\nfunction showActionBoxFloat(target_id = 'actionBox', override = 0, content_override = 0, hide_all = false) // eslint-disable-line no-unused-vars\n{\n\tab.showActionBoxFloat(target_id, override, content_override, hide_all);\n}\n\n/**\n * TODO: better stacked action box: CLOSE\n * @param {String} [target_id='actionBox'] which action box to close, default is set\n * @param {Boolean} [clean=true] if set to false will not remove html content, just hide\n */\n// @ts-ignore\nfunction closeActionBoxFloat(target_id = 'actionBox', clean = true) // eslint-disable-line no-unused-vars\n{\n\tab.closeActionBoxFloat(target_id, clean);\n}\n\n/**\n * create a new action box and fill it with basic elements\n * @param {String} [target_id='actionBox']\n * @param {String} [title='']\n * @param {Object} [contents={}]\n * @param {Object} [headers={}]\n * @param {Boolean} [show_close=true]\n * @param {Object} [settings={}] Optional settings, eg style sheets\n */\n// @ts-ignore\nfunction createActionBox( // eslint-disable-line no-unused-vars\n\ttarget_id = 'actionBox',\n\ttitle = '',\n\tcontents = {},\n\theaders = {},\n\tsettings = {},\n\tshow_close = true\n) {\n\tab.createActionBox(target_id, title, contents, headers, settings, show_close);\n}\n\n/**\n * adjusts the action box height based on content and window height of browser\n * TODO: border on outside/and other margin things need to be added in overall adjustment\n * @param {String} [target_id='actionBox'] target id, if not set, fall back to default\n * @param {Number} [override=0] override value to add to the actionBox height\n * @param {Number} [content_override=0] override the value from _content block if it exists\n */\n// @ts-ignore\nfunction adjustActionBoxHeight(target_id = 'actionBox', override = 0, content_override = 0) // eslint-disable-line no-unused-vars\n{\n\tab.adjustActionBoxHeight(target_id, override, content_override);\n}\n\n// MARK: BROWSER DETECTION\nfunction isWebkit() // eslint-disable-line no-unused-vars\n{\n\treturn _isWebkit();\n}\n\nfunction isMobileWebKit() // eslint-disable-line no-unused-vars\n{\n\treturn _isMobileWebKit();\n}\n\nfunction isDesktopWebKit() // eslint-disable-line no-unused-vars\n{\n\treturn _isDesktopWebKit();\n}\n\n/* END */\n"], + "mappings": "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", + "names": ["i18n", "hec", "l10n", "hec", "l10n", "escapeHtml", "roundPrecision", "formatString", "unescapeHtml", "loadEl", "pop", "expandTA", "getWindowSize", "getScrollOffset", "getScrollOffsetOpener", "setCenter", "goToPos", "goTo", "numberWithCommas", "convertLBtoBR", "getTimestamp", "dec2hex", "generateId", "randomIdF", "getRandomIntInclusive", "isFunction", "executeFunctionByName", "isObject", "isArray", "isIterable", "getObjectCount", "keyInObject", "getKeyByValue", "valueInObject", "deepCopyFunction", "exists", "formatBytes", "formatBytesLong", "stringByteFormat", "errorCatch", "actionIndicator", "actionIndicatorShow", "actionIndicatorHide", "overlayBoxShow", "overlayBoxHide", "setOverlayBox", "hideOverlayBox", "ClearCall", "html_options", "html_options_block", "html_options_refill", "parseQueryString", "getQueryStringParam", "updateUrlParameter", "removeUrlParameter", "hasUrlParameter", "getUrlParameter", "loginLogout", "isWebkit", "isMobileWebKit", "isDesktopWebKit"] } diff --git a/www/lib/CoreLibs/Convert/Byte.php b/www/lib/CoreLibs/Convert/Byte.php index b0d05ece..22e9cbf5 100644 --- a/www/lib/CoreLibs/Convert/Byte.php +++ b/www/lib/CoreLibs/Convert/Byte.php @@ -77,7 +77,7 @@ class Byte // labels in order of size [Y, Z] $labels = ['', 'K', 'M', 'G', 'T', 'P', 'E']; // exp position calculation - $exp = floor(log($abs_bytes, $unit)); + $exp = (int)floor(log($abs_bytes, $unit)); // avoid printing out anything larger than max labels if ($exp >= count($labels)) { $exp = count($labels) - 1; diff --git a/www/lib/CoreLibs/Logging/ErrorMessage.php b/www/lib/CoreLibs/Logging/ErrorMessage.php index c952c69e..bf99f972 100644 --- a/www/lib/CoreLibs/Logging/ErrorMessage.php +++ b/www/lib/CoreLibs/Logging/ErrorMessage.php @@ -131,6 +131,7 @@ class ErrorMessage // set a jump target $this->setJumpTarget($jump_target['target'] ?? null, $jump_target['info'] ?? null, $level); // write to log for abort/crash + $this->log->setErrorMessageCallSetErrorMsg(); switch ($level) { case 'notice': $this->log->notice($message ?? $str, array_merge([ @@ -210,6 +211,7 @@ class ErrorMessage ?bool $log_error = null, ?bool $log_warning = null, ): void { + $this->log->setErrorMessageCallSetMessage(); $this->setErrorMsg( $error_id ?? '', $level, diff --git a/www/lib/CoreLibs/Logging/Logging.php b/www/lib/CoreLibs/Logging/Logging.php index 1320212b..5bedf4bc 100644 --- a/www/lib/CoreLibs/Logging/Logging.php +++ b/www/lib/CoreLibs/Logging/Logging.php @@ -29,11 +29,19 @@ use Stringable; class Logging { /** @var int minimum size for a max file size, so we don't set 1 byte, 10kb */ - public const MIN_LOG_MAX_FILESIZE = 10 * 1024; + public const int MIN_LOG_MAX_FILESIZE = 10 * 1024; /** @var string log file extension, not changeable */ - private const LOG_FILE_NAME_EXT = "log"; + private const string LOG_FILE_NAME_EXT = "log"; /** @var string log file block separator, not changeable */ - private const LOG_FILE_BLOCK_SEPARATOR = '.'; + private const string LOG_FILE_BLOCK_SEPARATOR = '.'; + /** @var int the base stack trace level for the line number */ + private const int DEFAULT_STACK_TRACE_LEVEL_LINE = 1; + + /** @var array */ + private const array STACK_OVERRIDE_CHECK = [ + 'setErrorMsg' => 2, + 'setMessage' => 3, + ]; // MARK: OPTION array // NOTE: the second party array{} hs some errors @@ -138,6 +146,12 @@ class Logging /** @var string Y-m-d file in file name */ private string $log_file_date = ''; + // speical flags for ErrorMessage calls + /** @var bool Flag to set if called from ErrorMessage::setErrorMsg */ + private bool $error_message_call_set_error_msg = false; + /** @var bool Flag to set if called from ErrorMessage::setMessage */ + private bool $error_message_call_set_message = false; + /** * 1: create a new log file per run (time stamp + unique ID) * 2: add Y-m-d and do automatic daily rotation @@ -627,25 +641,55 @@ class Logging $file_line = ''; $caller_class_method = '-'; $traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); - // print "[" . $level->getName() . "] [$message] prepareLog:
" . Support::printAr($traces); - // file + line: call not this but one before (the one that calls this) - // start from this level, if unset fall down until we are at null - $start_trace_level = 2; - for ($trace_level = $start_trace_level; $trace_level >= 0; $trace_level--) { - if (isset($traces[$trace_level])) { - $file_line = ($traces[$trace_level]['file'] ?? $traces[$trace_level]['function']) - . ':' . ($traces[$trace_level]['line'] ?? '-'); - // as namespace\class->method - $caller_class_method = - // get the last call before we are in the Logging class - ($traces[$trace_level]['class'] ?? '') - // connector, if unkown use == - . ($traces[$trace_level]['type'] ?? '') - // method/function: prepareLog->(debug|info|...)->[THIS] - . $traces[$trace_level]['function']; - break; + $stack_trace_start_level_line = self::DEFAULT_STACK_TRACE_LEVEL_LINE; + // set stack trace level +1 if called from ErrorMessage::setMessage + if ($this->error_message_call_set_message) { + $stack_trace_start_level_line = 3; + } elseif ($this->error_message_call_set_error_msg) { + $stack_trace_start_level_line = 2; + } + // if we have line > default, then check if valid, else reset to default + if ($stack_trace_start_level_line > self::DEFAULT_STACK_TRACE_LEVEL_LINE) { + // check if function at level is one of the override checks + $fn_check = $traces[$stack_trace_start_level_line]['function'] ?? ''; + if ( + !isset(self::STACK_OVERRIDE_CHECK[$fn_check]) || + self::STACK_OVERRIDE_CHECK[$fn_check] != $stack_trace_start_level_line + ) { + $stack_trace_start_level_line = self::DEFAULT_STACK_TRACE_LEVEL_LINE; } } + $this->error_message_call_set_message = false; + $this->error_message_call_set_error_msg = false; + // set stack trace level +1 if called from ErrorMessage::setMessage + // print "[" . $level->getName() . "] [$message] [" . $stack_trace_start_level_line . "] " + // . "prepareLog:
" . Support::printAr($traces); + // file + line: call not this but one before (the one that calls this) + // start from this level, if unset fall down until we are at null + // NOTE this has to be pushed to 3 for setMessage wrap calls + for ($trace_level = $stack_trace_start_level_line; $trace_level >= 0; $trace_level--) { + if (!isset($traces[$trace_level])) { + continue; + } + $file_line = ($traces[$trace_level]['file'] ?? $traces[$trace_level]['function']) + . ':' . ($traces[$trace_level]['line'] ?? '-'); + // call function is one stack level above + $trace_level++; + // skip setting if we are in the top level already + if (!isset($traces[$trace_level])) { + break; + } + // as namespace\class->method + $caller_class_method = + // get the last call before we are in the Logging class + ($traces[$trace_level]['class'] ?? '') + // connector, if unkown use == + . ($traces[$trace_level]['type'] ?? '') + // method/function: prepareLog->(debug|info|...)->[THIS] + . $traces[$trace_level]['function']; + break; + } + // if not line is set if (empty($file_line)) { $file_line = System::getPageName(System::FULL_PATH); } @@ -1017,6 +1061,30 @@ class Logging return $this->log_max_filesize; } + // ********************************************************************* + // MARK: ErrorMessage class overrides + // ********************************************************************* + + /** + * call if called from Error Message setMessage wrapper + * + * @return void + */ + public function setErrorMessageCallSetMessage(): void + { + $this->error_message_call_set_message = true; + } + + /** + * call if called from Error Message setMessage wrapper + * + * @return void + */ + public function setErrorMessageCallSetErrorMsg(): void + { + $this->error_message_call_set_error_msg = true; + } + // ********************************************************************* // MARK: OPTIONS CALLS // *********************************************************************