1&&r&&r.length>1){var a=Bi(r)/Bi(o);!isFinite(a)&&(a=1),e.pinchScale=a;var s=[((i=r)[0][0]+i[1][0])/2,(i[0][1]+i[1][1])/2];return e.pinchX=s[0],e.pinchY=s[1],{type:"pinch",target:t[0].target,event:e}}}}};function Wi(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t}function Ui(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t}function Gi(t,e,n){var i=e[0]*n[0]+e[2]*n[1],r=e[1]*n[0]+e[3]*n[1],o=e[0]*n[2]+e[2]*n[3],a=e[1]*n[2]+e[3]*n[3],s=e[0]*n[4]+e[2]*n[5]+e[4],l=e[1]*n[4]+e[3]*n[5]+e[5];return t[0]=i,t[1]=r,t[2]=o,t[3]=a,t[4]=s,t[5]=l,t}function qi(t,e,n){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4]+n[0],t[5]=e[5]+n[1],t}function ji(t,e,n,i){void 0===i&&(i=[0,0]);var r=e[0],o=e[2],a=e[4],s=e[1],l=e[3],c=e[5],d=Math.sin(n),u=Math.cos(n);return t[0]=r*u+s*d,t[1]=-r*d+s*u,t[2]=o*u+l*d,t[3]=-o*d+u*l,t[4]=u*(a-i[0])+d*(c-i[1])+i[0],t[5]=u*(c-i[1])-d*(a-i[0])+i[1],t}function Xi(t,e){var n=e[0],i=e[2],r=e[4],o=e[1],a=e[3],s=e[5],l=n*a-o*i;return l?(l=1/l,t[0]=a*l,t[1]=-o*l,t[2]=-i*l,t[3]=n*l,t[4]=(i*s-a*r)*l,t[5]=(o*r-n*s)*l,t):null}var Yi=function(){function t(t,e){this.x=t||0,this.y=e||0}return t.prototype.copy=function(t){return this.x=t.x,this.y=t.y,this},t.prototype.clone=function(){return new t(this.x,this.y)},t.prototype.set=function(t,e){return this.x=t,this.y=e,this},t.prototype.equal=function(t){return t.x===this.x&&t.y===this.y},t.prototype.add=function(t){return this.x+=t.x,this.y+=t.y,this},t.prototype.scale=function(t){this.x*=t,this.y*=t},t.prototype.scaleAndAdd=function(t,e){this.x+=t.x*e,this.y+=t.y*e},t.prototype.sub=function(t){return this.x-=t.x,this.y-=t.y,this},t.prototype.dot=function(t){return this.x*t.x+this.y*t.y},t.prototype.len=function(){return Math.sqrt(this.x*this.x+this.y*this.y)},t.prototype.lenSquare=function(){return this.x*this.x+this.y*this.y},t.prototype.normalize=function(){var t=this.len();return this.x/=t,this.y/=t,this},t.prototype.distance=function(t){var e=this.x-t.x,n=this.y-t.y;return Math.sqrt(e*e+n*n)},t.prototype.distanceSquare=function(t){var e=this.x-t.x,n=this.y-t.y;return e*e+n*n},t.prototype.negate=function(){return this.x=-this.x,this.y=-this.y,this},t.prototype.transform=function(t){if(t){var e=this.x,n=this.y;return this.x=t[0]*e+t[2]*n+t[4],this.y=t[1]*e+t[3]*n+t[5],this}},t.prototype.toArray=function(t){return t[0]=this.x,t[1]=this.y,t},t.prototype.fromArray=function(t){this.x=t[0],this.y=t[1]},t.set=function(t,e,n){t.x=e,t.y=n},t.copy=function(t,e){t.x=e.x,t.y=e.y},t.len=function(t){return Math.sqrt(t.x*t.x+t.y*t.y)},t.lenSquare=function(t){return t.x*t.x+t.y*t.y},t.dot=function(t,e){return t.x*e.x+t.y*e.y},t.add=function(t,e,n){t.x=e.x+n.x,t.y=e.y+n.y},t.sub=function(t,e,n){t.x=e.x-n.x,t.y=e.y-n.y},t.scale=function(t,e,n){t.x=e.x*n,t.y=e.y*n},t.scaleAndAdd=function(t,e,n,i){t.x=e.x+n.x*i,t.y=e.y+n.y*i},t.lerp=function(t,e,n,i){var r=1-i;t.x=r*e.x+i*n.x,t.y=r*e.y+i*n.y},t}(),Zi=Math.min,Ki=Math.max,Qi=Math.abs,Ji=["x","y"],tr=["width","height"],er=new Yi,nr=new Yi,ir=new Yi,rr=new Yi,or=pr(),ar=or.minTv,sr=or.maxTv,lr=[0,0],cr=function(){function t(e,n,i,r){t.set(this,e,n,i,r)}return t.set=function(t,e,n,i,r){return i<0&&(e+=i,i=-i),r<0&&(n+=r,r=-r),t.x=e,t.y=n,t.width=i,t.height=r,t},t.prototype.union=function(t){var e=Zi(t.x,this.x),n=Zi(t.y,this.y);isFinite(this.x)&&isFinite(this.width)?this.width=Ki(t.x+t.width,this.x+this.width)-e:this.width=t.width,isFinite(this.y)&&isFinite(this.height)?this.height=Ki(t.y+t.height,this.y+this.height)-n:this.height=t.height,this.x=e,this.y=n},t.prototype.applyTransform=function(e){t.applyTransform(this,this,e)},t.prototype.calculateTransform=function(t){var e=this,n=t.width/e.width,i=t.height/e.height,r=[1,0,0,1,0,0];return qi(r,r,[-e.x,-e.y]),function(t,e,n){var i=n[0],r=n[1];t[0]=e[0]*i,t[1]=e[1]*r,t[2]=e[2]*i,t[3]=e[3]*r,t[4]=e[4]*i,t[5]=e[5]*r}(r,r,[n,i]),qi(r,r,[t.x,t.y]),r},t.prototype.intersect=function(e,n,i){return t.intersect(this,e,n,i)},t.intersect=function(e,n,i,r){i&&Yi.set(i,0,0);var o=r&&r.outIntersectRect||null,a=r&&r.clamp;if(o&&(o.x=o.y=o.width=o.height=NaN),!e||!n)return!1;e instanceof t||(e=t.set(dr,e.x,e.y,e.width,e.height)),n instanceof t||(n=t.set(ur,n.x,n.y,n.width,n.height));var s=!!i;or.reset(r,s);var l=or.touchThreshold,c=e.x+l,d=e.x+e.width-l,u=e.y+l,h=e.y+e.height-l,p=n.x+l,f=n.x+n.width-l,g=n.y+l,v=n.y+n.height-l;if(c>d||u>h||p>f||g>v)return!1;var m=!(d=t.x&&e<=t.x+t.width&&n>=t.y&&n<=t.y+t.height},t.prototype.contain=function(e,n){return t.contain(this,e,n)},t.prototype.clone=function(){return new t(this.x,this.y,this.width,this.height)},t.prototype.copy=function(e){t.copy(this,e)},t.prototype.plain=function(){return{x:this.x,y:this.y,width:this.width,height:this.height}},t.prototype.isFinite=function(){return isFinite(this.x)&&isFinite(this.y)&&isFinite(this.width)&&isFinite(this.height)},t.prototype.isZero=function(){return 0===this.width||0===this.height},t.create=function(e){return new t(e.x,e.y,e.width,e.height)},t.copy=function(t,e){return t.x=e.x,t.y=e.y,t.width=e.width,t.height=e.height,t},t.applyTransform=function(e,n,i){if(i){if(i[1]<1e-5&&i[1]>-1e-5&&i[2]<1e-5&&i[2]>-1e-5){var r=i[0],o=i[3],a=i[4],s=i[5];return e.x=n.x*r+a,e.y=n.y*o+s,e.width=n.width*r,e.height=n.height*o,e.width<0&&(e.x+=e.width,e.width=-e.width),void(e.height<0&&(e.y+=e.height,e.height=-e.height))}er.x=ir.x=n.x,er.y=rr.y=n.y,nr.x=rr.x=n.x+n.width,nr.y=ir.y=n.y+n.height,er.transform(i),rr.transform(i),nr.transform(i),ir.transform(i),e.x=Zi(er.x,nr.x,ir.x,rr.x),e.y=Zi(er.y,nr.y,ir.y,rr.y);var l=Ki(er.x,nr.x,ir.x,rr.x),c=Ki(er.y,nr.y,ir.y,rr.y);e.width=l-e.x,e.height=c-e.y}else e!==n&&t.copy(e,n)},t}(),dr=new cr(0,0,0,0),ur=new cr(0,0,0,0);function hr(t,e,n,i,r,o,a,s){var l=Qi(e-n),c=Qi(i-t),d=Zi(l,c),u=Ji[r],h=Ji[1-r],p=tr[r];e=c||!or.bidirectional)&&(ar[u]=-c,ar[h]=0,or.useDir&&or.calcDirMTV())))}function pr(){var t=0,e=new Yi,n=new Yi,i={minTv:new Yi,maxTv:new Yi,useDir:!1,dirMinTv:new Yi,touchThreshold:0,bidirectional:!0,negativeSize:!1,reset:function(r,o){i.touchThreshold=0,r&&null!=r.touchThreshold&&(i.touchThreshold=Ki(0,r.touchThreshold)),i.negativeSize=!1,o&&(i.minTv.set(1/0,1/0),i.maxTv.set(0,0),i.useDir=!1,r&&null!=r.direction&&(i.useDir=!0,i.dirMinTv.copy(i.minTv),n.copy(i.minTv),t=r.direction,i.bidirectional=null==r.bidirectional||!!r.bidirectional,i.bidirectional||e.set(Math.cos(t),Math.sin(t))))},calcDirMTV:function(){var o=i.minTv,a=i.dirMinTv,s=o.y*o.y+o.x*o.x,l=Math.sin(t),c=Math.cos(t),d=l*o.y+c*o.x;r(d)?r(o.x)&&r(o.y)&&a.set(0,0):(n.x=s*c/d,n.y=s*l/d,r(n.x)&&r(n.y)?a.set(0,0):(i.bidirectional||e.dot(n)>0)&&n.len()=0;c--){var d=i[c];d===n||d.ignore||d.ignoreCoarsePointer||d.parent&&d.parent.ignoreCoarsePointer||(_r.copy(d.getBoundingRect()),d.transform&&_r.applyTransform(d.transform),_r.intersect(l)&&o.push(d))}if(o.length)for(var u=Math.PI/12,h=2*Math.PI,p=0;p=0;o--){var a=t[o],s=void 0;if(a!==r&&!a.ignore&&(s=xr(a,n,i))&&(!e.topTarget&&(e.topTarget=a),s!==fr)){e.target=a;break}}}function Sr(t,e,n){var i=t.painter;return e<0||e>i.getWidth()||n<0||n>i.getHeight()}Cn(["click","mousedown","mouseup","mousewheel","dblclick","contextmenu"],function(t){br.prototype[t]=function(e){var n,i,r=e.zrX,o=e.zrY,a=Sr(this,r,o);if("mouseup"===t&&a||(i=(n=this.findHover(r,o)).target),"mousedown"===t)this._downEl=i,this._downPoint=[e.zrX,e.zrY],this._upEl=i;else if("mouseup"===t)this._upEl=i;else if("click"===t){if(this._downEl!==this._upEl||!this._downPoint||pi(this._downPoint,[e.zrX,e.zrY])>4)return;this._downPoint=null}this.dispatchToElement(n,t,e)}});function Cr(t,e,n,i){var r=e+1;if(r===n)return 1;if(i(t[r++],t[e])<0){for(;r=0;)r++;return r-e}function kr(t,e,n,i,r){for(i===e&&i++;i>>1])<0?l=o:s=o+1;var c=i-s;switch(c){case 3:t[s+3]=t[s+2];case 2:t[s+2]=t[s+1];case 1:t[s+1]=t[s];break;default:for(;c>0;)t[s+c]=t[s+c-1],c--}t[s]=a}}function Mr(t,e,n,i,r,o){var a=0,s=0,l=1;if(o(t,e[n+r])>0){for(s=i-r;l0;)a=l,(l=1+(l<<1))<=0&&(l=s);l>s&&(l=s),a+=r,l+=r}else{for(s=r+1;ls&&(l=s);var c=a;a=r-l,l=r-c}for(a++;a>>1);o(t,e[n+d])>0?a=d+1:l=d}return l}function Tr(t,e,n,i,r,o){var a=0,s=0,l=1;if(o(t,e[n+r])<0){for(s=r+1;ls&&(l=s);var c=a;a=r-l,l=r-c}else{for(s=i-r;l=0;)a=l,(l=1+(l<<1))<=0&&(l=s);l>s&&(l=s),a+=r,l+=r}for(a++;a>>1);o(t,e[n+d])<0?l=d:a=d+1}return l}function Ir(t,e){var n,i,r=7,o=0,a=[];function s(s){var l=n[s],c=i[s],d=n[s+1],u=i[s+1];i[s]=c+u,s===o-3&&(n[s+1]=n[s+2],i[s+1]=i[s+2]),o--;var h=Tr(t[d],t,l,c,0,e);l+=h,0!==(c-=h)&&0!==(u=Mr(t[l+c-1],t,d,u,u-1,e))&&(c<=u?function(n,i,o,s){var l=0;for(l=0;l=7||p>=7);if(f)break;g<0&&(g=0),g+=2}if((r=g)<1&&(r=1),1===i){for(l=0;l=0;l--)t[p+l]=t[h+l];return void(t[u]=a[d])}var f=r;for(;;){var g=0,v=0,m=!1;do{if(e(a[d],t[c])<0){if(t[u--]=t[c--],g++,v=0,0===--i){m=!0;break}}else if(t[u--]=a[d--],v++,g=0,1===--s){m=!0;break}}while((g|v)=0;l--)t[p+l]=t[h+l];if(0===i){m=!0;break}}if(t[u--]=a[d--],1===--s){m=!0;break}if(0!==(v=s-Mr(t[c],a,0,s,s-1,e))){for(s-=v,p=(u-=v)+1,h=(d-=v)+1,l=0;l=7||v>=7);if(m)break;f<0&&(f=0),f+=2}(r=f)<1&&(r=1);if(1===s){for(p=(u-=i)+1,h=(c-=i)+1,l=i-1;l>=0;l--)t[p+l]=t[h+l];t[u]=a[d]}else{if(0===s)throw new Error;for(h=u-(s-1),l=0;l1;){var t=o-2;if(t>=1&&i[t-1]<=i[t]+i[t+1]||t>=2&&i[t-2]<=i[t]+i[t-1])i[t-1]i[t+1])break;s(t)}},forceMergeRuns:function(){for(;o>1;){var t=o-2;t>0&&i[t-1]=32;)e|=1&t,t>>=1;return t+e}(r);do{if((o=Cr(t,n,i,e))s&&(l=s),kr(t,n,n+l,n+o,e),o=l}a.pushRun(n,o),a.mergeRuns(),r-=o,n+=o}while(0!==r);a.forceMergeRuns()}}}var Ar=!1;function Pr(){Ar||(Ar=!0,console.warn("z / z2 / zlevel of displayable is invalid, which may cause unexpected errors"))}function Lr(t,e){return t.zlevel===e.zlevel?t.z===e.z?t.z2-e.z2:t.z-e.z:t.zlevel-e.zlevel}var Er,zr=function(){function t(){this._roots=[],this._displayList=[],this._displayListLen=0,this.displayableSortFunc=Lr}return t.prototype.traverse=function(t,e){for(var n=0;n=0&&this._roots.splice(i,1)}},t.prototype.delAllRoots=function(){this._roots=[],this._displayList=[],this._displayListLen=0},t.prototype.getRoots=function(){return this._roots},t.prototype.dispose=function(){this._displayList=null,this._roots=null},t}();Er=Ye.hasGlobalWindow&&(window.requestAnimationFrame&&window.requestAnimationFrame.bind(window)||window.msRequestAnimationFrame&&window.msRequestAnimationFrame.bind(window)||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame)||function(t){return setTimeout(t,16)};var Nr={linear:function(t){return t},quadraticIn:function(t){return t*t},quadraticOut:function(t){return t*(2-t)},quadraticInOut:function(t){return(t*=2)<1?.5*t*t:-.5*(--t*(t-2)-1)},cubicIn:function(t){return t*t*t},cubicOut:function(t){return--t*t*t+1},cubicInOut:function(t){return(t*=2)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},quarticIn:function(t){return t*t*t*t},quarticOut:function(t){return 1- --t*t*t*t},quarticInOut:function(t){return(t*=2)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},quinticIn:function(t){return t*t*t*t*t},quinticOut:function(t){return--t*t*t*t*t+1},quinticInOut:function(t){return(t*=2)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},sinusoidalIn:function(t){return 1-Math.cos(t*Math.PI/2)},sinusoidalOut:function(t){return Math.sin(t*Math.PI/2)},sinusoidalInOut:function(t){return.5*(1-Math.cos(Math.PI*t))},exponentialIn:function(t){return 0===t?0:Math.pow(1024,t-1)},exponentialOut:function(t){return 1===t?1:1-Math.pow(2,-10*t)},exponentialInOut:function(t){return 0===t?0:1===t?1:(t*=2)<1?.5*Math.pow(1024,t-1):.5*(2-Math.pow(2,-10*(t-1)))},circularIn:function(t){return 1-Math.sqrt(1-t*t)},circularOut:function(t){return Math.sqrt(1- --t*t)},circularInOut:function(t){return(t*=2)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},elasticIn:function(t){var e,n=.1;return 0===t?0:1===t?1:(!n||n<1?(n=1,e=.1):e=.4*Math.asin(1/n)/(2*Math.PI),-n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4))},elasticOut:function(t){var e,n=.1;return 0===t?0:1===t?1:(!n||n<1?(n=1,e=.1):e=.4*Math.asin(1/n)/(2*Math.PI),n*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/.4)+1)},elasticInOut:function(t){var e,n=.1,i=.4;return 0===t?0:1===t?1:(!n||n<1?(n=1,e=.1):e=i*Math.asin(1/n)/(2*Math.PI),(t*=2)<1?n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*-.5:n*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*.5+1)},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){var e=1.70158;return--t*t*((e+1)*t+e)+1},backInOut:function(t){var e=2.5949095;return(t*=2)<1?t*t*((e+1)*t-e)*.5:.5*((t-=2)*t*((e+1)*t+e)+2)},bounceIn:function(t){return 1-Nr.bounceOut(1-t)},bounceOut:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},bounceInOut:function(t){return t<.5?.5*Nr.bounceIn(2*t):.5*Nr.bounceOut(2*t-1)+.5}},Or=Math.pow,$r=Math.sqrt,Rr=1e-8,Hr=1e-4,Fr=$r(3),Br=1/3,Vr=ai(),Wr=ai(),Ur=ai();function Gr(t){return t>-1e-8&&tRr||t<-1e-8}function jr(t,e,n,i,r){var o=1-r;return o*o*(o*t+3*r*e)+r*r*(r*i+3*o*n)}function Xr(t,e,n,i,r){var o=1-r;return 3*(((e-t)*o+2*(n-e)*r)*o+(i-n)*r*r)}function Yr(t,e,n,i,r,o){var a=i+3*(e-n)-t,s=3*(n-2*e+t),l=3*(e-t),c=t-r,d=s*s-3*a*l,u=s*l-9*a*c,h=l*l-3*s*c,p=0;if(Gr(d)&&Gr(u)){if(Gr(s))o[0]=0;else(C=-l/s)>=0&&C<=1&&(o[p++]=C)}else{var f=u*u-4*d*h;if(Gr(f)){var g=u/d,v=-g/2;(C=-s/a+g)>=0&&C<=1&&(o[p++]=C),v>=0&&v<=1&&(o[p++]=v)}else if(f>0){var m=$r(f),y=d*s+1.5*a*(-u+m),_=d*s+1.5*a*(-u-m);(C=(-s-((y=y<0?-Or(-y,Br):Or(y,Br))+(_=_<0?-Or(-_,Br):Or(_,Br))))/(3*a))>=0&&C<=1&&(o[p++]=C)}else{var b=(2*d*s-3*a*u)/(2*$r(d*d*d)),x=Math.acos(b)/3,w=$r(d),S=Math.cos(x),C=(-s-2*w*S)/(3*a),k=(v=(-s+w*(S+Fr*Math.sin(x)))/(3*a),(-s+w*(S-Fr*Math.sin(x)))/(3*a));C>=0&&C<=1&&(o[p++]=C),v>=0&&v<=1&&(o[p++]=v),k>=0&&k<=1&&(o[p++]=k)}}return p}function Zr(t,e,n,i,r){var o=6*n-12*e+6*t,a=9*e+3*i-3*t-9*n,s=3*e-3*t,l=0;if(Gr(a)){if(qr(o))(d=-s/o)>=0&&d<=1&&(r[l++]=d)}else{var c=o*o-4*a*s;if(Gr(c))r[0]=-o/(2*a);else if(c>0){var d,u=$r(c),h=(-o-u)/(2*a);(d=(-o+u)/(2*a))>=0&&d<=1&&(r[l++]=d),h>=0&&h<=1&&(r[l++]=h)}}return l}function Kr(t,e,n,i,r,o){var a=(e-t)*r+t,s=(n-e)*r+e,l=(i-n)*r+n,c=(s-a)*r+a,d=(l-s)*r+s,u=(d-c)*r+c;o[0]=t,o[1]=a,o[2]=c,o[3]=u,o[4]=u,o[5]=d,o[6]=l,o[7]=i}function Qr(t,e,n,i,r,o,a,s,l){for(var c=t,d=e,u=0,h=1/l,p=1;p<=l;p++){var f=p*h,g=jr(t,n,r,a,f),v=jr(e,i,o,s,f),m=g-c,y=v-d;u+=Math.sqrt(m*m+y*y),c=g,d=v}return u}function Jr(t,e,n,i){var r=1-i;return r*(r*t+2*i*e)+i*i*n}function to(t,e,n,i){return 2*((1-i)*(e-t)+i*(n-e))}function eo(t,e,n){var i=t+n-2*e;return 0===i?.5:(t-e)/i}function no(t,e,n,i,r){var o=(e-t)*i+t,a=(n-e)*i+e,s=(a-o)*i+o;r[0]=t,r[1]=o,r[2]=s,r[3]=s,r[4]=a,r[5]=n}function io(t,e,n,i,r,o,a){for(var s=t,l=e,c=0,d=1/a,u=1;u<=a;u++){var h=u*d,p=Jr(t,n,r,h),f=Jr(e,i,o,h),g=p-s,v=f-l;c+=Math.sqrt(g*g+v*v),s=p,l=f}return c}var ro=/cubic-bezier\(([0-9,\.e ]+)\)/;function oo(t){var e=t&&ro.exec(t);if(e){var n=e[1].split(","),i=+Xn(n[0]),r=+Xn(n[1]),o=+Xn(n[2]),a=+Xn(n[3]);if(isNaN(i+r+o+a))return;var s=[];return function(t){return t<=0?0:t>=1?1:Yr(0,i,o,1,t,s)&&jr(0,r,a,1,s[0])}}}var ao=function(){function t(t){this._inited=!1,this._startTime=0,this._pausedTime=0,this._paused=!1,this._life=t.life||1e3,this._delay=t.delay||0,this.loop=t.loop||!1,this.onframe=t.onframe||ri,this.ondestroy=t.ondestroy||ri,this.onrestart=t.onrestart||ri,t.easing&&this.setEasing(t.easing)}return t.prototype.step=function(t,e){if(this._inited||(this._startTime=t+this._delay,this._inited=!0),!this._paused){var n=this._life,i=t-this._startTime-this._pausedTime,r=i/n;r<0&&(r=0),r=Math.min(r,1);var o=this.easingFunc,a=o?o(r):r;if(this.onframe(a),1===r){if(!this.loop)return!0;var s=i%n;this._startTime=t-s,this._pausedTime=0,this.onrestart()}return!1}this._pausedTime+=e},t.prototype.pause=function(){this._paused=!0},t.prototype.resume=function(){this._paused=!1},t.prototype.setEasing=function(t){this.easing=t,this.easingFunc=Ln(t)?t:Nr[t]||oo(t)},t}(),so=function(t){this.value=t},lo=function(){function t(){this._len=0}return t.prototype.insert=function(t){var e=new so(t);return this.insertEntry(e),e},t.prototype.insertEntry=function(t){this.head?(this.tail.next=t,t.prev=this.tail,t.next=null,this.tail=t):this.head=this.tail=t,this._len++},t.prototype.remove=function(t){var e=t.prev,n=t.next;e?e.next=n:this.head=n,n?n.prev=e:this.tail=e,t.next=t.prev=null,this._len--},t.prototype.len=function(){return this._len},t.prototype.clear=function(){this.head=this.tail=null,this._len=0},t}(),co=function(){function t(t){this._list=new lo,this._maxSize=10,this._map={},this._maxSize=t}return t.prototype.put=function(t,e){var n=this._list,i=this._map,r=null;if(null==i[t]){var o=n.len(),a=this._lastRemovedEntry;if(o>=this._maxSize&&o>0){var s=n.head;n.remove(s),delete i[s.key],r=s.value,this._lastRemovedEntry=s}a?a.value=e:a=new so(e),a.key=t,n.insertEntry(a),i[t]=a}return r},t.prototype.get=function(t){var e=this._map[t],n=this._list;if(null!=e)return e!==n.tail&&(n.remove(e),n.insertEntry(e)),e.value},t.prototype.clear=function(){this._list.clear(),this._map={}},t.prototype.len=function(){return this._list.len()},t}(),uo={transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]};function ho(t){return(t=Math.round(t))<0?0:t>255?255:t}function po(t){return t<0?0:t>1?1:t}function fo(t){var e=t;return e.length&&"%"===e.charAt(e.length-1)?ho(parseFloat(e)/100*255):ho(parseInt(e,10))}function go(t){var e=t;return e.length&&"%"===e.charAt(e.length-1)?po(parseFloat(e)/100):po(parseFloat(e))}function vo(t,e,n){return n<0?n+=1:n>1&&(n-=1),6*n<1?t+(e-t)*n*6:2*n<1?e:3*n<2?t+(e-t)*(2/3-n)*6:t}function mo(t,e,n){return t+(e-t)*n}function yo(t,e,n,i,r){return t[0]=e,t[1]=n,t[2]=i,t[3]=r,t}function _o(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t}var bo=new co(20),xo=null;function wo(t,e){xo&&_o(xo,e),xo=bo.put(t,xo||e.slice())}function So(t,e){if(t){e=e||[];var n=bo.get(t);if(n)return _o(e,n);var i=(t+="").replace(/ /g,"").toLowerCase();if(i in uo)return _o(e,uo[i]),wo(t,e),e;var r,o=i.length;if("#"===i.charAt(0))return 4===o||5===o?(r=parseInt(i.slice(1,4),16))>=0&&r<=4095?(yo(e,(3840&r)>>4|(3840&r)>>8,240&r|(240&r)>>4,15&r|(15&r)<<4,5===o?parseInt(i.slice(4),16)/15:1),wo(t,e),e):void yo(e,0,0,0,1):7===o||9===o?(r=parseInt(i.slice(1,7),16))>=0&&r<=16777215?(yo(e,(16711680&r)>>16,(65280&r)>>8,255&r,9===o?parseInt(i.slice(7),16)/255:1),wo(t,e),e):void yo(e,0,0,0,1):void 0;var a=i.indexOf("("),s=i.indexOf(")");if(-1!==a&&s+1===o){var l=i.substr(0,a),c=i.substr(a+1,s-(a+1)).split(","),d=1;switch(l){case"rgba":if(4!==c.length)return 3===c.length?yo(e,+c[0],+c[1],+c[2],1):yo(e,0,0,0,1);d=go(c.pop());case"rgb":return c.length>=3?(yo(e,fo(c[0]),fo(c[1]),fo(c[2]),3===c.length?d:go(c[3])),wo(t,e),e):void yo(e,0,0,0,1);case"hsla":return 4!==c.length?void yo(e,0,0,0,1):(c[3]=go(c[3]),Co(c,e),wo(t,e),e);case"hsl":return 3!==c.length?void yo(e,0,0,0,1):(Co(c,e),wo(t,e),e);default:return}}yo(e,0,0,0,1)}}function Co(t,e){var n=(parseFloat(t[0])%360+360)%360/360,i=go(t[1]),r=go(t[2]),o=r<=.5?r*(i+1):r+i-r*i,a=2*r-o;return yo(e=e||[],ho(255*vo(a,o,n+1/3)),ho(255*vo(a,o,n)),ho(255*vo(a,o,n-1/3)),1),4===t.length&&(e[3]=t[3]),e}function ko(t,e){var n=So(t);if(n){for(var i=0;i<3;i++)n[i]=n[i]*(1-e)|0,n[i]>255?n[i]=255:n[i]<0&&(n[i]=0);return To(n,4===n.length?"rgba":"rgb")}}function Mo(t,e,n,i){var r=So(t);if(t)return r=function(t){if(t){var e,n,i=t[0]/255,r=t[1]/255,o=t[2]/255,a=Math.min(i,r,o),s=Math.max(i,r,o),l=s-a,c=(s+a)/2;if(0===l)e=0,n=0;else{n=c<.5?l/(s+a):l/(2-s-a);var d=((s-i)/6+l/2)/l,u=((s-r)/6+l/2)/l,h=((s-o)/6+l/2)/l;i===s?e=h-u:r===s?e=1/3+d-h:o===s&&(e=2/3+u-d),e<0&&(e+=1),e>1&&(e-=1)}var p=[360*e,n,c];return null!=t[3]&&p.push(t[3]),p}}(r),null!=n&&(r[1]=go(Ln(n)?n(r[1]):n)),null!=i&&(r[2]=go(Ln(i)?i(r[2]):i)),To(Co(r),"rgba")}function To(t,e){if(t&&t.length){var n=t[0]+","+t[1]+","+t[2];return"rgba"!==e&&"hsva"!==e&&"hsla"!==e||(n+=","+t[3]),e+"("+n+")"}}function Io(t,e){var n=So(t);return n?(.299*n[0]+.587*n[1]+.114*n[2])*n[3]/255+(1-n[3])*e:0}var Do=new co(100);function Ao(t){if(En(t)){var e=Do.get(t);return e||(e=ko(t,-.1),Do.put(t,e)),e}if(Fn(t)){var n=_n({},t);return n.colorStops=kn(t.colorStops,function(t){return{offset:t.offset,color:ko(t.color,-.1)}}),n}return t}var Po=Math.round;function Lo(t){var e;if(t&&"transparent"!==t){if("string"==typeof t&&t.indexOf("rgba")>-1){var n=So(t);n&&(t="rgb("+n[0]+","+n[1]+","+n[2]+")",e=n[3])}}else t="none";return{color:t,opacity:null==e?1:e}}var Eo=1e-4;function zo(t){return t-1e-4}function No(t){return Po(1e3*t)/1e3}function Oo(t){return Po(1e4*t)/1e4}var $o={left:"start",right:"end",center:"middle",middle:"middle"};function Ro(t){return t&&!!t.image}function Ho(t){return Ro(t)||function(t){return t&&!!t.svgElement}(t)}function Fo(t){return"linear"===t.type}function Bo(t){return"radial"===t.type}function Vo(t){return t&&("linear"===t.type||"radial"===t.type)}function Wo(t){return"url(#"+t+")"}function Uo(t){var e=t.getGlobalScale(),n=Math.max(e[0],e[1]);return Math.max(Math.ceil(Math.log(n)/Math.log(10)),1)}function Go(t){var e=t.x||0,n=t.y||0,i=(t.rotation||0)*oi,r=Wn(t.scaleX,1),o=Wn(t.scaleY,1),a=t.skewX||0,s=t.skewY||0,l=[];return(e||n)&&l.push("translate("+e+"px,"+n+"px)"),i&&l.push("rotate("+i+")"),1===r&&1===o||l.push("scale("+r+","+o+")"),(a||s)&&l.push("skew("+Po(a*oi)+"deg, "+Po(s*oi)+"deg)"),l.join(" ")}var qo=Ye.hasGlobalWindow&&Ln(window.btoa)?function(t){return window.btoa(unescape(encodeURIComponent(t)))}:"undefined"!=typeof Buffer?function(t){return Buffer.from(t).toString("base64")}:function(t){return null},jo=Array.prototype.slice;function Xo(t,e,n){return(e-t)*n+t}function Yo(t,e,n,i){for(var r=e.length,o=0;oi?e:t,o=Math.min(n,i),a=r[o-1]||{color:[0,0,0,0],offset:0},s=o;sa)i.length=a;else for(var s=o;s=1},t.prototype.getAdditiveTrack=function(){return this._additiveTrack},t.prototype.addKeyframe=function(t,e,n){this._needsSort=!0;var i=this.keyframes,r=i.length,o=!1,a=6,s=e;if(Sn(e)){var l=function(t){return Sn(t&&t[0])?2:1}(e);a=l,(1===l&&!Nn(e[0])||2===l&&!Nn(e[0][0]))&&(o=!0)}else if(Nn(e)&&!Bn(e))a=0;else if(En(e))if(isNaN(+e)){var c=So(e);c&&(s=c,a=3)}else a=0;else if(Fn(e)){var d=_n({},s);d.colorStops=kn(e.colorStops,function(t){return{offset:t.offset,color:So(t.color)}}),Fo(e)?a=4:Bo(e)&&(a=5),s=d}0===r?this.valType=a:a===this.valType&&6!==a||(o=!0),this.discrete=this.discrete||o;var u={time:t,value:s,rawValue:e,percent:0};return n&&(u.easing=n,u.easingFunc=Ln(n)?n:Nr[n]||oo(n)),i.push(u),u},t.prototype.prepare=function(t,e){var n=this.keyframes;this._needsSort&&n.sort(function(t,e){return t.time-e.time});for(var i=this.valType,r=n.length,o=n[r-1],a=this.discrete,s=ia(i),l=na(i),c=0;c=0&&!(l[n].percent<=e);n--);n=p(n,c-2)}else{for(n=h;ne);n++);n=p(n-1,c-2)}r=l[n+1],i=l[n]}if(i&&r){this._lastFr=n,this._lastFrP=e;var f=r.percent-i.percent,g=0===f?1:p((e-i.percent)/f,1);r.easingFunc&&(g=r.easingFunc(g));var v=o?this._additiveValue:u?ra:t[d];if(!ia(s)&&!u||v||(v=this._additiveValue=[]),this.discrete)t[d]=g<1?i.rawValue:r.rawValue;else if(ia(s))1===s?Yo(v,i[a],r[a],g):function(t,e,n,i){for(var r=e.length,o=r&&e[0].length,a=0;a0&&s.addKeyframe(0,ta(l),i),this._trackKeys.push(a)}s.addKeyframe(t,ta(e[a]),i)}return this._maxTime=Math.max(this._maxTime,t),this},t.prototype.pause=function(){this._clip.pause(),this._paused=!0},t.prototype.resume=function(){this._clip.resume(),this._paused=!1},t.prototype.isPaused=function(){return!!this._paused},t.prototype.duration=function(t){return this._maxTime=t,this._force=!0,this},t.prototype._doneCallback=function(){this._setTracksFinished(),this._clip=null;var t=this._doneCbs;if(t)for(var e=t.length,n=0;n0)){this._started=1;for(var e=this,n=[],i=this._maxTime||0,r=0;r1){var a=o.pop();r.addKeyframe(a.time,t[i]),r.prepare(this._maxTime,r.getAdditiveTrack())}}}},t}();function sa(){return(new Date).getTime()}var la,ca,da=function(t){function e(e){var n=t.call(this)||this;return n._running=!1,n._time=0,n._pausedTime=0,n._pauseStart=0,n._paused=!1,e=e||{},n.stage=e.stage||{},n}return y(e,t),e.prototype.addClip=function(t){t.animation&&this.removeClip(t),this._head?(this._tail.next=t,t.prev=this._tail,t.next=null,this._tail=t):this._head=this._tail=t,t.animation=this},e.prototype.addAnimator=function(t){t.animation=this;var e=t.getClip();e&&this.addClip(e)},e.prototype.removeClip=function(t){if(t.animation){var e=t.prev,n=t.next;e?e.next=n:this._head=n,n?n.prev=e:this._tail=e,t.next=t.prev=t.animation=null}},e.prototype.removeAnimator=function(t){var e=t.getClip();e&&this.removeClip(e),t.animation=null},e.prototype.update=function(t){for(var e=sa()-this._pausedTime,n=e-this._time,i=this._head;i;){var r=i.next;i.step(e,n)?(i.ondestroy(),this.removeClip(i),i=r):i=r}this._time=e,t||(this.trigger("frame",n),this.stage.update&&this.stage.update())},e.prototype._startLoop=function(){var t=this;this._running=!0,Er(function e(){t._running&&(Er(e),!t._paused&&t.update())})},e.prototype.start=function(){this._running||(this._time=sa(),this._pausedTime=0,this._startLoop())},e.prototype.stop=function(){this._running=!1},e.prototype.pause=function(){this._paused||(this._pauseStart=sa(),this._paused=!0)},e.prototype.resume=function(){this._paused&&(this._pausedTime+=sa()-this._pauseStart,this._paused=!1)},e.prototype.clear=function(){for(var t=this._head;t;){var e=t.next;t.prev=t.next=t.animation=null,t=e}this._head=this._tail=null},e.prototype.isFinished=function(){return null==this._head},e.prototype.animate=function(t,e){e=e||{},this.start();var n=new aa(t,e.loop);return this.addAnimator(n),n},e}(bi),ua=Ye.domSupported,ha=(ca={pointerdown:1,pointerup:1,pointermove:1,pointerout:1},{mouse:la=["click","dblclick","mousewheel","wheel","mouseout","mouseup","mousedown","mousemove","contextmenu"],touch:["touchstart","touchend","touchmove"],pointer:kn(la,function(t){var e=t.replace("mouse","pointer");return ca.hasOwnProperty(e)?e:t})}),pa=["mousemove","mouseup"],fa=["pointermove","pointerup"],ga=!1;function va(t){var e=t.pointerType;return"pen"===e||"touch"===e}function ma(t){t&&(t.zrByTouch=!0)}function ya(t,e){for(var n=e,i=!1;n&&9!==n.nodeType&&!(i=n.domBelongToZr||n!==e&&n===t.painterRoot);)n=n.parentNode;return i}var _a=function(t,e){this.stopPropagation=ri,this.stopImmediatePropagation=ri,this.preventDefault=ri,this.type=e.type,this.target=this.currentTarget=t.dom,this.pointerType=e.pointerType,this.clientX=e.clientX,this.clientY=e.clientY},ba={mousedown:function(t){t=$i(this.dom,t),this.__mayPointerCapture=[t.zrX,t.zrY],this.trigger("mousedown",t)},mousemove:function(t){t=$i(this.dom,t);var e=this.__mayPointerCapture;!e||t.zrX===e[0]&&t.zrY===e[1]||this.__togglePointerCapture(!0),this.trigger("mousemove",t)},mouseup:function(t){t=$i(this.dom,t),this.__togglePointerCapture(!1),this.trigger("mouseup",t)},mouseout:function(t){ya(this,(t=$i(this.dom,t)).toElement||t.relatedTarget)||(this.__pointerCapturing&&(t.zrEventControl="no_globalout"),this.trigger("mouseout",t))},wheel:function(t){ga=!0,t=$i(this.dom,t),this.trigger("mousewheel",t)},mousewheel:function(t){ga||(t=$i(this.dom,t),this.trigger("mousewheel",t))},touchstart:function(t){ma(t=$i(this.dom,t)),this.__lastTouchMoment=new Date,this.handler.processGesture(t,"start"),ba.mousemove.call(this,t),ba.mousedown.call(this,t)},touchmove:function(t){ma(t=$i(this.dom,t)),this.handler.processGesture(t,"change"),ba.mousemove.call(this,t)},touchend:function(t){ma(t=$i(this.dom,t)),this.handler.processGesture(t,"end"),ba.mouseup.call(this,t),+new Date-+this.__lastTouchMoment<300&&ba.click.call(this,t)},pointerdown:function(t){ba.mousedown.call(this,t)},pointermove:function(t){va(t)||ba.mousemove.call(this,t)},pointerup:function(t){ba.mouseup.call(this,t)},pointerout:function(t){va(t)||ba.mouseout.call(this,t)}};Cn(["click","dblclick","contextmenu"],function(t){ba[t]=function(e){e=$i(this.dom,e),this.trigger(t,e)}});var xa={pointermove:function(t){va(t)||xa.mousemove.call(this,t)},pointerup:function(t){xa.mouseup.call(this,t)},mousemove:function(t){this.trigger("mousemove",t)},mouseup:function(t){var e=this.__pointerCapturing;this.__togglePointerCapture(!1),this.trigger("mouseup",t),e&&(t.zrEventControl="only_globalout",this.trigger("mouseout",t))}};function wa(t,e){var n=e.domHandlers;Ye.pointerEventsSupported?Cn(ha.pointer,function(i){Ca(e,i,function(e){n[i].call(t,e)})}):(Ye.touchEventsSupported&&Cn(ha.touch,function(i){Ca(e,i,function(r){n[i].call(t,r),function(t){t.touching=!0,null!=t.touchTimer&&(clearTimeout(t.touchTimer),t.touchTimer=null),t.touchTimer=setTimeout(function(){t.touching=!1,t.touchTimer=null},700)}(e)})}),Cn(ha.mouse,function(i){Ca(e,i,function(r){r=Oi(r),e.touching||n[i].call(t,r)})}))}function Sa(t,e){function n(n){Ca(e,n,function(i){i=Oi(i),ya(t,i.target)||(i=function(t,e){return $i(t.dom,new _a(t,e),!0)}(t,i),e.domHandlers[n].call(t,i))},{capture:!0})}Ye.pointerEventsSupported?Cn(fa,n):Ye.touchEventsSupported||Cn(pa,n)}function Ca(t,e,n,i){t.mounted[e]=n,t.listenerOpts[e]=i,function(t,e,n,i){t.addEventListener(e,n,i)}(t.domTarget,e,n,i)}function ka(t){var e=t.mounted;for(var n in e)e.hasOwnProperty(n)&&Ri(t.domTarget,n,e[n],t.listenerOpts[n]);t.mounted={}}var Ma=function(t,e){this.mounted={},this.listenerOpts={},this.touching=!1,this.domTarget=t,this.domHandlers=e},Ta=function(t){function e(e,n){var i=t.call(this)||this;return i.__pointerCapturing=!1,i.dom=e,i.painterRoot=n,i._localHandlerScope=new Ma(e,ba),ua&&(i._globalHandlerScope=new Ma(document,xa)),wa(i,i._localHandlerScope),i}return y(e,t),e.prototype.dispose=function(){ka(this._localHandlerScope),ua&&ka(this._globalHandlerScope)},e.prototype.setCursor=function(t){this.dom.style&&(this.dom.style.cursor=t||"default")},e.prototype.__togglePointerCapture=function(t){if(this.__mayPointerCapture=null,ua&&+this.__pointerCapturing^+t){this.__pointerCapturing=t;var e=this._globalHandlerScope;t?Sa(this,e):ka(e)}},e}(bi),Ia=1;Ye.hasGlobalWindow&&(Ia=Math.max(window.devicePixelRatio||window.screen&&window.screen.deviceXDPI/window.screen.logicalXDPI||1,1));var Da=Ia,Aa="#333",Pa="#ccc",La=Wi,Ea=5e-5;function za(t){return t>Ea||t<-5e-5}var Na,Oa=[],$a=[],Ra=[1,0,0,1,0,0],Ha=Math.abs,Fa=function(){function t(){}var e;return t.prototype.getLocalTransform=function(e){return t.getLocalTransform(this,e)},t.prototype.setPosition=function(t){this.x=t[0],this.y=t[1]},t.prototype.setScale=function(t){this.scaleX=t[0],this.scaleY=t[1]},t.prototype.setSkew=function(t){this.skewX=t[0],this.skewY=t[1]},t.prototype.setOrigin=function(t){this.originX=t[0],this.originY=t[1]},t.prototype.needLocalTransform=function(){return za(this.rotation)||za(this.x)||za(this.y)||za(this.scaleX-1)||za(this.scaleY-1)||za(this.skewX)||za(this.skewY)},t.prototype.updateTransform=function(){var t=this.parent&&this.parent.transform,e=this.needLocalTransform(),n=this.transform;e||t?(n=n||[1,0,0,1,0,0],e?this.getLocalTransform(n):La(n),t&&(e?Gi(n,t,n):Ui(n,t)),this.transform=n,this._resolveGlobalScaleRatio(n)):n&&(La(n),this.invTransform=null)},t.prototype._resolveGlobalScaleRatio=function(t){var e=this.globalScaleRatio;if(null!=e&&1!==e){this.getGlobalScale(Oa);var n=Oa[0]<0?-1:1,i=Oa[1]<0?-1:1,r=((Oa[0]-n)*e+n)/Oa[0]||0,o=((Oa[1]-i)*e+i)/Oa[1]||0;t[0]*=r,t[1]*=r,t[2]*=o,t[3]*=o}this.invTransform=this.invTransform||[1,0,0,1,0,0],Xi(this.invTransform,t)},t.prototype.getComputedTransform=function(){for(var t=this,e=[];t;)e.push(t),t=t.parent;for(;t=e.pop();)t.updateTransform();return this.transform},t.prototype.setLocalTransform=function(t){if(t){var e=t[0]*t[0]+t[1]*t[1],n=t[2]*t[2]+t[3]*t[3],i=Math.atan2(t[1],t[0]),r=Math.PI/2+i-Math.atan2(t[3],t[2]);n=Math.sqrt(n)*Math.cos(r),e=Math.sqrt(e),this.skewX=r,this.skewY=0,this.rotation=-i,this.x=+t[4],this.y=+t[5],this.scaleX=e,this.scaleY=n,this.originX=0,this.originY=0}},t.prototype.decomposeTransform=function(){if(this.transform){var t=this.parent,e=this.transform;t&&t.transform&&(t.invTransform=t.invTransform||[1,0,0,1,0,0],Gi($a,t.invTransform,e),e=$a);var n=this.originX,i=this.originY;(n||i)&&(Ra[4]=n,Ra[5]=i,Gi($a,e,Ra),$a[4]-=n,$a[5]-=i,e=$a),this.setLocalTransform(e)}},t.prototype.getGlobalScale=function(t){var e=this.transform;return t=t||[],e?(t[0]=Math.sqrt(e[0]*e[0]+e[1]*e[1]),t[1]=Math.sqrt(e[2]*e[2]+e[3]*e[3]),e[0]<0&&(t[0]=-t[0]),e[3]<0&&(t[1]=-t[1]),t):(t[0]=1,t[1]=1,t)},t.prototype.transformCoordToLocal=function(t,e){var n=[t,e],i=this.invTransform;return i&&gi(n,n,i),n},t.prototype.transformCoordToGlobal=function(t,e){var n=[t,e],i=this.transform;return i&&gi(n,n,i),n},t.prototype.getLineScale=function(){var t=this.transform;return t&&Ha(t[0]-1)>1e-10&&Ha(t[3]-1)>1e-10?Math.sqrt(Ha(t[0]*t[3]-t[2]*t[1])):1},t.prototype.copyTransform=function(t){Va(this,t)},t.getLocalTransform=function(t,e){e=e||[];var n=t.originX||0,i=t.originY||0,r=t.scaleX,o=t.scaleY,a=t.anchorX,s=t.anchorY,l=t.rotation||0,c=t.x,d=t.y,u=t.skewX?Math.tan(t.skewX):0,h=t.skewY?Math.tan(-t.skewY):0;if(n||i||a||s){var p=n+a,f=i+s;e[4]=-p*r-u*f*o,e[5]=-f*o-h*p*r}else e[4]=e[5]=0;return e[0]=r,e[3]=o,e[1]=h*r,e[2]=u*o,l&&ji(e,e,l),e[4]+=n+c,e[5]+=i+d,e},t.initDefaultProps=((e=t.prototype).scaleX=e.scaleY=e.globalScaleRatio=1,void(e.x=e.y=e.originX=e.originY=e.skewX=e.skewY=e.rotation=e.anchorX=e.anchorY=0)),t}(),Ba=["x","y","originX","originY","anchorX","anchorY","rotation","scaleX","scaleY","skewX","skewY"];function Va(t,e){for(var n=0;n=Ga)){t=t||Ke;for(var e=[],n=+new Date,i=0;i<=127;i++)e[i]=en.measureText(String.fromCharCode(i),t).width;var r=+new Date-n;return r>16?Ua=Ga:r>2&&Ua++,e}}(t.font),t.asciiWidthMapTried=!0),0<=e&&e<=127?null!=t.asciiWidthMap?t.asciiWidthMap[e]:t.asciiCharWidth:t.stWideCharWidth}function ja(t,e){var n=t.strWidthCache,i=n.get(e);return null==i&&(i=en.measureText(e,t.font).width,n.put(e,i)),i}function Xa(t,e,n,i){var r=ja(Wa(e),t),o=Qa(e),a=Za(0,r,n),s=Ka(0,o,i);return new cr(a,s,r,o)}function Ya(t,e,n,i){var r=((t||"")+"").split("\n");if(1===r.length)return Xa(r[0],e,n,i);for(var o=new cr(0,0,0,0),a=0;a=0?parseFloat(t)/100*e:parseFloat(t):t}function ts(t,e,n){var i=e.position||"inside",r=null!=e.distance?e.distance:5,o=n.height,a=n.width,s=o/2,l=n.x,c=n.y,d="left",u="top";if(i instanceof Array)l+=Ja(i[0],n.width),c+=Ja(i[1],n.height),d=null,u=null;else switch(i){case"left":l-=r,c+=s,d="right",u="middle";break;case"right":l+=r+a,c+=s,u="middle";break;case"top":l+=a/2,c-=r,d="center",u="bottom";break;case"bottom":l+=a/2,c+=o+r,d="center";break;case"inside":l+=a/2,c+=s,d="center",u="middle";break;case"insideLeft":l+=r,c+=s,u="middle";break;case"insideRight":l+=a-r,c+=s,d="right",u="middle";break;case"insideTop":l+=a/2,c+=r,d="center";break;case"insideBottom":l+=a/2,c+=o-r,d="center",u="bottom";break;case"insideTopLeft":l+=r,c+=r;break;case"insideTopRight":l+=a-r,c+=r,d="right";break;case"insideBottomLeft":l+=r,c+=o-r,u="bottom";break;case"insideBottomRight":l+=a-r,c+=o-r,d="right",u="bottom"}return(t=t||{}).x=l,t.y=c,t.align=d,t.verticalAlign=u,t}var es="__zr_normal__",ns=Ba.concat(["ignore"]),is=Mn(Ba,function(t,e){return t[e]=!0,t},{ignore:!1}),rs={},os=new cr(0,0,0,0),as=[],ss=function(){function t(t){this.id=gn(),this.animators=[],this.currentStates=[],this.states={},this._init(t)}return t.prototype._init=function(t){this.attr(t)},t.prototype.drift=function(t,e,n){switch(this.draggable){case"horizontal":e=0;break;case"vertical":t=0}var i=this.transform;i||(i=this.transform=[1,0,0,1,0,0]),i[4]+=t,i[5]+=e,this.decomposeTransform(),this.markRedraw()},t.prototype.beforeUpdate=function(){},t.prototype.afterUpdate=function(){},t.prototype.update=function(){this.updateTransform(),this.__dirty&&this.updateInnerText()},t.prototype.updateInnerText=function(t){var e=this._textContent;if(e&&(!e.ignore||t)){this.textConfig||(this.textConfig={});var n=this.textConfig,i=n.local,r=e.innerTransformable,o=void 0,a=void 0,s=!1;r.parent=i?this:null;var l=!1;r.copyTransform(e);var c=null!=n.position,d=n.autoOverflowArea,u=void 0;if((d||c)&&(u=os,n.layoutRect?u.copy(n.layoutRect):u.copy(this.getBoundingRect()),i||u.applyTransform(this.transform)),c){this.calculateTextPosition?this.calculateTextPosition(rs,n,u):ts(rs,n,u),r.x=rs.x,r.y=rs.y,o=rs.align,a=rs.verticalAlign;var h=n.origin;if(h&&null!=n.rotation){var p=void 0,f=void 0;"center"===h?(p=.5*u.width,f=.5*u.height):(p=Ja(h[0],u.width),f=Ja(h[1],u.height)),l=!0,r.originX=-r.x+p+(i?0:u.x),r.originY=-r.y+f+(i?0:u.y)}}null!=n.rotation&&(r.rotation=n.rotation);var g=n.offset;g&&(r.x+=g[0],r.y+=g[1],l||(r.originX=-g[0],r.originY=-g[1]));var v=this._innerTextDefaultStyle||(this._innerTextDefaultStyle={});if(d){var m=v.overflowRect=v.overflowRect||new cr(0,0,0,0);r.getLocalTransform(as),Xi(as,as),cr.copy(m,u),m.applyTransform(as)}else v.overflowRect=null;var y=void 0,_=void 0,b=void 0;(null==n.inside?"string"==typeof n.position&&n.position.indexOf("inside")>=0:n.inside)&&this.canBeInsideText()?(y=n.insideFill,_=n.insideStroke,null!=y&&"auto"!==y||(y=this.getInsideTextFill()),null!=_&&"auto"!==_||(_=this.getInsideTextStroke(y),b=!0)):(y=n.outsideFill,_=n.outsideStroke,null!=y&&"auto"!==y||(y=this.getOutsideFill()),null!=_&&"auto"!==_||(_=this.getOutsideStroke(y),b=!0)),(y=y||"#000")===v.fill&&_===v.stroke&&b===v.autoStroke&&o===v.align&&a===v.verticalAlign||(s=!0,v.fill=y,v.stroke=_,v.autoStroke=b,v.align=o,v.verticalAlign=a,e.setDefaultTextStyle(v)),e.__dirty|=1,s&&e.dirtyStyle(!0)}},t.prototype.canBeInsideText=function(){return!0},t.prototype.getInsideTextFill=function(){return"#fff"},t.prototype.getInsideTextStroke=function(t){return"#000"},t.prototype.getOutsideFill=function(){return this.__zr&&this.__zr.isDarkMode()?Pa:Aa},t.prototype.getOutsideStroke=function(t){var e=this.__zr&&this.__zr.getBackgroundColor(),n="string"==typeof e&&So(e);n||(n=[255,255,255,1]);for(var i=n[3],r=this.__zr.isDarkMode(),o=0;o<3;o++)n[o]=n[o]*i+(r?0:255)*(1-i);return n[3]=1,To(n,"rgba")},t.prototype.traverse=function(t,e){},t.prototype.attrKV=function(t,e){"textConfig"===t?this.setTextConfig(e):"textContent"===t?this.setTextContent(e):"clipPath"===t?this.setClipPath(e):"extra"===t?(this.extra=this.extra||{},_n(this.extra,e)):this[t]=e},t.prototype.hide=function(){this.ignore=!0,this.markRedraw()},t.prototype.show=function(){this.ignore=!1,this.markRedraw()},t.prototype.attr=function(t,e){if("string"==typeof t)this.attrKV(t,e);else if(On(t))for(var n=In(t),i=0;i0},t.prototype.getState=function(t){return this.states[t]},t.prototype.ensureState=function(t){var e=this.states;return e[t]||(e[t]={}),e[t]},t.prototype.clearStates=function(t){this.useState(es,!1,t)},t.prototype.useState=function(t,e,n,i){var r=t===es;if(this.hasState()||!r){var o=this.currentStates,a=this.stateTransition;if(!(xn(o,t)>=0)||!e&&1!==o.length){var s;if(this.stateProxy&&!r&&(s=this.stateProxy(t)),s||(s=this.states&&this.states[t]),s||r){r||this.saveCurrentToNormalState(s);var l=!!(s&&s.hoverLayer||i);l&&this._toggleHoverLayerFlag(!0),this._applyStateObj(t,s,this._normalState,e,!n&&!this.__inHover&&a&&a.duration>0,a);var c=this._textContent,d=this._textGuide;return c&&c.useState(t,e,n,l),d&&d.useState(t,e,n,l),r?(this.currentStates=[],this._normalState={}):e?this.currentStates.push(t):this.currentStates=[t],this._updateAnimationTargets(),this.markRedraw(),!l&&this.__inHover&&(this._toggleHoverLayerFlag(!1),this.__dirty&=-2),s}vn("State "+t+" not exists.")}}},t.prototype.useStates=function(t,e,n){if(t.length){var i=[],r=this.currentStates,o=t.length,a=o===r.length;if(a)for(var s=0;s0,p);var f=this._textContent,g=this._textGuide;f&&f.useStates(t,e,u),g&&g.useStates(t,e,u),this._updateAnimationTargets(),this.currentStates=t.slice(),this.markRedraw(),!u&&this.__inHover&&(this._toggleHoverLayerFlag(!1),this.__dirty&=-2)}else this.clearStates()},t.prototype.isSilent=function(){for(var t=this;t;){if(t.silent)return!0;var e=t.__hostTarget;t=e?t.ignoreHostSilent?null:e:t.parent}return!1},t.prototype._updateAnimationTargets=function(){for(var t=0;t=0){var n=this.currentStates.slice();n.splice(e,1),this.useStates(n)}},t.prototype.replaceState=function(t,e,n){var i=this.currentStates.slice(),r=xn(i,t),o=xn(i,e)>=0;r>=0?o?i.splice(r,1):i[r]=e:n&&!o&&i.push(e),this.useStates(i)},t.prototype.toggleState=function(t,e){e?this.useState(t,!0):this.removeState(t)},t.prototype._mergeStates=function(t){for(var e,n={},i=0;i=0&&e.splice(n,1)}),this.animators.push(t),n&&n.animation.addAnimator(t),n&&n.wakeUp()},t.prototype.updateDuringAnimation=function(t){this.markRedraw()},t.prototype.stopAnimation=function(t,e){for(var n=this.animators,i=n.length,r=[],o=0;o0&&n.during&&o[0].during(function(t,e){n.during(e)});for(var h=0;h0||r.force&&!a.length){var w,S=void 0,C=void 0,k=void 0;if(s){C={},h&&(S={});for(b=0;b<_;b++){C[m=g[b]]=n[m],h?S[m]=i[m]:n[m]=i[m]}}else if(h){k={};for(b=0;b<_;b++){k[m=g[b]]=ta(n[m]),ds(n,i,m)}}(w=new aa(n,!1,!1,u?Tn(f,function(t){return t.targetName===e}):null)).targetName=e,r.scope&&(w.scope=r.scope),h&&S&&w.whenWithKeys(0,S,g),k&&w.whenWithKeys(0,k,g),w.whenWithKeys(null==c?500:c,s?C:i,g).delay(d||0),t.addAnimator(w,e),a.push(w)}}wn(ss,bi),wn(ss,Fa);var hs=function(t){function e(e){var n=t.call(this)||this;return n.isGroup=!0,n._children=[],n.attr(e),n}return y(e,t),e.prototype.childrenRef=function(){return this._children},e.prototype.children=function(){return this._children.slice()},e.prototype.childAt=function(t){return this._children[t]},e.prototype.childOfName=function(t){for(var e=this._children,n=0;n=0&&(n.splice(i,0,t),this._doAdd(t))}return this},e.prototype.replace=function(t,e){var n=xn(this._children,t);return n>=0&&this.replaceAt(e,n),this},e.prototype.replaceAt=function(t,e){var n=this._children,i=n[e];if(t&&t!==this&&t.parent!==this&&t!==i){n[e]=t,i.parent=null;var r=this.__zr;r&&i.removeSelfFromZr(r),this._doAdd(t)}return this},e.prototype._doAdd=function(t){t.parent&&t.parent.remove(t),t.parent=this;var e=this.__zr;e&&e!==t.__zr&&t.addSelfToZr(e),e&&e.refresh()},e.prototype.remove=function(t){var e=this.__zr,n=this._children,i=xn(n,t);return i<0||(n.splice(i,1),t.parent=null,e&&t.removeSelfFromZr(e),e&&e.refresh()),this},e.prototype.removeAll=function(){for(var t=this._children,e=this.__zr,n=0;nt.time>=d).map(t=>[t.time,Math.abs(t.value)]),p=[{type:"line",data:h,showSymbol:!1,smooth:!1,...a?{}:{step:"end"},lineStyle:{width:1.5,color:l},areaStyle:{color:{type:"linear",x:0,y:0,x2:0,y2:1,colorStops:[{offset:0,color:`rgba(${s}, 0.18)`},{offset:1,color:`rgba(${s}, 0.18)`}]}},itemStyle:{color:l}}],g=h.length>0?function(t){let e=0;for(const n of t)n[1]>e&&(e=n[1]);return e}(h):0,v={type:"value",splitNumber:4,axisLabel:{fontSize:10,formatter:g<10?t=>0===t?"0":t.toFixed(1):t=>n.format(t)},splitLine:{lineStyle:{opacity:.15}}};u?(v.min=n.fixedMin,v.max=n.fixedMax):g<1&&(v.min=0,v.max=1),o&&"current"===n.entityRole&&(v.min=0,v.max=Math.ceil(1.25*o),p.push({type:"line",data:[[d,.8*o],[c,.8*o]],showSymbol:!1,lineStyle:{width:1,color:"rgba(255, 200, 40, 0.6)",type:"dashed"},itemStyle:{color:"transparent"},tooltip:{show:!1}}),p.push({type:"line",data:[[d,o],[c,o]],showSymbol:!1,lineStyle:{width:1.5,color:"rgba(255, 60, 60, 0.7)",type:"solid"},itemStyle:{color:"transparent"},tooltip:{show:!1}}));const m={xAxis:{type:"time",min:d,max:c,axisLabel:{fontSize:10},splitLine:{show:!1}},yAxis:v,grid:{top:8,right:4,bottom:0,left:0,containLabel:!0},tooltip:{trigger:"axis",axisPointer:{type:"line",lineStyle:{type:"dashed"}},formatter:t=>{if(!t||0===t.length)return"";const e=t[0],i=new Date(e.value[0]).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"}),r=parseFloat(e.value[1].toFixed(2));return`${i}${n.format(r)} ${n.unit(r)}
`}},animation:!1};return{options:m,series:p}}(n,i,o,a,l,c),h=s??120;t.style.minHeight=h+"px";let p=t.querySelector("span-chart");p||(p=document.createElement("span-chart"),p.style.display="block",p.style.width="100%",t.innerHTML="",t.appendChild(p));const g=t.clientHeight;p.height=(g>0?g:h)+"px",p.options=d,p.data=u}function nT(t){return"function"==typeof globalThis.CSS?.escape?CSS.escape(t):t.replace(/["\\]/g,"\\$&")}function iT(t,e,n,i,r){const o="current"===(i.chart_metric||"power"),a=t.querySelector(".stat-consumption .stat-value"),s=t.querySelector(".stat-consumption .stat-unit");if(o){const t=n.panel_entities?.site_power,i=t?e.states[t]:null,r=i?parseFloat(i.attributes?.amperage):NaN;a&&(a.textContent=Number.isFinite(r)?Math.abs(r).toFixed(1):"--"),s&&(s.textContent="A")}else{let t=r;const i=n.panel_entities?.site_power;if(i){const n=e.states[i];n&&(t=Math.abs(parseFloat(n.state)||0))}a&&(a.textContent=fe(t)),s&&(s.textContent="kW")}const l=t.querySelector(".stat-upstream .stat-value"),c=t.querySelector(".stat-upstream .stat-unit");if(l){const t=n.panel_entities?.current_power,i=t?e.states[t]:null;if(o){const t=i?parseFloat(i.attributes?.amperage):NaN;l.textContent=Number.isFinite(t)?Math.abs(t).toFixed(1):"--",c&&(c.textContent="A")}else{const t=i?Math.abs(parseFloat(i.state)||0):0;l.textContent=fe(t),c&&(c.textContent="kW")}}const d=t.querySelector(".stat-downstream .stat-value"),u=t.querySelector(".stat-downstream .stat-unit");if(d){const t=n.panel_entities?.feedthrough_power,i=t?e.states[t]:null;if(o){const t=i?parseFloat(i.attributes?.amperage):NaN;d.textContent=Number.isFinite(t)?Math.abs(t).toFixed(1):"--",u&&(u.textContent="A")}else{const t=i?Math.abs(parseFloat(i.state)||0):0;d.textContent=fe(t),u&&(u.textContent="kW")}}const h=t.querySelector(".stat-solar .stat-value"),p=t.querySelector(".stat-solar .stat-unit");if(h){const t=n.panel_entities?.pv_power,i=t?e.states[t]:null;if(o){const t=i?parseFloat(i.attributes?.amperage):NaN;h.textContent=Number.isFinite(t)?Math.abs(t).toFixed(1):"--",p&&(p.textContent="A")}else{if(i){const t=Math.abs(parseFloat(i.state)||0);h.textContent=fe(t)}else h.textContent="--";p&&(p.textContent="kW")}}const f=t.querySelector(".stat-battery .stat-value");if(f){const t=n.panel_entities?.battery_level,i=t?e.states[t]:null;i&&(f.textContent=`${Math.round(parseFloat(i.state)||0)}`)}const g=t.querySelector(".stat-grid-state .stat-value");if(g){const t=n.panel_entities?.dsm_state,i=t?e.states[t]:null;g.textContent=i?e.formatEntityState?.(i)||i.state:"--"}}function rT(t,e,i,r,o,a){if(!t||!i||!e)return;const s=Re(r);let d=0;for(const[,t]of Object.entries(i.circuits)){const n=t.entities?.power;if(!n)continue;const i=e.states[n],r=i&&parseFloat(i.state)||0;t.device_type!==c&&(d+=Math.abs(r))}!function(t,e,n,i,r){const o=t.querySelector(".panel-stats");o&&iT(o,e,n,i,r)}(t,e,i,r,d);const u=ye(r),h="current"===u.entityRole;for(const[r,d]of Object.entries(i.circuits)){const i=t.querySelector(`.circuit-slot[data-uuid="${nT(r)}"]`);if(!i)continue;const p=d.entities?.power,f=p?e.states[p]:null,g=f&&parseFloat(f.state)||0,m=d.device_type===c||g<0,y=d.entities?.switch,_=y?e.states[y]:null,b=_?"on"===_.state:(f?.attributes?.relay_state||d.relay_state)===l,x=i.querySelector(".power-value");if(x)if(h){const t=d.entities?.current,n=t?e.states[t]:null,i=n&&parseFloat(n.state)||0;x.innerHTML=`${u.format(i)} A `}else x.innerHTML=`${pe(g)} ${he(g)} `;const w=i.querySelector(".toggle-pill");if(w){w.className="toggle-pill "+(b?"toggle-on":"toggle-off");const t=w.querySelector(".toggle-label");t&&(t.textContent=n(b?"grid.on":"grid.off"))}let S;if(i.classList.toggle("circuit-off",!b),i.classList.toggle("circuit-producer",m),d.always_on)S="always_on";else{const t=d.entities?.select,n=t?e.states[t]:null;S=n?n.state:"unknown"}const C=v[S]??v.unknown,k=i.querySelector(".shedding-icon");k&&(k.setAttribute("icon",C.icon),k.style.color=C.color,k.title=C.label());const M=i.querySelector(".shedding-icon-secondary");M&&(C.icon2?(M.setAttribute("icon",C.icon2),M.style.color=C.color,M.style.display=""):M.style.display="none");const T=i.querySelector(".shedding-label");T&&(C.textLabel?(T.textContent=C.textLabel,T.style.color=C.color,T.style.display=""):T.style.display="none");const I=i.querySelector(".chart-container");if(I){const t=o.get(r)||[],e=i.classList.contains("circuit-col-span")?200:100,n=a?.has(r)?He(a.get(r)):s,l=d.device_type===c;eT(I,0,t,n,u,m,e,d.breaker_rating_a??void 0,l)}}}class oT{get errorStore(){return this._errorStore}set errorStore(t){this._errorStore=t,this._retry=t?new qt(t):null}constructor(){this._errorStore=null,this._retry=null,this._settings=null,this._lastFetch=0,this._fetching=!1}async fetch(t,e){const i=Date.now();if(this._fetching)return this._settings;if(this._settings&&i-this._lastFetch<3e4)return this._settings;this._fetching=!0;try{const i={};e&&(i.config_entry_id=e);const r={type:"call_service",domain:s,service:"get_graph_settings",service_data:i,return_response:!0},o=this._retry?await this._retry.callWS(t,r,{errorId:"fetch:graph_settings",errorMessage:n("error.graph_settings_failed")}):await t.callWS(r);this._settings=o?.response??null,this._lastFetch=Date.now()}catch(t){console.warn("SPAN Panel: graph settings fetch failed",t),this._settings=null,this._retry||this._errorStore?.add({key:"fetch:graph_settings",level:"warning",message:n("error.graph_settings_failed"),persistent:!1})}finally{this._fetching=!1}return this._settings}invalidate(){this._lastFetch=0}get settings(){return this._settings}clear(){this._settings=null,this._lastFetch=0}}function aT(t,e){if(!t)return o;const n=t.circuits?.[e];return n?.has_override?n.horizon:t.global_horizon??o}function sT(t,e){if(!t)return o;const n=t.sub_devices?.[e];return n?.has_override?n.horizon:t.global_horizon??o}class lT{constructor(){this.powerHistory=new Map,this.horizonMap=new Map,this.subDeviceHorizonMap=new Map,this.monitoringCache=new be,this.monitoringMultiCache=new xe,this.graphSettingsCache=new oT,this._errorStore=null,this._hass=null,this._topology=null,this._config=null,this._configEntryId=null,this._favRefs=null,this._perPanelInfo=new Map,this._panelFavorites=null,this._showMonitoring=!1,this._updateInterval=null,this._recorderRefreshInterval=null,this._resizeObserver=null,this._lastWidth=0,this._resizeDebounce=null}get errorStore(){return this._errorStore}set errorStore(t){this._errorStore=t,this.monitoringCache.errorStore=t,this.graphSettingsCache.errorStore=t,this.monitoringMultiCache.errorStore=t}get hass(){return this._hass}set hass(t){this._hass=t}get topology(){return this._topology}get config(){return this._config}set showMonitoring(t){this._showMonitoring=t}init(t,e,n,i){this._topology=t,this._config=e,this._hass=n,this._configEntryId=i}setFavoriteRefs(t){this._favRefs=t}clearFavoriteRefs(){this._favRefs=null}setPanelFavorites(t){this._panelFavorites=t}setFavoritesPerPanelInfo(t){this._perPanelInfo=t??new Map}get _inFavoritesView(){return null!==this._favRefs}setConfig(t){this._config=t}buildHorizonMaps(t){if(this.horizonMap.clear(),this.subDeviceHorizonMap.clear(),t&&this._topology?.circuits)for(const e of Object.keys(this._topology.circuits))this.horizonMap.set(e,aT(t,e));if(t&&this._topology?.sub_devices)for(const e of Object.keys(this._topology.sub_devices))this.subDeviceHorizonMap.set(e,sT(t,e))}async fetchAndBuildHorizonMaps(){try{this._favRefs?await this._buildFavoritesHorizonMaps():(await this.graphSettingsCache.fetch(this._hass,this._configEntryId),this.buildHorizonMaps(this.graphSettingsCache.settings))}catch(t){console.warn("SPAN Panel: graph settings fetch failed",t),this.graphSettingsCache.errorStore||this._errorStore?.add({key:"fetch:graph_settings",level:"warning",message:n("error.graph_settings_failed"),persistent:!1})}}async fetchMergedMonitoringStatus(t){if(!this._hass||0===t.length)return null;const e=this._hass;return function(t){let e=!1;const n={},i={};for(const r of t)r&&(e=!0,r.circuits&&Object.assign(n,r.circuits),r.mains&&Object.assign(i,r.mains));return e?{circuits:n,mains:i}:null}(await Promise.all(t.map(t=>this.monitoringMultiCache.fetchOne(e,t))))}async _buildFavoritesHorizonMaps(){if(!this._hass||!this._favRefs||!this._topology)return;const t=new Set;for(const e of Object.values(this._favRefs))e.configEntryId&&t.add(e.configEntryId);const e=new Map;await Promise.all(Array.from(t).map(async t=>{e.set(t,await this._fetchGraphSettingsFresh(t))})),this.horizonMap.clear(),this.subDeviceHorizonMap.clear();for(const t of Object.keys(this._topology.circuits)){const n=this._favRefs[t],i=n?.configEntryId?e.get(n.configEntryId)??null:null,r=n?.targetId??t;this.horizonMap.set(t,aT(i,r))}if(this._topology.sub_devices)for(const t of Object.keys(this._topology.sub_devices)){const n=this._favRefs[t],i=n?.configEntryId?e.get(n.configEntryId)??null:null,r=n?.targetId??t;this.subDeviceHorizonMap.set(t,sT(i,r))}}async loadHistory(){await je(this._hass,this._topology,this._config,this.powerHistory,this.horizonMap,this.subDeviceHorizonMap)}recordSamples(){if(!this._topology||!this._hass||!this._config)return;const t=Date.now();for(const[e,n]of Object.entries(this._topology.circuits)){const i=this.horizonMap.get(e)??o;if(!a[i]?.useRealtime)continue;const r=_e(n,this._config);if(!r)continue;const s=this._hass.states[r];if(!s)continue;const l=parseFloat(s.state);if(isNaN(l))continue;const c=He(i),d=Fe(c),u=Be(c),h=t-c,p=this.powerHistory.get(e)??[];p.length>0&&t-p[p.length-1].time0&&t-p[p.length-1].time0&&this._topology)for(const{key:t,devId:e}of qe(this._topology))i.has(e)&&r.add(t);const o=new Map;try{await je(this._hass,this._topology,this._config,o,e,i);for(const t of e.keys()){const e=o.get(t);e?this.powerHistory.set(t,e):this.powerHistory.delete(t)}for(const t of r){const e=o.get(t);e?this.powerHistory.set(t,e):this.powerHistory.delete(t)}this.updateDOM(t)}catch(t){console.warn("SPAN Panel: history refresh failed",t),this._errorStore?.add({key:"fetch:history",level:"warning",message:n("error.history_failed"),persistent:!1})}}updateDOM(t){this._hass&&this._topology&&this._config&&(rT(t,this._hass,this._topology,this._config,this.powerHistory,this.horizonMap),function(t,e,n,i,r,o){if(!n.sub_devices)return;const a=Re(i);for(const[i,s]of Object.entries(n.sub_devices)){const n=t.querySelector(`[data-subdev="${nT(i)}"]`);if(!n)continue;const l=Pe(s);if(l){const t=e.states[l],i=t&&parseFloat(t.state)||0,r=n.querySelector(".sub-power-value");r&&(r.innerHTML=`${pe(i)} ${he(i)} `)}const c=n.querySelectorAll("[data-chart-key]");for(const t of c){const e=t.dataset.chartKey;if(!e)continue;const n=r.get(e)||[];let s=g.power;e.endsWith("_soc")?s=g.soc:e.endsWith("_soe")&&(s=g.soe);const l=!!t.closest(".bess-chart-col");eT(t,0,n,o?.has(i)?He(o.get(i)):a,s,!1,l?120:150,void 0,e.endsWith("_soc")||e.endsWith("_soe"))}for(const t of Object.keys(s.entities||{})){const i=n.querySelector(`[data-eid="${nT(t)}"]`);if(!i)continue;const r=e.states[t];if(r){let t;if(e.formatEntityState)t=e.formatEntityState(r);else{t=r.state;const e=r.attributes.unit_of_measurement||"";e&&(t+=" "+e)}if("Wh"===(r.attributes.unit_of_measurement||"")){const e=parseFloat(r.state);isNaN(e)||(t=(e/1e3).toFixed(1)+" kWh")}i.textContent=t}}}}(t,this._hass,this._topology,this._config,this.powerHistory,this.subDeviceHorizonMap))}async onGraphSettingsChanged(t){if(this._hass){this._favRefs?await this._buildFavoritesHorizonMaps():(this.graphSettingsCache.invalidate(),await this.graphSettingsCache.fetch(this._hass,this._configEntryId),this.buildHorizonMaps(this.graphSettingsCache.settings)),this.powerHistory.clear();try{await this.loadHistory()}catch{}this.updateDOM(t)}}onToggleClick(t,e){const i=t.target,r=i?.closest(".toggle-pill");if(!r)return;const o=e.querySelector(".slide-confirm");if(!o||!o.classList.contains("confirmed"))return;t.stopPropagation(),t.preventDefault();const a=r.closest("[data-uuid]");if(!a||!this._topology||!this._hass)return;const s=a.dataset.uuid;if(!s)return;const l=this._topology.circuits[s];if(!l)return;const c=l.entities?.switch;if(!c)return;const d=this._hass.states[c];if(!d)return void console.warn("SPAN Panel: switch entity not found:",c);const u="on"===d.state?"turn_off":"turn_on";this._hass.callService("switch",u,{},{entity_id:c}).catch(t=>{console.warn("SPAN Panel: switch service call failed",t),this._errorStore?.add({key:"service:relay",level:"error",message:n("error.relay_failed"),persistent:!1})})}async onGearClick(t,e){const n=t.target,i=n?.closest(".gear-icon");if(!i)return;const r=e.querySelector("span-side-panel");if(!r||!this._hass)return;if(r.hass=this._hass,r.errorStore=this.errorStore,i.classList.contains("panel-gear")){if(this._inFavoritesView){const t=await this._buildFavoritesSections();if(0===t.length)return;return void r.open({favoritesMode:!0,perPanelSections:t})}return await this.graphSettingsCache.fetch(this._hass,this._configEntryId),void r.open({panelMode:!0,topology:this._topology,graphSettings:this.graphSettingsCache.settings,showFavorites:null!==this._panelFavorites,favoritePanelDeviceId:this._panelFavorites?.panelDeviceId,favoriteCircuitUuids:this._panelFavorites?.circuitUuids,favoriteSubDeviceIds:this._panelFavorites?.subDeviceIds,configEntryId:this._configEntryId})}const a=i.dataset.uuid;if(a&&this._topology){const t=this._topology.circuits[a];if(t){const e=this._favRefs?.[a]??null,n=e&&"circuit"===e.kind?e.targetId:a,i=e?.configEntryId??this._configEntryId;let s,l;e?[s,l]=await Promise.all([this._fetchGraphSettingsFresh(i),this._fetchMonitoringStatusFresh(i)]):(await Promise.all([this.graphSettingsCache.fetch(this._hass,i),this.monitoringCache.fetch(this._hass,i)]),s=this.graphSettingsCache.settings,l=this.monitoringCache.status);const c=t.entities?.current??t.entities?.power,d=c?l?.circuits?.[c]??null:null,u=s?.global_horizon??o,h=s?.circuits?.[n],p=h?{...h,globalHorizon:u}:{horizon:u,has_override:!1,globalHorizon:u},f=e?.panelDeviceId??this._panelFavorites?.panelDeviceId,g=null!==e||(this._panelFavorites?.circuitUuids.has(n)??!1),v=this._inFavoritesView||null!==this._panelFavorites;return void r.open({...t,uuid:n,monitoringInfo:d,showMonitoring:this._showMonitoring,graphHorizonInfo:p,showFavorites:v,favoritePanelDeviceId:f,isFavorite:g,configEntryId:i})}}const s=i.dataset.subdevId;if(s&&this._topology?.sub_devices?.[s]){const t=this._topology.sub_devices[s],e=this._favRefs?.[s]??null,n=e&&"sub_device"===e.kind?e.targetId:s,i=e?.configEntryId??this._configEntryId;let a;e?a=await this._fetchGraphSettingsFresh(i):(await this.graphSettingsCache.fetch(this._hass,i),a=this.graphSettingsCache.settings);const l=a?.global_horizon??o,c=a?.sub_devices?.[n],d=c?{...c,globalHorizon:l}:{horizon:l,has_override:!1,globalHorizon:l},u=e?.panelDeviceId??this._panelFavorites?.panelDeviceId,h=null!==e||(this._panelFavorites?.subDeviceIds.has(n)??!1),p=this._inFavoritesView||null!==this._panelFavorites;r.open({subDeviceMode:!0,subDeviceId:n,name:t.name??n,deviceType:t.type??"",entities:t.entities,graphHorizonInfo:d,showFavorites:p,favoritePanelDeviceId:u,isFavorite:h,configEntryId:i})}}async _buildFavoritesSections(){if(!this._hass||!this._favRefs)return[];const t=function(t,e){const n=new Map;for(const i of Object.values(t)){if("circuit"!==i.kind)continue;const t=e.get(i.panelDeviceId);if(void 0===t)continue;let r=n.get(i.panelDeviceId);void 0===r&&(r={panelDeviceId:i.panelDeviceId,panelName:t.panelName,topology:t.topology,configEntryId:t.configEntryId,favoriteCircuitUuids:new Set},n.set(i.panelDeviceId,r)),r.favoriteCircuitUuids.add(i.targetId)}return Array.from(n.values()).sort((t,e)=>t.panelName.localeCompare(e.panelName))}(this._favRefs,this._perPanelInfo);if(0===t.length)return[];return await Promise.all(t.map(async t=>({panelDeviceId:t.panelDeviceId,panelName:t.panelName,topology:t.topology,graphSettings:await this._fetchGraphSettingsFresh(t.configEntryId),favoriteCircuitUuids:t.favoriteCircuitUuids,configEntryId:t.configEntryId})))}async _fetchGraphSettingsFresh(t){if(!this._hass)return null;try{const e={};t&&(e.config_entry_id=t);const i={type:"call_service",domain:s,service:"get_graph_settings",service_data:e,return_response:!0},r=this._errorStore?new qt(this._errorStore):null,o=r?await r.callWS(this._hass,i,{errorId:"fetch:graph_settings",errorMessage:n("error.graph_settings_failed")}):await this._hass.callWS(i);return o?.response??null}catch(t){return console.warn("SPAN Panel: fresh graph settings fetch failed",t),null}}async _fetchMonitoringStatusFresh(t){if(!this._hass)return null;try{const e={};t&&(e.config_entry_id=t);const i={type:"call_service",domain:s,service:"get_monitoring_status",service_data:e,return_response:!0},r=this._errorStore?new qt(this._errorStore):null,o=r?await r.callWS(this._hass,i,{errorId:"fetch:monitoring",errorMessage:n("error.monitoring_failed")}):await this._hass.callWS(i),a=o?.response;return a?{circuits:a.circuits,mains:a.mains}:null}catch(t){return console.warn("SPAN Panel: fresh monitoring status fetch failed",t),null}}bindSlideConfirm(t,e){const n=t.querySelector(".slide-confirm-knob"),i=t.querySelector(".slide-confirm-text");if(!n||!i)return;let r=!1,o=0,a=0;const s=e=>{t.classList.contains("confirmed")||(r=!0,o=e-n.offsetLeft,a=t.offsetWidth-n.offsetWidth-4,n.classList.remove("snapping"))},l=t=>{if(!r)return;const e=Math.max(2,Math.min(t-o,a));n.style.left=e+"px"},c=()=>{if(!r)return;r=!1;(n.offsetLeft-2)/a>=.9?(n.style.left=a+"px",t.classList.add("confirmed"),n.querySelector("span-icon")?.setAttribute("icon","mdi:lock-open"),i.textContent=t.dataset.textOn??"",e&&e.classList.remove("switches-disabled")):(n.classList.add("snapping"),n.style.left="2px")};n.addEventListener("mousedown",t=>{t.preventDefault(),s(t.clientX)}),t.addEventListener("mousemove",t=>l(t.clientX)),t.addEventListener("mouseup",c),t.addEventListener("mouseleave",c),n.addEventListener("touchstart",t=>{t.preventDefault(),s(t.touches[0].clientX)},{passive:!1}),t.addEventListener("touchmove",t=>l(t.touches[0].clientX),{passive:!0}),t.addEventListener("touchend",c),t.addEventListener("touchcancel",c),t.addEventListener("click",()=>{t.classList.contains("confirmed")&&(t.classList.remove("confirmed"),n.classList.add("snapping"),n.style.left="2px",n.querySelector("span-icon")?.setAttribute("icon","mdi:lock"),i.textContent=t.dataset.textOff??"",e&&e.classList.add("switches-disabled"))})}startIntervals(t,e){this._updateInterval=setInterval(()=>{this.recordSamples(),this.updateDOM(t),e&&e()},1e3),this._recorderRefreshInterval=setInterval(()=>{this.refreshRecorderData(t)},3e4)}stopIntervals(){this._updateInterval&&(clearInterval(this._updateInterval),this._updateInterval=null),this._recorderRefreshInterval&&(clearInterval(this._recorderRefreshInterval),this._recorderRefreshInterval=null),this.cleanupResizeObserver()}setupResizeObserver(t,e){this.cleanupResizeObserver(),e&&(this._lastWidth=e.clientWidth,this._resizeObserver=new ResizeObserver(e=>{const n=e[0];if(!n)return;const i=n.contentRect.width;Math.abs(i-this._lastWidth)<5||(this._lastWidth=i,this._resizeDebounce&&clearTimeout(this._resizeDebounce),this._resizeDebounce=setTimeout(()=>{for(const e of t.querySelectorAll(".chart-container")){const t=e.querySelector("span-chart");t&&t.remove()}this.updateDOM(t)},150))}),this._resizeObserver.observe(e))}cleanupResizeObserver(){this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),this._resizeDebounce&&(clearTimeout(this._resizeDebounce),this._resizeDebounce=null)}reset(){this.powerHistory.clear(),this.horizonMap.clear(),this.subDeviceHorizonMap.clear(),this.monitoringCache.clear(),this.monitoringMultiCache.clear(),this.graphSettingsCache.clear()}}function cT(t,e){const n=e.hysteresisPx??48,i=new WeakSet;let r=null;const o=t=>{const n=t.querySelector(e.nameSelector);return!!n&&(0!==t.clientWidth&&(n.clientWidth<1||n.scrollWidth>n.clientWidth+1))},a=()=>{const i=t.querySelectorAll(e.rowSelector);if(0===i.length)return;const a=i[0].clientWidth;if(0===a)return;if(null!==r){if(a>r+n){for(const t of i)t.classList.remove(e.foldClass);r=null}else for(const t of i)t.classList.add(e.foldClass);return}let s=!1;for(const t of i)if(o(t)){s=!0;break}if(s){for(const t of i)t.classList.add(e.foldClass);r=a}},s=new ResizeObserver(()=>a()),l=()=>{const n=t.querySelectorAll(e.rowSelector);for(const t of n)i.has(t)||(i.add(t),s.observe(t));requestAnimationFrame(()=>a())};l();const c=new MutationObserver(t=>{(t=>{const n=t=>{for(const n of t)if(n instanceof Element){if(n.matches(e.rowSelector))return!0;if(n.querySelector(e.rowSelector))return!0}return!1};for(const e of t)if(n(e.addedNodes)||n(e.removedNodes))return!0;return!1})(t)&&l()});return c.observe(t,{childList:!0,subtree:!0}),()=>{s.disconnect(),c.disconnect()}}const dT='\n :host {\n --span-accent: var(--primary-color, #4dd9af);\n }\n\n /* Card shell — replaces . Theme variables (--ha-card-*) are\n stable HA contracts (not the deprecated component APIs flagged by the\n 2026.4 frontend blog), so they stay in place to keep visual parity\n with the rest of HA\'s dashboards. */\n .span-card {\n display: block;\n padding: 24px;\n background: var(--card-background-color, #1c1c1c);\n color: var(--primary-text-color, #e0e0e0);\n border-radius: var(--ha-card-border-radius, 12px);\n border: var(--ha-card-border-width, 1px) solid var(--ha-card-border-color, var(--divider-color, #333));\n box-shadow: var(--ha-card-box-shadow, none);\n }\n\n .panel-header {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-between;\n align-items: flex-start;\n gap: 8px 16px;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--divider-color, #333);\n }\n .header-left { flex: 1 1 300px; min-width: 0; }\n .header-center { flex: 0 0 auto; }\n .header-right { flex: 0 1 auto; min-width: 0; }\n\n .panel-identity {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px 12px;\n margin-bottom: 12px;\n }\n\n .panel-title {\n font-size: 1.8em;\n font-weight: 700;\n margin: 0;\n color: var(--primary-text-color, #fff);\n }\n\n .panel-serial {\n font-size: 0.85em;\n color: var(--secondary-text-color, #999);\n font-family: monospace;\n }\n\n .panel-stats {\n display: flex;\n flex-wrap: wrap;\n gap: 16px 32px;\n }\n\n /* Favorites view header: gear + slide-to-arm + right-anchored legend/W-A cluster. */\n .favorites-summary {\n padding: 8px 24px;\n border-bottom: 1px solid var(--divider-color, #e0e0e0);\n display: flex;\n align-items: center;\n gap: 12px;\n }\n /* Override the generic .gear-icon { margin-left: auto } rule so the\n favorites gear stays flush-left instead of floating to the right of\n the flex row (same idea as .panel-identity .panel-gear does for\n real-panel headers). */\n .favorites-summary .favorites-gear {\n margin-left: 0;\n }\n /* Right-anchored cluster wrapping the shedding legend + W/A unit toggle.\n margin-left:auto moved here from .favorites-summary-unit-toggle so the\n legend and toggle cluster together, matching the real-panel header\n layout. */\n .favorites-summary-right {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 16px;\n }\n .favorites-subdevices-section {\n padding: 8px 16px 0;\n }\n\n /* Favorites view: responsive grid of per-contributing-panel status cards. */\n .favorites-panel-stats-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));\n gap: 12px;\n padding: 12px 24px;\n border-bottom: 1px solid var(--divider-color, #333);\n }\n .favorites-panel-card {\n background: var(--secondary-background-color, rgba(255, 255, 255, 0.04));\n border: 1px solid var(--divider-color, #333);\n border-radius: 8px;\n padding: 10px 14px;\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n .favorites-panel-card-title {\n font-size: 0.85em;\n font-weight: 600;\n color: var(--primary-text-color);\n opacity: 0.85;\n }\n .favorites-panel-card .panel-stats {\n gap: 10px 20px;\n }\n .favorites-panel-card .stat-value {\n font-size: 1.15em;\n }\n\n .stat { display: flex; flex-direction: column; }\n .stat-label { font-size: 0.8em; color: var(--secondary-text-color, #999); margin-bottom: 2px; }\n .stat-row { display: flex; align-items: baseline; gap: 2px; }\n .stat-value { font-size: 1.5em; font-weight: 700; color: var(--primary-text-color, #fff); }\n .stat-unit { font-size: 0.7em; font-weight: 400; color: var(--secondary-text-color, #999); }\n\n .header-right { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; padding-top: 8px; }\n .header-right-top { display: flex; gap: 20px; align-items: center; }\n .meta-item { font-size: 0.8em; color: var(--secondary-text-color, #999); }\n\n .shedding-legend { display: flex; gap: 12px; flex-wrap: wrap; justify-content: flex-end; }\n .shedding-legend-item { display: inline-flex; align-items: center; gap: 3px; }\n .shedding-legend-item span-icon { --mdc-icon-size: 16px; }\n .shedding-legend-secondary { --mdc-icon-size: 12px; opacity: 0.8; }\n .shedding-legend-text { font-size: 9px; font-weight: 600; }\n .shedding-legend-label { font-size: 0.7em; color: var(--secondary-text-color, #999); }\n\n .panel-gear {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--secondary-text-color);\n opacity: 0.6;\n padding: 4px;\n margin-left: 8px;\n vertical-align: middle;\n }\n .panel-gear:hover { opacity: 1; }\n .header-center {\n display: flex;\n align-items: flex-start;\n justify-content: center;\n padding-top: 8px;\n }\n .panel-identity .panel-gear {\n margin-left: 0;\n }\n .slide-confirm {\n position: relative;\n display: inline-flex;\n align-items: center;\n width: 160px;\n height: 28px;\n border-radius: 14px;\n background: color-mix(in srgb, var(--primary-color, #4dd9af) 20%, var(--secondary-background-color, #333));\n vertical-align: middle;\n overflow: hidden;\n user-select: none;\n touch-action: none;\n }\n .slide-confirm-text {\n position: absolute;\n width: 100%;\n text-align: center;\n font-size: 0.65em;\n font-weight: 600;\n color: var(--secondary-text-color, #999);\n pointer-events: none;\n z-index: 0;\n }\n .slide-confirm-knob {\n position: absolute;\n left: 2px;\n top: 2px;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background: var(--secondary-text-color, #666);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: grab;\n z-index: 1;\n transition: none;\n }\n .slide-confirm-knob span-icon {\n --mdc-icon-size: 14px;\n color: var(--card-background-color, #1c1c1c);\n }\n .slide-confirm-knob.snapping {\n transition: left 0.25s ease;\n }\n .slide-confirm.confirmed {\n background: color-mix(in srgb, var(--state-active-color, var(--span-accent)) 25%, transparent);\n }\n .slide-confirm.confirmed .slide-confirm-text {\n color: var(--state-active-color, var(--span-accent));\n }\n .slide-confirm.confirmed .slide-confirm-knob {\n background: var(--state-active-color, var(--span-accent));\n }\n .switches-disabled .toggle-pill {\n opacity: 0.3;\n pointer-events: none;\n }\n .unit-toggle {\n display: inline-flex;\n background: var(--secondary-background-color, #333);\n border-radius: 6px;\n overflow: hidden;\n margin-left: 8px;\n }\n .unit-btn {\n padding: 4px 10px;\n border: none;\n background: none;\n color: var(--secondary-text-color);\n font-size: 0.75em;\n font-weight: 600;\n cursor: pointer;\n }\n .unit-btn.unit-active {\n background: var(--primary-color, #4dd9af);\n color: var(--text-primary-color, #000);\n }\n\n .monitoring-summary {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 6px 16px;\n font-size: 0.8em;\n background: rgba(76, 175, 80, 0.1);\n border: 1px solid var(--divider-color, #333);\n border-top: none;\n }\n .monitoring-active { color: #4caf50; }\n .monitoring-counts { display: flex; gap: 12px; }\n .count-warning { color: #ff9800; }\n .count-alert { color: #f44336; }\n .count-overrides { color: var(--secondary-text-color); }\n\n .panel-grid {\n display: grid;\n /* Five columns: left tab label, left cell, explicit 8px spacer,\n right cell, right tab label. Spacer is in-band rather than a\n column-gap so we can keep inter-cell space without paying an\n equal gap between each cell and its tab label. The tab columns\n are sized to fit a 2-digit breaker number (the font is 0.85em\n of the panel body ≈ 14px glyph width). */\n grid-template-columns: 14px 1fr 8px 1fr 14px;\n column-gap: 0;\n row-gap: 8px;\n align-items: stretch;\n }\n\n .tab-label {\n display: flex;\n align-items: center;\n font-size: 0.85em;\n font-weight: 600;\n color: var(--secondary-text-color, #999);\n user-select: none;\n }\n .tab-left { justify-content: flex-start; }\n .tab-right { justify-content: flex-end; }\n\n .circuit-slot {\n background: var(--secondary-background-color, var(--card-background-color, #2a2a2a));\n border: 1px solid var(--divider-color, #333);\n border-radius: 12px;\n padding: 14px 16px 20px;\n min-height: 140px;\n transition: opacity 0.3s;\n position: relative;\n overflow: hidden;\n }\n\n .circuit-col-span { min-height: 280px; }\n .circuit-row-span { border-left: 3px solid var(--span-accent); }\n .circuit-off .circuit-name,\n .circuit-off .breaker-badge,\n .circuit-off .power-value,\n .circuit-off .chart-container { opacity: 0.35; }\n .circuit-off .toggle-pill,\n .circuit-off .gear-icon { opacity: 1; }\n\n .circuit-empty {\n opacity: 0.2;\n min-height: 60px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-style: dashed;\n }\n .empty-label { color: var(--secondary-text-color, #999); font-size: 0.85em; }\n\n .circuit-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 6px;\n gap: 8px;\n }\n\n .circuit-info { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }\n\n .breaker-badge {\n background: color-mix(in srgb, var(--span-accent) 15%, transparent);\n color: var(--span-accent);\n font-size: 0.7em;\n font-weight: 700;\n padding: 2px 3px;\n border-radius: 4px;\n white-space: nowrap;\n border: 1px solid color-mix(in srgb, var(--span-accent) 25%, transparent);\n flex-shrink: 0;\n }\n\n .circuit-name {\n font-size: 0.9em;\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--primary-text-color, #e0e0e0);\n }\n\n .circuit-controls { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }\n\n /* Truncation-driven fold for By Panel breaker cells. The .is-folded\n class is added/removed by the JS observer in\n src/core/truncation-fold.ts when the .circuit-name actually\n ellipsizes. Pixel thresholds can\'t get this right because name\n length varies wildly per circuit (e.g. "Spa" vs\n "Commissioned PV System") — only measuring the live name vs its\n container catches the exact moment of truncation.\n\n When folded the nested flex wrappers (.circuit-header,\n .circuit-info, .circuit-controls, .circuit-status) collapse via\n \'display: contents\' so the leaf elements participate directly in\n the outer grid: name gets the whole first row, readings/controls/\n gear drop to a second row, chart stays as the full-width third. */\n .circuit-slot.is-folded {\n display: grid;\n /* Columns: badges + relay-toggle pack tight on the left, slack\n absorbed by the 1fr column between the relay and the power\n reading, keeping power + gear pinned to the right edge. The\n previous layout placed the slack between the shedding icon and\n the relay, which read as wasted padding the user pointed out. */\n grid-template-columns: auto auto auto auto 1fr auto auto;\n /* Rows: name and controls sized to content; chart absorbs any\n extra cell height. Without the explicit 1fr on row 3, a tall\n cell (e.g. .circuit-col-span\'s 280px min-height for 240V\n double-pole breakers) distributes excess space equally across\n all three rows via the default align-content:stretch, which\n pushes the chart down and vertically inflates the badge and\n relay toggle to fill the controls row. */\n grid-template-rows: auto auto 1fr;\n grid-template-areas:\n "name name name name name name name"\n "badge util shed status . power gear"\n "chart chart chart chart chart chart chart";\n row-gap: 6px;\n column-gap: 8px;\n }\n .circuit-slot.is-folded > .circuit-header,\n .circuit-slot.is-folded > .circuit-status,\n .circuit-slot.is-folded > .circuit-header > .circuit-info,\n .circuit-slot.is-folded > .circuit-header > .circuit-controls {\n display: contents;\n }\n .circuit-slot.is-folded .circuit-name {\n grid-area: name;\n justify-self: start;\n }\n .circuit-slot.is-folded .breaker-badge {\n grid-area: badge;\n }\n .circuit-slot.is-folded .utilization {\n grid-area: util;\n }\n .circuit-slot.is-folded .shedding-icon,\n .circuit-slot.is-folded .shedding-composite {\n grid-area: shed;\n }\n .circuit-slot.is-folded .toggle-pill {\n grid-area: status;\n justify-self: end;\n }\n .circuit-slot.is-folded .power-value {\n grid-area: power;\n justify-self: end;\n }\n .circuit-slot.is-folded .gear-icon.circuit-gear {\n grid-area: gear;\n justify-self: end;\n }\n .circuit-slot.is-folded > .chart-container {\n grid-area: chart;\n }\n\n .power-value { font-size: 0.9em; color: var(--primary-text-color, #fff); white-space: nowrap; }\n .power-value strong { font-weight: 700; font-size: 1.1em; }\n .power-unit { font-size: 0.8em; font-weight: 400; color: var(--secondary-text-color, #999); margin-left: 1px; }\n .circuit-producer .power-value strong { color: var(--info-color, #4fc3f7); }\n\n .toggle-pill {\n display: flex;\n align-items: center;\n gap: 3px;\n padding: 2px 4px;\n border-radius: 10px;\n cursor: pointer;\n font-size: 0.65em;\n font-weight: 600;\n transition: background 0.2s;\n user-select: none;\n min-width: 40px;\n }\n .toggle-on {\n padding-left: 6px;\n background: color-mix(in srgb, var(--state-active-color, var(--span-accent)) 25%, transparent);\n color: var(--state-active-color, var(--span-accent));\n }\n .toggle-off {\n padding-right: 6px;\n background: color-mix(in srgb, var(--secondary-text-color) 15%, transparent);\n color: var(--secondary-text-color, #999);\n }\n .toggle-knob {\n width: 14px;\n height: 14px;\n border-radius: 50%;\n transition: background 0.2s, margin 0.2s;\n }\n .toggle-on .toggle-knob {\n background: var(--state-active-color, var(--span-accent));\n margin-left: auto;\n }\n .toggle-off .toggle-knob {\n background: var(--secondary-text-color, #999);\n margin-right: auto;\n order: -1;\n }\n\n .circuit-status {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-top: 4px;\n padding: 0 4px;\n }\n .shedding-icon { opacity: 0.8; cursor: default; }\n .shedding-composite {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n }\n .shedding-icon-secondary { opacity: 0.8; }\n .shedding-label {\n font-size: 10px;\n font-weight: 600;\n opacity: 0.8;\n }\n .gear-icon {\n background: none;\n border: none;\n cursor: pointer;\n padding: 2px;\n opacity: 0.6;\n transition: opacity 0.2s;\n margin-left: auto;\n }\n .gear-icon:hover { opacity: 1; }\n .utilization {\n font-size: 0.75em;\n font-weight: 600;\n }\n .utilization-normal { color: #4caf50; }\n .utilization-warning { color: #ff9800; }\n .utilization-alert { color: #f44336; }\n .circuit-alert {\n border-color: #f44336 !important;\n box-shadow: 0 0 8px rgba(244, 67, 54, 0.3);\n }\n .chart-container {\n width: 100%;\n aspect-ratio: 4 / 1;\n margin-top: 4px;\n overflow: hidden;\n min-width: 0;\n }\n\n .sub-devices {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 12px;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--divider-color, #333);\n }\n\n .sub-device {\n background: var(--secondary-background-color, var(--card-background-color, #2a2a2a));\n border: 1px solid var(--divider-color, #333);\n border-radius: 12px;\n padding: 14px 16px;\n }\n .sub-device-bess,\n .sub-device-full {\n grid-column: 1 / -1;\n }\n\n .sub-device-header { display: flex; gap: 10px; align-items: baseline; margin-bottom: 8px; }\n .sub-device-type { font-size: 0.7em; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--span-accent); }\n .sub-device-name { font-size: 0.85em; color: var(--secondary-text-color, #999); flex: 1; }\n .sub-power-value { font-size: 0.9em; color: var(--primary-text-color, #fff); white-space: nowrap; }\n .sub-power-value strong { font-weight: 700; font-size: 1.1em; }\n .sub-device .chart-container { margin-bottom: 8px; aspect-ratio: auto; }\n\n .bess-charts {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(0, 1fr));\n gap: 12px;\n margin-bottom: 10px;\n }\n .bess-chart-col { min-width: 0; }\n .bess-chart-title {\n font-size: 0.75em;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--secondary-text-color, #999);\n margin-bottom: 4px;\n }\n .bess-chart-col .chart-container { aspect-ratio: auto; }\n .sub-entity { display: flex; gap: 6px; padding: 3px 0; font-size: 0.85em; }\n .sub-entity-name { color: var(--secondary-text-color, #999); }\n .sub-entity-value { font-weight: 500; color: var(--primary-text-color, #e0e0e0); }\n\n /* ── Shared tab bar ────────────────────────────────────── */\n\n .shared-tab-bar {\n display: flex;\n gap: 0;\n margin-bottom: 16px;\n border-bottom: 1px solid var(--divider-color, #333);\n }\n\n .shared-tab {\n padding: 8px 16px;\n cursor: pointer;\n font-size: 0.9em;\n font-weight: 500;\n color: var(--primary-text-color);\n opacity: 0.6;\n border: none;\n border-bottom: 2px solid transparent;\n background: none;\n transition: opacity 0.15s;\n }\n\n .shared-tab:hover {\n opacity: 0.85;\n }\n\n .shared-tab.active {\n opacity: 1;\n border-bottom-color: var(--span-accent);\n }\n\n /* ── List view search ──────────────────────────────────── */\n\n .list-search-container {\n margin-bottom: 12px;\n position: relative;\n }\n\n .list-search {\n width: 100%;\n padding: 8px 36px 8px 12px;\n border-radius: 8px;\n border: 1px solid var(--divider-color, #333);\n background: var(--secondary-background-color, #2a2a2a);\n color: var(--primary-text-color);\n font-size: 0.9em;\n box-sizing: border-box;\n outline: none;\n }\n\n .list-search:focus {\n border-color: var(--span-accent);\n }\n\n .list-search-clear {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n background: none;\n border: none;\n color: var(--secondary-text-color);\n cursor: pointer;\n padding: 2px;\n display: flex;\n align-items: center;\n opacity: 0.7;\n }\n\n .list-search-clear:hover {\n opacity: 1;\n }\n\n .list-unit-toggle {\n display: inline-flex;\n margin-bottom: 12px;\n }\n\n /* ── List rows ─────────────────────────────────────────── */\n\n .list-view {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n /* Each circuit is wrapped in a .list-cell so the row + its optional\n expanded chart stay together. In single-column flex mode the cell\n just stacks naturally. In multi-column grid mode the cell becomes\n one grid item, so the chart is always in the same column as its\n row. Area headers (rendered as siblings, not inside a cell) span\n all columns via their inline "grid-column: 1 / -1". */\n .list-cell {\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n .list-view[data-columns="2"],\n .list-view[data-columns="3"] {\n display: grid;\n grid-template-columns: repeat(var(--list-cols), minmax(0, 1fr));\n gap: 6px 8px;\n flex-direction: initial;\n }\n /* On narrow viewports a 2/3-column list would squeeze rows into an\n unreadable shape, so force stacking regardless of user preference. */\n @media (max-width: 599px) {\n .list-view[data-columns="2"],\n .list-view[data-columns="3"] {\n display: flex;\n flex-direction: column;\n }\n }\n\n .list-row {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n gap: 10px;\n /* min-width: 0 lets the row shrink below the sum of its\n non-shrinking children when its parent .list-cell is in a\n narrow CSS-grid track (multi-column list mode). Without this\n the row would maintain its intrinsic min-content width and\n overflow the cell, leaving the name unshrunk and the\n truncation-fold observer with no signal to react to. */\n min-width: 0;\n background: var(--card-background-color, #1c1c1c);\n border: 1px solid var(--divider-color, #333);\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.15s;\n }\n\n .list-row:hover {\n background: var(--secondary-background-color, #2a2a2a);\n }\n\n .list-row.circuit-off {\n opacity: 0.5;\n }\n\n .list-row.list-row-expanded {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n border-bottom-color: transparent;\n }\n\n .list-circuit-name {\n flex: 1;\n color: var(--primary-text-color);\n font-size: 0.9em;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .list-status-badge {\n font-size: 0.75em;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 4px;\n flex-shrink: 0;\n }\n\n .list-status-on {\n color: #4dd9af;\n }\n\n .list-status-off {\n color: #f44336;\n }\n\n .list-power-value {\n font-size: 0.9em;\n font-weight: 600;\n flex-shrink: 0;\n /* No min-width / text-align:right: the old 70px right-aligned\n cell left a visible blank column for short readings (e.g.\n "1.3A" in a 70px slot), which robbed horizontal space from\n .list-circuit-name on narrow rows. Let the value hug the\n preceding relay control and size to its content so the freed\n width flows back into the flex:1 name column. */\n }\n\n .list-expand-toggle {\n background: none;\n border: none;\n color: var(--secondary-text-color);\n cursor: pointer;\n padding: 4px;\n transition: transform 0.2s;\n display: flex;\n align-items: center;\n flex-shrink: 0;\n }\n\n .list-expand-toggle.expanded {\n transform: rotate(180deg);\n }\n\n .list-row .gear-icon {\n background: transparent;\n border: none;\n padding: 2px;\n cursor: pointer;\n color: #555;\n display: inline-flex;\n align-items: center;\n }\n .list-row .gear-icon:hover {\n color: var(--primary-text-color);\n }\n\n /* Truncation-driven fold for list rows. The .is-folded class is\n added/removed by the JS observer in src/core/truncation-fold.ts\n when the .list-circuit-name actually ellipsizes — pixel breakpoints\n can\'t track this because name length varies wildly per circuit\n ("Spa" vs "Commissioned PV System") and any single threshold\n misfires for the other end of the range. Switch to a two-row grid\n so the name gets the full width (paired only with the expand\n chevron) and the badges/controls/reading/gear drop to a secondary\n row underneath. Named areas keep the CSS readable despite the flat\n HTML child order. */\n .list-row.is-folded {\n display: grid;\n /* Row 1: name spans the row up to the chevron at the trailing\n column. Row 2: badge + util + shed + relay-toggle pack left,\n the 1fr column absorbs slack between the relay and the power\n reading, power + gear stay pinned to the right edge. The\n earlier layout placed the slack between the shedding icon and\n the relay, which the user flagged as wasted padding. */\n grid-template-columns: auto auto auto auto 1fr auto auto;\n grid-template-areas:\n "name name name name name name chevron"\n "badge util shed status . power gear";\n row-gap: 6px;\n column-gap: 8px;\n }\n .list-row.is-folded > .list-circuit-name {\n grid-area: name;\n justify-self: start;\n }\n .list-row.is-folded > .list-expand-toggle {\n grid-area: chevron;\n }\n .list-row.is-folded > .breaker-badge {\n grid-area: badge;\n }\n .list-row.is-folded > .utilization {\n grid-area: util;\n }\n .list-row.is-folded > .shedding-icon,\n .list-row.is-folded > .shedding-composite {\n grid-area: shed;\n }\n .list-row.is-folded > .toggle-pill,\n .list-row.is-folded > .list-status-badge {\n grid-area: status;\n }\n .list-row.is-folded > .list-power-value {\n grid-area: power;\n justify-self: end;\n }\n .list-row.is-folded > .gear-icon.circuit-gear {\n grid-area: gear;\n justify-self: end;\n }\n\n /* ── Expanded circuit content ──────────────────────────── */\n\n .list-expanded-content {\n padding: 0;\n background: var(--card-background-color, #1c1c1c);\n border: 1px solid var(--divider-color, #333);\n border-top: none;\n border-radius: 0 0 8px 8px;\n margin-top: -6px;\n margin-bottom: 2px;\n }\n\n .circuit-slot.circuit-chart-only {\n border: none;\n margin: 0;\n background: none;\n padding: 8px 12px;\n min-height: 0;\n }\n\n /* ── Area headers ──────────────────────────────────────── */\n\n .area-header {\n padding: 16px 12px 6px;\n font-weight: 600;\n font-size: 0.85em;\n color: var(--secondary-text-color);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n }\n\n /* ── No results ────────────────────────────────────────── */\n\n .list-no-results {\n padding: 24px;\n text-align: center;\n color: var(--secondary-text-color);\n }\n\n';class uT{constructor(){this._ctrl=new lT,this._container=null,this._onGearClick=null,this._onToggleClick=null,this._onSidePanelClosed=null,this._onGraphSettingsChanged=null,this._foldUnobserve=null}get hass(){return this._ctrl.hass}set hass(t){this._ctrl.hass=t}set errorStore(t){this._ctrl.errorStore=t}setPanelFavorites(t){this._ctrl.setPanelFavorites(t)}async render(t,e,i,r,o){let a,s;this.stop(),this._ctrl.reset(),this._ctrl.showMonitoring=!0,this._container=t,this._ctrl.hass=e;try{const t=await se(e,i);a=t.topology,s=t.panelSize}catch(e){return void(t.innerHTML=`${Bt(e.message)}
`)}this._ctrl.init(a,r,e,o??null),await this._ctrl.monitoringCache.fetch(e,o??null),await this._ctrl.fetchAndBuildHorizonMaps();const l=Math.ceil(s/2),c=this._ctrl.monitoringCache.status,d=de(a,r),u=function(t){if(!t)return"";const e=Object.values(t.circuits??{}),i=Object.values(t.mains??{}),r=[...e,...i],o=r.filter(t=>void 0!==t.utilization_pct&&t.utilization_pct>=80&&t.utilization_pct<100).length,a=r.filter(t=>void 0!==t.utilization_pct&&t.utilization_pct>=100).length,s=r.filter(t=>t.has_override).length;return`\n \n ✓ ${n("status.monitoring")} · ${e.length} ${n("status.circuits")} · ${i.length} ${n("status.mains")} \n \n ${o>0?`${o} ${n(o>1?"status.warnings":"status.warning")} `:""}\n ${a>0?`${a} ${n(a>1?"status.alerts":"status.alert")} `:""}\n ${s>0?`${s} ${n(s>1?"status.overrides":"status.override")} `:""}\n \n
\n `}(c),h=function(t,e,n,i,r){const o=new Map,a=new Set;for(const[e,n]of Object.entries(t.circuits)){const t=n.tabs;if(!t||0===t.length)continue;const i=Math.min(...t),r=1===t.length?"single":me(t)??"single";o.set(i,{uuid:e,circuit:n,layout:r});for(const e of t)a.add(e)}const s=new Set,l=new Set;for(const[t,e]of o)if("col-span"===e.layout){const n=e.circuit.tabs,i=ge(Math.max(...n));0===ve(t)?s.add(i):l.add(i)}function c(t){const e=t.circuit.entities?.current??t.circuit.entities?.power,i=r?we(r,e??""):null;let o;if(t.circuit.always_on)o="always_on";else{const e=t.circuit.entities?.select;o=e&&n.states[e]?n.states[e].state:"unknown"}return{monInfo:i,sheddingPriority:o}}let d="";for(let t=1;t<=e;t++){const e=2*t-1,r=2*t,u=o.get(e),h=o.get(r);if(d+=`${e}
`,u&&"row-span"===u.layout){const{monInfo:e,sheddingPriority:o}=c(u);d+=Ce(u.uuid,u.circuit,t,"2 / 5","row-span",n,i,e,o),d+=`${r}
`;continue}if(!s.has(t))if(!u||"col-span"!==u.layout&&"single"!==u.layout)a.has(e)||(d+=ke(t,"2"));else{const{monInfo:e,sheddingPriority:r}=c(u);d+=Ce(u.uuid,u.circuit,t,"2",u.layout,n,i,e,r)}if(!l.has(t))if(!h||"col-span"!==h.layout&&"single"!==h.layout)a.has(r)||(d+=ke(t,"4"));else{const{monInfo:e,sheddingPriority:r}=c(h);d+=Ce(h.uuid,h.circuit,t,"4",h.layout,n,i,e,r)}d+=`${r}
`}return d}(a,l,e,r,c),p=Ne(a,e,r);t.innerHTML=`\n \n ${d}\n ${u}\n ${p?`${p}
`:""}\n ${!1!==r.show_panel?`\n \n ${h}\n
\n `:""}\n \n `,this._onGearClick=e=>{this._ctrl.onGearClick(e,t)},this._onToggleClick=e=>{this._ctrl.onToggleClick(e,t)},t.addEventListener("click",this._onGearClick),t.addEventListener("click",this._onToggleClick),this._onSidePanelClosed=()=>{this._ctrl.monitoringCache.invalidate(),this._ctrl.graphSettingsCache.invalidate()},t.addEventListener("side-panel-closed",this._onSidePanelClosed),this._onGraphSettingsChanged=()=>this._ctrl.onGraphSettingsChanged(t),t.addEventListener("graph-settings-changed",this._onGraphSettingsChanged);try{await this._ctrl.loadHistory()}catch{}this._ctrl.updateDOM(t);const f=t.querySelector(".slide-confirm");f&&(this._ctrl.bindSlideConfirm(f,t),t.classList.add("switches-disabled")),this._ctrl.setupResizeObserver(t,t),this._ctrl.startIntervals(t),this._foldUnobserve&&this._foldUnobserve(),this._foldUnobserve=cT(t,{rowSelector:".circuit-slot",nameSelector:".circuit-name",foldClass:"is-folded"})}stop(){this._ctrl.stopIntervals(),this._foldUnobserve&&(this._foldUnobserve(),this._foldUnobserve=null),this._container&&(this._onGearClick&&(this._container.removeEventListener("click",this._onGearClick),this._onGearClick=null),this._onToggleClick&&(this._container.removeEventListener("click",this._onToggleClick),this._onToggleClick=null),this._onSidePanelClosed&&(this._container.removeEventListener("side-panel-closed",this._onSidePanelClosed),this._onSidePanelClosed=null),this._onGraphSettingsChanged&&(this._container.removeEventListener("graph-settings-changed",this._onGraphSettingsChanged),this._onGraphSettingsChanged=null))}}const hT="\n display:flex;align-items:center;gap:8px;margin-bottom:8px;\n",pT="\n background:var(--secondary-background-color,#333);\n border:1px solid var(--divider-color);\n color:var(--primary-text-color);\n border-radius:4px;padding:6px 10px;width:80px;font-size:0.85em;\n",fT="\n min-width:130px;font-size:0.85em;color:var(--secondary-text-color);\n",gT="\n min-width:160px;font-size:0.85em;color:var(--secondary-text-color);\n",vT="\n background:var(--secondary-background-color,#333);\n border:1px solid var(--divider-color);\n color:var(--primary-text-color);\n border-radius:4px;padding:6px 10px;flex:1;font-size:0.85em;\n font-family:monospace;\n";function mT(t,e,n,i,r){return`\n ${i} \n `}class yT{constructor(){this.errorStore=null,this._debounceTimer=null,this._configEntryId=null,this._notifyCloseHandler=null,this._headerHTML=""}stop(){this._notifyCloseHandler&&(document.removeEventListener("click",this._notifyCloseHandler),this._notifyCloseHandler=null),this._debounceTimer&&(clearTimeout(this._debounceTimer),this._debounceTimer=null)}async render(t,e,i,r=""){let o;void 0!==i&&(this._configEntryId=i),this._headerHTML=r,this._notifyCloseHandler&&(document.removeEventListener("click",this._notifyCloseHandler),this._notifyCloseHandler=null);try{const t={};this._configEntryId&&(t.config_entry_id=this._configEntryId);const n=await e.callWS({type:"call_service",domain:s,service:"get_monitoring_status",service_data:t,return_response:!0});o=function(t){if(!t||"object"!=typeof t)return null;const e=t,n={};return"boolean"==typeof e.enabled&&(n.enabled=e.enabled),e.global_settings&&"object"==typeof e.global_settings&&(n.global_settings=e.global_settings),e.circuits&&"object"==typeof e.circuits&&(n.circuits=e.circuits),e.mains&&"object"==typeof e.mains&&(n.mains=e.mains),n}(n?.response)}catch(t){console.warn("SPAN Panel: monitoring status fetch failed",t),o=null}const a=o?.global_settings??{},l=!0===o?.enabled,c=o?.circuits??{},d=o?.mains??{},u=new Set;for(const t of Object.keys(e.states||{}))t.startsWith("notify.")&&u.add(t);const h=new Set(["notify","send_message"]);for(const t of Object.keys(e.services?.notify||{}))h.has(t)||u.add(`notify.${t}`);u.add("event_bus");const p=[...u].sort(),f=a.notify_targets??"",g=("string"==typeof f?f.split(","):f).map(t=>t.trim()).filter(Boolean),v=p.length>0&&p.every(t=>g.includes(t)),m=a.notification_title_template??"SPAN: {name} {alert_type}",y=a.notification_message_template??"{name} at {current_a}A ({utilization_pct}% of {breaker_rating_a}A rating)",_=a.notification_priority??"default",b=Object.entries(c).sort(([,t],[,e])=>(t.name??"").localeCompare(e.name??"")),x=Object.entries(d),w=[...b,...x],S=w.length>0&&w.every(([,t])=>!1!==t.monitoring_enabled),C=w.some(([,t])=>!1!==t.monitoring_enabled),k=b.map(([t,e])=>{const i=Bt(e.name??t),r=!1!==e.monitoring_enabled,o=!0===e.has_override,a=r?"":"opacity:0.4;",s=Bt(t);return`\n \n \n \n \n ${i} \n \n \n ${mT(s,"continuous_threshold_pct",e.continuous_threshold_pct,"%","circuit")}\n ${mT(s,"spike_threshold_pct",e.spike_threshold_pct,"%","circuit")}\n ${mT(s,"window_duration_m",e.window_duration_m,"m","circuit")}\n ${mT(s,"cooldown_duration_m",e.cooldown_duration_m,"m","circuit")}\n \n ${o?`\n ${n("monitoring.reset")}\n `:""}\n \n \n `}).join(""),M=Object.entries(d).map(([t,e])=>{const i=Bt(e.name??t),r=!1!==e.monitoring_enabled,o=!0===e.has_override,a=r?"":"opacity:0.4;",s=Bt(t);return`\n \n \n \n \n ${i} \n \n \n ${mT(s,"continuous_threshold_pct",e.continuous_threshold_pct,"%","mains")}\n ${mT(s,"spike_threshold_pct",e.spike_threshold_pct,"%","mains")}\n ${mT(s,"window_duration_m",e.window_duration_m,"m","mains")}\n ${mT(s,"cooldown_duration_m",e.cooldown_duration_m,"m","mains")}\n \n ${o?`\n ${n("monitoring.reset")}\n `:""}\n \n \n `}).join("");t.innerHTML=`\n ${this._headerHTML}\n \n
${n("monitoring.heading")} \n\n
\n
\n
${n("monitoring.global_settings")} \n \n \n ${n("monitoring.enabled")} \n \n \n\n
\n
\n ${n("monitoring.continuous")} \n \n
\n
\n ${n("monitoring.spike")} \n \n
\n
\n ${n("monitoring.window")} \n \n
\n
\n ${n("monitoring.cooldown")} \n \n
\n\n
\n
${n("notification.heading")} \n\n
\n
${n("notification.targets")} \n
\n \n ${n("notification.all_targets")} \n \n
\n
\n ${g.length?g.map(t=>"event_bus"===t?n("notification.event_bus_target"):Bt(t)).join(", "):n("notification.none_selected")} \n ▼ \n \n
\n ${0===p.length?`
${n("notification.no_targets")}
`:p.map(t=>{const i=g.includes(t),r="event_bus"===t,o=r?null:e.states[t],a=o?.attributes?.friendly_name,s=r?n("notification.event_bus_target"):a?`${Bt(a)} (${Bt(t)})`:Bt(t);return`
\n \n ${s} \n `}).join("")}\n
\n
\n
\n\n
\n ${n("notification.priority")} \n \n ${["default","passive","active","time-sensitive","critical"].map(t=>`${n(`notification.priority.${t.replace("-","_")}`)} `).join("")}\n \n \n ${"critical"===_?n("notification.hint.critical"):"time-sensitive"===_?n("notification.hint.time_sensitive"):"passive"===_?n("notification.hint.passive"):"active"===_?n("notification.hint.active"):""}\n \n
\n\n
\n ${n("notification.title_template")} \n \n
\n\n
\n ${n("notification.message_template")} \n \n
\n\n
\n ${n("notification.placeholders")} {name} {entity_id} {alert_type}\n {current_a} {breaker_rating_a} {threshold_pct}\n {utilization_pct} {window_m} {local_time}\n
\n
\n ${n("notification.event_bus_help")} span_panel_current_alert\n ${n("notification.event_bus_payload")} alert_source alert_id\n alert_name alert_type current_a\n breaker_rating_a threshold_pct utilization_pct\n panel_serial window_duration_s local_time\n
\n\n
\n ${n("notification.test_label")} \n \n ${n("notification.test_button")}\n \n \n
\n
\n\n
\n
\n\n
${n("monitoring.monitored_points")} \n
\n
\n `;const T=t.querySelector("#toggle-all-circuits");T&&!S&&C&&(T.indeterminate=!0);const I=t.querySelector("#notify-all-targets");if(I&&p.length>0){const t=g.length>0;!v&&t&&(I.indeterminate=!0)}this._bindGlobalControls(t,e),this._bindNotifyTargetSelect(t,e),this._bindNotificationSettings(t,e),this._bindToggleAll(t,e,c,d),this._bindCircuitToggles(t,e),this._bindMainsToggles(t,e),this._bindThresholdInputs(t,e),this._bindResetButtons(t,e)}_serviceData(t){return this._configEntryId&&(t.config_entry_id=this._configEntryId),t}_callSetGlobal(t,e){return t.callWS({type:"call_service",domain:s,service:"set_global_monitoring",service_data:this._serviceData({...e})})}_bindGlobalControls(t,e){const i=t.querySelector("#monitoring-enabled"),r=t.querySelector("#global-fields"),o=t.querySelector("#global-status"),a=()=>{const e=[["continuous_threshold_pct","#g-continuous"],["spike_threshold_pct","#g-spike"],["window_duration_m","#g-window"],["cooldown_duration_m","#g-cooldown"]],n={};for(const[i,r]of e){const e=t.querySelector(r);if(!e)return null;const o=parseInt(e.value,10);if(Number.isNaN(o))return null;n[i]=o}return n},s=(t,e,i)=>{if(!t)return;const r=e instanceof Error?e.message:i;t.textContent=`${n("error.prefix")} ${r}`,t.style.color="var(--error-color, #f44336)"},l=()=>{this._debounceTimer&&clearTimeout(this._debounceTimer),this._debounceTimer=setTimeout(async()=>{const i=a();if(i)try{await this._callSetGlobal(e,i),await this.render(t,e)}catch(t){s(o,t,n("error.failed_save"))}else s(o,null,n("error.failed_save"))},p)};i&&i.addEventListener("change",async()=>{const o=i.checked;r&&(r.style.opacity=o?"":"0.4",r.style.pointerEvents=o?"":"none");const l=t.querySelector("#global-status");try{if(o){const t=a();if(!t)return void s(l,null,n("error.failed"));await this._callSetGlobal(e,t)}else await this._callSetGlobal(e,{enabled:!1})}catch(t){return void s(l,t,n("error.failed"))}await this.render(t,e)});for(const e of t.querySelectorAll("#global-fields input[type=number]"))e.addEventListener("input",l)}_bindNotifyTargetSelect(t,e){const i=t.querySelector("#notify-target-btn"),r=t.querySelector("#notify-target-dropdown"),o=t.querySelector("#notify-target-label");if(!i||!r)return;i.addEventListener("click",t=>{t.stopPropagation();const e="none"!==r.style.display;r.style.display=e?"none":"block"});const a=e=>{const n=t.querySelector("#notify-target-select");n&&!n.contains(e.target)&&(r.style.display="none")};document.addEventListener("click",a),this._notifyCloseHandler=a;const s=()=>{const i=[...t.querySelectorAll(".notify-target-cb:checked")].map(t=>t.value);if(o){const t=i.map(t=>"event_bus"===t?n("notification.event_bus_target"):t);o.textContent=t.length?t.join(", "):n("notification.none_selected")}const r=t.querySelector("#notify-all-targets");if(r){const e=[...t.querySelectorAll(".notify-target-cb")];r.checked=e.length>0&&e.every(t=>t.checked),r.indeterminate=!r.checked&&e.some(t=>t.checked)}this._debounceTimer&&clearTimeout(this._debounceTimer),this._debounceTimer=setTimeout(async()=>{try{await this._callSetGlobal(e,{notify_targets:i.join(", ")})}catch(t){console.warn("SPAN Panel: notification targets save failed",t),this.errorStore?.add({key:"service:monitoring",level:"error",message:n("error.threshold_failed"),persistent:!1})}},p)},l=t.querySelector("#notify-all-targets");l&&l.addEventListener("change",()=>{for(const e of t.querySelectorAll(".notify-target-cb"))e.checked=l.checked;const e=t.querySelector("#notify-target-btn");e&&(e.style.opacity=l.checked?"0.4":"",e.style.pointerEvents=l.checked?"none":""),l.checked&&(r.style.display="none"),s()});for(const e of t.querySelectorAll(".notify-target-cb"))e.addEventListener("change",()=>{s()})}_bindNotificationSettings(t,e){const i=t.querySelector("#g-priority"),r=t.querySelector("#g-title-template"),o=t.querySelector("#g-message-template"),a=(t,i)=>{this._debounceTimer&&clearTimeout(this._debounceTimer),this._debounceTimer=setTimeout(async()=>{try{await this._callSetGlobal(e,{[t]:i})}catch(t){console.warn("SPAN Panel: notification settings save failed",t),this.errorStore?.add({key:"service:monitoring",level:"error",message:n("error.threshold_failed"),persistent:!1})}},p)};i&&i.addEventListener("change",async()=>{try{await this._callSetGlobal(e,{notification_priority:i.value}),await this.render(t,e)}catch(t){console.warn("SPAN Panel: notification priority change failed",t),this.errorStore?.add({key:"service:monitoring",level:"error",message:n("error.threshold_failed"),persistent:!1})}}),r&&r.addEventListener("input",()=>{a("notification_title_template",r.value)}),o&&o.addEventListener("input",()=>{a("notification_message_template",o.value)});const l=t.querySelector("#test-notification-btn"),c=t.querySelector("#test-notification-status");l&&l.addEventListener("click",async()=>{l.disabled=!0,c&&(c.textContent=n("notification.test_sending"),c.style.color="var(--secondary-text-color)");try{this._debounceTimer&&(clearTimeout(this._debounceTimer),this._debounceTimer=null);const i=[...t.querySelectorAll(".notify-target-cb:checked")].map(t=>t.value).join(", ");await this._callSetGlobal(e,{notify_targets:i});const r={};this._configEntryId&&(r.config_entry_id=this._configEntryId),await e.callWS({type:"call_service",domain:s,service:"test_notification",service_data:r}),c&&(c.textContent=n("notification.test_sent"),c.style.color="var(--success-color, #4caf50)")}catch(t){if(c){const e=t instanceof Error?t.message:n("error.failed");c.textContent=`${n("error.prefix")} ${e}`,c.style.color="var(--error-color, #f44336)"}}finally{l.disabled=!1}})}_bindToggleAll(t,e,i,r){const o=t.querySelector("#toggle-all-circuits");o&&o.addEventListener("change",async()=>{const a=o.checked,l=[...Object.keys(i).map(t=>e.callWS({type:"call_service",domain:s,service:"set_circuit_threshold",service_data:this._serviceData({circuit_id:t,monitoring_enabled:a})}).catch(t=>{console.warn("SPAN Panel: circuit monitoring toggle failed",t),this.errorStore?.add({key:"service:monitoring",level:"error",message:n("error.threshold_failed"),persistent:!1})})),...Object.keys(r).map(t=>e.callWS({type:"call_service",domain:s,service:"set_mains_threshold",service_data:this._serviceData({leg:t,monitoring_enabled:a})}).catch(t=>{console.warn("SPAN Panel: mains monitoring toggle failed",t),this.errorStore?.add({key:"service:monitoring",level:"error",message:n("error.threshold_failed"),persistent:!1})}))];await Promise.all(l),await this.render(t,e)})}_bindMainsToggles(t,e){for(const i of t.querySelectorAll(".mains-toggle"))i.addEventListener("change",async()=>{const r=i.dataset.entity,o=i.checked;try{await e.callWS({type:"call_service",domain:s,service:"set_mains_threshold",service_data:this._serviceData({leg:r,monitoring_enabled:o})})}catch(t){return console.warn("SPAN Panel: mains threshold toggle failed",t),this.errorStore?.add({key:"service:monitoring",level:"error",message:n("error.threshold_failed"),persistent:!1}),void(i.checked=!o)}await this.render(t,e)})}_bindCircuitToggles(t,e){for(const i of t.querySelectorAll(".circuit-toggle"))i.addEventListener("change",async()=>{const r=i.dataset.entity,o=i.checked;try{await e.callWS({type:"call_service",domain:s,service:"set_circuit_threshold",service_data:this._serviceData({circuit_id:r,monitoring_enabled:o})})}catch(t){return console.warn("SPAN Panel: circuit threshold toggle failed",t),this.errorStore?.add({key:"service:monitoring",level:"error",message:n("error.threshold_failed"),persistent:!1}),void(i.checked=!o)}await this.render(t,e)})}_bindThresholdInputs(t,e){const i=new Map;for(const r of t.querySelectorAll(".threshold-input"))r.addEventListener("input",()=>{const o=`${r.dataset.entity}-${r.dataset.field}`,a=i.get(o);a&&clearTimeout(a),i.set(o,setTimeout(async()=>{const i=parseInt(r.value,10);if(!i||i<1)return;const o=r.dataset.entity,a=r.dataset.field,l=r.dataset.type,c="mains"===l?"set_mains_threshold":"set_circuit_threshold",d="mains"===l?"leg":"circuit_id";try{await e.callWS({type:"call_service",domain:s,service:c,service_data:this._serviceData({[d]:o,[a]:i})}),await this.render(t,e)}catch(t){console.warn("SPAN Panel: threshold input save failed",t),this.errorStore?.add({key:"service:monitoring",level:"error",message:n("error.threshold_failed"),persistent:!1}),r.style.borderColor="var(--error-color, #f44336)"}},800))})}_bindResetButtons(t,e){for(const n of t.querySelectorAll(".reset-btn"))n.addEventListener("click",async()=>{const i=n.dataset.entity;if(!i)return;const r=n.dataset.type,o="mains"===r?"clear_mains_threshold":"clear_circuit_threshold",a=this._serviceData("mains"===r?{leg:i}:{circuit_id:i});await e.callService(s,o,a),await this.render(t,e)})}}function _T(t,e){return null!==t&&t.toLowerCase().includes(e)}function bT(t,e){const n=t[e];return"string"==typeof n?n:""}function xT(t,e){return{enabled:null!==e&&null===e.disabledBy,name:null===e?"":e.name,deviceClass:t.curation.device_class??"",stateClass:t.curation.state_class??"",promote:"none"===t.curation.entity_category}}function wT(t,e){const n=Number(e);return{unit_of_measurement:t||null,display_precision:""!==e&&Number.isFinite(n)?n:null}}function ST(t,e,n){return""!==t&&e.includes(t)&&n.length>0}function CT(t){if(!t)return"";const e=t.replace(/_/g," ");return e.charAt(0).toUpperCase()+e.slice(1)}const kT=["0","1","2","3","4","5","6"],MT="var(--secondary-text-color,#999)",TT="var(--primary-color,#4dd9af)",IT="var(--warning-color,#ff9800)",DT="var(--card-background-color,#1c1c1c)",AT="var(--secondary-background-color,#232323)",PT="var(--divider-color,#333)",LT=`background:${AT};border:1px solid ${PT};color:var(--primary-text-color);border-radius:4px;padding:4px 8px;font-size:0.85em;`,ET=`${LT}min-width:0;`,zT="display:flex;align-items:center;gap:12px;flex-wrap:wrap;",NT=`font-size:0.85em;color:${MT};min-width:130px;`,OT=`color:${MT};font-size:0.75em;`,$T=`background:none;border:1px solid ${PT};color:var(--primary-text-color);border-radius:6px;padding:6px 12px;font-size:0.8em;cursor:pointer;`;function RT(t,e){const n=e?TT:MT;return`${Bt(t)} `}function HT(t,e,n){const i=e.map(t=>`${Bt(t.label)} `).join("");return`${i} `}function FT(t){return"total_increasing"===t?n("adopted.warn_total_increasing"):"statistics_removed"===t?n("adopted.warn_statistics_removed"):t}function BT(t){return t instanceof Error||t&&"object"==typeof t&&"string"==typeof t.message?t.message:String(t)}class VT{constructor(){this._container=null,this._hass=null,this._deviceId=null,this._groups=[],this._loadError=null,this._query="",this._expandedKey=null,this._editor=null,this._unitsCache=new Map,this._refreshTimer=null,this._onClick=t=>{this._handleClick(t)},this._onInput=t=>{this._handleInput(t)},this._onChange=t=>{this._handleChange(t)}}stop(){this._refreshTimer&&(clearTimeout(this._refreshTimer),this._refreshTimer=null),this._unbind()}async render(t,e,n){const i=void 0===n?this._deviceId:n||null;i!==this._deviceId&&(this._deviceId=i,this._expandedKey=null,this._editor=null,this._query=""),this._unbind(),this._container=t,this._hass=e,await this._fetchList(e,!1),this._paint()}async _fetchList(t,e){if(!this._deviceId)return this._groups=[],void(this._loadError=null);try{const e=await t.callWS({type:`${s}/adopted/list`,device_id:this._deviceId});this._groups=Array.isArray(e?.devices)?e.devices:[],this._loadError=null}catch(t){if(e)return;this._groups=[],this._loadError=BT(t)}}async _fetchSeed(t,e){try{return function(t){if(!t||"object"!=typeof t)return null;const e=t;if("string"!=typeof e.entity_id)return null;const n=e.options&&"object"==typeof e.options?e.options:{},i=n.sensor&&"object"==typeof n.sensor?n.sensor:{},r=i.display_precision;return{disabledBy:"string"==typeof e.disabled_by?e.disabled_by:null,name:bT(e,"name"),unit:bT(i,"unit_of_measurement"),precision:"number"==typeof r?String(r):""}}(await t.callWS({type:"config/entity_registry/get",entity_id:e}))}catch{return null}}async _fetchUnits(t,e){if(!e)return[];const n=this._unitsCache.get(e);if(n)return n;try{const n=await t.callWS({type:"sensor/device_class_convertible_units",device_class:e}),i=Array.isArray(n?.units)?n.units.filter(t=>"string"==typeof t):[];return this._unitsCache.set(e,i),i}catch{return[]}}_findRow(t){for(const e of this._groups)for(const n of e.rows)if(n.key===t)return n;return null}_paint(){const t=this._container;t&&(t.innerHTML=`\n \n
${n("adopted.heading")} \n
${n("adopted.description")}
\n\n
\n \n \n
\n\n
${this._groupsHTML()}
\n
\n `,this._bind())}_paintGroups(){const t=this._container?.querySelector("#adopted-groups");t&&(t.innerHTML=this._groupsHTML())}_groupsHTML(){if(null!==this._loadError)return`${Bt(n("adopted.load_failed"))} — ${Bt(this._loadError)}
`;if(0===this._groups.length)return`${n("adopted.none")}
`;const t=function(t,e){const n=e.trim().toLowerCase();if(!n)return t;const i=[];for(const e of t){if(_T(e.name,n)){i.push(e);continue}const t=e.rows.filter(t=>_T(t.name,n));t.length>0&&i.push({...e,rows:t})}return i}(this._groups,this._query);return 0===t.length?`${n("adopted.no_results")}
`:t.map(t=>this._groupHTML(t)).join("")}_groupHTML(t){const e=t.adopted_device?RT(n("adopted.adopted_device"),!1):RT(n("adopted.vendor_readings"),!0),r=i("adopted.count",{count:String(t.rows.length)}),o=t.adopted_device?`${n("adopted.via_panel")} · ${r}`:r;return`\n \n ${Bt(t.name??"")} \n ${e}\n ${Bt(o)} \n
\n \n ${t.rows.map(t=>this._rowHTML(t)).join("")}\n
\n `}_rowHTML(t){const e=this._expandedKey===t.key,i=e&&this._editor?this._editorHTML(t,this._editor):"",r=e?`display:flex;align-items:center;padding:12px 16px;gap:10px;background:${AT};border:1px solid ${PT};border-bottom-color:transparent;border-radius:8px 8px 0 0;cursor:pointer;`:`display:flex;align-items:center;padding:12px 16px;gap:10px;background:${DT};border:1px solid ${PT};border-radius:8px;cursor:pointer;`;return`\n \n \n ${i}\n
\n `}_editorHTML(t,e){const r=[];null!==e.seed?(r.push(this._enableHTML(e)),r.push(this._identityHTML(e))):r.push(`${n("adopted.registry_unavailable")}
`),t.allowed_device_classes.length>0&&r.push(this._deviceClassHTML(t,e)),t.allowed_state_classes.length>0&&r.push(this._stateClassHTML(t,e)),r.push(this._prominenceHTML(e)),null!==e.seed&&ST(e.form.deviceClass,t.allowed_device_classes,e.units)&&r.push(this._displayHTML(t,e)),t.stale_fields.length>0&&r.push(`${Bt(i("adopted.stale_note",{fields:t.stale_fields.join(", ")}))}
`),r.push(this._actionsHTML(e)),null!==e.confirm&&r.push(this._confirmHTML(t,e)),null!==e.error&&r.push(`${Bt(e.error)}
`);for(const t of e.notices)r.push(`${Bt(t)}
`);return r.push(`${Bt(function(t){const e=[t.path,t.datatype];return t.unit&&e.push(t.unit),e.push(t.settable?n("adopted.settable"):n("adopted.read_only")),e.join(" · ")}(t))}
`),`\n \n ${r.join("")}\n
\n `}_enableHTML(t){const e=t.form.enabled,i=e?TT:MT;return`\n \n ${n("adopted.enable_entity")} \n \n ${n(e?"adopted.enabled":"adopted.disabled")} \n \n \n ${n("adopted.enable_note")} \n
\n `}_identityHTML(t){return`\n \n ${n("adopted.name")} \n \n
\n `}_deviceClassHTML(t,e){const r=[{value:"",label:n("adopted.no_device_class")},...t.allowed_device_classes.map(t=>({value:t,label:CT(t)}))],o=t.unit?i("adopted.device_class_note",{unit:t.unit}):n("adopted.device_class_note_unitless");return`\n \n ${n("adopted.device_class")} \n ${HT("device_class",r,e.form.deviceClass)}\n ${Bt(o)} \n
\n `}_stateClassHTML(t,e){const i=[{value:"",label:n("adopted.no_statistics")},...t.allowed_state_classes.map(t=>({value:t,label:CT(t)}))];return`\n \n ${n("adopted.statistics_class")} \n ${HT("state_class",i,e.form.stateClass)}\n ${n("adopted.statistics_note")} \n
\n `}_prominenceHTML(t){const e=(t,e,n)=>`${Bt(e)} `;return`\n \n ${n("adopted.prominence")} \n \n ${e("diagnostic",n("adopted.diagnostic"),!t.form.promote)}\n ${e("standard",n("adopted.standard"),t.form.promote)}\n \n
\n `}_displayHTML(t,e){const i=[{value:"",label:t.unit?`${t.unit} — ${n("adopted.unit_as_published")}`:n("adopted.unit_as_published")},...e.units.map(t=>({value:t,label:t}))],r=[{value:"",label:n("adopted.precision_default")},...kT.map(t=>({value:t,label:t}))];return`\n \n ${n("adopted.display_unit")} \n ${HT("unit",i,e.unit)}\n ${n("adopted.precision")} \n ${HT("precision",r,e.precision)}\n
\n `}_actionsHTML(t){const e=t.busy?" disabled":"";return`\n \n ${n("adopted.save")} \n ${n("adopted.clear")} \n ${n("adopted.reload_note")} \n
\n `}_confirmHTML(t,e){const r="clearing"===e.confirm,o=r?i("adopted.confirm_clearing_subject",{name:t.name}):i("adopted.confirm_setting",{name:t.name,value:CT(e.form.stateClass)}),a=n(r?"adopted.confirm_clearing":"adopted.confirm_total_increasing");return`\n \n
\n
\n
${n("adopted.confirm_heading")} \n
\n
${Bt(o)}
\n
${a}
\n
\n ${n("adopted.cancel")} \n ${n("adopted.save_anyway")} \n
\n
\n `}_bind(){const t=this._container;t&&(t.addEventListener("click",this._onClick),t.addEventListener("input",this._onInput),t.addEventListener("change",this._onChange))}_unbind(){const t=this._container;t&&(t.removeEventListener("click",this._onClick),t.removeEventListener("input",this._onInput),t.removeEventListener("change",this._onChange))}async _handleClick(t){const e=t.target;if(!e)return;const n=e.closest("[data-action]");if(n)return void await this._handleAction(n);const i=e.closest(".adopted-row-header"),r=i?.dataset.key;return r?this._expandedKey===r?(this._expandedKey=null,this._editor=null,void this._paintGroups()):void await this._openEditor(r):void 0}async _handleAction(t){const e=this._editor;if(e)switch(t.dataset.action){case"toggle-enable":return e.form={...e.form,enabled:!e.form.enabled},void this._paintGroups();case"prominence":return e.form={...e.form,promote:"standard"===t.dataset.value},void this._paintGroups();case"save":return void(e.busy||await this._save(!1));case"clear":return void(e.busy||await this._save(!0));case"confirm-cancel":return e.confirm=null,void this._paintGroups();case"confirm-save":{const t=e.confirmClears;return e.confirm=null,void await this._commit(t)}default:return}}_handleInput(t){const e=t.target;if(!e)return;if("adopted-filter"===e.id)return this._query=e.value,void this._paintGroups();const n=this._editor,i=e.dataset.field;if(!n||!i)return;const r=e.value;"name"===i&&(n.form={...n.form,name:r})}async _handleChange(t){const e=t.target,n=this._editor,i=e?.dataset.field;if(e&&n&&i)switch(i){case"device_class":return n.form={...n.form,deviceClass:e.value},n.units=this._hass?await this._fetchUnits(this._hass,e.value):[],void this._paintGroups();case"state_class":return void(n.form={...n.form,stateClass:e.value});case"unit":return void(n.unit=e.value);case"precision":return void(n.precision=e.value);default:return}}async _openEditor(t){const e=this._findRow(t),n=this._hass;if(!e||!n)return;this._expandedKey=t,this._editor={form:xT(e,null),seed:null,units:[],unit:"",precision:"",confirm:null,confirmClears:!1,busy:!0,error:null,notices:[]},this._paintGroups();const i=null===e.entity_id?null:await this._fetchSeed(n,e.entity_id);if(this._expandedKey!==t)return;const r=xT(e,i),o=await this._fetchUnits(n,r.deviceClass);this._expandedKey===t&&(this._editor={form:r,seed:i,units:o,unit:i?.unit??"",precision:i?.precision??"",confirm:null,confirmClears:!1,busy:!1,error:null,notices:[]},this._paintGroups())}async _save(t){const e=this._editor,n=null===this._expandedKey?null:this._findRow(this._expandedKey);if(!e||!n)return;const i=function(t,e){return"total_increasing"===e.stateClass?"total_increasing":t.curation.state_class&&""===e.stateClass?"clearing":null}(n,this._formFor(e,t));if(null!==i)return e.confirm=i,e.confirmClears=t,e.error=null,e.notices=[],void this._paintGroups();await this._commit(t)}_formFor(t,e){return e?{...t.form,deviceClass:"",stateClass:"",promote:!1}:t.form}async _commit(t){const e=this._editor,i=this._hass,r=null===this._expandedKey?null:this._findRow(this._expandedKey);if(!(e&&i&&r&&this._deviceId))return;const o=this._formFor(e,t),a=function(t,e){const n={};return e.deviceClass&&(n.device_class=e.deviceClass),e.stateClass&&(n.state_class=e.stateClass),e.promote&&(n.entity_category="none"),{registryUpdate:null===t.entity_id?null:{type:"config/entity_registry/update",entity_id:t.entity_id,name:e.name||null,disabled_by:e.enabled?null:"user"},curate:{key:t.key,record:n}}}(r,o);e.busy=!0,e.error=null,e.notices=[],this._paintGroups();let l=e.seed;try{const c=t||null===l?null:function(t,e,n){if(null===t.registryUpdate||null===e||!function(t,e){return null!==t&&(e.enabled!==(null===t.disabledBy)||e.name!==t.name)}(e,n))return null;const i={...t.registryUpdate};return function(t,e){return e.enabled===(null===t.disabledBy)}(e,n)&&delete i.disabled_by,i}(a,l,o);null!==c&&null!==l&&(await i.callWS(c),l=function(t,e){return{...t,disabledBy:e.enabled?null:t.disabledBy??"user",name:e.name}}(l,o),e.seed=l),!t&&null!==l&&null!==r.entity_id&&ST(o.deviceClass,r.allowed_device_classes,e.units)&&function(t,e,n){return null!==t&&(e!==t.unit||n!==t.precision)}(l,e.unit,e.precision)&&(await i.callWS({type:"config/entity_registry/update",entity_id:r.entity_id,options_domain:"sensor",options:wT(e.unit,e.precision)}),l={...l,unit:e.unit,precision:e.precision},e.seed=l);const d=await i.callWS({type:`${s}/adopted/curate`,device_id:this._deviceId,key:a.curate.key,record:a.curate.record});r.curation=d?.record??{},e.form=o,e.notices=[n("adopted.saved"),...Array.isArray(d?.warnings)?d.warnings.map(FT):[]]}catch(t){return e.error=BT(t),e.busy=!1,void this._paintGroups()}e.busy=!1,this._paintGroups(),this._scheduleRefresh()}_scheduleRefresh(){this._refreshTimer&&clearTimeout(this._refreshTimer),this._refreshTimer=setTimeout(()=>{this._refreshTimer=null;const t=this._hass;t&&this._fetchList(t,!0).then(()=>this._paintGroups())},2e3)}}function WT(t=""){const e=t?` value="${Bt(t)}"`:"",i=t?"":"display:none;";return`\n \n \n \n \n \n
\n `}function UT(t,e,i,r,o,a,s){const c=e.entities?.power,d=c?i.states[c]:null,u=d&&parseFloat(d.state)||0,h=e.entities?.switch,p=h?i.states[h]:null,f=p?"on"===p.state:(d?.attributes?.relay_state||e.relay_state)===l,g=e.breaker_rating_a,m=g?`${Math.round(g)}A`:"",y=Bt(e.name||n("grid.unknown")),_=ye(r),b="current"===_.entityRole;let x;if(f)if(b){const t=e.entities?.current,n=t?i.states[t]:null,r=n&&parseFloat(n.state)||0;x=`${_.format(r)} A `}else x=`${pe(u)} ${he(u)} `;else x="";const w=a||"unknown";let S="";if("unknown"!==w){const t=v[w]??v.unknown??{icon:"mdi:help",color:"#999",label:()=>"Unknown"};S=t.icon2?`\n \n \n `:t.textLabel?`\n \n ${t.textLabel} \n `:` `}let C="",k=o?.utilization_pct??null;if(null==k&&e.breaker_rating_a){const t=e.entities?.current,n=t?i.states[t]:null,r=n?Math.abs(parseFloat(n.state)||0):0;k=Math.round(r/e.breaker_rating_a*1e3)/10}if(null!=k){C=`=80?"utilization-warning":"utilization-normal"}">${Math.round(k)}% `}const M=`\n \n `,T=!1!==e.is_user_controllable&&!!e.entities?.switch?`\n ${n(f?"grid.on":"grid.off")} \n \n
`:`${f?"ON":"OFF"} `;return`\n \n ${m?`${m} `:""}\n ${C}\n ${y} \n ${S}\n ${T}\n \n ${x}\n \n ${M}\n \n \n \n
\n `}function GT(t,e,n,i,r){const o=e.entities?.power,a=o?n.states[o]:null,s=a&&parseFloat(a.state)||0,d=e.device_type===c||s<0,u=e.entities?.switch,h=u?n.states[u]:null,p=Se(0,r,h?"on"===h.state:(a?.attributes?.relay_state||e.relay_state)===l,d),f=Bt(t);return`\n \n `}function qT(t){return``}function jT(t,e,n){const i=t.entities?.switch,r=i?e.states[i]:null,o=t.entities?.power,a=o?e.states[o]:null,s=r?"on"===r.state:(a?.attributes?.relay_state||t.relay_state)===l;let c;if("current"===(n.chart_metric||"power")){const n=t.entities?.current,i=n?e.states[n]:null;c=i?Math.abs(parseFloat(i.state)||0):0}else c=a?Math.abs(parseFloat(a.state)||0):0;return{isOn:s,value:c}}function XT(t,e){if(t.always_on)return"always_on";const n=t.entities?.select,i=n?e.states[n]:null;return i?i.state:"unknown"}function YT(t,e,n,i){const r=jT(t,n,i),o=jT(e,n,i);return r.isOn&&!o.isOn?-1:!r.isOn&&o.isOn?1:o.value-r.value}function ZT(t,e,n){return t.sort((t,i)=>YT(t[1],i[1],e,n))}function KT(t){return t.entities?.current??t.entities?.power??""}class QT{constructor(t){this._expandedUuids=new Set,this._searchQuery="",this._container=null,this._clickHandler=null,this._inputHandler=null,this._graphSettingsHandler=null,this._hass=null,this._topology=null,this._config=null,this._monitoringStatus=null,this._viewName=null,this._columns=1,this._foldUnobserve=null,this._ctrl=t}setColumns(t){const e=Math.max(1,Math.min(3,Math.floor(t)));this._columns=e}setInitialExpansion(t){this._expandedUuids=new Set(t)}setInitialSearchQuery(t){this._searchQuery=t}setViewName(t){this._viewName=t}renderActivityView(t,e,n,i,r,o){this._unbindEvents(),this._hass=e,this._topology=n,this._config=i,this._monitoringStatus=r;const a=ZT(Object.entries(n.circuits),e,i);let s=o+WT(this._searchQuery);s+=``;for(const[t,n]of a){const o=we(r,KT(n)),a=XT(n,e),l=this._expandedUuids.has(t);s+=`
`,s+=UT(t,n,e,i,o,a,l),l&&(s+=GT(t,n,e,0,o)),s+="
"}s+="
",s+=" ",t.innerHTML=s;const l=t.querySelector("span-side-panel");l&&(l.hass=e,l.errorStore=this._ctrl.errorStore),this._bindEvents(t),this._searchQuery&&this._applyFilter(t),this._ctrl.updateDOM(t),this._attachFoldObserver(t)}renderAreaView(t,e,i,r,o,a){this._unbindEvents(),this._hass=e,this._topology=i,this._config=r,this._monitoringStatus=o;const s=n("list.unassigned_area"),l=new Map;for(const[t,e]of Object.entries(i.circuits)){const n=e.area??s,i=l.get(n);i?i.push([t,e]):l.set(n,[[t,e]])}const c=[...l.keys()].sort((t,e)=>t===s?1:e===s?-1:t.localeCompare(e));let d=a+WT(this._searchQuery);d+=``;for(const t of c){const n=l.get(t);if(!n)continue;const i=ZT(n,e,r);d+=qT(t);for(const[t,n]of i){const i=we(o,KT(n)),a=XT(n,e),s=this._expandedUuids.has(t);d+=`
`,d+=UT(t,n,e,r,i,a,s),s&&(d+=GT(t,n,e,0,i)),d+="
"}}d+="
",d+=" ",t.innerHTML=d;const u=t.querySelector("span-side-panel");u&&(u.hass=e,u.errorStore=this._ctrl.errorStore),this._bindEvents(t),this._searchQuery&&this._applyFilter(t),this._ctrl.updateDOM(t),this._attachFoldObserver(t)}updateCollapsedRows(t,e,i,r){const o=ye(r),a="current"===o.entityRole,s=t.querySelectorAll(".list-row[data-row-uuid]");for(const t of s){const s=t.dataset.rowUuid;if(!s)continue;const l=i.circuits[s];if(!l)continue;const{isOn:c,value:d}=jT(l,e,r),u=t.querySelector(".list-power-value");if(u)if(c)if(a)u.innerHTML=`${o.format(d)} A `;else{const t=l.entities?.power,n=t?e.states[t]:null,i=n&&parseFloat(n.state)||0;u.innerHTML=`${pe(i)} ${he(i)} `}else u.innerHTML="";const h=t.querySelector(".toggle-pill");if(h){h.classList.toggle("toggle-on",c),h.classList.toggle("toggle-off",!c);const t=h.querySelector(".toggle-label");t&&(t.textContent=n(c?"grid.on":"grid.off"))}const p=t.querySelector(".list-status-badge");p&&(p.textContent=c?"ON":"OFF",p.classList.toggle("list-status-on",c),p.classList.toggle("list-status-off",!c)),t.classList.toggle("circuit-off",!c)}!function(t,e,n,i){const r=t.querySelector(".list-view");if(r)for(const t of function(t,e){let n={anchor:null,units:[]};const i=[n];for(const r of[...t.children])if(r.classList.contains("area-header"))n={anchor:r,units:[]},i.push(n);else if(r.classList.contains("list-cell")){const t=r.dataset.cellUuid,i=t?e.circuits[t]:void 0;t&&i&&n.units.push({cell:r,uuid:t,circuit:i})}return i}(r,n)){if(t.units.length<2)continue;const n=[...t.units].sort((t,n)=>YT(t.circuit,n.circuit,e,i));if(!n.some((e,n)=>e.uuid!==t.units[n].uuid))continue;let o=t.anchor;for(const t of n)o?o.after(t.cell):r.prepend(t.cell),o=t.cell}}(t,e,i,r)}stop(){this._unbindEvents(),null===this._viewName&&(this._expandedUuids.clear(),this._searchQuery=""),this._hass=null,this._topology=null,this._config=null,this._monitoringStatus=null}_dispatchFavoritesViewState(){if(!this._viewName||!this._container)return;const t={view:this._viewName,expanded:[...this._expandedUuids],searchQuery:this._searchQuery};this._container.dispatchEvent(new CustomEvent("favorites-view-state-changed",{detail:t,bubbles:!0,composed:!0}))}_bindEvents(t){this._container=t,this._clickHandler=e=>{const n=e.target;if(!n)return;const i=n.closest(".list-expand-toggle");if(i){const t=i.dataset.expandUuid;return void(t&&this._toggleExpand(t))}if(n.closest(".gear-icon"))return void this._ctrl.onGearClick(e,t);if(n.closest(".toggle-pill"))return void this._ctrl.onToggleClick(e,t);if(n.closest(".list-search-clear")){const e=t.querySelector(".list-search");return void(e&&(e.value="",e.dispatchEvent(new Event("input",{bubbles:!0}))))}const r=n.closest(".unit-btn");if(r){const e=r.dataset.unit;e&&t.dispatchEvent(new CustomEvent("unit-changed",{detail:e,bubbles:!0,composed:!0}))}},this._inputHandler=e=>{const n=e.target;n&&n.classList.contains("list-search")&&(this._searchQuery=n.value.toLowerCase(),this._applyFilter(t),this._dispatchFavoritesViewState())},this._graphSettingsHandler=()=>{this._ctrl.onGraphSettingsChanged(t).then(()=>{this._ctrl.updateDOM(t)}).catch(()=>{})},t.addEventListener("click",this._clickHandler),t.addEventListener("input",this._inputHandler),t.addEventListener("graph-settings-changed",this._graphSettingsHandler);const e=t.querySelector(".slide-confirm");e&&(this._ctrl.bindSlideConfirm(e,t),t.classList.add("switches-disabled"))}_unbindEvents(){this._container&&(this._clickHandler&&this._container.removeEventListener("click",this._clickHandler),this._inputHandler&&this._container.removeEventListener("input",this._inputHandler),this._graphSettingsHandler&&this._container.removeEventListener("graph-settings-changed",this._graphSettingsHandler)),this._foldUnobserve&&(this._foldUnobserve(),this._foldUnobserve=null),this._container=null,this._clickHandler=null,this._inputHandler=null,this._graphSettingsHandler=null}_attachFoldObserver(t){this._foldUnobserve&&(this._foldUnobserve(),this._foldUnobserve=null),this._foldUnobserve=cT(t,{rowSelector:".list-row",nameSelector:".list-circuit-name",foldClass:"is-folded"})}_applyFilter(t){const e=t.querySelector(".list-search-clear");e&&(e.style.display=this._searchQuery?"":"none");const n=t.querySelectorAll(".list-cell[data-cell-uuid]");for(const t of n){const e=t.querySelector(".list-circuit-name"),n=(e?.textContent?.toLowerCase()??"").includes(this._searchQuery);t.style.display=n?"":"none"}const i=t.querySelectorAll(".area-header");for(const t of i){let e=!1,n=t.nextElementSibling;for(;n&&!n.classList.contains("area-header");){if(n.classList.contains("list-cell")&&"none"!==n.style.display){e=!0;break}n=n.nextElementSibling}t.style.display=e?"":"none"}}_toggleExpand(t){if(!(this._container&&this._hass&&this._topology&&this._config))return;const e=nT(t),n=this._container.querySelector(`.list-cell[data-cell-uuid="${e}"]`);if(!n)return;const i=n.querySelector(`.list-row[data-row-uuid="${e}"]`),r=n.querySelector(`.list-expand-toggle[data-expand-uuid="${e}"]`);if(i){if(this._expandedUuids.has(t)){this._expandedUuids.delete(t);const o=n.querySelector(`.list-expanded-content[data-expanded-uuid="${e}"]`);o&&o.remove(),r&&r.classList.remove("expanded"),i.classList.remove("list-row-expanded")}else{this._expandedUuids.add(t);const e=this._topology.circuits[t];if(!e)return;const n=we(this._monitoringStatus,KT(e)),o=GT(t,e,this._hass,this._config,n);i.insertAdjacentHTML("afterend",o),r&&r.classList.add("expanded"),i.classList.add("list-row-expanded"),this._ctrl.updateDOM(this._container)}this._dispatchFavoritesViewState()}}}function JT(t,e){return`${t}|${e}`}class tI{async build(t,e,n,i){const r=new Map;for(const t of n)r.set(t.id,t);const o=i?new qt(i):null,a=[];for(const[n,i]of Object.entries(e)){if(!((i?.circuits?.length??0)>0||(i?.sub_devices?.length??0)>0))continue;const e=r.get(n);e&&a.push((async()=>{try{const i=await se(t,n,o);return{panelDeviceId:n,panel:e,topology:i.topology}}catch(t){return console.warn("SPAN Panel: favorites topology fetch failed",n,t),{panelDeviceId:n,panel:e,topology:null}}})())}const s=(await Promise.all(a)).filter(t=>null!==t.topology),l=s.length>1,c={},d={},u={},h=new Set,p=[];for(const{panelDeviceId:t,panel:n,topology:i}of s){if(!i)continue;const r=n.config_entries?.[0]??null;r&&h.add(r);const o=n.name_by_user??n.name??i.device_name??"";p.push({panelDeviceId:t,panelName:o,topology:i});const a=e[t],s=a?.circuits??[],f=a?.sub_devices??[];for(const e of s){const n=i.circuits?.[e];if(!n)continue;const a=JT(t,e),s=l&&o?`${o} · ${n.name}`:n.name;c[a]={...n,name:s},u[a]={panelDeviceId:t,kind:"circuit",targetId:e,configEntryId:r}}for(const e of f){const n=i.sub_devices?.[e];if(!n)continue;const a=JT(t,e),s=l&&o&&n.name?`${o} · ${n.name}`:n.name??e;d[a]={...n,name:s},u[a]={panelDeviceId:t,kind:"sub_device",targetId:e,configEntryId:r}}}return{topology:{circuits:c,sub_devices:d,panel_entities:{},device_name:"",_favoriteRefs:u},entryIds:Array.from(h),perPanelStats:p}}}const eI="span_panel_favorites_view_state";function nI(t){try{localStorage.setItem(eI,JSON.stringify(t))}catch{}}var iI;const rI="favorites";function oI(t){return"dashboard"===t||"adopted"===t}let aI=iI=class extends Dt{constructor(){super(...arguments),this.narrow=!1,this._panels=[],this._selectedPanelId=null,this._activeTab="dashboard",this._discovered=!1,this._listColumns=Wt(),this._favorites={},this._favoritesViewState={expanded:{activity:[],area:[]}},this._favoritesPanelStats=[],this._dashboardTab=new uT,this._monitoringTab=new yT,this._adoptedTab=new VT,this._listDashCtrl=new lT,this._listCtrl=new QT(this._listDashCtrl),this._favCache=new Yt,this._favCtrl=new tI,this._favoritesMonitoringTabs=new Map,this._errorStore=new Ht,this._watchedPanelId=null,this._discovering=!1,this._refreshSeq=0,this._areaUnsub=null,this._areaSubscribing=!1,this._onFavoritesChanged=null,this._deviceRegistryUnsub=null,this._pendingTabRender=!1,this._persistFavoritesViewStateTimer=null,this._tabRenderScheduler=function(t){let e=null,n=!1;return async function i(){if(e)return n=!0,void await e.catch(()=>{});const r=(async()=>{try{await t()}finally{e=null,n&&(n=!1,await i())}})();e=r,await r}}(async()=>this._renderTab()),this._beginRender=function(){let t=0;return()=>{t+=1;const e=t;return()=>t!==e}}()}get _root(){const t=this.shadowRoot;if(!t)throw new Error("span-panel: shadow root is not available");return t}connectedCallback(){super.connectedCallback(),this._dashboardTab.errorStore=this._errorStore,this._listDashCtrl.errorStore=this._errorStore,this._favCache.errorStore=this._errorStore,this._monitoringTab.errorStore=this._errorStore,this._onFavoritesChanged=()=>{this._refreshFavorites()},document.addEventListener(jt,this._onFavoritesChanged),this._subscribeDeviceRegistry()}disconnectedCallback(){this._dashboardTab.stop(),this._monitoringTab.stop(),this._adoptedTab.stop(),this._listCtrl.stop(),this._listDashCtrl.stopIntervals();for(const t of this._favoritesMonitoringTabs.values())t.stop();this._favoritesMonitoringTabs.clear(),this._areaSubscribing=!1,this._areaUnsub&&(this._areaUnsub(),this._areaUnsub=null),this._onFavoritesChanged&&(document.removeEventListener(jt,this._onFavoritesChanged),this._onFavoritesChanged=null),this._unsubscribeDeviceRegistry(),this._persistFavoritesViewStateTimer&&(clearTimeout(this._persistFavoritesViewStateTimer),this._persistFavoritesViewStateTimer=null),this._errorStore.dispose(),super.disconnectedCallback()}firstUpdated(){this.hass&&!this._discovered&&this._discoverPanels()}updated(t){if(t.has("hass")){const e=t.get("hass");this._dashboardTab.hass=this.hass,this._listDashCtrl.hass=this.hass,this._errorStore.updateHass(this.hass),this._discovered?this._root.getElementById("tab-content")||this._scheduleTabRender():this._discoverPanels(),!e&&this.hass&&this._subscribeDeviceRegistry()}if(this._discovered&&(t.has("_discovered")||t.has("_activeTab")||t.has("_selectedPanelId")||t.has("_chartMetric")||t.has("_listColumns"))){if(this._isFavoritesView&&oI(this._activeTab))return void(this._activeTab="activity");this._scheduleTabRender()}if(t.has("_selectedPanelId")&&(this._selectedPanelId!==rI&&this._selectedPanelId?(this._updatePanelStatusWatch(),this._listDashCtrl.setFavoritesPerPanelInfo(null)):(this._errorStore.clearPanelStatusWatch(),this._watchedPanelId=null)),this._discovered&&(t.has("_panels")||t.has("_selectedPanelId"))){const t=this.shadowRoot?.getElementById("panel-select");t&&null!==this._selectedPanelId&&t.value!==this._selectedPanelId&&(t.value=this._selectedPanelId)}if(t.has("hass")&&this._discovered&&("activity"===this._activeTab||"area"===this._activeTab)){const t=this._root.getElementById("tab-content"),e=this._listDashCtrl.topology;if(t&&e){this._listCtrl.updateCollapsedRows(t,this.hass,e,this._buildDashboardConfig());const n=t.querySelector("span-side-panel");n&&(n.hass=this.hass,n.errorStore=this._errorStore)}}}setConfig(t){}render(){var i,r,o;if(i=this.hass?.language,t=i&&e[i]?i:"en",!this.hass)return dt`
+ `,_([Et({attribute:!1})],tT.prototype,"options",void 0),_([Et({attribute:!1})],tT.prototype,"data",void 0),_([Et({type:String})],tT.prototype,"height",void 0);try{customElements.get("span-chart")||customElements.define("span-chart",tT)}catch{}function eT(t,e,n,i,o,a,s,l,c){const{options:d,series:u}=function(t,e,n,i,o,a=!1){n||(n=f[r]);const s=i?"140, 160, 220":"77, 217, 175",l=`rgb(${s})`,c=Date.now(),d=c-e,u=void 0!==n.fixedMin&&void 0!==n.fixedMax,h=(t??[]).filter(t=>t.time>=d).map(t=>[t.time,Math.abs(t.value)]),p=[{type:"line",data:h,showSymbol:!1,smooth:!1,...a?{}:{step:"end"},lineStyle:{width:1.5,color:l},areaStyle:{color:{type:"linear",x:0,y:0,x2:0,y2:1,colorStops:[{offset:0,color:`rgba(${s}, 0.18)`},{offset:1,color:`rgba(${s}, 0.18)`}]}},itemStyle:{color:l}}],g=h.length>0?function(t){let e=0;for(const n of t)n[1]>e&&(e=n[1]);return e}(h):0,v={type:"value",splitNumber:4,axisLabel:{fontSize:10,formatter:g<10?t=>0===t?"0":t.toFixed(1):t=>n.format(t)},splitLine:{lineStyle:{opacity:.15}}};u?(v.min=n.fixedMin,v.max=n.fixedMax):g<1&&(v.min=0,v.max=1),o&&"current"===n.entityRole&&(v.min=0,v.max=Math.ceil(1.25*o),p.push({type:"line",data:[[d,.8*o],[c,.8*o]],showSymbol:!1,lineStyle:{width:1,color:"rgba(255, 200, 40, 0.6)",type:"dashed"},itemStyle:{color:"transparent"},tooltip:{show:!1}}),p.push({type:"line",data:[[d,o],[c,o]],showSymbol:!1,lineStyle:{width:1.5,color:"rgba(255, 60, 60, 0.7)",type:"solid"},itemStyle:{color:"transparent"},tooltip:{show:!1}}));const m={xAxis:{type:"time",min:d,max:c,axisLabel:{fontSize:10},splitLine:{show:!1}},yAxis:v,grid:{top:8,right:4,bottom:0,left:0,containLabel:!0},tooltip:{trigger:"axis",axisPointer:{type:"line",lineStyle:{type:"dashed"}},formatter:t=>{if(!t||0===t.length)return"";const e=t[0],i=new Date(e.value[0]).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"}),r=parseFloat(e.value[1].toFixed(2));return`${i}${n.format(r)} ${n.unit(r)}
`}},animation:!1};return{options:m,series:p}}(n,i,o,a,l,c),h=s??120;t.style.minHeight=h+"px";let p=t.querySelector("span-chart");p||(p=document.createElement("span-chart"),p.style.display="block",p.style.width="100%",t.innerHTML="",t.appendChild(p));const g=t.clientHeight;p.height=(g>0?g:h)+"px",p.options=d,p.data=u}function nT(t){return"function"==typeof globalThis.CSS?.escape?CSS.escape(t):t.replace(/["\\]/g,"\\$&")}function iT(t,e,n,i,r){const o="current"===(i.chart_metric||"power"),a=t.querySelector(".stat-consumption .stat-value"),s=t.querySelector(".stat-consumption .stat-unit");if(o){const t=n.panel_entities?.site_power,i=t?e.states[t]:null,r=i?parseFloat(i.attributes?.amperage):NaN;a&&(a.textContent=Number.isFinite(r)?Math.abs(r).toFixed(1):"--"),s&&(s.textContent="A")}else{let t=r;const i=n.panel_entities?.site_power;if(i){const n=e.states[i];n&&(t=Math.abs(parseFloat(n.state)||0))}a&&(a.textContent=fe(t)),s&&(s.textContent="kW")}const l=t.querySelector(".stat-upstream .stat-value"),c=t.querySelector(".stat-upstream .stat-unit");if(l){const t=n.panel_entities?.current_power,i=t?e.states[t]:null;if(o){const t=i?parseFloat(i.attributes?.amperage):NaN;l.textContent=Number.isFinite(t)?Math.abs(t).toFixed(1):"--",c&&(c.textContent="A")}else{const t=i?Math.abs(parseFloat(i.state)||0):0;l.textContent=fe(t),c&&(c.textContent="kW")}}const d=t.querySelector(".stat-downstream .stat-value"),u=t.querySelector(".stat-downstream .stat-unit");if(d){const t=n.panel_entities?.feedthrough_power,i=t?e.states[t]:null;if(o){const t=i?parseFloat(i.attributes?.amperage):NaN;d.textContent=Number.isFinite(t)?Math.abs(t).toFixed(1):"--",u&&(u.textContent="A")}else{const t=i?Math.abs(parseFloat(i.state)||0):0;d.textContent=fe(t),u&&(u.textContent="kW")}}const h=t.querySelector(".stat-solar .stat-value"),p=t.querySelector(".stat-solar .stat-unit");if(h){const t=n.panel_entities?.pv_power,i=t?e.states[t]:null;if(o){const t=i?parseFloat(i.attributes?.amperage):NaN;h.textContent=Number.isFinite(t)?Math.abs(t).toFixed(1):"--",p&&(p.textContent="A")}else{if(i){const t=Math.abs(parseFloat(i.state)||0);h.textContent=fe(t)}else h.textContent="--";p&&(p.textContent="kW")}}const f=t.querySelector(".stat-battery .stat-value");if(f){const t=n.panel_entities?.battery_level,i=t?e.states[t]:null;i&&(f.textContent=`${Math.round(parseFloat(i.state)||0)}`)}const g=t.querySelector(".stat-grid-state .stat-value");if(g){const t=n.panel_entities?.dsm_state,i=t?e.states[t]:null;g.textContent=i?e.formatEntityState?.(i)||i.state:"--"}}function rT(t,e,i,r,o,a){if(!t||!i||!e)return;const s=Re(r);let d=0;for(const[,t]of Object.entries(i.circuits)){const n=t.entities?.power;if(!n)continue;const i=e.states[n],r=i&&parseFloat(i.state)||0;t.device_type!==c&&(d+=Math.abs(r))}!function(t,e,n,i,r){const o=t.querySelector(".panel-stats");o&&iT(o,e,n,i,r)}(t,e,i,r,d);const u=ye(r),h="current"===u.entityRole;for(const[r,d]of Object.entries(i.circuits)){const i=t.querySelector(`.circuit-slot[data-uuid="${nT(r)}"]`);if(!i)continue;const p=d.entities?.power,f=p?e.states[p]:null,g=f&&parseFloat(f.state)||0,m=d.device_type===c||g<0,y=d.entities?.switch,_=y?e.states[y]:null,b=_?"on"===_.state:(f?.attributes?.relay_state||d.relay_state)===l,x=i.querySelector(".power-value");if(x)if(h){const t=d.entities?.current,n=t?e.states[t]:null,i=n&&parseFloat(n.state)||0;x.innerHTML=`${u.format(i)} A `}else x.innerHTML=`${pe(g)} ${he(g)} `;const w=i.querySelector(".toggle-pill");if(w){w.className="toggle-pill "+(b?"toggle-on":"toggle-off");const t=w.querySelector(".toggle-label");t&&(t.textContent=n(b?"grid.on":"grid.off"))}let S;if(i.classList.toggle("circuit-off",!b),i.classList.toggle("circuit-producer",m),d.always_on)S="always_on";else{const t=d.entities?.select,n=t?e.states[t]:null;S=n?n.state:"unknown"}const C=v[S]??v.unknown,k=i.querySelector(".shedding-icon");k&&(k.setAttribute("icon",C.icon),k.style.color=C.color,k.title=C.label());const M=i.querySelector(".shedding-icon-secondary");M&&(C.icon2?(M.setAttribute("icon",C.icon2),M.style.color=C.color,M.style.display=""):M.style.display="none");const T=i.querySelector(".shedding-label");T&&(C.textLabel?(T.textContent=C.textLabel,T.style.color=C.color,T.style.display=""):T.style.display="none");const I=i.querySelector(".chart-container");if(I){const t=o.get(r)||[],e=i.classList.contains("circuit-col-span")?200:100,n=a?.has(r)?He(a.get(r)):s,l=d.device_type===c;eT(I,0,t,n,u,m,e,d.breaker_rating_a??void 0,l)}}}class oT{get errorStore(){return this._errorStore}set errorStore(t){this._errorStore=t,this._retry=t?new qt(t):null}constructor(){this._errorStore=null,this._retry=null,this._settings=null,this._lastFetch=0,this._fetching=!1}async fetch(t,e){const i=Date.now();if(this._fetching)return this._settings;if(this._settings&&i-this._lastFetch<3e4)return this._settings;this._fetching=!0;try{const i={};e&&(i.config_entry_id=e);const r={type:"call_service",domain:s,service:"get_graph_settings",service_data:i,return_response:!0},o=this._retry?await this._retry.callWS(t,r,{errorId:"fetch:graph_settings",errorMessage:n("error.graph_settings_failed")}):await t.callWS(r);this._settings=o?.response??null,this._lastFetch=Date.now()}catch(t){console.warn("SPAN Panel: graph settings fetch failed",t),this._settings=null,this._retry||this._errorStore?.add({key:"fetch:graph_settings",level:"warning",message:n("error.graph_settings_failed"),persistent:!1})}finally{this._fetching=!1}return this._settings}invalidate(){this._lastFetch=0}get settings(){return this._settings}clear(){this._settings=null,this._lastFetch=0}}function aT(t,e){if(!t)return o;const n=t.circuits?.[e];return n?.has_override?n.horizon:t.global_horizon??o}function sT(t,e){if(!t)return o;const n=t.sub_devices?.[e];return n?.has_override?n.horizon:t.global_horizon??o}class lT{constructor(){this.powerHistory=new Map,this.horizonMap=new Map,this.subDeviceHorizonMap=new Map,this.monitoringCache=new be,this.monitoringMultiCache=new xe,this.graphSettingsCache=new oT,this._errorStore=null,this._hass=null,this._topology=null,this._config=null,this._configEntryId=null,this._favRefs=null,this._perPanelInfo=new Map,this._panelFavorites=null,this._showMonitoring=!1,this._updateInterval=null,this._recorderRefreshInterval=null,this._resizeObserver=null,this._lastWidth=0,this._resizeDebounce=null}get errorStore(){return this._errorStore}set errorStore(t){this._errorStore=t,this.monitoringCache.errorStore=t,this.graphSettingsCache.errorStore=t,this.monitoringMultiCache.errorStore=t}get hass(){return this._hass}set hass(t){this._hass=t}get topology(){return this._topology}get config(){return this._config}set showMonitoring(t){this._showMonitoring=t}init(t,e,n,i){this._topology=t,this._config=e,this._hass=n,this._configEntryId=i}setFavoriteRefs(t){this._favRefs=t}clearFavoriteRefs(){this._favRefs=null}setPanelFavorites(t){this._panelFavorites=t}setFavoritesPerPanelInfo(t){this._perPanelInfo=t??new Map}get _inFavoritesView(){return null!==this._favRefs}setConfig(t){this._config=t}buildHorizonMaps(t){if(this.horizonMap.clear(),this.subDeviceHorizonMap.clear(),t&&this._topology?.circuits)for(const e of Object.keys(this._topology.circuits))this.horizonMap.set(e,aT(t,e));if(t&&this._topology?.sub_devices)for(const e of Object.keys(this._topology.sub_devices))this.subDeviceHorizonMap.set(e,sT(t,e))}async fetchAndBuildHorizonMaps(){try{this._favRefs?await this._buildFavoritesHorizonMaps():(await this.graphSettingsCache.fetch(this._hass,this._configEntryId),this.buildHorizonMaps(this.graphSettingsCache.settings))}catch(t){console.warn("SPAN Panel: graph settings fetch failed",t),this.graphSettingsCache.errorStore||this._errorStore?.add({key:"fetch:graph_settings",level:"warning",message:n("error.graph_settings_failed"),persistent:!1})}}async fetchMergedMonitoringStatus(t){if(!this._hass||0===t.length)return null;const e=this._hass;return function(t){let e=!1;const n={},i={};for(const r of t)r&&(e=!0,r.circuits&&Object.assign(n,r.circuits),r.mains&&Object.assign(i,r.mains));return e?{circuits:n,mains:i}:null}(await Promise.all(t.map(t=>this.monitoringMultiCache.fetchOne(e,t))))}async _buildFavoritesHorizonMaps(){if(!this._hass||!this._favRefs||!this._topology)return;const t=new Set;for(const e of Object.values(this._favRefs))e.configEntryId&&t.add(e.configEntryId);const e=new Map;await Promise.all(Array.from(t).map(async t=>{e.set(t,await this._fetchGraphSettingsFresh(t))})),this.horizonMap.clear(),this.subDeviceHorizonMap.clear();for(const t of Object.keys(this._topology.circuits)){const n=this._favRefs[t],i=n?.configEntryId?e.get(n.configEntryId)??null:null,r=n?.targetId??t;this.horizonMap.set(t,aT(i,r))}if(this._topology.sub_devices)for(const t of Object.keys(this._topology.sub_devices)){const n=this._favRefs[t],i=n?.configEntryId?e.get(n.configEntryId)??null:null,r=n?.targetId??t;this.subDeviceHorizonMap.set(t,sT(i,r))}}async loadHistory(){await je(this._hass,this._topology,this._config,this.powerHistory,this.horizonMap,this.subDeviceHorizonMap)}recordSamples(){if(!this._topology||!this._hass||!this._config)return;const t=Date.now();for(const[e,n]of Object.entries(this._topology.circuits)){const i=this.horizonMap.get(e)??o;if(!a[i]?.useRealtime)continue;const r=_e(n,this._config);if(!r)continue;const s=this._hass.states[r];if(!s)continue;const l=parseFloat(s.state);if(isNaN(l))continue;const c=He(i),d=Fe(c),u=Be(c),h=t-c,p=this.powerHistory.get(e)??[];p.length>0&&t-p[p.length-1].time0&&t-p[p.length-1].time0&&this._topology)for(const{key:t,devId:e}of qe(this._topology))i.has(e)&&r.add(t);const o=new Map;try{await je(this._hass,this._topology,this._config,o,e,i);for(const t of e.keys()){const e=o.get(t);e?this.powerHistory.set(t,e):this.powerHistory.delete(t)}for(const t of r){const e=o.get(t);e?this.powerHistory.set(t,e):this.powerHistory.delete(t)}this.updateDOM(t)}catch(t){console.warn("SPAN Panel: history refresh failed",t),this._errorStore?.add({key:"fetch:history",level:"warning",message:n("error.history_failed"),persistent:!1})}}updateDOM(t){this._hass&&this._topology&&this._config&&(rT(t,this._hass,this._topology,this._config,this.powerHistory,this.horizonMap),function(t,e,n,i,r,o){if(!n.sub_devices)return;const a=Re(i);for(const[i,s]of Object.entries(n.sub_devices)){const n=t.querySelector(`[data-subdev="${nT(i)}"]`);if(!n)continue;const l=Pe(s);if(l){const t=e.states[l],i=t&&parseFloat(t.state)||0,r=n.querySelector(".sub-power-value");r&&(r.innerHTML=`${pe(i)} ${he(i)} `)}const c=n.querySelectorAll("[data-chart-key]");for(const t of c){const e=t.dataset.chartKey;if(!e)continue;const n=r.get(e)||[];let s=g.power;e.endsWith("_soc")?s=g.soc:e.endsWith("_soe")&&(s=g.soe);const l=!!t.closest(".bess-chart-col");eT(t,0,n,o?.has(i)?He(o.get(i)):a,s,!1,l?120:150,void 0,e.endsWith("_soc")||e.endsWith("_soe"))}for(const t of Object.keys(s.entities||{})){const i=n.querySelector(`[data-eid="${nT(t)}"]`);if(!i)continue;const r=e.states[t];if(r){let t;if(e.formatEntityState)t=e.formatEntityState(r);else{t=r.state;const e=r.attributes.unit_of_measurement||"";e&&(t+=" "+e)}if("Wh"===(r.attributes.unit_of_measurement||"")){const e=parseFloat(r.state);isNaN(e)||(t=(e/1e3).toFixed(1)+" kWh")}i.textContent=t}}}}(t,this._hass,this._topology,this._config,this.powerHistory,this.subDeviceHorizonMap))}async onGraphSettingsChanged(t){if(this._hass){this._favRefs?await this._buildFavoritesHorizonMaps():(this.graphSettingsCache.invalidate(),await this.graphSettingsCache.fetch(this._hass,this._configEntryId),this.buildHorizonMaps(this.graphSettingsCache.settings)),this.powerHistory.clear();try{await this.loadHistory()}catch{}this.updateDOM(t)}}onToggleClick(t,e){const i=t.target,r=i?.closest(".toggle-pill");if(!r)return;const o=e.querySelector(".slide-confirm");if(!o||!o.classList.contains("confirmed"))return;t.stopPropagation(),t.preventDefault();const a=r.closest("[data-uuid]");if(!a||!this._topology||!this._hass)return;const s=a.dataset.uuid;if(!s)return;const l=this._topology.circuits[s];if(!l)return;const c=l.entities?.switch;if(!c)return;const d=this._hass.states[c];if(!d)return void console.warn("SPAN Panel: switch entity not found:",c);const u="on"===d.state?"turn_off":"turn_on";this._hass.callService("switch",u,{},{entity_id:c}).catch(t=>{console.warn("SPAN Panel: switch service call failed",t),this._errorStore?.add({key:"service:relay",level:"error",message:n("error.relay_failed"),persistent:!1})})}async onGearClick(t,e){const n=t.target,i=n?.closest(".gear-icon");if(!i)return;const r=e.querySelector("span-side-panel");if(!r||!this._hass)return;if(r.hass=this._hass,r.errorStore=this.errorStore,i.classList.contains("panel-gear")){if(this._inFavoritesView){const t=await this._buildFavoritesSections();if(0===t.length)return;return void r.open({favoritesMode:!0,perPanelSections:t})}return await this.graphSettingsCache.fetch(this._hass,this._configEntryId),void r.open({panelMode:!0,topology:this._topology,graphSettings:this.graphSettingsCache.settings,showFavorites:null!==this._panelFavorites,favoritePanelDeviceId:this._panelFavorites?.panelDeviceId,favoriteCircuitUuids:this._panelFavorites?.circuitUuids,favoriteSubDeviceIds:this._panelFavorites?.subDeviceIds,configEntryId:this._configEntryId})}const a=i.dataset.uuid;if(a&&this._topology){const t=this._topology.circuits[a];if(t){const e=this._favRefs?.[a]??null,n=e&&"circuit"===e.kind?e.targetId:a,i=e?.configEntryId??this._configEntryId;let s,l;e?[s,l]=await Promise.all([this._fetchGraphSettingsFresh(i),this._fetchMonitoringStatusFresh(i)]):(await Promise.all([this.graphSettingsCache.fetch(this._hass,i),this.monitoringCache.fetch(this._hass,i)]),s=this.graphSettingsCache.settings,l=this.monitoringCache.status);const c=t.entities?.current??t.entities?.power,d=c?l?.circuits?.[c]??null:null,u=s?.global_horizon??o,h=s?.circuits?.[n],p=h?{...h,globalHorizon:u}:{horizon:u,has_override:!1,globalHorizon:u},f=e?.panelDeviceId??this._panelFavorites?.panelDeviceId,g=null!==e||(this._panelFavorites?.circuitUuids.has(n)??!1),v=this._inFavoritesView||null!==this._panelFavorites;return void r.open({...t,uuid:n,monitoringInfo:d,showMonitoring:this._showMonitoring,graphHorizonInfo:p,showFavorites:v,favoritePanelDeviceId:f,isFavorite:g,configEntryId:i})}}const s=i.dataset.subdevId;if(s&&this._topology?.sub_devices?.[s]){const t=this._topology.sub_devices[s],e=this._favRefs?.[s]??null,n=e&&"sub_device"===e.kind?e.targetId:s,i=e?.configEntryId??this._configEntryId;let a;e?a=await this._fetchGraphSettingsFresh(i):(await this.graphSettingsCache.fetch(this._hass,i),a=this.graphSettingsCache.settings);const l=a?.global_horizon??o,c=a?.sub_devices?.[n],d=c?{...c,globalHorizon:l}:{horizon:l,has_override:!1,globalHorizon:l},u=e?.panelDeviceId??this._panelFavorites?.panelDeviceId,h=null!==e||(this._panelFavorites?.subDeviceIds.has(n)??!1),p=this._inFavoritesView||null!==this._panelFavorites;r.open({subDeviceMode:!0,subDeviceId:n,name:t.name??n,deviceType:t.type??"",entities:t.entities,graphHorizonInfo:d,showFavorites:p,favoritePanelDeviceId:u,isFavorite:h,configEntryId:i})}}async _buildFavoritesSections(){if(!this._hass||!this._favRefs)return[];const t=function(t,e){const n=new Map;for(const i of Object.values(t)){if("circuit"!==i.kind)continue;const t=e.get(i.panelDeviceId);if(void 0===t)continue;let r=n.get(i.panelDeviceId);void 0===r&&(r={panelDeviceId:i.panelDeviceId,panelName:t.panelName,topology:t.topology,configEntryId:t.configEntryId,favoriteCircuitUuids:new Set},n.set(i.panelDeviceId,r)),r.favoriteCircuitUuids.add(i.targetId)}return Array.from(n.values()).sort((t,e)=>t.panelName.localeCompare(e.panelName))}(this._favRefs,this._perPanelInfo);if(0===t.length)return[];return await Promise.all(t.map(async t=>({panelDeviceId:t.panelDeviceId,panelName:t.panelName,topology:t.topology,graphSettings:await this._fetchGraphSettingsFresh(t.configEntryId),favoriteCircuitUuids:t.favoriteCircuitUuids,configEntryId:t.configEntryId})))}async _fetchGraphSettingsFresh(t){if(!this._hass)return null;try{const e={};t&&(e.config_entry_id=t);const i={type:"call_service",domain:s,service:"get_graph_settings",service_data:e,return_response:!0},r=this._errorStore?new qt(this._errorStore):null,o=r?await r.callWS(this._hass,i,{errorId:"fetch:graph_settings",errorMessage:n("error.graph_settings_failed")}):await this._hass.callWS(i);return o?.response??null}catch(t){return console.warn("SPAN Panel: fresh graph settings fetch failed",t),null}}async _fetchMonitoringStatusFresh(t){if(!this._hass)return null;try{const e={};t&&(e.config_entry_id=t);const i={type:"call_service",domain:s,service:"get_monitoring_status",service_data:e,return_response:!0},r=this._errorStore?new qt(this._errorStore):null,o=r?await r.callWS(this._hass,i,{errorId:"fetch:monitoring",errorMessage:n("error.monitoring_failed")}):await this._hass.callWS(i),a=o?.response;return a?{circuits:a.circuits,mains:a.mains}:null}catch(t){return console.warn("SPAN Panel: fresh monitoring status fetch failed",t),null}}bindSlideConfirm(t,e){const n=t.querySelector(".slide-confirm-knob"),i=t.querySelector(".slide-confirm-text");if(!n||!i)return;let r=!1,o=0,a=0;const s=e=>{t.classList.contains("confirmed")||(r=!0,o=e-n.offsetLeft,a=t.offsetWidth-n.offsetWidth-4,n.classList.remove("snapping"))},l=t=>{if(!r)return;const e=Math.max(2,Math.min(t-o,a));n.style.left=e+"px"},c=()=>{if(!r)return;r=!1;(n.offsetLeft-2)/a>=.9?(n.style.left=a+"px",t.classList.add("confirmed"),n.querySelector("span-icon")?.setAttribute("icon","mdi:lock-open"),i.textContent=t.dataset.textOn??"",e&&e.classList.remove("switches-disabled")):(n.classList.add("snapping"),n.style.left="2px")};n.addEventListener("mousedown",t=>{t.preventDefault(),s(t.clientX)}),t.addEventListener("mousemove",t=>l(t.clientX)),t.addEventListener("mouseup",c),t.addEventListener("mouseleave",c),n.addEventListener("touchstart",t=>{t.preventDefault(),s(t.touches[0].clientX)},{passive:!1}),t.addEventListener("touchmove",t=>l(t.touches[0].clientX),{passive:!0}),t.addEventListener("touchend",c),t.addEventListener("touchcancel",c),t.addEventListener("click",()=>{t.classList.contains("confirmed")&&(t.classList.remove("confirmed"),n.classList.add("snapping"),n.style.left="2px",n.querySelector("span-icon")?.setAttribute("icon","mdi:lock"),i.textContent=t.dataset.textOff??"",e&&e.classList.add("switches-disabled"))})}startIntervals(t,e){this._updateInterval=setInterval(()=>{this.recordSamples(),this.updateDOM(t),e&&e()},1e3),this._recorderRefreshInterval=setInterval(()=>{this.refreshRecorderData(t)},3e4)}stopIntervals(){this._updateInterval&&(clearInterval(this._updateInterval),this._updateInterval=null),this._recorderRefreshInterval&&(clearInterval(this._recorderRefreshInterval),this._recorderRefreshInterval=null),this.cleanupResizeObserver()}setupResizeObserver(t,e){this.cleanupResizeObserver(),e&&(this._lastWidth=e.clientWidth,this._resizeObserver=new ResizeObserver(e=>{const n=e[0];if(!n)return;const i=n.contentRect.width;Math.abs(i-this._lastWidth)<5||(this._lastWidth=i,this._resizeDebounce&&clearTimeout(this._resizeDebounce),this._resizeDebounce=setTimeout(()=>{for(const e of t.querySelectorAll(".chart-container")){const t=e.querySelector("span-chart");t&&t.remove()}this.updateDOM(t)},150))}),this._resizeObserver.observe(e))}cleanupResizeObserver(){this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),this._resizeDebounce&&(clearTimeout(this._resizeDebounce),this._resizeDebounce=null)}reset(){this.powerHistory.clear(),this.horizonMap.clear(),this.subDeviceHorizonMap.clear(),this.monitoringCache.clear(),this.monitoringMultiCache.clear(),this.graphSettingsCache.clear()}}function cT(t,e){const n=e.hysteresisPx??48,i=new WeakSet;let r=null;const o=t=>{const n=t.querySelector(e.nameSelector);return!!n&&(0!==t.clientWidth&&(n.clientWidth<1||n.scrollWidth>n.clientWidth+1))},a=()=>{const i=t.querySelectorAll(e.rowSelector);if(0===i.length)return;const a=i[0].clientWidth;if(0===a)return;if(null!==r){if(a>r+n){for(const t of i)t.classList.remove(e.foldClass);r=null}else for(const t of i)t.classList.add(e.foldClass);return}let s=!1;for(const t of i)if(o(t)){s=!0;break}if(s){for(const t of i)t.classList.add(e.foldClass);r=a}},s=new ResizeObserver(()=>a()),l=()=>{const n=t.querySelectorAll(e.rowSelector);for(const t of n)i.has(t)||(i.add(t),s.observe(t));requestAnimationFrame(()=>a())};l();const c=new MutationObserver(t=>{(t=>{const n=t=>{for(const n of t)if(n instanceof Element){if(n.matches(e.rowSelector))return!0;if(n.querySelector(e.rowSelector))return!0}return!1};for(const e of t)if(n(e.addedNodes)||n(e.removedNodes))return!0;return!1})(t)&&l()});return c.observe(t,{childList:!0,subtree:!0}),()=>{s.disconnect(),c.disconnect()}}const dT='\n :host {\n --span-accent: var(--primary-color, #4dd9af);\n }\n\n /* Card shell — replaces . Theme variables (--ha-card-*) are\n stable HA contracts (not the deprecated component APIs flagged by the\n 2026.4 frontend blog), so they stay in place to keep visual parity\n with the rest of HA\'s dashboards. */\n .span-card {\n display: block;\n padding: 24px;\n background: var(--card-background-color, #1c1c1c);\n color: var(--primary-text-color, #e0e0e0);\n border-radius: var(--ha-card-border-radius, 12px);\n border: var(--ha-card-border-width, 1px) solid var(--ha-card-border-color, var(--divider-color, #333));\n box-shadow: var(--ha-card-box-shadow, none);\n }\n\n .panel-header {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-between;\n align-items: flex-start;\n gap: 8px 16px;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--divider-color, #333);\n }\n .header-left { flex: 1 1 300px; min-width: 0; }\n .header-center { flex: 0 0 auto; }\n .header-right { flex: 0 1 auto; min-width: 0; }\n\n .panel-identity {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px 12px;\n margin-bottom: 12px;\n }\n\n .panel-title {\n font-size: 1.8em;\n font-weight: 700;\n margin: 0;\n color: var(--primary-text-color, #fff);\n }\n\n .panel-serial {\n font-size: 0.85em;\n color: var(--secondary-text-color, #999);\n font-family: monospace;\n }\n\n .panel-stats {\n display: flex;\n flex-wrap: wrap;\n gap: 16px 32px;\n }\n\n /* Favorites view header: gear + slide-to-arm + right-anchored legend/W-A cluster. */\n .favorites-summary {\n padding: 8px 24px;\n border-bottom: 1px solid var(--divider-color, #e0e0e0);\n display: flex;\n align-items: center;\n gap: 12px;\n }\n /* Override the generic .gear-icon { margin-left: auto } rule so the\n favorites gear stays flush-left instead of floating to the right of\n the flex row (same idea as .panel-identity .panel-gear does for\n real-panel headers). */\n .favorites-summary .favorites-gear {\n margin-left: 0;\n }\n /* Right-anchored cluster wrapping the shedding legend + W/A unit toggle.\n margin-left:auto moved here from .favorites-summary-unit-toggle so the\n legend and toggle cluster together, matching the real-panel header\n layout. */\n .favorites-summary-right {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 16px;\n }\n .favorites-subdevices-section {\n padding: 8px 16px 0;\n }\n\n /* Favorites view: responsive grid of per-contributing-panel status cards. */\n .favorites-panel-stats-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));\n gap: 12px;\n padding: 12px 24px;\n border-bottom: 1px solid var(--divider-color, #333);\n }\n .favorites-panel-card {\n background: var(--secondary-background-color, rgba(255, 255, 255, 0.04));\n border: 1px solid var(--divider-color, #333);\n border-radius: 8px;\n padding: 10px 14px;\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n .favorites-panel-card-title {\n font-size: 0.85em;\n font-weight: 600;\n color: var(--primary-text-color);\n opacity: 0.85;\n }\n .favorites-panel-card .panel-stats {\n gap: 10px 20px;\n }\n .favorites-panel-card .stat-value {\n font-size: 1.15em;\n }\n\n .stat { display: flex; flex-direction: column; }\n .stat-label { font-size: 0.8em; color: var(--secondary-text-color, #999); margin-bottom: 2px; }\n .stat-row { display: flex; align-items: baseline; gap: 2px; }\n .stat-value { font-size: 1.5em; font-weight: 700; color: var(--primary-text-color, #fff); }\n .stat-unit { font-size: 0.7em; font-weight: 400; color: var(--secondary-text-color, #999); }\n\n .header-right { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; padding-top: 8px; }\n .header-right-top { display: flex; gap: 20px; align-items: center; }\n .meta-item { font-size: 0.8em; color: var(--secondary-text-color, #999); }\n\n .shedding-legend { display: flex; gap: 12px; flex-wrap: wrap; justify-content: flex-end; }\n .shedding-legend-item { display: inline-flex; align-items: center; gap: 3px; }\n .shedding-legend-item span-icon { --mdc-icon-size: 16px; }\n .shedding-legend-secondary { --mdc-icon-size: 12px; opacity: 0.8; }\n .shedding-legend-text { font-size: 9px; font-weight: 600; }\n .shedding-legend-label { font-size: 0.7em; color: var(--secondary-text-color, #999); }\n\n .panel-gear {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--secondary-text-color);\n opacity: 0.6;\n padding: 4px;\n margin-left: 8px;\n vertical-align: middle;\n }\n .panel-gear:hover { opacity: 1; }\n .header-center {\n display: flex;\n align-items: flex-start;\n justify-content: center;\n padding-top: 8px;\n }\n .panel-identity .panel-gear {\n margin-left: 0;\n }\n .slide-confirm {\n position: relative;\n display: inline-flex;\n align-items: center;\n width: 160px;\n height: 28px;\n border-radius: 14px;\n background: color-mix(in srgb, var(--primary-color, #4dd9af) 20%, var(--secondary-background-color, #333));\n vertical-align: middle;\n overflow: hidden;\n user-select: none;\n touch-action: none;\n }\n .slide-confirm-text {\n position: absolute;\n width: 100%;\n text-align: center;\n font-size: 0.65em;\n font-weight: 600;\n color: var(--secondary-text-color, #999);\n pointer-events: none;\n z-index: 0;\n }\n .slide-confirm-knob {\n position: absolute;\n left: 2px;\n top: 2px;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background: var(--secondary-text-color, #666);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: grab;\n z-index: 1;\n transition: none;\n }\n .slide-confirm-knob span-icon {\n --mdc-icon-size: 14px;\n color: var(--card-background-color, #1c1c1c);\n }\n .slide-confirm-knob.snapping {\n transition: left 0.25s ease;\n }\n .slide-confirm.confirmed {\n background: color-mix(in srgb, var(--state-active-color, var(--span-accent)) 25%, transparent);\n }\n .slide-confirm.confirmed .slide-confirm-text {\n color: var(--state-active-color, var(--span-accent));\n }\n .slide-confirm.confirmed .slide-confirm-knob {\n background: var(--state-active-color, var(--span-accent));\n }\n .switches-disabled .toggle-pill {\n opacity: 0.3;\n pointer-events: none;\n }\n .unit-toggle {\n display: inline-flex;\n background: var(--secondary-background-color, #333);\n border-radius: 6px;\n overflow: hidden;\n margin-left: 8px;\n }\n .unit-btn {\n padding: 4px 10px;\n border: none;\n background: none;\n color: var(--secondary-text-color);\n font-size: 0.75em;\n font-weight: 600;\n cursor: pointer;\n }\n .unit-btn.unit-active {\n background: var(--primary-color, #4dd9af);\n color: var(--text-primary-color, #000);\n }\n\n .monitoring-summary {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 6px 16px;\n font-size: 0.8em;\n background: rgba(76, 175, 80, 0.1);\n border: 1px solid var(--divider-color, #333);\n border-top: none;\n }\n .monitoring-active { color: #4caf50; }\n .monitoring-counts { display: flex; gap: 12px; }\n .count-warning { color: #ff9800; }\n .count-alert { color: #f44336; }\n .count-overrides { color: var(--secondary-text-color); }\n\n .panel-grid {\n display: grid;\n /* Five columns: left tab label, left cell, explicit 8px spacer,\n right cell, right tab label. Spacer is in-band rather than a\n column-gap so we can keep inter-cell space without paying an\n equal gap between each cell and its tab label. The tab columns\n are sized to fit a 2-digit breaker number (the font is 0.85em\n of the panel body ≈ 14px glyph width). */\n grid-template-columns: 14px 1fr 8px 1fr 14px;\n column-gap: 0;\n row-gap: 8px;\n align-items: stretch;\n }\n\n .tab-label {\n display: flex;\n align-items: center;\n font-size: 0.85em;\n font-weight: 600;\n color: var(--secondary-text-color, #999);\n user-select: none;\n }\n .tab-left { justify-content: flex-start; }\n .tab-right { justify-content: flex-end; }\n\n .circuit-slot {\n background: var(--secondary-background-color, var(--card-background-color, #2a2a2a));\n border: 1px solid var(--divider-color, #333);\n border-radius: 12px;\n padding: 14px 16px 20px;\n min-height: 140px;\n transition: opacity 0.3s;\n position: relative;\n overflow: hidden;\n }\n\n .circuit-col-span { min-height: 280px; }\n .circuit-row-span { border-left: 3px solid var(--span-accent); }\n .circuit-off .circuit-name,\n .circuit-off .breaker-badge,\n .circuit-off .power-value,\n .circuit-off .chart-container { opacity: 0.35; }\n .circuit-off .toggle-pill,\n .circuit-off .gear-icon { opacity: 1; }\n\n .circuit-empty {\n opacity: 0.2;\n min-height: 60px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-style: dashed;\n }\n .empty-label { color: var(--secondary-text-color, #999); font-size: 0.85em; }\n\n .circuit-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 6px;\n gap: 8px;\n }\n\n .circuit-info { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }\n\n .breaker-badge {\n background: color-mix(in srgb, var(--span-accent) 15%, transparent);\n color: var(--span-accent);\n font-size: 0.7em;\n font-weight: 700;\n padding: 2px 3px;\n border-radius: 4px;\n white-space: nowrap;\n border: 1px solid color-mix(in srgb, var(--span-accent) 25%, transparent);\n flex-shrink: 0;\n }\n\n .circuit-name {\n font-size: 0.9em;\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--primary-text-color, #e0e0e0);\n }\n\n .circuit-controls { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }\n\n /* Truncation-driven fold for By Panel breaker cells. The .is-folded\n class is added/removed by the JS observer in\n src/core/truncation-fold.ts when the .circuit-name actually\n ellipsizes. Pixel thresholds can\'t get this right because name\n length varies wildly per circuit (e.g. "Spa" vs\n "Commissioned PV System") — only measuring the live name vs its\n container catches the exact moment of truncation.\n\n When folded the nested flex wrappers (.circuit-header,\n .circuit-info, .circuit-controls, .circuit-status) collapse via\n \'display: contents\' so the leaf elements participate directly in\n the outer grid: name gets the whole first row, readings/controls/\n gear drop to a second row, chart stays as the full-width third. */\n .circuit-slot.is-folded {\n display: grid;\n /* Columns: badges + relay-toggle pack tight on the left, slack\n absorbed by the 1fr column between the relay and the power\n reading, keeping power + gear pinned to the right edge. The\n previous layout placed the slack between the shedding icon and\n the relay, which read as wasted padding the user pointed out. */\n grid-template-columns: auto auto auto auto 1fr auto auto;\n /* Rows: name and controls sized to content; chart absorbs any\n extra cell height. Without the explicit 1fr on row 3, a tall\n cell (e.g. .circuit-col-span\'s 280px min-height for 240V\n double-pole breakers) distributes excess space equally across\n all three rows via the default align-content:stretch, which\n pushes the chart down and vertically inflates the badge and\n relay toggle to fill the controls row. */\n grid-template-rows: auto auto 1fr;\n grid-template-areas:\n "name name name name name name name"\n "badge util shed status . power gear"\n "chart chart chart chart chart chart chart";\n row-gap: 6px;\n column-gap: 8px;\n }\n .circuit-slot.is-folded > .circuit-header,\n .circuit-slot.is-folded > .circuit-status,\n .circuit-slot.is-folded > .circuit-header > .circuit-info,\n .circuit-slot.is-folded > .circuit-header > .circuit-controls {\n display: contents;\n }\n .circuit-slot.is-folded .circuit-name {\n grid-area: name;\n justify-self: start;\n }\n .circuit-slot.is-folded .breaker-badge {\n grid-area: badge;\n }\n .circuit-slot.is-folded .utilization {\n grid-area: util;\n }\n .circuit-slot.is-folded .shedding-icon,\n .circuit-slot.is-folded .shedding-composite {\n grid-area: shed;\n }\n .circuit-slot.is-folded .toggle-pill {\n grid-area: status;\n justify-self: end;\n }\n .circuit-slot.is-folded .power-value {\n grid-area: power;\n justify-self: end;\n }\n .circuit-slot.is-folded .gear-icon.circuit-gear {\n grid-area: gear;\n justify-self: end;\n }\n .circuit-slot.is-folded > .chart-container {\n grid-area: chart;\n }\n\n .power-value { font-size: 0.9em; color: var(--primary-text-color, #fff); white-space: nowrap; }\n .power-value strong { font-weight: 700; font-size: 1.1em; }\n .power-unit { font-size: 0.8em; font-weight: 400; color: var(--secondary-text-color, #999); margin-left: 1px; }\n .circuit-producer .power-value strong { color: var(--info-color, #4fc3f7); }\n\n .toggle-pill {\n display: flex;\n align-items: center;\n gap: 3px;\n padding: 2px 4px;\n border-radius: 10px;\n cursor: pointer;\n font-size: 0.65em;\n font-weight: 600;\n transition: background 0.2s;\n user-select: none;\n min-width: 40px;\n }\n .toggle-on {\n padding-left: 6px;\n background: color-mix(in srgb, var(--state-active-color, var(--span-accent)) 25%, transparent);\n color: var(--state-active-color, var(--span-accent));\n }\n .toggle-off {\n padding-right: 6px;\n background: color-mix(in srgb, var(--secondary-text-color) 15%, transparent);\n color: var(--secondary-text-color, #999);\n }\n .toggle-knob {\n width: 14px;\n height: 14px;\n border-radius: 50%;\n transition: background 0.2s, margin 0.2s;\n }\n .toggle-on .toggle-knob {\n background: var(--state-active-color, var(--span-accent));\n margin-left: auto;\n }\n .toggle-off .toggle-knob {\n background: var(--secondary-text-color, #999);\n margin-right: auto;\n order: -1;\n }\n\n .circuit-status {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-top: 4px;\n padding: 0 4px;\n }\n .shedding-icon { opacity: 0.8; cursor: default; }\n .shedding-composite {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n }\n .shedding-icon-secondary { opacity: 0.8; }\n .shedding-label {\n font-size: 10px;\n font-weight: 600;\n opacity: 0.8;\n }\n .gear-icon {\n background: none;\n border: none;\n cursor: pointer;\n padding: 2px;\n opacity: 0.6;\n transition: opacity 0.2s;\n margin-left: auto;\n }\n .gear-icon:hover { opacity: 1; }\n .utilization {\n font-size: 0.75em;\n font-weight: 600;\n }\n .utilization-normal { color: #4caf50; }\n .utilization-warning { color: #ff9800; }\n .utilization-alert { color: #f44336; }\n .circuit-alert {\n border-color: #f44336 !important;\n box-shadow: 0 0 8px rgba(244, 67, 54, 0.3);\n }\n .chart-container {\n width: 100%;\n aspect-ratio: 4 / 1;\n margin-top: 4px;\n overflow: hidden;\n min-width: 0;\n }\n\n .sub-devices {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 12px;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--divider-color, #333);\n }\n\n .sub-device {\n background: var(--secondary-background-color, var(--card-background-color, #2a2a2a));\n border: 1px solid var(--divider-color, #333);\n border-radius: 12px;\n padding: 14px 16px;\n }\n .sub-device-bess,\n .sub-device-full {\n grid-column: 1 / -1;\n }\n\n .sub-device-header { display: flex; gap: 10px; align-items: baseline; margin-bottom: 8px; }\n .sub-device-type { font-size: 0.7em; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--span-accent); }\n .sub-device-name { font-size: 0.85em; color: var(--secondary-text-color, #999); flex: 1; }\n .sub-power-value { font-size: 0.9em; color: var(--primary-text-color, #fff); white-space: nowrap; }\n .sub-power-value strong { font-weight: 700; font-size: 1.1em; }\n .sub-device .chart-container { margin-bottom: 8px; aspect-ratio: auto; }\n\n .bess-charts {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(0, 1fr));\n gap: 12px;\n margin-bottom: 10px;\n }\n .bess-chart-col { min-width: 0; }\n .bess-chart-title {\n font-size: 0.75em;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--secondary-text-color, #999);\n margin-bottom: 4px;\n }\n .bess-chart-col .chart-container { aspect-ratio: auto; }\n .sub-entity { display: flex; gap: 6px; padding: 3px 0; font-size: 0.85em; }\n .sub-entity-name { color: var(--secondary-text-color, #999); }\n .sub-entity-value { font-weight: 500; color: var(--primary-text-color, #e0e0e0); }\n\n /* ── Shared tab bar ────────────────────────────────────── */\n\n .shared-tab-bar {\n display: flex;\n gap: 0;\n margin-bottom: 16px;\n border-bottom: 1px solid var(--divider-color, #333);\n }\n\n .shared-tab {\n padding: 8px 16px;\n cursor: pointer;\n font-size: 0.9em;\n font-weight: 500;\n color: var(--primary-text-color);\n opacity: 0.6;\n border: none;\n border-bottom: 2px solid transparent;\n background: none;\n transition: opacity 0.15s;\n }\n\n .shared-tab:hover {\n opacity: 0.85;\n }\n\n .shared-tab.active {\n opacity: 1;\n border-bottom-color: var(--span-accent);\n }\n\n /* ── List view search ──────────────────────────────────── */\n\n .list-search-container {\n margin-bottom: 12px;\n position: relative;\n }\n\n .list-search {\n width: 100%;\n padding: 8px 36px 8px 12px;\n border-radius: 8px;\n border: 1px solid var(--divider-color, #333);\n background: var(--secondary-background-color, #2a2a2a);\n color: var(--primary-text-color);\n font-size: 0.9em;\n box-sizing: border-box;\n outline: none;\n }\n\n .list-search:focus {\n border-color: var(--span-accent);\n }\n\n .list-search-clear {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n background: none;\n border: none;\n color: var(--secondary-text-color);\n cursor: pointer;\n padding: 2px;\n display: flex;\n align-items: center;\n opacity: 0.7;\n }\n\n .list-search-clear:hover {\n opacity: 1;\n }\n\n .list-unit-toggle {\n display: inline-flex;\n margin-bottom: 12px;\n }\n\n /* ── List rows ─────────────────────────────────────────── */\n\n .list-view {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n /* Each circuit is wrapped in a .list-cell so the row + its optional\n expanded chart stay together. In single-column flex mode the cell\n just stacks naturally. In multi-column grid mode the cell becomes\n one grid item, so the chart is always in the same column as its\n row. Area headers (rendered as siblings, not inside a cell) span\n all columns via their inline "grid-column: 1 / -1". */\n .list-cell {\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n .list-view[data-columns="2"],\n .list-view[data-columns="3"] {\n display: grid;\n grid-template-columns: repeat(var(--list-cols), minmax(0, 1fr));\n gap: 6px 8px;\n flex-direction: initial;\n }\n /* On narrow viewports a 2/3-column list would squeeze rows into an\n unreadable shape, so force stacking regardless of user preference. */\n @media (max-width: 599px) {\n .list-view[data-columns="2"],\n .list-view[data-columns="3"] {\n display: flex;\n flex-direction: column;\n }\n }\n\n .list-row {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n gap: 10px;\n /* min-width: 0 lets the row shrink below the sum of its\n non-shrinking children when its parent .list-cell is in a\n narrow CSS-grid track (multi-column list mode). Without this\n the row would maintain its intrinsic min-content width and\n overflow the cell, leaving the name unshrunk and the\n truncation-fold observer with no signal to react to. */\n min-width: 0;\n background: var(--card-background-color, #1c1c1c);\n border: 1px solid var(--divider-color, #333);\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.15s;\n }\n\n .list-row:hover {\n background: var(--secondary-background-color, #2a2a2a);\n }\n\n .list-row.circuit-off {\n opacity: 0.5;\n }\n\n .list-row.list-row-expanded {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n border-bottom-color: transparent;\n }\n\n .list-circuit-name {\n flex: 1;\n color: var(--primary-text-color);\n font-size: 0.9em;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .list-status-badge {\n font-size: 0.75em;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 4px;\n flex-shrink: 0;\n }\n\n .list-status-on {\n color: #4dd9af;\n }\n\n .list-status-off {\n color: #f44336;\n }\n\n .list-power-value {\n font-size: 0.9em;\n font-weight: 600;\n flex-shrink: 0;\n /* No min-width / text-align:right: the old 70px right-aligned\n cell left a visible blank column for short readings (e.g.\n "1.3A" in a 70px slot), which robbed horizontal space from\n .list-circuit-name on narrow rows. Let the value hug the\n preceding relay control and size to its content so the freed\n width flows back into the flex:1 name column. */\n }\n\n .list-expand-toggle {\n background: none;\n border: none;\n color: var(--secondary-text-color);\n cursor: pointer;\n padding: 4px;\n transition: transform 0.2s;\n display: flex;\n align-items: center;\n flex-shrink: 0;\n }\n\n .list-expand-toggle.expanded {\n transform: rotate(180deg);\n }\n\n .list-row .gear-icon {\n background: transparent;\n border: none;\n padding: 2px;\n cursor: pointer;\n color: #555;\n display: inline-flex;\n align-items: center;\n }\n .list-row .gear-icon:hover {\n color: var(--primary-text-color);\n }\n\n /* Truncation-driven fold for list rows. The .is-folded class is\n added/removed by the JS observer in src/core/truncation-fold.ts\n when the .list-circuit-name actually ellipsizes — pixel breakpoints\n can\'t track this because name length varies wildly per circuit\n ("Spa" vs "Commissioned PV System") and any single threshold\n misfires for the other end of the range. Switch to a two-row grid\n so the name gets the full width (paired only with the expand\n chevron) and the badges/controls/reading/gear drop to a secondary\n row underneath. Named areas keep the CSS readable despite the flat\n HTML child order. */\n .list-row.is-folded {\n display: grid;\n /* Row 1: name spans the row up to the chevron at the trailing\n column. Row 2: badge + util + shed + relay-toggle pack left,\n the 1fr column absorbs slack between the relay and the power\n reading, power + gear stay pinned to the right edge. The\n earlier layout placed the slack between the shedding icon and\n the relay, which the user flagged as wasted padding. */\n grid-template-columns: auto auto auto auto 1fr auto auto;\n grid-template-areas:\n "name name name name name name chevron"\n "badge util shed status . power gear";\n row-gap: 6px;\n column-gap: 8px;\n }\n .list-row.is-folded > .list-circuit-name {\n grid-area: name;\n justify-self: start;\n }\n .list-row.is-folded > .list-expand-toggle {\n grid-area: chevron;\n }\n .list-row.is-folded > .breaker-badge {\n grid-area: badge;\n }\n .list-row.is-folded > .utilization {\n grid-area: util;\n }\n .list-row.is-folded > .shedding-icon,\n .list-row.is-folded > .shedding-composite {\n grid-area: shed;\n }\n .list-row.is-folded > .toggle-pill,\n .list-row.is-folded > .list-status-badge {\n grid-area: status;\n }\n .list-row.is-folded > .list-power-value {\n grid-area: power;\n justify-self: end;\n }\n .list-row.is-folded > .gear-icon.circuit-gear {\n grid-area: gear;\n justify-self: end;\n }\n\n /* ── Expanded circuit content ──────────────────────────── */\n\n .list-expanded-content {\n padding: 0;\n background: var(--card-background-color, #1c1c1c);\n border: 1px solid var(--divider-color, #333);\n border-top: none;\n border-radius: 0 0 8px 8px;\n margin-top: -6px;\n margin-bottom: 2px;\n }\n\n .circuit-slot.circuit-chart-only {\n border: none;\n margin: 0;\n background: none;\n padding: 8px 12px;\n min-height: 0;\n }\n\n /* ── Area headers ──────────────────────────────────────── */\n\n .area-header {\n padding: 16px 12px 6px;\n font-weight: 600;\n font-size: 0.85em;\n color: var(--secondary-text-color);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n }\n\n /* ── No results ────────────────────────────────────────── */\n\n .list-no-results {\n padding: 24px;\n text-align: center;\n color: var(--secondary-text-color);\n }\n\n';class uT{constructor(){this._ctrl=new lT,this._container=null,this._onGearClick=null,this._onToggleClick=null,this._onSidePanelClosed=null,this._onGraphSettingsChanged=null,this._foldUnobserve=null}get hass(){return this._ctrl.hass}set hass(t){this._ctrl.hass=t}set errorStore(t){this._ctrl.errorStore=t}setPanelFavorites(t){this._ctrl.setPanelFavorites(t)}async render(t,e,i,r,o){let a,s;this.stop(),this._ctrl.reset(),this._ctrl.showMonitoring=!0,this._container=t,this._ctrl.hass=e;try{const t=await se(e,i);a=t.topology,s=t.panelSize}catch(e){return void(t.innerHTML=`${Bt(e.message)}
`)}this._ctrl.init(a,r,e,o??null),await this._ctrl.monitoringCache.fetch(e,o??null),await this._ctrl.fetchAndBuildHorizonMaps();const l=Math.ceil(s/2),c=this._ctrl.monitoringCache.status,d=de(a,r),u=function(t){if(!t)return"";const e=Object.values(t.circuits??{}),i=Object.values(t.mains??{}),r=[...e,...i],o=r.filter(t=>void 0!==t.utilization_pct&&t.utilization_pct>=80&&t.utilization_pct<100).length,a=r.filter(t=>void 0!==t.utilization_pct&&t.utilization_pct>=100).length,s=r.filter(t=>t.has_override).length;return`\n \n ✓ ${n("status.monitoring")} · ${e.length} ${n("status.circuits")} · ${i.length} ${n("status.mains")} \n \n ${o>0?`${o} ${n(o>1?"status.warnings":"status.warning")} `:""}\n ${a>0?`${a} ${n(a>1?"status.alerts":"status.alert")} `:""}\n ${s>0?`${s} ${n(s>1?"status.overrides":"status.override")} `:""}\n \n
\n `}(c),h=function(t,e,n,i,r){const o=new Map,a=new Set;for(const[e,n]of Object.entries(t.circuits)){const t=n.tabs;if(!t||0===t.length)continue;const i=Math.min(...t),r=1===t.length?"single":me(t)??"single";o.set(i,{uuid:e,circuit:n,layout:r});for(const e of t)a.add(e)}const s=new Set,l=new Set;for(const[t,e]of o)if("col-span"===e.layout){const n=e.circuit.tabs,i=ge(Math.max(...n));0===ve(t)?s.add(i):l.add(i)}function c(t){const e=t.circuit.entities?.current??t.circuit.entities?.power,i=r?we(r,e??""):null;let o;if(t.circuit.always_on)o="always_on";else{const e=t.circuit.entities?.select;o=e&&n.states[e]?n.states[e].state:"unknown"}return{monInfo:i,sheddingPriority:o}}let d="";for(let t=1;t<=e;t++){const e=2*t-1,r=2*t,u=o.get(e),h=o.get(r);if(d+=`${e}
`,u&&"row-span"===u.layout){const{monInfo:e,sheddingPriority:o}=c(u);d+=Ce(u.uuid,u.circuit,t,"2 / 5","row-span",n,i,e,o),d+=`${r}
`;continue}if(!s.has(t))if(!u||"col-span"!==u.layout&&"single"!==u.layout)a.has(e)||(d+=ke(t,"2"));else{const{monInfo:e,sheddingPriority:r}=c(u);d+=Ce(u.uuid,u.circuit,t,"2",u.layout,n,i,e,r)}if(!l.has(t))if(!h||"col-span"!==h.layout&&"single"!==h.layout)a.has(r)||(d+=ke(t,"4"));else{const{monInfo:e,sheddingPriority:r}=c(h);d+=Ce(h.uuid,h.circuit,t,"4",h.layout,n,i,e,r)}d+=`${r}
`}return d}(a,l,e,r,c),p=Ne(a,e,r);t.innerHTML=`\n \n ${d}\n ${u}\n ${p?`${p}
`:""}\n ${!1!==r.show_panel?`\n \n ${h}\n
\n `:""}\n \n `,this._onGearClick=e=>{this._ctrl.onGearClick(e,t)},this._onToggleClick=e=>{this._ctrl.onToggleClick(e,t)},t.addEventListener("click",this._onGearClick),t.addEventListener("click",this._onToggleClick),this._onSidePanelClosed=()=>{this._ctrl.monitoringCache.invalidate(),this._ctrl.graphSettingsCache.invalidate()},t.addEventListener("side-panel-closed",this._onSidePanelClosed),this._onGraphSettingsChanged=()=>this._ctrl.onGraphSettingsChanged(t),t.addEventListener("graph-settings-changed",this._onGraphSettingsChanged);try{await this._ctrl.loadHistory()}catch{}this._ctrl.updateDOM(t);const f=t.querySelector(".slide-confirm");f&&(this._ctrl.bindSlideConfirm(f,t),t.classList.add("switches-disabled")),this._ctrl.setupResizeObserver(t,t),this._ctrl.startIntervals(t),this._foldUnobserve&&this._foldUnobserve(),this._foldUnobserve=cT(t,{rowSelector:".circuit-slot",nameSelector:".circuit-name",foldClass:"is-folded"})}stop(){this._ctrl.stopIntervals(),this._foldUnobserve&&(this._foldUnobserve(),this._foldUnobserve=null),this._container&&(this._onGearClick&&(this._container.removeEventListener("click",this._onGearClick),this._onGearClick=null),this._onToggleClick&&(this._container.removeEventListener("click",this._onToggleClick),this._onToggleClick=null),this._onSidePanelClosed&&(this._container.removeEventListener("side-panel-closed",this._onSidePanelClosed),this._onSidePanelClosed=null),this._onGraphSettingsChanged&&(this._container.removeEventListener("graph-settings-changed",this._onGraphSettingsChanged),this._onGraphSettingsChanged=null))}}const hT="\n display:flex;align-items:center;gap:8px;margin-bottom:8px;\n",pT="\n background:var(--secondary-background-color,#333);\n border:1px solid var(--divider-color);\n color:var(--primary-text-color);\n border-radius:4px;padding:6px 10px;width:80px;font-size:0.85em;\n",fT="\n min-width:130px;font-size:0.85em;color:var(--secondary-text-color);\n",gT="\n min-width:160px;font-size:0.85em;color:var(--secondary-text-color);\n",vT="\n background:var(--secondary-background-color,#333);\n border:1px solid var(--divider-color);\n color:var(--primary-text-color);\n border-radius:4px;padding:6px 10px;flex:1;font-size:0.85em;\n font-family:monospace;\n";function mT(t,e,n,i,r){return`\n ${i} \n `}class yT{constructor(){this.errorStore=null,this._debounceTimer=null,this._configEntryId=null,this._notifyCloseHandler=null,this._headerHTML=""}stop(){this._notifyCloseHandler&&(document.removeEventListener("click",this._notifyCloseHandler),this._notifyCloseHandler=null),this._debounceTimer&&(clearTimeout(this._debounceTimer),this._debounceTimer=null)}async render(t,e,i,r=""){let o;void 0!==i&&(this._configEntryId=i),this._headerHTML=r,this._notifyCloseHandler&&(document.removeEventListener("click",this._notifyCloseHandler),this._notifyCloseHandler=null);try{const t={};this._configEntryId&&(t.config_entry_id=this._configEntryId);const n=await e.callWS({type:"call_service",domain:s,service:"get_monitoring_status",service_data:t,return_response:!0});o=function(t){if(!t||"object"!=typeof t)return null;const e=t,n={};return"boolean"==typeof e.enabled&&(n.enabled=e.enabled),e.global_settings&&"object"==typeof e.global_settings&&(n.global_settings=e.global_settings),e.circuits&&"object"==typeof e.circuits&&(n.circuits=e.circuits),e.mains&&"object"==typeof e.mains&&(n.mains=e.mains),n}(n?.response)}catch(t){console.warn("SPAN Panel: monitoring status fetch failed",t),o=null}const a=o?.global_settings??{},l=!0===o?.enabled,c=o?.circuits??{},d=o?.mains??{},u=new Set;for(const t of Object.keys(e.states||{}))t.startsWith("notify.")&&u.add(t);const h=new Set(["notify","send_message"]);for(const t of Object.keys(e.services?.notify||{}))h.has(t)||u.add(`notify.${t}`);u.add("event_bus");const p=[...u].sort(),f=a.notify_targets??"",g=("string"==typeof f?f.split(","):f).map(t=>t.trim()).filter(Boolean),v=p.length>0&&p.every(t=>g.includes(t)),m=a.notification_title_template??"SPAN: {name} {alert_type}",y=a.notification_message_template??"{name} at {current_a}A ({utilization_pct}% of {breaker_rating_a}A rating)",_=a.notification_priority??"default",b=Object.entries(c).sort(([,t],[,e])=>(t.name??"").localeCompare(e.name??"")),x=Object.entries(d),w=[...b,...x],S=w.length>0&&w.every(([,t])=>!1!==t.monitoring_enabled),C=w.some(([,t])=>!1!==t.monitoring_enabled),k=b.map(([t,e])=>{const i=Bt(e.name??t),r=!1!==e.monitoring_enabled,o=!0===e.has_override,a=r?"":"opacity:0.4;",s=Bt(t);return`\n \n \n \n \n ${i} \n \n \n ${mT(s,"continuous_threshold_pct",e.continuous_threshold_pct,"%","circuit")}\n ${mT(s,"spike_threshold_pct",e.spike_threshold_pct,"%","circuit")}\n ${mT(s,"window_duration_m",e.window_duration_m,"m","circuit")}\n ${mT(s,"cooldown_duration_m",e.cooldown_duration_m,"m","circuit")}\n \n ${o?`\n ${n("monitoring.reset")}\n `:""}\n \n \n `}).join(""),M=Object.entries(d).map(([t,e])=>{const i=Bt(e.name??t),r=!1!==e.monitoring_enabled,o=!0===e.has_override,a=r?"":"opacity:0.4;",s=Bt(t);return`\n \n \n \n \n ${i} \n \n \n ${mT(s,"continuous_threshold_pct",e.continuous_threshold_pct,"%","mains")}\n ${mT(s,"spike_threshold_pct",e.spike_threshold_pct,"%","mains")}\n ${mT(s,"window_duration_m",e.window_duration_m,"m","mains")}\n ${mT(s,"cooldown_duration_m",e.cooldown_duration_m,"m","mains")}\n \n ${o?`\n ${n("monitoring.reset")}\n `:""}\n \n \n `}).join("");t.innerHTML=`\n ${this._headerHTML}\n \n
${n("monitoring.heading")} \n\n
\n
\n
${n("monitoring.global_settings")} \n \n \n ${n("monitoring.enabled")} \n \n \n\n
\n
\n ${n("monitoring.continuous")} \n \n
\n
\n ${n("monitoring.spike")} \n \n
\n
\n ${n("monitoring.window")} \n \n
\n
\n ${n("monitoring.cooldown")} \n \n
\n\n
\n
${n("notification.heading")} \n\n
\n
${n("notification.targets")} \n
\n \n ${n("notification.all_targets")} \n \n
\n
\n ${g.length?g.map(t=>"event_bus"===t?n("notification.event_bus_target"):Bt(t)).join(", "):n("notification.none_selected")} \n ▼ \n \n
\n ${0===p.length?`
${n("notification.no_targets")}
`:p.map(t=>{const i=g.includes(t),r="event_bus"===t,o=r?null:e.states[t],a=o?.attributes?.friendly_name,s=r?n("notification.event_bus_target"):a?`${Bt(a)} (${Bt(t)})`:Bt(t);return`
\n \n ${s} \n `}).join("")}\n
\n
\n
\n\n
\n ${n("notification.priority")} \n \n ${["default","passive","active","time-sensitive","critical"].map(t=>`${n(`notification.priority.${t.replace("-","_")}`)} `).join("")}\n \n \n ${"critical"===_?n("notification.hint.critical"):"time-sensitive"===_?n("notification.hint.time_sensitive"):"passive"===_?n("notification.hint.passive"):"active"===_?n("notification.hint.active"):""}\n \n
\n\n
\n ${n("notification.title_template")} \n \n
\n\n
\n ${n("notification.message_template")} \n \n
\n\n
\n ${n("notification.placeholders")} {name} {entity_id} {alert_type}\n {current_a} {breaker_rating_a} {threshold_pct}\n {utilization_pct} {window_m} {local_time}\n
\n
\n ${n("notification.event_bus_help")} span_panel_current_alert\n ${n("notification.event_bus_payload")} alert_source alert_id\n alert_name alert_type current_a\n breaker_rating_a threshold_pct utilization_pct\n panel_serial window_duration_s local_time\n
\n\n
\n ${n("notification.test_label")} \n \n ${n("notification.test_button")}\n \n \n
\n
\n\n
\n
\n\n
${n("monitoring.monitored_points")} \n
\n
\n `;const T=t.querySelector("#toggle-all-circuits");T&&!S&&C&&(T.indeterminate=!0);const I=t.querySelector("#notify-all-targets");if(I&&p.length>0){const t=g.length>0;!v&&t&&(I.indeterminate=!0)}this._bindGlobalControls(t,e),this._bindNotifyTargetSelect(t,e),this._bindNotificationSettings(t,e),this._bindToggleAll(t,e,c,d),this._bindCircuitToggles(t,e),this._bindMainsToggles(t,e),this._bindThresholdInputs(t,e),this._bindResetButtons(t,e)}_serviceData(t){return this._configEntryId&&(t.config_entry_id=this._configEntryId),t}_callSetGlobal(t,e){return t.callWS({type:"call_service",domain:s,service:"set_global_monitoring",service_data:this._serviceData({...e})})}_bindGlobalControls(t,e){const i=t.querySelector("#monitoring-enabled"),r=t.querySelector("#global-fields"),o=t.querySelector("#global-status"),a=()=>{const e=[["continuous_threshold_pct","#g-continuous"],["spike_threshold_pct","#g-spike"],["window_duration_m","#g-window"],["cooldown_duration_m","#g-cooldown"]],n={};for(const[i,r]of e){const e=t.querySelector(r);if(!e)return null;const o=parseInt(e.value,10);if(Number.isNaN(o))return null;n[i]=o}return n},s=(t,e,i)=>{if(!t)return;const r=e instanceof Error?e.message:i;t.textContent=`${n("error.prefix")} ${r}`,t.style.color="var(--error-color, #f44336)"},l=()=>{this._debounceTimer&&clearTimeout(this._debounceTimer),this._debounceTimer=setTimeout(async()=>{const i=a();if(i)try{await this._callSetGlobal(e,i),await this.render(t,e)}catch(t){s(o,t,n("error.failed_save"))}else s(o,null,n("error.failed_save"))},p)};i&&i.addEventListener("change",async()=>{const o=i.checked;r&&(r.style.opacity=o?"":"0.4",r.style.pointerEvents=o?"":"none");const l=t.querySelector("#global-status");try{if(o){const t=a();if(!t)return void s(l,null,n("error.failed"));await this._callSetGlobal(e,t)}else await this._callSetGlobal(e,{enabled:!1})}catch(t){return void s(l,t,n("error.failed"))}await this.render(t,e)});for(const e of t.querySelectorAll("#global-fields input[type=number]"))e.addEventListener("input",l)}_bindNotifyTargetSelect(t,e){const i=t.querySelector("#notify-target-btn"),r=t.querySelector("#notify-target-dropdown"),o=t.querySelector("#notify-target-label");if(!i||!r)return;i.addEventListener("click",t=>{t.stopPropagation();const e="none"!==r.style.display;r.style.display=e?"none":"block"});const a=e=>{const n=t.querySelector("#notify-target-select");n&&!n.contains(e.target)&&(r.style.display="none")};document.addEventListener("click",a),this._notifyCloseHandler=a;const s=()=>{const i=[...t.querySelectorAll(".notify-target-cb:checked")].map(t=>t.value);if(o){const t=i.map(t=>"event_bus"===t?n("notification.event_bus_target"):t);o.textContent=t.length?t.join(", "):n("notification.none_selected")}const r=t.querySelector("#notify-all-targets");if(r){const e=[...t.querySelectorAll(".notify-target-cb")];r.checked=e.length>0&&e.every(t=>t.checked),r.indeterminate=!r.checked&&e.some(t=>t.checked)}this._debounceTimer&&clearTimeout(this._debounceTimer),this._debounceTimer=setTimeout(async()=>{try{await this._callSetGlobal(e,{notify_targets:i.join(", ")})}catch(t){console.warn("SPAN Panel: notification targets save failed",t),this.errorStore?.add({key:"service:monitoring",level:"error",message:n("error.threshold_failed"),persistent:!1})}},p)},l=t.querySelector("#notify-all-targets");l&&l.addEventListener("change",()=>{for(const e of t.querySelectorAll(".notify-target-cb"))e.checked=l.checked;const e=t.querySelector("#notify-target-btn");e&&(e.style.opacity=l.checked?"0.4":"",e.style.pointerEvents=l.checked?"none":""),l.checked&&(r.style.display="none"),s()});for(const e of t.querySelectorAll(".notify-target-cb"))e.addEventListener("change",()=>{s()})}_bindNotificationSettings(t,e){const i=t.querySelector("#g-priority"),r=t.querySelector("#g-title-template"),o=t.querySelector("#g-message-template"),a=(t,i)=>{this._debounceTimer&&clearTimeout(this._debounceTimer),this._debounceTimer=setTimeout(async()=>{try{await this._callSetGlobal(e,{[t]:i})}catch(t){console.warn("SPAN Panel: notification settings save failed",t),this.errorStore?.add({key:"service:monitoring",level:"error",message:n("error.threshold_failed"),persistent:!1})}},p)};i&&i.addEventListener("change",async()=>{try{await this._callSetGlobal(e,{notification_priority:i.value}),await this.render(t,e)}catch(t){console.warn("SPAN Panel: notification priority change failed",t),this.errorStore?.add({key:"service:monitoring",level:"error",message:n("error.threshold_failed"),persistent:!1})}}),r&&r.addEventListener("input",()=>{a("notification_title_template",r.value)}),o&&o.addEventListener("input",()=>{a("notification_message_template",o.value)});const l=t.querySelector("#test-notification-btn"),c=t.querySelector("#test-notification-status");l&&l.addEventListener("click",async()=>{l.disabled=!0,c&&(c.textContent=n("notification.test_sending"),c.style.color="var(--secondary-text-color)");try{this._debounceTimer&&(clearTimeout(this._debounceTimer),this._debounceTimer=null);const i=[...t.querySelectorAll(".notify-target-cb:checked")].map(t=>t.value).join(", ");await this._callSetGlobal(e,{notify_targets:i});const r={};this._configEntryId&&(r.config_entry_id=this._configEntryId),await e.callWS({type:"call_service",domain:s,service:"test_notification",service_data:r}),c&&(c.textContent=n("notification.test_sent"),c.style.color="var(--success-color, #4caf50)")}catch(t){if(c){const e=t instanceof Error?t.message:n("error.failed");c.textContent=`${n("error.prefix")} ${e}`,c.style.color="var(--error-color, #f44336)"}}finally{l.disabled=!1}})}_bindToggleAll(t,e,i,r){const o=t.querySelector("#toggle-all-circuits");o&&o.addEventListener("change",async()=>{const a=o.checked,l=[...Object.keys(i).map(t=>e.callWS({type:"call_service",domain:s,service:"set_circuit_threshold",service_data:this._serviceData({circuit_id:t,monitoring_enabled:a})}).catch(t=>{console.warn("SPAN Panel: circuit monitoring toggle failed",t),this.errorStore?.add({key:"service:monitoring",level:"error",message:n("error.threshold_failed"),persistent:!1})})),...Object.keys(r).map(t=>e.callWS({type:"call_service",domain:s,service:"set_mains_threshold",service_data:this._serviceData({leg:t,monitoring_enabled:a})}).catch(t=>{console.warn("SPAN Panel: mains monitoring toggle failed",t),this.errorStore?.add({key:"service:monitoring",level:"error",message:n("error.threshold_failed"),persistent:!1})}))];await Promise.all(l),await this.render(t,e)})}_bindMainsToggles(t,e){for(const i of t.querySelectorAll(".mains-toggle"))i.addEventListener("change",async()=>{const r=i.dataset.entity,o=i.checked;try{await e.callWS({type:"call_service",domain:s,service:"set_mains_threshold",service_data:this._serviceData({leg:r,monitoring_enabled:o})})}catch(t){return console.warn("SPAN Panel: mains threshold toggle failed",t),this.errorStore?.add({key:"service:monitoring",level:"error",message:n("error.threshold_failed"),persistent:!1}),void(i.checked=!o)}await this.render(t,e)})}_bindCircuitToggles(t,e){for(const i of t.querySelectorAll(".circuit-toggle"))i.addEventListener("change",async()=>{const r=i.dataset.entity,o=i.checked;try{await e.callWS({type:"call_service",domain:s,service:"set_circuit_threshold",service_data:this._serviceData({circuit_id:r,monitoring_enabled:o})})}catch(t){return console.warn("SPAN Panel: circuit threshold toggle failed",t),this.errorStore?.add({key:"service:monitoring",level:"error",message:n("error.threshold_failed"),persistent:!1}),void(i.checked=!o)}await this.render(t,e)})}_bindThresholdInputs(t,e){const i=new Map;for(const r of t.querySelectorAll(".threshold-input"))r.addEventListener("input",()=>{const o=`${r.dataset.entity}-${r.dataset.field}`,a=i.get(o);a&&clearTimeout(a),i.set(o,setTimeout(async()=>{const i=parseInt(r.value,10);if(!i||i<1)return;const o=r.dataset.entity,a=r.dataset.field,l=r.dataset.type,c="mains"===l?"set_mains_threshold":"set_circuit_threshold",d="mains"===l?"leg":"circuit_id";try{await e.callWS({type:"call_service",domain:s,service:c,service_data:this._serviceData({[d]:o,[a]:i})}),await this.render(t,e)}catch(t){console.warn("SPAN Panel: threshold input save failed",t),this.errorStore?.add({key:"service:monitoring",level:"error",message:n("error.threshold_failed"),persistent:!1}),r.style.borderColor="var(--error-color, #f44336)"}},800))})}_bindResetButtons(t,e){for(const n of t.querySelectorAll(".reset-btn"))n.addEventListener("click",async()=>{const i=n.dataset.entity;if(!i)return;const r=n.dataset.type,o="mains"===r?"clear_mains_threshold":"clear_circuit_threshold",a=this._serviceData("mains"===r?{leg:i}:{circuit_id:i});await e.callService(s,o,a),await this.render(t,e)})}}function _T(t,e){return null!==t&&t.toLowerCase().includes(e)}function bT(t,e){const n=t[e];return"string"==typeof n?n:""}function xT(t,e){return{enabled:null!==e&&null===e.disabledBy,name:null===e?"":e.name,deviceClass:t.curation.device_class??"",stateClass:t.curation.state_class??"",promote:"none"===t.curation.entity_category}}function wT(t,e){const n=Number(e);return{unit_of_measurement:t||null,display_precision:""!==e&&Number.isFinite(n)?n:null}}function ST(t,e,n){return""!==t&&e.includes(t)&&n.length>0}function CT(t){if(!t)return"";const e=t.replace(/_/g," ");return e.charAt(0).toUpperCase()+e.slice(1)}const kT=["0","1","2","3","4","5","6"],MT="var(--secondary-text-color,#999)",TT="var(--primary-color,#4dd9af)",IT="var(--warning-color,#ff9800)",DT="var(--card-background-color,#1c1c1c)",AT="var(--secondary-background-color,#232323)",PT="var(--divider-color,#333)",LT=`background:${AT};border:1px solid ${PT};color:var(--primary-text-color);border-radius:4px;padding:4px 8px;font-size:0.85em;`,ET=`${LT}min-width:0;`,zT="display:flex;align-items:center;gap:12px;flex-wrap:wrap;",NT=`font-size:0.85em;color:${MT};min-width:130px;`,OT=`color:${MT};font-size:0.75em;`,$T=`background:none;border:1px solid ${PT};color:var(--primary-text-color);border-radius:6px;padding:6px 12px;font-size:0.8em;cursor:pointer;`;function RT(t,e){const n=e?TT:MT;return`${Bt(t)} `}function HT(t,e,n){const i=e.map(t=>`${Bt(t.label)} `).join("");return`${i} `}function FT(t){return"total_increasing"===t?n("adopted.warn_total_increasing"):"statistics_removed"===t?n("adopted.warn_statistics_removed"):t}function BT(t){return t instanceof Error||t&&"object"==typeof t&&"string"==typeof t.message?t.message:String(t)}class VT{constructor(){this._container=null,this._hass=null,this._deviceId=null,this._groups=[],this._loadError=null,this._query="",this._expandedKey=null,this._editor=null,this._unitsCache=new Map,this._refreshTimer=null,this._onClick=t=>{this._handleClick(t)},this._onInput=t=>{this._handleInput(t)},this._onChange=t=>{this._handleChange(t)}}stop(){this._refreshTimer&&(clearTimeout(this._refreshTimer),this._refreshTimer=null),this._unbind()}async render(t,e,n){const i=void 0===n?this._deviceId:n||null;i!==this._deviceId&&(this._deviceId=i,this._expandedKey=null,this._editor=null,this._query=""),this._unbind(),this._container=t,this._hass=e,await this._fetchList(e,!1),this._paint()}async _fetchList(t,e){if(!this._deviceId)return this._groups=[],void(this._loadError=null);try{const e=await t.callWS({type:`${s}/adopted/list`,device_id:this._deviceId});this._groups=Array.isArray(e?.devices)?e.devices:[],this._loadError=null}catch(t){if(e)return;this._groups=[],this._loadError=BT(t)}}async _fetchSeed(t,e){try{return function(t){if(!t||"object"!=typeof t)return null;const e=t;if("string"!=typeof e.entity_id)return null;const n=e.options&&"object"==typeof e.options?e.options:{},i=n.sensor&&"object"==typeof n.sensor?n.sensor:{},r=i.display_precision;return{disabledBy:"string"==typeof e.disabled_by?e.disabled_by:null,name:bT(e,"name"),unit:bT(i,"unit_of_measurement"),precision:"number"==typeof r?String(r):""}}(await t.callWS({type:"config/entity_registry/get",entity_id:e}))}catch{return null}}async _fetchUnits(t,e){if(!e)return[];const n=this._unitsCache.get(e);if(n)return n;try{const n=await t.callWS({type:"sensor/device_class_convertible_units",device_class:e}),i=Array.isArray(n?.units)?n.units.filter(t=>"string"==typeof t):[];return this._unitsCache.set(e,i),i}catch{return[]}}_findRow(t){for(const e of this._groups)for(const n of e.rows)if(n.key===t)return n;return null}_paint(){const t=this._container;t&&(t.innerHTML=`\n \n
${n("adopted.heading")} \n
${n("adopted.description")}
\n\n
\n \n \n
\n\n
${this._groupsHTML()}
\n
\n `,this._bind())}_paintGroups(){const t=this._container?.querySelector("#adopted-groups");t&&(t.innerHTML=this._groupsHTML())}_groupsHTML(){if(null!==this._loadError)return`${Bt(n("adopted.load_failed"))} — ${Bt(this._loadError)}
`;if(0===this._groups.length)return`${n("adopted.none")}
`;const t=function(t,e){const n=e.trim().toLowerCase();if(!n)return t;const i=[];for(const e of t){if(_T(e.name,n)){i.push(e);continue}const t=e.rows.filter(t=>_T(t.name,n));t.length>0&&i.push({...e,rows:t})}return i}(this._groups,this._query);return 0===t.length?`${n("adopted.no_results")}
`:t.map(t=>this._groupHTML(t)).join("")}_groupHTML(t){const e=t.adopted_device?RT(n("adopted.adopted_device"),!1):RT(n("adopted.vendor_readings"),!0),r=i("adopted.count",{count:String(t.rows.length)}),o=t.adopted_device?`${n("adopted.via_panel")} · ${r}`:r;return`\n \n ${Bt(t.name??"")} \n ${e}\n ${Bt(o)} \n
\n \n ${t.rows.map(t=>this._rowHTML(t)).join("")}\n
\n `}_rowHTML(t){const e=this._expandedKey===t.key,i=e&&this._editor?this._editorHTML(t,this._editor):"",r=e?`display:flex;align-items:center;padding:12px 16px;gap:10px;background:${AT};border:1px solid ${PT};border-bottom-color:transparent;border-radius:8px 8px 0 0;cursor:pointer;`:`display:flex;align-items:center;padding:12px 16px;gap:10px;background:${DT};border:1px solid ${PT};border-radius:8px;cursor:pointer;`;return`\n \n \n ${i}\n
\n `}_editorHTML(t,e){const r=[];null!==e.seed?(r.push(this._enableHTML(e)),r.push(this._identityHTML(e))):r.push(`${n("adopted.registry_unavailable")}
`),t.allowed_device_classes.length>0&&r.push(this._deviceClassHTML(t,e)),t.allowed_state_classes.length>0&&r.push(this._stateClassHTML(t,e)),r.push(this._prominenceHTML(e)),null!==e.seed&&ST(e.form.deviceClass,t.allowed_device_classes,e.units)&&r.push(this._displayHTML(t,e)),t.stale_fields.length>0&&r.push(`${Bt(i("adopted.stale_note",{fields:t.stale_fields.join(", ")}))}
`),r.push(this._actionsHTML(e)),null!==e.confirm&&r.push(this._confirmHTML(t,e)),null!==e.error&&r.push(`${Bt(e.error)}
`);for(const t of e.notices)r.push(`${Bt(t)}
`);return r.push(`${Bt(function(t){const e=[t.path,t.datatype];return t.unit&&e.push(t.unit),e.push(t.settable?n("adopted.settable"):n("adopted.read_only")),e.join(" · ")}(t))}
`),`\n \n ${r.join("")}\n
\n `}_enableHTML(t){const e=t.form.enabled,i=e?TT:MT;return`\n \n ${n("adopted.enable_entity")} \n \n ${n(e?"adopted.enabled":"adopted.disabled")} \n \n \n ${n("adopted.enable_note")} \n
\n `}_identityHTML(t){return`\n \n ${n("adopted.name")} \n \n
\n `}_deviceClassHTML(t,e){const r=[{value:"",label:n("adopted.no_device_class")},...t.allowed_device_classes.map(t=>({value:t,label:CT(t)}))],o=t.unit?i("adopted.device_class_note",{unit:t.unit}):n("adopted.device_class_note_unitless");return`\n \n ${n("adopted.device_class")} \n ${HT("device_class",r,e.form.deviceClass)}\n ${Bt(o)} \n
\n `}_stateClassHTML(t,e){const i=[{value:"",label:n("adopted.no_statistics")},...t.allowed_state_classes.map(t=>({value:t,label:CT(t)}))];return`\n \n ${n("adopted.statistics_class")} \n ${HT("state_class",i,e.form.stateClass)}\n ${n("adopted.statistics_note")} \n
\n `}_prominenceHTML(t){const e=(t,e,n)=>`${Bt(e)} `;return`\n \n ${n("adopted.prominence")} \n \n ${e("diagnostic",n("adopted.diagnostic"),!t.form.promote)}\n ${e("standard",n("adopted.standard"),t.form.promote)}\n \n
\n `}_displayHTML(t,e){const i=[{value:"",label:t.unit?`${t.unit} — ${n("adopted.unit_as_published")}`:n("adopted.unit_as_published")},...e.units.map(t=>({value:t,label:t}))],r=[{value:"",label:n("adopted.precision_default")},...kT.map(t=>({value:t,label:t}))];return`\n \n ${n("adopted.display_unit")} \n ${HT("unit",i,e.unit)}\n ${n("adopted.precision")} \n ${HT("precision",r,e.precision)}\n
\n `}_actionsHTML(t){const e=t.busy?" disabled":"";return`\n \n ${n("adopted.save")} \n ${n("adopted.clear")} \n ${n("adopted.reload_note")} \n
\n `}_confirmHTML(t,e){const r="clearing"===e.confirm,o=r?i("adopted.confirm_clearing_subject",{name:t.name}):i("adopted.confirm_setting",{name:t.name,value:CT(e.form.stateClass)}),a=n(r?"adopted.confirm_clearing":"adopted.confirm_total_increasing");return`\n \n
\n
\n
${n("adopted.confirm_heading")} \n
\n
${Bt(o)}
\n
${a}
\n
\n ${n("adopted.cancel")} \n ${n("adopted.save_anyway")} \n
\n
\n `}_bind(){const t=this._container;t&&(t.addEventListener("click",this._onClick),t.addEventListener("input",this._onInput),t.addEventListener("change",this._onChange))}_unbind(){const t=this._container;t&&(t.removeEventListener("click",this._onClick),t.removeEventListener("input",this._onInput),t.removeEventListener("change",this._onChange))}async _handleClick(t){const e=t.target;if(!e)return;const n=e.closest("[data-action]");if(n)return void await this._handleAction(n);const i=e.closest(".adopted-row-header"),r=i?.dataset.key;return r?this._expandedKey===r?(this._expandedKey=null,this._editor=null,void this._paintGroups()):void await this._openEditor(r):void 0}async _handleAction(t){const e=this._editor;if(e)switch(t.dataset.action){case"toggle-enable":return e.form={...e.form,enabled:!e.form.enabled},void this._paintGroups();case"prominence":return e.form={...e.form,promote:"standard"===t.dataset.value},void this._paintGroups();case"save":return void(e.busy||await this._save(!1));case"clear":return void(e.busy||await this._save(!0));case"confirm-cancel":return e.confirm=null,void this._paintGroups();case"confirm-save":{const t=e.confirmClears;return e.confirm=null,void await this._commit(t)}default:return}}_handleInput(t){const e=t.target;if(!e)return;if("adopted-filter"===e.id)return this._query=e.value,void this._paintGroups();const n=this._editor,i=e.dataset.field;if(!n||!i)return;const r=e.value;"name"===i&&(n.form={...n.form,name:r})}async _handleChange(t){const e=t.target,n=this._editor,i=e?.dataset.field;if(e&&n&&i)switch(i){case"device_class":return n.form={...n.form,deviceClass:e.value},n.units=this._hass?await this._fetchUnits(this._hass,e.value):[],void this._paintGroups();case"state_class":return void(n.form={...n.form,stateClass:e.value});case"unit":return void(n.unit=e.value);case"precision":return void(n.precision=e.value);default:return}}async _openEditor(t){const e=this._findRow(t),n=this._hass;if(!e||!n)return;this._expandedKey=t,this._editor={form:xT(e,null),seed:null,units:[],unit:"",precision:"",confirm:null,confirmClears:!1,busy:!0,error:null,notices:[]},this._paintGroups();const i=null===e.entity_id?null:await this._fetchSeed(n,e.entity_id);if(this._expandedKey!==t)return;const r=xT(e,i),o=await this._fetchUnits(n,r.deviceClass);this._expandedKey===t&&(this._editor={form:r,seed:i,units:o,unit:i?.unit??"",precision:i?.precision??"",confirm:null,confirmClears:!1,busy:!1,error:null,notices:[]},this._paintGroups())}async _save(t){const e=this._editor,n=null===this._expandedKey?null:this._findRow(this._expandedKey);if(!e||!n)return;const i=function(t,e){return"total_increasing"===e.stateClass?"total_increasing":t.curation.state_class&&""===e.stateClass?"clearing":null}(n,this._formFor(e,t));if(null!==i)return e.confirm=i,e.confirmClears=t,e.error=null,e.notices=[],void this._paintGroups();await this._commit(t)}_formFor(t,e){return e?{...t.form,deviceClass:"",stateClass:"",promote:!1}:t.form}async _commit(t){const e=this._editor,i=this._hass,r=null===this._expandedKey?null:this._findRow(this._expandedKey);if(!(e&&i&&r&&this._deviceId))return;const o=this._formFor(e,t),a=function(t,e){const n={};return e.deviceClass&&(n.device_class=e.deviceClass),e.stateClass&&(n.state_class=e.stateClass),e.promote&&(n.entity_category="none"),{registryUpdate:null===t.entity_id?null:{type:"config/entity_registry/update",entity_id:t.entity_id,name:e.name||null,disabled_by:e.enabled?null:"user"},curate:{key:t.key,record:n}}}(r,o);e.busy=!0,e.error=null,e.notices=[],this._paintGroups();let l=e.seed;try{const c=t||null===l?null:function(t,e,n){if(null===t.registryUpdate||null===e||!function(t,e){return null!==t&&(e.enabled!==(null===t.disabledBy)||e.name!==t.name)}(e,n))return null;const i={...t.registryUpdate};return function(t,e){return e.enabled===(null===t.disabledBy)}(e,n)&&delete i.disabled_by,i}(a,l,o);null!==c&&null!==l&&(await i.callWS(c),l=function(t,e){return{...t,disabledBy:e.enabled?null:t.disabledBy??"user",name:e.name}}(l,o),e.seed=l),!t&&null!==l&&null!==r.entity_id&&ST(o.deviceClass,r.allowed_device_classes,e.units)&&function(t,e,n){return null!==t&&(e!==t.unit||n!==t.precision)}(l,e.unit,e.precision)&&(await i.callWS({type:"config/entity_registry/update",entity_id:r.entity_id,options_domain:"sensor",options:wT(e.unit,e.precision)}),l={...l,unit:e.unit,precision:e.precision},e.seed=l);const d=await i.callWS({type:`${s}/adopted/curate`,device_id:this._deviceId,key:a.curate.key,record:a.curate.record});r.curation=d?.record??{},e.form=o,e.notices=[n("adopted.saved"),...Array.isArray(d?.warnings)?d.warnings.map(FT):[]]}catch(t){return e.error=BT(t),e.busy=!1,void this._paintGroups()}e.busy=!1,this._paintGroups(),this._scheduleRefresh()}_scheduleRefresh(){this._refreshTimer&&clearTimeout(this._refreshTimer),this._refreshTimer=setTimeout(()=>{this._refreshTimer=null;const t=this._hass;t&&this._fetchList(t,!0).then(()=>this._paintGroups())},2e3)}}function WT(t=""){const e=t?` value="${Bt(t)}"`:"",i=t?"":"display:none;";return`\n \n \n \n \n \n
\n `}function UT(t,e,i,r,o,a,s){const c=e.entities?.power,d=c?i.states[c]:null,u=d&&parseFloat(d.state)||0,h=e.entities?.switch,p=h?i.states[h]:null,f=p?"on"===p.state:(d?.attributes?.relay_state||e.relay_state)===l,g=e.breaker_rating_a,m=g?`${Math.round(g)}A`:"",y=Bt(e.name||n("grid.unknown")),_=ye(r),b="current"===_.entityRole;let x;if(f)if(b){const t=e.entities?.current,n=t?i.states[t]:null,r=n&&parseFloat(n.state)||0;x=`${_.format(r)} A `}else x=`${pe(u)} ${he(u)} `;else x="";const w=a||"unknown";let S="";if("unknown"!==w){const t=v[w]??v.unknown??{icon:"mdi:help",color:"#999",label:()=>"Unknown"};S=t.icon2?`\n \n \n `:t.textLabel?`\n \n ${t.textLabel} \n `:` `}let C="",k=o?.utilization_pct??null;if(null==k&&e.breaker_rating_a){const t=e.entities?.current,n=t?i.states[t]:null,r=n?Math.abs(parseFloat(n.state)||0):0;k=Math.round(r/e.breaker_rating_a*1e3)/10}if(null!=k){C=`=80?"utilization-warning":"utilization-normal"}">${Math.round(k)}% `}const M=`\n \n `,T=!1!==e.is_user_controllable&&!!e.entities?.switch?`\n ${n(f?"grid.on":"grid.off")} \n \n
`:`${f?"ON":"OFF"} `;return`\n \n ${m?`${m} `:""}\n ${C}\n ${y} \n ${S}\n ${T}\n \n ${x}\n \n ${M}\n \n \n \n
\n `}function GT(t,e,n,i,r){const o=e.entities?.power,a=o?n.states[o]:null,s=a&&parseFloat(a.state)||0,d=e.device_type===c||s<0,u=e.entities?.switch,h=u?n.states[u]:null,p=Se(0,r,h?"on"===h.state:(a?.attributes?.relay_state||e.relay_state)===l,d),f=Bt(t);return`\n \n `}function qT(t){return``}function jT(t,e,n){const i=t.entities?.switch,r=i?e.states[i]:null,o=t.entities?.power,a=o?e.states[o]:null,s=r?"on"===r.state:(a?.attributes?.relay_state||t.relay_state)===l;let c;if("current"===(n.chart_metric||"power")){const n=t.entities?.current,i=n?e.states[n]:null;c=i?Math.abs(parseFloat(i.state)||0):0}else c=a?Math.abs(parseFloat(a.state)||0):0;return{isOn:s,value:c}}function XT(t,e){if(t.always_on)return"always_on";const n=t.entities?.select,i=n?e.states[n]:null;return i?i.state:"unknown"}function YT(t,e,n,i){const r=jT(t,n,i),o=jT(e,n,i);return r.isOn&&!o.isOn?-1:!r.isOn&&o.isOn?1:o.value-r.value}function ZT(t,e,n){return t.sort((t,i)=>YT(t[1],i[1],e,n))}function KT(t){return t.entities?.current??t.entities?.power??""}class QT{constructor(t){this._expandedUuids=new Set,this._searchQuery="",this._container=null,this._clickHandler=null,this._inputHandler=null,this._graphSettingsHandler=null,this._hass=null,this._topology=null,this._config=null,this._monitoringStatus=null,this._viewName=null,this._columns=1,this._foldUnobserve=null,this._ctrl=t}setColumns(t){const e=Math.max(1,Math.min(3,Math.floor(t)));this._columns=e}setInitialExpansion(t){this._expandedUuids=new Set(t)}setInitialSearchQuery(t){this._searchQuery=t}setViewName(t){this._viewName=t}renderActivityView(t,e,n,i,r,o){this._unbindEvents(),this._hass=e,this._topology=n,this._config=i,this._monitoringStatus=r;const a=ZT(Object.entries(n.circuits),e,i);let s=o+WT(this._searchQuery);s+=``;for(const[t,n]of a){const o=we(r,KT(n)),a=XT(n,e),l=this._expandedUuids.has(t);s+=`
`,s+=UT(t,n,e,i,o,a,l),l&&(s+=GT(t,n,e,0,o)),s+="
"}s+="
",s+=" ",t.innerHTML=s;const l=t.querySelector("span-side-panel");l&&(l.hass=e,l.errorStore=this._ctrl.errorStore),this._bindEvents(t),this._searchQuery&&this._applyFilter(t),this._ctrl.updateDOM(t),this._attachFoldObserver(t)}renderAreaView(t,e,i,r,o,a){this._unbindEvents(),this._hass=e,this._topology=i,this._config=r,this._monitoringStatus=o;const s=n("list.unassigned_area"),l=new Map;for(const[t,e]of Object.entries(i.circuits)){const n=e.area??s,i=l.get(n);i?i.push([t,e]):l.set(n,[[t,e]])}const c=[...l.keys()].sort((t,e)=>t===s?1:e===s?-1:t.localeCompare(e));let d=a+WT(this._searchQuery);d+=``;for(const t of c){const n=l.get(t);if(!n)continue;const i=ZT(n,e,r);d+=qT(t);for(const[t,n]of i){const i=we(o,KT(n)),a=XT(n,e),s=this._expandedUuids.has(t);d+=`
`,d+=UT(t,n,e,r,i,a,s),s&&(d+=GT(t,n,e,0,i)),d+="
"}}d+="
",d+=" ",t.innerHTML=d;const u=t.querySelector("span-side-panel");u&&(u.hass=e,u.errorStore=this._ctrl.errorStore),this._bindEvents(t),this._searchQuery&&this._applyFilter(t),this._ctrl.updateDOM(t),this._attachFoldObserver(t)}updateCollapsedRows(t,e,i,r){const o=ye(r),a="current"===o.entityRole,s=t.querySelectorAll(".list-row[data-row-uuid]");for(const t of s){const s=t.dataset.rowUuid;if(!s)continue;const l=i.circuits[s];if(!l)continue;const{isOn:c,value:d}=jT(l,e,r),u=t.querySelector(".list-power-value");if(u)if(c)if(a)u.innerHTML=`${o.format(d)} A `;else{const t=l.entities?.power,n=t?e.states[t]:null,i=n&&parseFloat(n.state)||0;u.innerHTML=`${pe(i)} ${he(i)} `}else u.innerHTML="";const h=t.querySelector(".toggle-pill");if(h){h.classList.toggle("toggle-on",c),h.classList.toggle("toggle-off",!c);const t=h.querySelector(".toggle-label");t&&(t.textContent=n(c?"grid.on":"grid.off"))}const p=t.querySelector(".list-status-badge");p&&(p.textContent=c?"ON":"OFF",p.classList.toggle("list-status-on",c),p.classList.toggle("list-status-off",!c)),t.classList.toggle("circuit-off",!c)}!function(t,e,n,i){const r=t.querySelector(".list-view");if(r)for(const t of function(t,e){let n={anchor:null,units:[]};const i=[n];for(const r of[...t.children])if(r.classList.contains("area-header"))n={anchor:r,units:[]},i.push(n);else if(r.classList.contains("list-cell")){const t=r.dataset.cellUuid,i=t?e.circuits[t]:void 0;t&&i&&n.units.push({cell:r,uuid:t,circuit:i})}return i}(r,n)){if(t.units.length<2)continue;const n=[...t.units].sort((t,n)=>YT(t.circuit,n.circuit,e,i));if(!n.some((e,n)=>e.uuid!==t.units[n].uuid))continue;let o=t.anchor;for(const t of n)o?o.after(t.cell):r.prepend(t.cell),o=t.cell}}(t,e,i,r)}stop(){this._unbindEvents(),null===this._viewName&&(this._expandedUuids.clear(),this._searchQuery=""),this._hass=null,this._topology=null,this._config=null,this._monitoringStatus=null}_dispatchFavoritesViewState(){if(!this._viewName||!this._container)return;const t={view:this._viewName,expanded:[...this._expandedUuids],searchQuery:this._searchQuery};this._container.dispatchEvent(new CustomEvent("favorites-view-state-changed",{detail:t,bubbles:!0,composed:!0}))}_bindEvents(t){this._container=t,this._clickHandler=e=>{const n=e.target;if(!n)return;const i=n.closest(".list-expand-toggle");if(i){const t=i.dataset.expandUuid;return void(t&&this._toggleExpand(t))}if(n.closest(".gear-icon"))return void this._ctrl.onGearClick(e,t);if(n.closest(".toggle-pill"))return void this._ctrl.onToggleClick(e,t);if(n.closest(".list-search-clear")){const e=t.querySelector(".list-search");return void(e&&(e.value="",e.dispatchEvent(new Event("input",{bubbles:!0}))))}const r=n.closest(".unit-btn");if(r){const e=r.dataset.unit;e&&t.dispatchEvent(new CustomEvent("unit-changed",{detail:e,bubbles:!0,composed:!0}))}},this._inputHandler=e=>{const n=e.target;n&&n.classList.contains("list-search")&&(this._searchQuery=n.value.toLowerCase(),this._applyFilter(t),this._dispatchFavoritesViewState())},this._graphSettingsHandler=()=>{this._ctrl.onGraphSettingsChanged(t).then(()=>{this._ctrl.updateDOM(t)}).catch(()=>{})},t.addEventListener("click",this._clickHandler),t.addEventListener("input",this._inputHandler),t.addEventListener("graph-settings-changed",this._graphSettingsHandler);const e=t.querySelector(".slide-confirm");e&&(this._ctrl.bindSlideConfirm(e,t),t.classList.add("switches-disabled"))}_unbindEvents(){this._container&&(this._clickHandler&&this._container.removeEventListener("click",this._clickHandler),this._inputHandler&&this._container.removeEventListener("input",this._inputHandler),this._graphSettingsHandler&&this._container.removeEventListener("graph-settings-changed",this._graphSettingsHandler)),this._foldUnobserve&&(this._foldUnobserve(),this._foldUnobserve=null),this._container=null,this._clickHandler=null,this._inputHandler=null,this._graphSettingsHandler=null}_attachFoldObserver(t){this._foldUnobserve&&(this._foldUnobserve(),this._foldUnobserve=null),this._foldUnobserve=cT(t,{rowSelector:".list-row",nameSelector:".list-circuit-name",foldClass:"is-folded"})}_applyFilter(t){const e=t.querySelector(".list-search-clear");e&&(e.style.display=this._searchQuery?"":"none");const n=t.querySelectorAll(".list-cell[data-cell-uuid]");for(const t of n){const e=t.querySelector(".list-circuit-name"),n=(e?.textContent?.toLowerCase()??"").includes(this._searchQuery);t.style.display=n?"":"none"}const i=t.querySelectorAll(".area-header");for(const t of i){let e=!1,n=t.nextElementSibling;for(;n&&!n.classList.contains("area-header");){if(n.classList.contains("list-cell")&&"none"!==n.style.display){e=!0;break}n=n.nextElementSibling}t.style.display=e?"":"none"}}_toggleExpand(t){if(!(this._container&&this._hass&&this._topology&&this._config))return;const e=nT(t),n=this._container.querySelector(`.list-cell[data-cell-uuid="${e}"]`);if(!n)return;const i=n.querySelector(`.list-row[data-row-uuid="${e}"]`),r=n.querySelector(`.list-expand-toggle[data-expand-uuid="${e}"]`);if(i){if(this._expandedUuids.has(t)){this._expandedUuids.delete(t);const o=n.querySelector(`.list-expanded-content[data-expanded-uuid="${e}"]`);o&&o.remove(),r&&r.classList.remove("expanded"),i.classList.remove("list-row-expanded")}else{this._expandedUuids.add(t);const e=this._topology.circuits[t];if(!e)return;const n=we(this._monitoringStatus,KT(e)),o=GT(t,e,this._hass,this._config,n);i.insertAdjacentHTML("afterend",o),r&&r.classList.add("expanded"),i.classList.add("list-row-expanded"),this._ctrl.updateDOM(this._container)}this._dispatchFavoritesViewState()}}}function JT(t,e){return`${t}|${e}`}class tI{async build(t,e,n,i){const r=new Map;for(const t of n)r.set(t.id,t);const o=i?new qt(i):null,a=[];for(const[n,i]of Object.entries(e)){if(!((i?.circuits?.length??0)>0||(i?.sub_devices?.length??0)>0))continue;const e=r.get(n);e&&a.push((async()=>{try{const i=await se(t,n,o);return{panelDeviceId:n,panel:e,topology:i.topology}}catch(t){return console.warn("SPAN Panel: favorites topology fetch failed",n,t),{panelDeviceId:n,panel:e,topology:null}}})())}const s=(await Promise.all(a)).filter(t=>null!==t.topology),l=s.length>1,c={},d={},u={},h=new Set,p=[];for(const{panelDeviceId:t,panel:n,topology:i}of s){if(!i)continue;const r=n.config_entry_id??null;r&&h.add(r);const o=n.name_by_user??n.name??i.device_name??"";p.push({panelDeviceId:t,panelName:o,topology:i});const a=e[t],s=a?.circuits??[],f=a?.sub_devices??[];for(const e of s){const n=i.circuits?.[e];if(!n)continue;const a=JT(t,e),s=l&&o?`${o} · ${n.name}`:n.name;c[a]={...n,name:s},u[a]={panelDeviceId:t,kind:"circuit",targetId:e,configEntryId:r}}for(const e of f){const n=i.sub_devices?.[e];if(!n)continue;const a=JT(t,e),s=l&&o&&n.name?`${o} · ${n.name}`:n.name??e;d[a]={...n,name:s},u[a]={panelDeviceId:t,kind:"sub_device",targetId:e,configEntryId:r}}}return{topology:{circuits:c,sub_devices:d,panel_entities:{},device_name:"",_favoriteRefs:u},entryIds:Array.from(h),perPanelStats:p}}}const eI="span_panel_favorites_view_state";function nI(t){try{localStorage.setItem(eI,JSON.stringify(t))}catch{}}var iI;const rI="favorites";function oI(t){return"dashboard"===t||"adopted"===t}let aI=iI=class extends Dt{constructor(){super(...arguments),this.narrow=!1,this._panels=[],this._selectedPanelId=null,this._activeTab="dashboard",this._discovered=!1,this._listColumns=Wt(),this._favorites={},this._favoritesViewState={expanded:{activity:[],area:[]}},this._favoritesPanelStats=[],this._dashboardTab=new uT,this._monitoringTab=new yT,this._adoptedTab=new VT,this._listDashCtrl=new lT,this._listCtrl=new QT(this._listDashCtrl),this._favCache=new Yt,this._favCtrl=new tI,this._favoritesMonitoringTabs=new Map,this._errorStore=new Ht,this._watchedPanelId=null,this._discovering=!1,this._refreshSeq=0,this._areaUnsub=null,this._areaSubscribing=!1,this._onFavoritesChanged=null,this._deviceRegistryUnsub=null,this._pendingTabRender=!1,this._persistFavoritesViewStateTimer=null,this._tabRenderScheduler=function(t){let e=null,n=!1;return async function i(){if(e)return n=!0,void await e.catch(()=>{});const r=(async()=>{try{await t()}finally{e=null,n&&(n=!1,await i())}})();e=r,await r}}(async()=>this._renderTab()),this._beginRender=function(){let t=0;return()=>{t+=1;const e=t;return()=>t!==e}}()}get _root(){const t=this.shadowRoot;if(!t)throw new Error("span-panel: shadow root is not available");return t}connectedCallback(){super.connectedCallback(),this._dashboardTab.errorStore=this._errorStore,this._listDashCtrl.errorStore=this._errorStore,this._favCache.errorStore=this._errorStore,this._monitoringTab.errorStore=this._errorStore,this._onFavoritesChanged=()=>{this._refreshFavorites()},document.addEventListener(jt,this._onFavoritesChanged),this._subscribeDeviceRegistry()}disconnectedCallback(){this._dashboardTab.stop(),this._monitoringTab.stop(),this._adoptedTab.stop(),this._listCtrl.stop(),this._listDashCtrl.stopIntervals();for(const t of this._favoritesMonitoringTabs.values())t.stop();this._favoritesMonitoringTabs.clear(),this._areaSubscribing=!1,this._areaUnsub&&(this._areaUnsub(),this._areaUnsub=null),this._onFavoritesChanged&&(document.removeEventListener(jt,this._onFavoritesChanged),this._onFavoritesChanged=null),this._unsubscribeDeviceRegistry(),this._persistFavoritesViewStateTimer&&(clearTimeout(this._persistFavoritesViewStateTimer),this._persistFavoritesViewStateTimer=null),this._errorStore.dispose(),super.disconnectedCallback()}firstUpdated(){this.hass&&!this._discovered&&this._discoverPanels()}updated(t){if(t.has("hass")){const e=t.get("hass");this._dashboardTab.hass=this.hass,this._listDashCtrl.hass=this.hass,this._errorStore.updateHass(this.hass),this._discovered?this._root.getElementById("tab-content")||this._scheduleTabRender():this._discoverPanels(),!e&&this.hass&&this._subscribeDeviceRegistry()}if(this._discovered&&(t.has("_discovered")||t.has("_activeTab")||t.has("_selectedPanelId")||t.has("_chartMetric")||t.has("_listColumns"))){if(this._isFavoritesView&&oI(this._activeTab))return void(this._activeTab="activity");this._scheduleTabRender()}if(t.has("_selectedPanelId")&&(this._selectedPanelId!==rI&&this._selectedPanelId?(this._updatePanelStatusWatch(),this._listDashCtrl.setFavoritesPerPanelInfo(null)):(this._errorStore.clearPanelStatusWatch(),this._watchedPanelId=null)),this._discovered&&(t.has("_panels")||t.has("_selectedPanelId"))){const t=this.shadowRoot?.getElementById("panel-select");t&&null!==this._selectedPanelId&&t.value!==this._selectedPanelId&&(t.value=this._selectedPanelId)}if(t.has("hass")&&this._discovered&&("activity"===this._activeTab||"area"===this._activeTab)){const t=this._root.getElementById("tab-content"),e=this._listDashCtrl.topology;if(t&&e){this._listCtrl.updateCollapsedRows(t,this.hass,e,this._buildDashboardConfig());const n=t.querySelector("span-side-panel");n&&(n.hass=this.hass,n.errorStore=this._errorStore)}}}setConfig(t){}render(){var i,r,o;if(i=this.hass?.language,t=i&&e[i]?i:"en",!this.hass)return dt`