@nubisco/openbridge 1.5.2 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -67,7 +67,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
67
67
  For more please check the link https://github.com/suren-atoyan/monaco-loader#config
68
68
  `},dp=BR(WR)(sb),jR={config:zR},KR=function(){for(var t=arguments.length,i=new Array(t),n=0;n<t;n++)i[n]=arguments[n];return function(r){return i.reduceRight(function(s,a){return a(s)},r)}};function ab(e,t){return Object.keys(t).forEach(function(i){t[i]instanceof Object&&e[i]&&Object.assign(t[i],ab(e[i],t[i]))}),op(op({},e),t)}var qR={type:"cancelation",msg:"operation is manually canceled"};function uu(e){var t=!1,i=new Promise(function(n,r){e.then(function(s){return t?r(qR):n(s)}),e.catch(r)});return i.cancel=function(){return t=!0},i}var GR=["monaco"],YR=DR.create({config:ZR,isInitialized:!1,resolve:null,reject:null,monaco:null}),lb=wR(YR,2),i0=lb[0],y1=lb[1];function XR(e){var t=jR.config(e),i=t.monaco,n=bR(t,GR);y1(function(r){return{config:ab(r.config,n),monaco:i}})}function JR(){var e=i0(function(t){var i=t.monaco,n=t.isInitialized,r=t.resolve;return{monaco:i,isInitialized:n,resolve:r}});if(!e.isInitialized){if(y1({isInitialized:!0}),e.monaco)return e.resolve(e.monaco),uu(du);if(window.monaco&&window.monaco.editor)return ob(window.monaco),e.resolve(window.monaco),uu(du);KR(QR,tV)(iV)}return uu(du)}function QR(e){return document.body.appendChild(e)}function eV(e){var t=document.createElement("script");return e&&(t.src=e),t}function tV(e){var t=i0(function(n){var r=n.config,s=n.reject;return{config:r,reject:s}}),i=eV("".concat(t.config.paths.vs,"/loader.js"));return i.onload=function(){return e()},i.onerror=t.reject,i}function iV(){var e=i0(function(i){var n=i.config,r=i.resolve,s=i.reject;return{config:n,resolve:r,reject:s}}),t=window.require;t.config(e.config),t(["vs/editor/editor.main"],function(i){var n=i.m||i;ob(n),e.resolve(n)},function(i){e.reject(i)})}function ob(e){i0().monaco||y1({monaco:e})}function nV(){return i0(function(e){var t=e.monaco;return t})}var du=new Promise(function(e,t){return y1({resolve:e,reject:t})}),cb={config:XR,init:JR,__getMonacoInstance:nV};const rV={key:0,class:"monaco-skeleton"},sV=Ne({__name:"MonacoJsonEditor",props:{modelValue:{},height:{}},emits:["update:modelValue"],setup(e,{emit:t}){const i=e,n=t,{resolved:r}=c1(),s=K(null),a=zn(null),l=K(!1);let o=!1;return nt(async()=>{const c=await cb.init();s.value&&(Ve(r,u=>c.editor.setTheme(u==="dark"?"vs-dark":"vs")),a.value=c.editor.create(s.value,{value:i.modelValue,language:"json",theme:r.value==="dark"?"vs-dark":"vs",fontSize:12,fontFamily:'"MesloLGS NF", monospace',minimap:{enabled:!1},scrollBeyondLastLine:!1,lineNumbers:"off",wordWrap:"on",automaticLayout:!0,tabSize:2,folding:!1,renderLineHighlight:"none",overviewRulerLanes:0,scrollbar:{verticalScrollbarSize:6}}),a.value.onDidChangeModelContent(()=>{o||n("update:modelValue",a.value.getValue())}),l.value=!0)}),ri(()=>{var c;(c=a.value)==null||c.dispose()}),Ve(()=>i.modelValue,c=>{if(!a.value)return;a.value.getValue()!==c&&(o=!0,a.value.setValue(c),o=!1)}),(c,u)=>(m(),M("div",{style:mi({height:`${e.height??220}px`,width:"100%",position:"relative"})},[b("div",{ref_key:"containerEl",ref:s,style:{height:"100%",width:"100%"}},null,512),l.value?V("",!0):(m(),M("div",rV))],4))}}),hp=zt(sV,[["__scopeId","data-v-0c34d464"]]),aV={class:"pcf-root"},lV={key:1,class:"pcf-no-schema"},oV=Ne({__name:"PluginConfigForm",props:{hbSchema:{},modelValue:{}},emits:["update:modelValue"],setup(e,{emit:t}){const i=e,n=t;function r(d,h){const f=JSON.parse(JSON.stringify(i.modelValue));let v=f;for(let p=0;p<d.length-1;p++)(v[d[p]]===void 0||typeof v[d[p]]!="object")&&(v[d[p]]={}),v=v[d[p]];v[d[d.length-1]]=h,n("update:modelValue",f)}function s(d){let h=i.modelValue;for(const f of d){if(h==null||typeof h!="object")return;h=h[f]}return h}function a(d){return Array.isArray(d.type)?d.type[0]:d.type??"string"}function l(d,h){const f=s(d)??[],v=h.default??(a(h)==="string"?"":a(h)==="number"?0:"");r(d,[...f,v])}function o(d,h){const f=[...s(d)??[]];f.splice(h,1),r(d,f)}function c(d,h,f){const v=[...s(d)??[]];v[h]=f,r(d,v)}const u=q(()=>i.hbSchema.schema??{type:"object",properties:{}});return(d,h)=>{const f=wo("PluginConfigField");return m(),M("div",aV,[u.value.properties?(m(!0),M(Ce,{key:0},Fe(u.value.properties,(v,p)=>{var w;return m(),he(f,{key:p,"field-key":String(p),field:v,path:[String(p)],required:((w=u.value.required)==null?void 0:w.includes(String(p)))??!1,value:s([String(p)]),onChange:_=>r([String(p)],_),onAddArray:h[0]||(h[0]=(_,y)=>l(_,y)),onRemoveArray:h[1]||(h[1]=(_,y)=>o(_,y)),onUpdateArray:h[2]||(h[2]=(_,y,C)=>c(_,y,C))},null,8,["field-key","field","path","required","value","onChange"])}),128)):(m(),M("div",lV,"No configurable fields found in schema."))])}}}),cV=zt(oV,[["__scopeId","data-v-d9cf6b0f"]]),uV={key:0,class:"inspector nb-inspector"},dV={class:"inspector-header"},hV={class:"inspector-title"},fV={class:"inspector-name"},pV={class:"inspector-version"},_V={class:"inspector-body"},mV={class:"field-value"},vV={class:"field-value"},gV={class:"hap-bridge-info"},bV={class:"hap-qr"},yV=["src"],wV={class:"hap-details"},SV={class:"field-value mono"},CV={class:"field-value"},kV={class:"field-value"},AV={key:0,class:"setup-loading"},MV={key:0,class:"platform-tabs"},$V=["onClick"],LV={key:1,class:"visual-editor-wrap"},EV={key:0,class:"json-error"},xV={key:1,class:"json-error"},HV={key:3,class:"save-error"},TV={class:"setup-actions"},NV={key:0,class:"json-error"},PV={key:0,class:"save-error"},OV={class:"setup-actions"},IV={class:"import-export-row"},RV={class:"plugin-device-name"},VV={class:"plugin-device-type"},DV={class:"field-value"},ZV={class:"field-value"},BV={class:"field-value"},FV={class:"field-value"},zV={class:"error-text"},UV={class:"plog-time"},WV={class:"plog-msg"},fp="openbridge.pluginInspector.sections",jV=Ne({__name:"PluginInspector",setup(e){const t=Kr(),i=K(!1),n=K("");async function r(){if(!i.value){i.value=!0;try{await Re.daemon.restart();let P=0;const R=setInterval(async()=>{P++;try{await Re.health(),clearInterval(R),location.reload()}catch{}P>60&&(clearInterval(R),i.value=!1)},1e3)}catch{i.value=!1}}}const s=Qo(),a=[{id:"visual",label:"Visual",icon:"sliders"},{id:"json",label:"JSON",icon:"brackets-curly"}],l={status:"default",hap:"default",update:"default",manage:"collapsed",config:"default",transfer:"collapsed",devices:"default",manifest:"collapsed",error:"default",logs:"default"},o=K({...l});try{const P=JSON.parse(localStorage.getItem(fp)??"{}");o.value={...l,...P}}catch{}Ve(o,P=>localStorage.setItem(fp,JSON.stringify(P)),{deep:!0}),Ve(()=>{var P,R;return(R=(P=s.selectedPlugin)==null?void 0:P.hapBridge)==null?void 0:R.setupURI},async P=>{if(P)try{n.value=await Wa.toDataURL(P,{width:160,margin:1})}catch{n.value=""}else n.value=""},{immediate:!0});const c=q(()=>{const P=s.selectedPlugin;return P!=null&&P.devices?Object.values(P.devices):[]}),u={switch:"plugs",light:"lamp",thermostat:"thermometer",dehumidifier:"drop",energy_meter:"lightning",gate:"garage",sensor:"pulse"};function d(P){return u[P]??"cube"}const h={idle:"Idle",loading:"Loading",running:"Running",stopped:"Stopped",error:"Error"},f=K(!1);async function v(){if(!(!s.selectedPlugin||f.value)){f.value=!0;try{await Re.marketplace.update(s.selectedPlugin.manifest.name),await t.fetchPlugins(),await r()}catch(P){console.error("Failed to update plugin:",P)}finally{f.value=!1}}}const p=K(!1),w=K(!1);async function _(){if(!(!s.selectedPlugin||w.value)){w.value=!0;try{await Re.marketplace.uninstall(s.selectedPlugin.manifest.name),await t.fetchPlugins(),s.close(),await Re.daemon.restart()}catch(P){console.error("Failed to remove plugin:",P)}finally{w.value=!1,p.value=!1}}}const y=K(!1);async function C(){if(!s.selectedPlugin||y.value)return;const P=!s.selectedPlugin.disabled;y.value=!0;try{const R=await Re.setPluginDisabled(s.selectedPlugin.id,P);s.selectedPlugin.disabled=R.disabled}catch(R){console.error("Failed to toggle plugin disabled state:",R)}finally{y.value=!1}}const g=K(null),$=K(!1),E=K(""),L=K(""),B=K(!1),T=K(null),X=K(!1),W=K(null),A=K({}),x=K("visual"),F=q(()=>{var P;return((P=W.value)==null?void 0:P.schema)!=null}),ie=q(()=>{var P;return((P=s.selectedPlugin)==null?void 0:P.source)==="homebridge"}),re=q(()=>s.selectedPlugin!=null&&s.selectedPlugin.source!=="homebridge"),ue=K(""),J=K(!1),ae=K(null),ne=K(!1),Q=q(()=>{try{return JSON.parse(ue.value),!0}catch{return!1}});Ve(()=>s.selectedPlugin,async P=>{if(ue.value="",ae.value=null,ne.value=!1,!(!P||P.source==="homebridge"))try{const R=await Re.config.getPlugin(P.manifest.name);ue.value=JSON.stringify(R.config??{},null,2)}catch{ue.value="{}"}});const oe=K(null);function ve(){var P;(P=oe.value)==null||P.click()}function fe(){if(!s.selectedPlugin)return;const P=s.selectedPlugin.manifest.name,R=ie.value?L.value:ue.value;if(!R)return;const I=new Blob([R],{type:"application/json"}),z=URL.createObjectURL(I),Y=document.createElement("a");Y.href=z,Y.download=`${P.replace(/[^a-z0-9-]/gi,"-")}-config.json`,Y.click(),URL.revokeObjectURL(z)}async function pe(P){var I;const R=(I=P.target.files)==null?void 0:I[0];if(!(!R||!s.selectedPlugin))try{const z=await R.text(),Y=JSON.parse(z);let Se;if(Y.platform&&typeof Y.platform=="string"){const{plugin:Me,...De}=Y;Se=De}else Se=Y;await Re.config.savePlugin(s.selectedPlugin.manifest.name,Se),ie.value?L.value=JSON.stringify(Se,null,2):ue.value=JSON.stringify(Se,null,2),oe.value&&(oe.value.value="")}catch(z){console.error("Import failed:",z)}}async function ye(){if(J.value||!s.selectedPlugin)return;let P;try{P=JSON.parse(ue.value)}catch{ae.value="Invalid JSON: fix the syntax first";return}J.value=!0,ae.value=null,ne.value=!1;try{await Re.config.savePlugin(s.selectedPlugin.manifest.name,P),ne.value=!0,setTimeout(()=>{ne.value=!1},3e3)}catch(R){ae.value=String(R)}finally{J.value=!1}}const U=q(()=>{const P=s.selectedPlugin;return!P||P.source!=="homebridge"?"":P.platformName??P.id??P.manifest.name});Ve(()=>s.selectedPlugin,async P=>{if(g.value=null,E.value="",L.value="",W.value=null,A.value={},T.value=null,X.value=!1,!(!P||P.source!=="homebridge")){$.value=!0;try{const R=await Re.config.getHbPlugin(U.value,P.packageName);if(R.config){E.value=U.value,L.value=JSON.stringify(R.config,null,2),A.value=R.config,await _e(P.manifest.name);return}const I=await Re.pluginInfo(P.packageName??P.manifest.name);g.value=I,I.platforms.length>0&&await ge(I.platforms[0],I.mainFile),await _e(P.manifest.name)}catch{try{const R=await Re.config.getHbPlugin(U.value,P.packageName);R.config&&(E.value=U.value,L.value=JSON.stringify(R.config,null,2),A.value=R.config)}catch{}}finally{$.value=!1}}});async function _e(P){try{const R=await fetch(`/api/marketplace/plugin-schema/${encodeURIComponent(P)}`);if(R.ok){const I=await R.json();W.value=I.schema}}catch{}}async function ge(P,R){var I,z;E.value=P;try{const Y=await Re.config.getPlatform(P),Se=Y.config?Y.config:{platform:P,plugin:R??((I=g.value)==null?void 0:I.mainFile)??""};L.value=JSON.stringify(Se,null,2),A.value=Se}catch{const Y={platform:P,plugin:R??((z=g.value)==null?void 0:z.mainFile)??""};L.value=JSON.stringify(Y,null,2),A.value=Y}}function se(P){A.value=P,L.value=JSON.stringify(P,null,2)}function H(P){L.value=P;try{A.value=JSON.parse(P)}catch{}}function N(){try{return JSON.parse(L.value)}catch{return null}}const O=q(()=>N()!==null),te=q(()=>{const P=N();return P!==null&&typeof P.platform!="string"}),ee=K([]),me=K(null);let we=null;function S(){if(we&&(we.close(),we=null),!s.selectedPlugin)return;const P=location.protocol==="https:"?"wss:":"ws:";we=new WebSocket(`${P}//${location.host}/ws/logs`),we.onmessage=R=>{var I,z;try{const Y=JSON.parse(R.data);(Y.plugin===((I=s.selectedPlugin)==null?void 0:I.id)||Y.plugin===((z=s.selectedPlugin)==null?void 0:z.manifest.name))&&(ee.value=[...ee.value.slice(-199),Y],setTimeout(()=>{me.value&&(me.value.scrollTop=me.value.scrollHeight)},10))}catch{}},we.onclose=()=>{s.selectedPlugin&&setTimeout(S,3e3)}}Ve(()=>s.selectedPlugin,async P=>{if(ee.value=[],we==null||we.close(),we=null,!!P){try{const R=await Re.logs(P.manifest.name,100);ee.value=R.entries,setTimeout(()=>{me.value&&(me.value.scrollTop=me.value.scrollHeight)},20)}catch{}S()}}),nt(()=>{s.selectedPlugin&&S()}),ri(()=>{we==null||we.close()});const k={debug:"var(--nb-c-text-muted)",info:"var(--nb-c-info)",warn:"var(--nb-c-warning)",error:"var(--nb-c-danger)"};async function D(){if(B.value||!s.selectedPlugin)return;const P=N();if(!P){T.value="Invalid JSON: fix the syntax first";return}B.value=!0,T.value=null,X.value=!1;try{const R=s.selectedPlugin;R.source==="homebridge"?await Re.config.saveHbPlugin(U.value,P,R.packageName):await Re.config.savePlugin(R.manifest.name,P),X.value=!0,setTimeout(()=>{X.value=!1},3e3)}catch(R){T.value=String(R)}finally{B.value=!1}}return(P,R)=>{const I=Ue,z=r2,Y=o1,Se=S2,Me=Pt,De=ks,Xe=vN;return de(s).selectedPlugin?(m(),M("div",uV,[b("div",dV,[b("div",{class:Le(["inspector-avatar",de(s).selectedPlugin.status])},[j(I,{name:de(bs),size:24},null,8,["name"])],2),b("div",hV,[b("h2",fV,Z(de(s).selectedPlugin.manifest.name),1),b("span",pV,"v"+Z(de(s).selectedPlugin.manifest.version),1)])]),b("div",_V,[j(Se,{size:o.value.status,"onUpdate:size":R[0]||(R[0]=Te=>o.value.status=Te),title:"Status",fluid:""},{default:G(()=>[j(z,{label:"Status",control:"fit"},{default:G(()=>[b("span",{class:Le(["status-badge",de(s).selectedPlugin.status])},Z(h[de(s).selectedPlugin.status]),3)]),_:1}),de(s).selectedPlugin.startedAt?(m(),he(z,{key:0,label:"Started",control:"fit"},{default:G(()=>[b("span",mV,Z(new Date(de(s).selectedPlugin.startedAt).toLocaleString()),1)]),_:1})):V("",!0),de(s).selectedPlugin.stoppedAt?(m(),he(z,{key:1,label:"Stopped",control:"fit"},{default:G(()=>[b("span",vV,Z(new Date(de(s).selectedPlugin.stoppedAt).toLocaleString()),1)]),_:1})):V("",!0),j(z,{label:"Disabled",control:"fit"},{default:G(()=>[j(Y,{name:`plugin-disabled-${de(s).selectedPlugin.id}`,"model-value":de(s).selectedPlugin.disabled??!1,disabled:y.value,"onUpdate:modelValue":C},null,8,["name","model-value","disabled"])]),_:1})]),_:1},8,["size"]),de(s).selectedPlugin.hapBridge?(m(),he(Se,{key:0,size:o.value.hap,"onUpdate:size":R[1]||(R[1]=Te=>o.value.hap=Te),title:"HomeKit pairing",fluid:""},{default:G(()=>[b("div",gV,[b("div",bV,[n.value?(m(),M("img",{key:0,src:n.value,alt:"HomeKit QR Code",class:"hap-qr-img"},null,8,yV)):V("",!0)]),b("div",wV,[j(z,{label:"PIN",control:"fit"},{default:G(()=>[b("span",SV,Z(de(s).selectedPlugin.hapBridge.pincode),1)]),_:1}),j(z,{label:"Port",control:"fit"},{default:G(()=>[b("span",CV,Z(de(s).selectedPlugin.hapBridge.port),1)]),_:1}),j(z,{label:"Bridge",control:"fit"},{default:G(()=>[b("span",kV,Z(de(s).selectedPlugin.hapBridge.name),1)]),_:1})])]),R[15]||(R[15]=b("p",{class:"hap-hint"},"Scan with the Home app or enter the PIN manually to pair this plugin's devices.",-1))]),_:1},8,["size"])):V("",!0),de(s).selectedPlugin.availableUpdate?(m(),he(Se,{key:1,size:o.value.update,"onUpdate:size":R[2]||(R[2]=Te=>o.value.update=Te),title:"Update",fluid:""},{default:G(()=>[j(De,{status:"info",icon:$2,title:`Version ${de(s).selectedPlugin.availableUpdate} is available`},{action:G(()=>[j(Me,{variant:"primary",size:"sm",loading:f.value,disabled:f.value,onClick:v},{default:G(()=>[le(Z(f.value?"Updating...":"Update"),1)]),_:1},8,["loading","disabled"])]),default:G(()=>[le(" Currently on "+Z(de(s).selectedPlugin.manifest.version)+". ",1)]),_:1},8,["title"])]),_:1},8,["size"])):V("",!0),j(Se,{size:o.value.manage,"onUpdate:size":R[5]||(R[5]=Te=>o.value.manage=Te),title:"Manage",fluid:""},{default:G(()=>[p.value?(m(),he(De,{key:1,status:"error",title:"This uninstalls the plugin and removes its configuration"},{action:G(()=>[j(Me,{variant:"ghost",size:"sm",onClick:R[4]||(R[4]=Te=>p.value=!1)},{default:G(()=>[...R[17]||(R[17]=[le("Cancel",-1)])]),_:1}),j(Me,{variant:"primary",size:"sm",loading:w.value,style:{background:"var(--nb-c-danger)","border-color":"var(--nb-c-danger)"},onClick:_},{default:G(()=>[...R[18]||(R[18]=[le(" Remove ",-1)])]),_:1},8,["loading"])]),default:G(()=>[R[19]||(R[19]=le(" OpenBridge needs a restart afterwards. ",-1))]),_:1})):(m(),he(Me,{key:0,variant:"ghost",size:"sm",icon:C2,style:{color:"var(--nb-c-danger)"},onClick:R[3]||(R[3]=Te=>p.value=!0)},{default:G(()=>[...R[16]||(R[16]=[le(" Remove plugin ",-1)])]),_:1}))]),_:1},8,["size"]),ie.value?(m(),he(Se,{key:2,size:o.value.config,"onUpdate:size":R[7]||(R[7]=Te=>o.value.config=Te),title:"Platform config",fluid:""},{default:G(()=>[$.value?(m(),M("div",AV,[j(I,{name:de(ra),size:14},null,8,["name"]),R[20]||(R[20]=le(" Loading config… ",-1))])):(m(),M(Ce,{key:1},[g.value&&g.value.platforms.length>1?(m(),M("div",MV,[(m(!0),M(Ce,null,Fe(g.value.platforms,Te=>(m(),M("button",{key:Te,class:Le(["platform-tab",{active:E.value===Te}]),onClick:rt=>ge(Te)},Z(Te),11,$V))),128))])):g.value&&g.value.platforms.length===0?(m(),he(De,{key:1,status:"warning",variant:"callout",title:"No platform detected"},{default:G(()=>[...R[21]||(R[21]=[le(" Add a ",-1),b("code",null,"platforms[]",-1),le(" entry manually in Config. ",-1)])]),_:1})):V("",!0),!g.value||g.value.platforms.length>0?(m(),M(Ce,{key:2},[F.value?(m(),he(Xe,{key:0,"model-value":x.value,items:a,variant:"contained",size:"sm","onUpdate:modelValue":R[6]||(R[6]=Te=>x.value=Te)},null,8,["model-value"])):V("",!0),x.value==="visual"&&F.value?(m(),M("div",LV,[j(cV,{"hb-schema":W.value,"model-value":A.value,"onUpdate:modelValue":se},null,8,["hb-schema","model-value"])])):V("",!0),x.value==="json"||!F.value?(m(),M("div",{key:2,class:Le(["config-editor-wrap",{invalid:L.value&&!O.value}])},[j(hp,{"model-value":L.value,height:220,"onUpdate:modelValue":H},null,8,["model-value"]),L.value&&!O.value?(m(),M("div",EV,"Invalid JSON")):te.value?(m(),M("div",xV,'Missing "platform" field')):V("",!0)],2)):V("",!0),T.value?(m(),M("div",HV,[j(I,{name:de(xn),size:13},null,8,["name"]),le(" "+Z(T.value),1)])):V("",!0),b("div",TV,[j(Me,{variant:"primary",size:"sm",loading:B.value,disabled:B.value||!O.value||te.value,icon:X.value?dr:Hc,onClick:D},{default:G(()=>[le(Z(X.value?"Saved!":"Save config"),1)]),_:1},8,["loading","disabled","icon"]),X.value?(m(),he(Me,{key:0,variant:"secondary",size:"sm",outlined:"",loading:i.value,icon:i.value?Vo:_s,onClick:r},{default:G(()=>[le(Z(i.value?"Restarting…":"Restart OpenBridge"),1)]),_:1},8,["loading","icon"])):V("",!0)])],64)):V("",!0)],64))]),_:1},8,["size"])):V("",!0),re.value?(m(),he(Se,{key:3,size:o.value.config,"onUpdate:size":R[9]||(R[9]=Te=>o.value.config=Te),title:"Plugin config",fluid:""},{default:G(()=>[b("div",{class:Le(["config-editor-wrap",{invalid:ue.value&&!Q.value}])},[j(hp,{"model-value":ue.value,height:220,"onUpdate:modelValue":R[8]||(R[8]=Te=>ue.value=Te)},null,8,["model-value"]),ue.value&&!Q.value?(m(),M("div",NV,"Invalid JSON")):V("",!0)],2),ae.value?(m(),M("div",PV,[j(I,{name:de(xn),size:13},null,8,["name"]),le(" "+Z(ae.value),1)])):V("",!0),b("div",OV,[j(Me,{variant:"primary",size:"sm",loading:J.value,disabled:J.value||!Q.value,icon:ne.value?dr:Hc,onClick:ye},{default:G(()=>[le(Z(ne.value?"Saved!":"Save config"),1)]),_:1},8,["loading","disabled","icon"]),ne.value?(m(),he(Me,{key:0,variant:"secondary",size:"sm",outlined:"",loading:i.value,icon:i.value?Vo:_s,onClick:r},{default:G(()=>[le(Z(i.value?"Restarting…":"Restart OpenBridge"),1)]),_:1},8,["loading","icon"])):V("",!0)])]),_:1},8,["size"])):V("",!0),j(Se,{size:o.value.transfer,"onUpdate:size":R[10]||(R[10]=Te=>o.value.transfer=Te),title:"Import & export",fluid:""},{default:G(()=>[b("div",IV,[j(Me,{variant:"ghost",size:"sm",icon:yI,onClick:fe},{default:G(()=>[...R[22]||(R[22]=[le("Export config",-1)])]),_:1}),j(Me,{variant:"ghost",size:"sm",icon:$I,onClick:ve},{default:G(()=>[...R[23]||(R[23]=[le("Import config",-1)])]),_:1}),b("input",{ref_key:"importInput",ref:oe,type:"file",accept:".json",style:{display:"none"},onChange:pe},null,544)])]),_:1},8,["size"]),c.value.length>0?(m(),he(Se,{key:4,size:o.value.devices,"onUpdate:size":R[11]||(R[11]=Te=>o.value.devices=Te),title:`Devices (${c.value.length})`,fluid:""},{default:G(()=>[(m(!0),M(Ce,null,Fe(c.value,Te=>(m(),M("div",{key:Te.id,class:"plugin-device-row"},[j(I,{name:d(Te.widgetType),size:14},null,8,["name"]),b("span",RV,Z(Te.name),1),b("span",VV,Z(Te.widgetType),1)]))),128))]),_:1},8,["size","title"])):V("",!0),j(Se,{size:o.value.manifest,"onUpdate:size":R[12]||(R[12]=Te=>o.value.manifest=Te),title:"Manifest",fluid:""},{default:G(()=>[j(z,{label:"Name",control:"fit"},{default:G(()=>[b("span",DV,Z(de(s).selectedPlugin.manifest.name),1)]),_:1}),j(z,{label:"Version",control:"fit"},{default:G(()=>[b("span",ZV,Z(de(s).selectedPlugin.manifest.version),1)]),_:1}),de(s).selectedPlugin.manifest.description?(m(),he(z,{key:0,label:"Description",control:"fit"},{default:G(()=>[b("span",BV,Z(de(s).selectedPlugin.manifest.description),1)]),_:1})):V("",!0),de(s).selectedPlugin.manifest.author?(m(),he(z,{key:1,label:"Author",control:"fit"},{default:G(()=>[b("span",FV,Z(de(s).selectedPlugin.manifest.author),1)]),_:1})):V("",!0)]),_:1},8,["size"]),de(s).selectedPlugin.error?(m(),he(Se,{key:5,size:o.value.error,"onUpdate:size":R[13]||(R[13]=Te=>o.value.error=Te),title:"Error",fluid:""},{default:G(()=>[j(De,{status:"error"},{default:G(()=>[b("code",zV,Z(de(s).selectedPlugin.error),1)]),_:1})]),_:1},8,["size"])):V("",!0),ee.value.length>0?(m(),he(Se,{key:6,size:o.value.logs,"onUpdate:size":R[14]||(R[14]=Te=>o.value.logs=Te),title:"Recent logs",fluid:""},{default:G(()=>[b("div",{ref_key:"logsEl",ref:me,class:"plugin-log-terminal"},[(m(!0),M(Ce,null,Fe(ee.value,(Te,rt)=>(m(),M("div",{key:rt,class:"plugin-log-line"},[b("span",UV,Z(new Date(Te.timestamp).toLocaleTimeString()),1),b("span",{class:"plog-level",style:mi({color:k[Te.level]})},Z(Te.level.toUpperCase()),5),b("span",WV,Z(Te.message),1)]))),128))],512)]),_:1},8,["size"])):V("",!0)])])):V("",!0)}}}),KV=zt(jV,[["__scopeId","data-v-b8eb965d"]]),qV=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},pp=qV("arrow-square-out","0 0 256 256",'<path d="M224,104a8,8,0,0,1-16,0V59.32l-66.33,66.34a8,8,0,0,1-11.32-11.32L196.68,48H152a8,8,0,0,1,0-16h64a8,8,0,0,1,8,8Zm-40,24a8,8,0,0,0-8,8v72H48V80h72a8,8,0,0,0,0-16H48A16,16,0,0,0,32,80V208a16,16,0,0,0,16,16H176a16,16,0,0,0,16-16V136A8,8,0,0,0,184,128Z"/>'),GV=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},zs=GV("diamond","0 0 256 256",'<path d="M235.33,116.72,139.28,20.66a16,16,0,0,0-22.56,0l-96,96.06a16,16,0,0,0,0,22.56l96.05,96.06h0a16,16,0,0,0,22.56,0l96.05-96.06a16,16,0,0,0,0-22.56ZM128,224h0L32,128,128,32,224,128Z"/>'),YV=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},XV=YV("folder","0 0 256 256",'<path d="M216,72H131.31L104,44.69A15.86,15.86,0,0,0,92.69,40H40A16,16,0,0,0,24,56V200.62A15.4,15.4,0,0,0,39.38,216H216.89A15.13,15.13,0,0,0,232,200.89V88A16,16,0,0,0,216,72ZM40,56H92.69l16,16H40ZM216,200H40V88H216Z"/>'),JV=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},QV=JV("cloud-arrow-down","0 0 256 256",'<path d="M248,128a87.34,87.34,0,0,1-17.6,52.81,8,8,0,1,1-12.8-9.62A71.34,71.34,0,0,0,232,128a72,72,0,0,0-144,0,8,8,0,0,1-16,0,88,88,0,0,1,3.29-23.88C74.2,104,73.1,104,72,104a48,48,0,0,0,0,96H96a8,8,0,0,1,0,16H72A64,64,0,1,1,81.29,88.68,88,88,0,0,1,248,128Zm-69.66,42.34L160,188.69V128a8,8,0,0,0-16,0v60.69l-18.34-18.35a8,8,0,0,0-11.32,11.32l32,32a8,8,0,0,0,11.32,0l32-32a8,8,0,0,0-11.32-11.32Z"/>'),eD=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},tD=eD("star","0 0 256 256",'<path d="M234.29,114.85l-45,38.83L203,211.75a16.4,16.4,0,0,1-24.5,17.82L128,198.49,77.47,229.57A16.4,16.4,0,0,1,53,211.75l13.76-58.07-45-38.83A16.46,16.46,0,0,1,31.08,86l59-4.76,22.76-55.08a16.36,16.36,0,0,1,30.27,0l22.75,55.08,59,4.76a16.46,16.46,0,0,1,9.37,28.86Z"/>'),iD=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},ub=iD("book-open","0 0 256 256",'<path d="M232,48H160a40,40,0,0,0-32,16A40,40,0,0,0,96,48H24a8,8,0,0,0-8,8V200a8,8,0,0,0,8,8H96a24,24,0,0,1,24,24,8,8,0,0,0,16,0,24,24,0,0,1,24-24h72a8,8,0,0,0,8-8V56A8,8,0,0,0,232,48ZM96,192H32V64H96a24,24,0,0,1,24,24V200A39.81,39.81,0,0,0,96,192Zm128,0H160a39.81,39.81,0,0,0-24,8V88a24,24,0,0,1,24-24h64Z"/>');let nD=0;function rD(){return`notif-${Date.now()}-${++nD}`}function N2(){const e=$g();function t(i,n,r){e.add({id:rD(),variant:i,message:n,title:r==null?void 0:r.title,duration:(r==null?void 0:r.duration)??(i==="error"?6e3:3200)})}return{success:(i,n)=>t("success",i,n),error:(i,n)=>t("error",i,n),warning:(i,n)=>t("warning",i,n),info:(i,n)=>t("info",i,n),dismiss:i=>e.remove(i),clear:()=>e.clear()}}const sD={class:"mp-panel"},aD={class:"mp-header"},lD={class:"mp-search-wrap"},oD={key:0,class:"mp-count"},cD={key:3,class:"mp-local-section"},uD={class:"mp-local-heading"},dD={class:"mp-avatar mp-avatar--ob"},hD={class:"mp-info"},fD={class:"mp-name-row"},pD={class:"mp-name"},_D={class:"badge badge--native"},mD={class:"badge badge--local"},vD={class:"mp-ver"},gD={key:0,class:"mp-desc"},bD={class:"mp-meta"},yD={key:0},wD={class:"mp-action"},SD={class:"mp-list"},CD={key:0,class:"mp-loading"},kD=["src","alt"],AD={class:"mp-info"},MD={class:"mp-name-row"},$D={class:"mp-name"},LD={class:"mp-ver"},ED={key:0,class:"mp-desc"},xD={class:"mp-meta"},HD={key:0},TD={key:1,class:"mp-sep"},ND={class:"mp-enriched"},PD={key:0,class:"mp-stat"},OD={key:1,class:"mp-stat"},ID=["href"],RD=["href"],VD=["href"],DD={class:"mp-action"},ZD={key:1,class:"mp-load-more-wrap"},BD="https://marketplace.openbridge.nubisco.io",FD=20,zD="https://marketplace.openbridge.nubisco.io/api",UD=Ne({__name:"MarketplacePanel",setup(e){const t=Kr(),i=N2(),n=K(null),r=K(""),s=K([]),a=K(0),l=K(!1),o=K(null),c=K(null),u=K(new Map),d=K(null),h=K(0),f=K([]);function v(W){return{name:W.name,version:W.version,description:W.description??"",author:W.author?{name:W.author}:void 0,date:W.last_published_at,weeklyDownloads:W.weekly_downloads,githubStars:W.github_stars??void 0,githubSponsorsUrl:W.github_sponsors_url??void 0,documentationUrl:W.homepage??void 0,links:{npm:W.npm_url,homepage:W.homepage??void 0,repository:W.repository_url??void 0}}}function p(W){return W?W>=1e6?`${(W/1e6).toFixed(1)}M`:W>=1e3?`${(W/1e3).toFixed(1)}K`:W.toString():"0"}async function w(W=!0){W&&(h.value=0,s.value=[]),l.value=!0,o.value=null;try{const A=h.value+1,x=new URLSearchParams({q:r.value,page:String(A),limit:String(FD)}),F=await fetch(`${zD}/plugins?${x}`);if(!F.ok)throw new Error(`Marketplace API error: ${F.status}`);const ie=await F.json(),re=ie.plugins.map(v);s.value=W?re:[...s.value,...re],a.value=ie.total}catch(A){o.value=String(A)}finally{l.value=!1}}async function _(W){if(!c.value){c.value=W.name,o.value=null;try{const A=await Re.marketplace.install(W.name);u.value.set(W.name,A.mainFile),d.value={name:W.name,mainFile:A.mainFile},await Re.pluginsRefresh(),await t.fetchPlugins(),i.success(`Installed ${W.name}`)}catch(A){o.value=`Failed to install ${W.name}: ${A}`,i.error(`Failed to install ${W.name}`)}finally{c.value=null}}}async function y(W){if(!n.value){n.value=W,o.value=null;try{await Re.marketplace.uninstall(W),u.value.delete(W),await t.fetchPlugins(),i.success(`Removed ${W}`)}catch(A){o.value=`Failed to uninstall ${W}: ${A}`,i.error(`Failed to remove ${W}`)}finally{n.value=null}}}async function C(W){if(!(c.value||!W.platform)){c.value=W.name,o.value=null;try{await Re.config.savePlugin(W.name,{platform:W.platform}),u.value.set(W.name,`${W.path}/dist/index.js`),d.value={name:W.name,mainFile:`${W.path}/dist/index.js`},await t.fetchPlugins(),i.success(`Activated ${W.name}`)}catch(A){o.value=`Failed to activate ${W.name}: ${A}`,i.error(`Failed to activate ${W.name}`)}finally{c.value=null}}}function g(W){var F,ie;const x=(((F=W.links)==null?void 0:F.repository)??((ie=W.links)==null?void 0:ie.homepage)??"").match(/github\.com\/([^/]+)/);return x?`https://github.com/${x[1]}.png?size=48`:null}function $(W){return W.name.includes("openbridge-")||Array.isArray(W.badges)&&W.badges.includes("openbridge-plugin")}function E(W){return W.author?typeof W.author=="string"?W.author:W.author.name??"":""}function L(W){const A=Math.floor((Date.now()-new Date(W).getTime())/864e5);return A===0?"today":A<30?`${A}d ago`:A<365?`${Math.floor(A/30)}mo ago`:`${Math.floor(A/365)}y ago`}function B(){h.value++,w(!1)}let T=null;function X(){T&&clearTimeout(T),T=setTimeout(()=>w(),350)}return nt(async()=>{try{const W=await Re.marketplace.installed();for(const A of W.packages)u.value.set(A.name,A.mainFile)}catch{}try{const W=await Re.marketplace.local();f.value=W.plugins}catch{}w()}),(W,A)=>{const x=Ue,F=Wr,ie=ks,re=at,ue=Pt,J=Ss;return m(),M("div",sD,[b("div",aD,[A[4]||(A[4]=b("span",{class:"mp-title"},"Browse Plugins",-1)),b("a",{class:"mp-external",href:BD,target:"_blank",rel:"noopener noreferrer",title:"Open the full marketplace in a new tab"},[j(x,{name:de(pp),size:12},null,8,["name"]),A[3]||(A[3]=le(" Marketplace ",-1))])]),b("div",lD,[j(F,{modelValue:r.value,"onUpdate:modelValue":[A[0]||(A[0]=ae=>r.value=ae),X],placeholder:"Search plugins",size:"sm"},null,8,["modelValue"])]),a.value>0?(m(),M("div",oD,Z(a.value.toLocaleString())+" plugins found",1)):V("",!0),d.value?(m(),he(ie,{key:1,status:"success",dismissible:"",class:"mp-installed-banner",title:`${d.value.name} installed`,onDismiss:A[1]||(A[1]=ae=>d.value=null)},{default:G(()=>[...A[5]||(A[5]=[le(" Click it in your plugins list to configure it. ",-1)])]),_:1},8,["title"])):V("",!0),o.value?(m(),he(re,{key:2,variant:"error"},{default:G(()=>[le(Z(o.value),1)]),_:1})):V("",!0),f.value.length>0?(m(),M("div",cD,[b("div",uD,[j(x,{name:de(zs),size:11},null,8,["name"]),A[6]||(A[6]=le(" Local plugins ",-1))]),(m(!0),M(Ce,null,Fe(f.value,ae=>(m(),he(J,{key:ae.name,class:"mp-row mp-row--ob mp-row--local"},{default:G(()=>[b("div",dD,[j(x,{name:de(zs),size:16},null,8,["name"])]),b("div",hD,[b("div",fD,[b("span",pD,Z(ae.name),1),b("span",_D,[j(x,{name:de(zs),size:9},null,8,["name"]),A[7]||(A[7]=le(" Native ",-1))]),b("span",mD,[j(x,{name:de(XV),size:9},null,8,["name"]),A[8]||(A[8]=le(" Local ",-1))]),b("span",vD,"v"+Z(ae.version),1)]),ae.description?(m(),M("p",gD,Z(ae.description),1)):V("",!0),b("div",bD,[ae.author?(m(),M("span",yD,Z(ae.author),1)):V("",!0)])]),b("div",wD,[u.value.has(ae.name)?(m(),he(ue,{key:0,variant:"ghost",size:"sm",disabled:"",icon:dr},{default:G(()=>[...A[9]||(A[9]=[le("Active",-1)])]),_:1})):(m(),he(ue,{key:1,variant:"primary",size:"sm",loading:c.value===ae.name,disabled:!!c.value||!ae.platform,title:ae.platform?"":"No platform declared in package.json openbridge.platform",onClick:ne=>C(ae)},{default:G(()=>[...A[10]||(A[10]=[le(" Activate ",-1)])]),_:1},8,["loading","disabled","title","onClick"]))])]),_:2},1024))),128))])):V("",!0),b("div",SD,[l.value&&s.value.length===0?(m(),M("div",CD,[j(x,{name:de(ra),size:22},null,8,["name"]),A[11]||(A[11]=b("span",null,"Searching npm…",-1))])):V("",!0),(m(!0),M(Ce,null,Fe(s.value,ae=>(m(),he(J,{key:ae.name,class:Le(["mp-row",{"mp-row--ob":$(ae)}])},{default:G(()=>[b("div",{class:Le(["mp-avatar",{"mp-avatar--ob":$(ae)}])},[g(ae)?(m(),M("img",{key:0,src:g(ae),alt:ae.name,class:"mp-avatar-img",onError:A[2]||(A[2]=ne=>ne.target.style.display="none")},null,40,kD)):V("",!0),$(ae)?(m(),he(x,{key:1,name:de(zs),size:16},null,8,["name"])):(m(),he(x,{key:2,name:de(bs),size:16},null,8,["name"]))],2),b("div",AD,[b("div",MD,[b("span",$D,Z(ae.name),1),b("span",LD,"v"+Z(ae.version),1)]),ae.description?(m(),M("p",ED,Z(ae.description),1)):V("",!0),b("div",xD,[E(ae)?(m(),M("span",HD,Z(E(ae)),1)):V("",!0),E(ae)?(m(),M("span",TD,"·")):V("",!0),b("span",null,Z(L(ae.date)),1)]),b("div",ND,[ae.weeklyDownloads?(m(),M("span",PD,[j(x,{name:de(QV),size:11},null,8,["name"]),le(" "+Z(p(ae.weeklyDownloads)),1)])):V("",!0),ae.githubStars?(m(),M("span",OD,[j(x,{name:de(tD),weight:"fill",size:11},null,8,["name"]),le(" "+Z(p(ae.githubStars)),1)])):V("",!0),ae.githubSponsorsUrl?(m(),M("a",{key:2,href:ae.githubSponsorsUrl,target:"_blank",rel:"noopener",class:"mp-stat mp-stat--link"},[j(x,{name:de(M2),weight:"fill",size:11},null,8,["name"]),A[12]||(A[12]=le(" Sponsor ",-1))],8,ID)):V("",!0),ae.documentationUrl?(m(),M("a",{key:3,href:ae.documentationUrl,target:"_blank",rel:"noopener",class:"mp-stat mp-stat--link"},[j(x,{name:de(ub),size:11},null,8,["name"]),A[13]||(A[13]=le(" Docs ",-1))],8,RD)):V("",!0),b("a",{href:`https://marketplace.openbridge.nubisco.io/plugins/${ae.name}`,target:"_blank",rel:"noopener",class:"mp-stat mp-stat--link mp-stat--marketplace"},[j(x,{name:de(pp),size:11},null,8,["name"]),A[14]||(A[14]=le(" Marketplace ",-1))],8,VD)])]),b("div",DD,[u.value.has(ae.name)?(m(),he(ue,{key:0,variant:"danger",size:"sm",outlined:"",loading:n.value===ae.name,disabled:!!n.value,onClick:ne=>y(ae.name)},{default:G(()=>[...A[15]||(A[15]=[le(" Remove ",-1)])]),_:1},8,["loading","disabled","onClick"])):(m(),he(ue,{key:1,variant:"primary",size:"sm",loading:c.value===ae.name,disabled:!!c.value,onClick:ne=>_(ae)},{default:G(()=>[...A[16]||(A[16]=[le(" Install ",-1)])]),_:1},8,["loading","disabled","onClick"]))])]),_:2},1032,["class"]))),128)),s.value.length>0&&s.value.length<a.value?(m(),M("div",ZD,[j(ue,{variant:"ghost",size:"sm",loading:l.value,disabled:l.value,onClick:B},{default:G(()=>[le(Z(l.value?"Loading…":`Load more (${a.value-s.value.length} remaining)`),1)]),_:1},8,["loading","disabled"])])):V("",!0)])])}}}),WD=zt(UD,[["__scopeId","data-v-789c3f61"]]),jD={key:0,class:"inspector-content nb-inspector"},KD={class:"detail-header"},qD={class:"detail-icon native-icon"},GD={style:{flex:"1","min-width":"0"}},YD={key:1,class:"rename-row"},XD={class:"detail-type"},JD={class:"info-grid"},QD={class:"info-val"},eZ={class:"info-val"},tZ={class:"info-val"},iZ={class:"info-val"},nZ={class:"info-val mono"},rZ={key:0,class:"widget-energy"},sZ={class:"energy-primary"},aZ={class:"energy-value"},lZ={class:"energy-secondary"},oZ={key:0,class:"energy-item"},cZ={class:"energy-item-val"},uZ={key:1,class:"energy-item"},dZ={class:"energy-item-val"},hZ={key:1,class:"widget-thermo"},fZ={class:"thermo-row"},pZ={class:"thermo-value"},_Z={class:"thermo-row"},mZ={class:"thermo-value accent"},vZ={class:"thermo-row"},gZ={key:2,class:"widget-thermo"},bZ={class:"thermo-row"},yZ={class:"thermo-value"},wZ={class:"thermo-row"},SZ={class:"thermo-value accent"},CZ={class:"thermo-row"},kZ={key:3,class:"widget-generic"},AZ={key:0,class:"no-telemetry"},MZ={class:"char-name"},$Z={class:"char-value"},LZ={class:"event-list"},EZ=["title"],xZ={class:"event-body"},HZ={class:"event-message"},TZ={key:0,class:"event-source"},NZ={class:"history-tabs"},PZ=["onClick"],OZ={key:0,class:"history-nav"},IZ={class:"history-nav-center"},RZ={class:"history-total"},VZ={class:"history-date"},DZ={key:2,class:"no-history"},ZZ={key:3,class:"no-history"},BZ={key:4,class:"no-history"},FZ={class:"obs-help"},zZ={class:"obs-form"},UZ={class:"obs-verdicts"},WZ={key:1,class:"obs-list"},jZ={class:"obs-list-head"},KZ={class:"obs-when"},qZ={class:"obs-temp"},GZ={key:0,class:"obs-note"},YZ={class:"calibration-actions"},XZ={class:"char-list"},JZ={class:"char-name"},QZ={class:"char-value"},eB={key:0,class:"homekit-notice"},tB={class:"homekit-row"},iB={key:1,class:"homekit-notice"},nB={class:"detail-header"},rB={class:"detail-icon"},sB={style:{flex:"1","min-width":"0"}},aB={key:1,class:"rename-row"},lB={class:"detail-type"},oB={class:"info-grid"},cB={key:0,class:"info-key"},uB={key:1,class:"info-val"},dB={key:0,class:"homekit-row"},hB={key:1,class:"homekit-notice"},fB={class:"char-list"},pB={class:"char-name"},_B={class:"homekit-row"},mB={key:0,class:"homekit-notice"},vB={class:"detail-uuid"},gB=Ne({__name:"DeviceInspector",setup(e){const t=K(new Set),i=K(!1),n=K("");function r(be){return!t.value.has(be)}async function s(){try{const{hidden:be}=await Re.homekitHidden();t.value=new Set(be)}catch{}}async function a(be,ce){i.value=!0,n.value="";try{const Ie=await Re.setHomekitVisibility(be,ce),Ge=new Set(t.value);ce?Ge.delete(be):Ge.add(be),t.value=Ge,Ie.applied||(n.value="Saved. This takes effect after the next OpenBridge restart.")}catch(Ie){n.value=`Could not change visibility: ${Ie.message}`}finally{i.value=!1}}const l=K({}),o=K([]),c=K(""),u=q(()=>[{value:"",label:"Default (as published)"},...o.value.map(be=>({value:be.key,label:be.label}))]);function d(be){return o.value.some(ce=>ce.serviceUuid===be)}function h(be,ce){var Ie;return((Ie=l.value[be])==null?void 0:Ie[ce])??""}const f=K(null);function v(be){return be.homekitType||be.widgetType}async function p(be){f.value=null;try{const{accessory:ce}=await Re.deviceAccessory(be);f.value=ce}catch{}}async function w(){try{const{overrides:be,available:ce}=await Re.homekitServiceTypes();l.value=be,o.value=ce}catch{}}async function _(be,ce,Ie){i.value=!0,c.value="";try{await Re.setHomekitServiceType(be,ce,Ie||null);const Ge={...l.value},Ke={...Ge[be]??{}};Ie?Ke[ce]=Ie:delete Ke[ce],Object.keys(Ke).length>0?Ge[be]=Ke:delete Ge[be],l.value=Ge,c.value="Saved. This takes effect after the next OpenBridge restart."}catch(Ge){c.value=`Could not change type: ${Ge.message}`}finally{i.value=!1}}nt(()=>{s(),w()});const y=Qo(),C=Sg(),g=K(""),$=K(""),E=K("success"),L=q(()=>{const be=y.selectedDevice;return!be||be.kind!=="native"?null:be.dev.health??null}),B=q(()=>{var ce;const be=(ce=L.value)==null?void 0:ce.lastSeen;return be?`Not responding since ${new Date(be).toLocaleString()}`:"Not responding"}),T=[{id:"cold",label:"Too cold"},{id:"ok",label:"About right"},{id:"warm",label:"Too warm"}],X=K(null),W=K("ok"),A=K(""),x=K(!1),F=K(""),ie=K([]),re=K(0);async function ue(){const be=y.selectedDevice;if(!be||be.kind!=="native"||!be.dev.observations){ie.value=[],re.value=0;return}try{const ce=await Re.deviceObservations(be.dev.id,20);ie.value=ce.observations,re.value=ce.total}catch{}}async function J(){const be=y.selectedDevice;if(!(!be||be.kind!=="native"||X.value===null)){x.value=!0,F.value="";try{await Re.reportObservation(be.dev.id,{roomTemperature:X.value,comfort:W.value,...A.value.trim()?{note:A.value.trim()}:{}}),A.value="",await ue()}catch(ce){F.value=ce instanceof Error?ce.message:String(ce)}finally{x.value=!1}}}Ve(()=>y.selectedDevice,()=>{F.value="",A.value="",ue()},{immediate:!0});const ae=q(()=>{const be=y.selectedDevice;return!be||be.kind!=="native"?[]:be.dev.actions??[]});async function ne(be){const ce=y.selectedDevice;if(!(!ce||ce.kind!=="native")&&!(be.confirm&&!await C({title:be.label,subjectLabel:"Device",subject:ce.dev.name,message:be.confirm,confirmLabel:be.label}))){g.value=be.id,$.value="";try{await Re.controlDevice(ce.dev.id,be.id,!0),E.value="success",$.value=`${be.label} sent.`}catch(Ie){E.value="error",$.value=`${be.label} failed: ${Ie.message}`}finally{g.value=""}}}const Q=q(()=>y.selectedDevice),oe=q(()=>Q.value?Q.value.kind==="native"?Q.value.dev.id:Q.value.acc.uuid:null),ve={1:{label:"Other",icon:"cube"},2:{label:"Bridge",icon:"intersect"},3:{label:"Fan",icon:"fan"},4:{label:"Garage Door",icon:"garage"},5:{label:"Light",icon:"lightbulb"},6:{label:"Lock",icon:"lock"},7:{label:"Outlet",icon:"plugs"},8:{label:"Switch",icon:"toggle-right"},9:{label:"Thermostat",icon:"thermometer"},10:{label:"Sensor",icon:"pulse"},11:{label:"Security",icon:"shield"},12:{label:"Door",icon:"door"},13:{label:"Window",icon:"app-window"},14:{label:"Window Covering",icon:"rows"},15:{label:"Programm. Switch",icon:"sliders"},16:{label:"Range Extender",icon:"broadcast"},17:{label:"Camera",icon:"camera"},18:{label:"Video Doorbell",icon:"bell"},19:{label:"Air Purifier",icon:"wind"},20:{label:"Heater/Cooler",icon:"thermometer-hot"},21:{label:"Air Conditioner",icon:"snowflake"},22:{label:"Humidifier",icon:"drop"},23:{label:"Dehumidifier",icon:"drop"},26:{label:"Speaker",icon:"speaker-high"},28:{label:"Sprinkler",icon:"drop"},29:{label:"Faucet",icon:"drop"},30:{label:"Shower",icon:"drop"},32:{label:"TV",icon:"television"},34:{label:"Router",icon:"broadcast"},36:{label:"Target Control",icon:"game-controller"},38:{label:"Smart Speaker",icon:"speaker-hifi"}};function fe(be){return ve[be]??{label:`Category ${be}`,icon:"cube"}}const pe=new Set(["AccessoryInformation","0000003E-0000-1000-8000-0026BB765291","ProtocolInformation","000000A2-0000-1000-8000-0026BB765291"]);function ye(be){return be.services.filter(ce=>!pe.has(ce.name)&&!pe.has(ce.uuid))}function U(be){return be.services.find(ce=>pe.has(ce.name)||pe.has(ce.uuid))}function _e(be){const ce=U(be);if(!ce)return null;const Ie=Ge=>{var Ke;return(Ke=ce.characteristics.find(Wt=>Wt.name===Ge||Wt.name.includes(Ge)))==null?void 0:Ke.value};return{manufacturer:Ie("Manufacturer")??Ie("Manuf"),model:Ie("Model"),serial:Ie("SerialNumber")??Ie("Serial"),firmware:Ie("FirmwareRevision")??Ie("Firmware")}}function ge(be){return be.value===null||be.value===void 0?"—":be.format==="bool"?be.value?"On":"Off":typeof be.value=="number"?String(Math.round(be.value*100)/100):String(be.value)}function se(be){return be.perms.includes("pw")}const H=K(!1),N=K("");function O(be){N.value=be,H.value=!0}async function te(be){var ce,Ie;if(N.value.trim())try{const Ge=N.value.trim();await Re.renameDevice(be,Ge),H.value=!1,((ce=Q.value)==null?void 0:ce.kind)==="native"?Q.value.dev.name=Ge:((Ie=Q.value)==null?void 0:Ie.kind)==="hap"&&(Q.value.acc.displayName=Ge);const{useDaemonStore:Ke}=await $8(async()=>{const{useDaemonStore:yt}=await Promise.resolve().then(()=>X8);return{useDaemonStore:yt}},void 0);await Ke().fetchAccessories()}catch(Ge){console.error("Rename failed:",Ge)}}async function ee(be,ce,Ie,Ge){try{await Re.setCharacteristic(be,ce,Ie,Ge);const{useDaemonStore:Ke}=await $8(async()=>{const{useDaemonStore:yt}=await Promise.resolve().then(()=>X8);return{useDaemonStore:yt}},void 0);await Ke().fetchAccessories()}catch(Ke){console.error("Failed to set characteristic:",Ke)}}const me=K([]);function we(be){const ce=new Date(be);return Number.isNaN(ce.getTime())?be:new Date().toDateString()===ce.toDateString()?ce.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit"}):ce.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}async function S(){const be=Q.value;if((be==null?void 0:be.kind)!=="native"){me.value=[];return}try{const ce=await Re.deviceEvents(be.dev.id,100);me.value=ce.events}catch{me.value=[]}}const k={switch:"plugs",light:"lightbulb",thermostat:"thermometer",dehumidifier:"drop",energy_meter:"lightning",gate:"garage",sensor:"pulse",camera:"camera"},D={camera:"Camera",switch:"Switch",light:"Light",thermostat:"Thermostat",dehumidifier:"Dehumidifier",energy_meter:"Energy Meter",gate:"Gate",sensor:"Sensor"};function P(be){return k[be]??"cube"}function R(be){return D[be]??be}function I(be,ce=1){if(be==null)return"—";const Ie=Number(be);return isFinite(Ie)?Ie.toFixed(ce):String(be)}function z(be){return Object.entries(be.telemetry).filter(([ce])=>!ce.startsWith("_"))}const Y=K("day"),Se=K(new Date().toISOString().slice(0,10)),Me=K(null),De=K(!1);async function Xe(be){if(!De.value){De.value=!0;try{Me.value=await Re.deviceHistory(be,Y.value,Se.value)}catch{}finally{De.value=!1}}}function Te(be){var Ie;const ce=new Date(Se.value+(Se.value.length<=7?"-01":""));Y.value==="day"?(ce.setDate(ce.getDate()+be),Se.value=ce.toISOString().slice(0,10)):Y.value==="month"?(ce.setMonth(ce.getMonth()+be),Se.value=ce.toISOString().slice(0,7)):(ce.setFullYear(ce.getFullYear()+be),Se.value=String(ce.getFullYear())),((Ie=Q.value)==null?void 0:Ie.kind)==="native"&&Xe(Q.value.dev.id)}Ve(Y,()=>{var ce;const be=new Date;Y.value==="day"?Se.value=be.toISOString().slice(0,10):Y.value==="month"?Se.value=be.toISOString().slice(0,7):Se.value=String(be.getFullYear()),((ce=Q.value)==null?void 0:ce.kind)==="native"&&Q.value.dev.widgetType==="energy_meter"&&Xe(Q.value.dev.id)}),Ve(oe,(be,ce)=>{if(be===ce&&Me.value)return;const Ie=Q.value;(Ie==null?void 0:Ie.kind)==="native"?p(Ie.dev.id):f.value=null,S(),(Ie==null?void 0:Ie.kind)==="native"&&Ie.dev.widgetType==="energy_meter"&&(Se.value=new Date().toISOString().slice(0,10),Y.value="day",Xe(Ie.dev.id))},{immediate:!0});const rt=K([]),It=K([]),un=K(!1),Ut=K(!1),Rt=K(!1),vn=q(()=>JSON.stringify(rt.value)!==JSON.stringify(It.value)),gn=q(()=>!Q.value||Q.value.kind!=="native"?null:Q.value.dev);async function xl(be){const{plugins:ce}=await Re.plugins(),Ie=ce.find(Ke=>Ke.id===be.pluginId);if(!Ie)return null;if(Ie.source!=="homebridge"){const{config:Ke}=await Re.config.getPlugin(be.pluginId);return Ke?{pluginConfig:Ke,isNative:!0,pluginName:be.pluginId,platformName:void 0}:null}else{const Ke=Ie.platformName??be.pluginId,{config:Wt}=await Re.config.getPlatform(Ke);return Wt?{pluginConfig:Wt,isNative:!1,pluginName:be.pluginId,platformName:Ke}:null}}async function l0(){const be=gn.value;if(be!=null&&be.interpolation){un.value=!0,Rt.value=!1;try{const ce=await xl(be);if(!ce)return;const Ge=(ce.pluginConfig.devices??[]).find(mr=>mr.id===be.id);if(!Ge)return;const Ke=be.interpolation,yt=(Ge[Ke.configField]??[]).map(mr=>({input:mr[Ke.configShape.inputKey]??0,output:mr[Ke.configShape.outputKey]??0}));rt.value=yt,It.value=JSON.parse(JSON.stringify(yt))}catch(ce){console.error("Failed to load interpolation config:",ce)}finally{un.value=!1}}}async function o0(){const be=gn.value;if(be!=null&&be.interpolation){Ut.value=!0,Rt.value=!1;try{const ce=await xl(be);if(!ce)return;const Ie=be.interpolation,Ge=ce.pluginConfig.devices??[],Ke=Ge.findIndex(yt=>yt.id===be.id);if(Ke<0)return;const Wt=rt.value.map(yt=>({[Ie.configShape.inputKey]:yt.input,[Ie.configShape.outputKey]:yt.output}));Ge[Ke]={...Ge[Ke],[Ie.configField]:Wt},ce.pluginConfig.devices=Ge,ce.isNative?await Re.config.savePlugin(ce.pluginName,ce.pluginConfig):await Re.config.savePlatform(ce.pluginConfig),It.value=JSON.parse(JSON.stringify(rt.value)),Rt.value=!0}catch(ce){console.error("Failed to save interpolation config:",ce)}finally{Ut.value=!1}}}function Hl(){rt.value=JSON.parse(JSON.stringify(It.value)),Rt.value=!1}Ve(oe,(be,ce)=>{var Ie;be===ce&&It.value.length>0||(Rt.value=!1,((Ie=Q.value)==null?void 0:Ie.kind)==="native"&&Q.value.dev.interpolation?l0():(rt.value=[],It.value=[]))},{immediate:!0});const A1=q(()=>{var ce;return(ce=Me.value)!=null&&ce.buckets?[{name:"kWh",data:Me.value.buckets.map(Ie=>{let Ge=Ie.label;return Y.value==="day"?Ge=parseInt(Ie.label)%6===0?Ie.label:"":Y.value==="month"&&(Ge=parseInt(Ie.label)%5===1?Ie.label:""),{x:Ge,y:Math.max(0,Math.round((Ie.kwh??0)*100)/100)}})}]:[]});return(be,ce)=>{const Ie=Ue,Ge=Wr,Ke=Pt,Wt=ks,yt=S2,mr=WA,M1=w2,c0=at,ke=Cs,Be=Vx,Ye=ba,Ci=o1;return Q.value?(m(),M("div",jD,[Q.value.kind==="native"?(m(),M(Ce,{key:0},[b("div",KD,[b("div",qD,[j(Ie,{name:P(v(Q.value.dev)),size:26},null,8,["name"])]),b("div",GD,[H.value?(m(),M("div",YD,[j(Ge,{modelValue:N.value,"onUpdate:modelValue":ce[1]||(ce[1]=$e=>N.value=$e),size:"sm",onKeyup:[ce[2]||(ce[2]=xi($e=>te(Q.value.dev.id),["enter"])),ce[3]||(ce[3]=xi($e=>H.value=!1,["escape"]))]},null,8,["modelValue"]),j(Ke,{variant:"primary",size:"sm",icon:dr,"aria-label":"Save name",onClick:ce[4]||(ce[4]=$e=>te(Q.value.dev.id))}),j(Ke,{variant:"ghost",size:"sm",icon:wc,"aria-label":"Cancel rename",onClick:ce[5]||(ce[5]=$e=>H.value=!1)})])):(m(),M("h2",{key:0,class:"detail-name",title:"Click to rename",onClick:ce[0]||(ce[0]=$e=>O(Q.value.dev.name))},Z(Q.value.dev.name),1)),b("div",XD,Z(R(v(Q.value.dev))),1)])]),j(yt,{title:"Device info",fluid:""},Fm({default:G(()=>[L.value&&L.value.status==="stale"?(m(),he(Wt,{key:0,status:"warning",title:B.value,style:{"margin-bottom":"0.5rem"}},{default:G(()=>[le(Z(L.value.reason),1)]),_:1},8,["title"])):V("",!0),$.value?(m(),he(Wt,{key:1,status:E.value,title:$.value,style:{"margin-bottom":"0.5rem"}},null,8,["status","title"])):V("",!0),b("div",JD,[ce[21]||(ce[21]=b("span",{class:"info-key"},"Plugin",-1)),b("span",QD,Z(Q.value.dev.pluginId),1),Q.value.dev.manufacturer?(m(),M(Ce,{key:0},[ce[19]||(ce[19]=b("span",{class:"info-key"},"Manufacturer",-1)),b("span",eZ,Z(Q.value.dev.manufacturer),1)],64)):V("",!0),Q.value.dev.model?(m(),M(Ce,{key:1},[ce[20]||(ce[20]=b("span",{class:"info-key"},"Model",-1)),b("span",tZ,Z(Q.value.dev.model),1)],64)):V("",!0),ce[22]||(ce[22]=b("span",{class:"info-key"},"Status",-1)),b("span",iZ,Z(Q.value.dev.pluginStatus),1),ce[23]||(ce[23]=b("span",{class:"info-key"},"ID",-1)),b("span",nZ,Z(Q.value.dev.id),1)])]),_:2},[ae.value.length>0?{name:"toolbar",fn:G(()=>[(m(!0),M(Ce,null,Fe(ae.value,$e=>(m(),he(Ke,{key:$e.id,size:"xs",variant:$e.danger?"danger":"ghost",disabled:g.value!=="",loading:g.value===$e.id,onClick:et=>ne($e)},{default:G(()=>[le(Z($e.label),1)]),_:2},1032,["variant","disabled","loading","onClick"]))),128))]),key:"0"}:void 0]),1024),j(yt,{title:"State",fluid:""},{default:G(()=>[Q.value.dev.widgetType==="energy_meter"?(m(),M("div",rZ,[b("div",sZ,[b("span",aZ,Z(I(Q.value.dev.telemetry.power,1)),1),ce[24]||(ce[24]=b("span",{class:"energy-unit"},"W",-1))]),b("div",lZ,[Q.value.dev.telemetry.voltage!==void 0?(m(),M("span",oZ,[ce[25]||(ce[25]=b("span",{class:"energy-label"},"Voltage",-1)),b("span",cZ,Z(I(Q.value.dev.telemetry.voltage,1))+" V",1)])):V("",!0),Q.value.dev.telemetry.current!==void 0?(m(),M("span",uZ,[ce[26]||(ce[26]=b("span",{class:"energy-label"},"Current",-1)),b("span",dZ,Z(I(Q.value.dev.telemetry.current,3))+" A",1)])):V("",!0)])])):Q.value.dev.widgetType==="thermostat"?(m(),M("div",hZ,[b("div",fZ,[ce[27]||(ce[27]=b("span",{class:"thermo-label"},"Current",-1)),b("span",pZ,Z(I(Q.value.dev.telemetry.currentTemperature,1))+"°C",1)]),b("div",_Z,[ce[28]||(ce[28]=b("span",{class:"thermo-label"},"Target",-1)),b("span",mZ,Z(I(Q.value.dev.telemetry.targetTemperature,1))+"°C ",1)]),b("div",vZ,[ce[29]||(ce[29]=b("span",{class:"thermo-label"},"Active",-1)),b("span",{class:Le(["thermo-value",Q.value.dev.telemetry.active?"on":"off"])},Z(Q.value.dev.telemetry.active?"On":"Off"),3)])])):Q.value.dev.widgetType==="dehumidifier"?(m(),M("div",gZ,[b("div",bZ,[ce[30]||(ce[30]=b("span",{class:"thermo-label"},"Humidity",-1)),b("span",yZ,Z(I(Q.value.dev.telemetry.currentHumidity,0))+"%",1)]),b("div",wZ,[ce[31]||(ce[31]=b("span",{class:"thermo-label"},"Target",-1)),b("span",SZ,Z(I(Q.value.dev.telemetry.targetHumidity,0))+"%",1)]),b("div",CZ,[ce[32]||(ce[32]=b("span",{class:"thermo-label"},"Active",-1)),b("span",{class:Le(["thermo-value",Q.value.dev.telemetry.active?"on":"off"])},Z(Q.value.dev.telemetry.active?"On":"Off"),3)])])):(m(),M("div",kZ,[Object.keys(Q.value.dev.telemetry).filter($e=>!$e.startsWith("_")).length===0?(m(),M("span",AZ,"No telemetry yet")):V("",!0),(m(!0),M(Ce,null,Fe(z(Q.value.dev),([$e,et])=>(m(),M("div",{key:$e,class:"char-row"},[b("span",MZ,Z($e),1),b("span",$Z,Z(String(et)),1)]))),128))]))]),_:1}),me.value.length>0?(m(),he(yt,{key:0,title:"Recent activity",fluid:""},{default:G(()=>[b("ul",LZ,[(m(!0),M(Ce,null,Fe(me.value,($e,et)=>(m(),M("li",{key:`${$e.at}-${et}`,class:"event"},[b("span",{class:"event-time",title:$e.at},Z(we($e.at)),9,EZ),b("span",xZ,[b("span",HZ,Z($e.message),1),$e.source?(m(),M("span",TZ,Z($e.source),1)):V("",!0)])]))),128))])]),_:1})):V("",!0),Q.value.dev.widgetType==="energy_meter"?(m(),he(yt,{key:1,title:"Energy history",class:"energy-history",fluid:""},{default:G(()=>[b("div",NZ,[(m(),M(Ce,null,Fe(["day","month","year"],$e=>b("button",{key:$e,class:Le(["history-tab",{active:Y.value===$e}]),onClick:et=>Y.value=$e},Z($e),11,PZ)),64))]),Me.value?(m(),M("div",OZ,[j(Ke,{variant:"ghost",size:"xs",icon:Hv,title:"Previous",onClick:ce[6]||(ce[6]=$e=>Te(-1))}),b("div",IZ,[b("span",RZ,[le(Z(Me.value.totalKwh.toFixed(2))+" ",1),ce[33]||(ce[33]=b("span",{class:"history-unit"},"kWh",-1))]),b("span",VZ,Z(Me.value.date),1)]),j(Ke,{variant:"ghost",size:"xs",icon:l2,title:"Next",onClick:ce[7]||(ce[7]=$e=>Te(1))})])):V("",!0),Me.value&&Me.value.totalKwh>0?(m(),he(mr,{key:1,series:A1.value,height:120,"show-legend":!1,"show-tooltip":!0},null,8,["series"])):V("",!0),Me.value&&Me.value.totalKwh===0?(m(),M("div",DZ," No consumption recorded for this period. Data accumulates every 5 minutes. ")):V("",!0),!Me.value&&!De.value?(m(),M("div",ZZ,"No data available for this period.")):V("",!0),De.value?(m(),M("div",BZ,"Loading history…")):V("",!0)]),_:1})):V("",!0),Q.value.dev.observations?(m(),he(yt,{key:2,title:"Report",fluid:""},{default:G(()=>[b("p",FZ,Z(Q.value.dev.observations.help??"Tell the plugin what this device cannot measure itself."),1),b("div",zZ,[j(M1,{modelValue:X.value,"onUpdate:modelValue":ce[8]||(ce[8]=$e=>X.value=$e),size:"sm",min:Q.value.dev.observations.min,max:Q.value.dev.observations.max,step:.5,label:`${Q.value.dev.observations.label} (${Q.value.dev.observations.unit})`},null,8,["modelValue","min","max","label"]),b("div",UZ,[(m(),M(Ce,null,Fe(T,$e=>j(Ke,{key:$e.id,size:"sm",variant:W.value===$e.id?"primary":"ghost",onClick:et=>W.value=$e.id},{default:G(()=>[le(Z($e.label),1)]),_:2},1032,["variant","onClick"])),64))]),j(Ge,{modelValue:A.value,"onUpdate:modelValue":ce[9]||(ce[9]=$e=>A.value=$e),size:"sm",placeholder:"Anything worth noting (sunny, window open)"},null,8,["modelValue"]),j(Ke,{size:"sm",variant:"primary",disabled:X.value===null||x.value,onClick:J},{default:G(()=>[...ce[34]||(ce[34]=[le(" Save report ",-1)])]),_:1},8,["disabled"])]),F.value?(m(),he(c0,{key:0,variant:"error"},{default:G(()=>[le(Z(F.value),1)]),_:1})):V("",!0),ie.value.length>0?(m(),M("div",WZ,[b("div",jZ,Z(re.value)+" report"+Z(re.value===1?"":"s")+" so far",1),(m(!0),M(Ce,null,Fe(ie.value,($e,et)=>(m(),M("div",{key:et,class:"obs-row"},[b("span",KZ,Z(new Date($e.at).toLocaleString()),1),b("span",qZ,Z($e.roomTemperature)+"°",1),j(ke,{variant:$e.comfort==="ok"?"green":$e.comfort==="cold"?"blue":"orange",size:"sm"},{default:G(()=>[le(Z($e.comfort),1)]),_:2},1032,["variant"]),$e.note?(m(),M("span",GZ,Z($e.note),1)):V("",!0)]))),128))])):V("",!0)]),_:1})):V("",!0),Q.value.dev.interpolation&&rt.value.length>0?(m(),he(yt,{key:3,title:"Calibration",fluid:""},{default:G(()=>[j(Be,{modelValue:rt.value,"onUpdate:modelValue":ce[10]||(ce[10]=$e=>rt.value=$e),height:220,"input-label":Q.value.dev.interpolation.inputLabel,"output-label":Q.value.dev.interpolation.outputLabel,"input-min":Q.value.dev.interpolation.inputMin,"input-max":Q.value.dev.interpolation.inputMax,"output-min":Q.value.dev.interpolation.outputMin,"output-max":Q.value.dev.interpolation.outputMax,"input-step":.5,"output-step":1,"show-grid":!0,"show-tooltip":!0},null,8,["modelValue","input-label","output-label","input-min","input-max","output-min","output-max"]),ce[37]||(ce[37]=b("div",{class:"calibration-hint"},"Drag points to adjust. Double-click to add. Right-click to remove.",-1)),b("div",YZ,[j(Ke,{variant:"primary",size:"sm",disabled:!vn.value||Ut.value,onClick:o0},{default:G(()=>[le(Z(Ut.value?"Saving...":"Save"),1)]),_:1},8,["disabled"]),j(Ke,{variant:"ghost",size:"sm",disabled:!vn.value,onClick:Hl},{default:G(()=>[...ce[35]||(ce[35]=[le(" Reset ",-1)])]),_:1},8,["disabled"])]),Rt.value?(m(),he(Wt,{key:0,status:"success",title:"Configuration saved"},{default:G(()=>[...ce[36]||(ce[36]=[le(" Restart the plugin to apply the new mapping. ",-1)])]),_:1})):V("",!0)]),_:1})):Q.value.dev.interpolation&&un.value?(m(),he(yt,{key:4,title:"Calibration",fluid:""},{default:G(()=>[...ce[38]||(ce[38]=[b("div",{class:"no-history"},"Loading calibration data...",-1)])]),_:1})):V("",!0),z(Q.value.dev).length>0?(m(),he(yt,{key:5,title:"All telemetry",fluid:""},{default:G(()=>[b("div",XZ,[(m(!0),M(Ce,null,Fe(z(Q.value.dev),([$e,et])=>(m(),M("div",{key:$e,class:"char-row"},[b("span",JZ,Z($e),1),b("span",QZ,Z(String(et)),1)]))),128))])]),_:1})):V("",!0),f.value?(m(),he(yt,{key:6,title:"HomeKit",fluid:""},{default:G(()=>[(m(!0),M(Ce,null,Fe(ye(f.value),$e=>sn((m(),M("div",{key:$e.uuid,class:"homekit-row"},[ce[39]||(ce[39]=b("div",{class:"homekit-copy"},[b("span",{class:"homekit-title"},"Show in HomeKit as"),b("span",{class:"homekit-hint"}," A plugin cannot know what a generic relay drives. Set it here and OpenBridge re-applies it on every restart, so the Home app stops reverting to a switch. ")],-1)),j(Ye,{"model-value":h(f.value.uuid,$e.uuid),options:u.value,disabled:i.value,size:"sm","onUpdate:modelValue":et=>_(f.value.uuid,$e.uuid,String(et))},null,8,["model-value","options","disabled","onUpdate:modelValue"])])),[[Zh,d($e.uuid)]])),128)),c.value?(m(),M("div",eB,Z(c.value),1)):V("",!0),b("div",tB,[ce[40]||(ce[40]=b("div",{class:"homekit-copy"},[b("span",{class:"homekit-title"},"Expose to HomeKit"),b("span",{class:"homekit-hint"}," Hide devices the Home app cannot represent usefully. OpenBridge keeps its telemetry and history either way. ")],-1)),j(Ci,{name:`homekit-visible-${f.value.uuid}`,"model-value":r(f.value.uuid),disabled:i.value,"onUpdate:modelValue":ce[11]||(ce[11]=$e=>a(f.value.uuid,!!$e))},null,8,["name","model-value","disabled"])]),n.value?(m(),M("div",iB,Z(n.value),1)):V("",!0)]),_:1})):V("",!0)],64)):Q.value.kind==="hap"?(m(),M(Ce,{key:1},[b("div",nB,[b("div",rB,[j(Ie,{name:fe(Q.value.acc.category).icon,size:26},null,8,["name"])]),b("div",sB,[H.value?(m(),M("div",aB,[j(Ge,{modelValue:N.value,"onUpdate:modelValue":ce[13]||(ce[13]=$e=>N.value=$e),size:"sm",onKeyup:[ce[14]||(ce[14]=xi($e=>te(Q.value.acc.uuid),["enter"])),ce[15]||(ce[15]=xi($e=>H.value=!1,["escape"]))]},null,8,["modelValue"]),j(Ke,{variant:"primary",size:"sm",icon:dr,"aria-label":"Save name",onClick:ce[16]||(ce[16]=$e=>te(Q.value.acc.uuid))}),j(Ke,{variant:"ghost",size:"sm",icon:wc,"aria-label":"Cancel rename",onClick:ce[17]||(ce[17]=$e=>H.value=!1)})])):(m(),M("h2",{key:0,class:"detail-name",title:"Click to rename",onClick:ce[12]||(ce[12]=$e=>O(Q.value.acc.displayName))},Z(Q.value.acc.displayName),1)),b("div",lB,Z(fe(Q.value.acc.category).label),1)])]),_e(Q.value.acc)?(m(),he(yt,{key:0,title:"Device info",fluid:""},{default:G(()=>[b("div",oB,[(m(!0),M(Ce,null,Fe(Object.entries(_e(Q.value.acc)),([$e,et])=>(m(),M(Ce,{key:$e},[et?(m(),M("span",cB,Z($e),1)):V("",!0),et?(m(),M("span",uB,Z(et),1)):V("",!0)],64))),128))])]),_:1})):V("",!0),(m(!0),M(Ce,null,Fe(ye(Q.value.acc),$e=>(m(),he(yt,{key:$e.uuid,title:$e.displayName||$e.name,fluid:""},{default:G(()=>[d($e.uuid)?(m(),M("div",dB,[ce[41]||(ce[41]=b("div",{class:"homekit-copy"},[b("span",{class:"homekit-title"},"Show in HomeKit as"),b("span",{class:"homekit-hint"}," A plugin cannot know what a generic relay drives. Set it here and OpenBridge re-applies it on every restart, so the Home app stops reverting to a switch. ")],-1)),j(Ye,{"model-value":h(Q.value.acc.uuid,$e.uuid),options:u.value,disabled:i.value,size:"sm","onUpdate:modelValue":et=>_(Q.value.acc.uuid,$e.uuid,String(et))},null,8,["model-value","options","disabled","onUpdate:modelValue"])])):V("",!0),c.value?(m(),M("div",hB,Z(c.value),1)):V("",!0),b("div",fB,[(m(!0),M(Ce,null,Fe($e.characteristics,et=>(m(),M("div",{key:et.uuid,class:"char-row"},[b("span",pB,Z(et.name),1),se(et)&&et.format==="bool"?(m(),he(Ci,{key:0,name:`hap-char-${$e.uuid}-${et.uuid}`,"model-value":!!et.value,"onUpdate:modelValue":u0=>ee(Q.value.acc.uuid,$e.uuid,et.uuid,u0?1:0)},null,8,["name","model-value","onUpdate:modelValue"])):(m(),M("span",{key:1,class:Le(["char-value",{on:et.format==="bool"&&et.value}])},Z(ge(et)),3))]))),128))])]),_:2},1032,["title"]))),128)),j(yt,{title:"HomeKit",fluid:""},{default:G(()=>[b("div",_B,[ce[42]||(ce[42]=b("div",{class:"homekit-copy"},[b("span",{class:"homekit-title"},"Expose to HomeKit"),b("span",{class:"homekit-hint"}," Hide devices the Home app cannot represent usefully. OpenBridge keeps its telemetry and history either way. ")],-1)),j(Ci,{name:`homekit-visible-${Q.value.acc.uuid}`,"model-value":r(Q.value.acc.uuid),disabled:i.value,"onUpdate:modelValue":ce[18]||(ce[18]=$e=>a(Q.value.acc.uuid,!!$e))},null,8,["name","model-value","disabled"])]),n.value?(m(),M("div",mB,Z(n.value),1)):V("",!0)]),_:1}),b("div",vB,"UUID: "+Z(Q.value.acc.uuid),1)],64)):V("",!0)])):V("",!0)}}}),bB=zt(gB,[["__scopeId","data-v-93cac877"]]),yB={class:"logs-filter"},wB={key:0,class:"log-empty"},SB={class:"log-time"},CB={class:"log-plugin"},kB={class:"log-msg"},_p="openbridge.logs.panelSize",AB=Ne({__name:"LiveLogsPanel",setup(e){const t=Kr(),i=["collapsed","default","full"],n=K("collapsed");nt(()=>{const c=localStorage.getItem(_p);c&&i.includes(c)&&(n.value=c)}),Ve(n,c=>localStorage.setItem(_p,c));const r=K([]),s=K(null),a=q(()=>[{value:"system",label:"system"},...t.plugins.map(c=>({value:c.manifest.name,label:c.manifest.name}))]),l=q(()=>r.value.length===0?t.logs:t.logs.filter(c=>r.value.includes(c.plugin)));function o(){t.logs.length=0}return Ve(()=>l.value.length,async()=>{const c=s.value;!c||!(c.scrollHeight-c.scrollTop-c.clientHeight<40)||(await Gt(),c.scrollTop=c.scrollHeight)}),(c,u)=>{const d=ba,h=Pt,f=S2;return m(),he(f,{size:n.value,"onUpdate:size":u[1]||(u[1]=v=>n.value=v),title:"Live Logs"},{toolbar:G(()=>[b("div",yB,[j(d,{modelValue:r.value,"onUpdate:modelValue":u[0]||(u[0]=v=>r.value=v),multiple:"",options:a.value,placeholder:"All plugins",size:"xs"},null,8,["modelValue","options"])]),j(h,{size:"xs",variant:"ghost",icon:C2,title:"Clear",onClick:o})]),default:G(()=>[b("div",{ref_key:"logsEl",ref:s,class:"log-list"},[l.value.length===0?(m(),M("div",wB,"No log entries yet.")):V("",!0),(m(!0),M(Ce,null,Fe(l.value,(v,p)=>(m(),M("div",{key:p,class:"log-line"},[b("span",SB,Z(new Date(v.timestamp).toLocaleTimeString()),1),b("span",{class:Le(["log-level",`log-level--${v.level}`])},Z(v.level.toUpperCase()),3),b("span",CB,Z(v.plugin),1),b("span",kB,Z(v.message),1)]))),128))],512)]),_:1},8,["size"])}}}),MB=zt(AB,[["__scopeId","data-v-2d8d29ff"]]),mp="https://docs.nubisco.io/openbridge/",vp="https://github.com/sponsors/joseporto",$B=Ne({__name:"AppLayout",setup(e){const t=Jo(),i=Kr(),n=Qo(),r=Ms(),s=e0(),a=iP({storageKey:"openbridge.sidebar"}),l=q(()=>i.connected?"Daemon connected":"Daemon offline");function o($){window.open($,"_blank","noopener")}async function c(){await s.logout()}function u(){var E;const $=(E=s.config.value)==null?void 0:E.issuer;$&&window.open(`${$}/profile`,"_blank","noopener")}const d=K([]),h=K(!0),f=q(()=>d.value.map($=>{var E;return{id:$.sub,email:$.email,name:$.name,current:$.sub===((E=s.user.value)==null?void 0:E.id)}}));async function v(){const $=await s.listIdentities();d.value=$,h.value=$.length===0}function p($){s.switchAccount($.email)}async function w($){await s.removeIdentity($.id),await v()}const _=K(null),y=K(!1);async function C(){try{const $=await fetch("/api/updates/check");if(!$.ok)return;const E=await $.json();E.updateAvailable&&E.latest&&(_.value=E.latest)}catch{}}const g=[{name:"dashboard",icon:"house",label:"Dashboard",href:"/dashboard"},{name:"plugins",icon:"puzzle-piece",label:"Plugins",href:"/plugins"},{name:"devices",icon:"devices",label:"Devices",href:"/devices"},{name:"config",icon:"brackets-curly",label:"Config",href:"/config"},{name:"terminal",icon:"terminal",label:"Terminal",href:"/terminal"}];return Ve(()=>t.name,()=>n.close()),nt(async()=>{await i.fetchHealth(),await i.fetchPlugins(),i.fetchLogs(),i.connectLiveLogs();const $=setInterval(()=>i.fetchHealth(),1e4);Ii(()=>clearInterval($)),C()}),Ii(()=>i.disconnectLiveLogs()),($,E)=>{const L=iT,B=wo("RouterLink"),T=bT,X=uT,W=yT,A=TS,x=hE,F=CT,ie=$v,re=Cs,ue=Pt,J=ks,ae=wo("RouterView"),ne=XH;return m(),he(ne,{"inspector-visible":de(n).visible,"main-padding":!de(r).fullBleed,"sidebar-variant":de(a).variant.value,"sidebar-header-action-position":"start","sidebar-header-action-compact":"swap"},Fm({"sidebar-logo":G(()=>[j(B,{to:"/dashboard",class:"sidebar-brand-link","aria-label":"OpenBridge, dashboard"},{default:G(()=>[j(L,{title:"OpenBridge"},{icon:G(()=>[...E[5]||(E[5]=[b("img",{src:Zg,width:"28",height:"28",alt:""},null,-1)])]),_:1})]),_:1})]),"sidebar-header-action":G(()=>[j(T,{onToggle:de(a).toggle},null,8,["onToggle"])]),"sidebar-nav":G(()=>[j(W,null,{default:G(()=>[(m(),M(Ce,null,Fe(g,Q=>j(X,{key:Q.name,icon:Q.icon,label:Q.label,to:Q.href,active:de(t).name===Q.name},null,8,["icon","label","to","active"])),64))]),_:1})]),"sidebar-bottom":G(()=>{var Q;return[j(W,null,{default:G(()=>[j(X,{icon:CO,label:"Documentation",href:mp,onClick:E[0]||(E[0]=qe(oe=>o(mp),["prevent"]))}),j(X,{icon:EO,label:"Sponsor",href:vp,onClick:E[1]||(E[1]=qe(oe=>o(vp),["prevent"]))}),j(X,{icon:Bg,label:"Settings",to:"/settings",active:de(t).name==="settings"},null,8,["active"])]),_:1}),(Q=de(s).config.value)!=null&&Q.enabled&&de(s).user.value?(m(),he(x,{key:0,user:{email:de(s).user.value.email,name:de(s).user.value.name,picture:de(s).user.value.picture},trigger:"identity","show-theme":"",accounts:f.value,"accounts-unknown":h.value,"show-account-actions":de(s).isNubiscoPlatform.value,"show-profile":de(s).isNubiscoPlatform.value,brand:de(s).isNubiscoPlatform.value?"footer":void 0,onOpen:v,onSwitch:p,onSwitchAccount:E[2]||(E[2]=oe=>de(s).chooseAccount()),onAddAccount:E[3]||(E[3]=oe=>de(s).addAccount()),onRemove:w,onProfile:u,onSignOut:c},{default:G(({close:oe})=>[j(A,{icon:WL,label:"Sign out of all apps",danger:"",onSelect:ve=>(oe(),de(s).logoutEverywhere())},null,8,["onSelect"])]),_:1},8,["user","accounts","accounts-unknown","show-account-actions","show-profile","brand"])):V("",!0),j(F,{label:l.value,status:de(i).connected?"success":"danger"},null,8,["label","status"])]}),"topbar-left":G(()=>[j(ie,{subtitle:de(r).title},null,8,["subtitle"]),de(r).count!==null?(m(),he(re,{key:0},{default:G(()=>[le(Z(de(r).count),1)]),_:1})):V("",!0),E[6]||(E[6]=b("div",{id:"ob-topbar-left",class:"topbar-slot"},null,-1))]),"topbar-right":G(()=>[E[7]||(E[7]=b("div",{id:"ob-topbar-right",class:"topbar-slot"},null,-1))]),inspector:G(()=>[de(n).mode==="plugin"?(m(),he(KV,{key:0})):de(n).mode==="marketplace"?(m(),he(WD,{key:1})):de(n).mode==="device"?(m(),he(bB,{key:2})):V("",!0)]),bottom:G(()=>[j(MB)]),default:G(()=>[j(ae)]),_:2},[_.value&&!y.value?{name:"notification",fn:G(()=>[j(J,{status:"info",icon:$2,flush:"",dismissible:"",title:`OpenBridge v${_.value} is available`,onDismiss:E[4]||(E[4]=Q=>y.value=!0)},{action:G(()=>[j(ue,{variant:"ghost",size:"sm",href:"https://github.com/nubisco/openbridge/releases",target:"_blank",rel:"noopener"},{default:G(()=>[...E[8]||(E[8]=[le(" See what's new ",-1)])]),_:1})]),_:1},8,["title"])]),key:"0"}:void 0]),1032,["inspector-visible","main-padding","sidebar-variant"])}}}),LB=zt($B,[["__scopeId","data-v-082839de"]]),EB=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},xB=EB("qr-code","0 0 256 256",'<path d="M104,40H56A16,16,0,0,0,40,56v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V56A16,16,0,0,0,104,40Zm0,64H56V56h48v48Zm0,32H56a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V152A16,16,0,0,0,104,136Zm0,64H56V152h48v48ZM200,40H152a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm0,64H152V56h48v48Zm-64,72V144a8,8,0,0,1,16,0v32a8,8,0,0,1-16,0Zm80-16a8,8,0,0,1-8,8H184v40a8,8,0,0,1-8,8H144a8,8,0,0,1,0-16h24V144a8,8,0,0,1,16,0v8h24A8,8,0,0,1,216,160Zm0,32v16a8,8,0,0,1-16,0V192a8,8,0,0,1,16,0Z"/>'),HB=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},TB=HB("cpu","0 0 256 256",'<path d="M152,96H104a8,8,0,0,0-8,8v48a8,8,0,0,0,8,8h48a8,8,0,0,0,8-8V104A8,8,0,0,0,152,96Zm-8,48H112V112h32Zm88,0H216V112h16a8,8,0,0,0,0-16H216V56a16,16,0,0,0-16-16H160V24a8,8,0,0,0-16,0V40H112V24a8,8,0,0,0-16,0V40H56A16,16,0,0,0,40,56V96H24a8,8,0,0,0,0,16H40v32H24a8,8,0,0,0,0,16H40v40a16,16,0,0,0,16,16H96v16a8,8,0,0,0,16,0V216h32v16a8,8,0,0,0,16,0V216h40a16,16,0,0,0,16-16V160h16a8,8,0,0,0,0-16Zm-32,56H56V56H200v95.87s0,.09,0,.13,0,.09,0,.13V200Z"/>'),NB=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},PB=NB("database","0 0 256 256",'<path d="M128,24C74.17,24,32,48.6,32,80v96c0,31.4,42.17,56,96,56s96-24.6,96-56V80C224,48.6,181.83,24,128,24Zm80,104c0,9.62-7.88,19.43-21.61,26.92C170.93,163.35,150.19,168,128,168s-42.93-4.65-58.39-13.08C55.88,147.43,48,137.62,48,128V111.36c17.06,15,46.23,24.64,80,24.64s62.94-9.68,80-24.64ZM69.61,53.08C85.07,44.65,105.81,40,128,40s42.93,4.65,58.39,13.08C200.12,60.57,208,70.38,208,80s-7.88,19.43-21.61,26.92C170.93,115.35,150.19,120,128,120s-42.93-4.65-58.39-13.08C55.88,99.43,48,89.62,48,80S55.88,60.57,69.61,53.08ZM186.39,202.92C170.93,211.35,150.19,216,128,216s-42.93-4.65-58.39-13.08C55.88,195.43,48,185.62,48,176V159.36c17.06,15,46.23,24.64,80,24.64s62.94-9.68,80-24.64V176C208,185.62,200.12,195.43,186.39,202.92Z"/>'),OB=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},IB=OB("clock","0 0 256 256",'<path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm64-88a8,8,0,0,1-8,8H128a8,8,0,0,1-8-8V72a8,8,0,0,1,16,0v48h48A8,8,0,0,1,192,128Z"/>'),ja=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},RB=ja("pulse","0 0 256 256",'<path d="M236,128a4,4,0,0,1-4,4H202.47l-38.89,77.79A4,4,0,0,1,160,212h-.2a4,4,0,0,1-3.54-2.58l-60.59-159-36,79.28A4,4,0,0,1,56,132H24a4,4,0,0,1,0-8H53.42L92.36,38.35a4,4,0,0,1,7.38.23L160.5,198.06l35.92-71.85A4,4,0,0,1,200,124h32A4,4,0,0,1,236,128Z"/>'),VB=ja("pulse","0 0 256 256",'<path d="M238,128a6,6,0,0,1-6,6H203.71l-38.34,76.68A6,6,0,0,1,160,214h-.3a6,6,0,0,1-5.31-3.85L95.51,55.57,61.46,130.48A6,6,0,0,1,56,134H24a6,6,0,0,1,0-12H52.14l38.4-84.48a6,6,0,0,1,11.07.34L160.74,193.1l33.89-67.78A6,6,0,0,1,200,122h32A6,6,0,0,1,238,128Z"/>'),Pd=ja("pulse","0 0 256 256",'<path d="M240,128a8,8,0,0,1-8,8H204.94l-37.78,75.58A8,8,0,0,1,160,216h-.4a8,8,0,0,1-7.08-5.14L95.35,60.76,63.28,131.31A8,8,0,0,1,56,136H24a8,8,0,0,1,0-16H50.85L88.72,36.69a8,8,0,0,1,14.76.46l57.51,151,31.85-63.71A8,8,0,0,1,200,120h32A8,8,0,0,1,240,128Z"/>'),DB=ja("pulse","0 0 256 256",'<path d="M244,128a12,12,0,0,1-12,12H207.42l-36.69,73.37A12,12,0,0,1,160,220h-.6a12,12,0,0,1-10.61-7.72L95,71.15,66.92,133A12,12,0,0,1,56,140H24a12,12,0,0,1,0-24H48.27L85.08,35a12,12,0,0,1,22.13.7l54.28,142.46,27.78-55.56A12,12,0,0,1,200,116h32A12,12,0,0,1,244,128Z"/>'),ZB=ja("pulse","0 0 256 256",'<path d="M216,40H40A16,16,0,0,0,24,56V200a16,16,0,0,0,16,16H216a16,16,0,0,0,16-16V56A16,16,0,0,0,216,40Zm-8,96H188.64L159,188a8,8,0,0,1-6.95,4h-.46a8,8,0,0,1-6.89-4.84L103,89.92,79,132a8,8,0,0,1-7,4H48a8,8,0,0,1,0-16H67.36L97.05,68a8,8,0,0,1,14.3.82L153,166.08l24-42.05a8,8,0,0,1,6.95-4h24a8,8,0,0,1,0,16Z"/>'),BB=ja("pulse","0 0 256 256",'<path d="M96,40l33.52,88H56Zm104,88H129.52L160,208Z" opacity="0.2"/><path d="M240,128a8,8,0,0,1-8,8H204.94l-37.78,75.58A8,8,0,0,1,160,216h-.4a8,8,0,0,1-7.08-5.14L95.35,60.76,63.28,131.31A8,8,0,0,1,56,136H24a8,8,0,0,1,0-16H50.85L88.72,36.69a8,8,0,0,1,14.76.46l57.51,151,31.85-63.71A8,8,0,0,1,200,120h32A8,8,0,0,1,240,128Z"/>'),FB="pulse",zB=Object.freeze(Object.defineProperty({__proto__:null,bold:DB,default:Pd,duotone:BB,fill:ZB,glyphName:FB,light:VB,regular:Pd,thin:RB},Symbol.toStringTag,{value:"Module"})),UB={class:"dashboard"},WB={class:"top-row"},jB={class:"hk-body"},KB={key:0,class:"qr-wrap"},qB=["src"],GB={key:1,class:"qr-placeholder"},YB={class:"hk-details"},XB={key:0,class:"pin-display"},JB={key:1,class:"pin-label"},QB={class:"hk-status"},eF={key:2,class:"hk-error"},tF={key:0,class:"sys-grid"},iF={class:"sys-val"},nF={class:"sys-val"},rF={class:"sys-val"},sF={class:"sys-val"},aF={class:"sys-val"},lF={class:"sys-val"},oF={class:"sys-val"},cF={class:"sys-val mono"},uF={class:"sys-val mono"},dF={class:"sys-val mono"},hF={key:1,class:"loading-inline"},fF={class:"card-title"},pF={class:"plugins-counts"},_F={key:0,class:"pill red"},mF={key:0,class:"empty-inline"},vF={key:1,class:"plugins-list"},gF={class:"plugin-name"},bF={class:"plugin-ver"},yF={class:"metrics-row"},wF={class:"metric-header"},SF={class:"metric-icon purple"},CF={class:"metric-values"},kF={class:"metric-big"},AF={key:0,class:"metric-sub"},MF={class:"metric-chart"},$F={class:"metric-header"},LF={class:"metric-icon blue"},EF={class:"metric-values"},xF={class:"metric-big"},HF={class:"metric-sub"},TF={class:"metric-chart"},NF={class:"metric-header"},PF={class:"metric-icon green"},OF={class:"uptime-rows"},IF={class:"uptime-row"},RF={class:"uptime-val"},VF={class:"uptime-row"},DF={class:"uptime-val"},ZF={style:{"margin-top":"0.75rem"}},BF={class:"metric-header"},FF={class:"metric-icon amber"},zF={class:"net-values"},UF={class:"net-val"},WF={class:"net-val"},jF={class:"metric-chart net-charts"},KF=Ne({__name:"DashboardView",setup(e){const t=Kr(),i=Ms();function n(A){return A==="running"?"green":A==="error"?"red":A==="loading"?"blue":"grey"}const r=K(!1),s=K(!1);async function a(){if(!r.value){r.value=!0,s.value=!1;try{await Re.daemon.restart(),s.value=!0;let A=0;const x=setInterval(async()=>{A++;try{await Re.health(),clearInterval(x),location.reload()}catch{}A>60&&(clearInterval(x),r.value=!1)},1e3)}catch{r.value=!1}}}const l=K(null),o=K(""),c=K(""),u=K(""),d=q(()=>t.connected?u.value?"red":"green":"gray"),h=q(()=>t.connected?u.value?"HomeKit offline":"Bridge running":"Daemon offline"),f=K([]),v=K([]),p=K([]),w=K([]),_=zn(null);let y=null;function C(){y&&(y.onclose=null,y.close(),y=null);const A=location.protocol==="https:"?"wss:":"ws:";y=new WebSocket(`${A}//${location.host}/ws/metrics`),y.onmessage=x=>{if(!document.hidden)try{const F=JSON.parse(x.data);if(F.type==="history"){const ie=F.data;f.value=ie.map(re=>re.cpu),v.value=ie.map(re=>E(re)),p.value=ie.map(re=>re.netRxSec),w.value=ie.map(re=>re.netTxSec),ie.length&&(_.value=ie[ie.length-1])}else if(F.type==="snapshot"){const ie=F.data;_.value=ie,$(f,ie.cpu),$(v,E(ie)),$(p,ie.netRxSec),$(w,ie.netTxSec)}}catch{}},y.onclose=()=>{y=null,setTimeout(C,3e3)}}function g(){document.hidden||C()}function $(A,x){A.value=[...A.value.slice(-59),x]}function E(A){return A.memTotal?Math.round((A.memTotal-A.memFree)/A.memTotal*100):0}function L(A){return A<1024?`${A} B`:A<1024**2?`${(A/1024).toFixed(1)} KB`:A<1024**3?`${(A/1024**2).toFixed(1)} MB`:`${(A/1024**3).toFixed(1)} GB`}function B(A){const x=Math.floor(A/86400),F=Math.floor(A%86400/3600),ie=Math.floor(A%3600/60);return x>0?`${x}d ${F}h`:F>0?`${F}h ${ie}m`:`${ie}m`}const T=q(()=>_.value?L(_.value.memTotal-_.value.memFree):"—"),X=q(()=>_.value?L(_.value.memTotal):"—"),W=q(()=>_.value?E(_.value):0);return nt(async()=>{i.setPage("Dashboard"),t.fetchPlugins();try{l.value=await Re.system()}catch{}try{const A=await Re.qr();u.value=A.error??"",A.setupURI&&(c.value=A.pincode??"",o.value=await Wa.toDataURL(A.setupURI,{width:148,margin:1,color:{dark:"#000000",light:"#ffffff"}}))}catch{}C(),document.addEventListener("visibilitychange",g)}),Ii(()=>{y==null||y.close(),y=null,document.removeEventListener("visibilitychange",g)}),(A,x)=>{const F=Ue,ie=Ss,re=Cs,ue=hN,J=fg,ae=Pt;return m(),M("div",UB,[b("div",WB,[j(ie,{class:"hk-card"},{default:G(()=>[x[0]||(x[0]=b("div",{class:"card-title"},"HomeKit Pairing",-1)),b("div",jB,[o.value?(m(),M("div",KB,[b("img",{src:o.value,alt:"HomeKit QR Code",class:"qr-img"},null,8,qB)])):(m(),M("div",GB,[j(F,{name:de(xB),size:48},null,8,["name"]),b("span",null,Z(u.value?"HomeKit bridge unavailable":"No HAP bridge configured"),1)])),b("div",YB,[c.value?(m(),M("div",XB,Z(c.value),1)):V("",!0),c.value?(m(),M("div",JB,"Scan to add to HomeKit")):V("",!0),b("div",QB,[b("span",{class:Le(["dot",d.value])},null,2),le(" "+Z(h.value),1)]),u.value?(m(),M("div",eF,Z(u.value),1)):V("",!0)])])]),_:1}),j(ie,{class:"sys-card"},{default:G(()=>{var ne;return[x[12]||(x[12]=b("div",{class:"card-title"},"System Information",-1)),l.value?(m(),M("div",tF,[x[1]||(x[1]=b("span",{class:"sys-key"},"OS",-1)),b("span",iF,Z(l.value.os),1),x[2]||(x[2]=b("span",{class:"sys-key"},"Arch",-1)),b("span",nF,Z(l.value.arch),1),x[3]||(x[3]=b("span",{class:"sys-key"},"Hostname",-1)),b("span",rF,Z(l.value.hostname),1),x[4]||(x[4]=b("span",{class:"sys-key"},"IP Address",-1)),b("span",sF,Z(l.value.ip),1),x[5]||(x[5]=b("span",{class:"sys-key"},"User",-1)),b("span",aF,Z(l.value.user),1),x[6]||(x[6]=b("span",{class:"sys-key"},"Node.js",-1)),b("span",lF,Z(l.value.nodeVersion),1),x[7]||(x[7]=b("span",{class:"sys-key"},"OpenBridge",-1)),b("span",oF,"v"+Z(((ne=de(t).health)==null?void 0:ne.version)??"—"),1),x[8]||(x[8]=b("span",{class:"sys-key"},"Config",-1)),b("span",cF,Z(l.value.configPath),1),x[9]||(x[9]=b("span",{class:"sys-key"},"OB plugins",-1)),b("span",uF,Z(l.value.obPluginsDir),1),x[10]||(x[10]=b("span",{class:"sys-key"},"HB plugins",-1)),b("span",dF,Z(l.value.hbPluginsDir),1)])):(m(),M("div",hF,[j(F,{name:de(ra),size:16},null,8,["name"]),x[11]||(x[11]=le(" Loading... ",-1))]))]}),_:1}),j(ie,{class:"plugins-card"},{default:G(()=>[b("div",fF,[x[13]||(x[13]=le(" Plugins ",-1)),b("span",pF,[j(re,{variant:"green"},{default:G(()=>[le(Z(de(t).runningCount)+" running",1)]),_:1}),de(t).errorCount?(m(),M("span",_F,Z(de(t).errorCount)+" error",1)):V("",!0)])]),de(t).plugins.length===0?(m(),M("div",mF,"No plugins loaded yet.")):(m(),M("div",vF,[(m(!0),M(Ce,null,Fe(de(t).plugins,ne=>(m(),M("div",{key:ne.id,class:"plugin-row"},[b("div",{class:Le(["plugin-dot",ne.status])},null,2),b("span",gF,Z(ne.manifest.name),1),b("span",bF,"v"+Z(ne.manifest.version),1),ne.source==="homebridge"?(m(),he(re,{key:0,variant:"orange",size:"sm"},{default:G(()=>[...x[14]||(x[14]=[le("HB",-1)])]),_:1})):V("",!0),j(re,{variant:n(ne.status),size:"sm"},{default:G(()=>[le(Z(ne.status),1)]),_:2},1032,["variant"])]))),128))]))]),_:1})]),b("div",yF,[j(ie,{class:"metric-card"},{default:G(()=>{var ne,Q;return[b("div",wF,[b("div",SF,[j(F,{name:de(TB),size:13},null,8,["name"])]),x[15]||(x[15]=b("span",{class:"metric-title"},"CPU",-1))]),b("div",CF,[b("div",kF,[le(Z(((ne=_.value)==null?void 0:ne.cpu)??"—")+" ",1),x[16]||(x[16]=b("span",{class:"metric-unit"},"%",-1))]),(Q=_.value)!=null&&Q.cpuTemp&&_.value.cpuTemp>0?(m(),M("div",AF,Z(_.value.cpuTemp)+"°C",1)):V("",!0)]),b("div",MF,[j(ue,{data:f.value,color:"var(--nb-c-primary)",height:40},null,8,["data"])])]}),_:1}),j(ie,{class:"metric-card"},{default:G(()=>[b("div",$F,[b("div",LF,[j(F,{name:de(PB),size:13},null,8,["name"])]),x[17]||(x[17]=b("span",{class:"metric-title"},"Memory",-1))]),b("div",EF,[b("div",xF,[le(Z(W.value)+" ",1),x[18]||(x[18]=b("span",{class:"metric-unit"},"%",-1))]),b("div",HF,Z(T.value)+" / "+Z(X.value),1)]),j(J,{value:W.value,max:100,size:"sm"},null,8,["value"]),b("div",TF,[j(ue,{data:v.value,color:"var(--nb-c-info)",height:32},null,8,["data"])])]),_:1}),j(ie,{class:"metric-card"},{default:G(()=>[b("div",NF,[b("div",PF,[j(F,{name:de(IB),size:13},null,8,["name"])]),x[19]||(x[19]=b("span",{class:"metric-title"},"Uptime",-1))]),b("div",OF,[b("div",IF,[b("span",RF,Z(l.value?B(l.value.uptimeSystem):"—"),1),x[20]||(x[20]=b("span",{class:"uptime-label"},"System",-1))]),x[22]||(x[22]=b("div",{class:"uptime-divider"},null,-1)),b("div",VF,[b("span",DF,Z(l.value?B(l.value.uptimeProcess):"—"),1),x[21]||(x[21]=b("span",{class:"uptime-label"},"Process",-1))])]),b("div",ZF,[j(ae,{variant:"secondary",size:"sm",outlined:"",style:{width:"100%","justify-content":"center"},loading:r.value,icon:s.value?dr:r.value?Vo:_s,onClick:a},{default:G(()=>[le(Z(s.value?"Restarted":r.value?"Restarting…":"Restart OpenBridge"),1)]),_:1},8,["loading","icon"])])]),_:1}),j(ie,{class:"metric-card net-card"},{default:G(()=>[b("div",BF,[b("div",FF,[j(F,{name:de(Pd),size:13},null,8,["name"])]),x[23]||(x[23]=b("span",{class:"metric-title"},"Network",-1))]),b("div",zF,[b("div",null,[b("div",UF,Z(_.value?L(_.value.netRxSec)+"/s":"—"),1),x[24]||(x[24]=b("div",{class:"net-label"},"↓ Received",-1))]),b("div",null,[b("div",WF,Z(_.value?L(_.value.netTxSec)+"/s":"—"),1),x[25]||(x[25]=b("div",{class:"net-label"},"↑ Sent",-1))])]),b("div",jF,[j(ue,{data:p.value,color:"var(--nb-c-success)",height:28},null,8,["data"]),j(ue,{data:w.value,color:"var(--nb-c-warning)",height:28},null,8,["data"])])]),_:1})])])}}}),qF=zt(KF,[["__scopeId","data-v-d9b075b5"]]),Ka=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},GF=Ka("arrow-clockwise","0 0 256 256",'<path d="M236,56v48a4,4,0,0,1-4,4H184a4,4,0,0,1,0-8h37.7L187.53,68.69l-.13-.12a84,84,0,1,0-1.75,120.51,4,4,0,0,1,5.5,5.82A91.43,91.43,0,0,1,128,220h-1.26A92,92,0,1,1,193,62.84l35,32.05V56a4,4,0,1,1,8,0Z"/>'),YF=Ka("arrow-clockwise","0 0 256 256",'<path d="M238,56v48a6,6,0,0,1-6,6H184a6,6,0,0,1,0-12h32.55l-30.38-27.8c-.06-.06-.12-.13-.19-.19a82,82,0,1,0-1.7,117.65,6,6,0,0,1,8.24,8.73A93.46,93.46,0,0,1,128,222h-1.28A94,94,0,1,1,194.37,61.4L226,90.35V56a6,6,0,1,1,12,0Z"/>'),gp=Ka("arrow-clockwise","0 0 256 256",'<path d="M240,56v48a8,8,0,0,1-8,8H184a8,8,0,0,1,0-16H211.4L184.81,71.64l-.25-.24a80,80,0,1,0-1.67,114.78,8,8,0,0,1,11,11.63A95.44,95.44,0,0,1,128,224h-1.32A96,96,0,1,1,195.75,60L224,85.8V56a8,8,0,1,1,16,0Z"/>'),XF=Ka("arrow-clockwise","0 0 256 256",'<path d="M244,56v48a12,12,0,0,1-12,12H184a12,12,0,1,1,0-24H201.1l-19-17.38c-.13-.12-.26-.24-.38-.37A76,76,0,1,0,127,204h1a75.53,75.53,0,0,0,52.15-20.72,12,12,0,0,1,16.49,17.45A99.45,99.45,0,0,1,128,228h-1.37A100,100,0,1,1,198.51,57.06L220,76.72V56a12,12,0,0,1,24,0Z"/>'),JF=Ka("arrow-clockwise","0 0 256 256",'<path d="M240,56v48a8,8,0,0,1-8,8H184a8,8,0,0,1-5.66-13.66l17-17-10.55-9.65-.25-.24a80,80,0,1,0-1.67,114.78,8,8,0,1,1,11,11.63A95.44,95.44,0,0,1,128,224h-1.32A96,96,0,1,1,195.75,60l10.93,10L226.34,50.3A8,8,0,0,1,240,56Z"/>'),QF=Ka("arrow-clockwise","0 0 256 256",'<path d="M216,128a88,88,0,1,1-88-88A88,88,0,0,1,216,128Z" opacity="0.2"/><path d="M240,56v48a8,8,0,0,1-8,8H184a8,8,0,0,1,0-16H211.4L184.81,71.64l-.25-.24a80,80,0,1,0-1.67,114.78,8,8,0,0,1,11,11.63A95.44,95.44,0,0,1,128,224h-1.32A96,96,0,1,1,195.75,60L224,85.8V56a8,8,0,1,1,16,0Z"/>'),ez="arrow-clockwise",tz=Object.freeze(Object.defineProperty({__proto__:null,bold:XF,default:gp,duotone:QF,fill:JF,glyphName:ez,light:YF,regular:gp,thin:GF},Symbol.toStringTag,{value:"Module"})),db=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),qa=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},iz=qa("list","0 0 256 256",'<path d="M220,128a4,4,0,0,1-4,4H40a4,4,0,0,1,0-8H216A4,4,0,0,1,220,128ZM40,68H216a4,4,0,0,0,0-8H40a4,4,0,0,0,0,8ZM216,188H40a4,4,0,0,0,0,8H216a4,4,0,0,0,0-8Z"/>'),nz=qa("list","0 0 256 256",'<path d="M222,128a6,6,0,0,1-6,6H40a6,6,0,0,1,0-12H216A6,6,0,0,1,222,128ZM40,70H216a6,6,0,0,0,0-12H40a6,6,0,0,0,0,12ZM216,186H40a6,6,0,0,0,0,12H216a6,6,0,0,0,0-12Z"/>'),bp=qa("list","0 0 256 256",'<path d="M224,128a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16H216A8,8,0,0,1,224,128ZM40,72H216a8,8,0,0,0,0-16H40a8,8,0,0,0,0,16ZM216,184H40a8,8,0,0,0,0,16H216a8,8,0,0,0,0-16Z"/>'),rz=qa("list","0 0 256 256",'<path d="M228,128a12,12,0,0,1-12,12H40a12,12,0,0,1,0-24H216A12,12,0,0,1,228,128ZM40,76H216a12,12,0,0,0,0-24H40a12,12,0,0,0,0,24ZM216,180H40a12,12,0,0,0,0,24H216a12,12,0,0,0,0-24Z"/>'),sz=qa("list","0 0 256 256",'<path d="M208,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM192,184H64a8,8,0,0,1,0-16H192a8,8,0,0,1,0,16Zm0-48H64a8,8,0,0,1,0-16H192a8,8,0,0,1,0,16Zm0-48H64a8,8,0,0,1,0-16H192a8,8,0,0,1,0,16Z"/>'),az=qa("list","0 0 256 256",'<path d="M216,64V192H40V64Z" opacity="0.2"/><path d="M224,128a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16H216A8,8,0,0,1,224,128ZM40,72H216a8,8,0,0,0,0-16H40a8,8,0,0,0,0,16ZM216,184H40a8,8,0,0,0,0,16H216a8,8,0,0,0,0-16Z"/>'),lz="list",hb=Object.freeze(Object.defineProperty({__proto__:null,bold:rz,default:bp,duotone:az,fill:sz,glyphName:lz,light:nz,regular:bp,thin:iz},Symbol.toStringTag,{value:"Module"})),Ga=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},oz=Ga("squares-four","0 0 256 256",'<path d="M104,44H56A12,12,0,0,0,44,56v48a12,12,0,0,0,12,12h48a12,12,0,0,0,12-12V56A12,12,0,0,0,104,44Zm4,60a4,4,0,0,1-4,4H56a4,4,0,0,1-4-4V56a4,4,0,0,1,4-4h48a4,4,0,0,1,4,4Zm92-60H152a12,12,0,0,0-12,12v48a12,12,0,0,0,12,12h48a12,12,0,0,0,12-12V56A12,12,0,0,0,200,44Zm4,60a4,4,0,0,1-4,4H152a4,4,0,0,1-4-4V56a4,4,0,0,1,4-4h48a4,4,0,0,1,4,4ZM104,140H56a12,12,0,0,0-12,12v48a12,12,0,0,0,12,12h48a12,12,0,0,0,12-12V152A12,12,0,0,0,104,140Zm4,60a4,4,0,0,1-4,4H56a4,4,0,0,1-4-4V152a4,4,0,0,1,4-4h48a4,4,0,0,1,4,4Zm92-60H152a12,12,0,0,0-12,12v48a12,12,0,0,0,12,12h48a12,12,0,0,0,12-12V152A12,12,0,0,0,200,140Zm4,60a4,4,0,0,1-4,4H152a4,4,0,0,1-4-4V152a4,4,0,0,1,4-4h48a4,4,0,0,1,4,4Z"/>'),cz=Ga("squares-four","0 0 256 256",'<path d="M104,42H56A14,14,0,0,0,42,56v48a14,14,0,0,0,14,14h48a14,14,0,0,0,14-14V56A14,14,0,0,0,104,42Zm2,62a2,2,0,0,1-2,2H56a2,2,0,0,1-2-2V56a2,2,0,0,1,2-2h48a2,2,0,0,1,2,2Zm94-62H152a14,14,0,0,0-14,14v48a14,14,0,0,0,14,14h48a14,14,0,0,0,14-14V56A14,14,0,0,0,200,42Zm2,62a2,2,0,0,1-2,2H152a2,2,0,0,1-2-2V56a2,2,0,0,1,2-2h48a2,2,0,0,1,2,2Zm-98,34H56a14,14,0,0,0-14,14v48a14,14,0,0,0,14,14h48a14,14,0,0,0,14-14V152A14,14,0,0,0,104,138Zm2,62a2,2,0,0,1-2,2H56a2,2,0,0,1-2-2V152a2,2,0,0,1,2-2h48a2,2,0,0,1,2,2Zm94-62H152a14,14,0,0,0-14,14v48a14,14,0,0,0,14,14h48a14,14,0,0,0,14-14V152A14,14,0,0,0,200,138Zm2,62a2,2,0,0,1-2,2H152a2,2,0,0,1-2-2V152a2,2,0,0,1,2-2h48a2,2,0,0,1,2,2Z"/>'),yp=Ga("squares-four","0 0 256 256",'<path d="M104,40H56A16,16,0,0,0,40,56v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V56A16,16,0,0,0,104,40Zm0,64H56V56h48v48Zm96-64H152a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm0,64H152V56h48v48Zm-96,32H56a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V152A16,16,0,0,0,104,136Zm0,64H56V152h48v48Zm96-64H152a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V152A16,16,0,0,0,200,136Zm0,64H152V152h48v48Z"/>'),uz=Ga("squares-four","0 0 256 256",'<path d="M100,36H56A20,20,0,0,0,36,56v44a20,20,0,0,0,20,20h44a20,20,0,0,0,20-20V56A20,20,0,0,0,100,36ZM96,96H60V60H96ZM200,36H156a20,20,0,0,0-20,20v44a20,20,0,0,0,20,20h44a20,20,0,0,0,20-20V56A20,20,0,0,0,200,36Zm-4,60H160V60h36Zm-96,40H56a20,20,0,0,0-20,20v44a20,20,0,0,0,20,20h44a20,20,0,0,0,20-20V156A20,20,0,0,0,100,136Zm-4,60H60V160H96Zm104-60H156a20,20,0,0,0-20,20v44a20,20,0,0,0,20,20h44a20,20,0,0,0,20-20V156A20,20,0,0,0,200,136Zm-4,60H160V160h36Z"/>'),dz=Ga("squares-four","0 0 256 256",'<path d="M120,56v48a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V56A16,16,0,0,1,56,40h48A16,16,0,0,1,120,56Zm80-16H152a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm-96,96H56a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V152A16,16,0,0,0,104,136Zm96,0H152a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V152A16,16,0,0,0,200,136Z"/>'),hz=Ga("squares-four","0 0 256 256",'<path d="M112,56v48a8,8,0,0,1-8,8H56a8,8,0,0,1-8-8V56a8,8,0,0,1,8-8h48A8,8,0,0,1,112,56Zm88-8H152a8,8,0,0,0-8,8v48a8,8,0,0,0,8,8h48a8,8,0,0,0,8-8V56A8,8,0,0,0,200,48Zm-96,96H56a8,8,0,0,0-8,8v48a8,8,0,0,0,8,8h48a8,8,0,0,0,8-8V152A8,8,0,0,0,104,144Zm96,0H152a8,8,0,0,0-8,8v48a8,8,0,0,0,8,8h48a8,8,0,0,0,8-8V152A8,8,0,0,0,200,144Z" opacity="0.2"/><path d="M200,136H152a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V152A16,16,0,0,0,200,136Zm0,64H152V152h48v48ZM104,40H56A16,16,0,0,0,40,56v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V56A16,16,0,0,0,104,40Zm0,64H56V56h48v48Zm96-64H152a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm0,64H152V56h48v48Zm-96,32H56a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V152A16,16,0,0,0,104,136Zm0,64H56V152h48v48Z"/>'),fz="squares-four",fb=Object.freeze(Object.defineProperty({__proto__:null,bold:uz,default:yp,duotone:hz,fill:dz,glyphName:fz,light:cz,regular:yp,thin:oz},Symbol.toStringTag,{value:"Module"})),pz={key:0,class:"plugin-cards"},_z={class:"plugin-avatar"},mz=["src","alt"],vz={class:"plugin-meta"},gz={class:"plugin-name"},bz={key:0,class:"plugin-platform"},yz={class:"plugin-version"},wz={key:0,class:"plugin-desc"},Sz={key:1,class:"plugin-author"},Cz={key:2,class:"plugin-links"},kz=["href"],Az=["href"],Mz={key:3,class:"plugin-error"},$z={class:"cell-name"},Lz={class:"plugin-avatar plugin-avatar--sm"},Ez=["src","alt"],xz={class:"plugin-name"},Hz={key:0,class:"plugin-platform"},Tz=Ne({__name:"PluginList",props:{rows:{},view:{},selectedId:{}},emits:["select"],setup(e,{emit:t}){const i=e,n=t;function r(o){return o==="running"?"green":o==="error"?"red":o==="loading"?"blue":"grey"}const s=K({key:"name",direction:"asc"}),a=[{key:"name",header:"Plugin",sortable:!0},{key:"version",header:"Version",sortable:!0,width:140},{key:"source",header:"Source",sortable:!0,width:120},{key:"status",header:"Status",sortable:!0,width:120},{key:"author",header:"Author",sortable:!0}],l=q(()=>{const o=i.rows.map(d=>({id:d.plugin.id,name:d.plugin.manifest.name,version:`v${d.plugin.manifest.version}`,availableUpdate:d.plugin.availableUpdate,source:d.plugin.source==="homebridge"?"Homebridge":"Native",status:d.plugin.status,author:d.plugin.manifest.author??"—",platform:d.plugin.source==="homebridge"?d.plugin.platformName:void 0,avatarUrl:d.avatarUrl,isOpenBridge:d.isOpenBridge,plugin:d.plugin})),c=s.value;if(!c||c.direction==="none")return o;const u=c.direction==="asc"?1:-1;return[...o].sort((d,h)=>u*String(d[c.key]??"").localeCompare(String(h[c.key]??"")))});return(o,c)=>{const u=Ue,d=Cs,h=yi,f=Ss,v=b2;return e.view==="cards"?(m(),M("div",pz,[(m(!0),M(Ce,null,Fe(e.rows,p=>(m(),he(f,{key:p.plugin.id,class:Le(["plugin-card",{"plugin-card--selected":p.plugin.id===e.selectedId}]),onClick:w=>n("select",p.plugin)},{default:G(()=>[b("span",{class:Le(["plugin-card__accent",`plugin-card__accent--${p.plugin.status}`])},null,2),j(h,{dir:"row",align:"start",gap:"sm",class:"plugin-card__header"},{default:G(()=>[b("div",_z,[p.avatarUrl?(m(),M("img",{key:0,src:p.avatarUrl,alt:p.plugin.manifest.name,onError:c[0]||(c[0]=w=>w.target.style.display="none")},null,40,mz)):(m(),he(u,{key:1,name:p.isOpenBridge?de(zs):de(bs),size:20},null,8,["name"]))]),b("div",vz,[b("div",gz,Z(p.plugin.manifest.name),1),p.plugin.source==="homebridge"&&p.plugin.platformName?(m(),M("div",bz," Platform: "+Z(p.plugin.platformName),1)):V("",!0),b("div",yz,[le(" v"+Z(p.plugin.manifest.version)+" ",1),p.plugin.availableUpdate?(m(),he(d,{key:0,variant:"blue",size:"sm"},{default:G(()=>[le(" v"+Z(p.plugin.availableUpdate)+" available ",1)]),_:2},1024)):V("",!0)])]),j(d,{variant:r(p.plugin.status)},{default:G(()=>[le(Z(p.plugin.status),1)]),_:2},1032,["variant"])]),_:2},1024),p.plugin.manifest.description?(m(),M("p",wz,Z(p.plugin.manifest.description),1)):V("",!0),p.plugin.manifest.author?(m(),M("p",Sz,"by "+Z(p.plugin.manifest.author),1)):V("",!0),p.sponsorUrl||p.docsUrl?(m(),M("div",Cz,[p.sponsorUrl?(m(),M("a",{key:0,href:p.sponsorUrl,target:"_blank",rel:"noopener",onClick:c[1]||(c[1]=qe(()=>{},["stop"]))},[j(u,{name:de(M2),weight:"fill",size:11},null,8,["name"]),c[6]||(c[6]=le(" Sponsor ",-1))],8,kz)):V("",!0),p.docsUrl?(m(),M("a",{key:1,href:p.docsUrl,target:"_blank",rel:"noopener",onClick:c[2]||(c[2]=qe(()=>{},["stop"]))},[j(u,{name:de(ub),size:11},null,8,["name"]),c[7]||(c[7]=le(" Docs ",-1))],8,Az)):V("",!0)])):V("",!0),p.plugin.error?(m(),M("div",Mz,Z(p.plugin.error),1)):V("",!0)]),_:2},1032,["class","onClick"]))),128))])):(m(),he(v,{key:1,columns:a,rows:l.value,"row-key":"id",size:"sm",zebra:"","sort-state":s.value,onSort:c[4]||(c[4]=p=>s.value=p),onRowClick:c[5]||(c[5]=p=>n("select",p.plugin))},{"cell-name":G(({row:p})=>[b("div",$z,[b("div",Lz,[p.avatarUrl?(m(),M("img",{key:0,src:p.avatarUrl,alt:p.name,onError:c[3]||(c[3]=w=>w.target.style.display="none")},null,40,Ez)):(m(),he(u,{key:1,name:p.isOpenBridge?de(zs):de(bs),size:14},null,8,["name"]))]),b("div",null,[b("div",xz,Z(p.name),1),p.platform?(m(),M("div",Hz,"Platform: "+Z(p.platform),1)):V("",!0)])])]),"cell-version":G(({row:p})=>[le(Z(p.version)+" ",1),p.availableUpdate?(m(),he(d,{key:0,variant:"blue",size:"sm"},{default:G(()=>[le("v"+Z(p.availableUpdate),1)]),_:2},1024)):V("",!0)]),"cell-status":G(({row:p})=>[j(d,{variant:r(p.status)},{default:G(()=>[le(Z(p.status),1)]),_:2},1032,["variant"])]),_:1},8,["rows","sort-state"]))}}}),Nz=zt(Tz,[["__scopeId","data-v-8fdf7ec9"]]),Pz={class:"plugins-view"},Oz={key:0,class:"empty-state"},Iz={key:0},wp="openbridge.plugins.view",Rz=Ne({__name:"PluginsView",setup(e){const t=Kr(),i=Qo(),n=Ms(),r=N2(),s=K(""),a=K(new Map),l=K(new Set),o=K(!1),c=K(localStorage.getItem(wp)==="table"?"table":"cards");function u(){c.value=c.value==="cards"?"table":"cards",localStorage.setItem(wp,c.value)}const d=q(()=>{var T;return i.visible&&i.mode==="plugin"?((T=i.selectedPlugin)==null?void 0:T.id)??null:null}),h=q(()=>p().map(T=>{const X=y(T);return{plugin:T,avatarUrl:E(T),isOpenBridge:_(T),sponsorUrl:X==null?void 0:X.githubSponsorsUrl,docsUrl:X==null?void 0:X.documentationUrl}}));function f(T){if(T.source==="homebridge"){const W=(T.manifest.description??"").match(/Homebridge platform:\s*([^\s]+)/);if(W!=null&&W[1])return W[1]}return T.manifest.name}function v(T){var x;const W=(x=(T.manifest.description??"").match(/Homebridge platform:\s*([^\s]+)/))==null?void 0:x[1],A=[f(T),W,T.manifest.name,T.id];return Array.from(new Set(A.filter(F=>!!F&&F.trim().length>0)))}function p(){const T=s.value.toLowerCase();return t.plugins.filter(X=>X.manifest.name.toLowerCase().includes(T)||(X.manifest.description??"").toLowerCase().includes(T))}function w(T){var X;((X=i.selectedPlugin)==null?void 0:X.id)===T.id&&i.visible&&i.mode==="plugin"?i.close():i.openPlugin(T)}function _(T){return T.manifest.name.includes("openbridge-")||T.source==="native"}function y(T){const X=v(T);for(const W of X){const A=a.value.get(W);if(A)return A}if(T.enrichedMetadata)return T.enrichedMetadata}async function C(T,X=!1){var A;const W=v(T);for(const x of W)if(!(!X&&a.value.has(x))&&!(!X&&l.value.has(x))){l.value.add(x);try{const F=await Re.marketplace.enriched(x),ie=new Map(a.value);if(ie.set(x,F),ie.set(f(T),F),a.value=ie,T.enrichedMetadata=F,F.documentationUrl||F.githubSponsorsUrl||(A=F.links)!=null&&A.repository)return}catch{}finally{const F=new Set(l.value);F.delete(x),l.value=F}}}const g=K(new Map);function $(T){const W=T.trim().replace(/^github:/,"https://github.com/").replace(/^git\+/,"").replace(/^git@github\.com:/,"https://github.com/").match(/github\.com[/:]([^/]+)/);return W?`https://github.com/${W[1]}.png?size=48`:null}function E(T){var x,F;const X=y(T),W=((x=X==null?void 0:X.links)==null?void 0:x.repository)??((F=X==null?void 0:X.links)==null?void 0:F.homepage)??"";if(W){const ie=$(W);if(ie)return ie}const A=v(T);for(const ie of A){const re=g.value.get(ie);if(re)return re}return null}async function L(T,X=!1){var W;if(!(!X&&g.value.has(T)))try{const A=await fetch(`https://registry.npmjs.org/${encodeURIComponent(T)}/latest`,{signal:AbortSignal.timeout(5e3)});if(!A.ok){g.value.set(T,"");return}const x=await A.json(),F=((W=x==null?void 0:x.repository)==null?void 0:W.url)??(x==null?void 0:x.homepage)??"";g.value.set(T,$(F)??"")}catch{g.value.set(T,"")}}async function B(T=!1){if(!o.value){o.value=!0;try{T&&(a.value=new Map,g.value=new Map);const X=t.plugins;for(const W of X){const A=v(W);for(const x of A)await L(x,T);await C(W,T)}T&&r.success("Plugin metadata refreshed")}catch{r.error("Failed to refresh plugin metadata")}finally{o.value=!1}}}return nt(async()=>{await t.fetchPlugins()}),Ve(()=>t.plugins.length,T=>{n.setPage("Plugins",T)},{immediate:!0}),(T,X)=>{const W=Wr,A=Pt,x=Ue;return m(),M("div",Pz,[(m(),he(an,{defer:"",to:"#ob-topbar-right"},[j(W,{modelValue:s.value,"onUpdate:modelValue":X[0]||(X[0]=F=>s.value=F),placeholder:"Search plugins...",size:"sm",style:{width:"200px"}},null,8,["modelValue"]),j(A,{variant:"ghost",size:"sm",icon:tz,title:"Refresh metadata",loading:o.value,disabled:o.value,onClick:X[1]||(X[1]=F=>B(!0))},null,8,["loading","disabled"]),j(A,{variant:"ghost",size:"sm",icon:c.value===db?hb:fb,title:c.value==="cards"?"Show as table":"Show as cards",onClick:u},null,8,["icon","title"]),j(A,{variant:"primary",size:"sm",icon:od,onClick:X[2]||(X[2]=F=>de(i).openMarketplace())},{default:G(()=>[...X[5]||(X[5]=[le(" Browse plugins ",-1)])]),_:1})])),h.value.length===0?(m(),M("div",Oz,[j(x,{name:de(bs),size:40},null,8,["name"]),s.value?(m(),M("p",Iz,'No plugins matching "'+Z(s.value)+'"',1)):(m(),M(Ce,{key:1},[X[7]||(X[7]=b("p",null,"No plugins loaded yet.",-1)),j(A,{variant:"primary",size:"sm",icon:od,onClick:X[3]||(X[3]=F=>de(i).openMarketplace())},{default:G(()=>[...X[6]||(X[6]=[le(" Browse & install plugins ",-1)])]),_:1})],64))])):(m(),M("div",{key:1,class:"plugins-body",onClick:X[4]||(X[4]=qe(F=>de(i).close(),["self"]))},[j(Nz,{rows:h.value,view:c.value,"selected-id":d.value,onSelect:w},null,8,["rows","view","selected-id"])]))])}}}),Vz=zt(Rz,[["__scopeId","data-v-95e3ebc4"]]),Ya=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},Dz=Ya("devices","0 0 256 256",'<path d="M224,76H204V64a20,20,0,0,0-20-20H40A20,20,0,0,0,20,64v96a20,20,0,0,0,20,20H156v12a20,20,0,0,0,20,20h48a20,20,0,0,0,20-20V96A20,20,0,0,0,224,76ZM40,172a12,12,0,0,1-12-12V64A12,12,0,0,1,40,52H184a12,12,0,0,1,12,12V76H176a20,20,0,0,0-20,20v76Zm196,20a12,12,0,0,1-12,12H176a12,12,0,0,1-12-12V96a12,12,0,0,1,12-12h48a12,12,0,0,1,12,12ZM132,208a4,4,0,0,1-4,4H88a4,4,0,0,1,0-8h40A4,4,0,0,1,132,208Zm80-96a4,4,0,0,1-4,4H192a4,4,0,0,1,0-8h16A4,4,0,0,1,212,112Z"/>'),Zz=Ya("devices","0 0 256 256",'<path d="M224,74H206V64a22,22,0,0,0-22-22H40A22,22,0,0,0,18,64v96a22,22,0,0,0,22,22H154v10a22,22,0,0,0,22,22h48a22,22,0,0,0,22-22V96A22,22,0,0,0,224,74ZM40,170a10,10,0,0,1-10-10V64A10,10,0,0,1,40,54H184a10,10,0,0,1,10,10V74H176a22,22,0,0,0-22,22v74Zm194,22a10,10,0,0,1-10,10H176a10,10,0,0,1-10-10V96a10,10,0,0,1,10-10h48a10,10,0,0,1,10,10ZM134,208a6,6,0,0,1-6,6H88a6,6,0,0,1,0-12h40A6,6,0,0,1,134,208Zm80-96a6,6,0,0,1-6,6H192a6,6,0,0,1,0-12h16A6,6,0,0,1,214,112Z"/>'),Od=Ya("devices","0 0 256 256",'<path d="M224,72H208V64a24,24,0,0,0-24-24H40A24,24,0,0,0,16,64v96a24,24,0,0,0,24,24H152v8a24,24,0,0,0,24,24h48a24,24,0,0,0,24-24V96A24,24,0,0,0,224,72ZM40,168a8,8,0,0,1-8-8V64a8,8,0,0,1,8-8H184a8,8,0,0,1,8,8v8H176a24,24,0,0,0-24,24v72Zm192,24a8,8,0,0,1-8,8H176a8,8,0,0,1-8-8V96a8,8,0,0,1,8-8h48a8,8,0,0,1,8,8Zm-96,16a8,8,0,0,1-8,8H88a8,8,0,0,1,0-16h40A8,8,0,0,1,136,208Zm80-96a8,8,0,0,1-8,8H192a8,8,0,0,1,0-16h16A8,8,0,0,1,216,112Z"/>'),Bz=Ya("devices","0 0 256 256",'<path d="M224,72H212V64a28,28,0,0,0-28-28H40A28,28,0,0,0,12,64v88a28,28,0,0,0,28,28h96v12a28,28,0,0,0,28,28h60a28,28,0,0,0,28-28V100A28,28,0,0,0,224,72ZM40,156a4,4,0,0,1-4-4V64a4,4,0,0,1,4-4H184a4,4,0,0,1,4,4v8H164a28,28,0,0,0-28,28v56Zm188,36a4,4,0,0,1-4,4H164a4,4,0,0,1-4-4V100a4,4,0,0,1,4-4h60a4,4,0,0,1,4,4ZM124,208a12,12,0,0,1-12,12H88a12,12,0,0,1,0-24h24A12,12,0,0,1,124,208Zm88-84a12,12,0,0,1-12,12H188a12,12,0,0,1,0-24h12A12,12,0,0,1,212,124Z"/>'),Fz=Ya("devices","0 0 256 256",'<path d="M224,72H208V64a24,24,0,0,0-24-24H40A24,24,0,0,0,16,64v96a24,24,0,0,0,24,24H152v8a24,24,0,0,0,24,24h48a24,24,0,0,0,24-24V96A24,24,0,0,0,224,72Zm8,120a8,8,0,0,1-8,8H176a8,8,0,0,1-8-8V96a8,8,0,0,1,8-8h48a8,8,0,0,1,8,8Zm-96,16a8,8,0,0,1-8,8H88a8,8,0,0,1,0-16h40A8,8,0,0,1,136,208Zm80-96a8,8,0,0,1-8,8H192a8,8,0,0,1,0-16h16A8,8,0,0,1,216,112Z"/>'),zz=Ya("devices","0 0 256 256",'<path d="M200,64V80H176a16,16,0,0,0-16,16v80H40a16,16,0,0,1-16-16V64A16,16,0,0,1,40,48H184A16,16,0,0,1,200,64Z" opacity="0.2"/><path d="M224,72H208V64a24,24,0,0,0-24-24H40A24,24,0,0,0,16,64v96a24,24,0,0,0,24,24H152v8a24,24,0,0,0,24,24h48a24,24,0,0,0,24-24V96A24,24,0,0,0,224,72ZM40,168a8,8,0,0,1-8-8V64a8,8,0,0,1,8-8H184a8,8,0,0,1,8,8v8H176a24,24,0,0,0-24,24v72Zm192,24a8,8,0,0,1-8,8H176a8,8,0,0,1-8-8V96a8,8,0,0,1,8-8h48a8,8,0,0,1,8,8Zm-96,16a8,8,0,0,1-8,8H88a8,8,0,0,1,0-16h40A8,8,0,0,1,136,208Zm80-96a8,8,0,0,1-8,8H192a8,8,0,0,1,0-16h16A8,8,0,0,1,216,112Z"/>'),Uz="devices",Wz=Object.freeze(Object.defineProperty({__proto__:null,bold:Bz,default:Od,duotone:zz,fill:Fz,glyphName:Uz,light:Zz,regular:Od,thin:Dz},Symbol.toStringTag,{value:"Module"})),jz={class:"devices-view"},Kz={class:"toolbar-count"},qz={key:1,class:"empty-state"},Gz={class:"device-icon native-icon"},Yz={class:"device-info"},Xz={class:"device-name"},Jz={class:"device-type"},Qz={class:"device-summary"},eU={key:0,class:"summary-primary"},tU={class:"summary-primary"},iU={key:0,class:"summary-secondary"},nU={key:2,class:"summary-primary"},rU=["title"],sU={class:"device-info"},aU={class:"device-name"},lU={class:"device-type"},oU={key:0,class:"device-summary"},cU={class:"summary-primary"},uU=["title"],dU=["title"],hU={key:1},fU={class:"confirm-dialog"},pU={class:"confirm-icon"},_U={class:"confirm-message"},mU={class:"confirm-actions"},Sp="openbridge.devices.view",vU=Ne({__name:"DevicesView",setup(e){const t=Kr(),i=Qo(),n=_1();function r(N){var O;return((O=N.health)==null?void 0:O.status)==="stale"}function s(N){return N<90?`${Math.round(N)} seconds`:N<5400?`${Math.round(N/60)} minutes`:N<172800?`${Math.round(N/3600)} hours`:`${Math.round(N/86400)} days`}function a(N){const O=N.health;if(!O||O.status!=="stale")return"";const te=["Not responding"];return O.silentForSeconds!==null?te.push(`Silent for ${s(O.silentForSeconds)}.`):O.lastSeen&&te.push(`Last seen ${new Date(O.lastSeen).toLocaleString()}.`),O.reason&&te.push(O.reason),te.push("OpenBridge is running: the device itself is not answering. Check it is powered and reachable at its configured address.","Click to open it for its address, readings and recent events."),te.join(`
