import{D as e,E as t,F as n,G as r,L as i,M as a,Q as o,T as s,U as c,V as l,W as u,Y as d,a as f,b as p,d as m,g as h,k as g,m as _,n as v,p as y,q as b,r as x,t as S,u as C,v as w,w as T}from"./ui-CTx2ZrLp.js";import{n as ee,r as te,t as E}from"./message-square-DqzerHoB.js";import{t as D}from"./globe-C1LJ7PVd.js";import{t as O}from"./hash-B2c-3y-y.js";import{n as k,r as ne,t as A}from"./users-3wlaTGls.js";import{t as j}from"./radio-tower-Beh88DAK.js";import{n as M,t as N}from"./user-round-D606vhD9.js";import{t as P}from"./shield-check-OBDPf7l7.js";import{i as F,n as I,r as re}from"./index-LUhOsKYd.js";var L=[[`path`,{d:`M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z`,key:`1s6t7t`}],[`circle`,{cx:`16.5`,cy:`7.5`,r:`.5`,fill:`currentColor`,key:`w0ekpg`}]],R=e=>l(p,d(e,{iconNode:L,name:`key-round`})),z=[[`path`,{d:`M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z`,key:`zw3jo`}],[`path`,{d:`M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12`,key:`1wduqc`}],[`path`,{d:`M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17`,key:`kqbvx6`}]],B=e=>l(p,d(e,{iconNode:z,name:`layers`})),V=[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]],ie=e=>l(p,d(e,{iconNode:V,name:`refresh-cw`})),H=[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`1357e3`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}]],ae=e=>l(p,d(e,{iconNode:H,name:`rotate-ccw`})),U=[[`path`,{d:`M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z`,key:`1c8476`}],[`path`,{d:`M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7`,key:`1ydtos`}],[`path`,{d:`M7 3v4a1 1 0 0 0 1 1h7`,key:`t51u73`}]],W=e=>l(p,d(e,{iconNode:U,name:`save`})),G=[[`path`,{d:`M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915`,key:`1i5ecw`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]],K=e=>l(p,d(e,{iconNode:G,name:`settings`})),oe=[[`path`,{d:`M10 5H3`,key:`1qgfaw`}],[`path`,{d:`M12 19H3`,key:`yhmn1j`}],[`path`,{d:`M14 3v4`,key:`1sua03`}],[`path`,{d:`M16 17v4`,key:`1q0r14`}],[`path`,{d:`M21 12h-9`,key:`1o4lsq`}],[`path`,{d:`M21 19h-5`,key:`1rlt1p`}],[`path`,{d:`M21 5h-7`,key:`1oszz2`}],[`path`,{d:`M8 10v4`,key:`tgpxqk`}],[`path`,{d:`M8 12H3`,key:`a7s4jb`}]],q=e=>l(p,d(e,{iconNode:oe,name:`sliders-horizontal`})),se=[[`path`,{d:`M10 11v6`,key:`nco0om`}],[`path`,{d:`M14 11v6`,key:`outv1u`}],[`path`,{d:`M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6`,key:`miytrc`}],[`path`,{d:`M3 6h18`,key:`d0wm0j`}],[`path`,{d:`M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`,key:`e791ji`}]],J=e=>l(p,d(e,{iconNode:se,name:`trash-2`})),Y=[[`path`,{d:`m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5`,key:`ftymec`}],[`rect`,{x:`2`,y:`6`,width:`14`,height:`12`,rx:`2`,key:`158x01`}]],X=e=>l(p,d(e,{iconNode:Y,name:`video`})),ce=a(`
`),pe=a(`
manage / console
`),ve=a(`
暂无房间数据`),be=a(`
room /
创建者 · 状态
暂无活跃成员`),ke=a(`
全局: · 生效:
未设置时自动使用全局分发;勾选即为该房间单独覆盖(可为空表示关闭全部)。`),Ne=a(`
加载中…`),ze=a(``);function Be(a){let o=()=>a.members.filter(e=>e.status===`pending`),s=()=>a.members.filter(e=>e.status!==`pending`);return(()=>{var c=Ne(),u=c.firstChild,d=u.firstChild,p=d.firstChild.nextSibling,m=p.firstChild,h=m.firstChild.nextSibling,_=h.firstChild,y=m.nextSibling,b=y.firstChild.nextSibling,S=y.nextSibling,w=S.firstChild;w.firstChild;var A=w.nextSibling.firstChild.nextSibling,j=S.nextSibling.firstChild.nextSibling,P=j.firstChild,F=P.nextSibling,L=d.nextSibling.firstChild,R=L.firstChild.nextSibling,z=L.nextSibling,B=u.nextSibling;return t(h,l(O,{class:`size-4 shrink-0 text-muted-foreground`}),_),_.$$input=e=>a.setNewRoom({name:e.currentTarget.value}),b.$$input=e=>a.setNewRoom({desc:e.currentTarget.value}),t(w,l(C,{get value(){return a.newRoom.isPublic?`public`:`private`},onChange:e=>a.setNewRoom({isPublic:e===`public`}),options:[{value:`public`,label:`公开`},{value:`private`,label:`私密`}]}),null),A.$$input=e=>a.setNewRoom({max:e.currentTarget.value}),t(j,l(ne,{class:`size-4 shrink-0 text-muted-foreground`}),P),P.$$input=e=>a.setNewRoom({pwd:e.currentTarget.value}),F.$$click=()=>a.setNewRoom({showPwd:!a.newRoom.showPwd}),t(F,l(i,{get when(){return a.newRoom.showPwd},get fallback(){return l(ee,{class:`size-4`})},get children(){return l(te,{class:`size-4`})}})),t(p,l(x,{class:`w-full`,get onClick(){return a.onCreate},get disabled(){return a.loading||!a.newRoom.name.trim()},get children(){return[l(k,{class:`size-4`}),`创建房间`]}}),null),t(R,()=>a.rooms.length),t(z,l(n,{get each(){return a.rooms},children:e=>(()=>{var n=Pe(),i=n.firstChild,o=i.firstChild,s=o.nextSibling,c=i.nextSibling,u=c.firstChild,d=u.firstChild;return n.$$click=()=>a.onSelectRoom(e.room.name),t(o,()=>e.room.name),t(s,()=>e.room.description||e.room.creator||`—`),t(c,l(f,{get active(){return e.live}}),u),t(u,()=>e.member_count,d),r(()=>T(n,`flex w-full items-center justify-between gap-3 border-b border-line/60 px-4 py-3 text-left hover:bg-accent/40 ${a.selectedRoom===e.room.name?`bg-acid-lime/10`:``}`)),n})()})),t(B,l(i,{get when(){return a.selectedRoom},get fallback(){return Fe()},get children(){return[(()=>{var e=Ee(),n=e.firstChild,i=n.firstChild.firstChild;i.firstChild;var o=i.nextSibling,s=o.nextSibling,c=s.firstChild.nextSibling;c.nextSibling;var u=n.nextSibling,d=u.firstChild,f=d.firstChild.nextSibling,p=d.nextSibling.firstChild.nextSibling,m=u.nextSibling;return t(i,()=>a.selectedRoom,null),t(o,()=>a.editingRoom?.display_name||a.selectedRoom),t(s,()=>a.editingRoom?.creator||`-`,c),t(s,()=>a.editingRoom?.status||`active`,null),t(n,l(v,{get variant(){return a.editingRoom?.is_public?`success`:`warning`},get children(){return a.editingRoom?.is_public?`公开`:`私密`}}),null),f.$$input=e=>a.setEdit({desc:e.currentTarget.value}),p.$$input=e=>a.setEdit({max:e.currentTarget.value}),t(m,l(x,{class:`gap-1.5`,get onClick(){return a.onSave},get children(){return[l(W,{class:`size-4`}),`保存`]}}),null),t(m,l(x,{variant:`danger`,class:`gap-1.5`,onClick:()=>a.onDelete(a.selectedRoom),get children(){return[l(J,{class:`size-4`}),`删除`]}}),null),r(()=>f.value=a.edit.desc),r(()=>p.value=a.edit.max),e})(),l(i,{get when(){return o().length>0},get children(){var e=De(),r=e.firstChild,i=r.firstChild,s=i.firstChild,c=r.nextSibling;return t(i,l(M,{class:`size-4`}),s),t(i,()=>o().length,null),t(c,l(n,{get each(){return o()},children:e=>(()=>{var n=Ie(),r=n.firstChild,i=r.firstChild,o=i.nextSibling;o.firstChild;var s=r.nextSibling;return t(r,()=>e.username,i),t(o,()=>e.role,null),t(s,l(x,{class:`h-7 px-3`,onClick:()=>a.onApprove(a.selectedRoom,e.username),children:`批准`}),null),t(s,l(x,{variant:`ghost`,class:`h-7 px-3`,onClick:()=>a.onReject(a.selectedRoom,e.username),children:`拒绝`}),null),n})()})),e}}),(()=>{var c=ke(),u=c.firstChild,d=u.firstChild,f=d.firstChild.nextSibling,p=f.nextSibling.nextSibling;p.firstChild;var m=u.nextSibling;return t(d,()=>a.members.length,f),t(p,()=>o().length,null),t(m,l(n,{get each(){return s()},children:n=>(()=>{var o=Le(),s=o.firstChild,c=s.nextSibling,u=c.firstChild,d=u.firstChild,f=d.nextSibling;f.nextSibling;var p=u.nextSibling,m=c.nextSibling;return t(s,()=>(n.username[0]||`?`).toUpperCase()),t(u,()=>n.username,d),t(u,l(i,{get when(){return n.status===`banned`},get children(){return l(v,{variant:`outline`,class:`border-destructive/30 text-destructive text-[10px]`,children:`banned`})}}),f),t(u,l(i,{get when(){return e(()=>n.status===`active`)()&&n.role===`creator`},get children(){return l(I,{class:`size-3 text-amber-500`})}}),null),t(p,()=>n.effective_permissions?.join(`, `)||``),t(o,l(C,{class:`w-28`,get value(){return n.role},onChange:e=>a.onChangeRole(a.selectedRoom,n.username,e),options:[{value:`creator`,label:`房主`},{value:`admin`,label:`管理员`},{value:`member`,label:`成员`},{value:`guest`,label:`访客`}]}),m),t(m,l(i,{get when(){return n.role!==`creator`},get children(){return[l(x,{variant:`ghost`,class:`h-8 px-2 text-muted-foreground`,title:`转让房主`,onClick:()=>{confirm(`转让房主给 ${n.username}?`)&&a.onTransfer(a.selectedRoom,n.username)},get children(){return l(I,{class:`size-4`})}}),l(x,{variant:`ghost`,class:`h-8 px-2 text-destructive`,title:`踢出`,onClick:()=>a.onKick(a.selectedRoom,n.username),get children(){return l(re,{class:`size-4`})}}),l(x,{variant:`ghost`,class:`h-8 px-2 text-destructive`,title:`封禁(房内)`,onClick:()=>{confirm(`房内封禁 ${n.username}?`)&&a.onBan(a.selectedRoom,n.username)},get children(){return l(M,{class:`size-4`})}})]}})),r(()=>T(s,`flex size-8 items-center justify-center border font-mono text-xs font-bold ${$[n.role]?.color||``}`)),o})()}),null),t(m,l(i,{get when(){return s().length===0},get children(){return Oe()}}),null),c})(),(()=>{var e=je(),n=e.firstChild,o=n.firstChild;return t(n,l(q,{class:`size-4`}),o),t(e,l(i,{get when(){return a.roomSettings},get fallback(){return Re()},get children(){return[(()=>{var e=Ae(),n=e.firstChild,i=n.firstChild,o=i.firstChild,s=i.nextSibling,c=n.nextSibling,u=c.firstChild,d=u.firstChild,f=u.nextSibling,p=c.nextSibling,m=p.firstChild,h=m.firstChild,g=m.nextSibling,_=p.nextSibling.firstChild,v=_.firstChild,y=_.nextSibling;return t(i,l(E,{class:`size-4 text-muted-foreground`}),o),s.$$input=e=>a.setRoomSettings({...a.roomSettings,chat_enabled:e.currentTarget.checked}),t(u,l(N,{class:`size-4 text-muted-foreground`}),d),f.$$input=e=>a.setRoomSettings({...a.roomSettings,allow_guest_join:e.currentTarget.checked}),t(m,l(M,{class:`size-4 text-muted-foreground`}),h),g.$$input=e=>a.setRoomSettings({...a.roomSettings,require_approval:e.currentTarget.checked}),t(_,l(D,{class:`size-4 text-muted-foreground`}),v),y.$$input=e=>a.setRoomSettings({...a.roomSettings,is_public:e.currentTarget.checked}),r(()=>s.checked=!!a.roomSettings?.chat_enabled),r(()=>f.checked=!!a.roomSettings?.allow_guest_join),r(()=>g.checked=!!a.roomSettings?.require_approval),r(()=>y.checked=!!a.roomSettings?.is_public),e})(),l(x,{class:`mt-4 gap-1.5`,get onClick(){return a.onSaveSettings},get children(){return[l(W,{class:`size-4`}),`保存设置`]}})]}}),null),e})(),(()=>{var e=Me(),o=e.firstChild,s=o.firstChild,c=s.firstChild,u=o.nextSibling,d=u.firstChild.nextSibling;d.nextSibling;var f=u.nextSibling;return t(s,l(D,{class:`size-4`}),c),t(s,l(i,{get when(){return a.distribution?.has_custom},get fallback(){return l(v,{variant:`outline`,class:`text-[10px]`,children:`跟随全局`})},get children(){return l(v,{variant:`success`,class:`text-[10px]`,children:`房间自定义`})}}),null),t(o,l(i,{get when(){return a.distribution?.has_custom},get children(){return l(x,{variant:`ghost`,class:`h-7 px-2 text-xs`,onClick:()=>a.onClearDistribution?.(),children:`恢复全局`})}}),null),t(u,()=>a.distribution?.global?.join(`, `)||`—`,d),t(u,()=>a.distribution?.effective?.join(`, `)||`(无)`,null),t(u,l(i,{get when(){return!a.distribution},children:` · 加载中…`}),null),t(f,l(n,{each:[`srs-hls`,`cf`,`cdn`],children:e=>(()=>{var n=ze(),i=n.firstChild,o=i.nextSibling;return t(i,e),o.$$input=t=>a.onToggleDistribution?.(e,t.currentTarget.checked),r(()=>o.checked=!!a.distribution?.effective?.includes(e)),n})()})),e})()]}})),r(()=>g(P,`type`,a.newRoom.showPwd?`text`:`password`)),r(()=>_.value=a.newRoom.name),r(()=>b.value=a.newRoom.desc),r(()=>A.value=a.newRoom.max),r(()=>P.value=a.newRoom.pwd),c})()}s([`input`,`click`]);var Ve=a(`成员 / 角色`),He=a(`角色默认权限Creator 全量 · Guest 只读,个人覆盖 added/removed 生效。permission成员生效权限 · `),Ue=a(``),We=a(``),Ge=a(``),Ke=a(``),qe=a(``),Je=a(`请选择房间`),Ye=a(``),Xe=a(``),Ze=a(``);function Qe(e){return(()=>{var r=He(),a=r.firstChild,o=a.firstChild.nextSibling.nextSibling.firstChild.firstChild,s=o.firstChild;s.firstChild;var c=o.nextSibling,u=a.nextSibling,d=u.firstChild,f=d.firstChild;return f.firstChild,t(s,l(n,{each:[`creator`,`admin`,`member`,`guest`],children:e=>(()=>{var n=Ue();return t(n,e),n})()}),null),t(c,l(n,{each:we,children:r=>(()=>{var i=We(),a=i.firstChild;return t(a,()=>Te[r]||r),t(i,l(n,{each:[`creator`,`admin`,`member`,`guest`],children:n=>{let i=e.permDefs?.roles?.[n]?.perms?.includes(r);return(()=>{var e=Ge();return t(e,i?Ke():qe()),e})()}}),null),i})()})),t(f,()=>e.selectedRoom||`未选择`,null),t(d,l(C,{get value(){return e.selectedRoom},get onChange(){return e.onSelectRoom},get options(){return e.rooms.map(e=>({value:e.room.name,label:e.room.name}))},class:`w-48`}),null),t(u,l(i,{get when(){return e.selectedRoom},get fallback(){return Je()},get children(){var r=Ve(),i=r.firstChild.firstChild,a=i.firstChild;a.firstChild;var o=i.nextSibling;return t(a,l(n,{each:we,children:e=>(()=>{var n=Ye();return t(n,()=>Te[e]||e),n})()}),null),t(o,l(n,{get each(){return e.members},children:r=>(()=>{var i=Xe(),a=i.firstChild.firstChild,o=a.firstChild;return t(o,()=>r.username),t(a,l(v,{get class(){return`text-[10px] ${$[r.role]?.color||``}`},get children(){return r.role}}),null),t(i,l(n,{each:we,children:n=>{let i=r.effective_permissions?.includes(n),a=r.role===`creator`;return(()=>{var o=Ze(),s=o.firstChild;return s.$$click=()=>e.onTogglePerm(e.selectedRoom,r.username,n,!!i),s.disabled=a,T(s,`inline-flex size-6 items-center justify-center border text-[10px] ${i?`border-acid-lime bg-acid-lime text-black`:`border-line bg-background text-muted-foreground hover:border-ring`} ${a?`opacity-50`:``}`),t(s,i?`✓`:``),o})()}}),null),i})()})),r}}),null),r})()}s([`click`]);var $e=a(``),et=a(`关闭`),tt=a(`运行时配置修改后立即热生效并持久化到 data/runtime_config.json,无需重启。优先级:运行时覆盖 > 环境变量 > 默认值。来源标记 runtime 运行时覆盖 env 环境变量 default 默认值SFU 状态(只读)HTTP8088gRPC9090说明保存即热生效:Cloudflare/SRS/CDN/分发开关等无需重启。密钥字段默认以 •••••••• 脱敏回显;不修改则保持原值。重置会删除运行时覆盖,回落至环境变量或默认值。`),nt=a(``),rt=a(`加载中...`),it=a(` 项`),at=a(``),ot=a(`示例:`),st=a(``),ct=a(``),lt=[{title:`分发与 SFU`,icon:j,keys:[{key:`SFU_PROVIDER`,label:`SFU_PROVIDER`,placeholder:`cloudflare,srs`,hint:`后端顺序,逗号分隔`},{key:`DISTRIBUTORS`,label:`DISTRIBUTORS`,placeholder:`srs-hls,cf,cdn`,hint:`启用的分发方式`},{key:`CDN_RTMP_URL`,label:`CDN_RTMP_URL`,placeholder:`rtmp://cdn.example.com/live`,hint:`启用 cdn 时必填`},{key:`CDN_NAME`,label:`CDN 名称`,placeholder:`cdn`}]},{title:`SRS 主干`,icon:j,keys:[{key:`SRS_API_BASE`,label:`SRS_API_BASE`,placeholder:`http://localhost:1985`},{key:`SRS_HTTP_BASE`,label:`SRS_HTTP_BASE`,placeholder:`http://localhost:8080`},{key:`SRS_APP`,label:`SRS_APP`,placeholder:`live`},{key:`SRS_SECRET`,label:`SRS_SECRET`,placeholder:`留空则不鉴权`,hint:`推流鉴权密钥`},{key:`SRS_CANDIDATE`,label:`SRS_CANDIDATE`,placeholder:`127.0.0.1`,hint:`ICE candidate IP`},{key:`SFU_TOKEN_REQUIRED`,label:`SFU_TOKEN_REQUIRED`,type:`bool`}]},{title:`Cloudflare Realtime`,icon:D,keys:[{key:`CF_APP_ID`,label:`CF_APP_ID`},{key:`CF_APP_SECRET`,label:`CF_APP_SECRET`,hint:`保存后自动脱敏显示`},{key:`CF_BASE_URL`,label:`CF_BASE_URL`,placeholder:`https://rtc.live.cloudflare.com/v1`},{key:`CF_STUN_URL`,label:`CF_STUN_URL`,placeholder:`stun:stun.cloudflare.com:3478`}]},{title:`鉴权与注册`,icon:P,keys:[{key:`ALLOW_REGISTER`,label:`ALLOW_REGISTER`,type:`bool`,hint:`是否允许自助注册`},{key:`JWT_TTL`,label:`JWT_TTL`,placeholder:`2h`,hint:`例如 30m / 2h / 24h`}]},{title:`邮件与验证`,icon:K,keys:[{key:`SMTP_ENABLED`,label:`SMTP_ENABLED`,type:`bool`},{key:`SMTP_HOST`,label:`SMTP_HOST`,placeholder:`smtp.example.com`},{key:`SMTP_PORT`,label:`SMTP_PORT`,placeholder:`587`},{key:`SMTP_USER`,label:`SMTP_USER`},{key:`SMTP_PASS`,label:`SMTP_PASS`,hint:`脱敏存储`},{key:`SMTP_FROM`,label:`SMTP_FROM`},{key:`SMTP_FROM_NAME`,label:`SMTP_FROM_NAME`,placeholder:`SyncLive`},{key:`SMTP_TLS`,label:`SMTP_TLS`,type:`bool`},{key:`EMAIL_VERIFY_REQUIRED`,label:`EMAIL_VERIFY_REQUIRED`,type:`bool`},{key:`EMAIL_VERIFY_TTL`,label:`EMAIL_VERIFY_TTL`,placeholder:`24h`},{key:`EMAIL_VERIFY_BASE_URL`,label:`EMAIL_VERIFY_BASE_URL`}]},{title:`OAuth 登录`,icon:R,keys:[{key:`OAUTH_ENABLED`,label:`OAUTH_ENABLED`,type:`bool`},{key:`OAUTH_CALLBACK_BASE`,label:`OAUTH_CALLBACK_BASE`,placeholder:`http://localhost:8088`},{key:`OAUTH_GOOGLE_CLIENT_ID`,label:`GOOGLE_CLIENT_ID`},{key:`OAUTH_GOOGLE_CLIENT_SECRET`,label:`GOOGLE_CLIENT_SECRET`},{key:`OAUTH_GITHUB_CLIENT_ID`,label:`GITHUB_CLIENT_ID`},{key:`OAUTH_GITHUB_CLIENT_SECRET`,label:`GITHUB_CLIENT_SECRET`},{key:`OAUTH_GITLAB_CLIENT_ID`,label:`GITLAB_CLIENT_ID`},{key:`OAUTH_GITLAB_CLIENT_SECRET`,label:`GITLAB_CLIENT_SECRET`},{key:`OAUTH_GENERIC_URL`,label:`GENERIC_URL`},{key:`OAUTH_GENERIC_CLIENT_ID`,label:`GENERIC_CLIENT_ID`},{key:`OAUTH_GENERIC_CLIENT_SECRET`,label:`GENERIC_CLIENT_SECRET`},{key:`OAUTH_GENERIC_NAME`,label:`GENERIC_NAME`,placeholder:`generic`}]}];function ut(a){let s=()=>y.can(`config:write`)||y.can(`system:manage`)||y.isAdminOrAbove(),[u,d]=b(null),[f,p]=b({}),[g,_]=b(!1),[E,O]=b(null),[k,ne]=b(!1),[A,M]=b(0),N=async()=>{try{let e=await h.manageRuntimeConfig();d(e),p({...e.values})}catch(e){O({tone:`error`,text:String(e?.message||e)})}};o(N),c(()=>{y.check()});let P=()=>{let e=u();if(!e)return!1;let t=f();return Object.keys(t).some(n=>(t[n]??``)!==(e.values[n]??``))},F=(e,t)=>p(n=>({...n,[e]:t})),I=async()=>{if(!s()){O({tone:`error`,text:`无权限:需要 admin/root`});return}let e=u();if(!e)return;let t={},n=f();for(let r of Object.keys(n))if((n[r]??``)!==(e.values[r]??``)){if(e.masked[r]&&n[r]===`••••••••`)continue;t[r]=n[r]??``}if(Object.keys(t).length===0){O({tone:`info`,text:`没有变更`});return}_(!0);try{let e=await h.saveRuntimeConfig(t);O({tone:`success`,text:`已保存 ${e.changed?.length??0} 项,已热生效,无需重启`});let n=await h.manageRuntimeConfig();d(n),p({...n.values})}catch(e){O({tone:`error`,text:String(e?.message||e)})}finally{_(!1)}},re=async()=>{if(!s()||!confirm(`将当前分组的运行时覆盖重置为环境/默认值?`))return;let e=lt[A()];try{await h.resetRuntimeConfig(e.keys.map(e=>e.key)),O({tone:`success`,text:`已重置,已热生效`}),await N()}catch(e){O({tone:`error`,text:String(e?.message||e)})}},L=async()=>{if(!(!s()||!confirm(`重置所有运行时覆盖?将回落至环境变量/默认值并立即生效。`)))try{await h.resetRuntimeConfig([]),O({tone:`success`,text:`已重置全部,已热生效`}),await N()}catch(e){O({tone:`error`,text:String(e?.message||e)})}};return(()=>{var o=tt(),c=o.firstChild,d=c.firstChild,p=d.firstChild,h=p.firstChild,_=d.nextSibling,y=c.nextSibling.firstChild,b=y.firstChild,R=y.nextSibling,z=R.firstChild,B=z.firstChild,V=B.firstChild,ie=V.firstChild,H=V.nextSibling,U=H.firstChild,G=B.nextSibling.firstChild,oe=G.firstChild,q=G.nextSibling;return q.firstChild.nextSibling.nextSibling,t(o,l(i,{get when(){return E()},get children(){return l(S,{get tone(){return e(()=>E().tone===`error`)()?`error`:E().tone===`success`?`success`:`info`},class:`flex items-center justify-between gap-3`,get children(){return[(()=>{var e=$e();return t(e,l(w,{class:`size-4`}),null),t(e,()=>E().text,null),e})(),(()=>{var e=et();return e.$$click=()=>O(null),e})()]}})}}),c),t(p,l(K,{class:`size-4`}),h),t(_,l(i,{get when(){return!s()},get children(){return l(v,{variant:`warning`,children:`只读`})}}),null),t(_,l(i,{get when(){return s()},get children(){return l(x,{variant:`ghost`,class:`h-9 gap-1.5`,onClick:()=>ne(e=>!e),get children(){return[e(()=>e(()=>!!k())()?l(te,{class:`size-4`}):l(ee,{class:`size-4`})),e(()=>k()?`隐藏密钥`:`显示密钥`)]}})}}),null),t(_,l(x,{variant:`outline`,class:`h-9 gap-1.5`,onClick:N,get disabled(){return g()},children:`刷新`}),null),t(_,l(x,{variant:`ghost`,class:`h-9 gap-1.5`,onClick:re,get disabled(){return!s()||g()},get children(){return[l(ae,{class:`size-4`}),`重置分组`]}}),null),t(_,l(x,{variant:`ghost`,class:`h-9 gap-1.5`,onClick:L,get disabled(){return!s()||g()},children:`重置全部`}),null),t(_,l(x,{class:`h-9 gap-1.5`,onClick:I,get disabled(){return!s()||g()||!P()},get children(){return[l(W,{class:`size-4`}),e(()=>e(()=>!!g())()?`保存中...`:P()?`保存并生效`:`已是最新`)]}}),null),t(y,l(n,{each:lt,children:(e,n)=>{let i=e.icon,a=()=>n()===A();return(()=>{var o=nt(),s=o.firstChild;return o.$$click=()=>M(n()),t(o,l(i,{class:`size-3.5 shrink-0`}),s),t(s,()=>e.title),r(()=>T(o,`flex items-center gap-2 border px-3 py-2.5 text-left text-xs font-medium transition-colors ${a()?`border-line bg-acid-lime text-black`:`border-transparent bg-card text-muted-foreground hover:bg-accent hover:text-foreground`}`)),o})()}}),b),t(R,l(i,{get when(){return u()},get fallback(){return rt()},get children(){return(()=>{let e=lt[A()];return(()=>{var a=it(),o=a.firstChild,c=o.firstChild,d=c.nextSibling,p=d.firstChild,h=o.nextSibling;return t(c,()=>e.title),t(d,()=>e.keys.length,p),t(h,l(n,{get each(){return e.keys},children:e=>{let n=()=>u().source[e.key]||`default`,a=()=>!!u().masked[e.key],o=()=>f()[e.key]??``,c=()=>n()===`runtime`?`bg-acid-lime`:n()===`env`?`bg-acid-cyan`:`bg-line`;return(()=>{var u=st(),d=u.firstChild,f=d.firstChild,p=f.firstChild,h=p.nextSibling,g=h.firstChild,_=d.nextSibling;return t(p,()=>e.label),t(h,n,null),t(f,l(i,{get when(){return a()},get children(){return l(v,{variant:`outline`,class:`text-[10px]`,children:`secret`})}}),null),t(d,l(i,{get when(){return e.hint},get children(){var n=at();return t(n,()=>e.hint),n}}),null),t(d,l(i,{get when(){return e.placeholder},get children(){var n=ot();return n.firstChild,t(n,()=>e.placeholder,null),n}}),null),t(_,l(i,{get when(){return e.type===`bool`},get fallback(){return l(m,{get value(){return o()},onInput:t=>F(e.key,t),get placeholder(){return e.placeholder||``},get type(){return a()&&!k()?`password`:`text`},get disabled(){return!s()},class:`h-9 font-mono text-xs`})},get children(){return l(C,{get value(){return o()||`0`},onChange:t=>F(e.key,t),options:[{value:`0`,label:`关闭 (0)`},{value:`1`,label:`开启 (1)`}],get disabled(){return!s()}})}})),r(e=>{var t=`inline-flex items-center gap-1 border px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-widest ${n()===`runtime`?`border-acid-lime/40 bg-acid-lime/15 text-foreground`:n()===`env`?`border-acid-cyan/40 bg-acid-cyan/10 text-foreground`:`border-line bg-muted text-muted-foreground`}`,r=`size-1.5 ${c()}`;return t!==e.e&&T(h,e.e=t),r!==e.t&&T(g,e.t=r),e},{e:void 0,t:void 0}),u})()}})),a})()})()}}),z),t(V,l(j,{class:`size-4`}),ie),t(H,l(n,{get each(){return a.overview?.backends||[]},children:e=>(()=>{var n=ct(),r=n.firstChild;return t(r,l(j,{class:`size-4 text-muted-foreground`}),null),t(r,()=>e.name||e.kind,null),t(n,l(v,{get variant(){return e.configured?`success`:`muted`},get children(){return e.configured?`已配置`:`未配置`}}),null),n})()}),U),t(G,l(w,{class:`size-4`}),oe),t(q,l(x,{variant:`ghost`,class:`mt-2 h-8 gap-1.5 text-xs`,onClick:()=>window.open(`/api/manage/config?raw=1`,`_blank`),get children(){return[l(D,{class:`size-4`}),`查看原始 JSON`]}}),null),o})()}s([`click`]);var dt=a(`系统用户与全局角色 users`),ft=a(`暂无用户`),pt=a(``),mt=a(`banned`),ht=a(` · `),gt=a(`无权变更`);function _t(e){let a=t=>e.actorRole===`root`?[`viewer`,`publisher`,`admin`,`root`]:e.actorRole===`admin`?t===`admin`||t===`root`?[]:[`viewer`,`publisher`]:[],o=t=>e.actorRole===`root`?t.role!==`root`:e.actorRole===`admin`?t.role===`viewer`||t.role===`publisher`:!1;return(()=>{var s=dt(),c=s.firstChild.firstChild.nextSibling,u=c.firstChild;return t(c,()=>e.users.length,u),t(s,l(i,{get when(){return!e.canList},get fallback(){return(()=>{var s=pt();return t(s,l(n,{get each(){return e.users},children:n=>{let s=n.role,c=$[s]||$.viewer,u=n.status===`banned`,d=a(s),f=d.length>0;return(()=>{var a=ht(),p=a.firstChild,m=p.firstChild,h=m.nextSibling.firstChild,g=h.firstChild,_=h.nextSibling,y=_.firstChild,b=p.nextSibling;return T(a,`flex flex-wrap items-center justify-between gap-3 border-b border-line/60 px-5 py-3 last:border-0 ${u?`bg-destructive/5`:``}`),t(m,()=>(n.username[0]||`?`).toUpperCase()),t(h,()=>n.username,g),t(h,l(i,{when:u,get children(){return mt()}}),null),t(_,s,y),t(_,u?`已封禁`:`active`,null),t(b,l(v,{get class(){return c.color},children:s}),null),t(b,l(i,{when:f,get fallback(){return gt()},get children(){return l(C,{class:`w-28`,value:s,get"aria-label"(){return`调整 ${n.username} 的角色`},get disabled(){return!!e.busy||u},onChange:async t=>e.onRoleChange(n,t),get options(){return d.map(e=>({value:e,label:e}))}})}}),null),t(b,l(i,{get when(){return o(n)},get children(){return l(x,{variant:u?`outline`:`ghost`,class:`h-7 px-2 text-xs ${u?`border-success/30 text-success`:`text-destructive`}`,get disabled(){return e.busy===n.username},onClick:()=>e.onToggleBan(n),children:u?`解封`:`封禁`})}}),null),r(()=>T(m,`flex size-8 shrink-0 items-center justify-center border font-mono text-xs font-bold ${c.color}`)),a})()}}),null),t(s,l(i,{get when(){return e.users.length===0},get children(){return ft()}}),null),s})()},get children(){return l(S,{tone:`warning`,class:`m-4`,children:`无权限查看:需要 user:list(管理员及以上)`})}}),null),s})()}var vt=a(``),yt=a(`关闭`),bt=()=>{let[n,r]=b(`overview`),[a,o]=b(null),[s,u]=b([]),[d,f]=b(null),[p,m]=b(``),[g,C]=b([]),[w,T]=b(``),[ee,te]=b(!1),[E,D]=b(``),[O,k]=b(``),[ne,A]=b(!0),[j,N]=b(`100`),[F,I]=b(``),[re,L]=b(!1),[R,z]=b(null),[B,V]=b(``),[H,ae]=b(``),[U,W]=b(null),[G,K]=b(null),[oe,q]=b([]),[se,J]=b(``),Y=async()=>{try{let e=await h.manageOverview();o(e)}catch(e){T(String(e?.message||e))}},X=async()=>{try{let e=await h.manageRooms();u(e.rooms||[]),!p()&&e.rooms?.length&&m(e.rooms[0].room.name)}catch(e){T(String(e?.message||e))}},ce=async()=>{try{let e=await h.managePermMatrix();f(e)}catch{}},le=async()=>{try{let e=await h.listUsers();q(e.users||[])}catch{}},Z=async e=>{if(e)try{let t=await h.manageMembers(e);C(t.members||[]);let n=await h.manageRoomDetail(e);z(n.room),V(n.room.description||``),ae(String(n.room.max_members||100)),W(n.room.settings||null);try{let t=await h.manageRoomDistribution(e);K(t)}catch{K(null)}}catch(e){T(String(e?.message||e))}};c(()=>{Y(),X(),ce(),le()}),c(()=>{let e=p();e&&(n()===`rooms`||n()===`permissions`)&&Z(e)});let de=async()=>{let e=E().trim();if(e){te(!0);try{await h.manageCreateRoom({name:e,description:O().trim()||void 0,is_public:ne(),max_members:parseInt(j())||100,password:F().trim()||void 0}),D(``),k(``),I(``),await X(),await Y()}catch(e){T(String(e?.message||e))}finally{te(!1)}}},fe=async()=>{let e=p();if(!(!e||!R()))try{await h.manageUpdateRoom(e,{description:B(),max_members:parseInt(H())||void 0,is_public:R().is_public}),await X(),await Z(e)}catch(e){T(String(e?.message||e))}},pe=async e=>{if(confirm(`删除房间 ${e} ?`))try{await h.manageDeleteRoom(e),await X(),await Y()}catch(e){T(String(e?.message||e))}},me=async(e,t,n)=>{try{await h.manageUpdateMemberRole(e,t,n),await Z(e)}catch(e){T(String(e?.message||e))}},_e=async(e,t)=>{if(confirm(`踢出 ${t} ?`))try{await h.manageKickMember(e,t),await Z(e)}catch(e){T(String(e?.message||e))}},ve=async(e,t)=>{try{await h.manageBanMember(e,t),await Z(e)}catch(e){T(String(e?.message||e))}},ye=async(e,t)=>{try{await h.manageApproveMember(e,t),await Z(e)}catch(e){T(String(e?.message||e))}},be=async(e,t)=>{try{await h.manageRejectMember(e,t),await Z(e)}catch(e){T(String(e?.message||e))}},xe=async(e,t)=>{try{await h.manageTransferOwnership(e,t),await Z(e),await X()}catch(e){T(String(e?.message||e))}},Se=async(e,t,n,r)=>{let i=1<e.username===t);if(!a)return;let o=Number(a.added||0),s=Number(a.removed||0);r?(o&=~i,s|=i):(o|=i,s&=~i);try{await h.manageUpdateMemberPerms(e,t,o,s,!1),await Z(e)}catch(e){T(String(e?.message||e))}},Q=async()=>{let e=p();if(!(!e||!U()))try{await h.manageUpdateRoomSettings(e,U()),await Z(e)}catch(e){T(String(e?.message||e))}},Te=async(e,t)=>{let n=p();if(!n)return;let r=new Set(G()?.effective||[]);t?r.add(e):r.delete(e);let i=Array.from(r);try{let e=await h.manageUpdateRoomDistributionList(n,i);K(t=>({...t||{},effective:e.effective,custom:e.distributors,has_custom:!0,custom_list:e.effective})),await Z(n)}catch(e){T(String(e?.message||e))}},$=async()=>{let e=p();if(e)try{let t=await h.manageClearRoomDistribution(e);K(e=>({...e||{},effective:t.effective,has_custom:!1,custom:null,custom_list:[]})),await Z(e)}catch(e){T(String(e?.message||e))}},Ee=async(e,t)=>{J(e.username);try{await h.updateUserRole(e.username,t),q(n=>n.map(n=>n.username===e.username?{...n,role:t}:n)),await y.refresh()}catch(e){T(String(e?.message||e))}finally{J(``)}},De=async e=>{let t=e.status===`banned`;if(confirm(t?`解封 ${e.username}?`:`封禁 ${e.username}?封禁后无法登录`)){J(e.username);try{t?await h.unbanUser(e.username):await h.banUser(e.username),await le()}catch(e){T(String(e?.message||e))}finally{J(``)}}};return l(he,{get children(){return[l(ge,{title:`管理控制台`,description:`统一管理房间、角色与权限。房主全量,管理员/成员/访客基于角色默认值 + 个人覆盖计算生效权限。全局管理员(admin/root)可跨房间管理,无需加入房间。`,get actions(){return[l(v,{variant:`outline`,class:`gap-1.5`,get children(){return[l(P,{class:`size-3.5`}),e(()=>_.user()?.username||`guest`),` · `,e(()=>y.role())]}}),l(x,{variant:`ghost`,class:`h-9 gap-1.5`,onClick:()=>{Y(),X(),le(),p()&&Z(p())},get children(){return[l(ie,{class:`size-4`}),`刷新`]}})]}}),l(i,{get when(){return w()},get children(){return l(S,{tone:`error`,class:`flex items-center justify-between gap-3`,get children(){return[(()=>{var e=vt();return t(e,l(M,{class:`size-4`}),null),t(e,w,null),e})(),(()=>{var e=yt();return e.$$click=()=>T(``),e})()]}})}}),l(ue,{get value(){return n()},onChange:r}),l(i,{get when(){return n()===`overview`},get children(){return l(Ce,{get overview(){return a()},get rooms(){return s()}})}}),l(i,{get when(){return n()===`rooms`},get children(){return l(Be,{get rooms(){return s()},get selectedRoom(){return p()},onSelectRoom:m,get members(){return g()},get editingRoom(){return R()},get roomSettings(){return U()},setRoomSettings:W,get newRoom(){return{name:E(),desc:O(),isPublic:ne(),max:j(),pwd:F(),showPwd:re()}},setNewRoom:e=>{e.name!==void 0&&D(e.name),e.desc!==void 0&&k(e.desc),e.isPublic!==void 0&&A(e.isPublic),e.max!==void 0&&N(e.max),e.pwd!==void 0&&I(e.pwd),e.showPwd!==void 0&&L(e.showPwd)},get edit(){return{desc:B(),max:H()}},setEdit:e=>{e.desc!==void 0&&V(e.desc),e.max!==void 0&&ae(e.max)},get loading(){return ee()},onCreate:de,onSave:fe,onDelete:pe,onChangeRole:me,onKick:_e,onBan:ve,onApprove:ye,onReject:be,onTransfer:xe,onSaveSettings:Q,get distribution(){return G()},onToggleDistribution:Te,onClearDistribution:$})}}),l(i,{get when(){return n()===`permissions`},get children(){return l(Qe,{get rooms(){return s()},get selectedRoom(){return p()},onSelectRoom:m,get members(){return g()},get permDefs(){return d()},onTogglePerm:Se})}}),l(i,{get when(){return n()===`users`},get children(){return l(_t,{get users(){return oe()},onRoleChange:Ee,onToggleBan:De,get canList(){return y.can(`user:list`)},get actorRole(){return y.role()},get busy(){return se()}})}}),l(i,{get when(){return n()===`system`},get children(){return l(ut,{get overview(){return a()}})}})]}})};s([`click`]);export{bt as Manage};
Creator 全量 · Guest 只读,个人覆盖 added/removed 生效。
请选择房间`),Ye=a(`
修改后立即热生效并持久化到 data/runtime_config.json,无需重启。优先级:运行时覆盖 > 环境变量 > 默认值。
来源标记
runtime 运行时覆盖
env 环境变量
default 默认值
保存即热生效:Cloudflare/SRS/CDN/分发开关等无需重启。
密钥字段默认以 •••••••• 脱敏回显;不修改则保持原值。
重置会删除运行时覆盖,回落至环境变量或默认值。`),nt=a(``),rt=a(`加载中...`),it=a(` 项`),at=a(``),ot=a(`示例:`),st=a(``),ct=a(``),lt=[{title:`分发与 SFU`,icon:j,keys:[{key:`SFU_PROVIDER`,label:`SFU_PROVIDER`,placeholder:`cloudflare,srs`,hint:`后端顺序,逗号分隔`},{key:`DISTRIBUTORS`,label:`DISTRIBUTORS`,placeholder:`srs-hls,cf,cdn`,hint:`启用的分发方式`},{key:`CDN_RTMP_URL`,label:`CDN_RTMP_URL`,placeholder:`rtmp://cdn.example.com/live`,hint:`启用 cdn 时必填`},{key:`CDN_NAME`,label:`CDN 名称`,placeholder:`cdn`}]},{title:`SRS 主干`,icon:j,keys:[{key:`SRS_API_BASE`,label:`SRS_API_BASE`,placeholder:`http://localhost:1985`},{key:`SRS_HTTP_BASE`,label:`SRS_HTTP_BASE`,placeholder:`http://localhost:8080`},{key:`SRS_APP`,label:`SRS_APP`,placeholder:`live`},{key:`SRS_SECRET`,label:`SRS_SECRET`,placeholder:`留空则不鉴权`,hint:`推流鉴权密钥`},{key:`SRS_CANDIDATE`,label:`SRS_CANDIDATE`,placeholder:`127.0.0.1`,hint:`ICE candidate IP`},{key:`SFU_TOKEN_REQUIRED`,label:`SFU_TOKEN_REQUIRED`,type:`bool`}]},{title:`Cloudflare Realtime`,icon:D,keys:[{key:`CF_APP_ID`,label:`CF_APP_ID`},{key:`CF_APP_SECRET`,label:`CF_APP_SECRET`,hint:`保存后自动脱敏显示`},{key:`CF_BASE_URL`,label:`CF_BASE_URL`,placeholder:`https://rtc.live.cloudflare.com/v1`},{key:`CF_STUN_URL`,label:`CF_STUN_URL`,placeholder:`stun:stun.cloudflare.com:3478`}]},{title:`鉴权与注册`,icon:P,keys:[{key:`ALLOW_REGISTER`,label:`ALLOW_REGISTER`,type:`bool`,hint:`是否允许自助注册`},{key:`JWT_TTL`,label:`JWT_TTL`,placeholder:`2h`,hint:`例如 30m / 2h / 24h`}]},{title:`邮件与验证`,icon:K,keys:[{key:`SMTP_ENABLED`,label:`SMTP_ENABLED`,type:`bool`},{key:`SMTP_HOST`,label:`SMTP_HOST`,placeholder:`smtp.example.com`},{key:`SMTP_PORT`,label:`SMTP_PORT`,placeholder:`587`},{key:`SMTP_USER`,label:`SMTP_USER`},{key:`SMTP_PASS`,label:`SMTP_PASS`,hint:`脱敏存储`},{key:`SMTP_FROM`,label:`SMTP_FROM`},{key:`SMTP_FROM_NAME`,label:`SMTP_FROM_NAME`,placeholder:`SyncLive`},{key:`SMTP_TLS`,label:`SMTP_TLS`,type:`bool`},{key:`EMAIL_VERIFY_REQUIRED`,label:`EMAIL_VERIFY_REQUIRED`,type:`bool`},{key:`EMAIL_VERIFY_TTL`,label:`EMAIL_VERIFY_TTL`,placeholder:`24h`},{key:`EMAIL_VERIFY_BASE_URL`,label:`EMAIL_VERIFY_BASE_URL`}]},{title:`OAuth 登录`,icon:R,keys:[{key:`OAUTH_ENABLED`,label:`OAUTH_ENABLED`,type:`bool`},{key:`OAUTH_CALLBACK_BASE`,label:`OAUTH_CALLBACK_BASE`,placeholder:`http://localhost:8088`},{key:`OAUTH_GOOGLE_CLIENT_ID`,label:`GOOGLE_CLIENT_ID`},{key:`OAUTH_GOOGLE_CLIENT_SECRET`,label:`GOOGLE_CLIENT_SECRET`},{key:`OAUTH_GITHUB_CLIENT_ID`,label:`GITHUB_CLIENT_ID`},{key:`OAUTH_GITHUB_CLIENT_SECRET`,label:`GITHUB_CLIENT_SECRET`},{key:`OAUTH_GITLAB_CLIENT_ID`,label:`GITLAB_CLIENT_ID`},{key:`OAUTH_GITLAB_CLIENT_SECRET`,label:`GITLAB_CLIENT_SECRET`},{key:`OAUTH_GENERIC_URL`,label:`GENERIC_URL`},{key:`OAUTH_GENERIC_CLIENT_ID`,label:`GENERIC_CLIENT_ID`},{key:`OAUTH_GENERIC_CLIENT_SECRET`,label:`GENERIC_CLIENT_SECRET`},{key:`OAUTH_GENERIC_NAME`,label:`GENERIC_NAME`,placeholder:`generic`}]}];function ut(a){let s=()=>y.can(`config:write`)||y.can(`system:manage`)||y.isAdminOrAbove(),[u,d]=b(null),[f,p]=b({}),[g,_]=b(!1),[E,O]=b(null),[k,ne]=b(!1),[A,M]=b(0),N=async()=>{try{let e=await h.manageRuntimeConfig();d(e),p({...e.values})}catch(e){O({tone:`error`,text:String(e?.message||e)})}};o(N),c(()=>{y.check()});let P=()=>{let e=u();if(!e)return!1;let t=f();return Object.keys(t).some(n=>(t[n]??``)!==(e.values[n]??``))},F=(e,t)=>p(n=>({...n,[e]:t})),I=async()=>{if(!s()){O({tone:`error`,text:`无权限:需要 admin/root`});return}let e=u();if(!e)return;let t={},n=f();for(let r of Object.keys(n))if((n[r]??``)!==(e.values[r]??``)){if(e.masked[r]&&n[r]===`••••••••`)continue;t[r]=n[r]??``}if(Object.keys(t).length===0){O({tone:`info`,text:`没有变更`});return}_(!0);try{let e=await h.saveRuntimeConfig(t);O({tone:`success`,text:`已保存 ${e.changed?.length??0} 项,已热生效,无需重启`});let n=await h.manageRuntimeConfig();d(n),p({...n.values})}catch(e){O({tone:`error`,text:String(e?.message||e)})}finally{_(!1)}},re=async()=>{if(!s()||!confirm(`将当前分组的运行时覆盖重置为环境/默认值?`))return;let e=lt[A()];try{await h.resetRuntimeConfig(e.keys.map(e=>e.key)),O({tone:`success`,text:`已重置,已热生效`}),await N()}catch(e){O({tone:`error`,text:String(e?.message||e)})}},L=async()=>{if(!(!s()||!confirm(`重置所有运行时覆盖?将回落至环境变量/默认值并立即生效。`)))try{await h.resetRuntimeConfig([]),O({tone:`success`,text:`已重置全部,已热生效`}),await N()}catch(e){O({tone:`error`,text:String(e?.message||e)})}};return(()=>{var o=tt(),c=o.firstChild,d=c.firstChild,p=d.firstChild,h=p.firstChild,_=d.nextSibling,y=c.nextSibling.firstChild,b=y.firstChild,R=y.nextSibling,z=R.firstChild,B=z.firstChild,V=B.firstChild,ie=V.firstChild,H=V.nextSibling,U=H.firstChild,G=B.nextSibling.firstChild,oe=G.firstChild,q=G.nextSibling;return q.firstChild.nextSibling.nextSibling,t(o,l(i,{get when(){return E()},get children(){return l(S,{get tone(){return e(()=>E().tone===`error`)()?`error`:E().tone===`success`?`success`:`info`},class:`flex items-center justify-between gap-3`,get children(){return[(()=>{var e=$e();return t(e,l(w,{class:`size-4`}),null),t(e,()=>E().text,null),e})(),(()=>{var e=et();return e.$$click=()=>O(null),e})()]}})}}),c),t(p,l(K,{class:`size-4`}),h),t(_,l(i,{get when(){return!s()},get children(){return l(v,{variant:`warning`,children:`只读`})}}),null),t(_,l(i,{get when(){return s()},get children(){return l(x,{variant:`ghost`,class:`h-9 gap-1.5`,onClick:()=>ne(e=>!e),get children(){return[e(()=>e(()=>!!k())()?l(te,{class:`size-4`}):l(ee,{class:`size-4`})),e(()=>k()?`隐藏密钥`:`显示密钥`)]}})}}),null),t(_,l(x,{variant:`outline`,class:`h-9 gap-1.5`,onClick:N,get disabled(){return g()},children:`刷新`}),null),t(_,l(x,{variant:`ghost`,class:`h-9 gap-1.5`,onClick:re,get disabled(){return!s()||g()},get children(){return[l(ae,{class:`size-4`}),`重置分组`]}}),null),t(_,l(x,{variant:`ghost`,class:`h-9 gap-1.5`,onClick:L,get disabled(){return!s()||g()},children:`重置全部`}),null),t(_,l(x,{class:`h-9 gap-1.5`,onClick:I,get disabled(){return!s()||g()||!P()},get children(){return[l(W,{class:`size-4`}),e(()=>e(()=>!!g())()?`保存中...`:P()?`保存并生效`:`已是最新`)]}}),null),t(y,l(n,{each:lt,children:(e,n)=>{let i=e.icon,a=()=>n()===A();return(()=>{var o=nt(),s=o.firstChild;return o.$$click=()=>M(n()),t(o,l(i,{class:`size-3.5 shrink-0`}),s),t(s,()=>e.title),r(()=>T(o,`flex items-center gap-2 border px-3 py-2.5 text-left text-xs font-medium transition-colors ${a()?`border-line bg-acid-lime text-black`:`border-transparent bg-card text-muted-foreground hover:bg-accent hover:text-foreground`}`)),o})()}}),b),t(R,l(i,{get when(){return u()},get fallback(){return rt()},get children(){return(()=>{let e=lt[A()];return(()=>{var a=it(),o=a.firstChild,c=o.firstChild,d=c.nextSibling,p=d.firstChild,h=o.nextSibling;return t(c,()=>e.title),t(d,()=>e.keys.length,p),t(h,l(n,{get each(){return e.keys},children:e=>{let n=()=>u().source[e.key]||`default`,a=()=>!!u().masked[e.key],o=()=>f()[e.key]??``,c=()=>n()===`runtime`?`bg-acid-lime`:n()===`env`?`bg-acid-cyan`:`bg-line`;return(()=>{var u=st(),d=u.firstChild,f=d.firstChild,p=f.firstChild,h=p.nextSibling,g=h.firstChild,_=d.nextSibling;return t(p,()=>e.label),t(h,n,null),t(f,l(i,{get when(){return a()},get children(){return l(v,{variant:`outline`,class:`text-[10px]`,children:`secret`})}}),null),t(d,l(i,{get when(){return e.hint},get children(){var n=at();return t(n,()=>e.hint),n}}),null),t(d,l(i,{get when(){return e.placeholder},get children(){var n=ot();return n.firstChild,t(n,()=>e.placeholder,null),n}}),null),t(_,l(i,{get when(){return e.type===`bool`},get fallback(){return l(m,{get value(){return o()},onInput:t=>F(e.key,t),get placeholder(){return e.placeholder||``},get type(){return a()&&!k()?`password`:`text`},get disabled(){return!s()},class:`h-9 font-mono text-xs`})},get children(){return l(C,{get value(){return o()||`0`},onChange:t=>F(e.key,t),options:[{value:`0`,label:`关闭 (0)`},{value:`1`,label:`开启 (1)`}],get disabled(){return!s()}})}})),r(e=>{var t=`inline-flex items-center gap-1 border px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-widest ${n()===`runtime`?`border-acid-lime/40 bg-acid-lime/15 text-foreground`:n()===`env`?`border-acid-cyan/40 bg-acid-cyan/10 text-foreground`:`border-line bg-muted text-muted-foreground`}`,r=`size-1.5 ${c()}`;return t!==e.e&&T(h,e.e=t),r!==e.t&&T(g,e.t=r),e},{e:void 0,t:void 0}),u})()}})),a})()})()}}),z),t(V,l(j,{class:`size-4`}),ie),t(H,l(n,{get each(){return a.overview?.backends||[]},children:e=>(()=>{var n=ct(),r=n.firstChild;return t(r,l(j,{class:`size-4 text-muted-foreground`}),null),t(r,()=>e.name||e.kind,null),t(n,l(v,{get variant(){return e.configured?`success`:`muted`},get children(){return e.configured?`已配置`:`未配置`}}),null),n})()}),U),t(G,l(w,{class:`size-4`}),oe),t(q,l(x,{variant:`ghost`,class:`mt-2 h-8 gap-1.5 text-xs`,onClick:()=>window.open(`/api/manage/config?raw=1`,`_blank`),get children(){return[l(D,{class:`size-4`}),`查看原始 JSON`]}}),null),o})()}s([`click`]);var dt=a(`系统用户与全局角色 users`),ft=a(`暂无用户`),pt=a(``),mt=a(`banned`),ht=a(` · `),gt=a(`无权变更`);function _t(e){let a=t=>e.actorRole===`root`?[`viewer`,`publisher`,`admin`,`root`]:e.actorRole===`admin`?t===`admin`||t===`root`?[]:[`viewer`,`publisher`]:[],o=t=>e.actorRole===`root`?t.role!==`root`:e.actorRole===`admin`?t.role===`viewer`||t.role===`publisher`:!1;return(()=>{var s=dt(),c=s.firstChild.firstChild.nextSibling,u=c.firstChild;return t(c,()=>e.users.length,u),t(s,l(i,{get when(){return!e.canList},get fallback(){return(()=>{var s=pt();return t(s,l(n,{get each(){return e.users},children:n=>{let s=n.role,c=$[s]||$.viewer,u=n.status===`banned`,d=a(s),f=d.length>0;return(()=>{var a=ht(),p=a.firstChild,m=p.firstChild,h=m.nextSibling.firstChild,g=h.firstChild,_=h.nextSibling,y=_.firstChild,b=p.nextSibling;return T(a,`flex flex-wrap items-center justify-between gap-3 border-b border-line/60 px-5 py-3 last:border-0 ${u?`bg-destructive/5`:``}`),t(m,()=>(n.username[0]||`?`).toUpperCase()),t(h,()=>n.username,g),t(h,l(i,{when:u,get children(){return mt()}}),null),t(_,s,y),t(_,u?`已封禁`:`active`,null),t(b,l(v,{get class(){return c.color},children:s}),null),t(b,l(i,{when:f,get fallback(){return gt()},get children(){return l(C,{class:`w-28`,value:s,get"aria-label"(){return`调整 ${n.username} 的角色`},get disabled(){return!!e.busy||u},onChange:async t=>e.onRoleChange(n,t),get options(){return d.map(e=>({value:e,label:e}))}})}}),null),t(b,l(i,{get when(){return o(n)},get children(){return l(x,{variant:u?`outline`:`ghost`,class:`h-7 px-2 text-xs ${u?`border-success/30 text-success`:`text-destructive`}`,get disabled(){return e.busy===n.username},onClick:()=>e.onToggleBan(n),children:u?`解封`:`封禁`})}}),null),r(()=>T(m,`flex size-8 shrink-0 items-center justify-center border font-mono text-xs font-bold ${c.color}`)),a})()}}),null),t(s,l(i,{get when(){return e.users.length===0},get children(){return ft()}}),null),s})()},get children(){return l(S,{tone:`warning`,class:`m-4`,children:`无权限查看:需要 user:list(管理员及以上)`})}}),null),s})()}var vt=a(``),yt=a(`关闭`),bt=()=>{let[n,r]=b(`overview`),[a,o]=b(null),[s,u]=b([]),[d,f]=b(null),[p,m]=b(``),[g,C]=b([]),[w,T]=b(``),[ee,te]=b(!1),[E,D]=b(``),[O,k]=b(``),[ne,A]=b(!0),[j,N]=b(`100`),[F,I]=b(``),[re,L]=b(!1),[R,z]=b(null),[B,V]=b(``),[H,ae]=b(``),[U,W]=b(null),[G,K]=b(null),[oe,q]=b([]),[se,J]=b(``),Y=async()=>{try{let e=await h.manageOverview();o(e)}catch(e){T(String(e?.message||e))}},X=async()=>{try{let e=await h.manageRooms();u(e.rooms||[]),!p()&&e.rooms?.length&&m(e.rooms[0].room.name)}catch(e){T(String(e?.message||e))}},ce=async()=>{try{let e=await h.managePermMatrix();f(e)}catch{}},le=async()=>{try{let e=await h.listUsers();q(e.users||[])}catch{}},Z=async e=>{if(e)try{let t=await h.manageMembers(e);C(t.members||[]);let n=await h.manageRoomDetail(e);z(n.room),V(n.room.description||``),ae(String(n.room.max_members||100)),W(n.room.settings||null);try{let t=await h.manageRoomDistribution(e);K(t)}catch{K(null)}}catch(e){T(String(e?.message||e))}};c(()=>{Y(),X(),ce(),le()}),c(()=>{let e=p();e&&(n()===`rooms`||n()===`permissions`)&&Z(e)});let de=async()=>{let e=E().trim();if(e){te(!0);try{await h.manageCreateRoom({name:e,description:O().trim()||void 0,is_public:ne(),max_members:parseInt(j())||100,password:F().trim()||void 0}),D(``),k(``),I(``),await X(),await Y()}catch(e){T(String(e?.message||e))}finally{te(!1)}}},fe=async()=>{let e=p();if(!(!e||!R()))try{await h.manageUpdateRoom(e,{description:B(),max_members:parseInt(H())||void 0,is_public:R().is_public}),await X(),await Z(e)}catch(e){T(String(e?.message||e))}},pe=async e=>{if(confirm(`删除房间 ${e} ?`))try{await h.manageDeleteRoom(e),await X(),await Y()}catch(e){T(String(e?.message||e))}},me=async(e,t,n)=>{try{await h.manageUpdateMemberRole(e,t,n),await Z(e)}catch(e){T(String(e?.message||e))}},_e=async(e,t)=>{if(confirm(`踢出 ${t} ?`))try{await h.manageKickMember(e,t),await Z(e)}catch(e){T(String(e?.message||e))}},ve=async(e,t)=>{try{await h.manageBanMember(e,t),await Z(e)}catch(e){T(String(e?.message||e))}},ye=async(e,t)=>{try{await h.manageApproveMember(e,t),await Z(e)}catch(e){T(String(e?.message||e))}},be=async(e,t)=>{try{await h.manageRejectMember(e,t),await Z(e)}catch(e){T(String(e?.message||e))}},xe=async(e,t)=>{try{await h.manageTransferOwnership(e,t),await Z(e),await X()}catch(e){T(String(e?.message||e))}},Se=async(e,t,n,r)=>{let i=1<e.username===t);if(!a)return;let o=Number(a.added||0),s=Number(a.removed||0);r?(o&=~i,s|=i):(o|=i,s&=~i);try{await h.manageUpdateMemberPerms(e,t,o,s,!1),await Z(e)}catch(e){T(String(e?.message||e))}},Q=async()=>{let e=p();if(!(!e||!U()))try{await h.manageUpdateRoomSettings(e,U()),await Z(e)}catch(e){T(String(e?.message||e))}},Te=async(e,t)=>{let n=p();if(!n)return;let r=new Set(G()?.effective||[]);t?r.add(e):r.delete(e);let i=Array.from(r);try{let e=await h.manageUpdateRoomDistributionList(n,i);K(t=>({...t||{},effective:e.effective,custom:e.distributors,has_custom:!0,custom_list:e.effective})),await Z(n)}catch(e){T(String(e?.message||e))}},$=async()=>{let e=p();if(e)try{let t=await h.manageClearRoomDistribution(e);K(e=>({...e||{},effective:t.effective,has_custom:!1,custom:null,custom_list:[]})),await Z(e)}catch(e){T(String(e?.message||e))}},Ee=async(e,t)=>{J(e.username);try{await h.updateUserRole(e.username,t),q(n=>n.map(n=>n.username===e.username?{...n,role:t}:n)),await y.refresh()}catch(e){T(String(e?.message||e))}finally{J(``)}},De=async e=>{let t=e.status===`banned`;if(confirm(t?`解封 ${e.username}?`:`封禁 ${e.username}?封禁后无法登录`)){J(e.username);try{t?await h.unbanUser(e.username):await h.banUser(e.username),await le()}catch(e){T(String(e?.message||e))}finally{J(``)}}};return l(he,{get children(){return[l(ge,{title:`管理控制台`,description:`统一管理房间、角色与权限。房主全量,管理员/成员/访客基于角色默认值 + 个人覆盖计算生效权限。全局管理员(admin/root)可跨房间管理,无需加入房间。`,get actions(){return[l(v,{variant:`outline`,class:`gap-1.5`,get children(){return[l(P,{class:`size-3.5`}),e(()=>_.user()?.username||`guest`),` · `,e(()=>y.role())]}}),l(x,{variant:`ghost`,class:`h-9 gap-1.5`,onClick:()=>{Y(),X(),le(),p()&&Z(p())},get children(){return[l(ie,{class:`size-4`}),`刷新`]}})]}}),l(i,{get when(){return w()},get children(){return l(S,{tone:`error`,class:`flex items-center justify-between gap-3`,get children(){return[(()=>{var e=vt();return t(e,l(M,{class:`size-4`}),null),t(e,w,null),e})(),(()=>{var e=yt();return e.$$click=()=>T(``),e})()]}})}}),l(ue,{get value(){return n()},onChange:r}),l(i,{get when(){return n()===`overview`},get children(){return l(Ce,{get overview(){return a()},get rooms(){return s()}})}}),l(i,{get when(){return n()===`rooms`},get children(){return l(Be,{get rooms(){return s()},get selectedRoom(){return p()},onSelectRoom:m,get members(){return g()},get editingRoom(){return R()},get roomSettings(){return U()},setRoomSettings:W,get newRoom(){return{name:E(),desc:O(),isPublic:ne(),max:j(),pwd:F(),showPwd:re()}},setNewRoom:e=>{e.name!==void 0&&D(e.name),e.desc!==void 0&&k(e.desc),e.isPublic!==void 0&&A(e.isPublic),e.max!==void 0&&N(e.max),e.pwd!==void 0&&I(e.pwd),e.showPwd!==void 0&&L(e.showPwd)},get edit(){return{desc:B(),max:H()}},setEdit:e=>{e.desc!==void 0&&V(e.desc),e.max!==void 0&&ae(e.max)},get loading(){return ee()},onCreate:de,onSave:fe,onDelete:pe,onChangeRole:me,onKick:_e,onBan:ve,onApprove:ye,onReject:be,onTransfer:xe,onSaveSettings:Q,get distribution(){return G()},onToggleDistribution:Te,onClearDistribution:$})}}),l(i,{get when(){return n()===`permissions`},get children(){return l(Qe,{get rooms(){return s()},get selectedRoom(){return p()},onSelectRoom:m,get members(){return g()},get permDefs(){return d()},onTogglePerm:Se})}}),l(i,{get when(){return n()===`users`},get children(){return l(_t,{get users(){return oe()},onRoleChange:Ee,onToggleBan:De,get canList(){return y.can(`user:list`)},get actorRole(){return y.role()},get busy(){return se()}})}}),l(i,{get when(){return n()===`system`},get children(){return l(ut,{get overview(){return a()}})}})]}})};s([`click`]);export{bt as Manage};
`),ot=a(`
示例:`),st=a(`
暂无用户`),pt=a(`
·