live-sfu-demo/internal/server/static/assets/manage-D14QE2VO.js

1 line
47 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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(`<div class="flex flex-wrap gap-1.5">`),le=a(`<button type=button>`),Z=[{path:`overview`,label:`概览`,icon:B,perms:[`room:list`]},{path:`rooms`,label:`房间`,icon:j,perms:[`room:manage`]},{path:`permissions`,label:`权限`,icon:R,perms:[`room:manage`]},{path:`users`,label:`用户`,icon:A,perms:[`user:list`]},{path:`system`,label:`系统`,icon:K,perms:[`system:manage`,`config:read`]}];function ue(e){F();let i=u(()=>Z.filter(e=>e.perms.some(e=>y.can(e))||y.isAdminOrAbove()));return(()=>{var a=ce();return t(a,l(n,{get each(){return i()},children:n=>{let i=n.icon,a=()=>e.value===n.path;return(()=>{var o=le();return o.$$click=()=>e.onChange(n.path),t(o,l(i,{class:`size-3.5`}),null),t(o,()=>n.label,null),r(e=>{var t=`inline-flex h-9 items-center gap-1.5 border px-3 text-xs font-medium transition-colors ${a()?`border-line bg-acid-lime text-black`:`border-line bg-card text-muted-foreground hover:bg-accent`}`,n=a()?`page`:void 0;return t!==e.e&&T(o,e.e=t),n!==e.t&&g(o,`aria-current`,e.t=n),e},{e:void 0,t:void 0}),o})()}})),a})()}s([`click`]);var de=a(`<div>`),fe=a(`<p class="mt-3 max-w-2xl text-sm text-muted-foreground">`),pe=a(`<div class="flex shrink-0 items-center gap-2">`),me=a(`<div class="flex flex-wrap items-start justify-between gap-4"><div class="min-w-0 flex-1"><p class="mono-label text-muted-foreground">manage / console</p><h1 class="display mt-2 text-4xl sm:text-5xl">`);function he(e){return(()=>{var n=de();return t(n,()=>e.children),r(()=>T(n,`mx-auto max-w-[1400px] space-y-6 px-4 py-8 sm:px-6 sm:py-10 ${e.class??``}`)),n})()}function ge(e){return(()=>{var n=me(),r=n.firstChild,a=r.firstChild.nextSibling;return t(a,()=>e.title),t(r,l(i,{get when(){return e.description},get children(){var n=fe();return t(n,()=>e.description),n}}),null),t(n,l(i,{get when(){return e.actions},get children(){var n=pe();return t(n,()=>e.actions),n}}),null),n})()}var _e=a(`<p class="mt-1 text-xs text-muted-foreground">`),ve=a(`<div class="relative border border-line bg-card/60 p-4"><div class="flex items-start justify-between gap-3"><div><p class="micro-label text-muted-foreground"></p><p class="display mt-2 text-3xl"></p></div><span class="flex size-8 items-center justify-center border border-line bg-background text-muted-foreground">`),ye=a(`<p class="py-6 text-center text-sm text-muted-foreground">暂无房间数据`),be=a(`<div class=space-y-6><div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4"></div><div class="grid gap-4 lg:grid-cols-3"><div class="border border-line bg-card/50 p-4 lg:col-span-2"><div class="flex items-center justify-between gap-3"><h3 class=font-semibold>房间分发状态</h3><span class="mono-label text-muted-foreground"> rooms</span></div><div class="mt-4 space-y-2"></div></div><div class="border border-line bg-card/50 p-4"><h3 class=font-semibold>后端能力</h3><div class="mt-4 space-y-2">`),xe=a(`<div class="flex items-center justify-between gap-3 border border-line/60 bg-background/50 px-3 py-2.5"><div class="flex min-w-0 items-center gap-2.5"><span class="truncate font-mono text-sm"></span></div><div class="flex items-center gap-3 text-xs text-muted-foreground"><span class="hidden sm:inline"> 成员</span><span> targets`),Se=a(`<div class="flex items-center justify-between border border-line/60 px-3 py-2.5"><span class="font-mono text-xs uppercase">`);function Q(e){let n=e.icon;return(()=>{var r=ve(),a=r.firstChild.firstChild,o=a.firstChild,s=o.nextSibling,c=a.nextSibling;return t(o,()=>e.label),t(s,()=>e.value),t(a,l(i,{get when(){return e.hint},get children(){var n=_e();return t(n,()=>e.hint),n}}),null),t(c,l(n,{class:`size-4`})),r})()}function Ce(e){let r=()=>e.overview,a=()=>e.rooms;return(()=>{var e=be(),o=e.firstChild,s=o.nextSibling.firstChild,c=s.firstChild,u=c.firstChild.nextSibling,d=u.firstChild,p=c.nextSibling,m=s.nextSibling.firstChild.nextSibling;return t(o,l(Q,{label:`房间总数`,get value(){return r()?.rooms_total??`-`},get hint(){return`${r()?.rooms_live??0} 个正在直播`},icon:B}),null),t(o,l(Q,{label:`在线房间`,get value(){return r()?.rooms_live??`-`},hint:`有推流目标的房间`,icon:X}),null),t(o,l(Q,{label:`房间成员`,get value(){return r()?.members_total??`-`},hint:`所有房间成员汇总`,icon:A}),null),t(o,l(Q,{label:`系统用户`,get value(){return r()?.users_total??`-`},hint:`已注册账号`,icon:P}),null),t(u,()=>a().length,d),t(p,l(n,{get each(){return a().slice(0,6)},children:e=>(()=>{var n=xe(),r=n.firstChild,i=r.firstChild,a=r.nextSibling.firstChild,o=a.firstChild,s=a.nextSibling,c=s.firstChild;return t(r,l(f,{get active(){return e.live}}),i),t(i,()=>e.room.name),t(r,l(v,{get variant(){return e.live?`success`:`muted`},class:`hidden sm:inline-flex`,get children(){return e.live?`LIVE`:`IDLE`}}),null),t(a,()=>e.member_count,o),t(s,()=>e.targets?.length??0,c),n})()}),null),t(p,l(i,{get when(){return a().length===0},get children(){return ye()}}),null),t(m,l(n,{get each(){return r()?.backends||[]},children:e=>(()=>{var n=Se(),r=n.firstChild;return t(r,()=>e.name||e.kind),t(n,l(v,{get variant(){return e.configured?`success`:`muted`},get children(){return e.configured?`已配置`:`未配置`}}),null),n})()})),e})()}var we=[`send_chat`,`view_chat_history`,`view_members`,`subscribe`,`watch_room`,`publish`,`stop_stream`,`broadcast`,`manage_members`,`add_members`,`remove_members`,`manage_permissions`,`manage_room`,`delete_room`,`delete_chat_messages`,`control_stream`],Te={send_chat:`发弹幕`,view_chat_history:`看记录`,view_members:`看成员`,subscribe:`拉流`,watch_room:`监听`,publish:`推流`,stop_stream:`停播`,broadcast:`广播`,manage_members:`管成员`,add_members:`邀成员`,remove_members:`踢人`,manage_permissions:`管权限`,manage_room:`管房间`,delete_room:`删房间`,delete_chat_messages:`删消息`,control_stream:`控流`},$={creator:{label:`房主`,color:`border-amber-400/40 bg-amber-400/10 text-amber-600`},admin:{label:`管理员`,color:`border-acid-magenta/30 bg-acid-magenta/10 text-acid-magenta`},member:{label:`成员`,color:`border-acid-cyan/30 bg-acid-cyan/10 text-acid-cyan`},guest:{label:`访客`,color:`border-line bg-muted text-muted-foreground`},root:{label:`超管`,color:`border-amber-500/40 bg-amber-500/10 text-amber-600`},viewer:{label:`观看者`,color:`border-acid-cyan/30 bg-acid-cyan/10 text-acid-cyan`},publisher:{label:`发布者`,color:`border-warning/30 bg-warning/10 text-warning`}},Ee=a(`<div class="border border-line bg-card/60 p-4"><div class="flex flex-wrap items-start justify-between gap-3"><div class=min-w-0><p class="mono-label text-muted-foreground">room / </p><h3 class="display mt-1 truncate text-2xl"></h3><p class="text-xs text-muted-foreground">创建者 <!> · 状态 </p></div></div><div class="mt-4 grid gap-3 sm:grid-cols-2"><div class=space-y-1.5><label class=label>描述</label><input class=field></div><div class=space-y-1.5><label class=label>人数上限</label><input class="field field-mono"></div></div><div class="mt-3 flex flex-wrap gap-2">`),De=a(`<div class="border border-warning/30 bg-warning/10"><div class="flex items-center justify-between border-b border-warning/20 px-4 py-3"><h4 class="flex items-center gap-2 font-semibold text-warning"> 待审批 </h4></div><div class="divide-y divide-warning/20">`),Oe=a(`<p class="px-4 py-6 text-sm text-muted-foreground">暂无活跃成员`),ke=a(`<div class="border border-line bg-card/50"><div class="flex items-center justify-between border-b border-line/80 px-4 py-3"><h4 class=font-semibold>成员 <!> <span class="text-xs font-normal text-muted-foreground">· 含待审批 </span></h4></div><div class="divide-y divide-line/60">`),Ae=a(`<div class="mt-4 grid gap-4 sm:grid-cols-2"><label class="flex items-center justify-between gap-3 border border-line bg-background px-3 py-2.5"><span class="flex items-center gap-2 text-sm"> 聊天</span><input type=checkbox></label><label class="flex items-center justify-between gap-3 border border-line bg-background px-3 py-2.5"><span class="flex items-center gap-2 text-sm"> 访客加入</span><input type=checkbox></label><label class="flex items-center justify-between gap-3 border border-line bg-background px-3 py-2.5"><span class="flex items-center gap-2 text-sm"> 需审批</span><input type=checkbox></label><label class="flex items-center justify-between gap-3 border border-line bg-background px-3 py-2.5"><span class="flex items-center gap-2 text-sm"> 公开</span><input type=checkbox>`),je=a(`<div class="border border-line bg-card/50 p-4"><h4 class="flex items-center gap-2 font-semibold">房间设置`),Me=a(`<div class="border border-line bg-card/50 p-4"><div class="flex items-center justify-between gap-2"><h4 class="flex items-center gap-2 font-semibold">分发设置</h4></div><p class="mt-1.5 text-xs text-muted-foreground">全局:<!> · 生效:</p><div class="mt-3 grid gap-2 sm:grid-cols-3"></div><p class="mt-2 text-[11px] text-muted-foreground">未设置时自动使用全局分发;勾选即为该房间单独覆盖(可为空表示关闭全部)。`),Ne=a(`<div class="grid gap-4 lg:grid-cols-3"><div class="lg:col-span-1 space-y-4"><div class="border border-line bg-card/60 p-4"><h3 class=font-semibold>创建房间</h3><div class="mt-4 space-y-3"><div class=space-y-1.5><label class=label>房间名 *</label><div class="flex items-center gap-2 border border-line bg-background px-3 py-2 focus-within:border-ring"><input class="w-full bg-transparent font-mono text-sm outline-none"placeholder="如 live-101"></div></div><div class=space-y-1.5><label class=label>描述</label><input class=field placeholder=一句话介绍></div><div class="grid grid-cols-2 gap-3"><div class=space-y-1.5><label class=label>可见性</label></div><div class=space-y-1.5><label class=label>人数上限</label><input class="field field-mono"></div></div><div class=space-y-1.5><label class=label>房间密码(可选)</label><div class="flex items-center gap-2 border border-line bg-background px-3 py-2 focus-within:border-ring"><input class="w-full bg-transparent font-mono text-sm outline-none"placeholder=留空为无密码><button type=button class=text-muted-foreground></button></div></div></div></div><div class="border border-line bg-card/50"><div class="flex items-center justify-between border-b border-line/80 px-4 py-3"><h3 class=font-semibold>房间列表</h3><span class="mono-label text-muted-foreground"></span></div><div class="max-h-[480px] overflow-auto"></div></div></div><div class="space-y-4 lg:col-span-2">`),Pe=a(`<button type=button><div class=min-w-0><p class="truncate font-mono text-sm font-medium"></p><p class="truncate text-xs text-muted-foreground"></p></div><div class="flex shrink-0 flex-col items-end gap-1"><span class="micro-label text-muted-foreground"> 成员`),Fe=a(`<div class="border border-dashed border-line p-8 text-center text-sm text-muted-foreground">选择一个房间以管理`),Ie=a(`<div class="flex flex-wrap items-center justify-between gap-3 px-4 py-3"><span class="font-mono text-sm"> <span class="text-xs text-muted-foreground">· </span></span><div class="flex gap-2">`),Le=a(`<div class="flex flex-wrap items-center gap-3 px-4 py-3"><span></span><div class="min-w-0 flex-1"><p class="truncate font-mono text-sm font-medium flex items-center gap-1.5"> <!> </p><p class="micro-label truncate text-muted-foreground"></p></div><div class="flex items-center gap-1">`),Re=a(`<p class="mt-3 text-sm text-muted-foreground">加载中…`),ze=a(`<label class="flex items-center justify-between gap-2 border border-line bg-background px-3 py-2.5"><span class="text-sm font-mono"></span><input type=checkbox>`);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(`<div class=overflow-auto><table class="w-full min-w-[900px] border-collapse"><thead><tr class="border-b border-line bg-muted/20"><th class="px-3 py-2 text-left text-xs font-mono text-muted-foreground">成员 / 角色</th></tr></thead><tbody>`),He=a(`<div class=space-y-4><div class="border border-line bg-card/60 p-4"><h3 class=font-semibold>角色默认权限</h3><p class="mt-1 text-xs text-muted-foreground">Creator 全量 · Guest 只读,个人覆盖 added/removed 生效。</p><div class="mt-4 overflow-auto"><table class="w-full min-w-[520px] border-collapse text-xs"><thead><tr class="border-b border-line"><th class="px-2 py-2 text-left font-mono text-muted-foreground">permission</th></tr></thead><tbody></tbody></table></div></div><div class="border border-line bg-card/50"><div class="flex flex-wrap items-center justify-between gap-3 border-b border-line/80 px-4 py-3"><h3 class=font-semibold>成员生效权限 · `),Ue=a(`<th class="px-2 py-2 text-center font-mono text-muted-foreground">`),We=a(`<tr class="border-b border-line/60"><td class="px-2 py-2 font-mono">`),Ge=a(`<td class="px-2 py-2 text-center">`),Ke=a(`<span class="inline-flex size-2 bg-acid-lime">`),qe=a(`<span class="inline-flex size-2 border border-line">`),Je=a(`<p class="px-4 py-8 text-center text-sm text-muted-foreground">请选择房间`),Ye=a(`<th class="px-1 py-2 text-center text-[10px] font-mono text-muted-foreground">`),Xe=a(`<tr class="border-b border-line/40"><td class="px-3 py-2"><div class="flex items-center gap-2"><span class="font-mono text-xs font-medium">`),Ze=a(`<td class="px-1 py-1 text-center"><button type=button>`);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(`<span class="flex items-center gap-2">`),et=a(`<button class="text-xs underline">关闭`),tt=a(`<div class=space-y-4><div class="flex flex-wrap items-center justify-between gap-3 border border-line bg-card/60 px-4 py-3"><div class=min-w-0><h3 class="flex items-center gap-2 text-sm font-semibold">运行时配置</h3><p class="mt-1 text-xs text-muted-foreground">修改后立即热生效并持久化到 <span class=font-mono>data/runtime_config.json</span>,无需重启。优先级:运行时覆盖 &gt; 环境变量 &gt; 默认值。</p></div><div class="flex shrink-0 flex-wrap items-center gap-2"></div></div><div class="grid gap-4 xl:grid-cols-[220px_1fr]"><div class="flex h-fit flex-col gap-1 border border-line bg-card/40 p-2 xl:sticky xl:top-[88px]"><div class="mt-2 border-t border-line/60 pt-3"><div class="space-y-2 px-2 text-[11px] leading-relaxed text-muted-foreground"><p class="font-medium text-foreground">来源标记</p><p><span class="inline-flex items-center gap-1"><span class="size-2 bg-acid-lime"></span> runtime</span> 运行时覆盖</p><p><span class="inline-flex items-center gap-1"><span class="size-2 bg-acid-cyan"></span> env</span> 环境变量</p><p><span class="inline-flex items-center gap-1"><span class="size-2 bg-line"></span> default</span> 默认值</p></div></div></div><div class="min-w-0 space-y-4"><div class="grid gap-4 lg:grid-cols-2"><div class="border border-line bg-card/40 p-4"><h4 class="flex items-center gap-2 text-sm font-semibold">SFU 状态(只读)</h4><div class="mt-3 space-y-2 text-sm"><div class="flex items-center justify-between border border-line bg-background px-3 py-2.5"><span class=text-muted-foreground>HTTP</span><span class="font-mono text-xs">8088</span></div><div class="flex items-center justify-between border border-line bg-background px-3 py-2.5"><span class=text-muted-foreground>gRPC</span><span class="font-mono text-xs">9090</span></div></div></div><div class="border border-line bg-card/40 p-4"><h4 class="flex items-center gap-2 text-sm font-semibold">说明</h4><div class="mt-3 space-y-2 text-xs leading-relaxed text-muted-foreground"><p>保存即热生效:Cloudflare/SRS/CDN/分发开关等无需重启。</p><p>密钥字段默认以 <span class=font-mono>••••••••</span> 脱敏回显;不修改则保持原值。</p><p>重置会删除运行时覆盖,回落至环境变量或默认值。`),nt=a(`<button type=button><span class="min-w-0 flex-1 truncate">`),rt=a(`<div class="border border-line bg-card/40 px-4 py-12 text-center text-sm text-muted-foreground">加载中...`),it=a(`<div class="border border-line bg-card/60"><div class="flex items-center justify-between gap-3 border-b border-line/80 px-4 py-3"><span class="text-sm font-semibold"></span><span class="text-xs text-muted-foreground"> 项</span></div><div class="divide-y divide-line/60">`),at=a(`<p class="mt-1 text-xs text-muted-foreground">`),ot=a(`<p class="mt-0.5 font-mono text-[11px] text-muted-foreground/70">示例:`),st=a(`<div class="flex flex-col gap-2 px-4 py-3 sm:flex-row sm:items-start sm:gap-4"><div class="min-w-0 flex-1"><div class="flex flex-wrap items-center gap-2"><span class="font-mono text-xs font-medium"></span><span><span></span></span></div></div><div class="w-full shrink-0 sm:w-[min(420px,55%)]">`),ct=a(`<div class="flex items-center justify-between border border-line bg-background px-3 py-2.5"><span class="flex items-center gap-2">`),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(`<div class="border border-line bg-card/50"><div class="flex items-center justify-between border-b border-line/80 px-4 py-3"><h3 class=font-semibold>系统用户与全局角色</h3><span class="mono-label text-muted-foreground"> users`),ft=a(`<p class="px-5 py-6 text-sm text-muted-foreground">暂无用户`),pt=a(`<div>`),mt=a(`<span class="text-[10px] px-1.5 py-0.5 border border-destructive/30 bg-destructive/10 text-destructive">banned`),ht=a(`<div><div class="flex min-w-0 items-center gap-3"><span></span><div class=min-w-0><p class="truncate font-mono text-sm font-medium flex items-center gap-2"> </p><p class="micro-label text-muted-foreground"> · </p></div></div><div class="flex flex-wrap items-center gap-2">`),gt=a(`<span class="text-xs text-muted-foreground/60">无权变更`);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(`<span class="flex items-center gap-2">`),yt=a(`<button class="text-xs underline">关闭`),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<<we.indexOf(n),a=g().find(e=>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};