69
69
  `)}const l=["Not responding","HomeKit reports this accessory as unreachable. Check it is powered and on the network.","Click to open it for its services and characteristics."].join(`
70
- `);function o(N){var te;const O=(te=N.health)==null?void 0:te.status;return O==="ok"?"online":O==="stale"?"stale":"offline"}function c(N){var te;const O=(te=N.health)==null?void 0:te.status;return O==="ok"?"Responding":O==="stale"?"Not responding":"No data yet"}function u(N){n.push({name:"device-detail",params:{id:N.id}})}const d=Ms(),h=K(!1),f=K([]),v=K(localStorage.getItem(Sp)==="table"?"table":"cards");function p(){v.value=v.value==="cards"?"table":"cards",localStorage.setItem(Sp,v.value)}const w=K({key:"name",direction:"asc"}),_=[{key:"name",header:"Device",sortable:!0},{key:"type",header:"Type",sortable:!0,width:160},{key:"source",header:"Source",sortable:!0,width:120},{key:"state",header:"State",sortable:!0,width:120},{key:"detail",header:"Reading",sortable:!0,width:160}],y=q(()=>{const N=[...f.value.map(ee=>({key:"native:"+ee.id,name:ee.name,type:x(g(ee)),source:"Native",state:ee.telemetry.active===void 0?"":ee.telemetry.active?"On":"Off",stateOn:!!ee.telemetry.active,detail:C(ee),icon:A(g(ee)),unhealthy:r(ee),healthTooltip:a(ee),select:()=>L(ee)})),...t.accessories.map(ee=>{const me=ue(ee);return{key:"hap:"+ee.uuid,name:ee.displayName,type:T(ee.category).label,source:"HomeKit",state:ee.reachable?me?me.value?"On":"Off":"":"Not responding",stateOn:ee.reachable&&!!(me!=null&&me.value),detail:J(ee)??"",icon:T(ee.category).icon,unhealthy:!ee.reachable,healthTooltip:ee.reachable?"":l,select:()=>E(ee)}})],O=w.value;if(!O||O.direction==="none")return N;const te=O.direction==="asc"?1:-1;return[...N].sort((ee,me)=>te*String(ee[O.key]??"").localeCompare(String(me[O.key]??"")))});function C(N){const O=N.telemetry;return N.widgetType==="energy_meter"&&O.power!==void 0?`${ne(O.power,1)} W`:N.widgetType==="thermostat"&&O.currentTemperature!==void 0?`${ne(O.currentTemperature,1)}°C`:N.widgetType==="dehumidifier"&&O.currentHumidity!==void 0?`${ne(O.currentHumidity,0)}%`:O.power!==void 0?`${ne(O.power,1)} W`:""}function g(N){return N.homekitType||N.widgetType}const $=q(()=>i.mode!=="device"||!i.selectedDevice?null:i.selectedDevice.kind==="native"?i.selectedDevice.dev.id:i.selectedDevice.acc.uuid);function E(N){$.value===N.uuid?i.close():i.openDevice({kind:"hap",acc:N})}function L(N){$.value===N.id?i.close():i.openDevice({kind:"native",dev:N})}const B={1:{label:"Other",icon:"cube"},2:{label:"Bridge",icon:"intersect"},3:{label:"Fan",icon:"fan"},4:{label:"Garage Door",icon:"garage"},5:{label:"Light",icon:"lightbulb"},6:{label:"Lock",icon:"lock"},7:{label:"Outlet",icon:"plugs"},8:{label:"Switch",icon:"toggle-right"},9:{label:"Thermostat",icon:"thermometer"},10:{label:"Sensor",icon:"pulse"},11:{label:"Security",icon:"shield"},12:{label:"Door",icon:"door"},13:{label:"Window",icon:"app-window"},14:{label:"Window Covering",icon:"rows"},15:{label:"Programm. Switch",icon:"sliders"},16:{label:"Range Extender",icon:"broadcast"},17:{label:"Camera",icon:"camera"},18:{label:"Video Doorbell",icon:"bell"},19:{label:"Air Purifier",icon:"wind"},20:{label:"Heater/Cooler",icon:"thermometer-hot"},21:{label:"Air Conditioner",icon:"snowflake"},22:{label:"Humidifier",icon:"drop"},23:{label:"Dehumidifier",icon:"drop"},26:{label:"Speaker",icon:"speaker-high"},28:{label:"Sprinkler",icon:"drop"},29:{label:"Faucet",icon:"drop"},30:{label:"Shower",icon:"drop"},32:{label:"TV",icon:"television"},34:{label:"Router",icon:"broadcast"},36:{label:"Target Control",icon:"game-controller"},38:{label:"Smart Speaker",icon:"speaker-hifi"}};function T(N){return B[N]??{label:`Category ${N}`,icon:"cube"}}const X={switch:"plugs",light:"lightbulb",thermostat:"thermometer",dehumidifier:"drop",energy_meter:"lightning",gate:"garage",sensor:"pulse",camera:"camera"},W={camera:"Camera",switch:"Switch",light:"Light",thermostat:"Thermostat",dehumidifier:"Dehumidifier",energy_meter:"Energy Meter",gate:"Gate",sensor:"Sensor"};function A(N){return X[N]??"cube"}function x(N){return W[N]??N}const F=new Set(["AccessoryInformation","0000003E-0000-1000-8000-0026BB765291","ProtocolInformation","000000A2-0000-1000-8000-0026BB765291"]),ie=new Set(["On","Active","LockTargetState","TargetDoorState"]);function re(N){return N.services.find(O=>!F.has(O.name)&&!F.has(O.uuid))}function ue(N){const O=re(N);return O?O.characteristics.find(te=>ie.has(te.name)&&te.perms.includes("pw"))??null:null}function J(N){if(!N.reachable)return"Not responding";const O=re(N);if(!O)return null;for(const ee of O.characteristics){if(ee.name==="CurrentTemperature"&&ee.value!=null)return`${Number(ee.value).toFixed(1)}°C`;if(ee.name==="CurrentRelativeHumidity"&&ee.value!=null)return`${Math.round(Number(ee.value))}%`;if(ee.name==="CurrentPosition"&&ee.value!=null)return`${Math.round(Number(ee.value))}%`;if(ee.name==="Brightness"&&ee.value!=null)return`${Math.round(Number(ee.value))}%`}const te=O.characteristics.find(ee=>ee.name==="On");return te?te.value?"On":"Off":null}async function ae(N,O){const te=re(N),ee=ue(N);if(!(!te||!ee))try{await Re.setCharacteristic(N.uuid,te.uuid,ee.uuid,O?1:0),await t.fetchAccessories()}catch(me){console.error("HAP control failed",me)}}function ne(N,O=1){if(N==null)return"—";const te=Number(N);return isFinite(te)?te.toFixed(O):String(N)}const Q=q(()=>t.accessories.length+f.value.length);async function oe(){var N;try{const O=await Re.devices();if(f.value=O.devices,i.mode==="device"&&((N=i.selectedDevice)==null?void 0:N.kind)==="native"){const te=i.selectedDevice.dev.id,ee=O.devices.find(me=>me.id===te);ee&&i.updateDevice({kind:"native",dev:ee})}}catch{}}async function ve(){h.value=!0,await Promise.all([t.fetchAccessories(),oe()]),h.value=!1}let fe=null;const pe=K({visible:!1,deviceId:"",control:"",value:null,message:""});function ye(N,O,te){return N.widgetType==="energy_meter"&&O==="active"?te?`Turn on ${N.name}? This will energise the connected circuit.`:`Turn off ${N.name}? This will cut power to the connected circuit.`:!1}async function U(N,O,te){try{await Re.controlDevice(N,O,te),await oe()}catch(ee){console.error("Control failed",ee)}}function _e(N,O,te){const ee=ye(N,O,te);ee?pe.value={visible:!0,deviceId:N.id,control:O,value:te,message:ee}:U(N.id,O,te)}function ge(){const{deviceId:N,control:O,value:te}=pe.value;pe.value.visible=!1,U(N,O,te)}function se(){pe.value.visible=!1}async function H(){var N;if(await Promise.all([t.fetchAccessories(),oe()]),i.mode==="device"&&((N=i.selectedDevice)==null?void 0:N.kind)==="hap"){const O=i.selectedDevice.acc.uuid,te=t.accessories.find(ee=>ee.uuid===O);te&&i.updateDevice({kind:"hap",acc:te})}}return nt(async()=>{d.setPage("Devices"),await H(),fe=setInterval(H,3e3)}),Ii(()=>{fe&&clearInterval(fe)}),(N,O)=>{const te=Cs,ee=Pt,me=Ue,we=o1,S=w2,k=Ss,D=b2;return m(),M("div",jz,[Q.value>0?(m(),he(an,{key:0,defer:"",to:"#ob-topbar-left"},[b("span",Kz,Z(Q.value)+" device"+Z(Q.value!==1?"s":""),1),f.value.length>0?(m(),he(te,{key:0},{default:G(()=>[le(Z(f.value.length)+" native",1)]),_:1})):V("",!0)])):V("",!0),(m(),he(an,{defer:"",to:"#ob-topbar-right"},[j(ee,{variant:"ghost",size:"sm",icon:v.value===db?hb:fb,title:v.value==="cards"?"Show as table":"Show as cards",onClick:p},null,8,["icon","title"]),j(ee,{variant:"ghost",size:"sm",icon:_s,title:"Refresh",loading:h.value,onClick:ve},null,8,["loading"])])),Q.value===0?(m(),M("div",qz,[j(me,{name:de(Od),size:40},null,8,["name"]),O[8]||(O[8]=b("p",null,"No devices registered yet.",-1)),O[9]||(O[9]=b("p",{class:"empty-hint"},[le(" Devices appear here once a platform plugin registers accessories. "),b("br"),le(" This page auto-refreshes every 3 seconds: discovery can take up to 60s. ")],-1))])):(m(),M("div",{key:2,class:"devices-layout",onClick:O[7]||(O[7]=qe(P=>de(i).close(),["self"]))},[v.value==="cards"?(m(),M("div",{key:0,class:"device-grid",onClick:O[4]||(O[4]=qe(P=>de(i).close(),["self"]))},[(m(!0),M(Ce,null,Fe(f.value,P=>(m(),he(k,{key:"native:"+P.id,class:Le(["device-card native-card",{selected:$.value===P.id,unhealthy:r(P)}]),title:r(P)?a(P):void 0,onClick:R=>L(P),onDblclick:R=>u(P)},{default:G(()=>{var R;return[O[10]||(O[10]=b("span",{class:"device-card__accent"},null,-1)),b("div",Gz,[j(me,{name:A(g(P)),size:22},null,8,["name"])]),b("div",Yz,[b("div",Xz,[r(P)?(m(),he(me,{key:0,name:de(xn),size:14,class:"name-health-icon"},null,8,["name"])):V("",!0),b("span",null,Z(P.name),1)]),b("div",Jz,Z(x(g(P))),1),b("div",Qz,[P.widgetType==="energy_meter"&&P.telemetry.power!==void 0?(m(),M("span",eU,Z(ne(P.telemetry.power,1))+" W",1)):P.widgetType==="thermostat"&&P.telemetry.currentTemperature!==void 0?(m(),M(Ce,{key:1},[b("span",tU,Z(ne(P.telemetry.currentTemperature,1))+"°C",1),P.telemetry.targetTemperature!==void 0?(m(),M("span",iU," target "+Z(ne(P.telemetry.targetTemperature,1))+"°C ",1)):V("",!0)],64)):P.widgetType==="dehumidifier"&&P.telemetry.currentHumidity!==void 0?(m(),M("span",nU,Z(ne(P.telemetry.currentHumidity,0))+"%",1)):P.telemetry.active!==void 0?(m(),M("span",{key:3,class:Le(["summary-status",P.telemetry.active?"on":"off"])},Z(P.telemetry.active?"On":"Off"),3)):V("",!0)]),P.telemetry.active!==void 0?(m(),M("div",{key:0,class:"card-controls",onClick:O[0]||(O[0]=qe(()=>{},["stop"]))},[j(we,{name:`device-active-${P.id}`,"model-value":!!P.telemetry.active,"onUpdate:modelValue":I=>_e(P,"active",I)},null,8,["name","model-value","onUpdate:modelValue"])])):V("",!0),P.widgetType==="thermostat"&&P.telemetry.targetTemperature!==void 0?(m(),M("div",{key:1,class:"card-controls",onClick:O[1]||(O[1]=qe(()=>{},["stop"]))},[j(S,{"model-value":Number(P.telemetry.targetTemperature),size:"xs",min:5,max:35,step:1,"onUpdate:modelValue":I=>I!==null&&U(P.id,"targetTemperature",I)},null,8,["model-value","onUpdate:modelValue"])])):V("",!0),P.widgetType==="dehumidifier"&&P.telemetry.targetHumidity!==void 0?(m(),M("div",{key:2,class:"card-controls",onClick:O[2]||(O[2]=qe(()=>{},["stop"]))},[j(S,{"model-value":Number(P.telemetry.targetHumidity),size:"xs",min:30,max:80,step:5,"onUpdate:modelValue":I=>I!==null&&U(P.id,"targetHumidity",I)},null,8,["model-value","onUpdate:modelValue"])])):V("",!0)]),b("div",{class:Le(["device-reachability",o(P)]),title:((R=P.health)==null?void 0:R.reason)??c(P)},null,10,rU)]}),_:2},1032,["class","title","onClick","onDblclick"]))),128)),(m(!0),M(Ce,null,Fe(de(t).accessories,P=>(m(),he(k,{key:P.uuid,class:Le(["device-card hap-card",{selected:$.value===P.uuid,unreachable:!P.reachable,unhealthy:!P.reachable}]),title:P.reachable?void 0:de(l),onClick:R=>E(P)},{default:G(()=>{var R;return[b("div",{class:Le(["device-icon hap-icon",{unreachable:!P.reachable}])},[j(me,{name:T(P.category).icon,size:22},null,8,["name"])],2),b("div",sU,[b("div",aU,[P.reachable?V("",!0):(m(),he(me,{key:0,name:de(xn),size:14,class:"name-health-icon"},null,8,["name"])),b("span",null,Z(P.displayName),1)]),b("div",lU,Z(T(P.category).label),1),J(P)?(m(),M("div",oU,[b("span",cU,Z(J(P)),1)])):V("",!0),ue(P)?(m(),M("div",{key:1,class:"card-controls",onClick:O[3]||(O[3]=qe(()=>{},["stop"]))},[j(we,{name:`hap-on-${P.uuid}`,"model-value":!!((R=ue(P))!=null&&R.value),"onUpdate:modelValue":I=>ae(P,!!I)},null,8,["name","model-value","onUpdate:modelValue"])])):V("",!0)]),b("div",{class:Le(["device-reachability",P.reachable?"online":"stale"]),title:P.reachable?"Responding":de(l)},null,10,uU)]}),_:2},1032,["class","title","onClick"]))),128))])):(m(),he(D,{key:1,columns:_,rows:y.value,"row-key":"key",size:"sm",zebra:"","sort-state":w.value,onSort:O[5]||(O[5]=P=>w.value=P),onRowClick:O[6]||(O[6]=P=>P.select())},{"cell-name":G(({row:P})=>[b("div",{class:"cell-name",title:P.healthTooltip||void 0},[j(me,{name:P.icon,size:16},null,8,["name"]),b("span",null,Z(P.name),1),P.unhealthy?(m(),he(me,{key:0,name:de(xn),size:14,class:"cell-health-icon"},null,8,["name"])):V("",!0)],8,dU)]),"cell-state":G(({row:P})=>[P.state?(m(),he(te,{key:0,variant:P.unhealthy?"orange":P.stateOn?"green":"grey"},{default:G(()=>[le(Z(P.state),1)]),_:2},1032,["variant"])):(m(),M("span",hU,"—"))]),_:1},8,["rows","sort-state"]))])),(m(),he(an,{to:"body"},[pe.value.visible?(m(),M("div",{key:0,class:"confirm-overlay",onClick:qe(se,["self"])},[b("div",fU,[b("div",pU,[j(me,{name:de(xn),size:24},null,8,["name"])]),b("p",_U,Z(pe.value.message),1),b("div",mU,[j(ee,{variant:"ghost",size:"sm",onClick:se},{default:G(()=>[...O[11]||(O[11]=[le("Cancel",-1)])]),_:1}),j(ee,{variant:"primary",size:"sm",onClick:ge},{default:G(()=>[...O[12]||(O[12]=[le("Confirm",-1)])]),_:1})])])])):V("",!0)]))])}}}),gU=zt(vU,[["__scopeId","data-v-5ae916c1"]]),bU={class:"device-detail"},yU={class:"detail-header"},wU={key:0,class:"detail-model"},SU={key:0,class:"detail-message"},CU={class:"summary-row"},kU=["onClick"],AU={class:"tile-label"},MU={class:"tile-value"},$U={class:"tile-unit"},LU={key:0,class:"detail-message"},EU={class:"chart-toolbar"},xU={class:"range-tabs"},HU=["onClick"],TU={key:0,class:"resolution-note"},NU={class:"chart-panel"},PU={key:1,class:"chart-empty"},OU={key:2,class:"chart-empty"},IU={key:2,class:"detail-message"},RU=Ne({__name:"DeviceDetailView",setup(e){const t=Jo(),i=q(()=>String(t.params.id??"")),n=K(null),r=K([]),s=K(""),a=K(!1),l=K(""),o=K(0),c=K([]),u=[{key:"1h",label:"1 hour",seconds:3600},{key:"24h",label:"24 hours",seconds:86400},{key:"7d",label:"7 days",seconds:7*86400},{key:"30d",label:"30 days",seconds:30*86400},{key:"1y",label:"1 year",seconds:365*86400}],d=K("24h"),h=q(()=>{var B;return[{label:"Devices",to:{name:"devices"}},{label:((B=n.value)==null?void 0:B.name)??i.value}]}),f=q(()=>r.value.find(B=>B.key===s.value)??null),v=q(()=>{const B=f.value;if(!B||c.value.length===0)return[];const T={name:B.label,data:c.value.map(W=>({x:new Date(W.t*1e3),y:W.value??0}))};return c.value.some(W=>W.min!==void 0&&W.min!==null&&W.min!==W.value)?[T,{name:"Min",data:c.value.map(W=>({x:new Date(W.t*1e3),y:W.min??W.value??0}))},{name:"Max",data:c.value.map(W=>({x:new Date(W.t*1e3),y:W.max??W.value??0}))}]:[T]}),p=q(()=>{if(!o.value)return"";const B=o.value;return B<60?`${B}s resolution`:B<3600?`${Math.round(B/60)} min resolution`:`${Math.round(B/3600)} h resolution`});function w(B){var W,A;const T=(A=(W=n.value)==null?void 0:W.telemetry)==null?void 0:A[B.key],X=Number(T);return Number.isFinite(X)?X:null}function _(B,T){return B===null?"—":B.toFixed(T.precision??2)}function y(B){s.value!==B&&(s.value=B,$())}function C(B){d.value!==B&&(d.value=B,$())}async function g(){try{const{devices:B}=await Re.devices(),T=B.find(X=>X.id===i.value);if(!T){l.value=`Device "${i.value}" was not found. It may have been removed, or its plugin stopped.`;return}n.value=T,r.value=T.metrics??[],!s.value&&r.value.length>0&&(s.value=r.value[0].key)}catch(B){l.value=`Could not load device: ${B.message}`}}async function $(){var W,A;if(!s.value)return;const B=u.find(x=>x.key===d.value),T=Math.floor(Date.now()/1e3),X=T-B.seconds;a.value=!0;try{const x=await Re.deviceMetrics(i.value,{metric:s.value,from:X,to:T});c.value=((W=x.series)==null?void 0:W.points)??[],o.value=((A=x.series)==null?void 0:A.resolution)??0}catch(x){l.value=`Could not load history: ${x.message}`}finally{a.value=!1}}let E=null,L=null;return nt(async()=>{await g(),await $(),E=setInterval(()=>void g(),5e3),L=setInterval(()=>void $(),3e4)}),ri(()=>{E&&clearInterval(E),L&&clearInterval(L)}),Ve(i,async()=>{n.value=null,r.value=[],s.value="",c.value=[],l.value="",await g(),await $()}),(B,T)=>{var x;const X=$v,W=at,A=eH;return m(),M("div",bU,[b("div",yU,[j(X,{items:h.value},null,8,["items"]),(x=n.value)!=null&&x.model?(m(),M("span",wU,Z(n.value.model),1)):V("",!0)]),l.value?(m(),M("div",SU,[j(W,{variant:"error"},{default:G(()=>[le(Z(l.value),1)]),_:1})])):n.value?(m(),M(Ce,{key:1},[b("div",CU,[(m(!0),M(Ce,null,Fe(r.value,F=>(m(),M("div",{key:F.key,class:Le(["summary-tile",{active:F.key===s.value}]),onClick:ie=>y(F.key)},[b("span",AU,Z(F.label),1),b("span",MU,[le(Z(_(w(F),F))+" ",1),b("span",$U,Z(F.unit),1)])],10,kU))),128))]),r.value.length===0?(m(),M("div",LU,[j(W,{variant:"helper"},{default:G(()=>[...T[0]||(T[0]=[le(" This device does not declare any metrics, so there is nothing to chart. Plugins opt in by describing their series in the device descriptor. ",-1)])]),_:1})])):(m(),M(Ce,{key:1},[b("div",EU,[b("div",xU,[(m(),M(Ce,null,Fe(u,F=>b("button",{key:F.key,class:Le(["range-tab",{active:F.key===d.value}]),onClick:ie=>C(F.key)},Z(F.label),11,HU)),64))]),p.value?(m(),M("span",TU,Z(p.value),1)):V("",!0)]),b("div",NU,[v.value.length>0&&v.value[0].data.length>0?(m(),he(A,{key:0,series:v.value,height:320,"show-legend":v.value.length>1,"show-grid":!0,"show-tooltip":!0,points:!1,curve:"smooth"},null,8,["series","show-legend"])):a.value?(m(),M("div",PU,"Loading…")):(m(),M("div",OU," No data recorded yet for this range. History starts accumulating once the device reports. "))])],64))],64)):(m(),M("div",IU,"Loading…"))])}}}),VU=zt(RU,[["__scopeId","data-v-6e2a0af1"]]),Xa=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},DU=Xa("magic-wand","0 0 256 256",'<path d="M244,152a4,4,0,0,1-4,4H220v20a4,4,0,0,1-8,0V156H192a4,4,0,0,1,0-8h20V128a4,4,0,0,1,8,0v20h20A4,4,0,0,1,244,152ZM56,68H76V88a4,4,0,0,0,8,0V68h20a4,4,0,0,0,0-8H84V40a4,4,0,0,0-8,0V60H56a4,4,0,0,0,0,8ZM184,196H172V184a4,4,0,0,0-8,0v12H152a4,4,0,0,0,0,8h12v12a4,4,0,0,0,8,0V204h12a4,4,0,0,0,0-8ZM216.48,77.17,77.17,216.49a12,12,0,0,1-17,0L39.51,195.8a12,12,0,0,1,0-17L178.83,39.51a12,12,0,0,1,17,0L216.48,60.2A12,12,0,0,1,216.48,77.17ZM170.34,112,144,85.66,45.17,184.49a4,4,0,0,0,0,5.65l20.68,20.69a4,4,0,0,0,5.66,0Zm40.49-46.14L190.14,45.17a4,4,0,0,0-5.66,0L149.65,80,176,106.34l34.83-34.83A4,4,0,0,0,210.83,65.86Z"/>'),ZU=Xa("magic-wand","0 0 256 256",'<path d="M246,152a6,6,0,0,1-6,6H222v18a6,6,0,0,1-12,0V158H192a6,6,0,0,1,0-12h18V128a6,6,0,0,1,12,0v18h18A6,6,0,0,1,246,152ZM56,70H74V88a6,6,0,0,0,12,0V70h18a6,6,0,0,0,0-12H86V40a6,6,0,0,0-12,0V58H56a6,6,0,0,0,0,12ZM184,194H174V184a6,6,0,0,0-12,0v10H152a6,6,0,0,0,0,12h10v10a6,6,0,0,0,12,0V206h10a6,6,0,0,0,0-12ZM217.9,78.59,78.58,217.9a14,14,0,0,1-19.8,0L38.09,197.21a14,14,0,0,1,0-19.8L177.41,38.1a14,14,0,0,1,19.8,0L217.9,58.79A14,14,0,0,1,217.9,78.59ZM167.51,112,144,88.49,46.58,185.9a2,2,0,0,0,0,2.83l20.69,20.68a2,2,0,0,0,2.82,0h0Zm41.9-44.73L188.73,46.59a2,2,0,0,0-2.83,0L152.48,80,176,103.52,209.41,70.1A2,2,0,0,0,209.41,67.27Z"/>'),Cp=Xa("magic-wand","0 0 256 256",'<path d="M48,64a8,8,0,0,1,8-8H72V40a8,8,0,0,1,16,0V56h16a8,8,0,0,1,0,16H88V88a8,8,0,0,1-16,0V72H56A8,8,0,0,1,48,64ZM184,192h-8v-8a8,8,0,0,0-16,0v8h-8a8,8,0,0,0,0,16h8v8a8,8,0,0,0,16,0v-8h8a8,8,0,0,0,0-16Zm56-48H224V128a8,8,0,0,0-16,0v16H192a8,8,0,0,0,0,16h16v16a8,8,0,0,0,16,0V160h16a8,8,0,0,0,0-16ZM219.31,80,80,219.31a16,16,0,0,1-22.62,0L36.68,198.63a16,16,0,0,1,0-22.63L176,36.69a16,16,0,0,1,22.63,0l20.68,20.68A16,16,0,0,1,219.31,80Zm-54.63,32L144,91.31l-96,96L68.68,208ZM208,68.69,187.31,48l-32,32L176,100.69Z"/>'),BU=Xa("magic-wand","0 0 256 256",'<path d="M252,152a12,12,0,0,1-12,12H228v12a12,12,0,0,1-24,0V164H192a12,12,0,0,1,0-24h12V128a12,12,0,0,1,24,0v12h12A12,12,0,0,1,252,152ZM56,76H68V88a12,12,0,0,0,24,0V76h12a12,12,0,1,0,0-24H92V40a12,12,0,0,0-24,0V52H56a12,12,0,0,0,0,24ZM184,188h-4v-4a12,12,0,0,0-24,0v4h-4a12,12,0,0,0,0,24h4v4a12,12,0,0,0,24,0v-4h4a12,12,0,0,0,0-24ZM222.14,82.83,82.82,222.14a20,20,0,0,1-28.28,0L33.85,201.46a20,20,0,0,1,0-28.29L173.17,33.86a20,20,0,0,1,28.28,0l20.69,20.68A20,20,0,0,1,222.14,82.83ZM159,112,144,97,53.65,187.31l15,15Zm43.31-43.31-15-15L161,80l15,15Z"/>'),FU=Xa("magic-wand","0 0 256 256",'<path d="M248,152a8,8,0,0,1-8,8H224v16a8,8,0,0,1-16,0V160H192a8,8,0,0,1,0-16h16V128a8,8,0,0,1,16,0v16h16A8,8,0,0,1,248,152ZM56,72H72V88a8,8,0,0,0,16,0V72h16a8,8,0,0,0,0-16H88V40a8,8,0,0,0-16,0V56H56a8,8,0,0,0,0,16ZM184,192h-8v-8a8,8,0,0,0-16,0v8h-8a8,8,0,0,0,0,16h8v8a8,8,0,0,0,16,0v-8h8a8,8,0,0,0,0-16ZM219.31,80,80,219.31a16,16,0,0,1-22.62,0L36.68,198.63a16,16,0,0,1,0-22.63L176,36.69a16,16,0,0,1,22.63,0l20.68,20.68A16,16,0,0,1,219.31,80ZM208,68.69,187.31,48l-32,32L176,100.69Z"/>'),zU=Xa("magic-wand","0 0 256 256",'<path d="M176,112,74.34,213.66a8,8,0,0,1-11.31,0L42.34,193a8,8,0,0,1,0-11.31L144,80Z" opacity="0.2"/><path d="M248,152a8,8,0,0,1-8,8H224v16a8,8,0,0,1-16,0V160H192a8,8,0,0,1,0-16h16V128a8,8,0,0,1,16,0v16h16A8,8,0,0,1,248,152ZM56,72H72V88a8,8,0,0,0,16,0V72h16a8,8,0,0,0,0-16H88V40a8,8,0,0,0-16,0V56H56a8,8,0,0,0,0,16ZM184,192h-8v-8a8,8,0,0,0-16,0v8h-8a8,8,0,0,0,0,16h8v8a8,8,0,0,0,16,0v-8h8a8,8,0,0,0,0-16ZM219.31,80,80,219.31a16,16,0,0,1-22.62,0L36.68,198.63a16,16,0,0,1,0-22.63L176,36.69a16,16,0,0,1,22.63,0l20.68,20.68A16,16,0,0,1,219.31,80Zm-54.63,32L144,91.31l-96,96L68.68,208ZM208,68.69,187.31,48l-32,32L176,100.69Z"/>'),UU="magic-wand",WU=Object.freeze(Object.defineProperty({__proto__:null,bold:BU,default:Cp,duotone:zU,fill:FU,glyphName:UU,light:ZU,regular:Cp,thin:DU},Symbol.toStringTag,{value:"Module"})),jU={class:"config-view"},KU={key:0,class:"error-banner"},qU={key:1,class:"loading-state"},GU=Ne({__name:"ConfigView",setup(e){const t=Ms(),{resolved:i}=c1(),n=K(null),r=zn(null),s=K(!1),a=K(!1),l=K(null),o=K(!0);nt(async()=>{t.setPage("Config",void 0,{fullBleed:!0});let d="{}";try{d=(await Re.config.get()).content}catch(f){l.value=`Failed to load config: ${f}`}finally{o.value=!1}const h=await cb.init();h.languages.json.jsonDefaults.setDiagnosticsOptions({validate:!0,schemas:[{uri:"openbridge://config-schema",fileMatch:["*"],schema:{type:"object",properties:{bridge:{type:"object",description:"Bridge configuration",properties:{name:{type:"string",description:"Bridge display name"},port:{type:"number",description:"HTTP API port (default 8582)"},hapPort:{type:"number",description:"HomeKit HAP port (default 51829)"},pincode:{type:"string",description:"HomeKit pairing PIN (format: XXX-XX-XXX)"},username:{type:"string",description:"HAP username (MAC address format)"},logLevel:{type:"string",enum:["debug","info","warn","error"]}}},platforms:{type:"array",description:"Homebridge-compatible platform plugins",items:{type:"object",required:["platform"],properties:{platform:{type:"string",description:"Platform identifier"},plugin:{type:"string",description:"Absolute path to the plugin JS file"},enabled:{type:"boolean",default:!0}},additionalProperties:!0}},plugins:{type:"array",description:"Native OpenBridge plugins",items:{type:"object",required:["name"],properties:{name:{type:"string"},path:{type:"string"},enabled:{type:"boolean",default:!0},config:{type:"object"}}}}}}}]}),n.value&&(Ve(i,f=>h.editor.setTheme(f==="dark"?"vs-dark":"vs")),r.value=h.editor.create(n.value,{value:d,language:"json",theme:i.value==="dark"?"vs-dark":"vs",fontSize:13,fontFamily:'"MesloLGS NF", monospace',minimap:{enabled:!0},scrollBeyondLastLine:!1,formatOnPaste:!0,formatOnType:!0,tabSize:2,automaticLayout:!0,wordWrap:"off",bracketPairColorization:{enabled:!0},guides:{bracketPairs:!0},lineNumbers:"on",renderLineHighlight:"all",smoothScrolling:!0}))}),ri(()=>{var d;(d=r.value)==null||d.dispose()});async function c(){var d;if(!s.value){s.value=!0,l.value=null,a.value=!1;try{const h=((d=r.value)==null?void 0:d.getValue())??"";await Re.config.save(h),a.value=!0,setTimeout(()=>{a.value=!1},2500)}catch(h){l.value=String(h)}finally{s.value=!1}}}function u(){var d,h;(h=(d=r.value)==null?void 0:d.getAction("editor.action.formatDocument"))==null||h.run()}return(d,h)=>{const f=Pt,v=Ue;return m(),M("div",jU,[(m(),he(an,{defer:"",to:"#ob-topbar-left"},[h[0]||(h[0]=b("span",{class:"config-path"},"~/.openbridge/config.json",-1))])),(m(),he(an,{defer:"",to:"#ob-topbar-right"},[j(f,{variant:"ghost",size:"sm",icon:WU,title:"Format JSON",onClick:u},{default:G(()=>[...h[1]||(h[1]=[le("Format",-1)])]),_:1}),j(f,{variant:"primary",size:"sm",icon:a.value?dr:Hc,loading:s.value,disabled:s.value,title:"Changes take effect after restarting the daemon",onClick:c},{default:G(()=>[le(Z(a.value?"Saved!":s.value?"Saving…":"Save"),1)]),_:1},8,["icon","loading","disabled"])])),l.value?(m(),M("div",KU,[j(v,{name:de(xn),size:14},null,8,["name"]),le(" "+Z(l.value),1)])):V("",!0),o.value?(m(),M("div",qU,[j(v,{name:de(ra),size:28},null,8,["name"]),h[2]||(h[2]=b("span",null,"Loading config...",-1))])):(m(),M("div",{key:2,ref_key:"editorContainer",ref:n,class:"editor-container"},null,512))])}}}),YU=zt(GU,[["__scopeId","data-v-483debe2"]]),XU=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},JU=XU("bridge","0 0 256 256",'<path d="M232,160H200V101.34a71.89,71.89,0,0,0,29,21.42,8,8,0,0,0,6-14.83A55.78,55.78,0,0,1,200,56a8,8,0,0,0-16,0A56,56,0,0,1,72,56a8,8,0,0,0-16,0,55.78,55.78,0,0,1-35,51.93,8,8,0,0,0,6,14.83,71.89,71.89,0,0,0,29-21.42V160H24a8,8,0,0,0,0,16H56v24a8,8,0,0,0,16,0V176H184v24a8,8,0,0,0,16,0V176h32a8,8,0,0,0,0-16Zm-88-33.8V160H112V126.2a72,72,0,0,0,32,0Zm-72-25a72.47,72.47,0,0,0,24,19.27V160H72ZM160,160V120.48a72.47,72.47,0,0,0,24-19.27V160Z"/>'),QU=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},eW=QU("palette","0 0 256 256",'<path d="M200.77,53.89A103.27,103.27,0,0,0,128,24h-1.07A104,104,0,0,0,24,128c0,43,26.58,79.06,69.36,94.17A32,32,0,0,0,136,192a16,16,0,0,1,16-16h46.21a31.81,31.81,0,0,0,31.2-24.88,104.43,104.43,0,0,0,2.59-24A103.28,103.28,0,0,0,200.77,53.89Zm13,93.71A15.89,15.89,0,0,1,198.21,160H152a32,32,0,0,0-32,32,16,16,0,0,1-21.31,15.07C62.49,194.3,40,164,40,128a88,88,0,0,1,87.09-88h.9a88.35,88.35,0,0,1,88,87.25A88.86,88.86,0,0,1,213.81,147.6ZM140,76a12,12,0,1,1-12-12A12,12,0,0,1,140,76ZM96,100A12,12,0,1,1,84,88,12,12,0,0,1,96,100Zm0,56a12,12,0,1,1-12-12A12,12,0,0,1,96,156Zm88-56a12,12,0,1,1-12-12A12,12,0,0,1,184,100Z"/>'),tW=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},iW=tW("robot","0 0 256 256",'<path d="M200,48H136V16a8,8,0,0,0-16,0V48H56A32,32,0,0,0,24,80V192a32,32,0,0,0,32,32H200a32,32,0,0,0,32-32V80A32,32,0,0,0,200,48Zm16,144a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V80A16,16,0,0,1,56,64H200a16,16,0,0,1,16,16Zm-52-56H92a28,28,0,0,0,0,56h72a28,28,0,0,0,0-56Zm-24,16v24H116V152ZM80,164a12,12,0,0,1,12-12h8v24H92A12,12,0,0,1,80,164Zm84,12h-8V152h8a12,12,0,0,1,0,24ZM72,108a12,12,0,1,1,12,12A12,12,0,0,1,72,108Zm88,0a12,12,0,1,1,12,12A12,12,0,0,1,160,108Z"/>'),nW=Ne({__name:"NewTokenModal",props:{open:{type:Boolean}},emits:["close","created"],setup(e,{emit:t}){const i=e,n=t,r=K(""),s=K("read"),a=K(!1),l=K(""),o=K(),c=K(null);Ve(()=>i.open,h=>{h&&(r.value="",s.value="read",l.value="",o.value=void 0,requestAnimationFrame(()=>{var f;return(f=c.value)==null?void 0:f.focus()}))});function u(){o.value=r.value.trim()?void 0:"Give the token a name you will recognise later"}async function d(){if(u(),!o.value){a.value=!0,l.value="";try{const{token:h}=await Re.access.createToken(r.value.trim(),s.value);n("created",h)}catch(h){l.value=h.message}finally{a.value=!1}}}return(h,f)=>{const v=ks,p=Wr,w=ba,_=xN,y=Pt,C=dg;return m(),he(C,{"close-appearance":"button",open:e.open,title:"New token",size:"sm","close-on-overlay":!r.value,onClose:f[3]||(f[3]=g=>n("close"))},{footer:G(()=>[j(y,{type:"button",variant:"secondary",onClick:f[2]||(f[2]=g=>n("close"))},{default:G(()=>[...f[4]||(f[4]=[le("Cancel",-1)])]),_:1}),j(y,{type:"submit",form:"new-token-form",variant:"primary",loading:a.value},{default:G(()=>[...f[5]||(f[5]=[le("Create token",-1)])]),_:1},8,["loading"])]),default:G(()=>[j(_,{id:"new-token-form",onSubmit:qe(d,["prevent"])},{default:G(()=>[l.value?(m(),he(v,{key:0,status:"error",variant:"inline",title:l.value},null,8,["title"])):V("",!0),j(p,{id:"new-token-name",ref_key:"nameInput",ref:c,modelValue:r.value,"onUpdate:modelValue":f[0]||(f[0]=g=>r.value=g),label:"Name",placeholder:"Claude on my laptop",error:o.value,onBlur:u},null,8,["modelValue","error"]),j(w,{id:"new-token-access",modelValue:s.value,"onUpdate:modelValue":f[1]||(f[1]=g=>s.value=g),label:"Access",options:[{label:"Read only: devices, history, events and logs",value:"read"},{label:"Read and control: can also operate devices",value:"control"}]},null,8,["modelValue"])]),_:1})]),_:1},8,["open","close-on-overlay"])}}}),rW={class:"agents__header"},sW={class:"agents__icon"},aW={class:"agents__reveal"},lW={class:"agents__reveal"},oW={class:"agents__reveal"},cW={class:"agents__section-head"},uW=Ne({__name:"AgentAccessPanel",setup(e){const t=Sg(),i=N2(),n=K(null),r=K(`${location.origin}/mcp`),s=K([]),a=K([]),l=K(!1),o=K(""),c=K(!1),u=K(""),d=E=>`claude mcp add --transport http openbridge ${r.value} --header "Authorization: Bearer ${E}"`,h=E=>E==="control"?"Read and control":"Read only",f=E=>E?new Date(E).toLocaleString():"Never",v=[{key:"name",header:"Name",primary:!0},{key:"access",header:"Access"},{key:"created",header:"Created",phoneMeta:!0},{key:"lastUsed",header:"Last used"},{key:"actions",header:"",align:"right"}],p=q(()=>s.value.map(E=>({id:E.id,name:E.owner?`${E.name} (${E.owner})`:E.name,access:h(E.access),created:f(E.createdAt),lastUsed:f(E.lastUsedAt)}))),w=[{key:"name",header:"Application",primary:!0},{key:"access",header:"Access"},{key:"connected",header:"Connected",phoneMeta:!0},{key:"lastUsed",header:"Last used"},{key:"actions",header:"",align:"right"}],_=q(()=>a.value.map(E=>({clientId:E.clientId,name:E.owners.length?`${E.name} (${E.owners.join(", ")})`:E.name,access:h(E.access),connected:f(E.connectedAt),lastUsed:f(E.lastUsedAt)})));async function y(){l.value=!0;try{const E=await Re.access.get();n.value=E.enabled,E.enabled&&(r.value=E.endpoint,s.value=E.tokens,a.value=E.connections),o.value=""}catch(E){o.value=E.message}finally{l.value=!1}}nt(y);function C(E){c.value=!1,u.value=E,y()}async function g(E,L){if(await t({title:"Revoke token",subjectLabel:"Token",subject:L,message:"Anything using this token loses access immediately.",confirmLabel:"Revoke"}))try{await Re.access.revokeToken(E),i.success("Token revoked"),await y()}catch(T){i.error(T.message,{title:"Could not revoke"})}}async function $(E,L){if(await t({title:"Disconnect application",subjectLabel:"Application",subject:L,message:"Every sign-in this application holds stops working, including its refresh tokens.",confirmLabel:"Disconnect"}))try{await Re.access.revokeConnection(E),i.success(`${L} disconnected`),await y()}catch(T){i.error(T.message,{title:"Could not disconnect"})}}return(E,L)=>{const B=Ue,T=at,X=Wr,W=FS,A=r2,x=ks,F=Pt,ie=Pk,re=b2,ue=Ss;return m(),he(ue,{class:"agents"},{default:G(()=>[b("div",rW,[b("div",sW,[j(B,{name:de(iW),size:18},null,8,["name"])]),L[3]||(L[3]=b("div",null,[b("h2",{class:"agents__title"},"AI agents"),b("p",{class:"agents__subtitle"}," Let Claude and other MCP clients read your devices and their history, and with control access, operate them. ")],-1))]),n.value===!1?(m(),he(T,{key:0,variant:"helper"},{default:G(()=>[...L[4]||(L[4]=[le(" The MCP endpoint is off on this bridge. Start OpenBridge with ",-1),b("code",null,"OPENBRIDGE_MCP=on",-1),le(" in its environment to turn it on, then create a token here. ",-1),b("a",{href:"https://docs.nubisco.io/openbridge/guide/mcp",target:"_blank",rel:"noopener"},"How to turn it on",-1)])]),_:1})):V("",!0),n.value?(m(),M(Ce,{key:1},[u.value?(m(),he(x,{key:0,status:"info",variant:"inline",title:"Copy this token now. It is not shown again.",dismissible:"",onClose:L[0]||(L[0]=J=>u.value="")},{default:G(()=>[j(A,{label:"Token",orientation:"stack"},{default:G(({id:J})=>[b("div",aW,[j(X,{id:J,"model-value":u.value,readonly:"",size:"sm",class:"agents__mono"},null,8,["id","model-value"]),j(W,{text:u.value,label:"Copy","copied-label":"Copied"},null,8,["text"])])]),_:1}),j(A,{label:"Connect Claude Code",orientation:"stack"},{default:G(({id:J})=>[b("div",lW,[j(X,{id:J,"model-value":d(u.value),readonly:"",size:"sm",class:"agents__mono"},null,8,["id","model-value"]),j(W,{text:d(u.value),label:"Copy","copied-label":"Copied"},null,8,["text"])])]),_:1})]),_:1})):V("",!0),j(A,{label:"MCP endpoint",orientation:"stack"},{default:G(({id:J})=>[b("div",oW,[j(X,{id:J,"model-value":r.value,readonly:"",size:"sm",class:"agents__mono"},null,8,["id","model-value"]),j(W,{text:r.value,label:"Copy","copied-label":"Copied"},null,8,["text"])])]),_:1}),j(T,{variant:"helper"},{default:G(()=>[...L[5]||(L[5]=[le(" Every request needs a token, even when sign-in is off. Create one below and paste it into your client, or add the endpoint as a connector and approve it in your browser. ",-1),b("a",{href:"https://docs.nubisco.io/openbridge/guide/mcp",target:"_blank",rel:"noopener"},"How to connect",-1)])]),_:1}),b("div",cW,[L[7]||(L[7]=b("h3",{class:"agents__section-title"},"Tokens",-1)),j(F,{size:"sm",variant:"primary",icon:sg,onClick:L[1]||(L[1]=J=>c.value=!0)},{default:G(()=>[...L[6]||(L[6]=[le("New token",-1)])]),_:1})]),j(re,{"stack-on-phone":"",columns:v,rows:p.value,"row-key":"id",size:"sm","aria-label":"Tokens",loading:l.value},{"cell-actions":G(({row:J})=>[j(F,{size:"sm",variant:"ghost",onClick:ae=>g(String(J.id),String(J.name))},{default:G(()=>[...L[8]||(L[8]=[le("Revoke",-1)])]),_:1},8,["onClick"])]),empty:G(()=>[j(ie,{size:"sm",title:"No tokens yet",description:"Create one to connect Claude Code or another MCP client."})]),_:1},8,["rows","loading"]),L[10]||(L[10]=b("h3",{class:"agents__section-title"},"Connected applications",-1)),j(re,{"stack-on-phone":"",columns:w,rows:_.value,"row-key":"clientId",size:"sm","aria-label":"Connected applications",loading:l.value},{"cell-actions":G(({row:J})=>[j(F,{size:"sm",variant:"ghost",onClick:ae=>$(String(J.clientId),String(J.name))},{default:G(()=>[...L[9]||(L[9]=[le(" Disconnect ",-1)])]),_:1},8,["onClick"])]),empty:G(()=>[j(ie,{size:"sm",title:"Nothing connected",description:"Applications you approve through a connector sign-in appear here."})]),_:1},8,["rows","loading"])],64)):V("",!0),o.value?(m(),he(T,{key:2,variant:"error"},{default:G(()=>[le(Z(o.value),1)]),_:1})):V("",!0),j(nW,{open:c.value,onClose:L[2]||(L[2]=J=>c.value=!1),onCreated:C},null,8,["open"])]),_:1})}}}),dW=zt(uW,[["__scopeId","data-v-522743ea"]]),hW={class:"settings-view"},fW={class:"card-header"},pW={class:"card-icon"},_W={class:"pin-row"},mW={class:"card-actions"},vW={key:0,class:"action-hint"},gW={class:"card-header"},bW={class:"card-icon"},yW={class:"update-row"},wW={class:"update-versions"},SW={class:"update-actions"},CW={class:"update-command"},kW={key:3,class:"update-error-row"},AW={class:"card-header"},MW={class:"card-icon"},$W={class:"info-title"},LW=Ne({__name:"SettingsView",setup(e){const t=Ms(),i=e0(),n=q(()=>{var x;return!!((x=i.config.value)!=null&&x.enabled&&i.user.value)}),r=c1(),s=[{label:"Light",value:"light"},{label:"Dark",value:"dark"},{label:"Match my system",value:"system"}],a=[{value:"debug",label:"Debug"},{value:"info",label:"Info"},{value:"warn",label:"Warn"},{value:"error",label:"Error"}],l=K(!1),o=K(!1),c=K(null),u=K(!1),d=K(null),h=K(!1),f=K(!1),v=K(!1),p=K(null),w=K(""),_=K(0),y=K("");let C=null;async function g(){h.value=!0,p.value=null;try{d.value=await Re.updates.check()}catch(x){p.value=String(x)}finally{h.value=!1}}function $(){const x=location.protocol==="https:"?"wss":"ws";C=new WebSocket(`${x}://${location.host}/ws/updates`),C.onmessage=F=>{try{const ie=JSON.parse(F.data);w.value=ie.stage??"",_.value=Math.round((ie.progress??0)*100),y.value=ie.message??"",ie.stage==="restarting"&&E(),ie.stage==="error"&&(p.value=ie.message,f.value=!1)}catch{}},C.onclose=()=>{f.value&&E()}}function E(){let x=0;const F=setInterval(async()=>{x++;try{await Re.health(),clearInterval(F),f.value=!1,w.value="",y.value="",d.value=null,await g()}catch{}x>60&&(clearInterval(F),f.value=!1,p.value="Timed out waiting for restart")},2e3)}async function L(){if(!f.value){f.value=!0,v.value=!1,p.value=null,w.value="downloading",y.value="Starting update...",_.value=0,$();try{await Re.updates.apply(),v.value=!0}catch(x){p.value=x instanceof Error?x.message:String(x),f.value=!1}}}async function B(){if(!f.value){f.value=!0,p.value=null,y.value="Rolling back...";try{await Re.updates.rollback(),E()}catch(x){p.value=x instanceof Error?x.message:String(x),f.value=!1}}}const T=K({name:"OpenBridge",port:8582,hapPort:51829,pincode:"031-45-154",username:"",logLevel:"info"});nt(async()=>{t.setPage("Settings");try{const x=await Re.bridge();x&&typeof x=="object"&&(T.value={name:x.name??"OpenBridge",port:x.port??8582,hapPort:x.hapPort??51829,pincode:x.pincode??"031-45-154",username:x.username??"",logLevel:x.logLevel??"info"})}catch{}g()}),Ii(()=>{C&&(C.close(),C=null)});async function X(){if(!l.value){l.value=!0,c.value=null,o.value=!1;try{const x={name:T.value.name,port:Number(T.value.port),hapPort:Number(T.value.hapPort),pincode:T.value.pincode,logLevel:T.value.logLevel};T.value.username&&(x.username=T.value.username),await Re.saveBridge(x),o.value=!0,setTimeout(()=>{o.value=!1},3e3)}catch(x){c.value=String(x)}finally{l.value=!1}}}async function W(){if(!u.value){u.value=!0;try{await Re.daemon.restart();let x=0;const F=setInterval(async()=>{x++;try{await Re.health(),clearInterval(F),location.reload()}catch{}x>60&&(clearInterval(F),u.value=!1)},1e3)}catch{u.value=!1}}}function A(){const x=()=>Math.floor(Math.random()*9)+1,F=()=>`${x()}${Math.floor(Math.random()*10)}${Math.floor(Math.random()*10)}`,ie=()=>`${Math.floor(Math.random()*10)}${Math.floor(Math.random()*10)}`;T.value.pincode=`${F()}-${ie()}-${F()}`}return(x,F)=>{const ie=Ue,re=Wr,ue=r2,J=w2,ae=Pt,ne=ba,Q=yi,oe=at,ve=Ss,fe=Cs,pe=fg,ye=Nv;return m(),M("div",hW,[j(ve,{class:"settings-card"},{default:G(()=>[b("div",fW,[b("div",pW,[j(ie,{name:de(JU),size:18},null,8,["name"])]),F[7]||(F[7]=b("div",null,[b("h2",{class:"card-title"},"Bridge"),b("p",{class:"card-subtitle"},"HomeKit bridge identity and network settings")],-1))]),j(Q,{dir:"col",gap:"sm",class:"field-grid"},{default:G(()=>[j(ue,{label:"Bridge name",hint:"Displayed in the Home app"},{default:G(()=>[j(re,{modelValue:T.value.name,"onUpdate:modelValue":F[0]||(F[0]=U=>T.value.name=U),size:"sm",placeholder:"OpenBridge"},null,8,["modelValue"])]),_:1}),j(ue,{label:"HTTP port",hint:"OpenBridge web UI & API",control:"fit"},{default:G(()=>[j(J,{modelValue:T.value.port,"onUpdate:modelValue":F[1]||(F[1]=U=>T.value.port=U),size:"sm",min:1024,max:65535},null,8,["modelValue"])]),_:1}),j(ue,{label:"HAP port",hint:"HomeKit accessory protocol port",control:"fit"},{default:G(()=>[j(J,{modelValue:T.value.hapPort,"onUpdate:modelValue":F[2]||(F[2]=U=>T.value.hapPort=U),size:"sm",min:1024,max:65535},null,8,["modelValue"])]),_:1}),j(ue,{label:"PIN code",hint:"Format: XXX-XX-XXX, used to pair with HomeKit"},{default:G(()=>[b("div",_W,[j(re,{modelValue:T.value.pincode,"onUpdate:modelValue":F[3]||(F[3]=U=>T.value.pincode=U),size:"sm",placeholder:"031-45-154"},null,8,["modelValue"]),j(ae,{variant:"ghost",size:"sm",icon:_s,title:"Generate random PIN",onClick:A})])]),_:1}),j(ue,{label:"Bridge MAC",hint:"Leave empty to auto-generate. Change this only if pairing with HomeKit fails."},{default:G(()=>[j(re,{modelValue:T.value.username,"onUpdate:modelValue":F[4]||(F[4]=U=>T.value.username=U),size:"sm",class:"mono",placeholder:"AA:BB:CC:DD:EE:FF"},null,8,["modelValue"])]),_:1}),j(ue,{label:"Log level",control:"fit"},{default:G(()=>[j(ne,{modelValue:T.value.logLevel,"onUpdate:modelValue":F[5]||(F[5]=U=>T.value.logLevel=U),size:"sm",options:a},null,8,["modelValue"])]),_:1})]),_:1}),c.value?(m(),he(oe,{key:0,variant:"error"},{default:G(()=>[le(Z(c.value),1)]),_:1})):V("",!0),b("div",mW,[j(ae,{variant:"primary",size:"sm",loading:l.value,icon:o.value?dr:Hc,onClick:X},{default:G(()=>[le(Z(o.value?"Saved!":"Save"),1)]),_:1},8,["loading","icon"]),j(ae,{variant:"secondary",size:"sm",outlined:"",loading:u.value,icon:u.value?Vo:_s,onClick:W},{default:G(()=>[le(Z(u.value?"Restarting…":"Save & Restart OpenBridge"),1)]),_:1},8,["loading","icon"]),o.value&&!u.value?(m(),M("span",vW,[j(ie,{name:de(bc),size:12},null,8,["name"]),F[8]||(F[8]=le(" Restart the daemon for changes to take effect ",-1))])):V("",!0)])]),_:1}),j(ve,{class:"settings-card"},{default:G(()=>{var U,_e;return[b("div",gW,[b("div",bW,[j(ie,{name:de(Ed),size:18},null,8,["name"])]),F[9]||(F[9]=b("div",null,[b("h2",{class:"card-title"},"Updates"),b("p",{class:"card-subtitle"},"OpenBridge daemon and UI")],-1))]),b("div",yW,[b("div",wW,[j(fe,{variant:"grey"},{default:G(()=>{var ge;return[le("Current: v"+Z(((ge=d.value)==null?void 0:ge.current)??"…"),1)]}),_:1}),d.value&&!h.value?(m(),M(Ce,{key:0},[d.value.updateAvailable?(m(),he(fe,{key:0,variant:"blue"},{default:G(()=>[le("Available: v"+Z(d.value.latest),1)]),_:1})):d.value.latest===null?(m(),he(fe,{key:1,variant:"orange"},{default:G(()=>[...F[10]||(F[10]=[le("Unable to check",-1)])]),_:1})):(m(),he(fe,{key:2,variant:"green"},{default:G(()=>[...F[11]||(F[11]=[le("Up to date",-1)])]),_:1}))],64)):V("",!0),h.value?(m(),he(fe,{key:1,variant:"grey"},{default:G(()=>[...F[12]||(F[12]=[le("Checking…",-1)])]),_:1})):V("",!0)]),b("div",SW,[j(ae,{variant:"secondary",size:"sm",outlined:"",loading:h.value,icon:_s,onClick:g},{default:G(()=>[...F[13]||(F[13]=[le(" Check ",-1)])]),_:1},8,["loading"]),(U=d.value)!=null&&U.updateAvailable&&d.value.updateMethod==="self"?(m(),he(ae,{key:0,variant:"primary",size:"sm",loading:f.value,icon:f.value?Vo:$2,onClick:L},{default:G(()=>[le(Z(f.value?"Updating…":"Install update"),1)]),_:1},8,["loading","icon"])):V("",!0)])]),f.value&&w.value?(m(),he(pe,{key:0,label:y.value,value:w.value==="downloading"&&_.value>0?_.value:void 0,max:100,status:"active",size:"sm"},null,8,["label","value"])):V("",!0),f.value&&!w.value?(m(),he(oe,{key:1,variant:"helper"},{default:G(()=>[...F[14]||(F[14]=[le(" Starting update... This page will reconnect automatically. ",-1)])]),_:1})):V("",!0),((_e=d.value)==null?void 0:_e.updateMethod)==="manual"&&d.value.updateAvailable?(m(),he(oe,{key:2,variant:"helper"},{default:G(()=>[d.value.pinnedTo?(m(),M(Ce,{key:0},[le(" This deployment is pinned to "+Z(d.value.pinnedTo)+". To move version: ",1)],64)):d.value.updateBlockedBy?(m(),M(Ce,{key:1},[le(" Self-update is not available here ("+Z(d.value.updateBlockedBy)+"). To update: ",1)],64)):(m(),M(Ce,{key:2},[le("Self-update is not available for this install. To update:")],64)),b("code",CW,Z(d.value.updateCommand),1)]),_:1})):V("",!0),p.value?(m(),M("div",kW,[j(oe,{variant:"error"},{default:G(()=>[le(Z(p.value),1)]),_:1}),v.value?(m(),he(ae,{key:0,variant:"ghost",size:"sm",onClick:B},{default:G(()=>[...F[15]||(F[15]=[le("Rollback",-1)])]),_:1})):V("",!0)])):V("",!0)]}),_:1}),j(dW),n.value?V("",!0):(m(),he(ve,{key:0,class:"settings-card"},{default:G(()=>[b("div",AW,[b("div",MW,[j(ie,{name:de(eW),size:18},null,8,["name"])]),F[16]||(F[16]=b("div",null,[b("h2",{class:"card-title"},"Appearance"),b("p",{class:"card-subtitle"},"Theme for this browser")],-1))]),j(Q,{dir:"col",gap:"sm",class:"field-grid"},{default:G(()=>[j(ue,{label:"Theme"},{default:G(()=>[j(ye,{name:"settings-theme",options:s,"model-value":de(r).theme.value,"onUpdate:modelValue":F[6]||(F[6]=U=>de(r).setTheme(U))},null,8,["model-value"])]),_:1})]),_:1})]),_:1})),j(ve,{class:"settings-card info-card"},{default:G(()=>[b("h3",$W,[j(ie,{name:de(bc),size:14},null,8,["name"]),F[17]||(F[17]=le(" How to pair with HomeKit ",-1))]),F[18]||(F[18]=b("ol",{class:"info-list"},[b("li",null,[le(" Open the "),b("strong",null,"Home"),le(" app on your iPhone or iPad ")]),b("li",null,[le(" Tap "),b("strong",null,"+"),le(" → "),b("strong",null,"Add Accessory")]),b("li",null,[le(" Scan the QR code from the Dashboard, or tap "),b("strong",null,"More options"),le(" and enter the PIN code manually ")]),b("li",null,"If you change the PIN or username, unpair first from the Home app, then re-pair")],-1))]),_:1})])}}}),EW=zt(LW,[["__scopeId","data-v-4e6145f5"]]);/**
70
+ `);function o(N){var te;const O=(te=N.health)==null?void 0:te.status;return O==="ok"?"online":O==="stale"?"stale":"offline"}function c(N){var te;const O=(te=N.health)==null?void 0:te.status;return O==="ok"?"Responding":O==="stale"?"Not responding":"No data yet"}function u(N){n.push({name:"device-detail",params:{id:N.id}})}const d=Ms(),h=K(!1),f=K([]),v=K(localStorage.getItem(Sp)==="table"?"table":"cards");function p(){v.value=v.value==="cards"?"table":"cards",localStorage.setItem(Sp,v.value)}const w=K({key:"name",direction:"asc"}),_=[{key:"name",header:"Device",sortable:!0},{key:"type",header:"Type",sortable:!0,width:160},{key:"source",header:"Source",sortable:!0,width:120},{key:"state",header:"State",sortable:!0,width:120},{key:"detail",header:"Reading",sortable:!0,width:160}],y=q(()=>{const N=[...f.value.map(ee=>({key:"native:"+ee.id,name:ee.name,type:x(g(ee)),source:"Native",state:ee.telemetry.active===void 0?"":ee.telemetry.active?"On":"Off",stateOn:!!ee.telemetry.active,detail:C(ee),icon:A(g(ee)),unhealthy:r(ee),healthTooltip:a(ee),select:()=>L(ee)})),...t.accessories.map(ee=>{const me=ue(ee);return{key:"hap:"+ee.uuid,name:ee.displayName,type:T(ee.category).label,source:"HomeKit",state:ee.reachable?me?me.value?"On":"Off":"":"Not responding",stateOn:ee.reachable&&!!(me!=null&&me.value),detail:J(ee)??"",icon:T(ee.category).icon,unhealthy:!ee.reachable,healthTooltip:ee.reachable?"":l,select:()=>E(ee)}})],O=w.value;if(!O||O.direction==="none")return N;const te=O.direction==="asc"?1:-1;return[...N].sort((ee,me)=>te*String(ee[O.key]??"").localeCompare(String(me[O.key]??"")))});function C(N){const O=N.telemetry;return N.widgetType==="energy_meter"&&O.power!==void 0?`${ne(O.power,1)} W`:N.widgetType==="thermostat"&&O.currentTemperature!==void 0?`${ne(O.currentTemperature,1)}°C`:N.widgetType==="dehumidifier"&&O.currentHumidity!==void 0?`${ne(O.currentHumidity,0)}%`:O.power!==void 0?`${ne(O.power,1)} W`:""}function g(N){return N.homekitType||N.widgetType}const $=q(()=>i.mode!=="device"||!i.selectedDevice?null:i.selectedDevice.kind==="native"?i.selectedDevice.dev.id:i.selectedDevice.acc.uuid);function E(N){$.value===N.uuid?i.close():i.openDevice({kind:"hap",acc:N})}function L(N){$.value===N.id?i.close():i.openDevice({kind:"native",dev:N})}const B={1:{label:"Other",icon:"cube"},2:{label:"Bridge",icon:"intersect"},3:{label:"Fan",icon:"fan"},4:{label:"Garage Door",icon:"garage"},5:{label:"Light",icon:"lightbulb"},6:{label:"Lock",icon:"lock"},7:{label:"Outlet",icon:"plugs"},8:{label:"Switch",icon:"toggle-right"},9:{label:"Thermostat",icon:"thermometer"},10:{label:"Sensor",icon:"pulse"},11:{label:"Security",icon:"shield"},12:{label:"Door",icon:"door"},13:{label:"Window",icon:"app-window"},14:{label:"Window Covering",icon:"rows"},15:{label:"Programm. Switch",icon:"sliders"},16:{label:"Range Extender",icon:"broadcast"},17:{label:"Camera",icon:"camera"},18:{label:"Video Doorbell",icon:"bell"},19:{label:"Air Purifier",icon:"wind"},20:{label:"Heater/Cooler",icon:"thermometer-hot"},21:{label:"Air Conditioner",icon:"snowflake"},22:{label:"Humidifier",icon:"drop"},23:{label:"Dehumidifier",icon:"drop"},26:{label:"Speaker",icon:"speaker-high"},28:{label:"Sprinkler",icon:"drop"},29:{label:"Faucet",icon:"drop"},30:{label:"Shower",icon:"drop"},32:{label:"TV",icon:"television"},34:{label:"Router",icon:"broadcast"},36:{label:"Target Control",icon:"game-controller"},38:{label:"Smart Speaker",icon:"speaker-hifi"}};function T(N){return B[N]??{label:`Category ${N}`,icon:"cube"}}const X={switch:"plugs",light:"lightbulb",thermostat:"thermometer",dehumidifier:"drop",energy_meter:"lightning",gate:"garage",sensor:"pulse",camera:"camera"},W={camera:"Camera",switch:"Switch",light:"Light",thermostat:"Thermostat",dehumidifier:"Dehumidifier",energy_meter:"Energy Meter",gate:"Gate",sensor:"Sensor"};function A(N){return X[N]??"cube"}function x(N){return W[N]??N}const F=new Set(["AccessoryInformation","0000003E-0000-1000-8000-0026BB765291","ProtocolInformation","000000A2-0000-1000-8000-0026BB765291"]),ie=new Set(["On","Active","LockTargetState","TargetDoorState"]);function re(N){return N.services.find(O=>!F.has(O.name)&&!F.has(O.uuid))}function ue(N){const O=re(N);return O?O.characteristics.find(te=>ie.has(te.name)&&te.perms.includes("pw"))??null:null}function J(N){if(!N.reachable)return"Not responding";const O=re(N);if(!O)return null;for(const ee of O.characteristics){if(ee.name==="CurrentTemperature"&&ee.value!=null)return`${Number(ee.value).toFixed(1)}°C`;if(ee.name==="CurrentRelativeHumidity"&&ee.value!=null)return`${Math.round(Number(ee.value))}%`;if(ee.name==="CurrentPosition"&&ee.value!=null)return`${Math.round(Number(ee.value))}%`;if(ee.name==="Brightness"&&ee.value!=null)return`${Math.round(Number(ee.value))}%`}const te=O.characteristics.find(ee=>ee.name==="On");return te?te.value?"On":"Off":null}async function ae(N,O){const te=re(N),ee=ue(N);if(!(!te||!ee))try{await Re.setCharacteristic(N.uuid,te.uuid,ee.uuid,O?1:0),await t.fetchAccessories()}catch(me){console.error("HAP control failed",me)}}function ne(N,O=1){if(N==null)return"—";const te=Number(N);return isFinite(te)?te.toFixed(O):String(N)}const Q=q(()=>t.accessories.length+f.value.length);async function oe(){var N;try{const O=await Re.devices();if(f.value=O.devices,i.mode==="device"&&((N=i.selectedDevice)==null?void 0:N.kind)==="native"){const te=i.selectedDevice.dev.id,ee=O.devices.find(me=>me.id===te);ee&&i.updateDevice({kind:"native",dev:ee})}}catch{}}async function ve(){h.value=!0,await Promise.all([t.fetchAccessories(),oe()]),h.value=!1}let fe=null;const pe=K({visible:!1,deviceId:"",control:"",value:null,message:""});function ye(N,O,te){return N.widgetType==="energy_meter"&&O==="active"?te?`Turn on ${N.name}? This will energise the connected circuit.`:`Turn off ${N.name}? This will cut power to the connected circuit.`:!1}async function U(N,O,te){try{await Re.controlDevice(N,O,te),await oe()}catch(ee){console.error("Control failed",ee)}}function _e(N,O,te){const ee=ye(N,O,te);ee?pe.value={visible:!0,deviceId:N.id,control:O,value:te,message:ee}:U(N.id,O,te)}function ge(){const{deviceId:N,control:O,value:te}=pe.value;pe.value.visible=!1,U(N,O,te)}function se(){pe.value.visible=!1}async function H(){var N;if(await Promise.all([t.fetchAccessories(),oe()]),i.mode==="device"&&((N=i.selectedDevice)==null?void 0:N.kind)==="hap"){const O=i.selectedDevice.acc.uuid,te=t.accessories.find(ee=>ee.uuid===O);te&&i.updateDevice({kind:"hap",acc:te})}}return nt(async()=>{d.setPage("Devices"),await H(),fe=setInterval(H,3e3)}),Ii(()=>{fe&&clearInterval(fe)}),(N,O)=>{const te=Cs,ee=Pt,me=Ue,we=o1,S=w2,k=Ss,D=b2;return m(),M("div",jz,[Q.value>0?(m(),he(an,{key:0,defer:"",to:"#ob-topbar-left"},[b("span",Kz,Z(Q.value)+" device"+Z(Q.value!==1?"s":""),1),f.value.length>0?(m(),he(te,{key:0},{default:G(()=>[le(Z(f.value.length)+" native",1)]),_:1})):V("",!0)])):V("",!0),(m(),he(an,{defer:"",to:"#ob-topbar-right"},[j(ee,{variant:"ghost",size:"sm",icon:v.value===db?hb:fb,title:v.value==="cards"?"Show as table":"Show as cards",onClick:p},null,8,["icon","title"]),j(ee,{variant:"ghost",size:"sm",icon:_s,title:"Refresh",loading:h.value,onClick:ve},null,8,["loading"])])),Q.value===0?(m(),M("div",qz,[j(me,{name:de(Od),size:40},null,8,["name"]),O[8]||(O[8]=b("p",null,"No devices registered yet.",-1)),O[9]||(O[9]=b("p",{class:"empty-hint"},[le(" Devices appear here once a platform plugin registers accessories. "),b("br"),le(" This page auto-refreshes every 3 seconds: discovery can take up to 60s. ")],-1))])):(m(),M("div",{key:2,class:"devices-layout",onClick:O[7]||(O[7]=qe(P=>de(i).close(),["self"]))},[v.value==="cards"?(m(),M("div",{key:0,class:"device-grid",onClick:O[4]||(O[4]=qe(P=>de(i).close(),["self"]))},[(m(!0),M(Ce,null,Fe(f.value,P=>(m(),he(k,{key:"native:"+P.id,class:Le(["device-card native-card",{selected:$.value===P.id,unhealthy:r(P)}]),title:r(P)?a(P):void 0,onClick:R=>L(P),onDblclick:R=>u(P)},{default:G(()=>{var R;return[O[10]||(O[10]=b("span",{class:"device-card__accent"},null,-1)),b("div",Gz,[j(me,{name:A(g(P)),size:22},null,8,["name"])]),b("div",Yz,[b("div",Xz,[r(P)?(m(),he(me,{key:0,name:de(xn),size:14,class:"name-health-icon"},null,8,["name"])):V("",!0),b("span",null,Z(P.name),1)]),b("div",Jz,Z(x(g(P))),1),b("div",Qz,[P.widgetType==="energy_meter"&&P.telemetry.power!==void 0?(m(),M("span",eU,Z(ne(P.telemetry.power,1))+" W",1)):P.widgetType==="thermostat"&&P.telemetry.currentTemperature!==void 0?(m(),M(Ce,{key:1},[b("span",tU,Z(ne(P.telemetry.currentTemperature,1))+"°C",1),P.telemetry.targetTemperature!==void 0?(m(),M("span",iU," target "+Z(ne(P.telemetry.targetTemperature,1))+"°C ",1)):V("",!0)],64)):P.widgetType==="dehumidifier"&&P.telemetry.currentHumidity!==void 0?(m(),M("span",nU,Z(ne(P.telemetry.currentHumidity,0))+"%",1)):P.telemetry.active!==void 0?(m(),M("span",{key:3,class:Le(["summary-status",P.telemetry.active?"on":"off"])},Z(P.telemetry.active?"On":"Off"),3)):V("",!0)]),P.telemetry.active!==void 0?(m(),M("div",{key:0,class:"card-controls",onClick:O[0]||(O[0]=qe(()=>{},["stop"]))},[j(we,{name:`device-active-${P.id}`,"model-value":!!P.telemetry.active,"onUpdate:modelValue":I=>_e(P,"active",I)},null,8,["name","model-value","onUpdate:modelValue"])])):V("",!0),P.widgetType==="thermostat"&&P.telemetry.targetTemperature!==void 0?(m(),M("div",{key:1,class:"card-controls",onClick:O[1]||(O[1]=qe(()=>{},["stop"]))},[j(S,{"model-value":Number(P.telemetry.targetTemperature),size:"xs",min:5,max:35,step:1,"onUpdate:modelValue":I=>I!==null&&U(P.id,"targetTemperature",I)},null,8,["model-value","onUpdate:modelValue"])])):V("",!0),P.widgetType==="dehumidifier"&&P.telemetry.targetHumidity!==void 0?(m(),M("div",{key:2,class:"card-controls",onClick:O[2]||(O[2]=qe(()=>{},["stop"]))},[j(S,{"model-value":Number(P.telemetry.targetHumidity),size:"xs",min:30,max:80,step:5,"onUpdate:modelValue":I=>I!==null&&U(P.id,"targetHumidity",I)},null,8,["model-value","onUpdate:modelValue"])])):V("",!0)]),b("div",{class:Le(["device-reachability",o(P)]),title:((R=P.health)==null?void 0:R.reason)??c(P)},null,10,rU)]}),_:2},1032,["class","title","onClick","onDblclick"]))),128)),(m(!0),M(Ce,null,Fe(de(t).accessories,P=>(m(),he(k,{key:P.uuid,class:Le(["device-card hap-card",{selected:$.value===P.uuid,unreachable:!P.reachable,unhealthy:!P.reachable}]),title:P.reachable?void 0:de(l),onClick:R=>E(P)},{default:G(()=>{var R;return[b("div",{class:Le(["device-icon hap-icon",{unreachable:!P.reachable}])},[j(me,{name:T(P.category).icon,size:22},null,8,["name"])],2),b("div",sU,[b("div",aU,[P.reachable?V("",!0):(m(),he(me,{key:0,name:de(xn),size:14,class:"name-health-icon"},null,8,["name"])),b("span",null,Z(P.displayName),1)]),b("div",lU,Z(T(P.category).label),1),J(P)?(m(),M("div",oU,[b("span",cU,Z(J(P)),1)])):V("",!0),ue(P)?(m(),M("div",{key:1,class:"card-controls",onClick:O[3]||(O[3]=qe(()=>{},["stop"]))},[j(we,{name:`hap-on-${P.uuid}`,"model-value":!!((R=ue(P))!=null&&R.value),"onUpdate:modelValue":I=>ae(P,!!I)},null,8,["name","model-value","onUpdate:modelValue"])])):V("",!0)]),b("div",{class:Le(["device-reachability",P.reachable?"online":"stale"]),title:P.reachable?"Responding":de(l)},null,10,uU)]}),_:2},1032,["class","title","onClick"]))),128))])):(m(),he(D,{key:1,columns:_,rows:y.value,"row-key":"key",size:"sm",zebra:"","sort-state":w.value,onSort:O[5]||(O[5]=P=>w.value=P),onRowClick:O[6]||(O[6]=P=>P.select())},{"cell-name":G(({row:P})=>[b("div",{class:"cell-name",title:P.healthTooltip||void 0},[j(me,{name:P.icon,size:16},null,8,["name"]),b("span",null,Z(P.name),1),P.unhealthy?(m(),he(me,{key:0,name:de(xn),size:14,class:"cell-health-icon"},null,8,["name"])):V("",!0)],8,dU)]),"cell-state":G(({row:P})=>[P.state?(m(),he(te,{key:0,variant:P.unhealthy?"orange":P.stateOn?"green":"grey"},{default:G(()=>[le(Z(P.state),1)]),_:2},1032,["variant"])):(m(),M("span",hU,"—"))]),_:1},8,["rows","sort-state"]))])),(m(),he(an,{to:"body"},[pe.value.visible?(m(),M("div",{key:0,class:"confirm-overlay",onClick:qe(se,["self"])},[b("div",fU,[b("div",pU,[j(me,{name:de(xn),size:24},null,8,["name"])]),b("p",_U,Z(pe.value.message),1),b("div",mU,[j(ee,{variant:"ghost",size:"sm",onClick:se},{default:G(()=>[...O[11]||(O[11]=[le("Cancel",-1)])]),_:1}),j(ee,{variant:"primary",size:"sm",onClick:ge},{default:G(()=>[...O[12]||(O[12]=[le("Confirm",-1)])]),_:1})])])])):V("",!0)]))])}}}),gU=zt(vU,[["__scopeId","data-v-5ae916c1"]]),bU={class:"device-detail"},yU={class:"detail-header"},wU={key:0,class:"detail-model"},SU={key:0,class:"detail-message"},CU={class:"summary-row"},kU=["onClick"],AU={class:"tile-label"},MU={class:"tile-value"},$U={class:"tile-unit"},LU={key:0,class:"detail-message"},EU={class:"chart-toolbar"},xU={class:"range-tabs"},HU=["onClick"],TU={key:0,class:"resolution-note"},NU={class:"chart-panel"},PU={key:1,class:"chart-empty"},OU={key:2,class:"chart-empty"},IU={key:2,class:"detail-message"},RU=Ne({__name:"DeviceDetailView",setup(e){const t=Jo(),i=q(()=>String(t.params.id??"")),n=K(null),r=K([]),s=K(""),a=K(!1),l=K(""),o=K(0),c=K([]),u=[{key:"1h",label:"1 hour",seconds:3600},{key:"24h",label:"24 hours",seconds:86400},{key:"7d",label:"7 days",seconds:7*86400},{key:"30d",label:"30 days",seconds:30*86400},{key:"1y",label:"1 year",seconds:365*86400}],d=K("24h"),h=q(()=>{var B;return[{label:"Devices",to:{name:"devices"}},{label:((B=n.value)==null?void 0:B.name)??i.value}]}),f=q(()=>r.value.find(B=>B.key===s.value)??null),v=q(()=>{const B=f.value;if(!B||c.value.length===0)return[];const T={name:B.label,data:c.value.map(W=>({x:new Date(W.t*1e3),y:W.value??0}))};return c.value.some(W=>W.min!==void 0&&W.min!==null&&W.min!==W.value)?[T,{name:"Min",data:c.value.map(W=>({x:new Date(W.t*1e3),y:W.min??W.value??0}))},{name:"Max",data:c.value.map(W=>({x:new Date(W.t*1e3),y:W.max??W.value??0}))}]:[T]}),p=q(()=>{if(!o.value)return"";const B=o.value;return B<60?`${B}s resolution`:B<3600?`${Math.round(B/60)} min resolution`:`${Math.round(B/3600)} h resolution`});function w(B){var W,A;const T=(A=(W=n.value)==null?void 0:W.telemetry)==null?void 0:A[B.key],X=Number(T);return Number.isFinite(X)?X:null}function _(B,T){return B===null?"—":B.toFixed(T.precision??2)}function y(B){s.value!==B&&(s.value=B,$())}function C(B){d.value!==B&&(d.value=B,$())}async function g(){try{const{devices:B}=await Re.devices(),T=B.find(X=>X.id===i.value);if(!T){l.value=`Device "${i.value}" was not found. It may have been removed, or its plugin stopped.`;return}n.value=T,r.value=T.metrics??[],!s.value&&r.value.length>0&&(s.value=r.value[0].key)}catch(B){l.value=`Could not load device: ${B.message}`}}async function $(){var W,A;if(!s.value)return;const B=u.find(x=>x.key===d.value),T=Math.floor(Date.now()/1e3),X=T-B.seconds;a.value=!0;try{const x=await Re.deviceMetrics(i.value,{metric:s.value,from:X,to:T});c.value=((W=x.series)==null?void 0:W.points)??[],o.value=((A=x.series)==null?void 0:A.resolution)??0}catch(x){l.value=`Could not load history: ${x.message}`}finally{a.value=!1}}let E=null,L=null;return nt(async()=>{await g(),await $(),E=setInterval(()=>void g(),5e3),L=setInterval(()=>void $(),3e4)}),ri(()=>{E&&clearInterval(E),L&&clearInterval(L)}),Ve(i,async()=>{n.value=null,r.value=[],s.value="",c.value=[],l.value="",await g(),await $()}),(B,T)=>{var x;const X=$v,W=at,A=eH;return m(),M("div",bU,[b("div",yU,[j(X,{items:h.value},null,8,["items"]),(x=n.value)!=null&&x.model?(m(),M("span",wU,Z(n.value.model),1)):V("",!0)]),l.value?(m(),M("div",SU,[j(W,{variant:"error"},{default:G(()=>[le(Z(l.value),1)]),_:1})])):n.value?(m(),M(Ce,{key:1},[b("div",CU,[(m(!0),M(Ce,null,Fe(r.value,F=>(m(),M("div",{key:F.key,class:Le(["summary-tile",{active:F.key===s.value}]),onClick:ie=>y(F.key)},[b("span",AU,Z(F.label),1),b("span",MU,[le(Z(_(w(F),F))+" ",1),b("span",$U,Z(F.unit),1)])],10,kU))),128))]),r.value.length===0?(m(),M("div",LU,[j(W,{variant:"helper"},{default:G(()=>[...T[0]||(T[0]=[le(" This device does not declare any metrics, so there is nothing to chart. Plugins opt in by describing their series in the device descriptor. ",-1)])]),_:1})])):(m(),M(Ce,{key:1},[b("div",EU,[b("div",xU,[(m(),M(Ce,null,Fe(u,F=>b("button",{key:F.key,class:Le(["range-tab",{active:F.key===d.value}]),onClick:ie=>C(F.key)},Z(F.label),11,HU)),64))]),p.value?(m(),M("span",TU,Z(p.value),1)):V("",!0)]),b("div",NU,[v.value.length>0&&v.value[0].data.length>0?(m(),he(A,{key:0,series:v.value,height:320,"show-legend":v.value.length>1,"show-grid":!0,"show-tooltip":!0,points:!1,curve:"smooth"},null,8,["series","show-legend"])):a.value?(m(),M("div",PU,"Loading…")):(m(),M("div",OU," No data recorded yet for this range. History starts accumulating once the device reports. "))])],64))],64)):(m(),M("div",IU,"Loading…"))])}}}),VU=zt(RU,[["__scopeId","data-v-6e2a0af1"]]),Xa=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},DU=Xa("magic-wand","0 0 256 256",'<path d="M244,152a4,4,0,0,1-4,4H220v20a4,4,0,0,1-8,0V156H192a4,4,0,0,1,0-8h20V128a4,4,0,0,1,8,0v20h20A4,4,0,0,1,244,152ZM56,68H76V88a4,4,0,0,0,8,0V68h20a4,4,0,0,0,0-8H84V40a4,4,0,0,0-8,0V60H56a4,4,0,0,0,0,8ZM184,196H172V184a4,4,0,0,0-8,0v12H152a4,4,0,0,0,0,8h12v12a4,4,0,0,0,8,0V204h12a4,4,0,0,0,0-8ZM216.48,77.17,77.17,216.49a12,12,0,0,1-17,0L39.51,195.8a12,12,0,0,1,0-17L178.83,39.51a12,12,0,0,1,17,0L216.48,60.2A12,12,0,0,1,216.48,77.17ZM170.34,112,144,85.66,45.17,184.49a4,4,0,0,0,0,5.65l20.68,20.69a4,4,0,0,0,5.66,0Zm40.49-46.14L190.14,45.17a4,4,0,0,0-5.66,0L149.65,80,176,106.34l34.83-34.83A4,4,0,0,0,210.83,65.86Z"/>'),ZU=Xa("magic-wand","0 0 256 256",'<path d="M246,152a6,6,0,0,1-6,6H222v18a6,6,0,0,1-12,0V158H192a6,6,0,0,1,0-12h18V128a6,6,0,0,1,12,0v18h18A6,6,0,0,1,246,152ZM56,70H74V88a6,6,0,0,0,12,0V70h18a6,6,0,0,0,0-12H86V40a6,6,0,0,0-12,0V58H56a6,6,0,0,0,0,12ZM184,194H174V184a6,6,0,0,0-12,0v10H152a6,6,0,0,0,0,12h10v10a6,6,0,0,0,12,0V206h10a6,6,0,0,0,0-12ZM217.9,78.59,78.58,217.9a14,14,0,0,1-19.8,0L38.09,197.21a14,14,0,0,1,0-19.8L177.41,38.1a14,14,0,0,1,19.8,0L217.9,58.79A14,14,0,0,1,217.9,78.59ZM167.51,112,144,88.49,46.58,185.9a2,2,0,0,0,0,2.83l20.69,20.68a2,2,0,0,0,2.82,0h0Zm41.9-44.73L188.73,46.59a2,2,0,0,0-2.83,0L152.48,80,176,103.52,209.41,70.1A2,2,0,0,0,209.41,67.27Z"/>'),Cp=Xa("magic-wand","0 0 256 256",'<path d="M48,64a8,8,0,0,1,8-8H72V40a8,8,0,0,1,16,0V56h16a8,8,0,0,1,0,16H88V88a8,8,0,0,1-16,0V72H56A8,8,0,0,1,48,64ZM184,192h-8v-8a8,8,0,0,0-16,0v8h-8a8,8,0,0,0,0,16h8v8a8,8,0,0,0,16,0v-8h8a8,8,0,0,0,0-16Zm56-48H224V128a8,8,0,0,0-16,0v16H192a8,8,0,0,0,0,16h16v16a8,8,0,0,0,16,0V160h16a8,8,0,0,0,0-16ZM219.31,80,80,219.31a16,16,0,0,1-22.62,0L36.68,198.63a16,16,0,0,1,0-22.63L176,36.69a16,16,0,0,1,22.63,0l20.68,20.68A16,16,0,0,1,219.31,80Zm-54.63,32L144,91.31l-96,96L68.68,208ZM208,68.69,187.31,48l-32,32L176,100.69Z"/>'),BU=Xa("magic-wand","0 0 256 256",'<path d="M252,152a12,12,0,0,1-12,12H228v12a12,12,0,0,1-24,0V164H192a12,12,0,0,1,0-24h12V128a12,12,0,0,1,24,0v12h12A12,12,0,0,1,252,152ZM56,76H68V88a12,12,0,0,0,24,0V76h12a12,12,0,1,0,0-24H92V40a12,12,0,0,0-24,0V52H56a12,12,0,0,0,0,24ZM184,188h-4v-4a12,12,0,0,0-24,0v4h-4a12,12,0,0,0,0,24h4v4a12,12,0,0,0,24,0v-4h4a12,12,0,0,0,0-24ZM222.14,82.83,82.82,222.14a20,20,0,0,1-28.28,0L33.85,201.46a20,20,0,0,1,0-28.29L173.17,33.86a20,20,0,0,1,28.28,0l20.69,20.68A20,20,0,0,1,222.14,82.83ZM159,112,144,97,53.65,187.31l15,15Zm43.31-43.31-15-15L161,80l15,15Z"/>'),FU=Xa("magic-wand","0 0 256 256",'<path d="M248,152a8,8,0,0,1-8,8H224v16a8,8,0,0,1-16,0V160H192a8,8,0,0,1,0-16h16V128a8,8,0,0,1,16,0v16h16A8,8,0,0,1,248,152ZM56,72H72V88a8,8,0,0,0,16,0V72h16a8,8,0,0,0,0-16H88V40a8,8,0,0,0-16,0V56H56a8,8,0,0,0,0,16ZM184,192h-8v-8a8,8,0,0,0-16,0v8h-8a8,8,0,0,0,0,16h8v8a8,8,0,0,0,16,0v-8h8a8,8,0,0,0,0-16ZM219.31,80,80,219.31a16,16,0,0,1-22.62,0L36.68,198.63a16,16,0,0,1,0-22.63L176,36.69a16,16,0,0,1,22.63,0l20.68,20.68A16,16,0,0,1,219.31,80ZM208,68.69,187.31,48l-32,32L176,100.69Z"/>'),zU=Xa("magic-wand","0 0 256 256",'<path d="M176,112,74.34,213.66a8,8,0,0,1-11.31,0L42.34,193a8,8,0,0,1,0-11.31L144,80Z" opacity="0.2"/><path d="M248,152a8,8,0,0,1-8,8H224v16a8,8,0,0,1-16,0V160H192a8,8,0,0,1,0-16h16V128a8,8,0,0,1,16,0v16h16A8,8,0,0,1,248,152ZM56,72H72V88a8,8,0,0,0,16,0V72h16a8,8,0,0,0,0-16H88V40a8,8,0,0,0-16,0V56H56a8,8,0,0,0,0,16ZM184,192h-8v-8a8,8,0,0,0-16,0v8h-8a8,8,0,0,0,0,16h8v8a8,8,0,0,0,16,0v-8h8a8,8,0,0,0,0-16ZM219.31,80,80,219.31a16,16,0,0,1-22.62,0L36.68,198.63a16,16,0,0,1,0-22.63L176,36.69a16,16,0,0,1,22.63,0l20.68,20.68A16,16,0,0,1,219.31,80Zm-54.63,32L144,91.31l-96,96L68.68,208ZM208,68.69,187.31,48l-32,32L176,100.69Z"/>'),UU="magic-wand",WU=Object.freeze(Object.defineProperty({__proto__:null,bold:BU,default:Cp,duotone:zU,fill:FU,glyphName:UU,light:ZU,regular:Cp,thin:DU},Symbol.toStringTag,{value:"Module"})),jU={class:"config-view"},KU={key:0,class:"error-banner"},qU={key:1,class:"loading-state"},GU=Ne({__name:"ConfigView",setup(e){const t=Ms(),{resolved:i}=c1(),n=K(null),r=zn(null),s=K(!1),a=K(!1),l=K(null),o=K(!0);nt(async()=>{t.setPage("Config",void 0,{fullBleed:!0});let d="{}";try{d=(await Re.config.get()).content}catch(f){l.value=`Failed to load config: ${f}`}finally{o.value=!1}const h=await cb.init();h.languages.json.jsonDefaults.setDiagnosticsOptions({validate:!0,schemas:[{uri:"openbridge://config-schema",fileMatch:["*"],schema:{type:"object",properties:{bridge:{type:"object",description:"Bridge configuration",properties:{name:{type:"string",description:"Bridge display name"},port:{type:"number",description:"HTTP API port (default 8582)"},hapPort:{type:"number",description:"HomeKit HAP port (default 51829)"},pincode:{type:"string",description:"HomeKit pairing PIN (format: XXX-XX-XXX)"},username:{type:"string",description:"HAP username (MAC address format)"},logLevel:{type:"string",enum:["debug","info","warn","error"]}}},platforms:{type:"array",description:"Homebridge-compatible platform plugins",items:{type:"object",required:["platform"],properties:{platform:{type:"string",description:"Platform identifier"},plugin:{type:"string",description:"Absolute path to the plugin JS file"},enabled:{type:"boolean",default:!0}},additionalProperties:!0}},plugins:{type:"array",description:"Native OpenBridge plugins",items:{type:"object",required:["name"],properties:{name:{type:"string"},path:{type:"string"},enabled:{type:"boolean",default:!0},config:{type:"object"}}}}}}}]}),n.value&&(Ve(i,f=>h.editor.setTheme(f==="dark"?"vs-dark":"vs")),r.value=h.editor.create(n.value,{value:d,language:"json",theme:i.value==="dark"?"vs-dark":"vs",fontSize:13,fontFamily:'"MesloLGS NF", monospace',minimap:{enabled:!0},scrollBeyondLastLine:!1,formatOnPaste:!0,formatOnType:!0,tabSize:2,automaticLayout:!0,wordWrap:"off",bracketPairColorization:{enabled:!0},guides:{bracketPairs:!0},lineNumbers:"on",renderLineHighlight:"all",smoothScrolling:!0}))}),ri(()=>{var d;(d=r.value)==null||d.dispose()});async function c(){var d;if(!s.value){s.value=!0,l.value=null,a.value=!1;try{const h=((d=r.value)==null?void 0:d.getValue())??"";await Re.config.save(h),a.value=!0,setTimeout(()=>{a.value=!1},2500)}catch(h){l.value=String(h)}finally{s.value=!1}}}function u(){var d,h;(h=(d=r.value)==null?void 0:d.getAction("editor.action.formatDocument"))==null||h.run()}return(d,h)=>{const f=Pt,v=Ue;return m(),M("div",jU,[(m(),he(an,{defer:"",to:"#ob-topbar-left"},[h[0]||(h[0]=b("span",{class:"config-path"},"~/.openbridge/config.json",-1))])),(m(),he(an,{defer:"",to:"#ob-topbar-right"},[j(f,{variant:"ghost",size:"sm",icon:WU,title:"Format JSON",onClick:u},{default:G(()=>[...h[1]||(h[1]=[le("Format",-1)])]),_:1}),j(f,{variant:"primary",size:"sm",icon:a.value?dr:Hc,loading:s.value,disabled:s.value,title:"Changes take effect after restarting the daemon",onClick:c},{default:G(()=>[le(Z(a.value?"Saved!":s.value?"Saving…":"Save"),1)]),_:1},8,["icon","loading","disabled"])])),l.value?(m(),M("div",KU,[j(v,{name:de(xn),size:14},null,8,["name"]),le(" "+Z(l.value),1)])):V("",!0),o.value?(m(),M("div",qU,[j(v,{name:de(ra),size:28},null,8,["name"]),h[2]||(h[2]=b("span",null,"Loading config...",-1))])):(m(),M("div",{key:2,ref_key:"editorContainer",ref:n,class:"editor-container"},null,512))])}}}),YU=zt(GU,[["__scopeId","data-v-483debe2"]]),XU=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},JU=XU("bridge","0 0 256 256",'<path d="M232,160H200V101.34a71.89,71.89,0,0,0,29,21.42,8,8,0,0,0,6-14.83A55.78,55.78,0,0,1,200,56a8,8,0,0,0-16,0A56,56,0,0,1,72,56a8,8,0,0,0-16,0,55.78,55.78,0,0,1-35,51.93,8,8,0,0,0,6,14.83,71.89,71.89,0,0,0,29-21.42V160H24a8,8,0,0,0,0,16H56v24a8,8,0,0,0,16,0V176H184v24a8,8,0,0,0,16,0V176h32a8,8,0,0,0,0-16Zm-88-33.8V160H112V126.2a72,72,0,0,0,32,0Zm-72-25a72.47,72.47,0,0,0,24,19.27V160H72ZM160,160V120.48a72.47,72.47,0,0,0,24-19.27V160Z"/>'),QU=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},eW=QU("palette","0 0 256 256",'<path d="M200.77,53.89A103.27,103.27,0,0,0,128,24h-1.07A104,104,0,0,0,24,128c0,43,26.58,79.06,69.36,94.17A32,32,0,0,0,136,192a16,16,0,0,1,16-16h46.21a31.81,31.81,0,0,0,31.2-24.88,104.43,104.43,0,0,0,2.59-24A103.28,103.28,0,0,0,200.77,53.89Zm13,93.71A15.89,15.89,0,0,1,198.21,160H152a32,32,0,0,0-32,32,16,16,0,0,1-21.31,15.07C62.49,194.3,40,164,40,128a88,88,0,0,1,87.09-88h.9a88.35,88.35,0,0,1,88,87.25A88.86,88.86,0,0,1,213.81,147.6ZM140,76a12,12,0,1,1-12-12A12,12,0,0,1,140,76ZM96,100A12,12,0,1,1,84,88,12,12,0,0,1,96,100Zm0,56a12,12,0,1,1-12-12A12,12,0,0,1,96,156Zm88-56a12,12,0,1,1-12-12A12,12,0,0,1,184,100Z"/>'),tW=(e,t,i)=>{const n=r=>Ee("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:t,fill:"currentColor",...r,innerHTML:i});return n.displayName="NbGlyph",n.glyphName=e,n},iW=tW("robot","0 0 256 256",'<path d="M200,48H136V16a8,8,0,0,0-16,0V48H56A32,32,0,0,0,24,80V192a32,32,0,0,0,32,32H200a32,32,0,0,0,32-32V80A32,32,0,0,0,200,48Zm16,144a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V80A16,16,0,0,1,56,64H200a16,16,0,0,1,16,16Zm-52-56H92a28,28,0,0,0,0,56h72a28,28,0,0,0,0-56Zm-24,16v24H116V152ZM80,164a12,12,0,0,1,12-12h8v24H92A12,12,0,0,1,80,164Zm84,12h-8V152h8a12,12,0,0,1,0,24ZM72,108a12,12,0,1,1,12,12A12,12,0,0,1,72,108Zm88,0a12,12,0,1,1,12,12A12,12,0,0,1,160,108Z"/>'),nW=Ne({__name:"NewTokenModal",props:{open:{type:Boolean}},emits:["close","created"],setup(e,{emit:t}){const i=e,n=t,r=K(""),s=K("read"),a=K(!1),l=K(""),o=K(),c=K(null);Ve(()=>i.open,h=>{h&&(r.value="",s.value="read",l.value="",o.value=void 0,requestAnimationFrame(()=>{var f;return(f=c.value)==null?void 0:f.focus()}))});function u(){o.value=r.value.trim()?void 0:"Give the token a name you will recognise later"}async function d(){if(u(),!o.value){a.value=!0,l.value="";try{const{token:h}=await Re.access.createToken(r.value.trim(),s.value);n("created",h)}catch(h){l.value=h.message}finally{a.value=!1}}}return(h,f)=>{const v=ks,p=Wr,w=ba,_=xN,y=Pt,C=dg;return m(),he(C,{"close-appearance":"button",open:e.open,title:"New token",size:"sm","close-on-overlay":!r.value,onClose:f[3]||(f[3]=g=>n("close"))},{footer:G(()=>[j(y,{type:"button",variant:"secondary",onClick:f[2]||(f[2]=g=>n("close"))},{default:G(()=>[...f[4]||(f[4]=[le("Cancel",-1)])]),_:1}),j(y,{type:"submit",form:"new-token-form",variant:"primary",loading:a.value},{default:G(()=>[...f[5]||(f[5]=[le("Create token",-1)])]),_:1},8,["loading"])]),default:G(()=>[j(_,{id:"new-token-form",onSubmit:qe(d,["prevent"])},{default:G(()=>[l.value?(m(),he(v,{key:0,status:"error",variant:"inline",title:l.value},null,8,["title"])):V("",!0),j(p,{id:"new-token-name",ref_key:"nameInput",ref:c,modelValue:r.value,"onUpdate:modelValue":f[0]||(f[0]=g=>r.value=g),label:"Name",placeholder:"Claude on my laptop",error:o.value,onBlur:u},null,8,["modelValue","error"]),j(w,{id:"new-token-access",modelValue:s.value,"onUpdate:modelValue":f[1]||(f[1]=g=>s.value=g),label:"Access",options:[{label:"Read only: devices, history, events and logs",value:"read"},{label:"Read and control: can also operate devices",value:"control"}]},null,8,["modelValue"])]),_:1})]),_:1},8,["open","close-on-overlay"])}}}),rW={class:"agents__header"},sW={class:"agents__icon"},aW={class:"agents__reveal"},lW={class:"agents__reveal"},oW={class:"agents__reveal"},cW={class:"agents__section-head"},uW=Ne({__name:"AgentAccessPanel",setup(e){const t=Sg(),i=N2(),n=K(null),r=K(`${location.origin}/mcp`),s=K([]),a=K([]),l=K(!1),o=K(""),c=K(!1),u=K(""),d=E=>`claude mcp add --transport http openbridge ${r.value} --header "Authorization: Bearer ${E}"`,h=E=>E==="control"?"Read and control":"Read only",f=E=>E?new Date(E).toLocaleString():"Never",v=[{key:"name",header:"Name",primary:!0},{key:"access",header:"Access"},{key:"created",header:"Created",phoneMeta:!0},{key:"lastUsed",header:"Last used"},{key:"actions",header:"",align:"right"}],p=q(()=>s.value.map(E=>({id:E.id,name:E.owner?`${E.name} (${E.owner})`:E.name,access:h(E.access),created:f(E.createdAt),lastUsed:f(E.lastUsedAt)}))),w=[{key:"name",header:"Application",primary:!0},{key:"access",header:"Access"},{key:"connected",header:"Connected",phoneMeta:!0},{key:"lastUsed",header:"Last used"},{key:"actions",header:"",align:"right"}],_=q(()=>a.value.map(E=>({clientId:E.clientId,name:E.owners.length?`${E.name} (${E.owners.join(", ")})`:E.name,access:h(E.access),connected:f(E.connectedAt),lastUsed:f(E.lastUsedAt)})));async function y(){l.value=!0;try{const E=await Re.access.get();n.value=E.enabled,E.enabled&&(r.value=E.endpoint,s.value=E.tokens,a.value=E.connections),o.value=""}catch(E){o.value=E.message}finally{l.value=!1}}nt(y);function C(E){c.value=!1,u.value=E,y()}async function g(E,L){if(await t({title:"Revoke token",subjectLabel:"Token",subject:L,message:"Anything using this token loses access immediately.",confirmLabel:"Revoke"}))try{await Re.access.revokeToken(E),i.success("Token revoked"),await y()}catch(T){i.error(T.message,{title:"Could not revoke"})}}async function $(E,L){if(await t({title:"Disconnect application",subjectLabel:"Application",subject:L,message:"Every sign-in this application holds stops working, including its refresh tokens.",confirmLabel:"Disconnect"}))try{await Re.access.revokeConnection(E),i.success(`${L} disconnected`),await y()}catch(T){i.error(T.message,{title:"Could not disconnect"})}}return(E,L)=>{const B=Ue,T=at,X=Wr,W=FS,A=r2,x=ks,F=Pt,ie=Pk,re=b2,ue=Ss;return m(),he(ue,{class:"agents"},{default:G(()=>[b("div",rW,[b("div",sW,[j(B,{name:de(iW),size:18},null,8,["name"])]),L[3]||(L[3]=b("div",null,[b("h2",{class:"agents__title"},"AI agents"),b("p",{class:"agents__subtitle"}," Let Claude and other MCP clients read your devices and their history, and with control access, operate them. ")],-1))]),n.value===!1?(m(),he(T,{key:0,variant:"helper"},{default:G(()=>[...L[4]||(L[4]=[le(" The MCP endpoint is off on this bridge. Start OpenBridge with ",-1),b("code",null,"OPENBRIDGE_MCP=on",-1),le(" in its environment to turn it on, then create a token here. ",-1),b("a",{href:"https://docs.nubisco.io/openbridge/guide/mcp",target:"_blank",rel:"noopener"},"How to turn it on",-1)])]),_:1})):V("",!0),n.value?(m(),M(Ce,{key:1},[u.value?(m(),he(x,{key:0,status:"info",variant:"inline",title:"Copy this token now. It is not shown again.",dismissible:"",onClose:L[0]||(L[0]=J=>u.value="")},{default:G(()=>[j(A,{label:"Token",orientation:"stack"},{default:G(({id:J})=>[b("div",aW,[j(X,{id:J,"model-value":u.value,readonly:"",size:"sm",class:"agents__mono"},null,8,["id","model-value"]),j(W,{text:u.value,label:"Copy","copied-label":"Copied"},null,8,["text"])])]),_:1}),j(A,{label:"Connect Claude Code",orientation:"stack"},{default:G(({id:J})=>[b("div",lW,[j(X,{id:J,"model-value":d(u.value),readonly:"",size:"sm",class:"agents__mono"},null,8,["id","model-value"]),j(W,{text:d(u.value),label:"Copy","copied-label":"Copied"},null,8,["text"])])]),_:1})]),_:1})):V("",!0),j(A,{label:"MCP endpoint",orientation:"stack"},{default:G(({id:J})=>[b("div",oW,[j(X,{id:J,"model-value":r.value,readonly:"",size:"sm",class:"agents__mono"},null,8,["id","model-value"]),j(W,{text:r.value,label:"Copy","copied-label":"Copied"},null,8,["text"])])]),_:1}),j(T,{variant:"helper"},{default:G(()=>[...L[5]||(L[5]=[le(" Every request needs a token, even when sign-in is off. Create one below and paste it into your client, or add the endpoint as a connector and approve it in your browser. claude.ai and the Claude app connect from the cloud, so their connectors need this bridge on an https address reachable from the internet. ",-1),b("a",{href:"https://docs.nubisco.io/openbridge/guide/mcp",target:"_blank",rel:"noopener"},"How to connect",-1)])]),_:1}),b("div",cW,[L[7]||(L[7]=b("h3",{class:"agents__section-title"},"Tokens",-1)),j(F,{size:"sm",variant:"primary",icon:sg,onClick:L[1]||(L[1]=J=>c.value=!0)},{default:G(()=>[...L[6]||(L[6]=[le("New token",-1)])]),_:1})]),j(re,{"stack-on-phone":"",columns:v,rows:p.value,"row-key":"id",size:"sm","aria-label":"Tokens",loading:l.value},{"cell-actions":G(({row:J})=>[j(F,{size:"sm",variant:"ghost",onClick:ae=>g(String(J.id),String(J.name))},{default:G(()=>[...L[8]||(L[8]=[le("Revoke",-1)])]),_:1},8,["onClick"])]),empty:G(()=>[j(ie,{size:"sm",title:"No tokens yet",description:"Create one to connect Claude Code or another MCP client."})]),_:1},8,["rows","loading"]),L[10]||(L[10]=b("h3",{class:"agents__section-title"},"Connected applications",-1)),j(re,{"stack-on-phone":"",columns:w,rows:_.value,"row-key":"clientId",size:"sm","aria-label":"Connected applications",loading:l.value},{"cell-actions":G(({row:J})=>[j(F,{size:"sm",variant:"ghost",onClick:ae=>$(String(J.clientId),String(J.name))},{default:G(()=>[...L[9]||(L[9]=[le(" Disconnect ",-1)])]),_:1},8,["onClick"])]),empty:G(()=>[j(ie,{size:"sm",title:"Nothing connected",description:"Applications you approve through a connector sign-in appear here."})]),_:1},8,["rows","loading"])],64)):V("",!0),o.value?(m(),he(T,{key:2,variant:"error"},{default:G(()=>[le(Z(o.value),1)]),_:1})):V("",!0),j(nW,{open:c.value,onClose:L[2]||(L[2]=J=>c.value=!1),onCreated:C},null,8,["open"])]),_:1})}}}),dW=zt(uW,[["__scopeId","data-v-ab227c4c"]]),hW={class:"settings-view"},fW={class:"card-header"},pW={class:"card-icon"},_W={class:"pin-row"},mW={class:"card-actions"},vW={key:0,class:"action-hint"},gW={class:"card-header"},bW={class:"card-icon"},yW={class:"update-row"},wW={class:"update-versions"},SW={class:"update-actions"},CW={class:"update-command"},kW={key:3,class:"update-error-row"},AW={class:"card-header"},MW={class:"card-icon"},$W={class:"info-title"},LW=Ne({__name:"SettingsView",setup(e){const t=Ms(),i=e0(),n=q(()=>{var x;return!!((x=i.config.value)!=null&&x.enabled&&i.user.value)}),r=c1(),s=[{label:"Light",value:"light"},{label:"Dark",value:"dark"},{label:"Match my system",value:"system"}],a=[{value:"debug",label:"Debug"},{value:"info",label:"Info"},{value:"warn",label:"Warn"},{value:"error",label:"Error"}],l=K(!1),o=K(!1),c=K(null),u=K(!1),d=K(null),h=K(!1),f=K(!1),v=K(!1),p=K(null),w=K(""),_=K(0),y=K("");let C=null;async function g(){h.value=!0,p.value=null;try{d.value=await Re.updates.check()}catch(x){p.value=String(x)}finally{h.value=!1}}function $(){const x=location.protocol==="https:"?"wss":"ws";C=new WebSocket(`${x}://${location.host}/ws/updates`),C.onmessage=F=>{try{const ie=JSON.parse(F.data);w.value=ie.stage??"",_.value=Math.round((ie.progress??0)*100),y.value=ie.message??"",ie.stage==="restarting"&&E(),ie.stage==="error"&&(p.value=ie.message,f.value=!1)}catch{}},C.onclose=()=>{f.value&&E()}}function E(){let x=0;const F=setInterval(async()=>{x++;try{await Re.health(),clearInterval(F),f.value=!1,w.value="",y.value="",d.value=null,await g()}catch{}x>60&&(clearInterval(F),f.value=!1,p.value="Timed out waiting for restart")},2e3)}async function L(){if(!f.value){f.value=!0,v.value=!1,p.value=null,w.value="downloading",y.value="Starting update...",_.value=0,$();try{await Re.updates.apply(),v.value=!0}catch(x){p.value=x instanceof Error?x.message:String(x),f.value=!1}}}async function B(){if(!f.value){f.value=!0,p.value=null,y.value="Rolling back...";try{await Re.updates.rollback(),E()}catch(x){p.value=x instanceof Error?x.message:String(x),f.value=!1}}}const T=K({name:"OpenBridge",port:8582,hapPort:51829,pincode:"031-45-154",username:"",logLevel:"info"});nt(async()=>{t.setPage("Settings");try{const x=await Re.bridge();x&&typeof x=="object"&&(T.value={name:x.name??"OpenBridge",port:x.port??8582,hapPort:x.hapPort??51829,pincode:x.pincode??"031-45-154",username:x.username??"",logLevel:x.logLevel??"info"})}catch{}g()}),Ii(()=>{C&&(C.close(),C=null)});async function X(){if(!l.value){l.value=!0,c.value=null,o.value=!1;try{const x={name:T.value.name,port:Number(T.value.port),hapPort:Number(T.value.hapPort),pincode:T.value.pincode,logLevel:T.value.logLevel};T.value.username&&(x.username=T.value.username),await Re.saveBridge(x),o.value=!0,setTimeout(()=>{o.value=!1},3e3)}catch(x){c.value=String(x)}finally{l.value=!1}}}async function W(){if(!u.value){u.value=!0;try{await Re.daemon.restart();let x=0;const F=setInterval(async()=>{x++;try{await Re.health(),clearInterval(F),location.reload()}catch{}x>60&&(clearInterval(F),u.value=!1)},1e3)}catch{u.value=!1}}}function A(){const x=()=>Math.floor(Math.random()*9)+1,F=()=>`${x()}${Math.floor(Math.random()*10)}${Math.floor(Math.random()*10)}`,ie=()=>`${Math.floor(Math.random()*10)}${Math.floor(Math.random()*10)}`;T.value.pincode=`${F()}-${ie()}-${F()}`}return(x,F)=>{const ie=Ue,re=Wr,ue=r2,J=w2,ae=Pt,ne=ba,Q=yi,oe=at,ve=Ss,fe=Cs,pe=fg,ye=Nv;return m(),M("div",hW,[j(ve,{class:"settings-card"},{default:G(()=>[b("div",fW,[b("div",pW,[j(ie,{name:de(JU),size:18},null,8,["name"])]),F[7]||(F[7]=b("div",null,[b("h2",{class:"card-title"},"Bridge"),b("p",{class:"card-subtitle"},"HomeKit bridge identity and network settings")],-1))]),j(Q,{dir:"col",gap:"sm",class:"field-grid"},{default:G(()=>[j(ue,{label:"Bridge name",hint:"Displayed in the Home app"},{default:G(()=>[j(re,{modelValue:T.value.name,"onUpdate:modelValue":F[0]||(F[0]=U=>T.value.name=U),size:"sm",placeholder:"OpenBridge"},null,8,["modelValue"])]),_:1}),j(ue,{label:"HTTP port",hint:"OpenBridge web UI & API",control:"fit"},{default:G(()=>[j(J,{modelValue:T.value.port,"onUpdate:modelValue":F[1]||(F[1]=U=>T.value.port=U),size:"sm",min:1024,max:65535},null,8,["modelValue"])]),_:1}),j(ue,{label:"HAP port",hint:"HomeKit accessory protocol port",control:"fit"},{default:G(()=>[j(J,{modelValue:T.value.hapPort,"onUpdate:modelValue":F[2]||(F[2]=U=>T.value.hapPort=U),size:"sm",min:1024,max:65535},null,8,["modelValue"])]),_:1}),j(ue,{label:"PIN code",hint:"Format: XXX-XX-XXX, used to pair with HomeKit"},{default:G(()=>[b("div",_W,[j(re,{modelValue:T.value.pincode,"onUpdate:modelValue":F[3]||(F[3]=U=>T.value.pincode=U),size:"sm",placeholder:"031-45-154"},null,8,["modelValue"]),j(ae,{variant:"ghost",size:"sm",icon:_s,title:"Generate random PIN",onClick:A})])]),_:1}),j(ue,{label:"Bridge MAC",hint:"Leave empty to auto-generate. Change this only if pairing with HomeKit fails."},{default:G(()=>[j(re,{modelValue:T.value.username,"onUpdate:modelValue":F[4]||(F[4]=U=>T.value.username=U),size:"sm",class:"mono",placeholder:"AA:BB:CC:DD:EE:FF"},null,8,["modelValue"])]),_:1}),j(ue,{label:"Log level",control:"fit"},{default:G(()=>[j(ne,{modelValue:T.value.logLevel,"onUpdate:modelValue":F[5]||(F[5]=U=>T.value.logLevel=U),size:"sm",options:a},null,8,["modelValue"])]),_:1})]),_:1}),c.value?(m(),he(oe,{key:0,variant:"error"},{default:G(()=>[le(Z(c.value),1)]),_:1})):V("",!0),b("div",mW,[j(ae,{variant:"primary",size:"sm",loading:l.value,icon:o.value?dr:Hc,onClick:X},{default:G(()=>[le(Z(o.value?"Saved!":"Save"),1)]),_:1},8,["loading","icon"]),j(ae,{variant:"secondary",size:"sm",outlined:"",loading:u.value,icon:u.value?Vo:_s,onClick:W},{default:G(()=>[le(Z(u.value?"Restarting…":"Save & Restart OpenBridge"),1)]),_:1},8,["loading","icon"]),o.value&&!u.value?(m(),M("span",vW,[j(ie,{name:de(bc),size:12},null,8,["name"]),F[8]||(F[8]=le(" Restart the daemon for changes to take effect ",-1))])):V("",!0)])]),_:1}),j(ve,{class:"settings-card"},{default:G(()=>{var U,_e;return[b("div",gW,[b("div",bW,[j(ie,{name:de(Ed),size:18},null,8,["name"])]),F[9]||(F[9]=b("div",null,[b("h2",{class:"card-title"},"Updates"),b("p",{class:"card-subtitle"},"OpenBridge daemon and UI")],-1))]),b("div",yW,[b("div",wW,[j(fe,{variant:"grey"},{default:G(()=>{var ge;return[le("Current: v"+Z(((ge=d.value)==null?void 0:ge.current)??"…"),1)]}),_:1}),d.value&&!h.value?(m(),M(Ce,{key:0},[d.value.updateAvailable?(m(),he(fe,{key:0,variant:"blue"},{default:G(()=>[le("Available: v"+Z(d.value.latest),1)]),_:1})):d.value.latest===null?(m(),he(fe,{key:1,variant:"orange"},{default:G(()=>[...F[10]||(F[10]=[le("Unable to check",-1)])]),_:1})):(m(),he(fe,{key:2,variant:"green"},{default:G(()=>[...F[11]||(F[11]=[le("Up to date",-1)])]),_:1}))],64)):V("",!0),h.value?(m(),he(fe,{key:1,variant:"grey"},{default:G(()=>[...F[12]||(F[12]=[le("Checking…",-1)])]),_:1})):V("",!0)]),b("div",SW,[j(ae,{variant:"secondary",size:"sm",outlined:"",loading:h.value,icon:_s,onClick:g},{default:G(()=>[...F[13]||(F[13]=[le(" Check ",-1)])]),_:1},8,["loading"]),(U=d.value)!=null&&U.updateAvailable&&d.value.updateMethod==="self"?(m(),he(ae,{key:0,variant:"primary",size:"sm",loading:f.value,icon:f.value?Vo:$2,onClick:L},{default:G(()=>[le(Z(f.value?"Updating…":"Install update"),1)]),_:1},8,["loading","icon"])):V("",!0)])]),f.value&&w.value?(m(),he(pe,{key:0,label:y.value,value:w.value==="downloading"&&_.value>0?_.value:void 0,max:100,status:"active",size:"sm"},null,8,["label","value"])):V("",!0),f.value&&!w.value?(m(),he(oe,{key:1,variant:"helper"},{default:G(()=>[...F[14]||(F[14]=[le(" Starting update... This page will reconnect automatically. ",-1)])]),_:1})):V("",!0),((_e=d.value)==null?void 0:_e.updateMethod)==="manual"&&d.value.updateAvailable?(m(),he(oe,{key:2,variant:"helper"},{default:G(()=>[d.value.pinnedTo?(m(),M(Ce,{key:0},[le(" This deployment is pinned to "+Z(d.value.pinnedTo)+". To move version: ",1)],64)):d.value.updateBlockedBy?(m(),M(Ce,{key:1},[le(" Self-update is not available here ("+Z(d.value.updateBlockedBy)+"). To update: ",1)],64)):(m(),M(Ce,{key:2},[le("Self-update is not available for this install. To update:")],64)),b("code",CW,Z(d.value.updateCommand),1)]),_:1})):V("",!0),p.value?(m(),M("div",kW,[j(oe,{variant:"error"},{default:G(()=>[le(Z(p.value),1)]),_:1}),v.value?(m(),he(ae,{key:0,variant:"ghost",size:"sm",onClick:B},{default:G(()=>[...F[15]||(F[15]=[le("Rollback",-1)])]),_:1})):V("",!0)])):V("",!0)]}),_:1}),j(dW),n.value?V("",!0):(m(),he(ve,{key:0,class:"settings-card"},{default:G(()=>[b("div",AW,[b("div",MW,[j(ie,{name:de(eW),size:18},null,8,["name"])]),F[16]||(F[16]=b("div",null,[b("h2",{class:"card-title"},"Appearance"),b("p",{class:"card-subtitle"},"Theme for this browser")],-1))]),j(Q,{dir:"col",gap:"sm",class:"field-grid"},{default:G(()=>[j(ue,{label:"Theme"},{default:G(()=>[j(ye,{name:"settings-theme",options:s,"model-value":de(r).theme.value,"onUpdate:modelValue":F[6]||(F[6]=U=>de(r).setTheme(U))},null,8,["model-value"])]),_:1})]),_:1})]),_:1})),j(ve,{class:"settings-card info-card"},{default:G(()=>[b("h3",$W,[j(ie,{name:de(bc),size:14},null,8,["name"]),F[17]||(F[17]=le(" How to pair with HomeKit ",-1))]),F[18]||(F[18]=b("ol",{class:"info-list"},[b("li",null,[le(" Open the "),b("strong",null,"Home"),le(" app on your iPhone or iPad ")]),b("li",null,[le(" Tap "),b("strong",null,"+"),le(" → "),b("strong",null,"Add Accessory")]),b("li",null,[le(" Scan the QR code from the Dashboard, or tap "),b("strong",null,"More options"),le(" and enter the PIN code manually ")]),b("li",null,"If you change the PIN or username, unpair first from the Home app, then re-pair")],-1))]),_:1})])}}}),EW=zt(LW,[["__scopeId","data-v-4e6145f5"]]);/**
71
71
  * Copyright (c) 2014-2024 The xterm.js authors. All rights reserved.
72
72
  * @license MIT
73
73
  *