window.ls=window.ls||{};window.ls.container=function(){let stock={};let listeners={};let set=function(name,object,singleton,watch=true){if(typeof name!=='string'){throw new Error('var name must be of type string');} if(typeof singleton!=='boolean'){throw new Error('var singleton "'+singleton+'" of service "'+name+'" must be of type boolean');} stock[name]={name:name,object:object,singleton:singleton,instance:null,watch:watch,};if(!watch){return this;} let binds=listeners[name]||{};for(let key in binds){if(binds.hasOwnProperty(key)){document.dispatchEvent(new CustomEvent(key));}} return this;};let get=function(name){let service=(undefined!==stock[name])?stock[name]:null;if(null==service){return null;} if(service.instance){return service.instance;} let instance=(typeof service.object==='function')?this.resolve(service.object):service.object;let skip=false;if(service.watch&&name!=='window'&&name!=='document'&&name!=='element'&&typeof instance==='object'&&instance!==null){let handler={name:service.name,watch:function(){},get:function(target,key){if(key==="__name"){return this.name;} if(key==="__watch"){return this.watch;} if(key==="__proxy"){return true;} if(typeof target[key]==='object'&&target[key]!==null&&!target[key].__proxy){let handler=Object.assign({},this);handler.name=handler.name+'.'+key;return new Proxy(target[key],handler)} else{return target[key];}},set:function(target,key,value,receiver){if(key==="__name"){return this.name=value;} if(key==="__watch"){return this.watch=value;} target[key]=value;let path=receiver.__name+'.'+key;document.dispatchEvent(new CustomEvent(path+'.changed'));if(skip){return true;} skip=true;container.set('$prop',key,true);container.set('$value',value,true);container.resolve(this.watch);container.set('$key',null,true);container.set('$value',null,true);skip=false;return true;},};instance=new Proxy(instance,handler);} if(service.singleton){service.instance=instance;} return instance;};let resolve=function(target){if(!target){return()=>{};} let self=this;const REGEX_COMMENTS=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;const REGEX_FUNCTION_PARAMS=/(?:\s*(?:function\s*[^(]*)?\s*)((?:[^'"]|(?:(?:(['"])(?:(?:.*?[^\\]\2)|\2))))*?)\s*(?=(?:=>)|{)/m;const REGEX_PARAMETERS_VALUES=/\s*([\w\\$]+)\s*(?:=\s*((?:(?:(['"])(?:\3|(?:.*?[^\\]\3)))((\s*\+\s*)(?:(?:(['"])(?:\6|(?:.*?[^\\]\6)))|(?:[\w$]*)))*)|.*?))?\s*(?:,|$)/gm;function getParams(func){let functionAsString=func.toString();let params=[];let match;functionAsString=functionAsString.replace(REGEX_COMMENTS,'');functionAsString=functionAsString.match(REGEX_FUNCTION_PARAMS)[1];if(functionAsString.charAt(0)==='('){functionAsString=functionAsString.slice(1,-1);} while(match=REGEX_PARAMETERS_VALUES.exec(functionAsString)){params.push(match[1]);} return params;} let args=getParams(target);return target.apply(target,args.map(function(value){return self.get(value.trim());}));};let path=function(path,value,as,prefix){as=(as)?as:container.get('$as');prefix=(prefix)?prefix:container.get('$prefix');path=((path.indexOf('.')>-1)?path.replace(as+'.',prefix+'.'):path.replace(as,prefix)).split('.');let name=path.shift();let object=this.get(name);let result=null;while(path.length>1){if(!object){return null;} object=object[path.shift()];} if(value!==null&&value!==undefined){object[path.shift()]=value;return true;} if(!object){return null;} let shift=path.shift();if(!shift){result=object;} else{return object[shift];} return result;};let bind=function(element,path,callback,as,prefix){as=(as)?as:container.get('$as');prefix=(prefix)?prefix:container.get('$prefix');let event=((path.indexOf('.')>-1)?path.replace(as+'.',prefix+'.'):path.replace(as,prefix))+'.changed';let service=event.split('.').slice(0,1).pop();listeners[service]=listeners[service]||{};listeners[service][event]=true;let printer=()=>{if(!document.body.contains(element)){element=null;document.removeEventListener(event,printer,false);return false;} callback();};document.addEventListener(event,printer);};let container={set:set,get:get,resolve:resolve,path:path,bind:bind,stock:stock,listeners:listeners,};set('container',container,true,false);return container;}();window.ls.container.set('http',function(document){let globalParams=[],globalHeaders=[];let addParam=function(url,param,value){param=encodeURIComponent(param);let a=document.createElement('a');param+=(value?"="+encodeURIComponent(value):"");a.href=url;a.search+=(a.search?"&":"")+param;return a.href;};let request=function(method,url,headers,payload,progress){let i;if(-1===['GET','POST','PUT','DELETE','TRACE','HEAD','OPTIONS','CONNECT','PATCH'].indexOf(method)){throw new Error('var method must contain a valid HTTP method name');} if(typeof url!=='string'){throw new Error('var url must be of type string');} if(typeof headers!=='object'){throw new Error('var headers must be of type object');} if(typeof url!=='string'){throw new Error('var url must be of type string');} for(i=0;i-1?part.substr(0,eq):part;let val=eq>-1?decodeURIComponent(part.substr(eq+1)):'';let from=key.indexOf('[');if(from===-1){result[decodeURIComponent(key)]=val;} else{let to=key.indexOf(']');let index=decodeURIComponent(key.substring(from+1,to));key=decodeURIComponent(key.substring(0,from));if(!result[key]){result[key]=[];} if(!index){result[key].push(val);} else{result[key][index]=val;}}});return result;};let states=[];let params=getJsonFromUrl(window.location.search);let hash=window.location.hash;let current=null;let previous=null;let getPrevious=()=>previous;let getCurrent=()=>current;let setPrevious=(value)=>{previous=value;return this;};let setCurrent=(value)=>{current=value;return this;};let setParam=function(key,value){params[key]=value;return this;};let getParam=function(key,def){if(key in params){return params[key];} return def;};let getParams=function(){return params;};let getURL=function(){return window.location.href;};let add=function(path,view){if(typeof path!=='string'){throw new Error('path must be of type string');} if(typeof view!=='object'){throw new Error('view must be of type object');} states[states.length++]={path:path,view:view};return this;};let match=function(location){let url=location.pathname+((location.hash)?location.hash:'');states.sort(function(a,b){return b.path.length-a.path.length;});states.sort(function(a,b){let n=b.path.split('/').length-a.path.split('/').length;if(n!==0){return n;} return b.path.length-a.path.length;});for(let i=0;i{let reference=match.substring(2,match.length-2).replace('[\'','.').replace('\']','').trim();reference=reference.split('|');let path=(reference[0]||'');let result=container.path(path,undefined,as,prefix);path=(path.indexOf('.')>-1)?path.replace(as+'.',prefix+'.'):path.replace(as,prefix);if(!paths.includes(path)){paths.push(path);} if(reference.length>=2){for(let i=1;ipaths,}},true,false);window.ls.container.set('filter',function(container){let filters={};let add=function(name,callback){filters[name]=callback;return this;};let apply=function(name,value){container.set('$value',value,true,false);return container.resolve(filters[name]);};add('uppercase',($value)=>{return $value.toUpperCase();});add('lowercase',($value)=>{return $value.toLowerCase();});return{add:add,apply:apply}},true,false);window.ls.container.get('filter').add('escape',value=>{if(typeof value!=='string'){return value;} return value.replace(/&/g,'&').replace(//g,'>').replace(/\"/g,'"').replace(/\'/g,''').replace(/\//g,'/');});window.ls=window.ls||{};window.ls.container.set('window',window,true,false).set('document',window.document,true,false).set('element',window.document,true,false);window.ls.run=function(window){try{this.view.render(window.document);} catch(error){let handler=window.ls.container.resolve(this.error);handler(error);}};window.ls.error=()=>{return error=>{console.error('ls-error',error.message,error.stack,error.toString());}};window.ls.router=window.ls.container.get('router');window.ls.view=window.ls.container.get('view');window.ls.filter=window.ls.container.get('filter');window.ls.container.get('view').add({selector:'data-ls-router',repeat:false,controller:function(element,window,document,view,router,tasks){let firstFromServer=(element.getAttribute('data-first-from-server')==='true');let scope={selector:'data-ls-scope',template:false,repeat:true,controller:function(){},};let init=function(route){let count=parseInt(element.getAttribute('data-ls-scope-count')||0);element.setAttribute('data-ls-scope-count',count+1);window.scrollTo(0,0);if(window.document.body.scrollTo){window.document.body.scrollTo(0,0);} router.reset();if(null===route){return;} scope.template=(undefined!==route.view.template)?route.view.template:null;scope.controller=(undefined!==route.view.controller)?route.view.controller:function(){};document.dispatchEvent(new CustomEvent('state-change'));if(firstFromServer&&null===router.getPrevious()){scope.template='';} else if(count===1){view.render(element);} else if(null!==router.getPrevious()){view.render(element);} document.dispatchEvent(new CustomEvent('state-changed'));};let findParent=function(tagName,el){if((el.nodeName||el.tagName).toLowerCase()===tagName.toLowerCase()){return el;} while(el=el.parentNode){if((el.nodeName||el.tagName).toLowerCase()===tagName.toLowerCase()){return el;}} return null;};element.removeAttribute('data-ls-router');element.setAttribute('data-ls-scope','');element.setAttribute('data-ls-scope-count',1);view.add(scope);document.addEventListener('click',function(event){let target=findParent('a',event.target);if(!target){return false;} if(!target.href){return false;} if((event.metaKey)){return false;} if((target.hasAttribute('target'))&&('_blank'===target.getAttribute('target'))){return false;} if(target.hostname!==window.location.hostname){return false;} let route=router.match(target);if(null===route){return false;} event.preventDefault();if(window.location===target.href){return false;} route.view.state=(undefined===route.view.state)?true:route.view.state;if(true===route.view.state){if(router.getPrevious()&&router.getPrevious().view&&(router.getPrevious().view.scope!==route.view.scope)){window.location.href=target.href;return false;} window.history.pushState({},'Unknown',target.href);} init(route);return true;});window.addEventListener('popstate',function(){init(router.match(window.location));});window.addEventListener('hashchange',function(){init(router.match(window.location));});init(router.match(window.location));}});window.ls.container.get('view').add({selector:'data-ls-attrs',controller:function(element,expression,container,$as,$prefix){let attrs=element.getAttribute('data-ls-attrs').trim().split(',');let paths=[];let debug=element.getAttribute('data-debug')||false;let check=()=>{container.set('element',element,true,false);if(debug){console.info('debug-ls-attrs attributes:',attrs);} for(let i=0;i{for(let i=0;i-1));value=element.value;} catch{return null;}} if(bind){element.addEventListener('change',()=>{for(let i=0;i-1){value.splice(index,1);} container.path(paths[i],value,$as,$prefix);}});} return;} if(element.value!==value){element.value=value;} if(bind){element.addEventListener('input',sync);element.addEventListener('change',sync);}} else{if(element.innerText!==value){element.innerHTML=value;}}};let sync=((as,prefix)=>{return()=>{for(let i=0;i{echo(expression.parse(syntax,null,$as,$prefix),false);});path.pop();}}}});window.ls.container.get('view').add({selector:'data-ls-if',controller:function(element,expression,container,view,$as,$prefix){let result='';let syntax=element.getAttribute('data-ls-if')||'';let debug=element.getAttribute('data-debug')||false;let paths=[];let check=()=>{if(debug){console.info('debug-ls-if',expression.parse(syntax.replace(/(\r\n|\n|\r)/gm,' '),'undefined',$as,$prefix,true));} try{result=(eval(expression.parse(syntax.replace(/(\r\n|\n|\r)/gm,' '),'undefined',$as,$prefix,true)));} catch(error){throw new Error('Failed to evaluate expression "'+syntax+' (resulted with: "'+result+'")": '+error);} if(debug){console.info('debug-ls-if result:',result);} paths=expression.getPaths();let prv=element.$lsSkip;element.$lsSkip=!result;if(!result){element.style.visibility='hidden';element.style.display='none';} else{element.style.removeProperty('display');element.style.removeProperty('visibility');} if(prv===true&&element.$lsSkip===false){view.render(element)}};check();for(let i=0;i{let context=expr+'.'+index;container.set(as,container.path(context),true,watch);container.set('$index',index,true,false);container.set('$prefix',context,true,false);container.set('$as',as,true,false);view.render(children[prop]);})(prop);} container.set('$index',null,true,false,false);container.set('$prefix','',true,false,false);container.set('$as','',true,false,false);element.dispatchEvent(new Event('looped'));};let template=(element.children.length===1)?element.children[0]:window.document.createElement('li');echo();container.bind(element,expr+'.length',echo);let path=(expr+'.length').split('.');while(path.length){container.bind(element,path.join('.'),echo);path.pop();}}});window.ls.container.get('view').add({selector:'data-ls-template',template:false,repeat:true,controller:function(element,view,http,expression,document){let template=expression.parse(element.getAttribute('data-ls-template'));let type=element.getAttribute('data-type')||'url';element.innerHTML='';if('script'===type){let inlineTemplate=document.getElementById(template);if(inlineTemplate&&inlineTemplate.innerHTML){element.innerHTML=inlineTemplate.innerHTML;element.dispatchEvent(new CustomEvent('template-loaded',{bubbles:true,cancelable:false}));} else{element.innerHTML='Missing template "'+template+'"';} return;} http.get(template).then(function(element){return function(data){element.innerHTML=data;view.render(element);element.dispatchEvent(new CustomEvent('template-loaded',{bubbles:true,cancelable:false}));}}(element),function(){throw new Error('Failed loading template');});}});window.ls.error=function(){return function(error){alert(error);console.error('ERROR-APP',error);}};window.addEventListener('error',function(event){alert(event.error.message);console.error('ERROR-EVENT:',event.error.message,event.error.stack);});document.addEventListener('logout',function(){window.location='/auth/signin';});document.addEventListener('http-get-401',function(){document.dispatchEvent(new CustomEvent('logout'));},true);(function(window){"use strict";window.ls.container.set('alerts',function(window){return{list:[],counter:0,add:function(message,time){var scope=this;message.id=this.counter++;scope.list.unshift(message);if(time>0){window.setTimeout(function(message){return function(){scope.remove(message.id)}}(message),time);} return message.id;},remove:function(id){let scope=this;for(let index=0;index9?-1:0)},Y:function(){return jsdate.getFullYear()},y:function(){return f.Y().toString().slice(-2)},a:function(){return jsdate.getHours()>11?'pm':'am'},A:function(){return f.a().toUpperCase()},B:function(){var H=jsdate.getUTCHours()*36e2 var i=jsdate.getUTCMinutes()*60 var s=jsdate.getUTCSeconds() return _pad(Math.floor((H+i+s+36e2)/86.4)%1e3,3)},g:function(){return f.G()%12||12},G:function(){return jsdate.getHours()},h:function(){return _pad(f.g(),2)},H:function(){return _pad(f.G(),2)},i:function(){return _pad(jsdate.getMinutes(),2)},s:function(){return _pad(jsdate.getSeconds(),2)},u:function(){return _pad(jsdate.getMilliseconds()*1000,6)},e:function(){var msg='Not supported (see source code of date() for timezone on how to add support)' throw new Error(msg)},I:function(){var a=new Date(f.Y(),0) var c=Date.UTC(f.Y(),0) var b=new Date(f.Y(),6) var d=Date.UTC(f.Y(),6) return((a-c)!==(b-d))?1:0},O:function(){var tzo=jsdate.getTimezoneOffset() var a=Math.abs(tzo) return(tzo>0?'-':'+')+_pad(Math.floor(a/60)*100+a%60,4)},P:function(){var O=f.O() return(O.substr(0,3)+':'+O.substr(3,2))},T:function(){return'UTC'},Z:function(){return-jsdate.getTimezoneOffset()*60},c:function(){return'Y-m-d\\TH:i:sP'.replace(formatChr,formatChrCb)},r:function(){return'D, d M Y H:i:s O'.replace(formatChr,formatChrCb)},U:function(){return jsdate/1000|0}} var _date=function(format,timestamp){jsdate=(timestamp===undefined?new Date():(timestamp instanceof Date)?new Date(timestamp):new Date(timestamp*1000)) return format.replace(formatChr,formatChrCb)} return _date(format,timestamp)} function strtotime(text,now){var parsed var match var today var year var date var days var ranges var len var times var regex var i var fail=false if(!text){return fail} text=text.replace(/^\s+|\s+$/g,'').replace(/\s{2,}/g,' ').replace(/[\t\r\n]/g,'').toLowerCase() var pattern=new RegExp(['^(\\d{1,4})','([\\-\\.\\/:])','(\\d{1,2})','([\\-\\.\\/:])','(\\d{1,4})','(?:\\s(\\d{1,2}):(\\d{2})?:?(\\d{2})?)?','(?:\\s([A-Z]+)?)?$'].join('')) match=text.match(pattern) if(match&&match[2]===match[4]){if(match[1]>1901){switch(match[2]){case'-':if(match[3]>12||match[5]>31){return fail} return new Date(match[1],parseInt(match[3],10)-1,match[5],match[6]||0,match[7]||0,match[8]||0,match[9]||0)/1000 case'.':return fail case'/':if(match[3]>12||match[5]>31){return fail} return new Date(match[1],parseInt(match[3],10)-1,match[5],match[6]||0,match[7]||0,match[8]||0,match[9]||0)/1000}}else if(match[5]>1901){switch(match[2]){case'-':if(match[3]>12||match[1]>31){return fail} return new Date(match[5],parseInt(match[3],10)-1,match[1],match[6]||0,match[7]||0,match[8]||0,match[9]||0)/1000 case'.':if(match[3]>12||match[1]>31){return fail} return new Date(match[5],parseInt(match[3],10)-1,match[1],match[6]||0,match[7]||0,match[8]||0,match[9]||0)/1000 case'/':if(match[1]>12||match[3]>31){return fail} return new Date(match[5],parseInt(match[1],10)-1,match[3],match[6]||0,match[7]||0,match[8]||0,match[9]||0)/1000}}else{switch(match[2]){case'-':if(match[3]>12||match[5]>31||(match[1]<70&&match[1]>38)){return fail} year=match[1]>=0&&match[1]<=38?+match[1]+2000:match[1] return new Date(year,parseInt(match[3],10)-1,match[5],match[6]||0,match[7]||0,match[8]||0,match[9]||0)/1000 case'.':if(match[5]>=70){if(match[3]>12||match[1]>31){return fail} return new Date(match[5],parseInt(match[3],10)-1,match[1],match[6]||0,match[7]||0,match[8]||0,match[9]||0)/1000} if(match[5]<60&&!match[6]){if(match[1]>23||match[3]>59){return fail} today=new Date() return new Date(today.getFullYear(),today.getMonth(),today.getDate(),match[1]||0,match[3]||0,match[5]||0,match[9]||0)/1000} return fail case'/':if(match[1]>12||match[3]>31||(match[5]<70&&match[5]>38)){return fail} year=match[5]>=0&&match[5]<=38?+match[5]+2000:match[5] return new Date(year,parseInt(match[1],10)-1,match[3],match[6]||0,match[7]||0,match[8]||0,match[9]||0)/1000 case':':if(match[1]>23||match[3]>59||match[5]>59){return fail} today=new Date() return new Date(today.getFullYear(),today.getMonth(),today.getDate(),match[1]||0,match[3]||0,match[5]||0)/1000}}} if(text==='now'){return now===null||isNaN(now)?new Date().getTime()/1000|0:now|0} if(!isNaN(parsed=Date.parse(text))){return parsed/1000|0} pattern=new RegExp(['^([0-9]{4}-[0-9]{2}-[0-9]{2})','[ t]','([0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]+)?)','([\\+-][0-9]{2}(:[0-9]{2})?|z)'].join('')) match=text.match(pattern) if(match){if(match[4]==='z'){match[4]='Z'}else if(match[4].match(/^([+-][0-9]{2})$/)){match[4]=match[4]+':00'} if(!isNaN(parsed=Date.parse(match[1]+'T'+match[2]+match[4]))){return parsed/1000|0}} date=now?new Date(now*1000):new Date() days={'sun':0,'mon':1,'tue':2,'wed':3,'thu':4,'fri':5,'sat':6} ranges={'yea':'FullYear','mon':'Month','day':'Date','hou':'Hours','min':'Minutes','sec':'Seconds'} function lastNext(type,range,modifier){var diff var day=days[range] if(typeof day!=='undefined'){diff=day-date.getDay() if(diff===0){diff=7*modifier}else if(diff>0&&type==='last'){diff-=7}else if(diff<0&&type==='next'){diff+=7} date.setDate(date.getDate()+diff)}} function process(val){var splt=val.split(' ') var type=splt[0] var range=splt[1].substring(0,3) var typeIsNumber=/\d+/.test(type) var ago=splt[2]==='ago' var num=(type==='last'?-1:1)*(ago?-1:1) if(typeIsNumber){num*=parseInt(type,10)} if(ranges.hasOwnProperty(range)&&!splt[1].match(/^mon(day|\.)?$/i)){return date['set'+ranges[range]](date['get'+ranges[range]]()+num)} if(range==='wee'){return date.setDate(date.getDate()+(num*7))} if(type==='next'||type==='last'){lastNext(type,range,num)}else if(!typeIsNumber){return false} return true} times='(years?|months?|weeks?|days?|hours?|minutes?|min|seconds?|sec'+'|sunday|sun\\.?|monday|mon\\.?|tuesday|tue\\.?|wednesday|wed\\.?'+'|thursday|thu\\.?|friday|fri\\.?|saturday|sat\\.?)' regex='([+-]?\\d+\\s'+times+'|'+'(last|next)\\s'+times+')(\\sago)?' match=text.match(new RegExp(regex,'gi')) if(!match){return fail} for(i=0,len=match.length;i0){json[name]=element.children[element.selectedIndex].value;} else if('radio'===type){if(element.checked){json[name]=element.value;}} else if('checkbox'===type){if(!Array.isArray(json[name])){json[name]=[];} if(element.checked){json[name].push(element.value);}} else if('file'===type){console.log('form2json file:',element.files);json[name]=element.files[0];} else if(undefined!==element.value){if((json[name]!==undefined)&&(!Array.isArray(json[name]))){json[name]=[json[name]];} if(Array.isArray(json[name])){json[name].push(element.value);} else{json[name]=element.value;}} json[name]=cast(json[name],castTo);}} for(let i=0;i>>(32-d))}function K(G,k){let I,d,F,H,x;F=(G&2147483648);H=(k&2147483648);I=(G&1073741824);d=(k&1073741824);x=(G&1073741823)+(k&1073741823);if(I&d){return(x^2147483648^F^H)}if(I|d){if(x&1073741824){return(x^3221225472^F^H)}else{return(x^1073741824^F^H)}}else{return(x^F^H)}}function r(d,F,k){return(d&F)|((~d)&k)}function q(d,F,k){return(d&k)|(F&(~k))}function p(d,F,k){return(d^F^k)}function n(d,F,k){return(F^(d|(~k)))}function u(G,F,aa,Z,k,H,I){G=K(G,K(K(r(F,aa,Z),k),I));return K(L(G,H),F)}function f(G,F,aa,Z,k,H,I){G=K(G,K(K(q(F,aa,Z),k),I));return K(L(G,H),F)}function D(G,F,aa,Z,k,H,I){G=K(G,K(K(p(F,aa,Z),k),I));return K(L(G,H),F)}function t(G,F,aa,Z,k,H,I){G=K(G,K(K(n(F,aa,Z),k),I));return K(L(G,H),F)}function e(G){let Z;let F=G.length;let x=F+8;let k=(x-(x%64))/64;let I=(k+1)*16;let aa=Array(I-1);let d=0;let H=0;while(H>>29;return aa}function B(x){let k="",F="",G,d;for(d=0;d<=3;d++){G=(x>>>(d*8))&255;F="0"+G.toString(16);k=k+F.substr(F.length-2,2)}return k}function J(k){k=k.replace(/rn/g,"n");let d="";for(let F=0;F127)&&(x<2048)){d+=String.fromCharCode((x>>6)|192);d+=String.fromCharCode((x&63)|128)}else{d+=String.fromCharCode((x>>12)|224);d+=String.fromCharCode(((x>>6)&63)|128);d+=String.fromCharCode((x&63)|128)}}}return d}let C=Array();let P,h,E,v,g,Y,X,W,V;let S=7,Q=12,N=17,M=22;let A=5,z=9,y=14,w=20;let o=4,m=11,l=16,j=23;let U=6,T=10,R=15,O=21;s=J(s);C=e(s);Y=1732584193;X=4023233417;W=2562383102;V=271733878;for(P=0;Pchar.charCodeAt(0)).reduce((a,b)=>a+b,0).toString();let themes=[{color:'27005e',background:'e1d2f6'},{color:'5e2700',background:'f3d9c6'},{color:'006128',background:'c9f3c6'},{color:'580061',background:'f2d1f5'},{color:'00365d',background:'c6e1f3'},{color:'00075c',background:'d2d5f6'},{color:'610038',background:'f5d1e6'},{color:'386100',background:'dcf1bd'},{color:'615800',background:'f1ecba'},{color:'610008',background:'f6d2d5'},];name=name.split(' ').map(function(n){if(!isNaN(parseFloat(n))&&isFinite(n)){return'';} return n[0];}).join('')||'--';let background=themes[theme[theme.length-1]]['background'];let color=themes[theme[theme.length-1]]['color'];let def='https://ui-avatars.com/api/'+encodeURIComponent(name)+'/'+size+'/'+encodeURIComponent(background)+'/'+encodeURIComponent(color);return'//www.gravatar.com/avatar/'+MD5(email)+'.jpg?s='+size+'&d='+encodeURIComponent(def);}).add('date',function($value,date){return date.format('Y-m-d',$value);}).add('date-time',function($value,date){return date.format('Y-m-d H:i',$value);}).add('date-text',function($value,date){return date.format('d M Y',$value);}).add('ms2hum',function($value){let temp=$value;const years=Math.floor(temp/31536000),days=Math.floor((temp%=31536000)/86400),hours=Math.floor((temp%=86400)/3600),minutes=Math.floor((temp%=3600)/60),seconds=temp%60;if(days||hours||seconds||minutes){return(years?years+"y ":"")+ (days?days+"d ":"")+ (hours?hours+"h ":"")+ (minutes?minutes+"m ":"")+ Number.parseFloat(seconds).toFixed(0)+"s";} return"< 1s";}).add('markdown',function($value,markdown){return markdown.render($value);}).add('pageCurrent',function($value,env){return Math.ceil(parseInt($value||0)/env.PAGING_LIMIT)+1;}).add('pageTotal',function($value,env){let total=Math.ceil(parseInt($value||0)/env.PAGING_LIMIT);return(total)?total:1;}).add('humanFileSize',function($value){if(!$value){return 0;} let thresh=1000;if(Math.abs($value)=thresh&&u'+units[u]+'';}).add('statsTotal',function($value){if(!$value){return 0;} $value=abbreviate($value,1,false,false);return($value==='0')?'N/A':$value;});function abbreviate(number,maxPlaces,forcePlaces,forceLetter){number=Number(number);forceLetter=forceLetter||false;if(forceLetter!==false){return annotate(number,maxPlaces,forcePlaces,forceLetter);} let abbr;if(number>=1e12){abbr='T';} else if(number>=1e9){abbr='B';} else if(number>=1e6){abbr='M';} else if(number>=1e3){abbr='K';} else{abbr='';} return annotate(number,maxPlaces,forcePlaces,abbr);} function annotate(number,maxPlaces,forcePlaces,abbr){let rounded=0;switch(abbr){case'T':rounded=number/1e12;break;case'B':rounded=number/1e9;break;case'M':rounded=number/1e6;break;case'K':rounded=number/1e3;break;case'':rounded=number;break} if(maxPlaces!==false){let test=new RegExp('\\.\\d{'+(maxPlaces+1)+',}$') if(test.test((''+rounded))){rounded=rounded.toFixed(maxPlaces)}} if(forcePlaces!==false){rounded=Number(rounded).toFixed(forcePlaces)} return rounded+abbr} window.ls.container.get('view').add({selector:'data-acl',controller:function(element,document,router,alerts){document.body.classList.remove('console');document.body.classList.remove('home');document.body.classList.add(router.getCurrent().view.scope);if(!router.getCurrent().view.project){document.body.classList.add('hide-nav');document.body.classList.remove('show-nav');} else{document.body.classList.add('show-nav');document.body.classList.remove('hide-nav');} if('/console'===router.getCurrent().path){document.body.classList.add('index');} else{document.body.classList.remove('index');}}}).add({selector:'data-cookie-policy',repeat:false,controller:function(element,alerts,cookie){if(!cookie.get('cookie-alert')){let text=element.dataset['cookiePolicy']||'';alerts.add({text:text,class:'cookie-alert',link:'/policy/cookies',callback:function(){cookie.set('cookie-alert','true',365*10);}},0);}}}).add({selector:'data-ls-ui-alerts',controller:function(element,window,view){window.document.addEventListener('alerted',function(){view.render(element);},true);}}).add({selector:'data-ls-ui-alerts-delete',controller:function(document,element,alerts,expression){let message=expression.parse(element.dataset['message']);let remove=function(){alerts.remove(message);};element.addEventListener('click',remove);}}).add({selector:'data-forms-headers',repeat:false,controller:function(element){let key=document.createElement('input');let value=document.createElement('input');let wrap=document.createElement('div');let cell1=document.createElement('div');let cell2=document.createElement('div');key.type='text';key.className='margin-bottom-no';key.placeholder='Key';value.type='text';value.className='margin-bottom-no';value.placeholder='Value';wrap.className='row thin margin-bottom-small';cell1.className='col span-6';cell2.className='col span-6';element.parentNode.insertBefore(wrap,element);cell1.appendChild(key);cell2.appendChild(value);wrap.appendChild(cell1);wrap.appendChild(cell2);key.addEventListener('input',function(){syncA();});value.addEventListener('input',function(){syncA();});element.addEventListener('change',function(){syncB();});let syncA=function(){element.value=key.value.toLowerCase()+':'+value.value.toLowerCase();};let syncB=function(){let split=element.value.toLowerCase().split(':');key.value=split[0]||'';value.value=split[1]||'';key.value=key.value.trim();value.value=value.value.trim();};syncB();}}).add({selector:'data-prism',repeat:false,controller:function(window,document,element,alerts){Prism.highlightElement(element);let copy=document.createElement('i');copy.className='icon-docs copy';copy.title='Copy to Clipboard';copy.addEventListener('click',function(){window.getSelection().removeAllRanges();let range=document.createRange();range.selectNode(element);window.getSelection().addRange(range);try{document.execCommand('copy');alerts.add({text:'Copied to clipboard',class:''},3000);}catch(err){alerts.add({text:"Failed to copy text ",class:'error'},3000);} window.getSelection().removeAllRanges();});element.parentNode.parentNode.appendChild(copy);}}).add({selector:'data-code-example',repeat:false,controller:function(window,document,element,cookie){let prefix=element.dataset['codeExample']||'unknown';element.addEventListener('change',function(){select(element.value);});let select=function(value){for(let i=0;ielement.trim()):[];failure=(failure&&failure!='')?failure.split(',').map(element=>element.trim()):[];if(debug)console.log('%c[service init]: '+action+' ('+service+')','color:red');let callbacks={'reset':function(){return function(){if('FORM'===element.tagName){return element.reset();} throw new Error('This callback is only valid for forms');}},'alert':function(text,classname){return function(alerts){alerts.add({text:text,class:(classname||'success')},3000);}},'redirect':function(url){return function(router){router.change(url||'/');}},'reload':function(){return function(router){router.reload();}},'state':function(keys){let updateQueryString=function(key,value,url){var re=new RegExp("([?&])"+key+"=.*?(&|#|$)(.*)","gi"),hash;if(re.test(url)){if(typeof value!=='undefined'&&value!==null){return url.replace(re,'$1'+key+"="+value+'$2$3');} else{hash=url.split('#');url=hash[0].replace(re,'$1$3').replace(/(&|\?)$/,'');if(typeof hash[1]!=='undefined'&&hash[1]!==null){url+='#'+hash[1];} return url;}} else{if(typeof value!=='undefined'&&value!==null){var separator=url.indexOf('?')!==-1?'&':'?';hash=url.split('#');url=hash[0]+separator+key+'='+value;if(typeof hash[1]!=='undefined'&&hash[1]!==null){url+='#'+hash[1];} return url;} else{return url;}}} keys=keys.split(',').map(element=>element.trim());return function(serviceForm,router,window){let url=window.location.href;keys.map(node=>{node=node.split('=');let key=node[0]||'';let name=node[1]||key;let value=getValue(key,'param',serviceForm);url=updateQueryString(name,(value?value:null),url)});if(url!==window.location.href){console.log('UPDATE STATE');window.history.pushState({},'',url);router.reset();}}},'trigger':function(events){return function(document){events=events.trim().split(',');for(let i=0;i)|{)/m;const REGEX_PARAMETERS_VALUES=/\s*([\w\\$]+)\s*(?:=\s*((?:(?:(['"])(?:\3|(?:.*?[^\\]\3)))((\s*\+\s*)(?:(?:(['"])(?:\6|(?:.*?[^\\]\6)))|(?:[\w$]*)))*)|.*?))?\s*(?:,|$)/gm;let functionAsString=func.toString();let params=[];let match;functionAsString=functionAsString.replace(REGEX_COMMENTS,'');functionAsString=functionAsString.match(REGEX_FUNCTION_PARAMS)[1];if(functionAsString.charAt(0)==='('){functionAsString=functionAsString.slice(1,-1);} while(match=REGEX_PARAMETERS_VALUES.exec(functionAsString)){params.push(match[1]);} return params;} let getValue=function(key,prefix,data){let result=null;if(!key){return null;} if(element.dataset[prefix+key.charAt(0).toUpperCase()+key.slice(1)]){result=expression.parse(element.dataset[prefix+key.charAt(0).toUpperCase()+key.slice(1)]);} if(data[key]){result=data[key];} if(!result){result='';} if(debug)console.log('%c[param resolved]: ('+service+') '+key+'='+result,'color:#808080');return result;} let resolve=function(target,prefix='param',data={}){if(!target){return function(){};} let args=getParams(target);if(debug)console.log('%c[form data]: ','color:green',data);return target.apply(target,args.map(function(value){return getValue(value,prefix,data);}));};let exec=function(event){element.$lsSkip=true;element.classList.add('load-service-start');if(debug)console.log('%c[executed]: '+scope+'.'+action,'color:yellow',event,element,document.body.contains(element));if(!document.body.contains(element)){element=undefined;return false;} if(event){event.preventDefault();} if(confirm){if(window.confirm(confirm)!==true){return false;}} if(loading){loaderId=alerts.add({text:loading,class:''},0);} let method=container.path(scope+'.'+action);if(!method){throw new Error('Method "'+scope+'.'+action+'" not found');} let formData=('FORM'===element.tagName)?form.toJson(element):{};let result=resolve(method,'param',formData);if(!result){return;} result.then(function(data){if(loaderId!==null){alerts.remove(loaderId);} if(!element){return;} element.classList.add('load-service-end');container.set(service.replace('.','-'),data,true,true);container.set('serviceData',data,true,true);container.set('serviceForm',formData,true,true);if(debug)console.log('%cservice ready: "'+service.replace('.','-')+'"','color:green');if(debug)console.log('%cservice:','color:blue',container.get(service.replace('.','-')));for(let i=0;i=","<=","=",">","<"];let operator=null;for(let key=0;key-1){operator=operatorsMap[key];}} if(operator===null){throw new Error("Invalid operator");} filter=filter.split(operator);if(filter.length!==2){throw new Error("Invalid filter expression");} return{"key":filter[0],"value":filter[1],"operator":operator};};let flatten=function(params){let list={};for(let key in params){if(params.hasOwnProperty(key)){if(key!=='filters'){list[key]=params[key];} else{for(let i=0;i60) return meter.className='password-meter strong';if(score>30) return meter.className='password-meter medium';if(score>=0) return meter.className='password-meter weak';};var meter=window.document.createElement('div');meter.className='password-meter';element.parentNode.insertBefore(meter,element.nextSibling);element.addEventListener('change',callback);element.addEventListener('keypress',callback);element.addEventListener('keyup',callback);element.addEventListener('keydown',callback);}});})(window);(function(window){"use strict";window.ls.container.get('view').add({selector:'data-forms-pell',repeat:false,controller:function(element,window,document,markdown){var div=document.createElement('div');element.className='pell hide';div.className='input pell';element.parentNode.insertBefore(div,element);element.tabIndex=-1;var turndownService=new TurndownService();turndownService.addRule('underline',{filter:['u'],replacement:function(content){return'__'+content+'__'}});var editor=window.pell.init({element:div,onChange:function onChange(html){element.value=turndownService.turndown(html);},defaultParagraphSeparator:'p',actions:[{name:'bold',icon:''},{name:'underline',icon:''},{name:'italic',icon:''},{name:'olist',icon:''},{name:'ulist',icon:''}]});element.addEventListener('change',function(){editor.content.innerHTML=markdown.render(element.value);});editor.content.setAttribute('placeholder',element.placeholder);editor.content.innerHTML=markdown.render(element.value);editor.content.tabIndex=0;editor.content.onkeydown=function preventTab(event){if(event.which===9){event.preventDefault();if(document.activeElement){var focussable=Array.prototype.filter.call(document.querySelectorAll('a:not([disabled]), button:not([disabled]), select:not([disabled]), input[type=text]:not([disabled]), input[type=checkbox]:not([disabled]), [tabindex]:not([disabled]):not([tabindex="-1"])'),function(element){return element.offsetWidth>0||element.offsetHeight>0||element===document.activeElement});var index=focussable.indexOf(document.activeElement);if(index>-1){if(event.shiftKey){var prevElement=focussable[index-1]||focussable[focussable.length-1];prevElement.focus();} else{var nextElement=focussable[index+1]||focussable[0];nextElement.focus();}}}}};var clean=function(e){e.stopPropagation();e.preventDefault();var clipboardData=e.clipboardData||window.clipboardData;window.pell.exec('insertText',clipboardData.getData('Text'));return true;};div.addEventListener('paste',clean);div.addEventListener('drop',clean);}});})(window);(function(window){"use strict";window.ls.container.get('view').add({selector:'data-forms-remove',repeat:false,controller:function(element){Array.prototype.slice.call(element.querySelectorAll('[data-remove]')).map(function(obj){obj.addEventListener('click',function(){element.parentNode.removeChild(element);});});}});})(window);(function(window){"use strict";window.ls.container.get('view').add({selector:'data-forms-switch',repeat:false,controller:function(element){let input=window.document.createElement('input');input.type='checkbox';input.className='switch';let syncA=function(){element.value=(input.checked)?'on':'off';};let syncB=function(){input.checked=(element.value==='on');};input.addEventListener('input',syncA);input.addEventListener('change',syncA);element.addEventListener('input',syncB);element.addEventListener('change',syncB);syncA();element.parentNode.insertBefore(input,element);}});})(window);(function(window){"use strict";window.ls.container.get('view').add({selector:'data-forms-text-count',repeat:false,controller:function(element){var counter=document.createElement('span');counter.className='counter';element.parentNode.insertBefore(counter,element.nextSibling);var count=function(){if(0<=element.maxLength){counter.innerText=(element.maxLength-element.value.length).toString()+' / '+element.maxLength;} else{var words=(element.value!=='')?element.value.trim().split(' ').length:0;counter.innerText=words+' words and '+element.value.length.toString()+' chars';}};element.addEventListener('keyup',count);element.addEventListener('change',count);element.addEventListener('cut',count);element.addEventListener('paste',count);element.addEventListener('drop',count);count();}});})(window);(function(window){"use strict";window.ls.container.get('view').add({selector:'data-forms-text-direction',repeat:false,controller:function(element){var rtlStock='^ا^ب^ت^ث^ج^ح^خ^د^ذ^ر^ز^س^ش^ص^ض^ط^ظ^ع^غ^ف^ق^ك^ل^م^ن^ه^و^ي^א^ב^ג^ד^ה^ו^ז^ח^ט^י^כ^ך^ל^מ^ם^נ^ן^ס^ע^פ^ף^צ^ץ^ק^ר^ש^ת^';var special=['\n',' ','״','"','_','\'','!','@','#','$','^','&','%','*','(',')','+','=','-','[',']','\\','/','{','}','|',':','<','>','?',',','.','0','1','2','3','4','5','6','7','8','9'];var setDirection=function(){var value=(element.value[0])?element.value:'';var direction='ltr';var align='left';for(var i=0;i=thresh&&u=max)){input.disabled=true;upload.classList.add('disabled');} else{input.disabled=false;upload.classList.remove('disabled');} var remove=(function(obj){return function(event){output=(Array.isArray(output))?output.filter(function(e){return e!==obj}):[];render(output);}})(obj);file.addEventListener('click',remove);file.addEventListener('keypress',remove);element.value=(multiple)?JSON.stringify(output):output[0];});};input.addEventListener('change',function(){var message=alerts.add({text:labelLoading,class:''},0);var files=input.files;var read=JSON.parse(expression.parse(element.dataset['read']||'[]'));var write=JSON.parse(expression.parse(element.dataset['write']||'[]'));if(!multiple){output=[];} sdk.storage.createFile(files[0],read,write,1).then(function(response){response.map(function(obj){if(!Array.isArray(output)){throw new Error('Can\'t append new file to non array value');} output[output.length]=obj['$uid'];});onComplete(message);render(output);},function(error){alerts.add({text:'An error occurred!',class:''},3000);onComplete(message);});input.disabled=true;});element.addEventListener('change',function(){if(!element.value){return;} output=(multiple)?JSON.parse(element.value):[element.value];render(output);});upload.addEventListener('keypress',function(){input.click();});element.parentNode.insertBefore(wrapper,element);wrapper.appendChild(preview);wrapper.appendChild(progress);wrapper.appendChild(upload);if(multiple){wrapper.appendChild(count);} upload.appendChild(input);render(output);}});})(window);(function(window){"use strict";window.ls.view.add({selector:'data-general-oauth',repeat:false,controller:function(element,env,expression){let provider=expression.parse(element.dataset['authOauth']||'');let success=expression.parse(element.dataset['success']||'');let failure=expression.parse(element.dataset['failure']||'');element.href=env.API+'/oauth/'+provider+'?project='+env.PROJECT +'&success='+encodeURIComponent(success) +'&failure='+encodeURIComponent(failure);}});})(window);(function(window){window.ls.container.get('view').add({'selector':'data-page-title','repeat':true,'controller':function(element,document,expression){document.title=expression.parse(element.getAttribute('data-page-title'))||document.title;}});})(window);(function(window){window.ls.container.get('view').add({selector:'data-setup',controller:function(element,console,form){element.addEventListener('submit',function(event){event.preventDefault();let formData=form.toJson(element);formData['name']=formData['name']||(element.dataset['defaultName']||'');console.teams.createTeam(formData['name']||'').then(function(data){let team=data['$uid'];formData=JSON.parse(JSON.stringify(formData).replace(new RegExp('{{teamId}}','g'),team));console.projects.createProject(formData['name'],team).then(function(project){window.location.href='/console?project='+project['$uid'];},function(){throw new Error('Failed to setup project');});},function(){throw new Error('Setup failed creating project team');});})}});})(window);(function(window){window.ls.container.get('view').add({selector:'data-switch',controller:function(element,router,document){let debug=(element.dataset['debug']);let project=router.params.project||null;if(project){if(debug){console.log('project-load-start-init');} document.dispatchEvent(new CustomEvent('project-load'));} document.addEventListener('state-changed',function(){if(router.params.project&&project!==router.params.project){if(debug){console.log('project-load-init');} document.dispatchEvent(new CustomEvent('project-load'));project=router.params.project;}});element.addEventListener('change',function(){if(debug){console.log('change init',element.value);} if(element.value&&element.value!==project){if(debug){console.log('Changed: selected project from list');} return router.change('/console/home?project='+element.value);}});}});})(window);(function(window){window.ls.container.get('view').add({selector:'data-paging-back',controller:function(element,container,expression,env){let paths=[];let limit=env.PAGING_LIMIT;let check=function(){let offset=parseInt(expression.parse(element.dataset['offset'])||'0');paths=paths.concat(expression.getPaths());if((offset-limit)<0){element.disabled=true;} else{element.disabled=false;element.value=offset-limit;}};check();for(let i=0;i=sum){element.disabled=true;} else{element.disabled=false;element.value=offset+limit;}};check();for(let i=0;i{button.innerText=buttonText;button.className=buttonClass;button.type='button';if(buttonIcon){let iconElement=document.createElement('i');iconElement.className=buttonIcon;button.insertBefore(iconElement,button.firstChild);}});} if(buttonEvent){buttonElements.forEach((button)=>{button.addEventListener('click',function(){document.dispatchEvent(new CustomEvent(buttonEvent,{bubbles:false,cancelable:true}));});});} element.classList.add('modal');if(!buttonAlias){buttonElements.forEach((button)=>{element.parentNode.insertBefore(button,element);});} let open=function(){document.documentElement.classList.add('modal-open');document.dispatchEvent(new CustomEvent('modal-open',{bubbles:false,cancelable:true}));element.classList.add('open');element.classList.remove('close');};let close=function(){document.documentElement.classList.remove('modal-open');element.classList.add('close');element.classList.remove('open');};if(name){document.querySelectorAll("[data-ui-modal-ref='"+name+"']").forEach(function(elem){elem.addEventListener('click',open);});} if(openEvent){document.addEventListener(openEvent,open);} buttonElements.forEach((button)=>{button.addEventListener('click',open);});document.addEventListener('keydown',function(event){if(event.which===27){close();}});element.addEventListener('blur',close);let closeButtons=element.querySelectorAll('[data-ui-modal-close]');for(let i=0;i0)?current+' / '+total:'';}});})(window);(function(window){window.ls.container.get('view').add({selector:'data-ui-phases',controller:function(element,window,document,expression,router){var tabs=document.createElement('ul');var container=document.createElement('div');var titles=Array.prototype.slice.call(element.getElementsByTagName('h2'));var next=Array.prototype.slice.call(element.querySelectorAll('[data-next]'));var previous=Array.prototype.slice.call(element.querySelectorAll('[data-previous]'));var position=0;var init=false;for(var i=0;i