// ==UserScript== // @name 火箭按钮 // @description 一个常驻所有网页的悬浮「瑞士军刀」——单击平滑返回顶部,悬停展开快捷菜单,并能挂载插件扩展能力(内置 GitHub 下载加速、划词翻译、定时提醒,也可导入用户插件)。 // @match *://* // @include * // @grant GM_getValue // @grant GM_setValue // @grant GM_xmlhttpRequest // @grant GM_addValueChangeListener // @grant GM_removeValueChangeListener // @grant unsafeWindow // @run-at document-end // @license All Rights Reserved // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACxUlEQVR4nO3dMW8SYRzH8duKg5Nuhdo3UNib+hoUlqeNielm1LVLt7obEyOkATqQmG6Y6FSXGh3VOBjQNlUDDQ+yOPEGzjwrPFdLwD6/g+8n+U+Xu3ue+6YJhaZEEQDgf7tX+5o1tVbXN+5Y6PUtHLN/srpZb8e+ccdCr2/hGIJoMQTRYgiixRAkjK1qe8PUWo2xqbebiUHq7abvHHet0PtJPVNrbyc9+EnHXSv0flLPEESLIYgWQxAthiBaDEG0GIJoMQTRYgiixRBEiyFIGFvV05vuTcGxOWjtzCzIQWvHdw9379D7l+Pe/Nuc0YOf/Cen1Qi9fzkEEUMQMQQRQxAxBEl5kAcvv8ftHz3vuGMEueIgjw9P4t/9vnceHRJkagQRQxAxBBFDkJQE2X11Gr/+2Bmboy/dxCDumO+c3eYpQaYN8uzoLPHBTzruWgS5JIKIIYgYgoghSIpeZb351Bmbt/94leU7x12LIJfE7yFiCCKGIGIIIoYgc/CJ4befPe/wieEM8Jm6GIKIIYgYgoghiBiCBLJUrHzIFMu/Ruf2k3fDUEHcvX1rcmuN5l2mVO5kSpV4dNb3joPEcOPu7VuTW2s07wgihiBiCCKGIAFcv/viRqZYrnqnVB6mKMgwaR9uj1FaLN3ZX/VvMHk0g1QSx+0xSguCiCGIGIKIIYgYgoghiBiCiCGIGIKIIYiYa8XnWd8ncBfN+t7xmam1zke/T+p++fOfh0/fx7MYdy3Pd1adu3tPul63x2gR2Vxh264U4plMrsD/XJyWJYgWSxAtliBaLEG0WIJosQTRYgmixRJEiyWIFksQLZYgWixBtFiCaLEE0WIJosUSRIsliJZ+Lr/RW8k3RsfmCs0LHnzTd467Vuj9zK3BrcJqUhB3LPT6Fs6AIFoGBNEyIIiWAUG09JbXsr1cvuud5bXF/CM2AIiu1F+d56Qeo24SAwAAAABJRU5ErkJggg== // @version 0.8.80 // @author flowsaro.com // @namespace https://docs.scriptcat.org/ // @noframes // @require https://unpkg.com/vue@3/dist/vue.global.prod.js // @require data:application/javascript,unsafeWindow.Vue%3DVue%3B // ==/UserScript== /* ==UserConfig== general: githubAccel: title: 开启 GitHub 加速链接功能 description: 关闭后,GitHub 页面将不显示镜像加速下载按钮 type: checkbox default: true backTop: title: 开启返回顶部按钮 description: 关闭后,所有页面(包括 GitHub)都不显示返回顶部按钮 type: checkbox default: true alwaysShow: title: 总是显示返回顶部按钮 description: 开启后按钮不随滚动自动隐藏,始终显示在页面上 type: checkbox default: false noBtnBg: title: 不显示按钮背景 description: 开启后按钮背景/边框/阴影透明,仅保留图标与点击区域 type: checkbox default: false iconScale: title: 图标大小倍率(1x = 26px,范围 0.6 ~ 4) description: 允许小数(截断 1 位),范围 0.6 ~ 4;面板内可用「2倍」/「默认」快捷按钮 type: number default: 1 btnAnim: title: 按钮图标动画 description: 可选:none(无)/ breathe(呼吸)/ spin(旋转)/ pulse(脉冲)/ ripple(涟漪,从按钮边缘往外扩散的水波)。GIF 动图不受影响;系统开启「减少动态效果」时自动禁用 type: text default: none btnRotate: title: 按钮旋转角度(0 ~ 360 度) description: 主按钮图标的旋转角度,超出范围自动收敛到 0 ~ 360 type: number default: 0 btnMirror: title: 水平镜像主按钮 description: 把图标左右翻转。可与「旋转角度」叠加(先镜像再旋转,所以调好的角度不会被镜像翻反) type: checkbox default: false btnOpacity: title: 按钮不透明度(0.3 ~ 1) description: 平时按这个值淡在页面上(0.3 是最淡的档,再淡就难找了);鼠标悬停 / 拖动 / 打开面板时会自动回到完全不透明。触摸端不生效 —— 那边没有悬停这层补偿,淡着只会更难点中 type: number default: 1 quickMenu: title: 启用快捷菜单 description: 开启后鼠标悬停按钮自动展开快捷菜单(触摸端双击),显示已绑定的快捷功能插件。⚠️ 只控制悬停/双击:插件主动弹出的菜单(如选中文字后的快捷翻译)不受此开关限制,想彻底关闭请解绑槽位或禁用该插件 type: checkbox default: false menuSlots: title: 快捷菜单槽位数量(2 ~ 8) description: 快捷菜单可容纳的功能数量,超出范围自动收敛到 2 ~ 8 type: number default: 4 customIcon: title: 自定义按钮图标(base64) description: 填写 data:image/...;base64,... 或纯 base64 字符串,留空使用脚本默认图标 type: textarea default: '' disabledSites: title: 不显示返回顶部按钮的站点 description: 每行填写一个域名,例如 baidu.com type: textarea default: '' ==/UserConfig== */ unsafeWindow.Vue = Vue; (()=>{"use strict";const e=Vue,t=(0,e.defineComponent)({inheritAttrs:!1,__name:"Button",props:{size:{default:46},dragging:{type:Boolean,default:!1},transparent:{type:Boolean,default:!1},variant:{default:"glass"},round:{type:Boolean,default:!1}},setup(t){const n=t,o=(0,e.useAttrs)(),r=(0,e.ref)(!1),a=(0,e.computed)(()=>{const{style:e,...t}=o;return t}),i=(0,e.computed)(()=>{const e=o.style;return e?{...e}:void 0}),s=(0,e.computed)(()=>({width:n.size+"px",height:n.size+"px",borderRadius:n.round?"50%":Math.round(.3*n.size)+"px"}));return(t,o)=>((0,e.openBlock)(),(0,e.createElementBlock)("button",(0,e.mergeProps)(a.value,{class:["flex items-center justify-center p-0 box-border select-none cursor-grab touch-none",n.transparent?"bg-transparent border border-transparent shadow-none":"border-surface bg-btn shadow-btn hover:bg-btn-hover hover:shadow-btn-hover"],style:[s.value,i.value],onMouseenter:o[0]||(o[0]=e=>r.value=!0),onMouseleave:o[1]||(o[1]=e=>r.value=!1)}),[(0,e.renderSlot)(t.$slots,"default")],16))}}),n=(0,e.defineComponent)({inheritAttrs:!1,__name:"Panel",props:{radius:{default:14},padding:{default:"14px 16px"},variant:{default:"glass"}},setup(t){const n=t,o=(0,e.useAttrs)(),r=(0,e.computed)(()=>{const{style:e,...t}=o;return t}),a=(0,e.computed)(()=>{const e=o.style;return e?{...e}:void 0}),i=(0,e.computed)(()=>({borderRadius:n.radius+"px",padding:n.padding,borderColor:"var(--sc-surface-border)"}));return(t,n)=>((0,e.openBlock)(),(0,e.createElementBlock)("div",(0,e.mergeProps)(r.value,{class:"box-border bg-panel border rounded-xl shadow-panel text-primary backdrop-blur-[10px] backdrop-saturate-150",style:[i.value,a.value]}),[(0,e.renderSlot)(t.$slots,"default")],16))}}),o={class:"flex items-center gap-1 p-1 mb-3 rounded-xl bg-subtle-btn"},r=["onClick"],a={class:"text-xs"},i=(0,e.defineComponent)({__name:"Tabs",props:{items:{},modelValue:{}},emits:["update:modelValue"],setup(t,{emit:n}){const i=t,s=n,l=(0,e.ref)(""),c=(0,e.computed)(()=>i.modelValue||l.value||i.items[0]?.key||"");return(n,u)=>((0,e.openBlock)(),(0,e.createElementBlock)("div",null,[(0,e.createElementVNode)("div",o,[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(t.items,t=>((0,e.openBlock)(),(0,e.createElementBlock)("button",{key:t.key,type:"button",class:(0,e.normalizeClass)(["flex-1 px-3 py-1.5 text-xs rounded-lg cursor-pointer whitespace-nowrap transition-colors",t.key===c.value?"bg-panel text-primary shadow-sm border-surface font-medium":"text-secondary hover:bg-white/10 hover:text-primary border border-transparent"]),onClick:e=>{return n=t.key,void(void 0!==i.modelValue?s("update:modelValue",n):l.value=n);var n}},(0,e.toDisplayString)(t.label),11,r))),128))]),(0,e.createElementVNode)("div",a,[(0,e.renderSlot)(n.$slots,c.value)])]))}}),s=(0,e.defineComponent)({__name:"CopyButton",props:{label:{default:"复制"}},emits:["copy"],setup(t,{emit:n}){const o=n,r=(0,e.ref)(!1);let a=null;function i(){o("copy"),r.value=!0,a&&clearTimeout(a),a=setTimeout(()=>{r.value=!1},1500)}return(n,o)=>((0,e.openBlock)(),(0,e.createElementBlock)("button",{type:"button",class:(0,e.normalizeClass)(["shrink-0 text-xs px-2.5 py-0.5 rounded-md cursor-pointer transition-colors duration-200",r.value?"bg-save-btn text-white border border-save-border":"bg-subtle-btn text-primary border-surface"]),onClick:i},(0,e.toDisplayString)(r.value?"✓ 已复制":t.label),3))}});const l=["data-toast-id"],c={class:"flex items-center gap-1.5 mb-1"},u=["src"],d={class:"flex items-center gap-1 ml-auto shrink-0"},p=["onClick"],m=["title","onClick"],h={class:"flex-1 min-w-0 text-sm leading-[1.5] break-words whitespace-pre-wrap"},g={key:0,class:"text-[11px] leading-snug text-secondary/80 mt-1 break-words whitespace-pre-wrap"},f=(0,e.defineComponent)({__name:"ToastHost",props:{toasts:{},align:{}},emits:["close","copy","clear-plugin"],setup(t,{emit:n}){const o=t,r=(0,e.computed)(()=>"bottom"===o.align),a=n,i=(0,e.computed)(()=>function(e,t,n=2,o=3){const r=e.filter(e=>"high"===e.severity).slice(0,n);return[...e.filter(e=>"high"!==e.severity).slice(0,o),...r]}(o.toasts,o.align));function f(e){if(!e.pluginId||"high"===e.severity)return 0;const t=o.toasts.filter(t=>t.pluginId===e.pluginId&&"high"!==t.severity).length;return t>=2?t:0}const b=(0,e.ref)(new Set);(0,e.watch)(i,(e,t)=>{const n=new Set(t.map(e=>e.id)),o=new Set(v),r=e.filter(e=>o.has(e.id)&&!n.has(e.id));r.length&&(b.value=new Set([...b.value,...r.map(e=>e.id)]),setTimeout(()=>{b.value=new Set([...b.value].filter(e=>!r.some(t=>t.id===e)))},400))});let v=[];(0,e.watch)(()=>o.toasts,e=>{v=e.map(e=>e.id)},{immediate:!0});let y=0;const x=(0,e.ref)(0);function w(e){return i.value[0]?.id===e.id&&Date.now(){if(e.length&&e[0].id!==t[0]?.id){const e=Date.now();x.value=e-y>=1e3?e+800:0,y=e}});const k={info:"var(--color-accent)",success:"var(--color-success)",warning:"var(--color-warning)",error:"var(--color-danger)"};const E=(0,e.computed)(()=>r.value?{position:"relative",width:"300px","--sc-toast-from-y":Math.max(0,(S.value||46)-23)+"px"}:{position:"relative",width:"300px",height:N.value+"px",transition:"height .2s ease"}),V=(0,e.ref)({});function C(e){let t=0;for(let n=0;n div[data-toast-id]:not(.toast-leave-active)")),n={};t.forEach(e=>{const t=Number(e.dataset.toastId);Number.isFinite(t)&&(n[t]=e.offsetHeight||0)}),V.value=n;const o=t[0];o&&(S.value=o.offsetHeight||0,_&&o!==D&&(D&&_.unobserve(D),_.observe(o),D=o)),N.value=function(){const e=i.value;if(!e.length)return 0;const t=e[e.length-1];return C(e.length-1)+(V.value[t.id]??46)}()}function M(e,t){const n=i.value.length,o=0===t,a=C(t),s={boxShadow:"var(--sc-shadow-toast)"};return r.value?{position:o?"relative":"absolute",left:"0",right:"0",top:"auto",bottom:a+"px",zIndex:n-t,...s}:{position:o?"relative":"absolute",left:o?"auto":"0",right:o?"auto":"0",top:o?"auto":"0",marginTop:a+"px",zIndex:n-t,...s}}function z(e){return{color:k[e]||k.info}}const T={scrollbarWidth:"thin",scrollbarColor:"rgba(255,255,255,0.2) transparent"},L=(0,e.ref)();let _=null,D=null;(0,e.onMounted)(()=>{const e=L.value?.$el?.getRootNode();if(e&&e!==document){const t=document.createElement("style");t.textContent="@keyframes sc-toast-in{0%{opacity:0;filter:blur(4px);transform:translate(52px,var(--sc-toast-from-y,0px)) scale(0.9)}60%{opacity:1;filter:blur(0);transform:translate(-6px,0) scale(1.02)}100%{opacity:1;filter:blur(0);transform:translate(0,0) scale(1)}}@keyframes sc-toast-out{from{opacity:1;filter:blur(0)}to{opacity:0;filter:blur(5px);transform:translateX(-14px)}}.toast-enter-active{animation:sc-toast-in .32s cubic-bezier(0.22,1,0.36,1)}.toast-leave-active{animation:sc-toast-out .22s ease;position:absolute!important}.no-enter.toast-enter-active{animation:none!important}@keyframes sc-busy-dot{0%,80%,100%{opacity:.25;transform:translateY(0)}40%{opacity:1;transform:translateY(-3px)}}.sc-busy{display:inline-flex;align-items:center;gap:2px;height:10px}.sc-busy>i{width:3px;height:3px;border-radius:50%;background:currentColor;opacity:.25;animation:sc-busy-dot 1.1s ease-in-out infinite}.sc-busy>i:nth-child(2){animation-delay:.18s}.sc-busy>i:nth-child(3){animation-delay:.36s}.toast-body::-webkit-scrollbar{width:6px}.toast-body::-webkit-scrollbar-track{background:transparent}.toast-body::-webkit-scrollbar-thumb{background:rgba(255,255,255,0.15);border-radius:3px}",e.appendChild(t)}_=new ResizeObserver(()=>B()),B()});let I=null;return(0,e.watch)(()=>o.toasts,(e,t)=>{I&&clearTimeout(I),e.length((0,e.openBlock)(),(0,e.createBlock)(e.TransitionGroup,{ref_key:"hostRef",ref:L,tag:"div",class:"toast-host relative w-[300px]",name:"toast",style:(0,e.normalizeStyle)(E.value)},{default:(0,e.withCtx)(()=>[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(i.value,(o,r)=>{return(0,e.openBlock)(),(0,e.createElementBlock)("div",{key:o.id,"data-toast-id":o.id,class:(0,e.normalizeClass)(["w-[300px] min-h-[46px] box-border p-2 rounded-[10px] bg-panel border-surface backdrop-blur-[10px] backdrop-saturate-150 text-[13px] leading-[1.5] text-primary flex flex-col transition-[margin-top,bottom,box-shadow] duration-200",{"no-enter":b.value.has(o.id)}]),style:(0,e.normalizeStyle)(M(0,r))},[(0,e.createCommentVNode)(" 标题左 / 操作按钮组右(两端对齐) "),(0,e.createElementVNode)("div",c,[o.icon?((0,e.openBlock)(),(0,e.createElementBlock)("img",{key:0,src:o.icon,class:"w-4 h-4 object-contain rounded-sm shrink-0",alt:""},null,8,u)):(0,e.createCommentVNode)("v-if",!0),(0,e.createElementVNode)("span",{class:"font-semibold text-xs shrink-0",style:(0,e.normalizeStyle)(z(o.type))},(0,e.toDisplayString)(o.title||(v=o.type,{info:"提示",success:"成功",warning:"警告",error:"错误"}[v]||"提示")),5),(0,e.createCommentVNode)(" 进行中标记:标题后的循环动画(三点跳动),任务结束时由插件用 busy:false 停掉 "),o.busy?((0,e.openBlock)(),(0,e.createElementBlock)("span",{key:1,class:"sc-busy shrink-0",style:(0,e.normalizeStyle)(z(o.type)),"aria-hidden":"true"},[...n[0]||(n[0]=[(0,e.createElementVNode)("i",null,null,-1),(0,e.createElementVNode)("i",null,null,-1),(0,e.createElementVNode)("i",null,null,-1)])],4)):(0,e.createCommentVNode)("v-if",!0),(0,e.createElementVNode)("div",d,[f(o)?((0,e.openBlock)(),(0,e.createElementBlock)("button",{key:0,type:"button",class:"text-[10px] px-1.5 py-0.5 rounded-md border border-danger/40 text-danger cursor-pointer transition-colors hover:text-danger hover:bg-danger/15",title:"清空该插件的通知(同一插件的普通通知一起清,进行中任务不会被清空)",onClick:e=>function(e){w(e)||e.pluginId&&a("clear-plugin",e.pluginId)}(o)}," 清空("+(0,e.toDisplayString)(f(o))+"条) ",9,p)):(0,e.createCommentVNode)("v-if",!0),(0,e.createElementVNode)("button",{type:"button",class:"w-5 h-5 flex items-center justify-center rounded-md border-none bg-transparent text-sm cursor-pointer text-secondary leading-none transition-colors hover:text-primary hover:bg-white/15",title:i.value.length>1?"关闭这条":"关闭",onClick:e=>function(e){w(e)||a("close",e.id)}(o)}," × ",8,m)])]),(0,e.createElementVNode)("div",{class:"toast-body flex items-start gap-2 max-h-[160px] overflow-y-auto overflow-x-hidden",style:T},[(0,e.createElementVNode)("div",h,(0,e.toDisplayString)(o.text),1),o.copyable?((0,e.openBlock)(),(0,e.createBlock)(s,{key:0,onCopy:e=>t.$emit("copy",o)},null,8,["onCopy"])):(0,e.createCommentVNode)("v-if",!0)]),(0,e.createCommentVNode)(" 次要说明文字:正文下方的小号灰字(如「剩余 12:34 · 取消会直接结束任务」) "),o.note?((0,e.openBlock)(),(0,e.createElementBlock)("div",g,(0,e.toDisplayString)(o.note),1)):(0,e.createCommentVNode)("v-if",!0)],14,l);var v}),128))]),_:1},8,["style"]))}});class b{constructor(e,t,n){this.bus=e,this.load=t,this.save=n,this.records=new Map,this.reload()}reload(){this.records.clear();for(const e of this.load())this.records.set(e.manifest.id,e)}list(){return[...this.records.values()]}get(e){return this.records.get(e)}install(e){if(!String(e||"").trim())return{ok:!1,error:"插件内容为空"};if(!/\/\/\s*==Plugin==/.test(e))return{ok:!1,error:"缺少 ==Plugin== 头"};const t=function(e){const t=e.match(/\/\/\s*==Plugin==\s*([\s\S]*?)\/\/\s*==\/Plugin==/);if(!t)return null;const n=t[1],o=e=>{const t=n.match(new RegExp(`//\\s*@${e}\\s+(.+)`));return t?t[1].trim():void 0},r=o("id"),a=o("name");if(!r||!a)return null;const i="feature"===o("type")?"feature":"shortcut",s=(o("permissions")||o("permission")||"").split(",").map(e=>e.trim()).filter(e=>["selection","clipboard","storage","ui","menu","network","dom","broadcast"].includes(e));return{id:r,name:a,version:o("version")||"0.0.1",type:i,icon:o("icon"),permissions:s,description:o("description"),builtin:"true"===o("builtin")}}(e);if(!t)return{ok:!1,error:"插件头格式错误(@id、@name 为必填字段)"};const n={manifest:t,code:e,installedAt:Date.now()};return this.records.set(t.id,n),this.persist(),this.bus.emit("plugin-installed",n),{ok:!0,record:n}}installBuiltin(e,t,n){const o={manifest:e,code:t,installedAt:Date.now()};return n&&(o.init=n),this.records.set(e.id,o),this.bus.emit("plugin-installed",o),o}uninstall(e){const t=this.records.delete(e);return t&&(this.persist(),this.bus.emit("plugin-uninstalled",e)),t}persist(){this.save(this.list())}}class v{constructor(){this.handlers=new Map}on(e,t){return this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(t),()=>this.off(e,t)}off(e,t){this.handlers.get(e)?.delete(t)}emit(e,t){this.handlers.get(e)?.forEach(n=>{try{n(t)}catch(t){console.warn(`[plugin-core] event "${e}" handler error:`,t)}})}clear(){this.handlers.clear()}}class y{constructor(e){this.mode="soft",this.error=null,this.handlers=new Set,this.fn=null,this.code=e}run(e){try{const t=this.code.trim(),n=t.endsWith(";")?t.slice(0,-1).trim():t;this.fn=new Function("ctx","emit",`return (${n});`);const o=e=>this.dispatch(e);if(!this.fn)return;const r=this.fn(e,o);"function"==typeof r&&r(e,o)}catch(e){this.error=e instanceof Error?e.message:String(e),console.warn("[plugin-core] 插件主体执行失败:",e)}}send(e){this.dispatch(e)}onMessage(e){return this.handlers.add(e),()=>this.handlers.delete(e)}activate(){this.send({type:"activate"})}deactivate(){this.send({type:"deactivate"})}dispose(){this.send({type:"dispose"}),this.handlers.clear(),this.fn=null,this.code=""}dispatch(e){this.handlers.forEach(t=>{try{t(e)}catch(e){console.warn("[plugin-core] 插件消息处理错误:",e)}})}}class x{constructor(e,t,n){this.settings=[],this.initError=null,this.executor=null,this.onActivate=null,this.onDeactivate=null,this.disposeCbs=[],this.eventCbs=new Map,this.selectionCbs=[],this.manifest={...e.manifest},this.caps=t,this.uiHooks=n,this.mode="soft";const o=this.createCtx();if(e.init)try{e.init(o)}catch(e){this.initError=e instanceof Error?e.message:String(e),console.warn(`[plugin-core] 插件 ${this.manifest.id} 主体执行失败:`,e)}else{const t=new y(e.code);this.executor=t,t.run(o),t.error&&(this.initError=t.error)}}createCtx(){const e=this.manifest,t=t=>e.permissions.includes(t);return{manifest:{...e},getSelectedText:t("selection")?()=>this.caps.getSelectedText():void 0,readClipboard:t("clipboard")?()=>this.caps.readClipboard():void 0,copyText:t("clipboard")?e=>this.caps.copyText(e):void 0,getValue:t("storage")?(e,t)=>this.caps.getValue(e,t):void 0,setValue:t("storage")?(e,t)=>this.caps.setValue(e,t):void 0,getState:t("storage")?(e,t)=>this.caps.getState(e,t):void 0,setState:t("storage")?(e,t)=>this.caps.setState(e,t):void 0,openPanel:t("ui")?e=>this.caps.openPanel(e):void 0,closePanel:t("ui")?()=>this.caps.closePanel():void 0,openMenu:t("menu")?()=>this.caps.openMenu():void 0,closeMenu:t("menu")?()=>this.caps.closeMenu():void 0,toast:(e,n)=>{const o=n?.title?this.manifest.name+" "+n.title:this.manifest.name,r={...n,title:o,icon:this.manifest.icon};return r.broadcast&&!t("broadcast")&&delete r.broadcast,!r.severity||t("severity")&&this.manifest.builtin||delete r.severity,this.caps.toast(e,r)},dismissToast:e=>this.caps.dismissToast(e),updateToast:(e,t)=>this.caps.updateToast(e,t),httpRequest:t("network")?(e,t)=>this.caps.httpRequest(e,t):void 0,ui:{render:(t,n)=>{try{this.uiHooks.render(t,n)}catch(t){console.warn(`[plugin-core] 插件 ${e.id} UI 渲染失败:`,t)}},close:()=>this.uiHooks.close()},onActivate:e=>{this.onActivate=e},onDeactivate:e=>{this.onDeactivate=e},onEvent:(e,t)=>{this.eventCbs.set(e,t)},onSelectionChange:e=>{this.selectionCbs.push(e)},onDispose:e=>{this.disposeCbs.push(e)},declareSettings:e=>{this.settings=Array.isArray(e)?e:[]}}}activate(...e){if(this.onActivate)try{this.onActivate(...e)}catch(e){console.warn(`[plugin-core] 插件 ${this.manifest.id} activate 失败:`,e)}}deactivate(){if(this.onDeactivate)try{this.onDeactivate()}catch(e){console.warn(`[plugin-core] 插件 ${this.manifest.id} deactivate 失败:`,e)}}emitEvent(e,t){const n=this.eventCbs.get(e);if(n)try{n(t)}catch(t){console.warn(`[plugin-core] 插件 ${this.manifest.id} 事件 ${e} 处理失败:`,t)}}emitSelectionChange(e){this.selectionCbs.forEach(t=>{try{t(e)}catch(e){console.warn(`[plugin-core] 插件 ${this.manifest.id} selection 回调失败:`,e)}})}dispose(){this.disposeCbs.forEach(e=>{try{e()}catch(e){console.warn(`[plugin-core] 插件 ${this.manifest.id} dispose 回调失败:`,e)}}),this.disposeCbs=[],this.eventCbs.clear(),this.selectionCbs=[],this.executor?.dispose()}}const w="plugins",k="menuBindings",E="disabledPlugins",V="toastList";function C(e){if(!e||"object"!=typeof e)return null;const t=e;return"number"!=typeof t.id||"string"!=typeof t.text?null:{id:t.id,text:t.text,opts:t.opts&&"object"==typeof t.opts?t.opts:{},at:"number"==typeof t.at?t.at:Date.now()}}function S(e,t){const n=e.opts.timeout??2500;return 0===n?0:Math.max(0,n-(t-e.at))}class N{constructor(e,t=[]){this.runtimes=new Map,this.bindings=[],this.disabledIds=[],this.listeners=new Map,this.errors=[],this.MAX_PLUGIN_ERRORS=3,this.storageUnwatchers=[],this.knownBroadcasts=new Set,this.broadcastSeq=0,this.broadcastUnwatch=null,this.legacyCbs=new Map,this.deps=e,this.registry=new b(new v,()=>this.loadRecords(),e=>this.saveRecords(e)),this.bindings=this.loadBindings(),this.disabledIds=this.loadDisabled();for(const e of t){const t=this.registry.get(e.manifest.id);t&&!t.manifest.builtin&&this.registry.uninstall(e.manifest.id),this.registry.installBuiltin({...e.manifest,builtin:!0},e.code||"",e.init)}this.startStorageSync(),this.startBroadcastSync()}on(e,t){let n=this.listeners.get(e);return n||(n=new Set,this.listeners.set(e,n)),n.add(t),()=>{n?.delete(t)}}emit(e,...t){const n=this.listeners.get(e);if(n)for(const o of n)try{o(...t)}catch(t){console.warn(`[plugin] 事件 "${e}" 订阅者抛错:`,t)}}notifyChanged(){this.emit("changed")}get storage(){return this.deps.storage}loadRecords(){const e=this.storage.get(w,[]);return Array.isArray(e)?e:[]}saveRecords(e){try{this.storage.set(w,e)}catch(e){this.deps.log?.("保存插件记录失败:",e)}}loadBindings(){const e=this.storage.get(k,[]);return Array.isArray(e)?e.map(String):[]}loadDisabled(){const e=this.storage.get(E,[]);return Array.isArray(e)?e.map(String):[]}saveDisabled(){this.storage.set(E,this.disabledIds)}saveBindings(){this.storage.set(k,this.bindings)}startStorageSync(){for(const e of[w,k,E])try{const t=this.storage.watch(e,()=>{this.syncFromStorage(e)});this.storageUnwatchers.push(t)}catch{}}syncFromStorage(e){if(e===w)this.registry.reload(),this.preheatFeatures();else if(e===k)this.bindings=this.loadBindings();else if(e===E){this.disabledIds=this.loadDisabled();for(const[e,t]of this.runtimes)this.isEnabled(e)||(t.dispose(),this.runtimes.delete(e))}this.notifyChanged()}disposeStorageSync(){for(const e of this.storageUnwatchers)try{e()}catch{}this.storageUnwatchers=[]}readBroadcastList(){const e=this.storage.get(V,[]);if(!Array.isArray(e))return[];const t=Date.now();return e.map(C).filter(e=>null!==e&&!function(e,t){const n=e.opts.timeout??2500;return 0!==n&&t-e.at>=n}(e,t))}writeBroadcastList(e){try{this.storage.set(V,e)}catch{}}alignBroadcasts(e){const t=new Set(e.map(e=>e.id)),n=Date.now();for(const t of e)this.knownBroadcasts.has(t.id)||(this.knownBroadcasts.add(t.id),this.emit("toast",t.text,{...t.opts,timeout:S(t,n),broadcastId:t.id}));for(const e of Array.from(this.knownBroadcasts))t.has(e)||(this.knownBroadcasts.delete(e),this.emit("toastDismissed",e))}startBroadcastSync(){try{const e=this.storage.watch(V,()=>{this.alignBroadcasts(this.readBroadcastList())});this.broadcastUnwatch=()=>{try{e()}catch{}}}catch{this.broadcastUnwatch=null}}syncBroadcasts(){this.alignBroadcasts(this.readBroadcastList())}dismissBroadcast(e){const t=this.readBroadcastList();t.some(t=>t.id===e)&&this.writeBroadcastList(t.filter(t=>t.id!==e))}clearBroadcasts(e){const t=this.readBroadcastList(),n=t.filter(t=>!(t=>"high"!==t.opts.severity&&(void 0===e||t.opts.pluginId===e))(t));n.length!==t.length&&this.writeBroadcastList(n)}install(e){const t=this.registry.install(e);if(t.ok&&t.record){const e=t.record.manifest.id,n=this.runtimes.get(e);return n&&(n.dispose(),this.runtimes.delete(e)),this.errors=this.errors.filter(t=>t.id!==e),this.notifyChanged(),{ok:!0,id:e,type:t.record.manifest.type}}return{ok:!1,error:t.error}}uninstall(e){const t=this.registry.get(e);if(t?.manifest.builtin)return!1;this.runtimes.get(e)?.dispose(),this.runtimes.delete(e);try{this.storage.set("plugin:"+e+".settings","")}catch{}const n=this.registry.uninstall(e);this.emit("pluginUninstalled",e);let o=!1;for(let t=0;t'+t+"")}(t.manifest.name):""}getBindingName(e){const t=this.bindings[e];return t?this.registry.get(t)?.manifest.name||t:""}activateSlot(e){const t=this.bindings[e];t&&this.activate(t)}activate(e){this.isEnabled(e)&&this.getRuntime(e)?.activate()}collectError(e,t){const n=this.errors.find(n=>n.id===e&&n.message===t);n?n.count++:(this.errors.push({id:e,message:t,count:1}),this.errors.length>this.MAX_PLUGIN_ERRORS&&this.errors.shift())}getPluginErrors(){return this.errors.map(e=>({id:e.id,name:this.registry.get(e.id)?.manifest.name||e.id,message:e.message,count:e.count}))}clearPluginError(e){this.errors=this.errors.filter(t=>t.id!==e)}getSettings(e){const t=this.getRuntime(e);return t?.settings||[]}getPluginSetting(e,t){const n=this.storage.get("plugin:"+e+".settings",{});if(n&&"object"==typeof n)return t in n?n[t]:void 0}setPluginSetting(e,t,n){const o=this.storage.get("plugin:"+e+".settings",{}),r=o&&"object"==typeof o?o:{};r[t]=n,this.storage.set("plugin:"+e+".settings",r)}preheatFeatures(){this.registry.list().forEach(e=>{"feature"===e.manifest.type&&this.isEnabled(e.manifest.id)&&this.getRuntime(e.manifest.id)})}isEnabled(e){return!this.disabledIds.includes(e)}setEnabled(e,t){t?this.disabledIds=this.disabledIds.filter(t=>t!==e):this.disabledIds.includes(e)||(this.disabledIds.push(e),this.runtimes.get(e)?.dispose(),this.runtimes.delete(e)),this.saveDisabled(),this.notifyChanged()}getRuntime(e){const t=this.runtimes.get(e);if(t)return t;const n=this.registry.get(e);if(!n)return;const o=new x(n,this.createCaps(e),this.createUiHooks(e));return this.runtimes.set(e,o),o.initError&&this.collectError(e,o.initError),o}handleSelectionChange(e){this.registry.list().forEach(t=>{"shortcut"===t.manifest.type&&t.manifest.permissions.includes("selection")&&this.isEnabled(t.manifest.id)&&this.getRuntime(t.manifest.id)?.emitSelectionChange(e)})}createCaps(e){const{storage:t,http:n,clipboard:o,getSelectedText:r}=this.deps;return{getSelectedText:async()=>r?.()??"",readClipboard:async()=>{if(!o)return"";try{return await o.read()}catch{return""}},copyText:async e=>{if(o)try{await o.write(e)}catch{}},getValue:(n,o)=>{const r=t.get("plugin:"+e+".settings",{});return r&&"object"==typeof r&&n in r?r[n]:o},setValue:(n,o)=>{const r=t.get("plugin:"+e+".settings",{}),a=r&&"object"==typeof r?r:{};a[n]=o,t.set("plugin:"+e+".settings",a)},getState:(n,o)=>t.get("plugin:"+e+".state."+n,o),setState:(n,o)=>{t.set("plugin:"+e+".state."+n,o)},openPanel:async t=>(this.emit("panelRender",{kind:"panel",spec:{type:"panel",title:this.panelTitle(e),body:t.body??[]},pluginId:e}),{ok:!0}),closePanel:async()=>{this.emit("panelRender",{kind:"close",spec:null,pluginId:e})},openMenu:()=>{const t=this.listeners.get("menuRequest");if(!t||0===t.size)return{ok:!1};let n={ok:!1},o=!0;for(const r of t){const t=o;o=!1;try{if(t){const t=r(e);n=t&&"object"==typeof t?t:{ok:!1}}else r(e)}catch{}}return n},closeMenu:()=>this.emit("menuCloseRequest"),toast:(t,n)=>{let o={...n,pluginId:e};if(n?.broadcast){const e=1e3*Date.now()+this.broadcastSeq++%1e3;this.knownBroadcasts.add(e);const{broadcast:n,...r}=o,a=this.readBroadcastList();for(a.push({id:e,text:t,opts:r,at:Date.now()});a.length>30;)a.shift();this.writeBroadcastList(a),o={...r,broadcastId:e}}const r=this.listeners.get("toast");if(!r||0===r.size)return 0;let a=0,i=!0;for(const e of r)try{i?(a=e(t,o)??0,i=!1):e(t,o)}catch{}return a},dismissToast:e=>this.emit("dismissToast",e),updateToast:(e,t)=>{const n=this.listeners.get("toastUpdate");if(!n||0===n.size)return!1;let o=!1;for(const r of n)try{!0===r(e,t)&&(o=!0)}catch{}return o},httpRequest:(e,t)=>n?n.request(e,t):Promise.resolve({ok:!1,status:0,text:""})}}createUiHooks(e){return{render:(t,n)=>{const o="panel"===t&&n&&"panel"===n.type?{...n,title:this.panelTitle(e)}:n;this.emit("panelRender",{kind:t,spec:o,pluginId:e})},close:()=>{this.emit("panelRender",{kind:"close",spec:null,pluginId:e})}}}panelTitle(e){return this.registry.get(e)?.manifest.name||e}disposeAll(){if(this.runtimes.forEach(e=>e.dispose()),this.runtimes.clear(),this.disposeStorageSync(),this.broadcastUnwatch){try{this.broadcastUnwatch()}catch{}this.broadcastUnwatch=null}}registerLegacy(e,t){this.legacyCbs.get(e)&&this.offLegacy(e),this.legacyCbs.set(e,t),this.on(e,t)}offLegacy(e){const t=this.legacyCbs.get(e);if(!t)return;const n=this.listeners.get(e);n?.delete(t),this.legacyCbs.delete(e)}onPanelRender(e){this.registerLegacy("panelRender",e)}onMenuRequest(e){this.registerLegacy("menuRequest",e)}onPluginUninstalled(e){this.registerLegacy("pluginUninstalled",e)}onToast(e){this.registerLegacy("toast",e)}onDismissToast(e){this.registerLegacy("dismissToast",e)}onToastUpdate(e){this.registerLegacy("toastUpdate",e)}onToastDismissed(e){this.registerLegacy("toastDismissed",e)}onChanged(e){this.on("changed",e)}}function B(e){const t={fontSize:"13px",lineHeight:"1.5"};return"bold"===e?.weight&&(t.fontWeight="600"),"sm"===e?.size&&(t.fontSize="12px"),"lg"===e?.size&&(t.fontSize="15px"),"secondary"===e?.color&&(t.color="var(--color-secondary)"),"accent"===e?.color&&(t.color="var(--color-accent)"),"danger"===e?.color&&(t.color="var(--color-danger)"),t}function M(t,n){return t.map((t,o)=>(0,e.h)("div",{style:o?{marginTop:"6px"}:void 0},[_(t,n)]))}const z="w-full min-w-0 box-border px-2 py-1 text-xs border-surface rounded-lg bg-input text-primary font-[inherit] select-text transition-shadow sc-field",T="px-3 py-1.5 text-xs border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer font-[inherit] transition-colors hover:bg-white/15 active:scale-[0.97]",L="px-3 py-1.5 text-xs border border-save-border rounded-lg bg-save-btn text-white font-medium cursor-pointer font-[inherit] shadow-sm transition hover:opacity-90 active:scale-[0.97]";function _(t,o){switch(t.type){case"panel":return(0,e.h)(n,{variant:"glass",style:{width:"100%",padding:"12px"}},()=>(t.body||[]).map(e=>_(e,o)));case"text":return(0,e.h)("span",{style:B(t.style)},t.content);case"button":{const n=("primary"===t.variant?L:T)+(t.full?" w-full":"");return(0,e.h)("button",{type:"button",class:n,onClick:()=>o(t.event||"")},t.label)}case"list":return(0,e.h)("div",{class:"flex flex-col gap-1"},(t.items||[]).map(e=>_(e,o)));case"row":return(0,e.h)("div",{class:"flex items-center gap-1.5"},(t.items||[]).map(e=>_(e,o)));case"fieldset":return(0,e.h)("fieldset",{class:"border-surface rounded-xl p-3 min-w-0 bg-subtle-btn"},[t.legend?(0,e.h)("legend",{class:"text-[11px] px-2 py-0.5 rounded-full bg-chip text-accent font-medium"},t.legend):null,...M(t.body||[],o)]);case"divider":return(0,e.h)("hr",{class:"border-0 border-t border-seam my-2"});case"badge":return(0,e.h)("span",{class:"inline-block px-2 py-0.5 text-[11px] rounded-[10px] bg-subtle-btn text-secondary"},t.text);case"image":return(0,e.h)("img",{src:t.src,class:"max-w-full rounded-md block"});case"link":return(0,e.h)("a",{href:t.href,target:"_blank",rel:"noopener noreferrer",class:"text-accent no-underline"},t.label);case"icon":return(0,e.h)("span",{class:"text-base"},t.name);case"input":return(0,e.h)("input",{value:t.value||"",placeholder:t.placeholder||"",onInput:e=>o(t.event||"",e.target.value),onKeydown:t.submitEvent?e=>{"Enter"===e.key&&(e.preventDefault(),o(t.submitEvent,e.target.value))}:void 0,class:z});case"textarea":return(0,e.h)("textarea",{value:t.value||"",placeholder:t.placeholder||"",onInput:e=>o(t.event||"",e.target.value),onKeydown:t.submitEvent?e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),o(t.submitEvent,e.target.value))}:void 0,class:`${z} min-h-[96px] resize-y`});case"checkbox":return(0,e.h)("label",{class:"flex items-center gap-1.5 text-[13px]"},[(0,e.h)("input",{type:"checkbox",checked:!!t.checked,onChange:e=>o(t.event||"",e.target.checked)}),(0,e.h)("span",t.label)]);case"select":return(0,e.h)("select",{value:t.value??"",onChange:e=>o(t.event||"",e.target.value),class:z},(t.options||[]).map(t=>(0,e.h)("option",{value:t.value},t.label)));case"tabs":return(0,e.h)("div",{},[(0,e.h)("div",{class:"flex flex-wrap gap-1 mb-1.5"},(t.tabs||[]).map((t,n)=>(0,e.h)("button",{onClick:()=>o("tab",n),class:"px-2.5 py-0.5 text-xs rounded-md border-surface bg-subtle-btn text-primary cursor-pointer"},()=>t.label))),...M(t.tabs&&t.tabs[0]?t.tabs[0].body:[],o)]);case"component":return(0,e.h)("div",{class:"text-danger text-xs"},`组件 ${t.name} 未支持`);default:return(0,e.h)("span",{},"")}}const D=[{name:"gh-proxy.com",url:"https://gh-proxy.com"},{name:"gh-proxy.org",url:"https://gh-proxy.org"},{name:"ghproxy.com",url:"https://mirror.ghproxy.com"}],I=["⚡ 闪电五连鞭模式启动!{n} 个下载链接已加速~","🚀 引擎点火,{n} 个链接原地起飞~","🔥 火力全开!{n} 个下载链接全部加速~","🛸 虫洞已开启,{n} 个链接光速抵达~","🥋 一鞭三连!{n} 个下载链接已乖乖加速~","⚡ 闪电五连鞭模式启动!下载链接已加速~","🚀 引擎点火,这条链接起飞了~","🔥 火力全开!下载链接已加速~","🛸 虫洞已开启,下载链接光速抵达~","🥋 一鞭定音!下载链接已加速~"].join("\n");function A(e,t){const n=e.filter(e=>e.includes("{n}")),o=e.filter(e=>!e.includes("{n}")),r=t>1?n:o;return function(e){return e[Math.floor(Math.random()*e.length)]}(r.length?r:e).split("{n}").join(String(t))}const R=6e4,G=180,j=[{max:6e5,emoji:"😅"},{max:36e5,emoji:"😬"},{max:1/0,emoji:"😔"}],P="atCountdown:",U="📌 手动关闭会导致当前任务直接结束且不再通知",$="📌 手动关闭会删除这条倒计时(任务已结束)",F={一:1,二:2,三:3,四:4,五:5,六:6,日:0,天:0},H={秒:1e3,秒钟:1e3,s:1e3,sec:1e3,分:6e4,分钟:6e4,m:6e4,min:6e4,小时:36e5,h:36e5};function q(e,t){return e>=0&&e<=23&&t>=0&&t<=59}function O(e){return(e<10?"0":"")+e}function Y(e){return String(e||"").replace(/\\n/g,"\n").split(/\n+/).map(e=>e.trim()).filter(Boolean)}const W="com.flowsaro.translate",X="data:image/svg+xml;utf8,"+encodeURIComponent('译'),J=[{manifest:{id:"com.flowsaro.github-accel",name:"GitHub 下载加速",version:"1.2.0",type:"feature",permissions:["dom","storage"],icon:"data:image/svg+xml;utf8,"+encodeURIComponent('GH'),description:"GitHub Release/仓库下载链接添加镜像加速按钮(注入型插件,仅 GitHub 站点;镜像列表可在设置面板配置,加速完成会弹一次通知)",builtin:!0},init:function(e){const t=e;if(t.declareSettings([{key:"mirrors",label:"镜像列表(每行一个,格式:名称 URL;留空使用默认)",type:"textarea",placeholder:"gh-proxy.com https://gh-proxy.com\ngh-proxy.org https://gh-proxy.org\nghproxy.com https://mirror.ghproxy.com"},{key:"notify",label:"加速完成后弹通知",type:"checkbox",default:!0},{key:"hypeTexts",label:"加速完成通知文案(每行一条,{n} 代表链接数量;清空则恢复默认)",type:"textarea",default:I,placeholder:I}]),!/(^|\.)github\.com$/.test(location.hostname))return;if(!document.body)return;let n=D,o=D[0];function r(){const e=function(e){const t=[];for(const n of String(e||"").split("\n")){const e=n.trim();if(!e)continue;const o=e.split(/\s+/),r=o[o.length-1];if(!/^https?:\/\//.test(r))continue;let a=o.length>1?o.slice(0,-1).join(" "):r;try{1===o.length&&(a=new URL(r).hostname.replace(/^www\./,""))}catch{}t.push({name:a,url:r})}return t}(String(t.getValue("mirrors","")||""));n=e.length?e:D,n.some(e=>e.url===o.url)||(o=n[0])}r();let a=!1;function i(e){if(a)return;if(!1===t.getValue("notify",!0))return;a=!0;const n=function(e){const t=String(e||"").split("\n").map(e=>e.trim()).filter(Boolean);return t.length?t:I.split("\n")}(String(t.getValue("hypeTexts",I)||""));t.toast(A(n,e),{type:"success"})}function s(e,t){return e.url.replace(/\/+$/,"")+"/"+t}function l(){document.querySelectorAll(".gh-mirror-menu.open").forEach(e=>e.classList.remove("open"))}function c(e){e.querySelectorAll("li").forEach(e=>{const t=e.getAttribute("data-mirror-url")===o.url;e.classList.toggle("selected",t),e.textContent=(t?"✓ ":"")+e.getAttribute("data-mirror-name")})}function u(e){if(e.getAttribute("data-mirror-split"))return;e.setAttribute("data-mirror-split","1");const t=document.createElement("span");t.className="gh-mirror-split";const r=document.createElement("a");r.className="split-main",r.setAttribute("data-original-href",e.href),r.href=s(o,e.href),r.textContent="下载",r.title="通过 "+o.name+" 下载",r.target="_blank",r.rel="noopener noreferrer",r.setAttribute("data-mirror-split","1");const a=document.createElement("button");a.type="button",a.className="split-arrow",a.textContent="▾",a.title="选择镜像下载",a.setAttribute("aria-label","选择镜像下载");const i=document.createElement("ul");i.className="gh-mirror-menu",n.forEach(t=>{const n=document.createElement("li");n.setAttribute("data-mirror-url",t.url),n.setAttribute("data-mirror-name",t.name),n.addEventListener("click",n=>{n.stopPropagation(),window.open(s(t,e.href),"_blank"),o=t,document.querySelectorAll(".gh-mirror-split .split-main").forEach(e=>{const t=e,n=t.getAttribute("data-original-href");n&&(t.href=s(o,n),t.title="通过 "+o.name+" 下载")}),c(i),i.classList.remove("open")}),i.appendChild(n)}),c(i),a.addEventListener("click",e=>{e.stopPropagation();const t=i.classList.contains("open");l(),t||i.classList.add("open")}),t.appendChild(r),t.appendChild(a),t.appendChild(i),e.parentNode.insertBefore(t,e.nextSibling);const u=e.parentElement;e.href.includes("archive/refs/heads")&&u&&"LI"===u.tagName&&u.classList.add("gh-mirror-li")}let d=null,p=null;function m(){d&&clearTimeout(d),d=setTimeout(()=>{p&&p.disconnect();const e=document.querySelectorAll("a[href*='releases/download']:not([data-mirror-split]), a[href*='archive/refs/heads']:not([data-mirror-split])");e.forEach(u),p&&document.body&&p.observe(document.body,{childList:!0,subtree:!0}),e.length&&i(e.length)},250)}!function(){const e=document.createElement("style");e.textContent='.gh-mirror-split{position:relative;display:inline-flex;align-items:stretch;margin-left:8px;vertical-align:middle;flex-shrink:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif}.gh-mirror-split a,.gh-mirror-split button{font-size:12px;line-height:20px;padding:3px 12px;border:1px solid var(--color-border-default,#d0d7de);background-color:var(--color-btn-bg,#f6f8fa);color:var(--color-fg-default,#24292f);cursor:pointer;text-decoration:none !important;white-space:nowrap;box-shadow:var(--color-btn-shadow,0 1px 0 rgba(27,31,36,0.04));box-sizing:border-box}.gh-mirror-split a:hover,.gh-mirror-split a:active,.gh-mirror-split a:focus,.gh-mirror-split button:hover{text-decoration:none !important;background-color:var(--color-btn-hover-bg,#f3f4f6);border-color:var(--color-btn-hover-border,#d0d7de)}.gh-mirror-split .split-main{border-radius:6px 0 0 6px;border-right:none}.gh-mirror-split .split-arrow{border-radius:0 6px 6px 0;padding-left:8px;padding-right:8px}.gh-mirror-menu{position:absolute;right:0;top:calc(100% + 4px);min-width:160px;margin:0;padding:4px 0;list-style:none;background-color:var(--color-canvas-overlay,#fff);border:1px solid var(--color-border-default,#d0d7de);border-radius:6px;box-shadow:var(--color-shadow-large,0 8px 24px rgba(140,149,159,0.2));z-index:999999;display:none}.gh-mirror-menu.open{display:block}.gh-mirror-menu li{padding:4px 12px;font-size:12px;cursor:pointer;color:var(--color-fg-default,#24292f);white-space:nowrap}.gh-mirror-menu li:hover{background-color:var(--color-accent-subtle,#ddf4ff);color:var(--color-accent-fg,#0969da)}.gh-mirror-menu li.selected{color:var(--color-accent-fg,#0969da);font-weight:600}li.gh-mirror-li{display:flex !important;align-items:center}',document.head.appendChild(e)}(),p=new MutationObserver(m),p.observe(document.body,{childList:!0,subtree:!0}),m(),document.addEventListener("click",l);let h=null;try{"function"==typeof GM_addValueChangeListener&&(h=GM_addValueChangeListener("sc:plugin:com.flowsaro.github-accel.settings",()=>{r(),document.querySelectorAll(".gh-mirror-split").forEach(e=>e.remove()),m()}))}catch{}t.onDispose(()=>{if(p&&p.disconnect(),d&&clearTimeout(d),document.removeEventListener("click",l),null!=h&&"function"==typeof GM_removeValueChangeListener)try{GM_removeValueChangeListener(h)}catch{}})}},{manifest:{id:W,name:"快捷翻译",version:"0.7.5",type:"shortcut",permissions:["selection","menu","network","storage","ui"],icon:X,description:"选中文本后自动弹出快捷菜单,点图标即翻译(结果以通知展示,单词附带词典信息);无选中时点图标弹出手动翻译面板,翻译结果直接展示在面板里(可选源/目标语言,未选时按字符集自动猜源语言;MyMemory 免费接口,支持配置 API Key;英文单词经 freedictionaryapi.com 补充音标/词性/释义)",builtin:!0},init:function(e){const t=e,n=[{label:"中文",value:"zh-CN"},{label:"English",value:"en"},{label:"日本語",value:"ja"},{label:"한국어",value:"ko"},{label:"Français",value:"fr"},{label:"Deutsch",value:"de"},{label:"Español",value:"es"},{label:"Русский",value:"ru"}],o=[{label:"自动检测",value:"auto"},...n],r="auto",a=r,i="zh-CN",s=[[/[\u3040-\u30ff]/,"ja"],[/[\uac00-\ud7af]/,"ko"],[/[\u0600-\u06ff]/,"ar"],[/[\u0400-\u04ff]/,"ru"],[/[\u4e00-\u9fa5]/,"zh-CN"],[/[\u0900-\u097f]/,"hi"]];function l(e,t,n){const o=t&&t!==r?t:function(e){for(const[t,n]of s)if(t.test(e))return n;return"en"}(e);return{from:o,to:o===n?"zh-CN"===n?"en":"zh-CN":n}}t.declareSettings([{key:"apiKey",label:"MyMemory API Key(可选,提升每日配额)",type:"text",placeholder:"留空使用匿名接口"},{key:"sourceLang",label:"默认源语言(划词翻译始终自动检测,此项只作用于手动输入)",type:"select",default:a,options:o},{key:"targetLang",label:"默认目标语言(划词与手动输入共用;与源语言相同时自动换向)",type:"select",default:i,options:n}]);const c="guideShownAt:menu";let u="";t.onSelectionChange(e=>{const n=(e||"").trim();if(n===u)return;if(u=n,!n)return void t.closeMenu();const o=t.openMenu();o&&(o.ok&&!1!==o.inMenu||function(){const e=Date.now();e-(Number(t.getState(c,0))||0)<432e5||(t.setState(c,e),t.toast("还差一步:把「快捷翻译」放进快捷菜单",{type:"info",timeout:8e3,note:"长按按钮 → 设置 → 快捷菜单 → 槽位绑定选「快捷翻译」"}))}())});let d="";t.onEvent("manual-input",e=>{d="string"==typeof e?e:""}),t.onEvent("manual-src",e=>{"string"==typeof e&&e&&t.setValue("sourceLang",e)}),t.onEvent("manual-dst",e=>{"string"==typeof e&&e&&t.setValue("targetLang",e)}),t.onEvent("manual-go",e=>{const n=("string"==typeof e?e:d).trim();if(!n)return void t.toast("先输入要翻译的内容",{type:"warning"});if(V)return;const{from:o,to:r}=l(n,t.getValue("sourceLang",a),t.getValue("targetLang",i));!async function(e,n,o){const r=++C;V=!0;const a=t.toast("翻译中…",{type:"info",timeout:0}),i=n.startsWith("en")&&h(e),s=i?k(e.trim(),"en"):Promise.resolve([]);let l="";try{t.openPanel(N({busy:!0}));let r="";try{const a=await t.httpRequest(E(e,n,o));if(a.ok){const e=JSON.parse(a.text);l=e&&e.responseData&&e.responseData.translatedText||"",l||(r="未获取到翻译结果")}else r="翻译失败("+a.status+")"}catch{r="翻译失败,请检查网络"}if(t.dismissToast(a),r)return void t.openPanel(N({error:r}))}finally{V=!1}const c=await Promise.race([s,new Promise(e=>setTimeout(()=>e(null),S))]);if(r!==C)return;if(c)return void t.openPanel(N({result:l,infoLines:c}));t.openPanel(N({result:l,infoPending:i}));const u=await s;if(r!==C)return;t.openPanel(N({result:l,infoLines:u}))}(n,o,r)}),t.onActivate(async()=>{t.closeMenu();const e=(await t.getSelectedText()||"").trim();if(!e)return void t.openPanel(N());const{from:n,to:o}=l(e,r,t.getValue("targetLang",i));!async function(e,n,o){t.closePanel();const r=t.toast("翻译中…",{type:"info",timeout:0}),a=n.startsWith("en")&&h(e),i=a?k(e.trim(),"en"):Promise.resolve([]);try{const a=await t.httpRequest(E(e,n,o));if(!a.ok)return t.dismissToast(r),void t.toast("翻译失败("+a.status+")",{type:"error"});const s=JSON.parse(a.text),l=s&&s.responseData&&s.responseData.translatedText;if(!l)return t.dismissToast(r),void t.toast("未获取到翻译结果",{type:"warning"});t.dismissToast(r);const c=t.toast(l,{type:"success",copyable:!0,timeout:0});i.then(e=>{e.length&&t.updateToast(c,{note:e.join("\n")})})}catch(e){t.dismissToast(r),t.toast("翻译失败,请检查网络",{type:"error"})}}(e,n,o)});const p="https://freedictionaryapi.com/api/v1/entries/",m={noun:"名词",verb:"动词",adjective:"形容词",adverb:"副词",pronoun:"代词",preposition:"介词",conjunction:"连词",interjection:"感叹词",exclamation:"感叹词",determiner:"限定词",article:"冠词",numeral:"数词",prefix:"前缀",suffix:"后缀",abbreviation:"缩写"};function h(e){return/^[a-zA-Z][a-zA-Z'’-]*$/.test(e.trim())}function g(e,t){const n=String(e??"").replace(/<[^>]*>/g,"").replace(/\s+/g," ").trim();return n.length>t?n.slice(0,t-1).trimEnd()+"…":n}const f=15e3,b=600,v=6e4;let y=0;function x(e,t,n){try{console.debug(`[火箭按钮] 词典未命中 ${e}:${t}(${n}ms)`)}catch{}}async function w(e,n){const o=Date.now();try{const r=await t.httpRequest(p+n+"/"+encodeURIComponent(e),{timeout:f});if(!r.ok)return x(e,"status="+r.status,Date.now()-o),{lines:[],definitive:!1};let a;try{a=JSON.parse(r.text)}catch{return x(e,"响应无法解析",Date.now()-o),{lines:[],definitive:!1}}const i=Array.isArray(a&&a.entries)?a.entries:[];if(!i.length)return{lines:[],definitive:!0};let s="";for(const e of i){for(const t of e&&e.pronunciations||[])if(t&&t.text){s=String(t.text).trim();break}if(s)break}const l=Array.from(new Set(i.map(e=>e&&e.partOfSpeech).filter(Boolean))).slice(0,3).map(e=>m[e]||e),c=[];for(const e of i){for(const t of e&&e.senses||[])if(t&&t.definition&&c.push({text:t.definition,examples:Array.isArray(t.examples)?t.examples:[]}),c.length>=2)break;if(c.length>=2)break}if(!s&&!l.length&&!c.length)return{lines:[],definitive:!0};const u=[],d=[];s&&d.push("/"+s.replace(/^\/+|\/+$/g,"")+"/"),l.length&&d.push(l.join("/")),d.length&&u.push(d.join(" · ")),c.forEach((e,t)=>u.push(`${t+1}. ${g(e.text,80)}`));const h=c.map(e=>e.examples[0]).filter(Boolean)[0];return h&&u.push("例 "+g(h,80)),{lines:u,definitive:!0}}catch{return x(e,"请求异常",Date.now()-o),{lines:[],definitive:!1}}}async function k(e,t){if(Date.now()setTimeout(e,b)),n=await w(e,t)),n.lines.length||n.definitive||(y=Date.now()+v,x(e,"两次都没拿到,进入 "+v/1e3+"s 静默",0)),n.lines}function E(e,n,o){let r="https://api.mymemory.translated.net/get?q="+encodeURIComponent(e)+"&langpair="+n+"|"+o;const a=t.getValue("apiKey","");return a&&(r+="&de="+encodeURIComponent(a)),r}let V=!1,C=0;const S=400;function N(e){const r=[{type:"text",content:"输入单词或句子即可翻译:",style:{color:"secondary",size:"sm"}},{type:"row",items:[{type:"select",value:t.getValue("sourceLang",a),options:o,event:"manual-src"},{type:"text",content:"→",style:{color:"secondary"}},{type:"select",value:t.getValue("targetLang",i),options:n,event:"manual-dst"}]},{type:"textarea",event:"manual-input",submitEvent:"manual-go",value:d,placeholder:"输入要翻译的单词或句子…(回车翻译,Shift+回车换行)"},{type:"button",label:e?.busy?"翻译中…":"翻译",event:"manual-go",variant:"primary",full:!0}];if(e?.error&&r.push({type:"fieldset",legend:"翻译失败",body:[{type:"text",content:e.error,style:{color:"danger",size:"sm"}}]}),e?.result){const t=[{type:"text",content:e.result,style:{weight:"bold",size:"lg"}}];for(const n of e.infoLines||[])t.push({type:"text",content:n,style:{color:"secondary",size:"sm"}});e.infoLines?.length||t.push({type:"text",content:e.infoPending?"(🔍 正在查词典…)":"(🔍 无法找到相关的词典信息)",style:{color:"secondary",size:"sm"}}),r.push({type:"fieldset",legend:"翻译结果",body:t})}return{type:"panel",body:r}}}},{manifest:{id:"com.flowsaro.reminder",name:"提醒助手",version:"1.12.0",type:"feature",permissions:["storage","broadcast","severity"],icon:"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='0.9em' font-size='90'%3E%E2%8F%B0%3C/text%3E%3C/svg%3E",description:"按固定时间弹提醒:支持每 N 分钟/小时循环、每天 HH:MM、每周X HH:MM、一次性 YYYY-MM-DD HH:MM,以及从保存时刻起算的倒计时(如 30 分钟,只支持一条);提醒内容由「|」后的文本自定义,所有打开的标签页同步弹出;迟到的提醒会补发,并在次要文字里说明原定时刻与延迟多久",builtin:!0},init:function(e){const t=e;t.declareSettings([{key:"reminders",label:"提醒列表(每行一条:规则|通知内容,支持安排多个计划分行输入)",type:"textarea",placeholder:"每 45 分钟|⏰ 到点啦:起来喝水\n09:30|📅 到点啦:晨会\n每周一,周五 18:00|💼 到点啦:写周报\n2026-09-20 15:00|✅ 该交材料了",default:""},{key:"countdowns",label:"倒计时(一次性,只支持一条):一条「时长|通知内容」,从保存那一刻起算,只响一次",type:"textarea",placeholder:"30 分钟|🥢 泡面好了",default:""},{key:"schedLate",label:"定点提醒(每日/每周/一次性):迟到多久之内仍然补发(分钟,0 = 只报准点)",type:"text",placeholder:String(G),default:String(G)},{key:"intervalToast",label:"周期提醒(每 N 分钟/小时):通知自动关闭秒数(0 = 不自动关闭)",type:"text",placeholder:"8",default:String(8)},{key:"schedToast",label:"定点提醒(每日/每周/一次性):通知自动关闭秒数(0 = 不自动关闭)",type:"text",placeholder:"0",default:"0"}]);let n=null,o=null,r=null,a=[],i=[],s=[];const l=new Map;let c=[];const u=new Map,d=new Map,p=new Map;function m(e){const n=p.get(e);return void 0!==n?n:String(t.getState(e,""))}function h(e,n){!function(e,t){if(p.set(e,t),p.size>200){const e=p.keys().next().value;void 0!==e&&p.delete(e)}}(e,n),t.setState(e,n)}function g(){const e=String(t.getValue("reminders","")||"").replace(/\\n/g,"\n");if(e===o)return;o=e;const n=[],r=[];Y(e).forEach(e=>{const t=function(e){const t=e.indexOf("|");if(t<0)return{line:e,error:"缺少「|」分隔符"};const n=e.slice(0,t).trim(),o=e.slice(t+1).trim();if(!n)return{line:e,error:"「|」左边的时间规则是空的"};if(!o)return{line:e,error:"「|」右边的提醒内容是空的"};let r;if(r=n.match(/^(\d{4})-(\d{1,2})-(\d{1,2})[ T](\d{1,2}):(\d{2})$/),r)return q(+r[4],+r[5])?{type:"once",key:"once|"+n+"|"+o,content:o,y:+r[1],mo:+r[2]-1,d:+r[3],h:+r[4],mi:+r[5],line:e}:{line:e,error:"时间超出范围(小时 0-23,分钟 0-59)"};if(r=n.match(/^每天\s*(\d{1,2}):(\d{2})$/)||n.match(/^(\d{1,2}):(\d{2})$/),r)return q(+r[1],+r[2])?{type:"daily",key:"daily|"+n+"|"+o,content:o,h:+r[1],mi:+r[2]}:{line:e,error:"时间超出范围(小时 0-23,分钟 0-59)"};if(r=n.match(/^(?:每)?周(周?[一二三四五六日天](?:[,,、]周?[一二三四五六日天])*)\s+(\d{1,2}):(\d{2})$/),r){if(!q(+r[2],+r[3]))return{line:e,error:"时间超出范围(小时 0-23,分钟 0-59)"};const t=r[1].split(/[,,、]/).map(e=>F[e.replace(/^周/,"").trim()]).filter(e=>void 0!==e);return t.length?{type:"weekly",key:"weekly|"+n+"|"+o,content:o,days:t,h:+r[2],mi:+r[3]}:{line:e,error:"没看懂星期写法「"+r[1]+"」(示例:每周一,周五 18:00)"}}if(r=n.match(/^每\s*(\d+)\s*(秒|秒钟|分钟|小时|分)?$/)||n.match(/^(\d+)\s*(秒|秒钟|分钟|小时|分|s|sec|m|min|h)$/i),r){const t=String(r[2]||"分钟").toLowerCase(),a=(H[t]||0)*+r[1];return a?ae.key));c.forEach(e=>{i.has(e)||u.set(e,0)}),i.forEach(e=>u.delete(e)),c=n.map(e=>e.key),f(r,[],"提醒规则","格式:规则|内容。规则支持:每 N 分钟/小时、HH:MM、每周X HH:MM、YYYY-MM-DD HH:MM","badRulesSig")}function f(e,n,o,r,a){const i=e.map(e=>e.line+" → "+e.error).concat(n.map(e=>e+" → 超出条数上限")).join("\n");if(i===String(t.getState(a,"")))return;if(t.setState(a,i),!i)return;const s=[];e.length&&(s.push("有 "+e.length+" 条"+o+"没被识别,已忽略:"+b(e.map(e=>e.line))),e.forEach(e=>{console.warn("[提醒助手] 无法识别的"+o+":「"+e.line+"」原因:"+e.error)})),n.length&&(s.push(o+"只支持一条,已忽略后面 "+n.length+" 条:"+b(n)),n.forEach(e=>{console.warn("[提醒助手]"+o+"只支持一条,已忽略:「"+e+"」")})),t.toast(s.join(";")+"。"+r,{type:"warning",timeout:0})}function b(e){const t=e.slice(0,2).map(e=>"「"+e+"」").join("");return e.length>2?t+" 等 "+e.length+" 条":t}function v(){const e=String(t.getValue("countdowns","")||"").replace(/\\n/g,"\n");if(e===r)return;r=e;const n=[],o=[];Y(e).forEach(e=>{const t=function(e){const t=e.indexOf("|");if(t<0)return{line:e,error:"缺少「|」分隔符"};const n=e.slice(0,t).trim(),o=e.slice(t+1).trim();if(!n)return{line:e,error:"「|」左边的时长是空的"};if(!o)return{line:e,error:"「|」右边的提醒内容是空的"};if(/^每/.test(n))return{line:e,error:"倒计时是一次性的,「每 …」这类循环写法请写到「提醒列表」里"};const r=n.match(/^(\d+)\s*(秒|秒钟|分钟|小时|分|s|sec|m|min|h)\s*(?:后|以后|之后)?$/i);if(!r)return{line:e,error:"没看懂时长写法「"+n+"」(示例:30 分钟、2 小时、45m)"};const a=(H[String(r[2]).toLowerCase()]||0)*+r[1];return a?ae.line);i=a;const u=new Set(a.map(e=>e.key));s.forEach(e=>{u.has(e)||l.set(e,0)}),u.forEach(e=>l.delete(e)),s=a.map(e=>e.key),f(o,c,"倒计时","格式:时长|内容,只支持一条。时长支持 N 秒/分钟/小时(如 30 分钟、2 小时、45m)","badCdSig")}function y(e,n){const o=parseInt(String(t.getValue(e,n)),10);return isNaN(o)||o<0?n:o}function x(){const e=parseInt(String(t.getValue("schedLate",String(G))),10);return isNaN(e)||e<0?108e5:6e4*e}function w(e){if(e<=6e4)return"";for(const t of j)if(e<=t.max)return t.emoji;return""}function k(e,t){const n=new Date(e),o=O(n.getHours())+":"+O(n.getMinutes());return t?O(n.getMonth()+1)+"-"+O(n.getDate())+" "+o:o}function E(e,t,n){const o=w(n);if(!o)return"";const r=function(e){const t=Math.max(0,Math.round(e/1e3));if(t<60)return t+" 秒";const n=Math.round(t/60);if(n<60)return n+" 分钟";const o=Math.floor(n/60),r=n%60;if(o<24)return r?o+" 小时 "+r+" 分钟":o+" 小时";const a=Math.floor(o/24),i=o%24;return i?a+" 天 "+i+" 小时":a+" 天"}(n);return"interval"===e.type?o+" 延迟 "+r+"(页面休眠或标签页被节流)":"daily"===e.type||"weekly"===e.type?o+" 补发:原定 "+k(t,!1)+",迟到 "+r:o+" 补发:原定 "+k(t,!0)+",迟到 "+r}function V(e,n,o){const r="interval"===e.type?y("intervalToast",8):y("schedToast",0),a=E(e,n,o);t.toast(e.content,{type:"warning",timeout:1e3*r,broadcast:!0,...a?{note:a}:null})}function C(e,n,o){if(ox()?(h(r,"missed"),function(e,n){t.toast("「"+e+"」已错过(原定 "+k(n,!0)+"),不会再补发,可以从设置里删掉它",{type:"warning",timeout:0})}(e.line,n),!1):(h(r,"done"),V(e,n,a),!0)}function S(e){return"nextAt:"+e}const N="lastFired:";function B(e,t){return function(e){const t=Math.max(0,Math.ceil(e/1e3)),n=Math.floor(t/3600),o=Math.floor(t%3600/60),r=t%60;return n>0?n+":"+O(o)+":"+O(r):O(o)+":"+O(r)}(t)+" ➡️ "+e.content}function M(e,n,o){const a=t.toast(n,{type:"info",severity:"high",busy:!0,timeout:0,note:o,onClose:()=>function(e){const n="fired:"+e.key;"done"===m(n)?(t.setValue("countdowns",""),r=""):h(n,"cancel");d.delete(e.key)}(e)});"number"==typeof a&&a>0&&d.set(e.key,a)}function z(e,n,o){const r=B(e,n-o),a=d.get(e.key);void 0!==a?t.updateToast(a,{text:r})||(d.delete(e.key),M(e,r,U)):M(e,r,U)}function T(e,n){const o=P+e.key,r=Number(t.getState(o,0));if(!Number.isFinite(r)||r<=0)return t.setState(o,n+e.ms),void z(e,n+e.ms,n);const a="fired:"+e.key,i=m(a);if("cancel"!==i)return n>=r?("done"!==i&&h(a,"done"),z(e,r,n),void function(e,n,o){const r=d.get(e.key);if(void 0===r)return;const a=o-n,i=a>6e4?"📌 "+w(a)+" 已于 "+k(n,!0)+" 到点 · "+$.slice(2):$;t.updateToast(r,{text:B(e,0),note:i,type:"success",busy:!1})||d.delete(e.key)}(e,r,n)):void z(e,r,n);!function(e){const n=d.get(e.key);void 0!==n&&(t.dismissToast(n),d.delete(e.key))}(e)}function L(){if(g(),v(),function(){if(!l.size)return;const e=new Set(i.map(e=>e.key));l.forEach((n,o)=>{if(e.has(o))return void l.delete(o);if(n+1<2)return void l.set(o,n+1);l.delete(o),t.setState(P+o,""),t.setState("fired:"+o,""),p.delete("fired:"+o);const r=d.get(o);void 0!==r&&(t.dismissToast(r),d.delete(o))})}(),function(){if(!u.size)return;const e=new Set(a.map(e=>e.key));u.forEach((n,o)=>{e.has(o)?u.delete(o):n+1<2?u.set(o,n+1):(u.delete(o),t.setState(S(o),""),t.setState(N+o,""),t.setState("fired:"+o,""),p.delete("fired:"+o))})}(),!a.length&&!i.length)return;const e=new Date,n=e.getTime();i.forEach(e=>T(e,n)),a.forEach(o=>{if("interval"===o.type)return void function(e,n){const o=Number(t.getState(S(e.key),0));if(!Number.isFinite(o)||o<=0)return void t.setState(S(e.key),n+e.ms);if(na&&(a=i),t.setState(S(e.key),a);const s=Number(t.getState(N+e.key,0));Number.isFinite(s)&&s>=o||(t.setState(N+e.key,o),r<=12e4&&V(e,o,r))}(o,n);if("once"===o.type)return void C(o,new Date(o.y,o.mo,o.d,o.h,o.mi,0).getTime(),n);if(!("daily"===o.type||-1!==o.days.indexOf(e.getDay())))return;const r=new Date(e.getFullYear(),e.getMonth(),e.getDate(),o.h,o.mi,0).getTime(),a=n-r;var i,s,l;a<0||a>x()||(i="fired:"+o.key,s=(l=e).getFullYear()+"-"+O(l.getMonth()+1)+"-"+O(l.getDate()),m(i)!==s&&(h(i,s),1)&&V(o,r,a))})}g(),v(),L(),n=setInterval(L,5e3);let _=null;try{"function"==typeof GM_addValueChangeListener&&(_=GM_addValueChangeListener("sc:plugin:com.flowsaro.reminder.settings",()=>{o=null,r=null,L()}))}catch{}t.onDispose(()=>{if(n&&(clearInterval(n),n=null),null!=_&&"function"==typeof GM_removeValueChangeListener){try{GM_removeValueChangeListener(_)}catch{}_=null}a=[],i=[]})}}],K="sc:",Z={get(e,t){try{if("function"!=typeof GM_getValue)return t;const n=GM_getValue(K+e,"");return n?JSON.parse(String(n)):t}catch{return t}},set(e,t){try{if("function"!=typeof GM_setValue)return;GM_setValue(K+e,JSON.stringify(t))}catch{}},watch(e,t){if("function"!=typeof GM_addValueChangeListener)return()=>{};try{const n=GM_addValueChangeListener(K+e,(e,n,o)=>{t(o)});return()=>{if("function"==typeof GM_removeValueChangeListener)try{GM_removeValueChangeListener(n)}catch{}}}catch{return()=>{}}}},Q="function"==typeof GM_xmlhttpRequest?{request:(e,t)=>new Promise(n=>{try{GM_xmlhttpRequest({method:t?.method||"GET",url:e,headers:t?.headers,data:t?.data,timeout:t?.timeout||1e4,overrideMimeType:"text/plain; charset=utf-8",onload:e=>n({ok:e.status>=200&&e.status<300,status:e.status,text:e.responseText||""}),onerror:()=>n({ok:!1,status:0,text:""}),ontimeout:()=>n({ok:!1,status:0,text:""})})}catch{n({ok:!1,status:0,text:""})}})}:void 0;let ee=null;function te(){return ee||(ee=function(e,t=[]){return new N(e,t)}({storage:Z,http:Q,clipboard:{read:async()=>{try{return await(navigator.clipboard?.readText())||""}catch{return""}},write:async e=>{try{await(navigator.clipboard?.writeText(e))}catch{}}},getSelectedText:()=>window.getSelection()?.toString()||"",log:(...e)=>console.log("[plugin]",...e)},J)),ee}function ne(){return GM_info.script.icon}function oe(e){const t=(e||"").trim();if(!t)return ne();const n=t.match(/data:([^;,]+);base64,\s*([A-Za-z0-9+/=]+)/i);if(n)return`data:${n[1]};base64,${n[2]}`;const o=t.replace(/\s+/g,"");return/^[A-Za-z0-9+/=]+$/.test(o)?`data:${r=o,r.startsWith("R0lGOD")?"image/gif":r.startsWith("UklGR")?"image/webp":"image/png"};base64,${o}`:t.startsWith("data:")?t:"data:image/png;base64,"+o;var r}const re=2147483646;function ae(t,n,o){const r=o?o(GM_getValue(t,n)):GM_getValue(t,n),a=(0,e.ref)(r);try{const r=GM_addValueChangeListener(t,(e,t,r)=>{a.value=o?o(r):r??n});(0,e.onScopeDispose)(()=>{try{GM_removeValueChangeListener(r)}catch{}})}catch{}return a}function ie(e){return t=>null==t?e:Boolean(t)}function se(e){return t=>null==t?e:String(t)}function le(){return e=>{const t=parseFloat(String(e??1));if(isNaN(t))return 1;const n=Math.floor(10*t)/10;return Math.min(4,Math.max(.6,n))}}function ce(){return e=>{const t=parseFloat(String(e??1));if(isNaN(t))return 1;const n=Math.round(20*t)/20;return Math.min(1,Math.max(.3,n))}}function ue(){return e=>Math.min(8,Math.max(2,parseInt(String(e??4),10)||4))}function de(){return e=>oe(String(e||""))}function pe(){return e=>Array.isArray(e)?e.join("\n"):null==e?"":String(e)}const me="app.welcomeShown";const he="app.shortcutHintAt";const ge={class:"flex items-center gap-2 mb-3 pb-3 border-b border-seam"},fe=["src","alt"],be={class:"flex flex-col min-w-0"},ve={class:"text-sm font-semibold leading-tight truncate"},ye={class:"mt-0.5 text-[10px] leading-tight text-secondary truncate"},xe={class:"sc-scroll flex-1 min-h-0 overflow-y-auto p-[2px_10px_8px_4px] -mr-1.5"},we={key:0,class:"mb-2.5"},ke={class:"flex-1 break-words"},Ee={key:0},Ve=["onClick"],Ce={class:"flex items-center gap-2 mb-2 text-[13px] cursor-pointer rounded-lg px-2 -mx-2 py-1.5 transition-colors hover:bg-white/10"},Se={class:"border-surface rounded-xl p-3 mb-3 min-w-0 bg-subtle-btn"},Ne={class:"flex flex-wrap items-center gap-x-5 gap-y-1 mb-4 -mx-2 px-2"},Be={class:"flex items-center gap-2 text-[13px] cursor-pointer rounded-lg py-1.5 transition-colors hover:bg-white/10"},Me={class:"flex items-center gap-2 text-[13px] cursor-pointer rounded-lg py-1.5 transition-colors hover:bg-white/10"},ze={class:"flex items-center gap-1.5 mb-4"},Te={class:"flex items-center gap-2 mb-2 text-[13px] cursor-pointer rounded-lg px-2 -mx-2 py-1.5 transition-colors hover:bg-white/10"},Le={class:"flex items-center gap-1.5 mb-1 text-[13px] cursor-pointer"},_e={class:"flex items-center gap-1.5 mb-2.5 text-[13px] cursor-pointer"},De={class:"flex items-start gap-1.5"},Ie={key:0,class:"mt-3.5"},Ae=["src","title","onClick"],Re=["onClick"],Ge={key:1,class:"mt-1.5 text-[11px] text-danger"},je={class:"border-surface rounded-xl p-3 mb-3 min-w-0 bg-subtle-btn"},Pe={class:"border-surface rounded-xl p-3 mb-3 min-w-0 bg-subtle-btn"},Ue={class:"flex items-center gap-2 mb-2 text-[13px] cursor-pointer rounded-lg px-2 -mx-2 py-1.5 transition-colors hover:bg-white/10"},$e={class:"flex items-center gap-2 mb-2 text-[13px] cursor-pointer rounded-lg px-2 -mx-2 py-1.5 transition-colors hover:bg-white/10"},Fe={class:"border-surface rounded-xl p-3 mb-3 min-w-0 bg-subtle-btn"},He={class:"flex-[0_0_44px]"},qe=["onUpdate:modelValue"],Oe=["value"],Ye={class:"flex justify-between gap-1.5 mb-2"},We={key:1,class:"mb-2"},Xe=["onClick"],Je={class:"flex-[0_0_14px] text-secondary text-[10px]"},Ke=["src"],Ze={key:1,class:"w-4 h-4 shrink-0 flex items-center justify-center rounded-md bg-subtle-btn text-[10px] text-secondary font-medium"},Qe={class:"text-secondary"},et={key:0,class:"ml-1 text-[10px] px-1 py-[1px] rounded-lg bg-accent/20 text-accent"},tt={key:0,class:"py-1 text-secondary"},nt={key:0,class:"text-warning"},ot={key:0},rt={key:1,class:"mt-1 text-danger text-[11px]"},at={class:"mt-1 flex items-center gap-2"},it={class:"flex items-center gap-1 cursor-pointer"},st=["checked","onChange"],lt=["onClick"],ct={key:1,class:"text-[11px] opacity-60"},ut={class:"mb-0.5"},dt=["type","value","placeholder","onInput","onChange"],pt=["value","placeholder","onInput","onChange"],mt=["value","onChange"],ht=["value"],gt={key:3,class:"flex items-center gap-1"},ft=["checked","onChange"],bt={key:2,class:"text-secondary text-xs mb-2"},vt={class:"flex justify-end gap-2 pt-2.5 mt-2.5 border-t border-seam"},yt=(0,e.defineComponent)({__name:"Settings",props:{anchor:{},btnSize:{},initialTab:{}},emits:["close","icon-change","rotate-change","scale-change","opacity-change","anim-change","bg-change","mirror-change","saved","hint"],setup(t,{emit:o}){const r=t,a=o,s=ne(),l=(0,e.ref)(GM_info.script.name),c=(0,e.ref)(GM_info.script.icon),u=(0,e.ref)(GM_info.script.version),d=(0,e.ref)(null),p=(0,e.ref)(0),m=ae("general.githubAccel",!0,ie(!0)),h=ae("general.backTop",!0,ie(!0)),g=ae("general.alwaysShow",!1,ie(!1)),f=ae("general.noBtnBg",!1,ie(!1)),b=ae("general.iconScale","1",e=>String(e??1)),v=ae("general.menuSlots","4",e=>String(e??4)),y=ae("general.quickMenu",!1,ie(!1)),x=ae("general.btnAnim","none",se("none")),w=ae("general.btnOpacity",1,ce()),k=ae("general.btnMirror",!1,ie(!1)),E=ae("general.btnRotate",0,e=>{const t=parseFloat(String(e??0));return isNaN(t)?0:Math.min(360,Math.max(0,Math.round(t)))});(0,e.watch)(E,e=>a("rotate-change",e)),(0,e.watch)(w,e=>{const t=Number(e);a("opacity-change",isNaN(t)?1:t)}),(0,e.watch)(x,e=>a("anim-change",e)),(0,e.watch)(f,e=>a("bg-change",e)),(0,e.watch)(k,e=>a("mirror-change",e)),(0,e.watch)(b,e=>{const t=parseFloat(String(e));a("scale-change",isNaN(t)?1:t)});const V=(0,e.ref)(""),C=ae("general.customIcon","",se("")),S=(0,e.ref)("");const N=ae("general.iconList",[],function(e){try{let t=[];if(Array.isArray(e))t=e.map(String).filter(Boolean);else{const n=null==e?"":String(e),o=n?JSON.parse(n):[];Array.isArray(o)&&(t=o.filter(e=>"string"==typeof e&&e.trim()))}return t.includes(s)||t.push(s),t.length>12&&(t=t.slice(0,11).concat(s)),t}catch{return[s]}}),B=(0,e.ref)(N.value.includes(C.value)?C.value:null),M=(0,e.ref)(!1),z=(0,e.ref)(!1),T=(0,e.ref)(null);function L(e){return function(e){const t=e.match(/base64,([A-Za-z0-9+/=]+)/),n=t?t[1]:e,o=n.endsWith("==")?2:n.endsWith("=")?1:0;return Math.floor(3*n.length/4)-o}(e)>51200?(S.value="图片超过 50KB,无法添加",!1):!N.value.includes(e)&&N.value.length>=12?(S.value="图标列表最多 12 个",!1):(S.value="",e===s||(N.value.includes(e)?N.value=[e,...N.value.filter(t=>t!==e)]:N.value.unshift(e),GM_setValue("general.iconList",JSON.stringify(N.value))),!0)}function _(){const e=V.value.trim();if(!e)return;const t=oe(e);L(t)&&(B.value=t,V.value="",a("icon-change",t))}(0,e.watch)(C,e=>{e&&N.value.includes(e)&&(B.value=e)});const D=(0,e.ref)(null);function I(){D.value?.click()}function A(e){const t=e.target,n=t.files?.[0];if(t.value="",!n)return;if(n.size>51200)return void(S.value="图片不能超过 50KB");const o=new FileReader;o.onload=()=>{const e=String(o.result||"");if(!e)return;const t=oe(e);L(t),B.value=t,a("icon-change",t)},o.readAsDataURL(n)}function R(){const e=T.value;e&&(z.value=e.scrollHeight>e.clientHeight+2)}const G=ae("general.disabledSites","",pe()),j=(0,e.computed)(()=>{const e=r.btnSize??46,t=r.anchor.x+e+20,n=re,o=Math.max(0,window.innerHeight-p.value-12);return{right:t+"px",bottom:Math.min(r.anchor.y,o)+"px",zIndex:n}});function P(){const e=location.hostname,t=G.value.split("\n").map(e=>e.trim()).filter(Boolean);t.includes(e)||t.push(e),G.value=t.join("\n")}const U=(0,e.ref)("general"),$=[{key:"general",label:"常规"},{key:"menu",label:"快捷菜单"},{key:"plugin",label:"插件管理"}],F=te(),H=(0,e.ref)([]),q=(0,e.ref)([]),O=(0,e.ref)(""),Y=(0,e.ref)(!1),W=(0,e.ref)(""),X=(0,e.ref)(null),J=(0,e.ref)(null),K=(0,e.ref)(new Set),Z=(0,e.computed)(()=>Math.min(8,Math.max(2,parseInt(v.value,10)||4)));function Q(){H.value=F.list();const e=Z.value,t=F.getBindings();q.value=[];for(let n=0;n{W.value=String(o.result||""),O.value=""},o.readAsText(n)}const ue=(0,e.computed)(()=>F.getPluginErrors());function de(e){return F.getSettings(e)}const me=(0,e.ref)({});function yt(e,t){return e+"::"+t}function xt(e,t){const n=yt(e,t.key);if(n in me.value)return me.value[n];const o=F.getPluginSetting(e,t.key);return void 0!==o?o:t.default??""}function wt(e,t,n){me.value={...me.value,[yt(e,t)]:n}}function kt(e,t,n){F.setPluginSetting(e,t,n);const o=yt(e,t);if(o in me.value){const e={...me.value};delete e[o],me.value=e}}function Et(){Object.keys(me.value).forEach(e=>{const t=e.indexOf("::");t<0||kt(e.slice(0,t),e.slice(t+1),me.value[e])})}function Vt(e){return F.isEnabled(e)}function Ct(){const e=W.value.trim();if(!e)return;const t=F.install(e);Y.value=t.ok,O.value=t.ok?"shortcut"===t.type?`安装成功:${t.id}(快捷功能,请到「快捷菜单」标签绑定槽位后使用)`:`安装成功:${t.id}`:`安装失败:${t.error||"未知错误"}`,t.ok&&(W.value=""),Q()}function St(e){return K.value.has(e)}function Nt(e){const t=new Set(q.value.filter((t,n)=>n!==e&&t));return H.value.filter(e=>"shortcut"===e.manifest.type&&!t.has(e.manifest.id))}function Bt(){const e=V.value.trim();let t="";e?t=oe(e):B.value?t=B.value:N.value.length&&(t=N.value[0]),GM_setValue("general.githubAccel",m.value),GM_setValue("general.backTop",h.value),GM_setValue("general.alwaysShow",g.value),GM_setValue("general.noBtnBg",f.value),GM_setValue("general.iconScale",function(e){const t=parseFloat(e);if(isNaN(t))return 1;const n=Math.floor(10*t)/10;return Math.min(4,Math.max(.6,n))}(b.value)),GM_setValue("general.menuSlots",Math.min(8,Math.max(2,parseInt(v.value,10)||4))),GM_setValue("general.quickMenu",y.value),GM_setValue("general.btnAnim",x.value),GM_setValue("general.btnRotate",E.value),GM_setValue("general.btnOpacity",ce()(w.value)),GM_setValue("general.btnMirror",k.value),GM_setValue("general.customIcon",t),GM_setValue("general.iconList",JSON.stringify(N.value)),GM_setValue("general.disabledSites",G.value);const n=Z.value;for(let e=0;eF.uninstall(e)),K.value=new Set,Et(),function(){const e=new Set(q.value.filter(Boolean)),t=H.value.filter(t=>"shortcut"===t.manifest.type&&Vt(t.manifest.id)&&!e.has(t.manifest.id));if(!t.length)return;const n=Date.now();n-(Number(GM_getValue(he,0))||0)<432e5||(GM_setValue(he,n),a("hint",{text:`「${t.map(e=>e.manifest.name).join("、")}」还没放进快捷菜单,装了也找不到入口`,note:"长按按钮 → 设置 → 快捷菜单 → 槽位绑定选中它(保存后选中文字就会自动亮出菜单)"}))}(),a("saved",t),a("close")}function Mt(e){const t=d.value?.$el;t&&(e.composedPath().includes(t)||(Et(),a("close")))}let zt=null;return(0,e.onMounted)(()=>{p.value=d.value?.$el.offsetHeight??0,function(){const e=d.value?.$el?.getRootNode();e&&!zt&&(zt=document.createElement("style"),zt.textContent=".sc-scroll::-webkit-scrollbar { width: 6px; }.sc-scroll::-webkit-scrollbar-track { background: transparent; }.sc-scroll::-webkit-scrollbar-thumb { background: var(--color-secondary); border-radius: 3px; }.sc-scroll::-webkit-scrollbar-thumb:hover { background: var(--color-primary); opacity: .5; }",e.appendChild(zt))}(),Q(),r.initialTab&&(U.value=r.initialTab),(0,e.nextTick)(R),setTimeout(()=>{document.addEventListener("mousedown",Mt)},0)}),(0,e.watch)(N,()=>{(0,e.nextTick)(R)}),(0,e.watch)(U,t=>{"icon"===t&&(0,e.nextTick)(R)}),(0,e.onUnmounted)(()=>{if(Et(),document.removeEventListener("mousedown",Mt),zt){try{zt.remove()}catch{}zt=null}}),(t,o)=>((0,e.openBlock)(),(0,e.createBlock)((0,e.unref)(n),{ref_key:"panelRef",ref:d,class:"fixed w-[300px] max-w-[80vw] h-[520px] flex flex-col box-border",style:(0,e.normalizeStyle)(j.value)},{default:(0,e.withCtx)(()=>[(0,e.createElementVNode)("div",ge,[c.value?((0,e.openBlock)(),(0,e.createElementBlock)("img",{key:0,src:c.value,class:"w-7 h-7 shrink-0 object-contain",alt:l.value},null,8,fe)):(0,e.createCommentVNode)("v-if",!0),(0,e.createElementVNode)("div",be,[(0,e.createElementVNode)("strong",ve,(0,e.toDisplayString)(l.value+"设置"),1),(0,e.createElementVNode)("span",ye,"v"+(0,e.toDisplayString)(u.value),1)]),(0,e.createElementVNode)("button",{type:"button",class:"ml-auto w-6 h-6 flex items-center justify-center rounded-md text-secondary text-lg leading-none transition-colors hover:text-primary hover:bg-white/15",title:"关闭",onClick:o[0]||(o[0]=e=>t.$emit("close"))}," × ")]),(0,e.createCommentVNode)(" 可滚动内容区 "),(0,e.createElementVNode)("div",xe,[(0,e.createVNode)((0,e.unref)(i),{modelValue:U.value,"onUpdate:modelValue":o[23]||(o[23]=e=>U.value=e),items:$},{general:(0,e.withCtx)(()=>[(0,e.createCommentVNode)(" 插件加载错误通知(如 CSP 拦截) "),ue.value.length?((0,e.openBlock)(),(0,e.createElementBlock)("div",we,[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(ue.value,t=>((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:t.id,class:"flex items-start gap-2 p-2 px-2.5 mb-1.5 text-xs leading-[1.5] rounded-lg bg-warning/15 border border-warning/40 text-warning"},[(0,e.createElementVNode)("span",ke,[(0,e.createElementVNode)("b",null,(0,e.toDisplayString)(t.name),1),(0,e.createTextVNode)(" 加载失败:"+(0,e.toDisplayString)(t.message),1),t.count>1?((0,e.openBlock)(),(0,e.createElementBlock)("span",Ee,"(×"+(0,e.toDisplayString)(t.count)+")",1)):(0,e.createCommentVNode)("v-if",!0)]),(0,e.createElementVNode)("button",{type:"button",class:"shrink-0 border-none bg-transparent text-sm cursor-pointer text-inherit leading-none",onClick:e=>{return n=t.id,void F.clearPluginError(n);var n}}," × ",8,Ve)]))),128))])):(0,e.createCommentVNode)("v-if",!0),(0,e.createCommentVNode)(" 主按钮设置 "),(0,e.createElementVNode)("label",Ce,[(0,e.withDirectives)((0,e.createElementVNode)("input",{"onUpdate:modelValue":o[1]||(o[1]=t=>(0,e.isRef)(g)?g.value=t:null),type:"checkbox",class:"accent-accent"},null,512),[[e.vModelCheckbox,(0,e.unref)(g)]]),o[25]||(o[25]=(0,e.createTextVNode)(" 关闭智能隐藏 ",-1))]),(0,e.createElementVNode)("fieldset",Se,[o[34]||(o[34]=(0,e.createElementVNode)("legend",{class:"text-[11px] px-2 py-0.5 rounded-full bg-chip text-accent font-medium"}," 图标设置 ",-1)),(0,e.createCommentVNode)(" 外观开关:两个小勾选框并排,省一行 "),(0,e.createElementVNode)("div",Ne,[(0,e.createElementVNode)("label",Be,[(0,e.withDirectives)((0,e.createElementVNode)("input",{"onUpdate:modelValue":o[2]||(o[2]=t=>(0,e.isRef)(f)?f.value=t:null),type:"checkbox",class:"accent-accent"},null,512),[[e.vModelCheckbox,(0,e.unref)(f)]]),o[26]||(o[26]=(0,e.createTextVNode)(" 只显示图标 ",-1))]),(0,e.createElementVNode)("label",Me,[(0,e.withDirectives)((0,e.createElementVNode)("input",{"onUpdate:modelValue":o[3]||(o[3]=t=>(0,e.isRef)(k)?k.value=t:null),type:"checkbox",class:"accent-accent"},null,512),[[e.vModelCheckbox,(0,e.unref)(k)]]),o[27]||(o[27]=(0,e.createTextVNode)(" 水平镜像 ",-1))])]),(0,e.createElementVNode)("div",ze,[(0,e.withDirectives)((0,e.createElementVNode)("input",{"onUpdate:modelValue":o[4]||(o[4]=t=>(0,e.isRef)(b)?b.value=t:null),type:"number",min:"0.6",max:"4",step:"0.1",title:"图标倍率(1x = 26px,最大 4x)",class:"flex-[0_0_52px] w-[52px] p-[5px_6px] text-xs leading-[1.5] border-surface rounded-lg bg-input text-primary transition-shadow sc-field"},null,512),[[e.vModelText,(0,e.unref)(b)]]),o[28]||(o[28]=(0,e.createElementVNode)("span",{class:"text-secondary whitespace-nowrap"},"倍",-1)),(0,e.createElementVNode)("button",{type:"button",class:"flex-1 text-xs px-2.5 py-1 border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",title:"设为 2x",onClick:o[5]||(o[5]=e=>b.value="2")}," 2倍 "),(0,e.createElementVNode)("button",{type:"button",class:"flex-1 text-xs px-2.5 py-1 border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",title:"重置为默认大小",onClick:o[6]||(o[6]=e=>b.value="1")}," 默认 ")]),(0,e.createCommentVNode)(" 按钮图标动画 "),(0,e.createElementVNode)("label",Te,[o[30]||(o[30]=(0,e.createElementVNode)("span",{class:"shrink-0"},"按钮动画",-1)),(0,e.withDirectives)((0,e.createElementVNode)("select",{"onUpdate:modelValue":o[7]||(o[7]=t=>(0,e.isRef)(x)?x.value=t:null),class:"flex-1 px-1.5 py-1 text-xs border-surface rounded-lg bg-input text-primary select-text transition-shadow sc-field",title:"图标动画(GIF 动图不受影响;系统开启减少动态效果时自动禁用)"},[...o[29]||(o[29]=[(0,e.createElementVNode)("option",{value:"none"},"无",-1),(0,e.createElementVNode)("option",{value:"breathe"},"呼吸",-1),(0,e.createElementVNode)("option",{value:"spin"},"旋转",-1),(0,e.createElementVNode)("option",{value:"pulse"},"脉冲",-1),(0,e.createElementVNode)("option",{value:"ripple"},"涟漪",-1)])],512),[[e.vModelSelect,(0,e.unref)(x)]])]),(0,e.createCommentVNode)(" 按钮透明度:平时淡着,交互时自动回到不透明 "),(0,e.createElementVNode)("label",Le,[o[31]||(o[31]=(0,e.createElementVNode)("span",{class:"shrink-0"},"不透明度",-1)),(0,e.withDirectives)((0,e.createElementVNode)("input",{"onUpdate:modelValue":o[8]||(o[8]=t=>(0,e.isRef)(w)?w.value=t:null),type:"number",min:"0.3",max:"1",step:"0.05",class:"w-16 px-1.5 py-1 text-xs border-surface rounded-lg bg-input text-primary transition-shadow sc-field",title:"0.3 ~ 1:平时按这个值淡在页面上",onInput:o[9]||(o[9]=e=>a("opacity-change",Number(e.target.value)))},null,544),[[e.vModelText,(0,e.unref)(w),void 0,{number:!0}]]),(0,e.createElementVNode)("button",{type:"button",class:"text-[11px] px-1.5 py-0.5 border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",title:"半透明",onClick:o[10]||(o[10]=e=>w.value=.6)}," 0.6 "),(0,e.createElementVNode)("button",{type:"button",class:"text-[11px] px-1.5 py-0.5 border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",title:"完全不透明(默认)",onClick:o[11]||(o[11]=e=>w.value=1)}," 默认 ")]),o[35]||(o[35]=(0,e.createElementVNode)("p",{class:"mb-2 -mt-1 px-2 -mx-2 text-[11px] text-secondary leading-snug"}," 平时按这个值淡在页面上;鼠标移到按钮上或拖动时会自动变清晰。 设置面板打开期间按你调的值显示(方便边调边看),触摸端不生效 —— 那边淡着只会更难点中 ",-1)),(0,e.createCommentVNode)(" 按钮旋转角度:固定刻度 + 可输入 "),(0,e.createElementVNode)("label",_e,[o[32]||(o[32]=(0,e.createElementVNode)("span",{class:"shrink-0"},"旋转",-1)),(0,e.withDirectives)((0,e.createElementVNode)("input",{"onUpdate:modelValue":o[12]||(o[12]=t=>(0,e.isRef)(E)?E.value=t:null),type:"number",min:"0",max:"360",step:"15",class:"w-16 px-1.5 py-1 text-xs border-surface rounded-lg bg-input text-primary transition-shadow sc-field",title:"主按钮旋转角度(0-360°)"},null,512),[[e.vModelText,(0,e.unref)(E),void 0,{number:!0}]]),o[33]||(o[33]=(0,e.createElementVNode)("span",{class:"text-secondary text-xs"},"°",-1)),(0,e.createElementVNode)("button",{type:"button",class:"text-[11px] px-1.5 py-0.5 border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",onClick:o[13]||(o[13]=e=>E.value=0)}," 0 "),(0,e.createElementVNode)("button",{type:"button",class:"text-[11px] px-1.5 py-0.5 border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",onClick:o[14]||(o[14]=e=>E.value=90)}," 90 "),(0,e.createElementVNode)("button",{type:"button",class:"text-[11px] px-1.5 py-0.5 border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",onClick:o[15]||(o[15]=e=>E.value=180)}," 180 "),(0,e.createElementVNode)("button",{type:"button",class:"text-[11px] px-1.5 py-0.5 border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",onClick:o[16]||(o[16]=e=>E.value=270)}," 270 ")]),(0,e.createElementVNode)("div",De,[(0,e.withDirectives)((0,e.createElementVNode)("textarea",{"onUpdate:modelValue":o[17]||(o[17]=e=>V.value=e),rows:"5",placeholder:"data:image/png;base64,...",class:"flex-1 h-16 min-h-0 max-h-24 w-full box-border px-2 py-1.5 text-xs leading-[1.5] border-surface rounded-lg resize-y font-[inherit] bg-input text-primary select-text transition-shadow sc-field"},null,512),[[e.vModelText,V.value]]),(0,e.createElementVNode)("div",{class:"flex flex-col gap-1.5 shrink-0"},[(0,e.createElementVNode)("button",{type:"button",class:"w-8 h-8 shrink-0 text-base leading-none border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",title:"添加到图标列表",onClick:_}," + "),(0,e.createElementVNode)("button",{type:"button",class:"w-8 h-8 shrink-0 text-sm leading-none border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",title:"上传图片并转 base64",onClick:I}," 🖼 ")]),(0,e.createElementVNode)("input",{ref_key:"fileInputRef",ref:D,type:"file",accept:"image/*",style:{display:"none"},onChange:A},null,544)]),(0,e.unref)(N).length?((0,e.openBlock)(),(0,e.createElementBlock)("div",Ie,[(0,e.createElementVNode)("div",{ref_key:"listRef",ref:T,class:"flex flex-wrap gap-1 p-1",style:(0,e.normalizeStyle)({maxHeight:M.value?"none":"36px",overflow:"hidden"})},[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)((0,e.unref)(N),t=>((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:t,class:"relative"},[(0,e.createElementVNode)("img",{src:t,class:"w-8 h-8 p-1 object-contain rounded-lg bg-input cursor-pointer block border-surface transition-transform hover:scale-110",style:(0,e.normalizeStyle)(t===B.value?{borderColor:"var(--color-save-border)"}:void 0),title:t.slice(0,60),onClick:e=>function(e){B.value=e,a("icon-change",e)}(t)},null,12,Ae),t!==(0,e.unref)(s)?((0,e.openBlock)(),(0,e.createElementBlock)("button",{key:0,type:"button",class:"absolute -top-1 -right-1 w-[13px] h-[13px] leading-none text-[10px] p-0 border-none rounded-full bg-black/60 text-white cursor-pointer flex items-center justify-center",title:"从列表移除",onClick:(0,e.withModifiers)(e=>function(e){e!==s&&(S.value="",N.value=N.value.filter(t=>t!==e),B.value===e&&(B.value=N.value[0],a("icon-change",B.value)))}(t),["stop"])}," × ",8,Re)):(0,e.createCommentVNode)("v-if",!0)]))),128))],4),M.value||z.value?((0,e.openBlock)(),(0,e.createElementBlock)("button",{key:0,type:"button",class:"mt-1.5 text-[11px] px-2 py-0.5 border-surface rounded-md bg-subtle-btn text-secondary cursor-pointer",onClick:o[18]||(o[18]=e=>M.value=!M.value)},(0,e.toDisplayString)(M.value?"收起":"展开全部("+(0,e.unref)(N).length+")"),1)):(0,e.createCommentVNode)("v-if",!0)])):(0,e.createCommentVNode)("v-if",!0),S.value?((0,e.openBlock)(),(0,e.createElementBlock)("div",Ge,(0,e.toDisplayString)(S.value),1)):(0,e.createCommentVNode)("v-if",!0)]),(0,e.createElementVNode)("fieldset",je,[o[36]||(o[36]=(0,e.createElementVNode)("legend",{class:"text-[11px] px-2 py-0.5 rounded-full bg-chip text-accent font-medium"}," 在以下站点禁用 ",-1)),(0,e.createCommentVNode)(" 站点(禁用返回按钮) "),(0,e.createElementVNode)("div",{class:"flex justify-between items-baseline p-0 pb-[5px]"},[(0,e.createElementVNode)("button",{type:"button",class:"!mt-0 !pt-0 text-xs px-2.5 pb-[3px] border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",onClick:P}," 添加当前网站 ")]),(0,e.withDirectives)((0,e.createElementVNode)("textarea",{"onUpdate:modelValue":o[19]||(o[19]=t=>(0,e.isRef)(G)?G.value=t:null),rows:"3",placeholder:"例如:baidu.com",class:"w-full box-border px-2 py-1.5 text-xs leading-[1.5] border-surface rounded-lg resize-y font-[inherit] bg-input text-primary select-text transition-shadow sc-field"},null,512),[[e.vModelText,(0,e.unref)(G)]])])]),menu:(0,e.withCtx)(()=>[(0,e.createElementVNode)("fieldset",Pe,[o[39]||(o[39]=(0,e.createElementVNode)("legend",{class:"text-[11px] px-2 py-0.5 rounded-full bg-chip text-accent font-medium"}," 快捷菜单设置 ",-1)),(0,e.createElementVNode)("label",Ue,[(0,e.withDirectives)((0,e.createElementVNode)("input",{"onUpdate:modelValue":o[20]||(o[20]=t=>(0,e.isRef)(y)?y.value=t:null),type:"checkbox",class:"accent-accent"},null,512),[[e.vModelCheckbox,(0,e.unref)(y)]]),o[37]||(o[37]=(0,e.createTextVNode)(" 启用快捷功能 ",-1))]),(0,e.createCommentVNode)(" 说清这个开关**管不到**什么:否则用户关了它却仍看到划词弹菜单,会当成 bug "),o[40]||(o[40]=(0,e.createElementVNode)("p",{class:"mb-2 -mt-1 px-2 -mx-2 text-[11px] text-secondary leading-snug"}," 只控制「悬停 / 双击」展开。插件主动弹出的菜单(如选中文字后的快捷翻译)不受此开关限制, 想彻底关闭 → 解绑下方「快捷菜单槽位绑定」里的插件 ↓ 或禁用该插件 ",-1)),(0,e.createElementVNode)("label",$e,[(0,e.withDirectives)((0,e.createElementVNode)("input",{"onUpdate:modelValue":o[21]||(o[21]=t=>(0,e.isRef)(v)?v.value=t:null),type:"number",min:"2",max:"8",step:"1",class:"w-12 px-1.5 py-1 text-xs border-surface rounded-lg bg-input text-primary transition-shadow sc-field"},null,512),[[e.vModelText,(0,e.unref)(v)]]),o[38]||(o[38]=(0,e.createTextVNode)(" 设置快捷菜单数量 ",-1))])]),(0,e.createElementVNode)("fieldset",Fe,[o[42]||(o[42]=(0,e.createElementVNode)("legend",{class:"text-[11px] px-2 py-0.5 rounded-full bg-chip text-accent font-medium"}," 快捷菜单槽位绑定(保存后生效) ",-1)),((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(Z.value,t=>((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:t,class:"flex items-center gap-1.5 mb-1 text-xs"},[(0,e.createElementVNode)("span",He,"槽位 "+(0,e.toDisplayString)(t),1),(0,e.withDirectives)((0,e.createElementVNode)("select",{"onUpdate:modelValue":e=>q.value[t-1]=e,class:"flex-1 px-1.5 py-1 text-xs border-surface rounded-lg bg-input text-primary select-text transition-shadow sc-field"},[o[41]||(o[41]=(0,e.createElementVNode)("option",{value:""},"(空)",-1)),((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(Nt(t-1),t=>((0,e.openBlock)(),(0,e.createElementBlock)("option",{key:t.manifest.id,value:t.manifest.id},(0,e.toDisplayString)(t.manifest.name),9,Oe))),128))],8,qe),[[e.vModelSelect,q.value[t-1]]])]))),128))])]),plugin:(0,e.withCtx)(()=>[(0,e.createElementVNode)("div",Ye,[(0,e.createElementVNode)("button",{type:"button",class:"mt-1.5 text-xs px-2.5 py-[3px] border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",onClick:ee}," 从文件导入 "),(0,e.createElementVNode)("input",{ref_key:"pluginFileInputRef",ref:X,type:"file",accept:".js,.txt",style:{display:"none"},onChange:le},null,544),(0,e.createElementVNode)("button",{type:"button",class:"mt-1.5 text-xs px-2.5 py-[3px] border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",onClick:Ct}," 立即安装 ")]),(0,e.withDirectives)((0,e.createElementVNode)("textarea",{"onUpdate:modelValue":o[22]||(o[22]=e=>W.value=e),rows:"4",placeholder:"粘贴插件代码(含 ==Plugin== 头),或点击上方导入文件后点「立即安装」...",class:"w-full box-border px-2 py-1.5 text-xs leading-[1.5] border-surface rounded-lg resize-y font-[inherit] bg-input text-primary select-text transition-shadow sc-field"},null,512),[[e.vModelText,W.value]]),O.value?((0,e.openBlock)(),(0,e.createElementBlock)("span",{key:0,class:"block mt-1 text-[11px]",style:(0,e.normalizeStyle)({color:Y.value?"var(--color-save-border)":"var(--color-danger)"})},(0,e.toDisplayString)(O.value),5)):(0,e.createCommentVNode)("v-if",!0),H.value.length?((0,e.openBlock)(),(0,e.createElementBlock)("div",We,[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(H.value,t=>{return(0,e.openBlock)(),(0,e.createElementBlock)("div",{key:t.manifest.id,class:"mb-0.5 text-xs"},[(0,e.createElementVNode)("div",{class:"flex items-center gap-1.5 cursor-pointer py-1 rounded-lg px-1 -mx-1 transition-colors hover:bg-white/10",onClick:e=>{return n=t.manifest.id,void(J.value=J.value===n?null:n);var n}},[(0,e.createElementVNode)("span",Je,(0,e.toDisplayString)(J.value===t.manifest.id?"▾":"▸"),1),t.manifest.icon?((0,e.openBlock)(),(0,e.createElementBlock)("img",{key:0,src:t.manifest.icon,class:"w-4 h-4 object-contain"},null,8,Ke)):((0,e.openBlock)(),(0,e.createElementBlock)("span",Ze,(0,e.toDisplayString)((t.manifest.name||"?").charAt(0)),1)),(0,e.createElementVNode)("span",{class:"flex-1",style:(0,e.normalizeStyle)({textDecoration:St(t.manifest.id)?"line-through":"none",opacity:St(t.manifest.id)?.5:1})},[(0,e.createTextVNode)((0,e.toDisplayString)(t.manifest.name)+" ",1),(0,e.createElementVNode)("span",Qe,"v"+(0,e.toDisplayString)(t.manifest.version),1),t.manifest.builtin?((0,e.openBlock)(),(0,e.createElementBlock)("span",et,"内置")):(0,e.createCommentVNode)("v-if",!0)],4)],8,Xe),J.value===t.manifest.id?((0,e.openBlock)(),(0,e.createElementBlock)("div",tt,[(0,e.createElementVNode)("div",null,[o[43]||(o[43]=(0,e.createTextVNode)(" 类型:",-1)),(0,e.createElementVNode)("b",null,(0,e.toDisplayString)((n=t.manifest.type,"feature"===n?"后台运行":"shortcut"===n?"快捷功能":n)),1),t.manifest.permissions&&t.manifest.permissions.length?((0,e.openBlock)(),(0,e.createElementBlock)("span",nt," · 权限:"+(0,e.toDisplayString)((t.manifest.permissions||[]).join(", ")),1)):(0,e.createCommentVNode)("v-if",!0)]),t.manifest.description?((0,e.openBlock)(),(0,e.createElementBlock)("div",ot,(0,e.toDisplayString)(t.manifest.description),1)):(0,e.createCommentVNode)("v-if",!0),St(t.manifest.id)?((0,e.openBlock)(),(0,e.createElementBlock)("div",rt," ⚠ 卸载将清空该插件的所有数据(设置等) ")):(0,e.createCommentVNode)("v-if",!0),(0,e.createElementVNode)("div",at,[(0,e.createElementVNode)("label",it,[(0,e.createElementVNode)("input",{type:"checkbox",checked:Vt(t.manifest.id),onChange:e=>{return n=t.manifest.id,void F.setEnabled(n,!F.isEnabled(n));var n}},null,40,st),o[44]||(o[44]=(0,e.createTextVNode)(" 启用 ",-1))]),t.manifest.builtin?((0,e.openBlock)(),(0,e.createElementBlock)("span",ct,"内置")):((0,e.openBlock)(),(0,e.createElementBlock)("button",{key:0,type:"button",class:"mt-1.5 text-xs px-2.5 py-[3px] border-surface rounded-md bg-subtle-btn cursor-pointer",style:(0,e.normalizeStyle)({color:St(t.manifest.id)?"var(--color-danger)":"var(--color-primary)"}),onClick:(0,e.withModifiers)(e=>function(e){const t=new Set(K.value);t.has(e)?t.delete(e):t.add(e),K.value=t}(t.manifest.id),["stop"])},(0,e.toDisplayString)(St(t.manifest.id)?"取消卸载":"卸载"),13,lt))]),(0,e.createCommentVNode)(" 插件设置表单:与上面的「类型/描述/启用」同为整行内容,**不缩进**。 "),de(t.manifest.id).length?((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,{key:2},(0,e.renderList)(de(t.manifest.id),n=>((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:n.key,class:"mt-1.5"},[(0,e.createElementVNode)("div",ut,(0,e.toDisplayString)(n.label),1),"text"===n.type||"password"===n.type?((0,e.openBlock)(),(0,e.createElementBlock)("input",{key:0,type:n.type,value:xt(t.manifest.id,n),placeholder:n.placeholder||"",class:"w-full box-border px-2 py-1.5 text-xs leading-[1.5] border-surface rounded-lg resize-y font-[inherit] bg-input text-primary select-text transition-shadow sc-field",onInput:e=>wt(t.manifest.id,n.key,e.target.value),onChange:e=>kt(t.manifest.id,n.key,e.target.value)},null,40,dt)):"textarea"===n.type?((0,e.openBlock)(),(0,e.createElementBlock)("textarea",{key:1,value:String(xt(t.manifest.id,n)??""),placeholder:n.placeholder||"",rows:"4",class:"w-full box-border px-2 py-1.5 text-xs leading-[1.5] border-surface rounded-lg resize-y font-[inherit] bg-input text-primary select-text transition-shadow sc-field",onInput:e=>wt(t.manifest.id,n.key,e.target.value),onChange:e=>kt(t.manifest.id,n.key,e.target.value)},null,40,pt)):"select"===n.type?((0,e.openBlock)(),(0,e.createElementBlock)("select",{key:2,value:xt(t.manifest.id,n),class:"flex-1 px-1.5 py-1 text-xs border-surface rounded-lg bg-input text-primary select-text transition-shadow sc-field",onChange:e=>kt(t.manifest.id,n.key,e.target.value)},[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(n.options||[],t=>((0,e.openBlock)(),(0,e.createElementBlock)("option",{key:t.value,value:t.value},(0,e.toDisplayString)(t.label),9,ht))),128))],40,mt)):"checkbox"===n.type?((0,e.openBlock)(),(0,e.createElementBlock)("label",gt,[(0,e.createElementVNode)("input",{type:"checkbox",checked:!!xt(t.manifest.id,n),onChange:e=>kt(t.manifest.id,n.key,e.target.checked)},null,40,ft),o[45]||(o[45]=(0,e.createTextVNode)(" 启用 ",-1))])):(0,e.createCommentVNode)("v-if",!0)]))),128)):(0,e.createCommentVNode)("v-if",!0)])):(0,e.createCommentVNode)("v-if",!0)]);var n}),128))])):((0,e.openBlock)(),(0,e.createElementBlock)("div",bt,"暂无插件,点击上方导入"))]),_:1},8,["modelValue"])]),(0,e.createCommentVNode)(" 底部固定操作栏 "),(0,e.createElementVNode)("div",vt,[(0,e.createElementVNode)("button",{type:"button",class:"text-xs px-3 py-1.5 border-surface rounded-lg text-secondary cursor-pointer transition-colors hover:bg-white/10 hover:text-primary",onClick:o[24]||(o[24]=e=>t.$emit("close"))}," 取消 "),(0,e.createElementVNode)("button",{type:"button",class:"text-xs px-4 py-1.5 border border-save-border rounded-lg bg-save-btn text-white font-medium cursor-pointer shadow-sm transition hover:opacity-90 active:scale-[0.97]",onClick:Bt}," 保存 ")])]),_:1},8,["style"]))}}),xt=["title","onClick"],wt={key:0,class:"text-xl font-bold leading-none pointer-events-none"},kt=["src"],Et=(0,e.defineComponent)({__name:"QuickMenu",props:{show:{type:Boolean},bindings:{},slotCount:{},btnSize:{},anchorY:{},enterDelay:{}},emits:["close","slot","empty","hoverIn","hoverOut"],setup(t,{emit:n}){const o=t,r=n,a=(0,e.computed)(()=>o.bindings.filter(Boolean).length),i=(0,e.computed)(()=>{const e=[];let t=0;for(let n=0;n42*i.value.length-6+16),l=(0,e.computed)(()=>o.anchorY({top:l.value?"auto":o.btnSize+20+"px",bottom:l.value?o.btnSize+20+"px":"auto",transform:"translateX(-50%)",borderColor:"var(--sc-surface-border)",zIndex:re}));function u(e,t){return`translateX(-50%) translateY(${e}px) scale(${t})`}function d(e,t,n,o,r,a=0){const i=e;i.getAnimations().forEach(e=>e.cancel());const s=i.animate(t,{duration:n,easing:o,delay:a,fill:"backwards"});s.onfinish=()=>r(),s.oncancel=()=>r()}let p=0;function m(e,t){const n=l.value?12:-12,r=o.enterDelay??0;p=r>0?performance.now()+r:0,d(e,[{opacity:0,transform:u(n,.86),filter:"blur(6px)"},{opacity:1,transform:u(0,1),filter:"blur(0px)"}],220,"cubic-bezier(0.2, 0.9, 0.25, 1)",t,r)}function h(e,t){if(p>0&&performance.now()e.cancel()),void t();p=0;const n=l.value?8:-8;d(e,[{opacity:1,transform:u(0,1),filter:"blur(0px)"},{opacity:0,transform:u(n,.9),filter:"blur(5px)"}],150,"ease-in",t)}return(n,o)=>((0,e.openBlock)(),(0,e.createElementBlock)(e.Fragment,null,[(0,e.createCommentVNode)(" 竖条快捷菜单:容器内 absolute 定位,内部 flex 纵向排列(浏览器自动对齐) "),(0,e.createVNode)(e.Transition,{css:!1,onEnter:m,onLeave:h},{default:(0,e.withCtx)(()=>[t.show?((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:0,style:(0,e.normalizeStyle)(c.value),class:"absolute left-1/2 flex flex-col items-center gap-1.5 p-1.5 rounded-full bg-panel border backdrop-blur-[10px] backdrop-saturate-150 shadow-panel",onMouseenter:o[1]||(o[1]=e=>r("hoverIn")),onMouseleave:o[2]||(o[2]=e=>r("hoverOut"))},[(0,e.createCommentVNode)("\n ⚠️ 每个槽位都 `@mousedown.prevent`:mousedown 的默认行为会 collapse 页面选区,\n 于是「划词 → 点图标」这条链路会在按下的一瞬间丢掉刚选中的文字(更糟的是选区一空,\n 宿主就把插件自动打开的菜单收起,click 可能根本落不到槽位上)。\n 阻止默认行为后选区原样保留,点击与「实时选区」都稳。\n "),((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(i.value,(t,n)=>((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:n,class:(0,e.normalizeClass)(["w-9 h-9 flex items-center justify-center rounded-[10px] cursor-pointer select-none",t.isAdd?"text-menu-plus":"text-primary"]),title:t.isAdd?"点击绑定快捷功能":"",onClick:e=>function(e){r("close"),e{},["prevent"]))},[t.isAdd?((0,e.openBlock)(),(0,e.createElementBlock)("span",wt,"+")):((0,e.openBlock)(),(0,e.createElementBlock)("img",{key:1,src:t.icon,class:"w-5 h-5 object-contain pointer-events-none"},null,8,kt))],42,xt))),128))],36)):(0,e.createCommentVNode)("v-if",!0)]),_:1})],2112))}}),Vt={class:"flex items-center gap-2 mb-2.5"},Ct=["src"],St={class:"text-[13px]"},Nt=(0,e.defineComponent)({__name:"PluginPanelHost",props:{req:{},anchor:{},btnSize:{}},emits:["close","plugin-event"],setup(t,{emit:o}){const r=t,a=o,i=(0,e.computed)(()=>{const e=r.req.spec;return e&&"panel"===e.type&&e.title||"插件"}),s=te(),l=(0,e.computed)(()=>s.getPluginIcon(r.req.pluginId)),c=(0,e.computed)(()=>{const e=r.req.spec;return e&&"panel"===e.type&&e.body||[]}),u=(0,e.ref)(null),d=(0,e.ref)(0);let p=null;(0,e.onMounted)(()=>{const e=u.value?.$el;e&&(d.value=e.offsetHeight,p=new ResizeObserver(()=>{d.value=e.offsetHeight}),p.observe(e))}),(0,e.onBeforeUnmount)(()=>p?.disconnect());const m=(0,e.computed)(()=>{const e=r.btnSize??46,t=r.anchor?.x??20,n=r.anchor?.y??20,o=Math.max(0,window.innerHeight-d.value-12);return{position:"fixed",right:t+e+20+"px",bottom:Math.min(n,o)+"px",width:"300px",maxWidth:"80vw",maxHeight:"min(560px, calc(100vh - 24px))",overflowY:"auto",zIndex:re,boxSizing:"border-box"}}),h=(e,t)=>{e&&a("plugin-event",r.req.pluginId,e,t)};function g(e,t){return _(e,h)}return(o,r)=>t.req&&t.req.spec?((0,e.openBlock)(),(0,e.createBlock)((0,e.unref)(n),{key:0,ref_key:"panelRef",ref:u,variant:"glass",style:(0,e.normalizeStyle)(m.value)},{default:(0,e.withCtx)(()=>[(0,e.createElementVNode)("div",Vt,[(0,e.createCommentVNode)(" 插件图标:与快捷菜单槽位同源(manifest.icon,无图标则首字占位)。\n 面板是插件的门面,只有名字没有图标会让「这是谁弹的」少一条线索。 "),l.value?((0,e.openBlock)(),(0,e.createElementBlock)("img",{key:0,src:l.value,class:"w-4 h-4 object-contain shrink-0",alt:""},null,8,Ct)):(0,e.createCommentVNode)("v-if",!0),(0,e.createElementVNode)("strong",St,(0,e.toDisplayString)(i.value),1),(0,e.createElementVNode)("button",{type:"button",class:"ml-auto border-none bg-transparent text-base cursor-pointer text-secondary leading-none",onClick:r[0]||(r[0]=e=>o.$emit("close"))}," × ")]),((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(c.value,(t,n)=>((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:n,class:"mb-1.5"},[((0,e.openBlock)(),(0,e.createBlock)((0,e.resolveDynamicComponent)(g(t))))]))),128))]),_:1},8,["style"])):(0,e.createCommentVNode)("v-if",!0)}}),Bt=["src"],Mt="rocket-btn-pos",zt=(0,e.defineComponent)({__name:"BackToTop",emits:["config-saved"],setup(n,{emit:o}){const r=(0,e.ref)(!1),a=(0,e.ref)(!1),i=(0,e.ref)(!1),s=(0,e.ref)(!1),l=(0,e.ref)(GM_info.script.name),c=ae("general.alwaysShow",!1,ie(!1)),u=ae("general.noBtnBg",!1,ie(!1)),d=ae("general.customIcon","",de()),p=(0,e.ref)(d.value);(0,e.watch)(d,e=>{p.value=e});const m=ae("general.iconScale",1,le()),h=(0,e.ref)(m.value),g=(0,e.ref)(null),b=(0,e.ref)(null);function v(e){h.value=Math.min(4,Math.max(.6,e||1))}function y(e){tt.value=e}function x(e){g.value=e}function w(e){z.value=e}function k(e){b.value=e}(0,e.watch)(m,e=>{h.value=e});const E=ae("general.menuSlots",4,ue()),V=ae("general.githubAccel",!0,ie(!0)),C=ae("general.btnAnim","none",se("none")),S=ae("general.btnOpacity",1,ce()),N=ae("general.btnRotate",0,e=>{const t=parseFloat(String(e??0));return isNaN(t)?0:Math.min(360,Math.max(0,Math.round(t)))}),B=(0,e.ref)(N.value),M=ae("general.btnMirror",!1,ie(!1)),z=(0,e.ref)(null),T=(0,e.computed)(()=>z.value??M.value),L=(0,e.computed)(()=>`rotate(${B.value}deg) scaleX(${T.value?-1:1})`);function _(e){B.value=e}(0,e.watch)(N,e=>{B.value=e});const D=(0,e.ref)(0),I=(0,e.computed)(()=>{D.value;const e=[];for(let t=0;t26*h.value),G=(0,e.computed)(()=>g.value??C.value),j=(0,e.computed)(()=>"none"===G.value||"ripple"===G.value?"":`sc-anim-${G.value}`),P=(0,e.computed)(()=>"ripple"===G.value&&!(b.value??u.value)),U=(0,e.computed)(()=>({width:R.value+"px",height:R.value+"px",objectFit:"cover",pointerEvents:"none"})),$=o;function F(e){p.value=oe(e)}function H(e){c.value=ie(!1)(GM_getValue("general.alwaysShow",!1)),u.value=ie(!1)(GM_getValue("general.noBtnBg",!1)),m.value=le()(GM_getValue("general.iconScale",1)),h.value=m.value,Pe.value=ie(!1)(GM_getValue("general.quickMenu",!1)),E.value=ue()(GM_getValue("general.menuSlots",4)),S.value=ce()(GM_getValue("general.btnOpacity",1)),tt.value=null,g.value=null,b.value=null,z.value=null,z.value=null,d.value=de()(GM_getValue("general.customIcon","")),p.value=oe(e),N.value=(()=>{const e=parseFloat(String(GM_getValue("general.btnRotate",0)));return isNaN(e)?0:Math.min(360,Math.max(0,Math.round(e)))})(),B.value=N.value,kt(),Ce(),D.value++,$("config-saved")}function q(e){Be(e.text,{title:"💡 还差一步",type:"info",timeout:8e3,note:e.note})}let O=null,Y=document.documentElement,X=0;const J=[],K=function(){try{const e=GM_getValue(Mt,"");return e?JSON.parse(String(e)):null}catch{return null}}(),Z=(0,e.reactive)({x:K?.x??20,y:K?.y??20,fromRight:!K,fromBottom:!K});let Q=0,ee=0,ne=!1;function pe(){try{GM_setValue(Mt,JSON.stringify({x:Z.x,y:Z.y}))}catch{}}function he(e){0===e.button&&(ne=!1,Q=e.clientX,ee=e.clientY,i.value=!1,O=e.timeStamp,document.addEventListener("mousemove",fe),document.addEventListener("mouseup",ye))}function ge(e){if(1!==e.touches.length)return;const t=e.touches[0];ne=!1,Q=t.clientX,ee=t.clientY,i.value=!1,O=e.timeStamp,document.addEventListener("touchmove",be,{passive:!1}),document.addEventListener("touchend",xe)}function fe(e){ve(e.clientX,e.clientY)}function be(e){1===e.touches.length&&(e.preventDefault(),ve(e.touches[0].clientX,e.touches[0].clientY))}function ve(e,t){const n=e-Q,o=t-ee;if((Math.abs(n)>3||Math.abs(o)>3)&&(ne||(ne=!0,a.value&&(a.value=!1))),!ne)return;s.value=!0;const r=window.innerHeight,i=r-t-23;Z.y=Math.max(0,Math.min(r-46,i)),Z.fromBottom=!0}function ye(e){if(document.removeEventListener("mousemove",fe),document.removeEventListener("mouseup",ye),s.value=!1,ne)return pe(),void(O=null);we(e)}function xe(){document.removeEventListener("touchmove",be),document.removeEventListener("touchend",xe),s.value=!1,ne&&pe()}function we(e){if(null===O||ne)return void(O=null);const t=e.timeStamp-O;O=null,t<600||(i.value=!0,Ue.value=!1,Se.value=null,Fe.value="general",a.value=!0)}function ke(e){we(e),xe()}function Ee(){O=null}const Ve=te();function Ce(){Ve.setEnabled("com.flowsaro.github-accel",V.value)}Ce(),(0,e.watch)(V,Ce),Ve.preheatFeatures();const Se=(0,e.ref)(null);Ve.onPanelRender(e=>{"close"===e.kind?Se.value=null:"panel"===e.kind&&(a.value=!1,Se.value={kind:e.kind,spec:e.spec,pluginId:e.pluginId})}),Ve.onMenuRequest(e=>Ze(!0,"auto",e)),Ve.on("menuCloseRequest",()=>{"auto"===$e.value&&(Ue.value=!1)}),Ve.onChanged(()=>D.value++);const{toasts:Ne,push:Be,update:Me,close:ze,clearPlugin:Te}=function(t={}){const n=t.max??30,o=t.minTimeout??1e3,r=(0,e.ref)([]);let a=0;const i=new Map;function s(e){return 0===e?0:Math.max(o,e)}function l(e){const t=i.get(e);void 0!==t&&(clearTimeout(t),i.delete(e))}function c(e){e.timeout<=0||i.set(e.id,setTimeout(()=>u(e.id),e.timeout))}function u(e,t){l(e);const n=r.value.find(t=>t.id===e);if(r.value=r.value.filter(t=>t.id!==e),t?.user&&n?.onClose)try{n.onClose()}catch(e){console.warn("[toast] onClose 回调抛错:",e)}}return{toasts:r,push:function(e,t){const o={id:++a,text:e,title:t?.title,type:t?.type||"info",timeout:s(t?.timeout??2500),copyable:!!t?.copyable,icon:t?.icon,broadcastId:t?.broadcastId,pluginId:t?.pluginId,severity:"high"===t?.severity?"high":"low",busy:!!t?.busy,note:t?.note,onClose:t?.onClose};for(t?.reverse?r.value.push(o):r.value.unshift(o);r.value.length>n;){const e=[...r.value].sort((e,t)=>e.id-t.id);u((e.find(e=>"high"!==e.severity)??e[0]).id)}return c(o),o.id},update:function(e,t){const n=r.value.find(t=>t.id===e);if(!n)return!1;if(void 0!==t.text&&(n.text=t.text),void 0!==t.title&&(n.title=t.title),void 0!==t.type&&(n.type=t.type),void 0!==t.icon&&(n.icon=t.icon),void 0!==t.note&&(n.note=t.note),void 0!==t.severity&&(n.severity="high"===t.severity?"high":"low"),void 0!==t.busy&&(n.busy=t.busy),void 0!==t.copyable&&(n.copyable=t.copyable),void 0!==t.timeout){const o=s(t.timeout);o!==n.timeout&&(n.timeout=o,l(e),c(n))}return!0},close:u,clearPlugin:function(e){const t=t=>t.pluginId===e&&"high"!==t.severity;r.value.filter(t).forEach(e=>l(e.id)),r.value=r.value.filter(e=>!t(e))}}}();Ve.onToast((e,t)=>Be(e,t)),Ve.onToastUpdate((e,t)=>Me(e,t)),Ve.onToastDismissed(e=>{Ne.value.filter(t=>t.broadcastId===e).forEach(e=>ze(e.id))}),Ve.syncBroadcasts();let Le=null;function _e(){"visible"===document.visibilityState&&Ve.syncBroadcasts()}function De(e){try{navigator.clipboard.writeText(e.text)}catch{}}function Ie(e){const t=Ne.value.find(t=>t.id===e);void 0!==t?.broadcastId&&Ve.dismissBroadcast(t.broadcastId),ze(e,{user:!0})}function Ae(e){Te(e),Ve.clearBroadcasts(e)}function Re(e){Ve.activateSlot(e)}function Ge(e){Ue.value=!1,Fe.value="menu",a.value=!0,Se.value=null}function je(e,t,n){Ve.getRuntime(e)?.emitEvent(t,n)}document.addEventListener("visibilitychange",_e),window.addEventListener("focus",_e),window.addEventListener("pageshow",_e),function e(){const t=Ne.value.some(e=>void 0!==e.broadcastId);Le=setTimeout(()=>{_e(),e()},t?2e3:8e3)}(),Ve.onDismissToast(e=>ze(e)),Ve.onPluginUninstalled(e=>{Se.value?.pluginId===e&&(Se.value=null)});const Pe=ae("general.quickMenu",!1,ie(!1)),Ue=(0,e.ref)(!1),$e=(0,e.ref)(null);(0,e.watch)(Ue,e=>{e||($e.value=null)});const Fe=(0,e.ref)("general");let He=null;const qe=(0,e.ref)(0);let Oe=0;const Ye=(0,e.computed)(()=>({position:"fixed",right:Z.x+"px",bottom:Z.y+"px",width:"46px",height:"46px",zIndex:re})),We=(0,e.computed)(()=>window.innerHeight-Z.y<200),Xe=(0,e.computed)(()=>{const e=window.innerHeight,t=e-Z.y;return{position:"fixed",right:Z.x+A+20+"px",...We.value?{top:t+20+"px"}:{bottom:e-t+"px"},zIndex:2147483647}});function Je(){for(let e=0;e0?performance.now()+i:0,Ue.value=!0,r&&"manual"!==t||($e.value=t);const s={ok:!0};return n&&(s.inMenu=Ke(n)),s}const Qe=window.matchMedia("(hover: hover)").matches,et=(0,e.ref)(!1),tt=(0,e.ref)(null),nt=(0,e.computed)(()=>{if(!Qe)return 1;const e=tt.value??S.value;if(a.value)return e;return et.value||s.value||Ue.value||Ne.value.length>0?1:e});let ot=null;function rt(){et.value=!0,Qe&&!s.value&&Pe.value&&(clearTimeout(ot),a.value||Ze(!0,"manual",void 0,{enterDelay:200}))}function at(){if(et.value=!1,Qe){if(clearTimeout(ot),Oe>0&&performance.now(){"manual"===$e.value&&(Ue.value=!1)},500)}}function it(){clearTimeout(ot)}function st(){at()}function lt(){if(!ne)return i.value?(i.value=!1,void(He&&(clearTimeout(He),He=null))):void(He?(clearTimeout(He),He=null,Ze()):He=setTimeout(()=>{He=null,function(){const e=document.scrollingElement;Y===document.documentElement||Y===e||Y===document.body?window.scrollTo({top:0,behavior:"smooth"}):(Y.scrollTo({top:0,behavior:"smooth"}),window.scrollY>0&&window.scrollTo({top:0,behavior:"smooth"}))}()},250))}function ct(e){try{return e.scrollHeight>e.clientHeight}catch{return!1}}function ut(){if(document.scrollingElement&&ct(document.scrollingElement))return document.scrollingElement;let e=null,t=0,n=0;const o=(r,a)=>{if(!(a>3||n>=60)){n++;try{const n=getComputedStyle(r);("auto"===n.overflowY||"scroll"===n.overflowY)&&ct(r)&&r.scrollHeight>t&&(e=r,t=r.scrollHeight)}catch{}for(const e of Array.from(r.children))o(e,a+1)}};if(o(document.body,0),e)return e;const r=[document.body,...Array.from(document.body.children)];for(const e of r)if(e&&e.scrollTop>0)return e;return document.documentElement}function dt(){const e=document.scrollingElement,t=window.scrollY||(e?e.scrollTop:0)||document.body.scrollTop||0;if(Y===document.documentElement||Y===e||Y===document.body)return t;const n=Y.scrollTop||0;return Math.max(t,n)}let pt=-1/0,mt=!1;function ht(){const e=performance.now();return e-pt>=500&&(mt=function(){const e=document.scrollingElement;return!!e&&e.scrollHeight>e.clientHeight}(),pt=e),mt}let gt=!1,ft=!1;function bt(){gt||(gt=!0,requestAnimationFrame(()=>{gt=!1,ft||vt()}))}function vt(){const e=dt();e>X?r.value=!1:e200),X=e}function xt(e){const t=e.target;if(t===document||t===document.documentElement||t===document.body)return pt=-1/0,void bt();t!==Y?ht()||(ct(t)||t.scrollTop>0)&&(t!==Y&&(Y.removeEventListener("scroll",xt),Y=t,Y.addEventListener("scroll",xt,{passive:!0}),X=dt()),bt()):bt()}const wt=(0,e.reactive)({position:"absolute",left:"0",top:"0",width:"100%",height:"100%",zIndex:1,opacity:"0",visibility:"hidden",transform:"translateY(8px)",transition:"opacity .25s ease, visibility .25s ease, transform .25s ease",background:u.value?"transparent":"var(--color-btn)",backdropFilter:u.value?"none":"blur(10px) saturate(150%)",WebkitBackdropFilter:u.value?"none":"blur(10px) saturate(150%)"});function kt(){const e=b.value??u.value;wt.background=e?"transparent":"var(--color-btn)",wt.backdropFilter=e?"none":"blur(10px) saturate(150%)",wt.WebkitBackdropFilter=e?"none":"blur(10px) saturate(150%)"}function Vt(){dt()<=200&&(r.value=!1),p.value=d.value,B.value=N.value,h.value=m.value,tt.value=null,g.value=null,b.value=null,a.value=!1}(0,e.watch)([u,b],kt),(0,e.onMounted)(()=>{var e;!GM_getValue(me,!1)&&(GM_setValue(me,!0),1)&&Be("火箭按钮安装好了尽情玩耍吧~\n单击回顶部 · 长按打开设置 · 选中文字自动弹出快捷菜单 · 支持挂载插件",{title:"🎉 安装成功",type:"success",timeout:0}),e="app.menuSeeded",!GM_getValue(e,!1)&&(GM_setValue(e,!0),1)&&Ve.getBindings().every(e=>!e)&&Ve.setBinding(0,W),Y=ut(),Y.addEventListener("scroll",xt,{passive:!0}),document.addEventListener("scroll",xt,{passive:!0,capture:!0}),window.addEventListener("resize",vt,{passive:!0}),document.addEventListener("selectionchange",zt),vt(),setTimeout(()=>{const e=ut();e!==Y&&(Y.removeEventListener("scroll",xt),Y=e,Y.addEventListener("scroll",xt,{passive:!0}),X=dt(),vt())},2e3)});let Ct="";const St=(0,e.ref)(null);function zt(){if(function(){const e=window.getSelection()?.anchorNode;if(!e)return!1;const t=St.value?.getRootNode();return!!t&&t.contains(e)}())return;if(a.value)return;const e=window.getSelection()?.toString()||"";e!==Ct&&(Ct=e,e||"auto"!==$e.value||(Ue.value=!1),Ve.handleSelectionChange(e))}return(0,e.onUnmounted)(()=>{Y.removeEventListener("scroll",xt),document.removeEventListener("scroll",xt,{capture:!0}),window.removeEventListener("resize",vt),document.removeEventListener("selectionchange",zt),document.removeEventListener("visibilitychange",_e),window.removeEventListener("focus",_e),window.removeEventListener("pageshow",_e),null!==Le&&(clearTimeout(Le),Le=null),ft=!0,function(){for(const[e,t,n]of J)e.removeEventListener(t,n);J.length=0}(),Ve.disposeAll()}),(0,e.watch)([r,a,s,c,Ue,()=>Ne.value.length>0,nt],function(){c.value||r.value||a.value||s.value||Ue.value||Ne.value.length>0?(wt.opacity=String(nt.value),wt.visibility="visible",wt.transform="none"):(wt.opacity="0",wt.visibility="hidden",wt.transform="translateY(8px)")},{immediate:!0}),(n,o)=>((0,e.openBlock)(),(0,e.createElementBlock)(e.Fragment,null,[(0,e.createCommentVNode)(" user-select: none 防止选中脚本自身 UI 触发 selectionchange(套娃);编辑输入框单独恢复 "),(0,e.createElementVNode)("div",{ref_key:"uiRootEl",ref:St,style:{userSelect:"none",WebkitUserSelect:"none"}},[(0,e.createCommentVNode)(" 快捷菜单全屏遮罩:点击外部关闭。\n ⚠️ 插件自动打开的菜单(menuOpenSource === 'auto')**不挂遮罩**:遮罩的 @mousedown\n 关闭会连带吞掉那一次 mousedown,于是「划词弹出菜单后想接着拖选下一段」的第一下没反应。 "),Ue.value&&"auto"!==$e.value?((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:0,style:(0,e.normalizeStyle)({position:"fixed",inset:"0",zIndex:(0,e.unref)(2147483645)}),onMousedown:o[0]||(o[0]=e=>Ue.value=!1),onTouchstart:o[1]||(o[1]=e=>Ue.value=!1)},null,36)):(0,e.createCommentVNode)("v-if",!0),(0,e.createCommentVNode)(" 锚点容器:按钮 + 快捷菜单同容器(hover 容器,鼠标在按钮或菜单上都不消失) "),(0,e.createElementVNode)("div",{style:(0,e.normalizeStyle)(Ye.value),onMouseenter:rt,onMouseleave:o[3]||(o[3]=e=>at())},[(0,e.createVNode)((0,e.unref)(t),{dragging:s.value,transparent:(0,e.unref)(u),size:(0,e.unref)(A),round:"",style:(0,e.normalizeStyle)(wt),title:l.value+"(长按设置)",onMouseleave:Ee,onClick:lt,onMousedown:he,onTouchstart:ge,onTouchend:ke,onTouchcancel:xe},{default:(0,e.withCtx)(()=>[(0,e.createCommentVNode)(" 旋转应用到外层 wrapper(不动画冲突);动画类作用在 img 上 "),(0,e.createElementVNode)("div",{class:"flex items-center justify-center w-full h-full overflow-hidden rounded-full",style:(0,e.normalizeStyle)({transform:L.value})},[(0,e.createElementVNode)("img",{src:p.value,class:(0,e.normalizeClass)(j.value),style:(0,e.normalizeStyle)(U.value)},null,14,Bt)],4)]),_:1},8,["dragging","transparent","size","style","title"]),(0,e.createCommentVNode)("\n 涟漪特效:独立一层贴在按钮上、靠两个圆环错开扩散(见 theme.css 的 .sc-anim-ripple)。\n ⚠️ 必须在 Button **外面**:图标那层带 `overflow: hidden`,挂在里面的圆环扩不出去;\n z-index 也比按钮低(按钮是 1),波纹才是「从按钮边缘推出来」而不是盖在图标上。\n "),P.value?((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:0,class:"sc-anim-ripple",style:(0,e.normalizeStyle)({opacity:String(nt.value)}),"aria-hidden":"true"},null,4)):(0,e.createCommentVNode)("v-if",!0),(0,e.createCommentVNode)(" 菜单显隐交给组件自己:进出场动画在 QuickMenu 内部,元素要撑到动画结束才移除 "),(0,e.createVNode)(Et,{show:Ue.value,bindings:I.value,"slot-count":(0,e.unref)(E),"btn-size":(0,e.unref)(A),"anchor-y":Z.y,"enter-delay":qe.value,onClose:o[2]||(o[2]=e=>Ue.value=!1),onSlot:Re,onEmpty:Ge,onHoverIn:it,onHoverOut:st},null,8,["show","bindings","slot-count","btn-size","anchor-y","enter-delay"])],36),(0,e.createCommentVNode)(" Toast 独立定位(按钮上方,空间不足放下方) "),(0,e.createVNode)((0,e.unref)(f),{toasts:(0,e.unref)(Ne),style:(0,e.normalizeStyle)(Xe.value),align:We.value?"top":"bottom",onClose:Ie,onCopy:De,onClearPlugin:Ae},null,8,["toasts","style","align"]),a.value?((0,e.openBlock)(),(0,e.createBlock)(yt,{key:1,anchor:{x:Z.x,y:Z.y},"btn-size":(0,e.unref)(A),"initial-tab":Fe.value,onClose:Vt,onIconChange:F,onRotateChange:_,onScaleChange:v,onOpacityChange:y,onAnimChange:x,onBgChange:k,onMirrorChange:w,onSaved:H,onHint:q},null,8,["anchor","btn-size","initial-tab"])):(0,e.createCommentVNode)("v-if",!0),Se.value?((0,e.openBlock)(),(0,e.createBlock)(Nt,{key:2,req:Se.value,anchor:{x:Z.x,y:Z.y},"btn-size":(0,e.unref)(A),onClose:o[4]||(o[4]=e=>Se.value=null),onPluginEvent:je},null,8,["req","anchor","btn-size"])):(0,e.createCommentVNode)("v-if",!0)],512)],2112))}}),Tt=(0,e.defineComponent)({__name:"App",setup(t){let n=!1;function o(){if(n)return;const t=function(){const t=(0,e.getCurrentInstance)()?.vnode?.el;if(!t)return null;const n=t.getRootNode();return n instanceof ShadowRoot&&n.host instanceof HTMLElement?n.host:null}(),o=t?.shadowRoot;if(!o)return;const r=document.createElement("style");r.dataset.scTheme="1",r.textContent='/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n@layer properties;\n@layer base {\n *, ::after, ::before, ::backdrop, ::file-selector-button {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0 solid;\n }\n html, :host {\n line-height: 1.5;\n -webkit-text-size-adjust: 100%;\n tab-size: 4;\n font-family: var(--default-font-family, -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, \'Helvetica Neue\', \'Noto Sans\', Arial, sans-serif, \'Apple Color Emoji\', \'Segoe UI Emoji\', \'Segoe UI Symbol\', \'Noto Color Emoji\');\n font-feature-settings: var(--default-font-feature-settings, normal);\n font-variation-settings: var(--default-font-variation-settings, normal);\n -webkit-tap-highlight-color: transparent;\n }\n hr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n }\n abbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n }\n h1, h2, h3, h4, h5, h6 {\n font-size: inherit;\n font-weight: inherit;\n }\n a {\n color: inherit;\n -webkit-text-decoration: inherit;\n text-decoration: inherit;\n }\n b, strong {\n font-weight: bolder;\n }\n code, kbd, samp, pre {\n font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \'Liberation Mono\', \'Courier New\', monospace);\n font-feature-settings: var(--default-mono-font-feature-settings, normal);\n font-variation-settings: var(--default-mono-font-variation-settings, normal);\n font-size: 1em;\n }\n small {\n font-size: 80%;\n }\n sub, sup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n }\n sub {\n bottom: -0.25em;\n }\n sup {\n top: -0.5em;\n }\n table {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n }\n :-moz-focusring:where(:not(iframe)) {\n outline: auto;\n }\n progress {\n vertical-align: baseline;\n }\n summary {\n display: list-item;\n }\n ol, ul, menu {\n list-style: none;\n }\n img, svg, video, canvas, audio, iframe, embed, object {\n display: block;\n vertical-align: middle;\n }\n img, video {\n max-width: 100%;\n height: auto;\n }\n button, input, select, optgroup, textarea, ::file-selector-button {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n border-radius: 0;\n background-color: transparent;\n opacity: 1;\n }\n :where(select:is([multiple], [size])) optgroup {\n font-weight: bolder;\n }\n :where(select:is([multiple], [size])) optgroup option {\n padding-inline-start: 20px;\n }\n ::file-selector-button {\n margin-inline-end: 4px;\n }\n ::placeholder {\n opacity: 1;\n }\n @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {\n ::placeholder {\n color: currentcolor;\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, currentcolor 50%, transparent);\n }\n }\n }\n textarea {\n resize: vertical;\n }\n ::-webkit-search-decoration {\n -webkit-appearance: none;\n }\n ::-webkit-date-and-time-value {\n min-height: 1lh;\n text-align: inherit;\n }\n ::-webkit-datetime-edit {\n display: inline-flex;\n }\n ::-webkit-datetime-edit-fields-wrapper {\n padding: 0;\n }\n ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {\n padding-block: 0;\n }\n ::-webkit-calendar-picker-indicator {\n line-height: 1;\n }\n :-moz-ui-invalid {\n box-shadow: none;\n }\n button, input:where([type=\'button\'], [type=\'reset\'], [type=\'submit\']), ::file-selector-button {\n appearance: button;\n }\n ::-webkit-inner-spin-button, ::-webkit-outer-spin-button {\n height: auto;\n }\n [hidden]:where(:not([hidden=\'until-found\'])) {\n display: none !important;\n }\n}\n@layer theme {\n :root, :host {\n --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial,\n sans-serif;\n --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \'Liberation Mono\', \'Courier New\',\n monospace;\n --color-black: #000;\n --color-white: #fff;\n --spacing: 4px;\n --text-xs: 12px;\n --text-xs--line-height: calc(1 / 0.75);\n --text-sm: 14px;\n --text-sm--line-height: calc(1.25 / 0.875);\n --text-base: 16px;\n --text-base--line-height: calc(1.5 / 1);\n --text-lg: 18px;\n --text-lg--line-height: calc(1.75 / 1.125);\n --text-xl: 20px;\n --text-xl--line-height: calc(1.75 / 1.25);\n --font-weight-medium: 500;\n --font-weight-semibold: 600;\n --font-weight-bold: 700;\n --leading-tight: 1.25;\n --leading-snug: 1.375;\n --radius-sm: 4px;\n --radius-md: 6px;\n --radius-lg: 8px;\n --radius-xl: 12px;\n --ease-in: cubic-bezier(0.4, 0, 1, 1);\n --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);\n --default-transition-duration: 150ms;\n --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n --default-font-family: var(--font-sans);\n --default-mono-font-family: var(--font-mono);\n --spacing-0\\.5: 2px;\n --spacing-1\\.5: 6px;\n --spacing-2\\.5: 10px;\n --spacing-3\\.5: 14px;\n --color-panel: rgba(255, 255, 255, 0.86);\n --color-border: rgba(0, 0, 0, 0.2);\n --sc-surface-border: transparent;\n --sc-focus-ring: rgba(47, 129, 247, 0.28);\n --sc-focus-border: rgba(47, 129, 247, 0.55);\n --sc-seam: rgba(0, 0, 0, 0.08);\n --sc-chip-bg: #e0ecfe;\n --color-primary: #24292f;\n --color-secondary: #57606a;\n --color-input: rgba(0, 0, 0, 0.08);\n --color-subtle-btn: rgba(0, 0, 0, 0.05);\n --color-save-btn: rgba(31, 136, 61, 0.9);\n --color-save-border: #1f883d;\n --color-btn: rgba(255, 255, 255, 0.8);\n --color-btn-hover: rgba(255, 255, 255, 0.88);\n --color-menu-plus: #111418;\n --color-accent: #2f81f7;\n --color-success: #3fb950;\n --color-warning: #d29922;\n --color-danger: #f85149;\n --sc-shadow-panel: 0 1px 2px rgba(0, 0, 0, 0.08), 0 2px 10px rgba(0, 0, 0, 0.14),\n inset 0 0.5px 0 rgba(255, 255, 255, 0.6);\n --sc-shadow-btn: 0 1px 2px rgba(0, 0, 0, 0.08), 0 4px 24px rgba(0, 0, 0, 0.2),\n inset 0 0.5px 0 rgba(255, 255, 255, 0.6);\n --sc-shadow-btn-hover: 0 1px 2px rgba(0, 0, 0, 0.1), 0 6px 28px rgba(0, 0, 0, 0.24),\n inset 0 0.5px 0 rgba(255, 255, 255, 0.8);\n --sc-shadow-toast: 0 1px 2px rgba(0, 0, 0, 0.08), 0 2px 10px rgba(0, 0, 0, 0.14),\n inset 0 0.5px 0 rgba(255, 255, 255, 0.6);\n }\n}\n@layer utilities {\n .pointer-events-none {\n pointer-events: none;\n }\n .collapse {\n visibility: collapse;\n }\n .visible {\n visibility: visible;\n }\n .absolute {\n position: absolute;\n }\n .fixed {\n position: fixed;\n }\n .relative {\n position: relative;\n }\n .-top-1 {\n top: calc(var(--spacing) * -1);\n }\n .-right-1 {\n right: calc(var(--spacing) * -1);\n }\n .left-1\\/2 {\n left: calc(1 / 2 * 100%);\n }\n .z-\\[\\.\\.\\.\\] {\n z-index: ...;\n }\n .-mx-1 {\n margin-inline: calc(var(--spacing) * -1);\n }\n .-mx-2 {\n margin-inline: calc(var(--spacing) * -2);\n }\n .my-2 {\n margin-block: calc(var(--spacing) * 2);\n }\n .\\!mt-0 {\n margin-top: 0px !important;\n }\n .-mt-1 {\n margin-top: calc(var(--spacing) * -1);\n }\n .mt-0\\.5 {\n margin-top: var(--spacing-0\\.5);\n }\n .mt-1 {\n margin-top: var(--spacing);\n }\n .mt-1\\.5 {\n margin-top: var(--spacing-1\\.5);\n }\n .mt-2\\.5 {\n margin-top: var(--spacing-2\\.5);\n }\n .mt-3\\.5 {\n margin-top: var(--spacing-3\\.5);\n }\n .-mr-1\\.5 {\n margin-right: calc(var(--spacing-1\\.5) * -1);\n }\n .mb-0\\.5 {\n margin-bottom: var(--spacing-0\\.5);\n }\n .mb-1 {\n margin-bottom: var(--spacing);\n }\n .mb-1\\.5 {\n margin-bottom: var(--spacing-1\\.5);\n }\n .mb-2 {\n margin-bottom: calc(var(--spacing) * 2);\n }\n .mb-2\\.5 {\n margin-bottom: var(--spacing-2\\.5);\n }\n .mb-3 {\n margin-bottom: calc(var(--spacing) * 3);\n }\n .mb-4 {\n margin-bottom: calc(var(--spacing) * 4);\n }\n .ml-1 {\n margin-left: var(--spacing);\n }\n .ml-auto {\n margin-left: auto;\n }\n .box-border {\n box-sizing: border-box;\n }\n .block {\n display: block;\n }\n .flex {\n display: flex;\n }\n .hidden {\n display: none;\n }\n .inline-block {\n display: inline-block;\n }\n .h-4 {\n height: calc(var(--spacing) * 4);\n }\n .h-5 {\n height: calc(var(--spacing) * 5);\n }\n .h-6 {\n height: calc(var(--spacing) * 6);\n }\n .h-7 {\n height: calc(var(--spacing) * 7);\n }\n .h-8 {\n height: calc(var(--spacing) * 8);\n }\n .h-9 {\n height: calc(var(--spacing) * 9);\n }\n .h-16 {\n height: calc(var(--spacing) * 16);\n }\n .h-\\[13px\\] {\n height: 13px;\n }\n .h-\\[520px\\] {\n height: 520px;\n }\n .h-full {\n height: 100%;\n }\n .max-h-24 {\n max-height: calc(var(--spacing) * 24);\n }\n .max-h-\\[160px\\] {\n max-height: 160px;\n }\n .min-h-0 {\n min-height: 0px;\n }\n .min-h-\\[46px\\] {\n min-height: 46px;\n }\n .min-h-\\[96px\\] {\n min-height: 96px;\n }\n .w-4 {\n width: calc(var(--spacing) * 4);\n }\n .w-5 {\n width: calc(var(--spacing) * 5);\n }\n .w-6 {\n width: calc(var(--spacing) * 6);\n }\n .w-7 {\n width: calc(var(--spacing) * 7);\n }\n .w-8 {\n width: calc(var(--spacing) * 8);\n }\n .w-9 {\n width: calc(var(--spacing) * 9);\n }\n .w-12 {\n width: calc(var(--spacing) * 12);\n }\n .w-16 {\n width: calc(var(--spacing) * 16);\n }\n .w-\\[13px\\] {\n width: 13px;\n }\n .w-\\[52px\\] {\n width: 52px;\n }\n .w-\\[300px\\] {\n width: 300px;\n }\n .w-full {\n width: 100%;\n }\n .max-w-\\[80vw\\] {\n max-width: 80vw;\n }\n .max-w-full {\n max-width: 100%;\n }\n .min-w-0 {\n min-width: 0px;\n }\n .flex-1 {\n flex: 1;\n }\n .flex-\\[0_0_14px\\] {\n flex: 0 0 14px;\n }\n .flex-\\[0_0_44px\\] {\n flex: 0 0 44px;\n }\n .flex-\\[0_0_52px\\] {\n flex: 0 0 52px;\n }\n .shrink-0 {\n flex-shrink: 0;\n }\n .transform {\n transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);\n }\n .cursor-grab {\n cursor: grab;\n }\n .cursor-pointer {\n cursor: pointer;\n }\n .touch-none {\n touch-action: none;\n }\n .resize {\n resize: both;\n }\n .resize-y {\n resize: vertical;\n }\n .flex-col {\n flex-direction: column;\n }\n .flex-wrap {\n flex-wrap: wrap;\n }\n .items-baseline {\n align-items: baseline;\n }\n .items-center {\n align-items: center;\n }\n .items-start {\n align-items: flex-start;\n }\n .justify-between {\n justify-content: space-between;\n }\n .justify-center {\n justify-content: center;\n }\n .justify-end {\n justify-content: flex-end;\n }\n .gap-1 {\n gap: var(--spacing);\n }\n .gap-1\\.5 {\n gap: var(--spacing-1\\.5);\n }\n .gap-2 {\n gap: calc(var(--spacing) * 2);\n }\n .gap-x-5 {\n column-gap: calc(var(--spacing) * 5);\n }\n .gap-y-1 {\n row-gap: var(--spacing);\n }\n .truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .overflow-hidden {\n overflow: hidden;\n }\n .overflow-x-hidden {\n overflow-x: hidden;\n }\n .overflow-y-auto {\n overflow-y: auto;\n }\n .rounded-\\[10px\\] {\n border-radius: 10px;\n }\n .rounded-full {\n border-radius: calc(infinity * 1px);\n }\n .rounded-lg {\n border-radius: var(--radius-lg);\n }\n .rounded-md {\n border-radius: var(--radius-md);\n }\n .rounded-sm {\n border-radius: var(--radius-sm);\n }\n .rounded-xl {\n border-radius: var(--radius-xl);\n }\n .border-surface {\n border-style: solid;\n border-width: 1px;\n border-color: var(--sc-surface-border);\n }\n .border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n .border-0 {\n border-style: var(--tw-border-style);\n border-width: 0px;\n }\n .border-t {\n border-top-style: var(--tw-border-style);\n border-top-width: 1px;\n }\n .border-b {\n border-bottom-style: var(--tw-border-style);\n border-bottom-width: 1px;\n }\n .border-none {\n --tw-border-style: none;\n border-style: none;\n }\n .border-border {\n border-color: var(--color-border);\n }\n .border-danger\\/40 {\n border-color: color-mix(in srgb, #f85149 40%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--color-danger) 40%, transparent);\n }\n }\n .border-save-border {\n border-color: var(--color-save-border);\n }\n .border-seam {\n border-color: var(--sc-seam);\n }\n .border-transparent {\n border-color: transparent;\n }\n .border-warning\\/40 {\n border-color: color-mix(in srgb, #d29922 40%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--color-warning) 40%, transparent);\n }\n }\n .bg-accent\\/15 {\n background-color: color-mix(in srgb, #2f81f7 15%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-accent) 15%, transparent);\n }\n }\n .bg-accent\\/20 {\n background-color: color-mix(in srgb, #2f81f7 20%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-accent) 20%, transparent);\n }\n }\n .bg-black\\/60 {\n background-color: color-mix(in srgb, #000 60%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-black) 60%, transparent);\n }\n }\n .bg-btn {\n background-color: var(--color-btn);\n }\n .bg-chip {\n background-color: var(--sc-chip-bg);\n }\n .bg-input {\n background-color: var(--color-input);\n }\n .bg-panel {\n background-color: var(--color-panel);\n }\n .bg-save-btn {\n background-color: var(--color-save-btn);\n }\n .bg-subtle-btn {\n background-color: var(--color-subtle-btn);\n }\n .bg-transparent {\n background-color: transparent;\n }\n .bg-warning\\/15 {\n background-color: color-mix(in srgb, #d29922 15%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-warning) 15%, transparent);\n }\n }\n .object-contain {\n object-fit: contain;\n }\n .p-0 {\n padding: 0px;\n }\n .p-1 {\n padding: var(--spacing);\n }\n .p-1\\.5 {\n padding: var(--spacing-1\\.5);\n }\n .p-2 {\n padding: calc(var(--spacing) * 2);\n }\n .p-3 {\n padding: calc(var(--spacing) * 3);\n }\n .p-\\[2px_10px_8px_4px\\] {\n padding: 2px 10px 8px 4px;\n }\n .p-\\[5px_6px\\] {\n padding: 5px 6px;\n }\n .px-1 {\n padding-inline: var(--spacing);\n }\n .px-1\\.5 {\n padding-inline: var(--spacing-1\\.5);\n }\n .px-2 {\n padding-inline: calc(var(--spacing) * 2);\n }\n .px-2\\.5 {\n padding-inline: var(--spacing-2\\.5);\n }\n .px-3 {\n padding-inline: calc(var(--spacing) * 3);\n }\n .px-4 {\n padding-inline: calc(var(--spacing) * 4);\n }\n .py-0\\.5 {\n padding-block: var(--spacing-0\\.5);\n }\n .py-1 {\n padding-block: var(--spacing);\n }\n .py-1\\.5 {\n padding-block: var(--spacing-1\\.5);\n }\n .py-\\[1px\\] {\n padding-block: 1px;\n }\n .py-\\[3px\\] {\n padding-block: 3px;\n }\n .\\!pt-0 {\n padding-top: 0px !important;\n }\n .pt-2\\.5 {\n padding-top: var(--spacing-2\\.5);\n }\n .pb-3 {\n padding-bottom: calc(var(--spacing) * 3);\n }\n .pb-\\[3px\\] {\n padding-bottom: 3px;\n }\n .pb-\\[5px\\] {\n padding-bottom: 5px;\n }\n .pl-\\[30px\\] {\n padding-left: 30px;\n }\n .font-\\[inherit\\] {\n font-family: inherit;\n }\n .text-base {\n font-size: var(--text-base);\n line-height: var(--tw-leading, var(--text-base--line-height));\n }\n .text-lg {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n }\n .text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n .text-xl {\n font-size: var(--text-xl);\n line-height: var(--tw-leading, var(--text-xl--line-height));\n }\n .text-xs {\n font-size: var(--text-xs);\n line-height: var(--tw-leading, var(--text-xs--line-height));\n }\n .text-\\[10px\\] {\n font-size: 10px;\n }\n .text-\\[11px\\] {\n font-size: 11px;\n }\n .text-\\[13px\\] {\n font-size: 13px;\n }\n .leading-\\[1\\.5\\] {\n --tw-leading: 1.5;\n line-height: 1.5;\n }\n .leading-none {\n --tw-leading: 1;\n line-height: 1;\n }\n .leading-snug {\n --tw-leading: var(--leading-snug);\n line-height: var(--leading-snug);\n }\n .leading-tight {\n --tw-leading: var(--leading-tight);\n line-height: var(--leading-tight);\n }\n .font-bold {\n --tw-font-weight: var(--font-weight-bold);\n font-weight: var(--font-weight-bold);\n }\n .font-medium {\n --tw-font-weight: var(--font-weight-medium);\n font-weight: var(--font-weight-medium);\n }\n .font-semibold {\n --tw-font-weight: var(--font-weight-semibold);\n font-weight: var(--font-weight-semibold);\n }\n .break-words {\n overflow-wrap: break-word;\n }\n .whitespace-nowrap {\n white-space: nowrap;\n }\n .whitespace-pre-wrap {\n white-space: pre-wrap;\n }\n .text-accent {\n color: var(--color-accent);\n }\n .text-danger {\n color: var(--color-danger);\n }\n .text-inherit {\n color: inherit;\n }\n .text-menu-plus {\n color: var(--color-menu-plus);\n }\n .text-primary {\n color: var(--color-primary);\n }\n .text-secondary {\n color: var(--color-secondary);\n }\n .text-secondary\\/80 {\n color: color-mix(in srgb, #57606a 80%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, var(--color-secondary) 80%, transparent);\n }\n }\n .text-warning {\n color: var(--color-warning);\n }\n .text-white {\n color: var(--color-white);\n }\n .line-through {\n text-decoration-line: line-through;\n }\n .no-underline {\n text-decoration-line: none;\n }\n .accent-accent {\n accent-color: var(--color-accent);\n }\n .opacity-60 {\n opacity: 60%;\n }\n .shadow {\n --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-none {\n --tw-shadow: 0 0 #0000;\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-sm {\n --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .ring {\n --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-btn {\n box-shadow: var(--sc-shadow-btn);\n }\n .shadow-btn-hover {\n box-shadow: var(--sc-shadow-btn-hover);\n }\n .shadow-panel {\n box-shadow: var(--sc-shadow-panel);\n }\n .shadow-btn {\n --tw-shadow-color: rgba(255, 255, 255, 0.8);\n @supports (color: color-mix(in lab, red, red)) {\n --tw-shadow-color: color-mix(in oklab, var(--color-btn) var(--tw-shadow-alpha), transparent);\n }\n }\n .shadow-btn-hover {\n --tw-shadow-color: rgba(255, 255, 255, 0.88);\n @supports (color: color-mix(in lab, red, red)) {\n --tw-shadow-color: color-mix(in oklab, var(--color-btn-hover) var(--tw-shadow-alpha), transparent);\n }\n }\n .shadow-panel {\n --tw-shadow-color: rgba(255, 255, 255, 0.86);\n @supports (color: color-mix(in lab, red, red)) {\n --tw-shadow-color: color-mix(in oklab, var(--color-panel) var(--tw-shadow-alpha), transparent);\n }\n }\n .outline {\n outline-style: var(--tw-outline-style);\n outline-width: 1px;\n }\n .filter {\n filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);\n }\n .backdrop-blur-\\[10px\\] {\n --tw-backdrop-blur: blur(10px);\n -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n }\n .backdrop-saturate-150 {\n --tw-backdrop-saturate: saturate(150%);\n -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n }\n .backdrop-filter {\n -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n }\n .transition {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-\\[margin-top\\,bottom\\,box-shadow\\] {\n transition-property: margin-top,bottom,box-shadow;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-colors {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-shadow {\n transition-property: box-shadow;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-transform {\n transition-property: transform, translate, scale, rotate;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .duration-200 {\n --tw-duration: 200ms;\n transition-duration: 200ms;\n }\n .ease-in {\n --tw-ease: var(--ease-in);\n transition-timing-function: var(--ease-in);\n }\n .ease-in-out {\n --tw-ease: var(--ease-in-out);\n transition-timing-function: var(--ease-in-out);\n }\n .outline-none {\n --tw-outline-style: none;\n outline-style: none;\n }\n .select-none {\n -webkit-user-select: none;\n user-select: none;\n }\n .select-text {\n -webkit-user-select: text;\n user-select: text;\n }\n @media (hover: hover) {\n .hover\\:scale-110:hover {\n --tw-scale-x: 110%;\n --tw-scale-y: 110%;\n --tw-scale-z: 110%;\n scale: var(--tw-scale-x) var(--tw-scale-y);\n }\n .hover\\:bg-btn-hover:hover {\n background-color: var(--color-btn-hover);\n }\n .hover\\:bg-danger\\/15:hover {\n background-color: color-mix(in srgb, #f85149 15%, transparent);\n }\n @supports (color: color-mix(in lab, red, red)) {\n .hover\\:bg-danger\\/15:hover {\n background-color: color-mix(in oklab, var(--color-danger) 15%, transparent);\n }\n }\n .hover\\:bg-white\\/10:hover {\n background-color: color-mix(in srgb, #fff 10%, transparent);\n }\n @supports (color: color-mix(in lab, red, red)) {\n .hover\\:bg-white\\/10:hover {\n background-color: color-mix(in oklab, var(--color-white) 10%, transparent);\n }\n }\n .hover\\:bg-white\\/15:hover {\n background-color: color-mix(in srgb, #fff 15%, transparent);\n }\n @supports (color: color-mix(in lab, red, red)) {\n .hover\\:bg-white\\/15:hover {\n background-color: color-mix(in oklab, var(--color-white) 15%, transparent);\n }\n }\n .hover\\:text-danger:hover {\n color: var(--color-danger);\n }\n .hover\\:text-primary:hover {\n color: var(--color-primary);\n }\n .hover\\:opacity-90:hover {\n opacity: 90%;\n }\n .hover\\:shadow-btn-hover:hover {\n box-shadow: var(--sc-shadow-btn-hover);\n --tw-shadow-color: rgba(255, 255, 255, 0.88);\n }\n @supports (color: color-mix(in lab, red, red)) {\n .hover\\:shadow-btn-hover:hover {\n --tw-shadow-color: color-mix(in oklab, var(--color-btn-hover) var(--tw-shadow-alpha), transparent);\n }\n }\n }\n .focus\\:border:focus {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n .active\\:scale-\\[0\\.97\\]:active {\n scale: 0.97;\n }\n}\n.border,\n.border-t,\n.border-b,\n.border-l,\n.border-r {\n border-style: solid;\n}\n.border-none {\n border-style: none;\n}\n.sc-field:focus,\ninput:not([type="checkbox"]):not([type="radio"]):focus,\nselect:focus,\ntextarea:focus,\nbutton:focus-visible,\na:focus-visible,\n[tabindex]:focus-visible,\ninput[type="checkbox"]:focus-visible,\ninput[type="radio"]:focus-visible {\n outline: none;\n border-color: var(--sc-focus-border);\n box-shadow: 0 0 0 3px var(--sc-focus-ring);\n}\n:host {\n font-family: var(--font-sans);\n font-size: 16px;\n}\n@layer base {\n button,\n input,\n select,\n textarea {\n font: inherit;\n color: inherit;\n margin: 0;\n }\n button {\n appearance: none;\n -webkit-appearance: none;\n background: none;\n padding: 0;\n }\n button:not(:disabled) {\n cursor: pointer;\n }\n}\n@media (prefers-color-scheme: dark) {\n :host {\n --color-panel: rgba(30, 30, 30, 0.8);\n --color-border: rgba(255, 255, 255, 0.15);\n --sc-surface-border: transparent;\n --sc-focus-ring: rgba(88, 166, 255, 0.3);\n --sc-focus-border: rgba(88, 166, 255, 0.6);\n --sc-seam: rgba(255, 255, 255, 0.1);\n --sc-chip-bg: #2b3749;\n --color-primary: #f0f6fc;\n --color-secondary: #8b949e;\n --color-input: rgba(13, 17, 23, 0.6);\n --color-subtle-btn: rgba(255, 255, 255, 0.12);\n --color-save-btn: rgba(35, 134, 54, 0.9);\n --color-save-border: #238636;\n --color-btn: rgba(30, 30, 30, 0.8);\n --color-btn-hover: rgba(45, 45, 45, 0.88);\n --color-menu-plus: #ffffff;\n --sc-shadow-panel: 0 2px 10px rgba(0, 0, 0, 0.35), inset 0 0.5px 0 rgba(255, 255, 255, 0.6);\n --sc-shadow-btn: 0 4px 24px rgba(0, 0, 0, 0.4), inset 0 0.5px 0 rgba(255, 255, 255, 0.6);\n --sc-shadow-btn-hover: 0 6px 28px rgba(0, 0, 0, 0.5), inset 0 0.5px 0 rgba(255, 255, 255, 0.8);\n --sc-shadow-toast: 0 2px 10px rgba(0, 0, 0, 0.35), inset 0 0.5px 0 rgba(255, 255, 255, 0.6);\n }\n}\n@keyframes sc-breathe {\n 0%,\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.65;\n transform: scale(0.9);\n }\n}\n@keyframes sc-spin {\n to {\n transform: rotate(360deg);\n }\n}\n@keyframes sc-pulse {\n 0%,\n 100% {\n transform: scale(1);\n }\n 50% {\n transform: scale(1.15);\n }\n}\n.sc-anim-breathe {\n animation: sc-breathe 2.6s ease-in-out infinite;\n}\n.sc-anim-spin {\n animation: sc-spin 5s linear infinite;\n}\n.sc-anim-pulse {\n animation: sc-pulse 1.8s ease-in-out infinite;\n}\n@keyframes sc-ripple {\n 0% {\n transform: scale(1);\n opacity: 0.55;\n }\n 100% {\n transform: scale(1.9);\n opacity: 0;\n }\n}\n.sc-anim-ripple {\n position: absolute;\n inset: 0;\n border-radius: 9999px;\n pointer-events: none;\n z-index: 0;\n}\n.sc-anim-ripple::before,\n.sc-anim-ripple::after {\n content: "";\n position: absolute;\n inset: 0;\n border-radius: 9999px;\n border: 2px solid var(--color-accent);\n animation: sc-ripple 2.4s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;\n}\n.sc-anim-ripple::after {\n animation-delay: 1.2s;\n}\n@media (prefers-reduced-motion: reduce) {\n .sc-anim-breathe,\n .sc-anim-spin,\n .sc-anim-pulse {\n animation: none;\n }\n .sc-anim-ripple::before,\n .sc-anim-ripple::after {\n animation: none;\n opacity: 0;\n }\n}\n@property --tw-rotate-x {\n syntax: "*";\n inherits: false;\n}\n@property --tw-rotate-y {\n syntax: "*";\n inherits: false;\n}\n@property --tw-rotate-z {\n syntax: "*";\n inherits: false;\n}\n@property --tw-skew-x {\n syntax: "*";\n inherits: false;\n}\n@property --tw-skew-y {\n syntax: "*";\n inherits: false;\n}\n@property --tw-border-style {\n syntax: "*";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-leading {\n syntax: "*";\n inherits: false;\n}\n@property --tw-font-weight {\n syntax: "*";\n inherits: false;\n}\n@property --tw-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-shadow-alpha {\n syntax: "";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-inset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-inset-shadow-alpha {\n syntax: "";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-ring-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-ring-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-inset-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-ring-inset {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ring-offset-width {\n syntax: "";\n inherits: false;\n initial-value: 0px;\n}\n@property --tw-ring-offset-color {\n syntax: "*";\n inherits: false;\n initial-value: #fff;\n}\n@property --tw-ring-offset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-outline-style {\n syntax: "*";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-blur {\n syntax: "*";\n inherits: false;\n}\n@property --tw-brightness {\n syntax: "*";\n inherits: false;\n}\n@property --tw-contrast {\n syntax: "*";\n inherits: false;\n}\n@property --tw-grayscale {\n syntax: "*";\n inherits: false;\n}\n@property --tw-hue-rotate {\n syntax: "*";\n inherits: false;\n}\n@property --tw-invert {\n syntax: "*";\n inherits: false;\n}\n@property --tw-opacity {\n syntax: "*";\n inherits: false;\n}\n@property --tw-saturate {\n syntax: "*";\n inherits: false;\n}\n@property --tw-sepia {\n syntax: "*";\n inherits: false;\n}\n@property --tw-drop-shadow {\n syntax: "*";\n inherits: false;\n}\n@property --tw-drop-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-drop-shadow-alpha {\n syntax: "";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-drop-shadow-size {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-blur {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-brightness {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-contrast {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-grayscale {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-hue-rotate {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-invert {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-opacity {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-saturate {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-sepia {\n syntax: "*";\n inherits: false;\n}\n@property --tw-duration {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ease {\n syntax: "*";\n inherits: false;\n}\n@property --tw-scale-x {\n syntax: "*";\n inherits: false;\n initial-value: 1;\n}\n@property --tw-scale-y {\n syntax: "*";\n inherits: false;\n initial-value: 1;\n}\n@property --tw-scale-z {\n syntax: "*";\n inherits: false;\n initial-value: 1;\n}\n@layer properties {\n @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {\n *, ::before, ::after, ::backdrop {\n --tw-rotate-x: initial;\n --tw-rotate-y: initial;\n --tw-rotate-z: initial;\n --tw-skew-x: initial;\n --tw-skew-y: initial;\n --tw-border-style: solid;\n --tw-leading: initial;\n --tw-font-weight: initial;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-color: initial;\n --tw-shadow-alpha: 100%;\n --tw-inset-shadow: 0 0 #0000;\n --tw-inset-shadow-color: initial;\n --tw-inset-shadow-alpha: 100%;\n --tw-ring-color: initial;\n --tw-ring-shadow: 0 0 #0000;\n --tw-inset-ring-color: initial;\n --tw-inset-ring-shadow: 0 0 #0000;\n --tw-ring-inset: initial;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-outline-style: solid;\n --tw-blur: initial;\n --tw-brightness: initial;\n --tw-contrast: initial;\n --tw-grayscale: initial;\n --tw-hue-rotate: initial;\n --tw-invert: initial;\n --tw-opacity: initial;\n --tw-saturate: initial;\n --tw-sepia: initial;\n --tw-drop-shadow: initial;\n --tw-drop-shadow-color: initial;\n --tw-drop-shadow-alpha: 100%;\n --tw-drop-shadow-size: initial;\n --tw-backdrop-blur: initial;\n --tw-backdrop-brightness: initial;\n --tw-backdrop-contrast: initial;\n --tw-backdrop-grayscale: initial;\n --tw-backdrop-hue-rotate: initial;\n --tw-backdrop-invert: initial;\n --tw-backdrop-opacity: initial;\n --tw-backdrop-saturate: initial;\n --tw-backdrop-sepia: initial;\n --tw-duration: initial;\n --tw-ease: initial;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-scale-z: 1;\n }\n }\n}\n',o.appendChild(r),n=!0}(0,e.onMounted)(()=>{o()});const r=ae("general.backTop",!0,ie(!0)),a=ae("general.disabledSites","",pe()),i=(0,e.computed)(()=>a.value.split("\n").map(e=>e.trim()).filter(Boolean)),s=location.hostname.toLowerCase(),l=(0,e.computed)(()=>i.value.some(e=>{const t=e.toLowerCase().replace(/^https?:\/\//,"");return t&&(s===t||s.endsWith("."+t))}));return(t,n)=>((0,e.openBlock)(),(0,e.createElementBlock)(e.Fragment,null,[(0,e.createCommentVNode)(" GitHub 加速已插件化(内置 com.flowsaro.github-accel,由 BackToTop 管理开关) "),(0,e.unref)(r)&&!l.value?((0,e.openBlock)(),(0,e.createBlock)(zt,{key:0})):(0,e.createCommentVNode)("v-if",!0)],2112))}}),Lt=Tt,_t="app-QGNvbS5mbG93c2Fyby9yb2NrZXRfYnRu",Dt="[火箭按钮]";console.debug(Dt+" 启动中");let It=document.getElementById(_t);if(!It){It=document.createElement("div"),It.id=_t;const e=[["all","initial"],["position","fixed"],["z-index","2147483647"],["pointer-events","none"],["font-family","var(--font-sans, ui-sans-serif, system-ui, sans-serif)"],["font-size","16px"],["line-height","1.5"],["color-scheme","light dark"]];for(const t of e)try{It.style.setProperty(t[0],t[1],"important")}catch{}try{document.body?document.body.appendChild(It):document.addEventListener("DOMContentLoaded",()=>document.body.appendChild(It))}catch(e){console.error(Dt+" 宿主挂载失败:",e)}}if(!It.__shadowMount){const e=It.attachShadow({mode:"open"}),t=document.createElement("div");t.style.cssText="pointer-events: auto;",e.appendChild(t),It.__shadowMount=t}let At=null;const Rt=()=>{It.isConnected||((document.body||document.documentElement).appendChild(It),At&&At.disconnect(),document.body&&(At=new MutationObserver(Rt),At.observe(document.body,{childList:!0})))};document.body&&(At=new MutationObserver(Rt),At.observe(document.body,{childList:!0}));if(new MutationObserver(Rt).observe(document.documentElement,{childList:!0}),"undefined"==typeof Vue)console.error(Dt+" Vue 依赖未就绪(@require 未加载完成),本次注入放弃");else try{(0,e.createApp)(Lt).mount(It.__shadowMount),console.debug(Dt+" v0.8.80 已挂载")}catch(e){console.error(Dt+" 挂载失败:",e)}})();