diff --git a/404.html b/404.html new file mode 100644 index 00000000..f3cba621 --- /dev/null +++ b/404.html @@ -0,0 +1,19 @@ + + + + + + 404 | AmiyaBot + + + + + + + +
Skip to content

404

PAGE NOT FOUND

But if you don't change your direction, and if you keep looking, you may end up where you are heading.
+ + + + \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 00000000..690efef9 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +www.amiyabot.com diff --git a/E0BA9D78918921391A5BE261A96C6F04.jpg b/E0BA9D78918921391A5BE261A96C6F04.jpg new file mode 100644 index 00000000..fc907a5d Binary files /dev/null and b/E0BA9D78918921391A5BE261A96C6F04.jpg differ diff --git a/F7AB3AFE554027987502E5E1AB65746E.jpg b/F7AB3AFE554027987502E5E1AB65746E.jpg new file mode 100644 index 00000000..4e724bfc Binary files /dev/null and b/F7AB3AFE554027987502E5E1AB65746E.jpg differ diff --git a/assets/5a4a07cc67f556288d3df2e9029fc14.f485e307.jpg b/assets/5a4a07cc67f556288d3df2e9029fc14.f485e307.jpg new file mode 100644 index 00000000..02641bbc Binary files /dev/null and b/assets/5a4a07cc67f556288d3df2e9029fc14.f485e307.jpg differ diff --git a/assets/account.d1c96da5.svg b/assets/account.d1c96da5.svg new file mode 100644 index 00000000..96174a31 --- /dev/null +++ b/assets/account.d1c96da5.svg @@ -0,0 +1 @@ +PluginAmiyaBotPlugin  MultipleAccountsPluginAmiyaBotPluginCenterProcessorPlugin  \ No newline at end of file diff --git a/assets/adapter.b252f80a.svg b/assets/adapter.b252f80a.svg new file mode 100644 index 00000000..e3b1ed94 --- /dev/null +++ b/assets/adapter.b252f80a.svg @@ -0,0 +1 @@ +TencentMirai-api-httpGo-cqhttpAdapterCenterProcessorAmiyaBot \ No newline at end of file diff --git a/assets/addBot.c3c3627e.png b/assets/addBot.c3c3627e.png new file mode 100644 index 00000000..4657e933 Binary files /dev/null and b/assets/addBot.c3c3627e.png differ diff --git a/assets/app.ff43e989.js b/assets/app.ff43e989.js new file mode 100644 index 00000000..b35273db --- /dev/null +++ b/assets/app.ff43e989.js @@ -0,0 +1 @@ +import{Q as s,a5 as p,a6 as i,a7 as u,a8 as c,a9 as l,aa as d,ab as f,ac as m,ad as h,ae as A,M as g,d as P,u as v,k as y,q as C,af as w,ag as _,ah as b,ai as E}from"./chunks/framework.63f12d77.js";import{t as R}from"./chunks/theme.e23c65ce.js";function r(e){if(e.extends){const a=r(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const n=r(R),D=P({name:"VitePressApp",setup(){const{site:e}=v();return y(()=>{C(()=>{document.documentElement.lang=e.value.lang,document.documentElement.dir=e.value.dir})}),w(),_(),b(),n.setup&&n.setup(),()=>E(n.Layout)}});async function O(){const e=T(),a=S();a.provide(i,e);const t=u(e.route);return a.provide(c,t),a.component("Content",l),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),n.enhanceApp&&await n.enhanceApp({app:a,router:e,siteData:f}),{app:a,router:e,data:t}}function S(){return m(D)}function T(){let e=s,a;return h(t=>{let o=A(t);return e&&(a=o),(e||a===o)&&(o=o.replace(/\.js$/,".lean.js")),s&&(e=!1),g(()=>import(o),[])},n.NotFound)}s&&O().then(({app:e,router:a,data:t})=>{a.go().then(()=>{p(a.route,t.site),e.mount("#app")})});export{O as createApp}; diff --git a/assets/awesome1.7d49a140.png b/assets/awesome1.7d49a140.png new file mode 100644 index 00000000..1078e64d Binary files /dev/null and b/assets/awesome1.7d49a140.png differ diff --git a/assets/centerProcessor.46a8ea9e.svg b/assets/centerProcessor.46a8ea9e.svg new file mode 100644 index 00000000..412b86a0 --- /dev/null +++ b/assets/centerProcessor.46a8ea9e.svg @@ -0,0 +1 @@ +CenterProcessorAdapterType CheckmiddlewareExecuteChoiceAmiyaBotmessage_handlersevent_handlersBotHandlerFactoryChoiceExecuteMessageEvent \ No newline at end of file diff --git a/assets/chunks/@localSearchIndexroot.13a295e8.js b/assets/chunks/@localSearchIndexroot.13a295e8.js new file mode 100644 index 00000000..7c528c1d --- /dev/null +++ b/assets/chunks/@localSearchIndexroot.13a295e8.js @@ -0,0 +1 @@ +const e='{"documentCount":409,"nextId":409,"documentIds":{"0":"/develop/adapters/comwechat.html#comwechatbot-client-beta","1":"/develop/adapters/comwechat.html#连接-comwechatbot","2":"/develop/adapters/gocq.html#go-cqhttp","3":"/develop/adapters/gocq.html#连接-gocq","4":"/develop/adapters/#适配器","5":"/develop/adapters/#适配器参数-adapter","6":"/develop/adapters/kook.html#kook-机器人","7":"/develop/adapters/mah.html#mirai-api-http","8":"/develop/adapters/mah.html#连接-mah","9":"/develop/adapters/onebot11.html#onebot-v11-beta","10":"/develop/adapters/onebot11.html#连接-onebot11","11":"/develop/adapters/onebot12.html#onebot-v12-beta","12":"/develop/adapters/onebot12.html#连接-onebot12","13":"/develop/adapters/qqChannel.html#qq-频道机器人","14":"/develop/adapters/qqChannel.html#事件分片","15":"/develop/adapters/qqChannel.html#沙箱环境","16":"/develop/adapters/qqGlobal.html#qq-全域机器人-beta","17":"/develop/adapters/qqGlobal.html#创建全域适配器","18":"/develop/adapters/qqGroup.html#qq-群机器人-beta","19":"/develop/adapters/qqGroup.html#在公网下使用","20":"/develop/adapters/qqGroup.html#事件分片","21":"/develop/adapters/qqGroup.html#修改资源服务配置","22":"/develop/adapters/qqGroup.html#自定义资源服务","23":"/develop/adapters/qqGroup.html#继承-chainbuilder-并实现相关方法。","24":"/develop/advanced/blockingIO.html#处理-io-阻塞的操作","25":"/develop/advanced/blockingIO.html#run-in-thread-pool","26":"/develop/advanced/chainBuilder.html#介入-chain-构建媒体消息时的操作","27":"/develop/advanced/chainBuilder.html#创建辅助类","28":"/develop/advanced/chainBuilder.html#get-image","29":"/develop/advanced/chainBuilder.html#get-voice","30":"/develop/advanced/chainBuilder.html#get-video","31":"/develop/advanced/chainBuilder.html#on-page-rendered","32":"/develop/advanced/databaseSupport.html#数据库支持","33":"/develop/advanced/databaseSupport.html#sqlite","34":"/develop/advanced/databaseSupport.html#mysql","35":"/develop/advanced/databaseSupport.html#表结构管理","36":"/develop/advanced/databaseSupport.html#扩展查询","37":"/develop/advanced/databaseSupport.html#batch-insert","38":"/develop/advanced/databaseSupport.html#insert-or-update","39":"/develop/advanced/databaseSupport.html#查询转换工具","40":"/develop/advanced/databaseSupport.html#convert-model","41":"/develop/advanced/databaseSupport.html#query-to-list","42":"/develop/advanced/databaseSupport.html#select-for-paginate","43":"/develop/advanced/eventBus.html#事件总线","44":"/develop/advanced/eventBus.html#发布事件","45":"/develop/advanced/eventBus.html#订阅事件","46":"/develop/advanced/eventBus.html#取消订阅","47":"/develop/advanced/httpRequests.html#发送-http-请求","48":"/develop/advanced/httpRequests.html#返回值","49":"/develop/advanced/httpRequests.html#json","50":"/develop/advanced/httpRequests.html#response","51":"/develop/advanced/httpRequests.html#error","52":"/develop/advanced/httpRequests.html#get-请求","53":"/develop/advanced/httpRequests.html#post-请求","54":"/develop/advanced/httpRequests.html#form-表单请求","55":"/develop/advanced/httpRequests.html#文件上传","56":"/develop/advanced/httpRequests.html#自定义请求","57":"/develop/advanced/httpRequests.html#下载文件","58":"/develop/advanced/httpRequests.html#同步下载","59":"/develop/advanced/httpSupport.html#http服务器支持","60":"/develop/advanced/httpSupport.html#创建服务","61":"/develop/advanced/httpSupport.html#httpserver-类","62":"/develop/advanced/httpSupport.html#自定义路由","63":"/develop/advanced/httpSupport.html#请求头密钥","64":"/develop/advanced/httpSupport.html#fastapi-扩展","65":"/develop/advanced/#进阶指南","66":"/develop/advanced/lifeCycle.html#生命周期","67":"/develop/advanced/lifeCycle.html#消息生命周期","68":"/develop/advanced/lifeCycle.html#message-created","69":"/develop/advanced/lifeCycle.html#message-before-waiter-set","70":"/develop/advanced/lifeCycle.html#message-before-handle","71":"/develop/advanced/lifeCycle.html#message-before-send","72":"/develop/advanced/lifeCycle.html#message-after-send","73":"/develop/advanced/lifeCycle.html#message-after-handle","74":"/develop/advanced/lifeCycle.html#事件生命周期","75":"/develop/advanced/loadPlugins.html#加载插件","76":"/develop/advanced/loadPlugins.html#前言","77":"/develop/advanced/loadPlugins.html#开发插件","78":"/develop/advanced/loadPlugins.html#导入插件实例","79":"/develop/advanced/loadPlugins.html#导入-python-文件","80":"/develop/advanced/loadPlugins.html#导入-python-package-目录","81":"/develop/advanced/loadPlugins.html#导入-zip-压缩包","82":"/develop/advanced/loadPlugins.html#卸载插件","83":"/develop/advanced/logger.html#日志模块","84":"/develop/advanced/logger.html#输出日志","85":"/develop/advanced/logger.html#输出异常日志","86":"/develop/advanced/logger.html#创建日志模块","87":"/develop/advanced/logger.html#自定义全局日志模块","88":"/develop/advanced/playwright.html#改变-playwright-启动","89":"/develop/advanced/startupParameter.html#启动参数","90":"/develop/advanced/startupParameter.html#在-兔兔-v6-下使用","91":"/develop/advanced/timedTask.html#定时任务","92":"/develop/advanced/timedTask.html#简单使用","93":"/develop/advanced/timedTask.html#插件开发","94":"/develop/advanced/timedTask.html#timed-task-装饰器","95":"/develop/advanced/timedTask.html#自定义执行时机","96":"/develop/advanced/timedTask.html#取消定时任务","97":"/develop/advanced/timedTask.html#bot-remove-timed-task","98":"/develop/basic/api/#api","99":"/develop/basic/api/#引入-api-类以注解变量","100":"/develop/basic/api/#共同的方法","101":"/develop/basic/api/#get","102":"/develop/basic/api/#post","103":"/develop/basic/api/#request","104":"/develop/basic/api/#api-的返回","105":"/develop/basic/api/qqbot.html#qq-频道-api","106":"/develop/basic/api/qqbot.html#add-message-reaction","107":"/develop/basic/api/qqbot.html#add-pin","108":"/develop/basic/api/qqbot.html#create-announces","109":"/develop/basic/api/qqbot.html#create-channel","110":"/develop/basic/api/qqbot.html#create-guild-api-permission-link","111":"/develop/basic/api/qqbot.html#create-guild-role","112":"/develop/basic/api/qqbot.html#create-schedule","113":"/develop/basic/api/qqbot.html#create-thread","114":"/develop/basic/api/qqbot.html#delete-announces","115":"/develop/basic/api/qqbot.html#delete-channel","116":"/develop/basic/api/qqbot.html#delete-guild-member","117":"/develop/basic/api/qqbot.html#delete-guild-role","118":"/develop/basic/api/qqbot.html#delete-message","119":"/develop/basic/api/qqbot.html#delete-message-reaction","120":"/develop/basic/api/qqbot.html#delete-pin","121":"/develop/basic/api/qqbot.html#delete-schedule","122":"/develop/basic/api/qqbot.html#delete-thread","123":"/develop/basic/api/qqbot.html#delete-user-role","124":"/develop/basic/api/qqbot.html#gateway","125":"/develop/basic/api/qqbot.html#gateway-bot","126":"/develop/basic/api/qqbot.html#get-channel","127":"/develop/basic/api/qqbot.html#get-channel-online-nums","128":"/develop/basic/api/qqbot.html#get-channels","129":"/develop/basic/api/qqbot.html#get-guild","130":"/develop/basic/api/qqbot.html#get-guild-api-permission","131":"/develop/basic/api/qqbot.html#get-guild-member","132":"/develop/basic/api/qqbot.html#get-guild-members","133":"/develop/basic/api/qqbot.html#get-guild-roles","134":"/develop/basic/api/qqbot.html#get-guild-roles-members","135":"/develop/basic/api/qqbot.html#get-guilds","136":"/develop/basic/api/qqbot.html#get-me","137":"/develop/basic/api/qqbot.html#get-me-dms","138":"/develop/basic/api/qqbot.html#get-message","139":"/develop/basic/api/qqbot.html#get-message-reactions","140":"/develop/basic/api/qqbot.html#get-message-setting","141":"/develop/basic/api/qqbot.html#get-pins","142":"/develop/basic/api/qqbot.html#get-role-permission","143":"/develop/basic/api/qqbot.html#get-schedule","144":"/develop/basic/api/qqbot.html#get-schedules","145":"/develop/basic/api/qqbot.html#get-thread","146":"/develop/basic/api/qqbot.html#get-threads","147":"/develop/basic/api/qqbot.html#get-user-avatar","148":"/develop/basic/api/qqbot.html#get-user-permission","149":"/develop/basic/api/qqbot.html#modify-channel","150":"/develop/basic/api/qqbot.html#modify-guild-role","151":"/develop/basic/api/qqbot.html#modify-schedule","152":"/develop/basic/api/qqbot.html#mute-all","153":"/develop/basic/api/qqbot.html#mute-all-lift","154":"/develop/basic/api/qqbot.html#mute-user","155":"/develop/basic/api/qqbot.html#mute-user-lift","156":"/develop/basic/api/qqbot.html#mute-users","157":"/develop/basic/api/qqbot.html#mute-users-lift","158":"/develop/basic/api/qqbot.html#post-message","159":"/develop/basic/api/qqbot.html#set-role-permission","160":"/develop/basic/api/qqbot.html#set-user-permission","161":"/develop/basic/api/qqbot.html#set-user-role","162":"/develop/basic/chainBuild/ark.html#ark-消息","163":"/develop/basic/chainBuild/ark.html#chain-ark","164":"/develop/basic/chainBuild/at.html#at","165":"/develop/basic/chainBuild/at.html#chain-at","166":"/develop/basic/chainBuild/atAll.html#at-所有人","167":"/develop/basic/chainBuild/atAll.html#chain-at-all","168":"/develop/basic/chainBuild/embed.html#embed-消息","169":"/develop/basic/chainBuild/embed.html#chain-embed","170":"/develop/basic/chainBuild/extend.html#原生模板","171":"/develop/basic/chainBuild/extend.html#chain-extend","172":"/develop/basic/chainBuild/extend.html#示例","173":"/develop/basic/chainBuild/extend.html#发送-cq-码","174":"/develop/basic/chainBuild/face.html#emoji-表情","175":"/develop/basic/chainBuild/face.html#chain-face","176":"/develop/basic/chainBuild/forward.html#合并转发消息-beta","177":"/develop/basic/chainBuild/forward.html#添加自定义消息","178":"/develop/basic/chainBuild/forward.html#添加指定-id-的消息","179":"/develop/basic/chainBuild/forward.html#添加嵌套的合并转发消息","180":"/develop/basic/chainBuild/forward.html#发送-撤回","181":"/develop/basic/chainBuild/html.html#html-生成的图片","182":"/develop/basic/chainBuild/html.html#安装-chromium","183":"/develop/basic/chainBuild/html.html#启动时打开-chromium","184":"/develop/basic/chainBuild/html.html#chain-html","185":"/develop/basic/chainBuild/html.html#创建html模板文件","186":"/develop/basic/chainBuild/html.html#通过网站url制图","187":"/develop/basic/chainBuild/image.html#图片","188":"/develop/basic/chainBuild/image.html#chain-image","189":"/develop/basic/chainBuild/markdown.html#markdown-生成的图片","190":"/develop/basic/chainBuild/markdown.html#chain-markdown","191":"/develop/basic/chainBuild/markdown.html#更换渲染-markdown-的-html-文件","192":"/develop/basic/chainBuild/mdTemplate.html#markdown-模版消息","193":"/develop/basic/chainBuild/mdTemplate.html#chain-markdown-template","194":"/develop/basic/chainBuild/mdTemplate.html#按钮消息","195":"/develop/basic/chainBuild/mdTemplate.html#使用按钮模版","196":"/develop/basic/chainBuild/mdTemplate.html#自定义按钮","197":"/develop/basic/chainBuild/tag.html#频道跳转超链接","198":"/develop/basic/chainBuild/tag.html#chain-tag","199":"/develop/basic/chainBuild/text.html#文字","200":"/develop/basic/chainBuild/text.html#chain-text","201":"/develop/basic/chainBuild/text.html#插入表情","202":"/develop/basic/chainBuild/textImage.html#文字生成的图片","203":"/develop/basic/chainBuild/textImage.html#chain-text-image","204":"/develop/basic/chainBuild/textImage.html#调色模板","205":"/develop/basic/chainBuild/textImage.html#渲染图片","206":"/develop/basic/chainBuild/textImage.html#更换字体","207":"/develop/basic/chainBuild/video.html#视频","208":"/develop/basic/chainBuild/video.html#chain-video","209":"/develop/basic/chainBuild/voice.html#语音","210":"/develop/basic/chainBuild/voice.html#chain-voice","211":"/develop/basic/continuityMessage.html#创建连续对话","212":"/develop/basic/continuityMessage.html#message-wait","213":"/develop/basic/continuityMessage.html#force-强制等待","214":"/develop/basic/continuityMessage.html#data-filter-消息过滤器","215":"/develop/basic/continuityMessage.html#关于-wait-方法你需要知道的事","216":"/develop/basic/continuityMessage.html#message-wait-channel","217":"/develop/basic/continuityMessage.html#close-event","218":"/develop/basic/continuityMessage.html#不清除消息队列","219":"/develop/basic/handleEvents.html#事件监听","220":"/develop/basic/handleEvents.html#注册事件响应","221":"/develop/basic/handleEvents.html#event-对象","222":"/develop/basic/handleEvents.html#频道事件","223":"/develop/basic/handleEvents.html#mirai-api-http-事件","224":"/develop/basic/handleEvents.html#go-cqhttp-事件","225":"/develop/basic/handleException.html#异常监听","226":"/develop/basic/handleException.html#指定异常类型","227":"/develop/basic/handleException.html#指定多种异常类型","228":"/develop/basic/messageHandler.html#注册消息响应器","229":"/develop/basic/messageHandler.html#on-message-装饰器","230":"/develop/basic/messageHandler.html#参数列表","231":"/develop/basic/messageHandler.html#功能组","232":"/develop/basic/messageHandler.html#私域模式的前缀校验","233":"/develop/basic/messageHandler.html#接收不包含前缀的消息","234":"/develop/basic/messageHandler.html#接收指定前缀的消息","235":"/develop/basic/messageHandler.html#校验符合正则检查的句式","236":"/develop/basic/messageHandler.html#校验完全匹配的句式","237":"/develop/basic/messageHandler.html#组合多个和多种-keywords","238":"/develop/basic/messageHandler.html#功能优先级","239":"/develop/basic/messageHandler.html#自定义检查","240":"/develop/basic/messageHandler.html#动态输出优先级的值","241":"/develop/basic/messageHandler.html#输出关键值","242":"/develop/basic/messageHandler.html#使功能在私信里可用","243":"/develop/basic/#开始使用","244":"/develop/basic/#安装依赖","245":"/develop/basic/#创建你的第一个-bot","246":"/develop/basic/#创建私域机器人","247":"/develop/basic/#使用前缀触发词唤醒机器人","248":"/develop/basic/#沙箱环境","249":"/develop/basic/multipleAccounts.html#多账号","250":"/develop/basic/multipleAccounts.html#创建多个单独实例","251":"/develop/basic/multipleAccounts.html#创建一个多账号实例","252":"/develop/basic/multipleAccounts.html#多账号热插拔","253":"/develop/basic/multipleAccounts.html#multipleaccounts-append","254":"/develop/basic/recallMessage.html#撤回消息","255":"/develop/basic/recallMessage.html#在-message-对象中撤回","256":"/develop/basic/recallMessage.html#手动撤回","257":"/develop/basic/recallMessage.html#撤回-bot-发送的消息","258":"/develop/basic/recallMessage.html#撤回等待的消息","259":"/develop/basic/recallMessage.html#撤回合并转发的消息","260":"/develop/basic/recvMessage.html#接收消息","261":"/develop/basic/recvMessage.html#message-对象","262":"/develop/basic/recvMessage.html#属性","263":"/develop/basic/recvMessage.html#方法","264":"/develop/basic/sendActiveMessage.html#发送主动消息","265":"/develop/basic/sendActiveMessage.html#amiyabot-send-message","266":"/develop/basic/sendActiveMessage.html#发送一条主动子频道消息","267":"/develop/basic/sendActiveMessage.html#发送一条主动私信-beta","268":"/develop/basic/sendActiveMessage.html#在多账号实例里使用-send-message","269":"/develop/basic/sendActiveMessage.html#在事件响应里使用-send-message","270":"/develop/basic/sendActiveMessage.html#事件监听","271":"/develop/basic/sendActiveMessage.html#异常监听","272":"/develop/basic/sendMessage.html#发送消息","273":"/develop/basic/sendMessage.html#chain-对象","274":"/develop/basic/sendMessage.html#构建消息的方法","275":"/develop/basic/sendMessage.html#普通消息","276":"/develop/basic/sendMessage.html#合并转发消息","277":"/develop/basic/sendMessage.html#空-chain","278":"/develop/basic/sendMessage.html#使用辅助类扩展构建","279":"/develop/basic/statement.html#声明","280":"/develop/basic/testInstance.html#使用测试实例调试","281":"/develop/design.html#设计","282":"/develop/design.html#业务模块","283":"/develop/design.html#插件设计","284":"/develop/design.html#业务设计","285":"/develop/design.html#通讯与数据处理模块","286":"/develop/design.html#适配器","287":"/develop/design.html#运转中心","288":"/develop/design.html#消息处理","289":"/develop/design.html#结语","290":"/develop/#欢迎访问开发文档","291":"/develop/plugin/addDoc.html#添加插件文档","292":"/develop/plugin/addDoc.html#添加一个-markdown-文档","293":"/develop/plugin/addDoc.html#添加使用指引文档","294":"/develop/plugin/addDoc.html#直接在参数内编写","295":"/develop/plugin/amiyaBotPluginInstance.html#amiyabotplugininstance","296":"/develop/plugin/amiyaBotPluginInstance.html#参数","297":"/develop/plugin/amiyaBotPluginInstance.html#使用-jsonschema-对接控制台","298":"/develop/plugin/amiyaBotPluginInstance.html#get-config","299":"/develop/plugin/amiyaBotPluginInstance.html#set-config","300":"/develop/plugin/amiyaBotPluginInstance.html#说明","301":"/develop/plugin/amiyaBotPluginInstance.html#添加插件依赖","302":"/develop/plugin/create.html#创建插件","303":"/develop/plugin/create.html#编写插件程序","304":"/develop/plugin/create.html#插件内静态资源的使用","305":"/develop/plugin/create.html#导出插件的实例","306":"/develop/plugin/debug.html#调试插件","307":"/develop/plugin/debug.html#在测试脚本中调试","308":"/develop/plugin/build.html#打包插件","309":"/develop/plugin/build.html#直接打包","310":"/develop/plugin/build.html#示例","311":"/develop/plugin/build.html#使用脚本打包","312":"/develop/plugin/env.html#准备开发环境","313":"/develop/plugin/env.html#克隆仓库","314":"/develop/plugin/#简要说明","315":"/develop/plugin/jsonSchema.html#jsonschema-解释","316":"/develop/plugin/jsonSchema.html#基本配置","317":"/develop/plugin/jsonSchema.html#文本输入框","318":"/develop/plugin/jsonSchema.html#数字输入框","319":"/develop/plugin/jsonSchema.html#切换按钮","320":"/develop/plugin/jsonSchema.html#下拉选择框","321":"/develop/plugin/jsonSchema.html#日期时间选择器","322":"/develop/plugin/jsonSchema.html#format-选项","323":"/develop/plugin/jsonSchema.html#动态输入-值数组","324":"/develop/plugin/jsonSchema.html#动态输入-对象数组","325":"/develop/plugin/jsonSchema.html#子级对象","326":"/develop/plugin/jsonSchema.html#示例","327":"/develop/plugin/life.html#插件生命周期","328":"/develop/plugin/publish.html#发布到插件商店","329":"/develop/plugin/publish.html#插件密钥","330":"/download.html#下载","331":"/download.html#兔兔-v6","332":"/guide/deploy/advanced/#说明","333":"/guide/deploy/advanced/mysql.html#使用-mysql","334":"/guide/deploy/console/configure.html#配置实例","335":"/guide/deploy/console/configure.html#添加实例","336":"/guide/deploy/console/configure.html#qq频道机器人-官方","337":"/guide/deploy/console/configure.html#qq群机器人-官方","338":"/guide/deploy/console/configure.html#kook机器人","339":"/guide/deploy/console/configure.html#cq-http-qq群机器人","340":"/guide/deploy/console/configure.html#mirai-api-http-qq群机器人","341":"/guide/deploy/console/configure.html#运行实例","342":"/guide/deploy/console/configure.html#配置可控实例","343":"/guide/deploy/console/#连接控制台","344":"/guide/deploy/console/#连接","345":"/guide/deploy/console/#公网-局域网访问","346":"/guide/deploy/console/plugin.html#安装插件","347":"/guide/deploy/console/plugin.html#在插件商店安装插件","348":"/guide/deploy/console/plugin.html#通过插件包自动安装","349":"/guide/deploy/console/plugin.html#管理插件","350":"/guide/deploy/faq/PluginProblem.html#插件常见问题","351":"/guide/deploy/faq/PluginProblem.html#公招图片识别没法用","352":"/guide/deploy/faq/PluginProblem.html#如何给兔兔添加表情","353":"/guide/deploy/faq/PluginProblem.html#代码部署后部分插件无法正常产生图片","354":"/guide/deploy/faq/PluginProblem.html#有时候公招图-专精材料图显示不完整","355":"/guide/deploy/faq/PluginProblem.html#抽卡时出现了-按游戏卡池发布顺序来说-不可能出现的新干员","356":"/guide/deploy/faq/PluginProblem.html#抽卡时出现了黑色的人物条-出现了限定-赠送-肉鸽干员","357":"/guide/deploy/faq/commonProblem.html#常见问题","358":"/guide/deploy/faq/commonProblem.html#我看不懂什么是克隆仓库-代码部署的指令会报错","359":"/guide/deploy/faq/commonProblem.html#使用可执行文件部署时-兔兔的窗口闪现了一下-出现了一小段时间又消失了-闪退","360":"/guide/deploy/faq/commonProblem.html#git-未正确配置","361":"/guide/deploy/faq/commonProblem.html#资源包没能完成下载","362":"/guide/deploy/faq/commonProblem.html#启动时弹窗提示-无法定位程序输入点","363":"/guide/deploy/faq/commonProblem.html#无法进入控制台","364":"/guide/deploy/faq/commonProblem.html#控制台中实例无法连接","365":"/guide/deploy/faq/commonProblem.html#指定bot不存在","366":"/guide/deploy/faq/commonProblem.html#auth-key错误","367":"/guide/deploy/faq/commonProblem.html#cannot-connect-to-mirai-api-http-websocket-server","368":"/guide/deploy/faq/commonProblem.html#got-code-401","369":"/guide/deploy/faq/commonProblem.html#无效参数","370":"/guide/deploy/faq/commonProblem.html#mcl无法正常启动","371":"/guide/deploy/faq/commonProblem.html#系统找不到指定的路径","372":"/guide/deploy/faq/commonProblem.html#当前qq版本太低","373":"/guide/deploy/faq/commonProblem.html#登录存在安全风险","374":"/guide/deploy/faq/commonProblem.html#苹果手机无法安装滑块助手","375":"/guide/deploy/faq/commonProblem.html#a-jni-error-has-occured","376":"/guide/deploy/faq/commonProblem.html#有大段看不懂-完全没有中文信息的红色报错","377":"/guide/deploy/faq/commonProblem.html#address-already-in-use","378":"/guide/deploy/faq/commonProblem.html#代码部署启动时-使用特定命令时会报错","379":"/guide/deploy/faq/commonProblem.html#可执行文件部署启动时会报错","380":"/guide/deploy/faq/commonProblem.html#部署过程看起来一切都很正常-但兔兔就是不理人","381":"/guide/deploy/faq/commonProblem.html#更新兔兔-迁移兔兔时-如何保留原来的数据","382":"/guide/deploy/getStarted.html#开始部署","383":"/guide/deploy/getStarted.html#安装-git","384":"/guide/deploy/getStarted.html#部署","385":"/guide/deploy/getStarted.html#通过可执行文件部署","386":"/guide/deploy/getStarted.html#windows","387":"/guide/deploy/getStarted.html#linux","388":"/guide/deploy/getStarted.html#通过代码部署","389":"/guide/deploy/#简要说明","390":"/guide/deploy/#官方版兔兔","391":"/guide/deploy/maintain/upgrade.html#如何更新","392":"/guide/deploy/maintain/upgrade.html#游戏资源更新","393":"/guide/deploy/maintain/upgrade.html#程序更新","394":"/guide/deploy/maintain/upgrade.html#插件更新","395":"/guide/deploy/yourChoose.html#选择你的运营方","396":"/guide/deploy/yourChoose.html#频道机器人","397":"/guide/deploy/yourChoose.html#kook-机器人","398":"/guide/deploy/yourChoose.html#qq-群机器人","399":"/guide/deploy/yourChoose.html#使用-go-cqhttp","400":"/guide/deploy/yourChoose.html#使用-mirai-api-http","401":"/guide/deploy/yourChoose.html#结语","402":"/guide/#amiyabot-简介","403":"/guide/#介绍","404":"/guide/#她的过去","405":"/guide/#现在","406":"/sponsor.html#赞助","407":"/sponsor.html#特别鸣谢","408":"/sponsor.html#充电鸣谢"},"fieldIds":{"title":0,"titles":1,"text":2},"fieldLength":{"0":[3,1,10],"1":[2,3,39],"2":[2,1,27],"3":[2,2,44],"4":[1,1,12],"5":[2,1,20],"6":[2,1,23],"7":[3,1,20],"8":[2,3,45],"9":[3,1,13],"10":[2,3,43],"11":[3,1,11],"12":[2,3,43],"13":[2,1,7],"14":[1,2,57],"15":[1,2,20],"16":[3,1,3],"17":[1,3,24],"18":[3,1,8],"19":[1,3,58],"20":[1,3,41],"21":[1,4,47],"22":[1,3,11],"23":[4,4,49],"24":[3,1,10],"25":[4,3,33],"26":[3,1,4],"27":[1,3,42],"28":[2,3,17],"29":[2,3,10],"30":[2,3,10],"31":[3,3,62],"32":[1,1,17],"33":[1,1,43],"34":[1,1,28],"35":[1,1,18],"36":[1,1,3],"37":[2,2,21],"38":[3,2,21],"39":[1,1,1],"40":[2,2,19],"41":[3,2,18],"42":[3,2,29],"43":[1,1,8],"44":[1,1,19],"45":[1,1,28],"46":[1,1,21],"47":[3,1,38],"48":[1,3,9],"49":[1,4,17],"50":[1,4,17],"51":[1,4,15],"52":[2,3,17],"53":[2,3,29],"54":[2,3,29],"55":[1,3,34],"56":[1,3,33],"57":[1,3,27],"58":[1,4,33],"59":[1,1,5],"60":[1,1,1],"61":[2,2,70],"62":[1,1,21],"63":[1,1,19],"64":[2,1,14],"65":[1,1,23],"66":[1,1,5],"67":[1,1,16],"68":[2,2,32],"69":[4,2,18],"70":[3,2,25],"71":[3,2,24],"72":[3,2,17],"73":[3,2,19],"74":[1,1,11],"75":[1,1,4],"76":[1,1,24],"77":[1,1,13],"78":[1,1,44],"79":[3,1,46],"80":[4,1,21],"81":[3,1,126],"82":[1,1,22],"83":[1,1,5],"84":[1,1,42],"85":[1,1,90],"86":[1,1,47],"87":[1,1,25],"88":[3,1,41],"89":[1,1,37],"90":[4,1,23],"91":[1,1,50],"92":[1,1,23],"93":[1,1,24],"94":[3,1,36],"95":[1,4,39],"96":[1,1,8],"97":[5,2,31],"98":[1,1,22],"99":[3,1,27],"100":[1,1,10],"101":[1,2,16],"102":[1,2,25],"103":[1,2,42],"104":[2,1,6],"105":[3,1,8],"106":[3,3,12],"107":[2,3,9],"108":[2,3,17],"109":[2,3,24],"110":[5,3,12],"111":[3,3,14],"112":[2,3,20],"113":[2,3,13],"114":[2,3,11],"115":[2,3,8],"116":[3,3,17],"117":[3,3,9],"118":[2,3,13],"119":[3,3,12],"120":[2,3,9],"121":[2,3,9],"122":[2,3,9],"123":[3,3,10],"124":[1,3,5],"125":[2,3,5],"126":[2,3,8],"127":[4,3,8],"128":[2,3,8],"129":[2,3,8],"130":[4,3,8],"131":[3,3,9],"132":[3,3,11],"133":[3,3,8],"134":[4,3,13],"135":[2,3,12],"136":[2,3,5],"137":[3,3,10],"138":[2,3,9],"139":[3,3,16],"140":[3,3,8],"141":[2,3,8],"142":[3,3,9],"143":[2,3,9],"144":[2,3,10],"145":[2,3,9],"146":[2,3,8],"147":[3,3,8],"148":[3,3,9],"149":[2,3,18],"150":[3,3,15],"151":[2,3,21],"152":[2,3,12],"153":[3,3,8],"154":[2,3,13],"155":[3,3,9],"156":[2,3,15],"157":[3,3,11],"158":[2,3,12],"159":[3,3,13],"160":[3,3,13],"161":[3,3,13],"162":[2,1,9],"163":[3,2,42],"164":[1,1,3],"165":[3,1,31],"166":[2,1,5],"167":[4,2,7],"168":[2,1,7],"169":[3,2,28],"170":[1,1,16],"171":[3,1,8],"172":[1,4,28],"173":[3,1,42],"174":[2,1,4],"175":[3,2,13],"176":[2,1,44],"177":[1,2,44],"178":[3,2,15],"179":[1,2,31],"180":[3,2,11],"181":[2,1,36],"182":[2,2,14],"183":[2,2,14],"184":[3,2,34],"185":[1,2,54],"186":[1,2,39],"187":[1,1,2],"188":[3,1,21],"189":[2,1,25],"190":[3,2,29],"191":[5,2,28],"192":[2,1,9],"193":[4,2,36],"194":[1,2,2],"195":[1,3,18],"196":[1,3,59],"197":[1,1,9],"198":[3,1,12],"199":[1,1,2],"200":[3,1,25],"201":[1,1,14],"202":[1,1,4],"203":[4,1,27],"204":[1,5,34],"205":[1,5,66],"206":[1,1,15],"207":[1,1,9],"208":[3,1,25],"209":[1,1,14],"210":[3,1,29],"211":[1,1,6],"212":[3,1,50],"213":[2,4,14],"214":[3,4,38],"215":[3,4,15],"216":[4,1,82],"217":[3,5,20],"218":[1,5,12],"219":[1,1,19],"220":[1,1,24],"221":[2,2,15],"222":[1,1,59],"223":[4,1,34],"224":[3,1,50],"225":[1,1,29],"226":[1,1,16],"227":[1,1,17],"228":[1,1,27],"229":[3,1,27],"230":[1,5,33],"231":[1,1,60],"232":[1,1,10],"233":[1,2,21],"234":[1,2,23],"235":[1,1,24],"236":[1,1,32],"237":[2,1,32],"238":[1,1,41],"239":[1,1,50],"240":[1,2,16],"241":[1,2,26],"242":[1,1,27],"243":[1,1,31],"244":[1,1,4],"245":[2,1,50],"246":[1,1,19],"247":[1,1,13],"248":[1,1,20],"249":[1,1,4],"250":[1,1,37],"251":[1,1,51],"252":[1,1,6],"253":[3,2,32],"254":[1,1,2],"255":[3,1,38],"256":[1,1,25],"257":[3,1,51],"258":[1,4,38],"259":[1,4,2],"260":[1,1,31],"261":[2,1,16],"262":[1,3,75],"263":[1,3,26],"264":[1,1,8],"265":[4,1,32],"266":[1,1,14],"267":[2,1,23],"268":[3,1,13],"269":[3,1,3],"270":[1,4,16],"271":[1,4,18],"272":[1,1,24],"273":[2,1,37],"274":[1,1,1],"275":[1,2,14],"276":[1,2,3],"277":[2,1,13],"278":[1,1,7],"279":[1,1,21],"280":[1,1,52],"281":[1,1,23],"282":[1,1,16],"283":[1,2,11],"284":[1,2,8],"285":[1,1,4],"286":[1,2,16],"287":[1,1,8],"288":[1,2,13],"289":[1,1,7],"290":[1,1,3],"291":[1,1,2],"292":[3,1,23],"293":[1,1,38],"294":[1,1,9],"295":[1,1,40],"296":[1,2,64],"297":[3,1,9],"298":[2,4,27],"299":[2,4,27],"300":[1,4,37],"301":[1,1,41],"302":[1,1,20],"303":[1,1,48],"304":[1,1,27],"305":[1,1,26],"306":[1,1,10],"307":[1,1,43],"308":[1,1,4],"309":[1,1,6],"310":[1,2,34],"311":[1,1,15],"312":[1,1,10],"313":[1,1,31],"314":[1,1,5],"315":[2,1,22],"316":[1,2,33],"317":[1,2,14],"318":[1,2,29],"319":[1,2,14],"320":[1,2,18],"321":[1,2,21],"322":[2,3,33],"323":[2,2,31],"324":[2,2,35],"325":[1,2,19],"326":[1,3,20],"327":[1,1,29],"328":[1,1,7],"329":[1,1,5],"330":[1,1,4],"331":[2,1,10],"332":[1,1,23],"333":[2,1,20],"334":[1,1,5],"335":[1,1,5],"336":[3,1,6],"337":[3,1,6],"338":[1,1,14],"339":[3,1,84],"340":[4,1,47],"341":[1,1,10],"342":[1,1,5],"343":[1,1,52],"344":[1,1,16],"345":[2,1,23],"346":[1,1,2],"347":[1,1,3],"348":[1,1,9],"349":[1,1,11],"350":[1,1,2],"351":[1,1,8],"352":[1,1,8],"353":[1,1,16],"354":[2,1,4],"355":[3,1,3],"356":[4,1,8],"357":[1,1,7],"358":[2,1,9],"359":[5,1,1],"360":[2,6,120],"361":[1,6,11],"362":[3,1,16],"363":[1,1,80],"364":[1,1,42],"365":[1,2,2],"366":[2,2,3],"367":[8,2,8],"368":[3,2,6],"369":[1,2,2],"370":[1,1,3],"371":[1,2,14],"372":[1,2,9],"373":[1,2,13],"374":[1,2,7],"375":[6,2,11],"376":[2,2,5],"377":[4,4,19],"378":[2,1,13],"379":[1,1,6],"380":[2,1,30],"381":[3,1,11],"382":[1,1,23],"383":[2,1,9],"384":[1,1,11],"385":[1,1,19],"386":[1,2,9],"387":[1,2,24],"388":[1,1,107],"389":[1,1,33],"390":[1,1,4],"391":[1,1,1],"392":[1,1,7],"393":[1,1,15],"394":[1,1,3],"395":[1,1,6],"396":[1,1,21],"397":[2,1,5],"398":[2,1,13],"399":[3,1,17],"400":[4,1,25],"401":[1,1,11],"402":[2,1,1],"403":[1,2,10],"404":[2,3,34],"405":[1,3,9],"406":[1,1,19],"407":[1,1,8],"408":[1,1,9]},"averageFieldLength":[1.8141809290953546,1.8068459657701703,21.090464547677264],"storedFields":{"0":{"title":"ComWeChatBot Client Beta","titles":[]},"1":{"title":"连接 ComWeChatBot","titles":["ComWeChatBot Client Beta"]},"2":{"title":"go-cqhttp","titles":[]},"3":{"title":"连接 gocq","titles":["go-cqhttp"]},"4":{"title":"适配器","titles":[]},"5":{"title":"适配器参数 adapter","titles":["适配器"]},"6":{"title":"KOOK 机器人","titles":[]},"7":{"title":"mirai-api-http","titles":[]},"8":{"title":"连接 mah","titles":["mirai-api-http"]},"9":{"title":"OneBot v11 Beta","titles":[]},"10":{"title":"连接 onebot11","titles":["OneBot v11 Beta"]},"11":{"title":"OneBot v12 Beta","titles":[]},"12":{"title":"连接 onebot12","titles":["OneBot v12 Beta"]},"13":{"title":"QQ 频道机器人","titles":[]},"14":{"title":"事件分片","titles":["QQ 频道机器人"]},"15":{"title":"沙箱环境","titles":["QQ 频道机器人"]},"16":{"title":"QQ 全域机器人 Beta","titles":[]},"17":{"title":"创建全域适配器","titles":["QQ 全域机器人 Beta"]},"18":{"title":"QQ 群机器人 Beta","titles":[]},"19":{"title":"在公网下使用","titles":["QQ 群机器人 Beta"]},"20":{"title":"事件分片","titles":["QQ 群机器人 Beta"]},"21":{"title":"修改资源服务配置","titles":["QQ 群机器人 Beta","事件分片"]},"22":{"title":"自定义资源服务","titles":["QQ 群机器人 Beta"]},"23":{"title":"继承 ChainBuilder 并实现相关方法。","titles":["QQ 群机器人 Beta","自定义资源服务"]},"24":{"title":"处理 IO 阻塞的操作","titles":[]},"25":{"title":"run_in_thread_pool","titles":["处理 IO 阻塞的操作"]},"26":{"title":"介入 Chain 构建媒体消息时的操作","titles":[]},"27":{"title":"创建辅助类","titles":["介入 Chain 构建媒体消息时的操作"]},"28":{"title":"get_image","titles":["介入 Chain 构建媒体消息时的操作"]},"29":{"title":"get_voice","titles":["介入 Chain 构建媒体消息时的操作"]},"30":{"title":"get_video","titles":["介入 Chain 构建媒体消息时的操作"]},"31":{"title":"on_page_rendered","titles":["介入 Chain 构建媒体消息时的操作"]},"32":{"title":"数据库支持","titles":[]},"33":{"title":"Sqlite","titles":["数据库支持"]},"34":{"title":"MySQL","titles":["数据库支持"]},"35":{"title":"表结构管理","titles":["数据库支持"]},"36":{"title":"扩展查询","titles":["数据库支持"]},"37":{"title":"batch_insert","titles":["数据库支持","扩展查询"]},"38":{"title":"insert_or_update","titles":["数据库支持","扩展查询"]},"39":{"title":"查询转换工具","titles":["数据库支持"]},"40":{"title":"convert_model","titles":["数据库支持","查询转换工具"]},"41":{"title":"query_to_list","titles":["数据库支持","查询转换工具"]},"42":{"title":"select_for_paginate","titles":["数据库支持","查询转换工具"]},"43":{"title":"事件总线","titles":[]},"44":{"title":"发布事件","titles":["事件总线"]},"45":{"title":"订阅事件","titles":["事件总线"]},"46":{"title":"取消订阅","titles":["事件总线"]},"47":{"title":"发送 HTTP 请求","titles":[]},"48":{"title":"返回值","titles":["发送 HTTP 请求"]},"49":{"title":"json","titles":["发送 HTTP 请求","返回值"]},"50":{"title":"response","titles":["发送 HTTP 请求","返回值"]},"51":{"title":"error","titles":["发送 HTTP 请求","返回值"]},"52":{"title":"GET 请求","titles":["发送 HTTP 请求"]},"53":{"title":"POST 请求","titles":["发送 HTTP 请求"]},"54":{"title":"FORM 表单请求","titles":["发送 HTTP 请求"]},"55":{"title":"文件上传","titles":["发送 HTTP 请求"]},"56":{"title":"自定义请求","titles":["发送 HTTP 请求"]},"57":{"title":"下载文件","titles":["发送 HTTP 请求"]},"58":{"title":"同步下载","titles":["发送 HTTP 请求","下载文件"]},"59":{"title":"HTTP服务器支持","titles":[]},"60":{"title":"创建服务","titles":["HTTP服务器支持"]},"61":{"title":"HttpServer 类","titles":["HTTP服务器支持","创建服务"]},"62":{"title":"自定义路由","titles":["HTTP服务器支持"]},"63":{"title":"请求头密钥","titles":["HTTP服务器支持"]},"64":{"title":"FastApi 扩展","titles":["HTTP服务器支持"]},"65":{"title":"进阶指南","titles":[]},"66":{"title":"生命周期","titles":[]},"67":{"title":"消息生命周期","titles":["生命周期"]},"68":{"title":"message_created","titles":["生命周期","消息生命周期"]},"69":{"title":"message_before_waiter_set","titles":["生命周期","消息生命周期"]},"70":{"title":"message_before_handle","titles":["生命周期","消息生命周期"]},"71":{"title":"message_before_send","titles":["生命周期","消息生命周期"]},"72":{"title":"message_after_send","titles":["生命周期","消息生命周期"]},"73":{"title":"message_after_handle","titles":["生命周期","消息生命周期"]},"74":{"title":"事件生命周期","titles":["生命周期"]},"75":{"title":"加载插件","titles":[]},"76":{"title":"前言","titles":["加载插件"]},"77":{"title":"开发插件","titles":["加载插件"]},"78":{"title":"导入插件实例","titles":["加载插件"]},"79":{"title":"导入 Python 文件","titles":["加载插件"]},"80":{"title":"导入 Python Package 目录","titles":["加载插件"]},"81":{"title":"导入 zip 压缩包","titles":["加载插件"]},"82":{"title":"卸载插件","titles":["加载插件"]},"83":{"title":"日志模块","titles":[]},"84":{"title":"输出日志","titles":["日志模块"]},"85":{"title":"输出异常日志","titles":["日志模块"]},"86":{"title":"创建日志模块","titles":["日志模块"]},"87":{"title":"自定义全局日志模块","titles":["日志模块"]},"88":{"title":"改变 Playwright 启动","titles":[]},"89":{"title":"启动参数","titles":[]},"90":{"title":"在 兔兔-v6 下使用","titles":["启动参数"]},"91":{"title":"定时任务","titles":[]},"92":{"title":"简单使用","titles":["定时任务"]},"93":{"title":"插件开发","titles":["定时任务"]},"94":{"title":"timed_task 装饰器","titles":["定时任务"]},"95":{"title":"自定义执行时机","titles":["定时任务","timed_task 装饰器"]},"96":{"title":"取消定时任务","titles":["定时任务"]},"97":{"title":"bot.remove_timed_task()","titles":["定时任务","取消定时任务"]},"98":{"title":"API","titles":[]},"99":{"title":"引入 API 类以注解变量","titles":["API"]},"100":{"title":"共同的方法","titles":["API"]},"101":{"title":"get","titles":["API","共同的方法"]},"102":{"title":"post","titles":["API","共同的方法"]},"103":{"title":"request","titles":["API","共同的方法"]},"104":{"title":"api 的返回","titles":["API"]},"105":{"title":"QQ 频道 API","titles":[]},"106":{"title":"add_message_reaction","titles":["QQ 频道 API"]},"107":{"title":"add_pin","titles":["QQ 频道 API"]},"108":{"title":"create_announces","titles":["QQ 频道 API"]},"109":{"title":"create_channel","titles":["QQ 频道 API"]},"110":{"title":"create_guild_api_permission_link","titles":["QQ 频道 API"]},"111":{"title":"create_guild_role","titles":["QQ 频道 API"]},"112":{"title":"create_schedule","titles":["QQ 频道 API"]},"113":{"title":"create_thread","titles":["QQ 频道 API"]},"114":{"title":"delete_announces","titles":["QQ 频道 API"]},"115":{"title":"delete_channel","titles":["QQ 频道 API"]},"116":{"title":"delete_guild_member","titles":["QQ 频道 API"]},"117":{"title":"delete_guild_role","titles":["QQ 频道 API"]},"118":{"title":"delete_message","titles":["QQ 频道 API"]},"119":{"title":"delete_message_reaction","titles":["QQ 频道 API"]},"120":{"title":"delete_pin","titles":["QQ 频道 API"]},"121":{"title":"delete_schedule","titles":["QQ 频道 API"]},"122":{"title":"delete_thread","titles":["QQ 频道 API"]},"123":{"title":"delete_user_role","titles":["QQ 频道 API"]},"124":{"title":"gateway","titles":["QQ 频道 API"]},"125":{"title":"gateway_bot","titles":["QQ 频道 API"]},"126":{"title":"get_channel","titles":["QQ 频道 API"]},"127":{"title":"get_channel_online_nums","titles":["QQ 频道 API"]},"128":{"title":"get_channels","titles":["QQ 频道 API"]},"129":{"title":"get_guild","titles":["QQ 频道 API"]},"130":{"title":"get_guild_api_permission","titles":["QQ 频道 API"]},"131":{"title":"get_guild_member","titles":["QQ 频道 API"]},"132":{"title":"get_guild_members","titles":["QQ 频道 API"]},"133":{"title":"get_guild_roles","titles":["QQ 频道 API"]},"134":{"title":"get_guild_roles_members","titles":["QQ 频道 API"]},"135":{"title":"get_guilds","titles":["QQ 频道 API"]},"136":{"title":"get_me","titles":["QQ 频道 API"]},"137":{"title":"get_me_dms","titles":["QQ 频道 API"]},"138":{"title":"get_message","titles":["QQ 频道 API"]},"139":{"title":"get_message_reactions","titles":["QQ 频道 API"]},"140":{"title":"get_message_setting","titles":["QQ 频道 API"]},"141":{"title":"get_pins","titles":["QQ 频道 API"]},"142":{"title":"get_role_permission","titles":["QQ 频道 API"]},"143":{"title":"get_schedule","titles":["QQ 频道 API"]},"144":{"title":"get_schedules","titles":["QQ 频道 API"]},"145":{"title":"get_thread","titles":["QQ 频道 API"]},"146":{"title":"get_threads","titles":["QQ 频道 API"]},"147":{"title":"get_user_avatar","titles":["QQ 频道 API"]},"148":{"title":"get_user_permission","titles":["QQ 频道 API"]},"149":{"title":"modify_channel","titles":["QQ 频道 API"]},"150":{"title":"modify_guild_role","titles":["QQ 频道 API"]},"151":{"title":"modify_schedule","titles":["QQ 频道 API"]},"152":{"title":"mute_all","titles":["QQ 频道 API"]},"153":{"title":"mute_all_lift","titles":["QQ 频道 API"]},"154":{"title":"mute_user","titles":["QQ 频道 API"]},"155":{"title":"mute_user_lift","titles":["QQ 频道 API"]},"156":{"title":"mute_users","titles":["QQ 频道 API"]},"157":{"title":"mute_users_lift","titles":["QQ 频道 API"]},"158":{"title":"post_message","titles":["QQ 频道 API"]},"159":{"title":"set_role_permission","titles":["QQ 频道 API"]},"160":{"title":"set_user_permission","titles":["QQ 频道 API"]},"161":{"title":"set_user_role","titles":["QQ 频道 API"]},"162":{"title":"Ark 消息","titles":[]},"163":{"title":"Chain().ark()","titles":["Ark 消息"]},"164":{"title":"At","titles":[]},"165":{"title":"Chain().at()","titles":["At"]},"166":{"title":"At 所有人","titles":[]},"167":{"title":"Chain().at_all()","titles":["At 所有人"]},"168":{"title":"Embed 消息","titles":[]},"169":{"title":"Chain().embed()","titles":["Embed 消息"]},"170":{"title":"原生模板","titles":[]},"171":{"title":"Chain().extend()","titles":["原生模板"]},"172":{"title":"示例","titles":["原生模板","Chain().extend()"]},"173":{"title":"发送 CQ 码","titles":["原生模板"]},"174":{"title":"emoji 表情","titles":[]},"175":{"title":"Chain().face()","titles":["emoji 表情"]},"176":{"title":"合并转发消息 Beta","titles":[]},"177":{"title":"添加自定义消息","titles":["合并转发消息 Beta"]},"178":{"title":"添加指定 ID 的消息","titles":["合并转发消息 Beta"]},"179":{"title":"添加嵌套的合并转发消息","titles":["合并转发消息 Beta"]},"180":{"title":"发送 & 撤回","titles":["合并转发消息 Beta"]},"181":{"title":"HTML 生成的图片","titles":[]},"182":{"title":"安装 Chromium","titles":["HTML 生成的图片"]},"183":{"title":"启动时打开 Chromium","titles":["HTML 生成的图片"]},"184":{"title":"Chain().html()","titles":["HTML 生成的图片"]},"185":{"title":"创建html模板文件","titles":["HTML 生成的图片"]},"186":{"title":"通过网站URL制图","titles":["HTML 生成的图片"]},"187":{"title":"图片","titles":[]},"188":{"title":"Chain().image()","titles":["图片"]},"189":{"title":"Markdown 生成的图片","titles":[]},"190":{"title":"Chain().markdown()","titles":["Markdown 生成的图片"]},"191":{"title":"更换渲染 Markdown 的 HTML 文件","titles":["Markdown 生成的图片"]},"192":{"title":"Markdown 模版消息","titles":[]},"193":{"title":"Chain().markdown_template()","titles":["Markdown 模版消息"]},"194":{"title":"按钮消息","titles":["Markdown 模版消息"]},"195":{"title":"使用按钮模版","titles":["Markdown 模版消息","按钮消息"]},"196":{"title":"自定义按钮","titles":["Markdown 模版消息","按钮消息"]},"197":{"title":"频道跳转超链接","titles":[]},"198":{"title":"Chain().tag()","titles":["频道跳转超链接"]},"199":{"title":"文字","titles":[]},"200":{"title":"Chain().text()","titles":["文字"]},"201":{"title":"插入表情","titles":["文字"]},"202":{"title":"文字生成的图片","titles":[]},"203":{"title":"Chain().text_image()","titles":["文字生成的图片"]},"204":{"title":"调色模板","titles":["文字生成的图片","Chain().text_image()"]},"205":{"title":"渲染图片","titles":["文字生成的图片","Chain().text_image()"]},"206":{"title":"更换字体","titles":["文字生成的图片"]},"207":{"title":"视频","titles":[]},"208":{"title":"Chain().video()","titles":["视频"]},"209":{"title":"语音","titles":[]},"210":{"title":"Chain().voice()","titles":["语音"]},"211":{"title":"创建连续对话","titles":[]},"212":{"title":"Message.wait()","titles":["创建连续对话"]},"213":{"title":"force 强制等待","titles":["创建连续对话","Message.wait()"]},"214":{"title":"data_filter 消息过滤器","titles":["创建连续对话","Message.wait()"]},"215":{"title":"关于 wait 方法你需要知道的事","titles":["创建连续对话","Message.wait()"]},"216":{"title":"Message.wait_channel()","titles":["创建连续对话"]},"217":{"title":"close_event()","titles":["创建连续对话","Message.wait_channel()"]},"218":{"title":"不清除消息队列","titles":["创建连续对话","Message.wait_channel()"]},"219":{"title":"事件监听","titles":[]},"220":{"title":"注册事件响应","titles":["事件监听"]},"221":{"title":"Event 对象","titles":["事件监听","注册事件响应"]},"222":{"title":"频道事件","titles":["事件监听"]},"223":{"title":"mirai-api-http 事件","titles":["事件监听"]},"224":{"title":"go-cqhttp 事件","titles":["事件监听"]},"225":{"title":"异常监听","titles":[]},"226":{"title":"指定异常类型","titles":["异常监听"]},"227":{"title":"指定多种异常类型","titles":["异常监听"]},"228":{"title":"注册消息响应器","titles":[]},"229":{"title":"on_message 装饰器","titles":["注册消息响应器"]},"230":{"title":"参数列表","titles":["注册消息响应器","on_message 装饰器",null]},"231":{"title":"功能组","titles":["注册消息响应器"]},"232":{"title":"私域模式的前缀校验","titles":["注册消息响应器"]},"233":{"title":"接收不包含前缀的消息","titles":["注册消息响应器","私域模式的前缀校验"]},"234":{"title":"接收指定前缀的消息","titles":["注册消息响应器","私域模式的前缀校验"]},"235":{"title":"校验符合正则检查的句式","titles":["注册消息响应器"]},"236":{"title":"校验完全匹配的句式","titles":["注册消息响应器"]},"237":{"title":"组合多个和多种 keywords","titles":["注册消息响应器"]},"238":{"title":"功能优先级","titles":["注册消息响应器"]},"239":{"title":"自定义检查","titles":["注册消息响应器"]},"240":{"title":"动态输出优先级的值","titles":["注册消息响应器","自定义检查"]},"241":{"title":"输出关键值","titles":["注册消息响应器","自定义检查"]},"242":{"title":"使功能在私信里可用","titles":["注册消息响应器"]},"243":{"title":"开始使用","titles":[]},"244":{"title":"安装依赖","titles":["开始使用"]},"245":{"title":"创建你的第一个 Bot","titles":["开始使用"]},"246":{"title":"创建私域机器人","titles":["开始使用"]},"247":{"title":"使用前缀触发词唤醒机器人","titles":["开始使用"]},"248":{"title":"沙箱环境","titles":["开始使用"]},"249":{"title":"多账号","titles":[]},"250":{"title":"创建多个单独实例","titles":["多账号"]},"251":{"title":"创建一个多账号实例","titles":["多账号"]},"252":{"title":"多账号热插拔","titles":["多账号"]},"253":{"title":"MultipleAccounts.append()","titles":["多账号","多账号热插拔"]},"254":{"title":"撤回消息","titles":[]},"255":{"title":"在 Message 对象中撤回","titles":["撤回消息"]},"256":{"title":"手动撤回","titles":["撤回消息"]},"257":{"title":"撤回 Bot 发送的消息","titles":["撤回消息"]},"258":{"title":"撤回等待的消息","titles":["撤回消息","撤回 Bot 发送的消息"]},"259":{"title":"撤回合并转发的消息","titles":["撤回消息","撤回 Bot 发送的消息"]},"260":{"title":"接收消息","titles":[]},"261":{"title":"Message 对象","titles":["接收消息"]},"262":{"title":"属性","titles":["接收消息","Message 对象"]},"263":{"title":"方法","titles":["接收消息","Message 对象"]},"264":{"title":"发送主动消息","titles":[]},"265":{"title":"AmiyaBot.send_message()","titles":["发送主动消息"]},"266":{"title":"发送一条主动子频道消息","titles":["发送主动消息"]},"267":{"title":"发送一条主动私信 Beta","titles":["发送主动消息"]},"268":{"title":"在多账号实例里使用 send_message","titles":["发送主动消息"]},"269":{"title":"在事件响应里使用 send_message","titles":["发送主动消息"]},"270":{"title":"事件监听","titles":["发送主动消息","在事件响应里使用 send_message"]},"271":{"title":"异常监听","titles":["发送主动消息","在事件响应里使用 send_message"]},"272":{"title":"发送消息","titles":[]},"273":{"title":"Chain 对象","titles":["发送消息"]},"274":{"title":"构建消息的方法","titles":["发送消息"]},"275":{"title":"普通消息","titles":["发送消息","构建消息的方法"]},"276":{"title":"合并转发消息","titles":["发送消息","构建消息的方法"]},"277":{"title":"空 Chain","titles":["发送消息"]},"278":{"title":"使用辅助类扩展构建","titles":["发送消息"]},"279":{"title":"声明","titles":[]},"280":{"title":"使用测试实例调试","titles":[]},"281":{"title":"设计","titles":[]},"282":{"title":"业务模块","titles":["设计"]},"283":{"title":"插件设计","titles":["设计","业务模块"]},"284":{"title":"业务设计","titles":["设计","业务模块"]},"285":{"title":"通讯与数据处理模块","titles":["设计"]},"286":{"title":"适配器","titles":["设计","通讯与数据处理模块"]},"287":{"title":"运转中心","titles":["设计"]},"288":{"title":"消息处理","titles":["设计","运转中心"]},"289":{"title":"结语","titles":["设计"]},"290":{"title":"欢迎访问开发文档","titles":[]},"291":{"title":"添加插件文档","titles":[]},"292":{"title":"添加一个 markdown 文档","titles":["添加插件文档"]},"293":{"title":"添加使用指引文档","titles":["添加插件文档"]},"294":{"title":"直接在参数内编写","titles":["添加插件文档"]},"295":{"title":"AmiyaBotPluginInstance","titles":[]},"296":{"title":"参数","titles":["AmiyaBotPluginInstance",null]},"297":{"title":"使用 JsonSchema 对接控制台","titles":["AmiyaBotPluginInstance"]},"298":{"title":"get_config","titles":["AmiyaBotPluginInstance","使用 JsonSchema 对接控制台"]},"299":{"title":"set_config","titles":["AmiyaBotPluginInstance","使用 JsonSchema 对接控制台"]},"300":{"title":"说明","titles":["AmiyaBotPluginInstance","使用 JsonSchema 对接控制台"]},"301":{"title":"添加插件依赖","titles":["AmiyaBotPluginInstance"]},"302":{"title":"创建插件","titles":[]},"303":{"title":"编写插件程序","titles":["创建插件"]},"304":{"title":"插件内静态资源的使用","titles":["创建插件"]},"305":{"title":"导出插件的实例","titles":["创建插件"]},"306":{"title":"调试插件","titles":[]},"307":{"title":"在测试脚本中调试","titles":["调试插件"]},"308":{"title":"打包插件","titles":[]},"309":{"title":"直接打包","titles":["打包插件"]},"310":{"title":"示例","titles":["打包插件","直接打包"]},"311":{"title":"使用脚本打包","titles":["打包插件"]},"312":{"title":"准备开发环境","titles":[]},"313":{"title":"克隆仓库","titles":["准备开发环境"]},"314":{"title":"简要说明","titles":[]},"315":{"title":"JsonSchema 解释","titles":[]},"316":{"title":"基本配置","titles":["JsonSchema 解释"]},"317":{"title":"文本输入框","titles":["JsonSchema 解释"]},"318":{"title":"数字输入框","titles":["JsonSchema 解释"]},"319":{"title":"切换按钮","titles":["JsonSchema 解释"]},"320":{"title":"下拉选择框","titles":["JsonSchema 解释"]},"321":{"title":"日期时间选择器","titles":["JsonSchema 解释"]},"322":{"title":"format 选项","titles":["JsonSchema 解释","日期时间选择器"]},"323":{"title":"动态输入-值数组","titles":["JsonSchema 解释"]},"324":{"title":"动态输入-对象数组","titles":["JsonSchema 解释"]},"325":{"title":"子级对象","titles":["JsonSchema 解释"]},"326":{"title":"示例","titles":["JsonSchema 解释","子级对象"]},"327":{"title":"插件生命周期","titles":[]},"328":{"title":"发布到插件商店","titles":[]},"329":{"title":"插件密钥","titles":["发布到插件商店"]},"330":{"title":"下载","titles":[]},"331":{"title":"兔兔-v6","titles":["下载"]},"332":{"title":"说明","titles":[]},"333":{"title":"使用 Mysql","titles":[]},"334":{"title":"配置实例","titles":[]},"335":{"title":"添加实例","titles":["配置实例"]},"336":{"title":"QQ频道机器人(官方)","titles":["配置实例"]},"337":{"title":"QQ群机器人(官方)","titles":["配置实例"]},"338":{"title":"KOOK机器人","titles":["配置实例"]},"339":{"title":"CQ-Http QQ群机器人","titles":["配置实例"]},"340":{"title":"Mirai-api-http QQ群机器人","titles":["配置实例"]},"341":{"title":"运行实例","titles":["配置实例"]},"342":{"title":"配置可控实例","titles":["配置实例"]},"343":{"title":"连接控制台","titles":[]},"344":{"title":"连接","titles":["连接控制台"]},"345":{"title":"公网/局域网访问","titles":["连接控制台"]},"346":{"title":"安装插件","titles":[]},"347":{"title":"在插件商店安装插件","titles":["安装插件"]},"348":{"title":"通过插件包自动安装","titles":["安装插件"]},"349":{"title":"管理插件","titles":["安装插件"]},"350":{"title":"插件常见问题","titles":[]},"351":{"title":"公招图片识别没法用","titles":["插件常见问题"]},"352":{"title":"如何给兔兔添加表情","titles":["插件常见问题"]},"353":{"title":"代码部署后部分插件无法正常产生图片","titles":["插件常见问题"]},"354":{"title":"有时候公招图/专精材料图显示不完整","titles":["插件常见问题"]},"355":{"title":"抽卡时出现了(按游戏卡池发布顺序来说)不可能出现的新干员","titles":["插件常见问题"]},"356":{"title":"抽卡时出现了黑色的人物条/出现了限定/赠送/肉鸽干员","titles":["插件常见问题"]},"357":{"title":"常见问题","titles":[]},"358":{"title":"我看不懂什么是克隆仓库/代码部署的指令会报错","titles":["常见问题"]},"359":{"title":"使用可执行文件部署时,兔兔的窗口闪现了一下/出现了一小段时间又消失了(闪退)","titles":["常见问题"]},"360":{"title":"git 未正确配置","titles":["常见问题","使用可执行文件部署时,兔兔的窗口闪现了一下/出现了一小段时间又消失了(闪退)"]},"361":{"title":"资源包没能完成下载","titles":["常见问题","使用可执行文件部署时,兔兔的窗口闪现了一下/出现了一小段时间又消失了(闪退)"]},"362":{"title":"启动时弹窗提示“无法定位程序输入点...”","titles":["常见问题"]},"363":{"title":"无法进入控制台","titles":["常见问题"]},"364":{"title":"控制台中实例无法连接","titles":["常见问题"]},"365":{"title":"指定bot不存在","titles":["常见问题","控制台中实例无法连接"]},"366":{"title":"Auth Key错误","titles":["常见问题","控制台中实例无法连接"]},"367":{"title":"Cannot connect to mirai-api-http websocket server","titles":["常见问题","控制台中实例无法连接"]},"368":{"title":"Got code 401","titles":["常见问题","控制台中实例无法连接"]},"369":{"title":"无效参数","titles":["常见问题","控制台中实例无法连接"]},"370":{"title":"mcl无法正常启动","titles":["常见问题"]},"371":{"title":"系统找不到指定的路径","titles":["常见问题","mcl无法正常启动"]},"372":{"title":"当前qq版本太低","titles":["常见问题","mcl无法正常启动"]},"373":{"title":"登录存在安全风险","titles":["常见问题","mcl无法正常启动"]},"374":{"title":"苹果手机无法安装滑块助手","titles":["常见问题","mcl无法正常启动"]},"375":{"title":"A JNI error has occured.","titles":["常见问题","mcl无法正常启动"]},"376":{"title":"有大段看不懂/完全没有中文信息的红色报错","titles":["常见问题","mcl无法正常启动"]},"377":{"title":"Address already in use","titles":["常见问题","mcl无法正常启动","有大段看不懂/完全没有中文信息的红色报错"]},"378":{"title":"代码部署启动时/使用特定命令时会报错","titles":["常见问题"]},"379":{"title":"可执行文件部署启动时会报错","titles":["常见问题"]},"380":{"title":"部署过程看起来一切都很正常,但兔兔就是不理人","titles":["常见问题"]},"381":{"title":"更新兔兔/迁移兔兔时,如何保留原来的数据","titles":["常见问题"]},"382":{"title":"开始部署","titles":[]},"383":{"title":"安装 Git","titles":["开始部署"]},"384":{"title":"部署","titles":["开始部署"]},"385":{"title":"通过可执行文件部署","titles":["开始部署"]},"386":{"title":"Windows","titles":["开始部署","通过可执行文件部署"]},"387":{"title":"Linux","titles":["开始部署","通过可执行文件部署"]},"388":{"title":"通过代码部署","titles":["开始部署"]},"389":{"title":"简要说明","titles":[]},"390":{"title":"官方版兔兔","titles":["简要说明"]},"391":{"title":"如何更新","titles":[]},"392":{"title":"游戏资源更新","titles":["如何更新"]},"393":{"title":"程序更新","titles":["如何更新"]},"394":{"title":"插件更新","titles":["如何更新"]},"395":{"title":"选择你的运营方","titles":[]},"396":{"title":"频道机器人","titles":["选择你的运营方"]},"397":{"title":"KOOK 机器人","titles":["选择你的运营方"]},"398":{"title":"QQ 群机器人","titles":["选择你的运营方"]},"399":{"title":"使用 go-cqhttp","titles":["选择你的运营方"]},"400":{"title":"使用 mirai-api-http","titles":["选择你的运营方"]},"401":{"title":"结语","titles":["选择你的运营方"]},"402":{"title":"AmiyaBot 简介","titles":[]},"403":{"title":"介绍","titles":["AmiyaBot 简介"]},"404":{"title":"她的过去...","titles":["AmiyaBot 简介","介绍"]},"405":{"title":"现在","titles":["AmiyaBot 简介","介绍"]},"406":{"title":"赞助","titles":[]},"407":{"title":"特别鸣谢","titles":["赞助"]},"408":{"title":"充电鸣谢","titles":["赞助"]}},"dirtCount":0,"index":[["❤️",{"2":{"408":1}}],["秉承初衷",{"2":{"408":1}}],["感谢有你",{"2":{"408":1}}],["感谢各位对",{"2":{"407":1}}],["充电鸣谢",{"0":{"408":1}}],["🌹",{"2":{"407":1}}],["🎉🎉🎉",{"2":{"390":1}}],["🎉",{"2":{"349":2}}],["期待未来我们能携手创造更多可能",{"2":{"407":1}}],["社区的繁荣",{"2":{"407":1}}],["社区做出的贡献",{"2":{"407":1}}],["特别鸣谢",{"0":{"407":1}}],["特别的",{"2":{"343":1}}],["⭐",{"2":{"406":1}}],["恳请你在",{"2":{"406":1}}],["想必",{"2":{"406":1}}],["想必你对其应有了一定的了解",{"2":{"76":1}}],["赞助",{"0":{"406":1},"1":{"407":1,"408":1}}],["加入我们的",{"2":{"405":1}}],["加载失败",{"2":{"81":1}}],["加载插件",{"0":{"75":1},"1":{"76":1,"77":1,"78":1,"79":1,"80":1,"81":1,"82":1}}],["加载插件以及额外支持的数据库",{"2":{"65":1}}],["剥离出其核心部分成为框架",{"2":{"404":1}}],["终止服务",{"2":{"404":1}}],["决定迁移至",{"2":{"404":1}}],["免费为用户提供服务",{"2":{"404":1}}],["跌跌撞撞到现在",{"2":{"404":1}}],["个里程碑版本",{"2":{"404":1}}],["至本框架发布时已迭代了",{"2":{"404":1}}],["民间",{"2":{"404":1}}],["诞生于2019年",{"2":{"404":1}}],["她的过去",{"0":{"404":1}}],["务必部署成功再往下继续",{"2":{"401":1}}],["非常重要",{"2":{"401":1}}],["非必须",{"2":{"388":1}}],["官网",{"2":{"399":1}}],["官方群",{"2":{"405":1}}],["官方全域机器人正式发布",{"2":{"404":1}}],["官方api",{"2":{"403":1}}],["官方频道",{"2":{"393":1,"396":1,"405":1}}],["官方版兔兔",{"0":{"390":1}}],["官方支持列表",{"2":{"353":1}}],["官方",{"0":{"336":1,"337":1}}],["官方文档示例的",{"2":{"222":1}}],["第三方技术目前支持",{"2":{"398":1}}],["第一个函数更早注册完毕",{"2":{"238":1}}],["第一个函数会首先通过校验并输出",{"2":{"238":1}}],["框架开发自己的机器人并发布",{"2":{"396":1}}],["框架结构可分为业务模块",{"2":{"281":1}}],["点上一颗小小的️",{"2":{"406":1}}],["点开资料卡添加到自己的频道里",{"2":{"396":1}}],["点击查看代码",{"2":{"388":1}}],["点击下载",{"2":{"383":1}}],["点击",{"2":{"328":1,"341":1,"344":1}}],["点击可以跳转至子频道",{"2":{"197":1}}],["很遗憾地告诉你",{"2":{"396":1}}],["另一种则是由第三方技术提供支持的qq群机器人",{"2":{"395":1}}],["程序到你原来的目录下并启动新的程序就可以了",{"2":{"393":1}}],["程序更新",{"0":{"393":1}}],["游戏资源更新",{"0":{"392":1}}],["明日方舟",{"2":{"389":2,"404":1}}],["成功后可以进入下一节",{"2":{"388":1}}],["成功进入后即可开始配置",{"2":{"344":1}}],["~",{"2":{"388":1}}],["两种方式其一",{"2":{"384":1}}],["两个解决方案",{"2":{"375":1}}],["便可以不用迁移数据库文件",{"2":{"381":1}}],["整个覆盖至新兔兔的根目录下即可",{"2":{"381":1}}],["迁移兔兔时",{"0":{"381":1}}],["产生应用卡住不动的表象",{"2":{"380":1}}],["产生异常的数据",{"2":{"225":1}}],["划重点",{"2":{"380":1}}],["部署完第三方服务",{"2":{"401":1}}],["部署用户的指引",{"2":{"389":1}}],["部署难度低",{"2":{"384":1}}],["部署",{"0":{"384":1},"2":{"400":2}}],["部署过程看起来一切都很正常",{"0":{"380":1}}],["部分系统由于版本过低",{"2":{"388":1}}],["部分插件依赖本地的",{"2":{"383":1}}],["部分插件可能存在需要配置的信息",{"2":{"349":1}}],["部分内核的浏览器可能会拦截公网对私网不安全的访问请求",{"2":{"363":1}}],["部分功能可能无法或者不会在控制台中实现",{"2":{"332":1}}],["部分",{"2":{"236":1}}],["依旧坚持初心",{"2":{"405":1}}],["依旧坚持开源",{"2":{"404":1}}],["依赖",{"2":{"378":1}}],["依然会无视前缀检查",{"2":{"237":1}}],["既然你是代码部署的",{"2":{"378":1}}],["苹果手机无法安装滑块助手",{"0":{"374":1}}],["外别无他法",{"2":{"373":1}}],["哥",{"2":{"373":1}}],["挺玄学的",{"2":{"373":1}}],["登录存在安全风险",{"0":{"373":1}}],["登录用户名",{"2":{"333":1}}],["删除bots文件夹下所有内容",{"2":{"372":1}}],["删除实例",{"2":{"253":1}}],["升级mcl本体",{"2":{"372":1}}],["系统推荐使用可执行文件部署",{"2":{"384":1}}],["系统找不到指定的路径",{"0":{"371":1}}],["系统官方支持",{"2":{"181":1,"382":1}}],["常见错误为看错并填写错端口",{"2":{"367":1}}],["常见问题",{"0":{"357":1},"1":{"358":1,"359":1,"360":1,"361":1,"362":1,"363":1,"364":1,"365":1,"366":1,"367":1,"368":1,"369":1,"370":1,"371":1,"372":1,"373":1,"374":1,"375":1,"376":1,"377":1,"378":1,"379":1,"380":1,"381":1}}],["填写127",{"2":{"364":1}}],["填写配置的",{"2":{"339":1}}],["协议为tcp",{"2":{"363":1}}],["协议支持的高效率机器人库",{"2":{"7":1}}],["首先你需要参照上面的指示将",{"2":{"363":1}}],["首先需要知道的是",{"2":{"228":1}}],["打赏请前往爱发电主页",{"2":{"408":1}}],["打开",{"2":{"363":1}}],["打包插件",{"0":{"308":1},"1":{"309":1,"310":1,"311":1}}],["检查报错",{"2":{"380":1}}],["检查是否有消息推送的提示",{"2":{"380":1}}],["检查是否有安装插件",{"2":{"380":1}}],["检查mirai",{"2":{"367":1}}],["检查mirai是否启动",{"2":{"367":1}}],["检查mirai本体配置中authkey的值与控制台填写的是否一致",{"2":{"366":1}}],["检查浏览器顶端的地址栏",{"2":{"363":1}}],["检查结果",{"2":{"239":1}}],["资源的解包需要一定时间",{"2":{"392":1}}],["资源包没能完成下载",{"0":{"361":1}}],["资源服务监听端口",{"2":{"21":1}}],["资源服务监听地址",{"2":{"21":1}}],["资源服务也会一同启动",{"2":{"19":1}}],["尝试将",{"2":{"360":1}}],["|",{"2":{"360":5}}],["再次重复上述操作",{"2":{"360":1}}],["再次从消息接收开始",{"2":{"67":1}}],["未正确安装导致的",{"2":{"360":1}}],["未正确配置",{"0":{"360":1}}],["输入",{"2":{"360":1}}],["输出关键值",{"0":{"241":1}}],["输出异常日志",{"0":{"85":1}}],["输出的日志会储存在",{"2":{"84":1}}],["输出日志",{"0":{"84":1}}],["闪退",{"0":{"359":1},"1":{"360":1,"361":1}}],["出现了一小段时间又消失了",{"0":{"359":1},"1":{"360":1,"361":1}}],["出现了限定",{"0":{"356":1}}],["执行完即可进入下一步骤",{"2":{"358":1}}],["执行一次后取消任务",{"2":{"97":1}}],["任选其一进行即可",{"2":{"358":1}}],["任何需要发送消息的时候",{"2":{"228":1,"273":1}}],["任何时候",{"2":{"228":1}}],["修饰",{"2":{"357":1}}],["修改配置中的",{"2":{"399":1}}],["修改为",{"2":{"363":2}}],["修改完后重启",{"2":{"339":1}}],["修改如下位置的代码",{"2":{"307":1}}],["修改浏览器属性",{"2":{"88":1}}],["修改",{"2":{"68":1}}],["修改默认的资源服务配置",{"2":{"21":1}}],["修改资源服务配置",{"0":{"21":1}}],["晓月君",{"2":{"357":1}}],["黑色的条一般是各个预备干员",{"2":{"356":1}}],["肉鸽干员",{"0":{"356":1}}],["赠送",{"0":{"356":1}}],["复刻的卡池中显然会出现任何非限定或特殊干员",{"2":{"355":1}}],["抽卡时出现了黑色的人物条",{"0":{"356":1}}],["抽卡时出现了",{"0":{"355":1}}],["偶现该情况是正常现象",{"2":{"354":1}}],["专精材料图显示不完整",{"0":{"354":1}}],["快去体验兔兔吧",{"2":{"349":1}}],["到这里你已经部署完成了",{"2":{"349":1}}],["恭喜你",{"2":{"349":1}}],["现在",{"0":{"405":1},"2":{"349":1,"390":1}}],["管理插件",{"0":{"349":1}}],["反向代理加密连接的博客",{"2":{"345":1}}],["反之则不必",{"2":{"300":1}}],["局域网访问",{"0":{"345":1}}],["公域机器人",{"2":{"396":1}}],["公招图片识别功能需要申请并配置相应的百度智能云",{"2":{"351":1}}],["公招图片识别没法用",{"0":{"351":1}}],["公网",{"0":{"345":1}}],["公共功能",{"2":{"251":1}}],["括起",{"2":{"343":1}}],["规范定义其为整数类型",{"2":{"343":1}}],["规范编辑",{"2":{"315":1}}],["由用户延续原群聊机器人",{"2":{"404":1}}],["由您自行承担",{"2":{"343":2,"345":1}}],["由于作者仅涉足过mirai",{"2":{"364":1}}],["由于",{"2":{"343":1}}],["由于本部分的特殊性",{"2":{"332":1}}],["由于它属于顶级模块",{"2":{"81":1}}],["危险",{"2":{"343":1,"345":1}}],["保存并启动",{"2":{"341":1}}],["令牌桶大小",{"2":{"339":1}}],["令牌回复频率",{"2":{"339":1}}],["强烈推荐在公网的服务器设置",{"2":{"339":1}}],["强制等待",{"0":{"213":1}}],["找到",{"2":{"339":1,"340":1}}],["没有配置则不需要填写",{"2":{"339":1}}],["没有返回执行",{"2":{"258":1}}],["推荐修改为火狐",{"2":{"388":1}}],["推荐升级",{"2":{"362":1}}],["推荐使用nginx反代服务提供更高的安全性",{"2":{"363":1}}],["推荐使用",{"2":{"338":1,"388":1}}],["推荐你使用自己的更优的数据库解决方案",{"2":{"32":1}}],["指过两天再试就好了",{"2":{"373":1}}],["指的是机器人的账号",{"2":{"334":1}}],["指定bot不存在",{"0":{"365":1}}],["指定多种异常类型",{"0":{"227":1}}],["指定异常类型",{"0":{"226":1}}],["甚至可能随时删除或停止维护这些文档",{"2":{"332":1}}],["甚至是html模板",{"2":{"273":1}}],["高级使用",{"2":{"332":1}}],["届时对应的文档也会从这里删去",{"2":{"332":1}}],["备注",{"2":{"331":1,"385":1}}],["继续作为新的子级对象",{"2":{"325":1}}],["继承了",{"2":{"295":1}}],["继承",{"0":{"23":1},"2":{"27":1,"33":1}}],["根据你的设备系统或习惯",{"2":{"384":1}}],["根据上文",{"2":{"324":1,"325":1}}],["根目录下的",{"2":{"307":1}}],["值理论上可以是1024~65535中的任何一个数字",{"2":{"377":1}}],["值类型",{"2":{"323":1}}],["值数组",{"0":{"323":1}}],["切换按钮",{"0":{"319":1},"2":{"324":1}}],["切勿同时启动",{"2":{"14":1,"20":1}}],["数组",{"2":{"324":1}}],["数字输入框",{"0":{"318":1},"2":{"324":1}}],["数据为数组类型",{"2":{"322":1}}],["数据填充",{"2":{"296":1}}],["数据覆盖",{"2":{"296":1}}],["数据处理模块",{"2":{"281":1}}],["数据结构",{"2":{"224":1}}],["数据可被",{"2":{"184":1}}],["数据",{"2":{"163":1,"193":1,"296":1}}],["数据列表",{"2":{"37":1}}],["数据库密码",{"2":{"333":1}}],["数据库端口",{"2":{"333":1}}],["数据库地址",{"2":{"333":1}}],["数据库文件",{"2":{"33":1}}],["数据库",{"2":{"33":1,"34":1}}],["数据库的",{"2":{"32":1}}],["数据库支持",{"0":{"32":1},"1":{"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1,"42":1}}],["鼠标移动到页面的问号图标时显示的内容",{"2":{"316":1}}],["敬请期待",{"2":{"315":1}}],["暂未支持前端校验",{"2":{"315":1}}],["暂不支持更新字段类型",{"2":{"35":1}}],["$schema",{"2":{"315":1}}],["版本不兼容",{"2":{"362":1}}],["版本无法运行兔兔",{"2":{"362":1}}],["版本",{"2":{"362":1,"404":1}}],["版本的",{"2":{"315":1}}],["版本号",{"2":{"301":1}}],["解释",{"0":{"315":1},"1":{"316":1,"317":1,"318":1,"319":1,"320":1,"321":1,"322":1,"323":1,"324":1,"325":1,"326":1}}],["解决上述问题",{"2":{"81":1}}],["克隆",{"2":{"313":1}}],["克隆仓库",{"0":{"313":1},"2":{"388":1}}],["准备开发环境",{"0":{"312":1},"1":{"313":1}}],["脚本打包尚处于试验阶段",{"2":{"311":1}}],["优先使用插件内的",{"2":{"310":1}}],["优先级允许为",{"2":{"238":1}}],["优先级",{"2":{"212":1,"216":1,"239":2}}],["被执行时",{"2":{"310":1}}],["环境内找到",{"2":{"310":1}}],["显式导入插件开发目录",{"2":{"307":1}}],["显然这不够效率",{"2":{"306":1}}],["即启动成功",{"2":{"341":1}}],["即使",{"2":{"305":1}}],["即可更新干员数据",{"2":{"356":1}}],["即可更改为",{"2":{"34":1}}],["即可让服务通过本机",{"2":{"345":1}}],["即可自动打包",{"2":{"311":1}}],["即可模拟测试对话",{"2":{"280":1}}],["即可拼接出内容丰富的消息",{"2":{"275":1}}],["即可撤回发送的消息",{"2":{"257":1}}],["即可以指定动态优先级",{"2":{"240":1}}],["即可达到效果",{"2":{"236":1}}],["即可监听到准确的戳一戳事件",{"2":{"224":1}}],["即可",{"2":{"223":1,"313":1,"338":1}}],["即可完成合并消息嵌套",{"2":{"179":1}}],["即可看到生成了如下两个接口",{"2":{"61":1}}],["即可创建可在",{"2":{"18":1}}],["命名为",{"2":{"305":1}}],["命令行执行以下命令安装",{"2":{"182":1}}],["命令执行了",{"2":{"81":1}}],["导致mirai这一步就收不到消息",{"2":{"380":1}}],["导致不可预测的后果",{"2":{"305":1}}],["导出插件的实例",{"0":{"305":1}}],["导入浏览器启动配置类",{"2":{"388":1}}],["导入插件",{"2":{"307":1}}],["导入插件实例",{"0":{"78":1}}],["导入转换为",{"2":{"81":1}}],["导入时",{"2":{"81":1}}],["导入这个插件",{"2":{"81":1}}],["导入",{"0":{"79":1,"80":1,"81":1}}],["去编写你的插件功能",{"2":{"303":1}}],["去字符处理",{"2":{"262":1}}],["编写插件程序",{"0":{"303":1}}],["才会进行自身的安装",{"2":{"301":1}}],["才允许访问",{"2":{"63":1}}],["您可能无法正确执行该操作",{"2":{"353":1}}],["您的服务将面临极大的安全风险",{"2":{"345":1}}],["您的服务将可能面临较大的安全风险",{"2":{"343":1}}],["您的服务将可能面临极大的安全风险",{"2":{"343":1}}],["您的",{"2":{"343":1}}],["您使用过期文档导致生产事故等的情况我们不负任何责任",{"2":{"332":1}}],["您需要在您的插件实例的构造函数",{"2":{"300":1}}],["您想要对用户的配置进行校验",{"2":{"300":1}}],["您想要使用下拉列表框",{"2":{"300":1}}],["界面可以新建频道配置",{"2":{"300":1}}],["界面会生成下拉列表框",{"2":{"300":1}}],["元素时",{"2":{"300":1}}],["说明",{"0":{"300":1,"332":1}}],["说明和参数释义",{"2":{"105":1}}],["写入配置",{"2":{"299":1}}],["写出更美观的页面",{"2":{"185":1}}],["读取一个指定名称的配置项",{"2":{"298":1}}],["读取了此压缩包",{"2":{"81":1}}],["介绍",{"0":{"403":1},"1":{"404":1,"405":1}}],["介绍文档",{"2":{"297":1}}],["介入生命周期",{"2":{"65":1}}],["介入",{"0":{"26":1},"1":{"27":1,"28":1,"29":1,"30":1,"31":1}}],["介入媒体消息的构建过程",{"2":{"23":1,"278":1}}],["777",{"2":{"387":1}}],["7",{"2":{"296":1}}],["720",{"2":{"89":1,"184":1}}],["旧配置项失效的天数",{"2":{"296":1}}],["项目是值得的",{"2":{"408":1}}],["项目内克隆插件开发仓库",{"2":{"313":1}}],["项目内",{"2":{"312":1}}],["项目以及插件仓库的代码",{"2":{"312":1}}],["项目里导入",{"2":{"295":1}}],["项目中的对插件类",{"2":{"295":1}}],["能够获得更多的能力",{"2":{"295":1}}],["除非你的插件文档只有少量文本",{"2":{"294":1}}],["除了以上内置的消息类型外",{"2":{"170":1}}],["除了",{"2":{"4":1}}],["向其展示",{"2":{"293":1}}],["查看兔兔窗口",{"2":{"380":1}}],["查看mirai窗口",{"2":{"380":1}}],["查看并在实例配置填写你创建的机器人应用的",{"2":{"338":1}}],["查看并在实例配置填写你注册的群机器人信息",{"2":{"337":1}}],["查看并在实例配置填写你注册的频道机器人信息",{"2":{"336":1}}],["查看功能指引",{"2":{"293":2}}],["查询对象",{"2":{"40":1,"41":1,"42":1}}],["查询结果",{"2":{"40":1,"41":1,"42":1}}],["查询转换工具",{"0":{"39":1},"1":{"40":1,"41":1,"42":1}}],["若是在此处修改了端口值",{"2":{"377":1}}],["若是勾选了",{"2":{"364":1}}],["若你访问控制台的设备与运行兔兔的设备不是同一台设备",{"2":{"363":1}}],["若你有意或无意地导致了",{"2":{"361":1}}],["若情况允许",{"2":{"362":1}}],["若使用的操作系统不在",{"2":{"353":1}}],["若使用了",{"2":{"293":1}}],["若配置了对应的",{"2":{"321":1}}],["若无法通过上述手段将第三方包添加进插件包",{"2":{"310":1}}],["若用户超过最长等待时间未回复",{"2":{"215":1}}],["允许直接使用",{"2":{"292":1}}],["允许功能在私信里触发",{"2":{"242":1}}],["└──",{"2":{"292":1,"302":1,"304":1,"310":1}}],["欢迎访问开发文档",{"0":{"290":1}}],["结语",{"0":{"289":1,"401":1}}],["工厂对象可以介入这些周期影响消息处理的分配与执行结果",{"2":{"288":1}}],["工厂对象是业务模块与运转中心的桥梁",{"2":{"284":1}}],["选择其中一个进行部署即可",{"2":{"398":1}}],["选择你的运营方",{"0":{"395":1},"1":{"396":1,"397":1,"398":1,"399":1,"400":1,"401":1}}],["选择安装即可",{"2":{"375":1}}],["选择安装你需要的功能插件",{"2":{"346":1}}],["选择适配器",{"2":{"286":1}}],["选项",{"0":{"322":1}}],["选取最高优先级的执行",{"2":{"288":1}}],["最好的方法其实是将mcl",{"2":{"371":1}}],["最终提供给运转中心调用",{"2":{"284":1}}],["最长等待时间",{"2":{"212":1,"216":1}}],["业务函数会被工厂对象收集并封装",{"2":{"284":1}}],["业务设计",{"0":{"284":1}}],["业务模块通过各种装饰器来定义业务逻辑以及规则",{"2":{"284":1}}],["业务模块由插件",{"2":{"282":1}}],["业务模块",{"0":{"282":1},"1":{"283":1,"284":1}}],["防止这种关系的出现",{"2":{"283":1}}],["理论上账号实例之间也能互相嵌套",{"2":{"283":1}}],["理解这一原理",{"2":{"76":1}}],["顶级对象会组合所有子级对象的属性提供给运转中心",{"2":{"282":1}}],["运转中心会将消息归类并分发到不同的处理模块",{"2":{"287":1}}],["运转中心包含事件处理",{"2":{"287":1}}],["运转中心",{"0":{"287":1},"1":{"288":1}}],["运转中心获取到的源数据格式都必须是一致的",{"2":{"286":1}}],["运转中心在访问这些对象时",{"2":{"282":1}}],["运转中心无法访问插件",{"2":{"282":1}}],["运行本项目代码",{"2":{"388":1}}],["运行脚本",{"2":{"311":1}}],["运行",{"2":{"307":1,"386":1,"387":1}}],["运行实例",{"0":{"341":1},"2":{"280":1,"341":1}}],["运行代码",{"2":{"61":1,"245":1,"388":1}}],["组件",{"2":{"283":1}}],["组件设计",{"2":{"283":1}}],["组成",{"2":{"282":1}}],["组合中包含",{"2":{"237":1}}],["组合多个和多种",{"0":{"237":1}}],["账号实例也可以脱离运转中心的调控随时调用适配器与运营方服务通讯",{"2":{"286":1}}],["账号实例里面有一个重要参数",{"2":{"286":1}}],["账号实例图解",{"2":{"284":1}}],["账号实例和多账号实例是同质的",{"2":{"282":1}}],["账号实例",{"2":{"282":1}}],["存放",{"2":{"325":1}}],["存储模块以及运转中心的日志等模块",{"2":{"289":1}}],["存储模块和运转中心五个组成部分",{"2":{"281":1}}],["存在多个此钩子时",{"2":{"68":1,"70":1,"71":1}}],["旨在帮助你更高效地编写业务逻辑",{"2":{"281":1}}],["旨在统一不同聊天平台上的机器人应用开发接口",{"2":{"11":1}}],["设定浏览器属性",{"2":{"388":1}}],["设计",{"0":{"281":1},"1":{"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1}}],["设置为",{"2":{"363":1}}],["设置前缀触发词后",{"2":{"232":1}}],["设置",{"2":{"200":1}}],["设置参数",{"2":{"186":1,"242":2}}],["设置需要的时间",{"2":{"186":1,"190":1}}],["变量的存在",{"2":{"279":1}}],["变量名是必须的",{"2":{"79":1}}],["声明",{"0":{"279":1}}],["本章接下来的文档",{"2":{"389":1}}],["本章收录了用户在部署",{"2":{"357":1}}],["本章收录了用户在使用官方插件时向我们提问较多的问题",{"2":{"350":1}}],["本框架原名为",{"2":{"389":1}}],["本框架仅对其做了适度的封装",{"2":{"289":1}}],["本处仅将提供mirai相关问题的解决思路",{"2":{"364":1}}],["本部分文档可能只是对控制台暂未支持的部分的一种补充",{"2":{"332":1}}],["本文档将讲述如何为",{"2":{"314":1}}],["本文称之为",{"2":{"277":1}}],["本篇介绍如何使用",{"2":{"315":1}}],["本篇将会讲解",{"2":{"75":1}}],["本篇章将会深入讲解",{"2":{"65":1}}],["空",{"0":{"277":1},"2":{"277":2}}],["减少消息的请求数量",{"2":{"275":1}}],["用于对接由机器人运营方提供的服务",{"2":{"285":1}}],["用于构建复杂的消息结构",{"2":{"275":1}}],["用户id",{"2":{"265":1,"267":1}}],["用户加入频道的时间",{"2":{"262":1}}],["用户头像的",{"2":{"262":1}}],["用户的",{"2":{"177":1}}],["用户昵称",{"2":{"177":1,"262":1}}],["用户",{"2":{"177":1,"262":1,"273":1}}],["用户后换行",{"2":{"165":1}}],["普通消息",{"0":{"275":1}}],["辅助构建实例",{"2":{"273":1}}],["引用消息",{"2":{"273":1}}],["引入相应的",{"2":{"99":1}}],["引入数据库模块",{"2":{"33":1}}],["引入",{"0":{"99":1},"2":{"21":1}}],["均可发送消息",{"2":{"272":1}}],["得到",{"2":{"265":1}}],["主动消息需要频道设置允许机器人推送",{"2":{"264":1}}],["主动消息限制",{"2":{"264":1}}],["列表",{"2":{"262":2}}],["适用于群聊适配器",{"2":{"262":1}}],["适配sqlite和mysql",{"2":{"38":1}}],["适配器类型应该是mirai",{"2":{"368":1}}],["适配器类型",{"2":{"364":1}}],["适配器需要把数据封包为运营方协定的格式",{"2":{"286":1}}],["适配器必须为数据处理模块提供统一的接口",{"2":{"286":1}}],["适配器实例",{"2":{"225":1}}],["适配器将",{"2":{"15":1,"248":1}}],["适配器不需要",{"2":{"6":1}}],["适配器参数",{"0":{"5":1}}],["适配器",{"0":{"4":1,"286":1},"1":{"5":1},"2":{"173":1}}],["前往config",{"2":{"372":1}}],["前往兔兔的config",{"2":{"363":1}}],["前缀在对话文本中被移除后将赋值到",{"2":{"261":1}}],["前言",{"0":{"76":1}}],["起",{"2":{"261":1}}],["重新启动兔兔",{"2":{"363":1}}],["重命名",{"2":{"305":1}}],["重置为默认",{"2":{"296":1}}],["重要变动",{"2":{"261":1}}],["重复的",{"2":{"96":1}}],["建议版本为17或18",{"2":{"375":1}}],["建议安装",{"2":{"313":1}}],["建议考虑提供",{"2":{"300":1}}],["建议在开发时引入",{"2":{"260":1}}],["建议先阅读",{"2":{"189":1}}],["只要敲击回车就可以推出快速选择",{"2":{"380":1}}],["只能输入整数",{"2":{"318":1}}],["只等待",{"2":{"258":1}}],["只需要继承",{"2":{"327":1}}],["只需要把路径传入到",{"2":{"292":1}}],["只需要按顺序以链式使用上述方法",{"2":{"275":1}}],["只需要实例化多个",{"2":{"250":1}}],["只需要传入",{"2":{"6":1}}],["达到这个效果",{"2":{"258":1}}],["因此造成的一切后果与项目组无关",{"2":{"343":2,"345":1}}],["因此您如果需要对全局配置进行初始化操作",{"2":{"300":1}}],["因此你无法在使用该方法发送消息的情况下撤回",{"2":{"258":1}}],["因为兔兔有官方版本",{"2":{"396":1}}],["因为机器人的主要功能",{"2":{"229":1}}],["因为在本文档里",{"2":{"243":1}}],["因为在模块加载阶段",{"2":{"238":1}}],["因为在",{"2":{"224":1}}],["因为",{"2":{"205":1}}],["❌",{"2":{"257":6}}],["✅",{"2":{"257":2}}],["获取最新的通知",{"2":{"393":1}}],["获取到",{"2":{"256":1}}],["获得",{"2":{"33":1}}],["手动撤回",{"0":{"256":1}}],["随后往里面插入",{"2":{"252":1}}],["仍能单独注册属于自己的私有功能",{"2":{"251":1}}],["仍然可以监听这个事件名",{"2":{"224":1}}],["共享",{"2":{"251":1}}],["共同的方法",{"0":{"100":1},"1":{"101":1,"102":1,"103":1}}],["配置等整套部署",{"2":{"400":1}}],["配置有问题",{"2":{"380":1}}],["配置时打开选项",{"2":{"342":1}}],["配置可控实例",{"0":{"342":1}}],["配置实例",{"0":{"334":1},"1":{"335":1,"336":1,"337":1,"338":1,"339":1,"340":1,"341":1,"342":1}}],["配置相应的",{"2":{"322":1}}],["配置为",{"2":{"321":1,"323":1,"324":2,"325":2,"345":1}}],["配置值",{"2":{"299":1}}],["配置名称",{"2":{"298":1,"299":1,"316":1}}],["配置",{"2":{"246":1,"339":1,"340":1}}],["配合标准库的",{"2":{"76":1}}],["申请并创建你的",{"2":{"245":1}}],["动态输入",{"0":{"323":1,"324":1}}],["动态输出优先级的值",{"0":{"240":1}}],["动态执行代码",{"2":{"76":2}}],["中两个端口的值解决",{"2":{"377":1}}],["中修改",{"2":{"363":1}}],["中可以配置使用的数据库",{"2":{"333":1}}],["中指定",{"2":{"300":1}}],["中文转数字处理",{"2":{"262":1}}],["中间件处理",{"2":{"262":2}}],["中讲述了如何注册一个接收指定消息的函数",{"2":{"260":1}}],["中",{"2":{"239":1,"353":1}}],["必填字段",{"2":{"315":1}}],["必选",{"2":{"239":1}}],["必须安装",{"2":{"383":1}}],["必须同时提供默认值数据",{"2":{"296":1}}],["必须跟随",{"2":{"195":1,"196":1}}],["必须定义全局的",{"2":{"185":1}}],["必须包含常规的几个等级输出方法",{"2":{"87":1}}],["必须是以上两种类型",{"2":{"28":1}}],["就结论而言",{"2":{"362":1}}],["就是接收到的消息的内容",{"2":{"260":1}}],["就需要使用自定义检查",{"2":{"239":1}}],["就能够很好的完成外部代码的导入与执行",{"2":{"76":1}}],["然后重启",{"2":{"363":1}}],["然后选取第一个执行",{"2":{"238":1}}],["然后执行常规的图片发送方法",{"2":{"185":1}}],["正则",{"2":{"237":1}}],["正向",{"2":{"0":1}}],["唤起的场合",{"2":{"236":1}}],["完全没有中文信息的红色报错",{"0":{"376":1},"1":{"377":1}}],["完全匹配的句式指对话的文本内容全等于",{"2":{"236":1}}],["完成流程即可发布到商店",{"2":{"328":1}}],["完成一些特殊情况下的操作",{"2":{"286":1}}],["完成发送",{"2":{"286":1}}],["完成代码的动态执行",{"2":{"77":1}}],["完成企业主体入驻",{"2":{"18":1}}],["校验不通过则会报错",{"2":{"300":1}}],["校验符合正则检查的句式",{"0":{"235":1}}],["校验完全匹配的句式",{"0":{"236":1}}],["校验完全匹配",{"2":{"232":1}}],["忽略前缀检查",{"2":{"232":1}}],["私信下有效",{"2":{"262":1}}],["私信回复里无效",{"2":{"165":1,"167":1}}],["私域机器人",{"2":{"396":1}}],["私域机器人支持接收非",{"2":{"246":1}}],["私域模式建议在对话中包含指定前缀才能进入消息分配器",{"2":{"232":1}}],["私域模式的前缀校验",{"0":{"232":1},"1":{"233":1,"234":1}}],["触发关键字",{"2":{"230":1}}],["触发会话时",{"2":{"186":1}}],["功能系列插件",{"2":{"389":1}}],["功能仅私信可触发",{"2":{"242":1}}],["功能优先级",{"0":{"238":1}}],["功能组的参数才会对其生效",{"2":{"231":1}}],["功能组可以批量为功能设置参数",{"2":{"231":1}}],["功能组",{"0":{"231":1}}],["功能组id",{"2":{"230":1,"231":1}}],["功能开发的关键模块一共有三个",{"2":{"228":1}}],["作者",{"2":{"357":1}}],["作为默认全局配置写入数据库",{"2":{"300":1}}],["作为脚本语言的一个优点",{"2":{"76":1}}],["作用于你的业务逻辑主体函数",{"2":{"229":1}}],["何为机器人的功能",{"2":{"229":1}}],["核心会调用",{"2":{"228":1}}],["供编辑器智能提示使用",{"2":{"228":1}}],["包内",{"2":{"310":1}}],["包即可",{"2":{"309":1}}],["包",{"2":{"307":1,"310":1}}],["包含了消息和事件的注册器",{"2":{"228":1}}],["包括汉字与中文标点",{"2":{"371":1}}],["包括多账号实例",{"2":{"183":1}}],["包括此周期后续的钩子函数",{"2":{"68":1}}],["包括如何控制日志",{"2":{"65":1}}],["其次你需要给云服务器运营商的防火墙设置一个入站规则",{"2":{"363":1}}],["其作用是当",{"2":{"293":1}}],["其他类别的事件同理",{"2":{"224":1}}],["其值应从原始插入中保留",{"2":{"38":1}}],["还包含了好友添加",{"2":{"224":1}}],["还提供了多种消息类型用于发送丰富的消息内容",{"2":{"170":1}}],["针对",{"2":{"224":1}}],["监听",{"2":{"223":1,"224":3}}],["监听频道发生的事件",{"2":{"219":1}}],["戳一戳事件中",{"2":{"224":1}}],["戳一戳事件推送的消息",{"2":{"223":1}}],["戳了戳",{"2":{"223":1}}],["响应函数是一个协程",{"2":{"220":1}}],["响应方法同时支持异步和同步函数",{"2":{"45":1}}],["响应方法",{"2":{"45":1,"46":1}}],["剩下的事件类型",{"2":{"219":1}}],["让",{"2":{"408":1}}],["让你轻松实现你的创意",{"2":{"403":1}}],["让你可以按顺序获取到子频道内的消息",{"2":{"218":1}}],["让实例改为私域",{"2":{"246":1}}],["让事件不清除消息队列",{"2":{"218":1}}],["那这两项应该分别为8080和8060",{"2":{"364":1}}],["那样关闭事件",{"2":{"217":1}}],["那么接着来看开始部署部分",{"2":{"401":1}}],["那么",{"2":{"389":1}}],["那么请前往红色文本的最上方查找关键信息",{"2":{"376":1}}],["那么除了使用一些玄学手段",{"2":{"373":1}}],["那么事情将会变得有些棘手",{"2":{"363":1}}],["那么控制台将可能会有指向这些文档的链接",{"2":{"332":1}}],["那么只需要安装",{"2":{"313":1}}],["那么你可以在自己任意的目录内开发而不需要克隆",{"2":{"312":1}}],["那么恭喜你",{"2":{"245":1}}],["那么当",{"2":{"81":1}}],["那么周期将会延长",{"2":{"67":1}}],["关键值信息",{"2":{"239":1}}],["关键值",{"2":{"239":1}}],["关键字",{"2":{"236":1}}],["关键字传入",{"2":{"235":1}}],["关键字校验成功后函数的候选默认等级",{"2":{"230":1}}],["关键字时",{"2":{"229":1}}],["关闭它",{"2":{"217":1}}],["关闭等待事件",{"2":{"216":2,"217":1}}],["关于如何做到这一点",{"2":{"363":1}}],["关于这部分的内容将会非常少",{"2":{"243":1}}],["关于",{"0":{"215":1}}],["与",{"2":{"216":1,"217":1,"358":1}}],["代表范围",{"2":{"322":1}}],["代表此则消息符合期望",{"2":{"214":1}}],["代码部署启动时",{"0":{"378":1}}],["代码部署的指令会报错",{"0":{"358":1}}],["代码部署后部分插件无法正常产生图片",{"0":{"353":1}}],["代码部署",{"2":{"90":1,"384":1}}],["希望你能看懂",{"2":{"378":1}}],["希望",{"2":{"214":1}}],["比等待事件的默认优先级高",{"2":{"213":1}}],["比如在连续对话或异常监听里",{"2":{"255":1}}],["比如询问使用者以获取信息等",{"2":{"211":1}}],["比如",{"2":{"31":1}}],["过滤器",{"2":{"212":1,"216":1}}],["问候",{"2":{"210":1}}],["阿姆斯特朗",{"2":{"245":1}}],["阿米娅",{"2":{"210":1}}],["阿里云oss",{"2":{"22":1}}],["视频文件路径",{"2":{"208":1}}],["视频",{"0":{"207":1},"1":{"208":1}}],["坐标之间的影响",{"2":{"205":1}}],["颜色代码",{"2":{"204":1}}],["调试",{"2":{"307":1}}],["调试插件的方法有很多种",{"2":{"306":1}}],["调试插件",{"0":{"306":1},"1":{"307":1}}],["调色模板",{"0":{"204":1}}],["调用方法",{"2":{"279":1}}],["调用",{"2":{"257":1,"343":1}}],["调用接口",{"2":{"103":1}}],["调用接口的鉴权规则也不一样",{"2":{"100":1}}],["调用这个属性可以返回请求结果",{"2":{"50":1}}],["调用这个属性会尝试返回",{"2":{"49":1}}],["调用更改为沙箱环境",{"2":{"15":1,"248":1}}],["亦可插入图片渲染",{"2":{"202":1}}],["测试可用",{"2":{"387":1}}],["测试并连接",{"2":{"344":1}}],["测试实例",{"2":{"306":1,"307":1}}],["测试",{"2":{"196":1}}],["简要说明",{"0":{"314":1,"389":1},"1":{"390":1}}],["简单尝试一下",{"2":{"205":1}}],["简单使用",{"0":{"92":1}}],["简介",{"0":{"402":1},"1":{"403":1,"404":1,"405":1},"2":{"193":1}}],["段落2",{"2":{"193":1}}],["段落1",{"2":{"193":1}}],["要通过这个验证",{"2":{"373":1}}],["要发送官方的",{"2":{"189":1}}],["要低得多",{"2":{"181":1}}],["了解如何编辑",{"2":{"297":1}}],["了解如何启动",{"2":{"189":1}}],["了解",{"2":{"243":1}}],["了解分片机制",{"2":{"14":1,"20":1}}],["网络图片的url",{"2":{"188":1}}],["图片缓存的目录路径",{"2":{"316":1}}],["图片缓存目录",{"2":{"316":1}}],["图片渲染位置",{"2":{"205":1}}],["图片大小",{"2":{"205":1}}],["图片路径",{"2":{"205":1}}],["图片背景色",{"2":{"203":1}}],["图片高度",{"2":{"203":1}}],["图片宽度",{"2":{"203":1}}],["图片文件路径或图片",{"2":{"188":1}}],["图片",{"0":{"187":1},"1":{"188":1}}],["图片字节数据",{"2":{"28":1}}],["后回车",{"2":{"360":2}}],["后缀",{"2":{"339":1}}],["后续的文档可能会对你造成疑惑",{"2":{"243":1}}],["后截图发送图片",{"2":{"186":1}}],["后执行此钩子",{"2":{"73":1}}],["效果相同",{"2":{"231":1}}],["效果",{"2":{"185":1}}],["渲染图片",{"0":{"205":1}}],["渲染将会耗费较长时间",{"2":{"190":1}}],["渲染结束后",{"2":{"185":1}}],["渲染",{"2":{"185":1,"186":1}}],["渲染时间",{"2":{"184":1,"190":1}}],["毫秒",{"2":{"184":1,"190":1}}],["序列化的值类型",{"2":{"299":1}}],["序列化",{"2":{"184":1}}],["安装浏览器内核",{"2":{"388":1}}],["安装方法请自行百度",{"2":{"375":1}}],["安装完成后",{"2":{"360":1}}],["安装好的插件可以在插件管理查看",{"2":{"349":1}}],["安装插件",{"0":{"346":1},"1":{"347":1,"348":1,"349":1}}],["安装第三方依赖",{"2":{"310":1}}],["安装依赖",{"0":{"244":1},"2":{"388":1}}],["安装",{"0":{"182":1,"383":1}}],["及以上系统",{"2":{"181":2,"331":1,"382":2,"385":1}}],["所需的流程",{"2":{"400":1}}],["所导致",{"2":{"360":1}}],["所以它与数据处理模块紧密相连",{"2":{"286":1}}],["所以在代码层面",{"2":{"283":1}}],["所以你可以像",{"2":{"251":1}}],["所以任何时候",{"2":{"205":1}}],["所以需要指定一下图片高度",{"2":{"205":1}}],["所以仅支持以下操作系统",{"2":{"181":1}}],["所有账号之间可以共享资源以及功能",{"2":{"249":1}}],["所有函数的默认优先级都为",{"2":{"238":1}}],["所有人",{"0":{"166":1},"1":{"167":1},"2":{"166":2}}],["所有适配器的",{"2":{"100":1}}],["所有钩子均可以同时存在多个",{"2":{"67":1}}],["操作系统",{"2":{"331":1,"385":1}}],["操作系统支持",{"2":{"181":1,"382":1}}],["操作详见",{"2":{"33":1}}],["技术难度也比",{"2":{"181":1}}],["合成的图片更加生动",{"2":{"181":1}}],["合并转发消息需要使用独立的工具类创建",{"2":{"276":1}}],["合并转发消息不是",{"2":{"176":1}}],["合并转发消息",{"0":{"176":1,"276":1},"1":{"177":1,"178":1,"179":1,"180":1}}],["生效",{"2":{"339":1}}],["生成的图片",{"0":{"181":1,"189":1},"1":{"182":1,"183":1,"184":1,"185":1,"186":1,"190":1,"191":1},"2":{"189":1}}],["生命周期",{"0":{"66":1},"1":{"67":1,"68":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1},"2":{"288":1}}],["撤回合并转发",{"2":{"259":1}}],["撤回合并转发的消息",{"0":{"259":1}}],["撤回等待的消息",{"0":{"258":1}}],["撤回当前消息",{"2":{"255":1}}],["撤回一条消息",{"2":{"254":1}}],["撤回消息",{"0":{"254":1},"1":{"255":1,"256":1,"257":1,"258":1,"259":1},"2":{"263":1}}],["撤回",{"0":{"180":1,"257":1},"1":{"258":1,"259":1},"2":{"180":1}}],["添加实例",{"0":{"335":1},"2":{"335":1}}],["添加任意输入类型或将",{"2":{"325":1}}],["添加",{"2":{"324":1}}],["添加插件依赖",{"0":{"301":1}}],["添加插件文档",{"0":{"291":1},"1":{"292":1,"293":1,"294":1}}],["添加使用指引文档",{"0":{"293":1}}],["添加一个",{"0":{"292":1}}],["添加一张由",{"2":{"189":1}}],["添加前缀触发词",{"2":{"247":1}}],["添加参数",{"2":{"233":1}}],["添加第二行按钮组",{"2":{"196":1}}],["添加第一行按钮组",{"2":{"196":1}}],["添加嵌套的合并转发消息",{"0":{"179":1}}],["添加指定",{"0":{"178":1}}],["添加自定义消息",{"0":{"177":1}}],["添加时立即执行一次任务",{"2":{"94":1}}],["码目前仅支持",{"2":{"173":1}}],["码",{"0":{"173":1}}],["百度",{"2":{"172":1}}],["百度一下",{"2":{"31":1}}],["链接分享",{"2":{"172":1}}],["白银",{"2":{"169":1}}],["之前等级",{"2":{"169":1}}],["黄金",{"2":{"169":1}}],["缩略图",{"2":{"169":1}}],["标志是窗口标题最前面出现了选择二字",{"2":{"380":1}}],["标题",{"2":{"163":1,"169":2}}],["标识",{"2":{"56":1}}],["详情请查看",{"2":{"168":1}}],["详情请查看发送",{"2":{"162":1,"192":1}}],["详见官方文档",{"2":{"264":1}}],["详见本章文档",{"2":{"230":1}}],["详见插件开发文档",{"2":{"79":1}}],["详见",{"2":{"47":1,"307":1}}],["缺少",{"2":{"105":1}}],["🐰",{"2":{"234":1}}],["😁继续努力",{"2":{"169":1}}],["🚧",{"2":{"105":2}}],["👉",{"2":{"103":1}}],["参照文档将",{"2":{"363":1}}],["参考此文章查询你部署兔兔的设备的局域网ip",{"2":{"363":1}}],["参考",{"2":{"104":1}}],["参数内传入",{"2":{"301":1}}],["参数内传入一个包含",{"2":{"205":1}}],["参数是多个",{"2":{"251":1}}],["参数为",{"2":{"239":1}}],["参数改为字符串列表可以临时修改前缀检查为指定单词",{"2":{"234":1}}],["参数过滤消息",{"2":{"214":1}}],["参数列表",{"0":{"230":1},"2":{"212":1,"216":1}}],["参数传入",{"2":{"179":1,"188":1}}],["参数传入了空",{"2":{"177":1}}],["参数也是一样的",{"2":{"100":1}}],["参数定义任务",{"2":{"95":1}}],["参数已删除",{"2":{"91":1}}],["参数接受的",{"2":{"68":1,"71":1}}],["参数设置",{"2":{"34":1}}],["参数",{"0":{"296":1},"2":{"14":1,"19":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"63":1,"89":1,"91":1,"94":2,"96":1,"101":2,"102":2,"103":2,"185":1,"216":1,"231":2,"260":1,"263":1,"292":1}}],["参数即可启动一个测试实例",{"2":{"280":1}}],["参数即可",{"2":{"6":1,"62":1}}],["参数名",{"2":{"1":1,"3":1,"8":1,"10":1,"12":1,"14":1,"19":1,"21":1,"25":1,"37":1,"38":1,"40":1,"41":1,"42":1,"44":1,"45":1,"46":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"61":1,"81":1,"82":1,"85":1,"86":1,"91":1,"94":1,"97":1,"101":1,"102":1,"103":1,"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1,"115":1,"116":1,"117":1,"118":1,"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"157":1,"158":1,"159":1,"160":1,"161":1,"163":1,"165":1,"169":1,"171":1,"175":1,"177":1,"178":1,"184":1,"188":1,"190":1,"193":1,"198":1,"200":1,"203":1,"205":1,"208":1,"210":1,"212":1,"216":1,"230":1,"231":1,"253":1,"256":1,"265":1,"273":1,"296":1,"298":1,"299":1,"301":1}}],["控制台群组id应为你希望运行信息出现在的群聊的群聊号中",{"2":{"364":1}}],["控制台中实例无法连接",{"0":{"364":1},"1":{"365":1,"366":1,"367":1,"368":1,"369":1}}],["控制台中应填写",{"2":{"363":1}}],["控制台",{"2":{"328":1,"343":1}}],["控制了",{"2":{"103":1}}],["控制任务执行时机",{"2":{"91":1}}],["频道成为正式的机器人",{"2":{"404":1}}],["频道id",{"2":{"298":1,"299":1}}],["频道级别配置表单的",{"2":{"296":1}}],["频道级别配置默认值",{"2":{"296":1}}],["频道的事件名和内容可以查看官方文档",{"2":{"222":1}}],["频道名称",{"2":{"222":2}}],["频道介绍",{"2":{"222":2}}],["频道事件",{"0":{"222":1},"2":{"222":2}}],["频道跳转超链接",{"0":{"197":1},"1":{"198":1}}],["频道卡片消息",{"2":{"168":1}}],["频道",{"0":{"105":1},"1":{"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1,"115":1,"116":1,"117":1,"118":1,"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"157":1,"158":1,"159":1,"160":1,"161":1},"2":{"162":1,"192":1,"197":1,"262":1}}],["频道拥有此参数",{"2":{"102":1}}],["频道机器人展开",{"2":{"243":1}}],["频道机器人的运营规则",{"2":{"243":1}}],["频道机器人的框架",{"2":{"243":1}}],["频道机器人的适配器",{"2":{"5":1}}],["频道机器人暂时不支持发送语音",{"2":{"209":1}}],["频道机器人暂时不支持发送视频",{"2":{"207":1}}],["频道机器人暂时不支持发送合并转发消息",{"2":{"176":1}}],["频道机器人",{"0":{"13":1,"396":1},"1":{"14":1,"15":1},"2":{"13":1,"243":1,"395":1}}],["都秉着",{"2":{"404":1}}],["都请把握好你的文字图片宽高与插入的图片的大小",{"2":{"205":1}}],["都存在以下三个方法",{"2":{"100":1}}],["都会历经一个完整的生命周期",{"2":{"66":1}}],["示例在触发会话并开始发送消息时",{"2":{"185":1}}],["示例",{"0":{"172":1,"310":1,"326":1},"2":{"97":1,"253":1,"316":1}}],["会临时添加插件目录为系统路径",{"2":{"305":1}}],["会从插件市场服务尝试寻找对应的插件依赖并一同安装",{"2":{"301":1}}],["会将",{"2":{"300":1}}],["会优化图片与文字的组成",{"2":{"275":1}}],["会无视前缀检查",{"2":{"236":1}}],["会执行这些注册的异常处理函数",{"2":{"225":1}}],["会返回",{"2":{"215":1}}],["会自动将本段落转换为图片发送",{"2":{"200":1}}],["会被整合为一组",{"2":{"96":1}}],["会使用返回值构建视频消息",{"2":{"30":1}}],["会使用返回值构建语音消息",{"2":{"29":1}}],["会使用返回值构建图片消息",{"2":{"28":1}}],["jdk",{"2":{"375":1}}],["jni",{"0":{"375":1}}],["joined",{"2":{"222":1,"262":1}}],["job",{"2":{"94":2,"95":1}}],["javascript",{"2":{"185":1}}],["jpg",{"2":{"163":1}}],["jump",{"2":{"112":1,"151":1}}],["jswindow",{"2":{"191":1}}],["jsonschema",{"0":{"297":1,"315":1},"1":{"298":1,"299":1,"300":1,"316":1,"317":1,"318":1,"319":1,"320":1,"321":1,"322":1,"323":1,"324":1,"325":1,"326":1},"2":{"296":7,"297":1,"315":1}}],["json",{"0":{"49":1},"2":{"49":2,"53":1,"184":1,"222":1,"223":1,"224":1,"296":6,"297":1,"299":1,"315":2,"316":1,"317":1,"318":1,"319":1,"320":1,"321":1,"322":1,"323":1,"324":1,"325":1,"326":2}}],["js",{"2":{"31":1}}],["定义事件监听名即可",{"2":{"224":1}}],["定义的任务可以在插件被卸载时自动取消",{"2":{"93":1}}],["定义任务",{"2":{"93":1}}],["定时任务",{"0":{"91":1},"1":{"92":1,"93":1,"94":1,"95":1,"96":1,"97":1}}],["子级对象",{"0":{"325":1},"1":{"326":1}}],["子频道id",{"2":{"198":1,"265":1}}],["子频道",{"2":{"197":1,"262":1}}],["子标题",{"2":{"163":1}}],["子标签",{"2":{"91":1,"94":1}}],["子类时",{"2":{"85":1}}],["秒数",{"2":{"212":1,"216":1}}],["秒和",{"2":{"95":1}}],["秒时执行",{"2":{"95":2}}],["秒执行一次任务",{"2":{"92":1}}],["秒",{"2":{"91":1,"94":1}}],["单击窗体内黑色部分进入快速选择",{"2":{"380":1}}],["单位秒",{"2":{"339":1}}],["单位",{"2":{"91":1,"94":1}}],["单文件插件是最简单的开发方式",{"2":{"79":1}}],["循环执行间隔时间",{"2":{"91":1,"94":1}}],["已删除",{"2":{"91":1}}],["此文章",{"2":{"360":1}}],["此处即是",{"2":{"340":1}}],["此处不作详细说明",{"2":{"245":1}}],["此方法可以将文字转换为图片发送",{"2":{"202":1}}],["此方法已不再支持",{"2":{"91":1}}],["此时你不需要再点击open",{"2":{"374":1}}],["此时应该会显示如下的文本",{"2":{"360":1}}],["此时重启兔兔本体或点击按钮",{"2":{"356":1}}],["此时的目录结构应为",{"2":{"313":1}}],["此时机器人只能接收指定前缀的对话",{"2":{"247":1}}],["此时插件的目录应如下所示",{"2":{"80":1}}],["此时",{"2":{"78":1}}],["95",{"2":{"339":1}}],["97",{"2":{"339":1}}],["99ada6b",{"2":{"261":1}}],["9",{"2":{"91":1,"261":1,"388":1}}],["6597000",{"2":{"339":1}}],["60",{"2":{"92":1}}],["6",{"2":{"91":1,"172":2,"222":1,"385":1}}],["⚠️注意⚠️不兼容的更新",{"2":{"91":1}}],["x",{"2":{"90":2,"205":1,"386":2,"387":6}}],["xxxxx",{"2":{"224":1}}],["xxxxxx",{"2":{"169":1,"208":1}}],["xxx",{"2":{"25":2,"164":1,"165":1,"310":1}}],["下",{"2":{"352":1}}],["下载更新包",{"2":{"393":1}}],["下载页面",{"2":{"393":1}}],["下载并解压",{"2":{"386":1,"387":1}}],["下载",{"0":{"330":1},"1":{"331":1},"2":{"331":1,"385":1}}],["下载文件",{"0":{"57":1},"1":{"58":1}}],["下拉选择框不需要",{"2":{"320":1}}],["下拉选择框",{"0":{"320":1},"2":{"324":1}}],["下开发的插件",{"2":{"311":1}}],["下面来看一个简单的例子",{"2":{"216":1}}],["下使用",{"0":{"90":1}}],["取消定时任务",{"0":{"96":1},"1":{"97":1}}],["取消自动关闭",{"2":{"89":1}}],["取消订阅需要传入订阅时的响应方法对象",{"2":{"46":1}}],["取消订阅",{"0":{"46":1}}],["浏览器打开控制台",{"2":{"344":1}}],["浏览器视窗高度",{"2":{"184":1}}],["浏览器视窗宽度",{"2":{"184":1}}],["浏览器视窗默认高度",{"2":{"89":1}}],["浏览器视窗默认宽度",{"2":{"89":1}}],["浏览器默认渲染时间",{"2":{"89":1}}],["否则后续的操作将毫无意义",{"2":{"401":1}}],["否则使用默认值的",{"2":{"296":1}}],["否则优先使用",{"2":{"231":1}}],["否则等待事件没有被正常关闭时",{"2":{"217":1}}],["否则插入的图片可能会显示不全",{"2":{"205":1}}],["否",{"2":{"89":2,"216":1}}],["启动时弹窗提示",{"0":{"362":1}}],["启动时可以自动安装",{"2":{"348":1}}],["启动时开启",{"2":{"253":1}}],["启动时打开",{"0":{"183":1}}],["启动的",{"2":{"183":1}}],["启动参数",{"0":{"89":1},"1":{"90":1}}],["启动行为",{"2":{"88":1,"183":1}}],["启动",{"0":{"88":1}}],["启动程序时会自动修改到数据库表结构中",{"2":{"35":1}}],["改变默认的",{"2":{"88":1,"183":1}}],["改变",{"0":{"88":1}}],["8d92a2feb3e2",{"2":{"400":1}}],["8c",{"2":{"339":1}}],["89",{"2":{"339":1}}],["8",{"2":{"261":1,"388":1}}],["8s",{"2":{"86":2}}],["80",{"2":{"401":1}}],["8088",{"2":{"61":1,"343":2,"344":1,"363":3}}],["8086",{"2":{"21":2}}],["8080",{"2":{"1":1,"3":1,"8":1,"10":1,"12":1,"340":1}}],["8060",{"2":{"1":1,"8":1,"10":1,"12":1,"340":1}}],["3",{"2":{"196":1,"388":2}}],["37",{"2":{"163":1}}],["300",{"2":{"222":1}}],["30",{"2":{"95":1,"212":1,"216":1}}],["32001",{"2":{"280":1}}],["32",{"2":{"86":1}}],["39",{"2":{"1":4,"3":6,"6":2,"8":6,"10":6,"12":6,"14":8,"17":6,"19":6,"20":8,"21":10,"25":4,"31":10,"33":2,"34":8,"42":4,"44":2,"45":4,"46":2,"49":4,"50":2,"51":2,"61":10,"62":4,"63":2,"78":12,"79":14,"80":2,"81":6,"82":2,"85":16,"86":4,"88":2,"95":4,"97":4,"103":2,"163":40,"165":2,"169":12,"172":20,"173":6,"176":6,"177":2,"179":4,"184":2,"185":8,"186":4,"191":6,"193":26,"195":4,"196":28,"200":2,"201":2,"203":2,"204":4,"205":6,"206":2,"208":4,"210":4,"212":6,"214":6,"216":8,"220":6,"222":6,"223":2,"224":6,"229":6,"231":8,"233":4,"234":8,"235":4,"236":4,"237":10,"238":8,"239":4,"241":8,"242":8,"245":8,"246":4,"247":4,"250":16,"251":20,"253":4,"255":6,"256":4,"257":6,"258":5,"260":2,"265":2,"266":4,"267":6,"268":6,"270":2,"272":4,"273":2,"280":10,"293":6,"294":6,"295":8,"296":4,"298":4,"299":6,"301":6,"303":14,"304":2,"307":2,"327":8,"333":8,"339":4,"360":2,"388":4}}],["异步",{"2":{"216":1,"263":1}}],["异步方式",{"2":{"85":1}}],["异常类型实例",{"2":{"225":1}}],["异常处理函数接受三个参数",{"2":{"225":1}}],["异常监听",{"0":{"225":1,"271":1},"1":{"226":1,"227":1}}],["异常",{"2":{"215":1}}],["异常标题",{"2":{"85":1}}],["捕获异常后执行的方法",{"2":{"85":1}}],["来源频道id",{"2":{"265":1,"267":1}}],["来源频道",{"2":{"262":1}}],["来开启私域模式",{"2":{"246":1}}],["来进一步完成你的业务逻辑",{"2":{"98":1}}],["来捕获并输出在上下文中产出的异常",{"2":{"85":1}}],["来实现上传文件到托管服务以及返回生成的",{"2":{"22":1}}],["+=",{"2":{"85":5}}],["也给你带去了快乐吧",{"2":{"406":1}}],["也许你难以将它们抽离",{"2":{"389":1}}],["也就无法对常见的互动进行回应",{"2":{"380":1}}],["也就是本文档所指的",{"2":{"404":1}}],["也就是你bot的qq号",{"2":{"364":1}}],["也就是网址最开头的http",{"2":{"363":1}}],["也就是说",{"2":{"213":1}}],["也请自行百度",{"2":{"363":1}}],["也无法获得官方的任何支持",{"2":{"353":1}}],["也不会推送更新消息",{"2":{"393":1}}],["也不会一直有效",{"2":{"332":1}}],["也不是可运行的程序或批处理文件",{"2":{"360":1}}],["也不对其造成的影响负责",{"2":{"332":1}}],["也允许先创建空多账号实例",{"2":{"252":1}}],["也属于事件",{"2":{"219":1}}],["也包括本功能的初始触发方式",{"2":{"213":1}}],["也可以选择用新的可执行文件覆盖旧的可执行文件",{"2":{"381":1}}],["也可以直接传入",{"2":{"188":1}}],["也可以通过传入响应函数订阅事件",{"2":{"45":1}}],["也支持传入",{"2":{"85":1}}],["5128",{"2":{"178":1}}],["5",{"2":{"84":1,"85":1,"95":1,"307":1,"318":1,"404":1}}],["5700",{"2":{"3":1}}],["4",{"2":{"196":1,"385":1}}],["44",{"2":{"85":1}}],["425",{"2":{"84":2}}],["401",{"0":{"368":1}}],["4096",{"2":{"340":1}}],["40",{"2":{"84":2,"95":2}}],["模板也会失效",{"2":{"204":1}}],["模板也可以插入",{"2":{"201":1}}],["模板文件路径或网站url",{"2":{"184":1}}],["模板消息",{"2":{"162":1,"192":1}}],["模版发送",{"2":{"195":1,"196":1}}],["模版消息",{"0":{"192":1},"1":{"193":1,"194":1,"195":1,"196":1}}],["模版消息请查看",{"2":{"189":1}}],["模版",{"2":{"163":2,"189":1,"193":3}}],["模块",{"2":{"181":1}}],["模块下",{"2":{"99":1}}],["模块名称",{"2":{"86":1}}],["模块提供了上下文管理的方式",{"2":{"85":1}}],["模块构建日志体系",{"2":{"83":1}}],["模式渲染",{"2":{"189":1}}],["模式启动程序",{"2":{"89":1}}],["模式",{"2":{"84":1}}],["模式下会显示日志的输出文件名和位置",{"2":{"84":1}}],["相同的等级输出",{"2":{"84":1}}],["相当于执行了代码",{"2":{"79":1,"80":1}}],["日期范围",{"2":{"322":1}}],["日期时间范围",{"2":{"322":1}}],["日期时间",{"2":{"322":1}}],["日期时间选择器",{"0":{"321":1},"1":{"322":1}}],["日期",{"2":{"322":1,"324":1}}],["日志显示同可执行文件部署",{"2":{"388":1}}],["日志文件名",{"2":{"86":1}}],["日志文件保存目录",{"2":{"86":1}}],["日志格式",{"2":{"86":1}}],["日志等级",{"2":{"86":1}}],["日志等级和日志内容",{"2":{"84":1}}],["日志的固有格式如下所示",{"2":{"84":1}}],["日志模块名",{"2":{"84":1}}],["日志模块",{"0":{"83":1},"1":{"84":1,"85":1,"86":1,"87":1}}],["日常使用的查询操作详见",{"2":{"32":1}}],["属性内",{"2":{"261":1}}],["属性下",{"2":{"98":1}}],["属性位于",{"2":{"98":1}}],["属性",{"0":{"262":1},"2":{"82":1,"99":1,"179":1,"216":2,"221":1,"239":1,"262":1}}],["卸载插件",{"0":{"82":1}}],["应该使用http",{"2":{"363":1}}],["应该以插件的绝对目录读取",{"2":{"304":1}}],["应用本体的运行将会被冻结",{"2":{"380":1}}],["应用干员设置",{"2":{"356":1}}],["应用的",{"2":{"6":1,"338":1}}],["应注意这一特性",{"2":{"81":1}}],["先看看这个方法的参数列表",{"2":{"81":1}}],["里数据类型为",{"2":{"339":1}}],["里没有设置该参数时",{"2":{"231":1}}],["里接收到时",{"2":{"222":1}}],["里提供了参数解决这一问题",{"2":{"81":1}}],["里添加",{"2":{"63":1}}],["语料配置",{"2":{"264":1}}],["语音或频道多图消息会产生分开发送的结果",{"2":{"257":1}}],["语音标题",{"2":{"210":1}}],["语音",{"0":{"209":1},"1":{"210":1},"2":{"210":1}}],["语音文件必须是",{"2":{"23":1}}],["语句",{"2":{"81":1,"185":1}}],["压缩文件",{"2":{"81":1}}],["压缩包",{"0":{"81":1},"2":{"77":1,"308":1}}],["虽然启用了",{"2":{"339":1}}],["虽然",{"2":{"81":1}}],["│",{"2":{"80":1,"81":1,"292":10,"302":6,"304":8,"313":3}}],["├──",{"2":{"80":3,"81":5,"292":5,"302":3,"304":4,"310":2,"313":1}}],["它指定了通讯模块的运行方式",{"2":{"286":1}}],["它们均可以被运转中心",{"2":{"282":1}}],["它们一般会被组织成层层嵌套的树状结构",{"2":{"282":1}}],["它们独立运作",{"2":{"281":1}}],["它们通常在适配器模块的",{"2":{"99":1}}],["它的第一个参数",{"2":{"265":1}}],["它拥有与",{"2":{"251":1}}],["它可能会持续拦截子频道消息直至超时自动关闭",{"2":{"217":1}}],["它可能会是一个",{"2":{"81":1}}],["它可能会是以",{"2":{"80":1}}],["它通常比使用",{"2":{"181":1}}],["它是基于",{"2":{"2":1}}],["目前在",{"2":{"387":1}}],["目前该限速设置为令牌桶算法",{"2":{"339":1}}],["目前仅支持官方",{"2":{"207":1,"209":1}}],["目前仅支持",{"2":{"176":1}}],["目前事件生命周期只有一个",{"2":{"74":1}}],["目录下",{"2":{"348":1}}],["目录下的文件",{"2":{"339":2,"340":1}}],["目录名称",{"2":{"332":1}}],["目录内",{"2":{"302":1}}],["目录导入",{"2":{"81":1}}],["目录同样能实现",{"2":{"81":1}}],["目录的形式存在",{"2":{"80":1}}],["目录",{"0":{"80":1},"2":{"387":1}}],["静态资源或变量污染的前提下",{"2":{"79":1}}],["我相信快乐是可以互相传递的",{"2":{"406":1}}],["我已经安装好插件了",{"2":{"380":1}}],["我通常称这种行为叫旧瓶装新酒",{"2":{"379":1}}],["我很确定我的路径中没有中文字符",{"2":{"371":1}}],["我很确定我已经安装了git",{"2":{"360":1}}],["我不知道服务地址应该填什么",{"2":{"363":1}}],["我不知道如何申请百度云",{"2":{"351":1}}],["我尝试进入控制台时出现了",{"2":{"363":1}}],["我在窗口最上方看到了一些进度条",{"2":{"361":1}}],["我看不懂什么是克隆仓库",{"0":{"358":1}}],["我们先来对配置单的具体内容进行一些解释",{"2":{"364":1}}],["我们的团队成员",{"2":{"345":1,"400":1}}],["我们可能不会高频率的维护这些文档以至于它们可能无法与最新的版本相匹配",{"2":{"332":1}}],["我们希望这个文件有且只有上面的一行",{"2":{"305":1}}],["我们希望你知道",{"2":{"243":1}}],["我们不推荐这种做法",{"2":{"294":1}}],["我们建议你先在",{"2":{"243":1}}],["我们强烈建议在使用不同的适配器时",{"2":{"99":1}}],["我们只需要添加参数",{"2":{"81":1}}],["我们尽量为所有适配器的基本逻辑实现了相同的效果",{"2":{"4":1}}],["我的第一个插件",{"2":{"78":1,"79":1,"295":1,"303":1,"327":1}}],["我的插件",{"2":{"78":1,"79":1,"295":1,"303":1,"327":1}}],["有一定的部署难度",{"2":{"400":1}}],["有的话还不回应就见鬼了",{"2":{"380":1}}],["有大段看不懂",{"0":{"376":1},"1":{"377":1}}],["有意或无意",{"2":{"371":1}}],["有时这会导致插件与本体版本不一致的问题",{"2":{"381":1}}],["有时你可能更新了卡池却没有更新干员数据也会导致这个问题",{"2":{"356":1}}],["有时候公招图",{"0":{"354":1}}],["有时候有些复杂配置不能用只有一级的对象",{"2":{"325":1}}],["有时候会是",{"2":{"310":1}}],["有现成的示例脚本",{"2":{"306":1}}],["有很大帮助",{"2":{"78":1}}],["有差异外",{"2":{"4":1}}],["事实上这对你的功能管理",{"2":{"78":1}}],["事件过滤器文件目录",{"2":{"339":1}}],["事件响应的方法通常可以返回触发了该事件的实例",{"2":{"269":1}}],["事件时",{"2":{"224":1}}],["事件的",{"2":{"224":1}}],["事件的内容字典",{"2":{"221":1}}],["事件类型一览",{"2":{"223":1}}],["事件",{"0":{"223":1,"224":1},"2":{"224":1}}],["事件订阅",{"2":{"222":1}}],["事件监听",{"0":{"219":1,"270":1},"1":{"220":1,"221":1,"222":1,"223":1,"224":1}}],["事件或定时任务等功能",{"2":{"78":1}}],["事件生命周期",{"0":{"74":1}}],["事件数据",{"2":{"44":1}}],["事件名可参阅对应适配器服务的官方文档",{"2":{"220":1}}],["事件名",{"2":{"44":1,"45":1,"46":1,"221":1}}],["事件总线",{"0":{"43":1},"1":{"44":1,"45":1,"46":1}}],["事件通知会落在不同的分片上",{"2":{"14":1,"20":1}}],["事件分片",{"0":{"14":1,"20":1},"1":{"21":1}}],["zip",{"0":{"81":1},"2":{"77":1,"81":9,"307":2,"308":1,"309":1,"310":2,"385":1}}],["zipimporter",{"2":{"81":1}}],["zipimport",{"2":{"76":1,"81":3}}],["形式的值数值",{"2":{"323":1,"324":1}}],["形式的模块",{"2":{"302":1}}],["形式的",{"2":{"94":1}}],["形式",{"2":{"77":1}}],["而进入了快速选择",{"2":{"380":1}}],["而如果你使用了云服务器",{"2":{"373":1}}],["而服务密钥留空",{"2":{"363":2}}],["而不是两者都要进行",{"2":{"358":1}}],["而接收到运转中心需要发出的数据时",{"2":{"286":1}}],["而其中的",{"2":{"251":1}}],["而是直接将教程中获取到的ticket填入ticket栏中即可",{"2":{"374":1}}],["而是被它们共享",{"2":{"250":1}}],["而是保持接收子频道的消息",{"2":{"217":1}}],["而是",{"2":{"216":1}}],["而是通过标准库",{"2":{"81":1}}],["而",{"2":{"76":1}}],["通讯与数据处理模块",{"0":{"285":1},"1":{"286":1}}],["通讯模块负责解决对接收和发送的数据进行解包与封包",{"2":{"286":1}}],["通讯模块主要形式为适配器",{"2":{"285":1}}],["通讯模块",{"2":{"281":1}}],["通常使用上一个方案",{"2":{"381":1}}],["通常这是由于java版本太低导致的",{"2":{"375":1}}],["通常这个异常会被全局异常捕捉器过滤",{"2":{"215":1}}],["通常需要手机与电脑在同一网络环境下",{"2":{"373":1}}],["通常是云服务器上部署的mirai才会有这个问题",{"2":{"373":1}}],["通常是以",{"2":{"363":1}}],["通常你应该选择cq",{"2":{"364":1}}],["通常你应该填写的就是http",{"2":{"363":1}}],["通常端口是",{"2":{"363":1}}],["通常指在同一个家里",{"2":{"363":1}}],["通常",{"2":{"363":1,"376":1,"380":1}}],["通常情况下",{"2":{"360":1,"393":1}}],["通常再请求一次即可正常返回图片",{"2":{"354":1}}],["通常只需要几秒钟不到",{"2":{"341":1}}],["通常可以在",{"2":{"256":1}}],["通常会以可执行文件的形式发布",{"2":{"76":1}}],["通知提醒",{"2":{"163":1}}],["通过代码部署",{"0":{"388":1}}],["通过可执行文件部署",{"0":{"385":1},"1":{"386":1,"387":1}}],["通过公网访问",{"2":{"363":1}}],["通过插件包自动安装",{"0":{"348":1}}],["通过事件数据中的",{"2":{"224":1}}],["通过事件名",{"2":{"224":1}}],["通过主动消息发送",{"2":{"196":1}}],["通过网站url制图",{"0":{"186":1}}],["通过扩展消息发送",{"2":{"173":1}}],["通过这个",{"2":{"82":1}}],["通过",{"2":{"67":1,"93":1,"173":1,"251":1}}],["通过装饰器订阅事件",{"2":{"45":1}}],["通过自定义默认的",{"2":{"22":1}}],["兔兔的窗口闪现了一下",{"0":{"359":1},"1":{"360":1,"361":1}}],["兔兔在启动后会开启一个",{"2":{"343":1}}],["兔兔支持登录多个机器人账号同时使用",{"2":{"334":1}}],["兔兔",{"0":{"90":1,"331":1},"2":{"76":1,"185":1,"295":1,"307":1,"313":2,"314":1,"389":5}}],["无效参数",{"0":{"369":1}}],["无法获取更新时可稍后再试",{"2":{"392":1}}],["无法获得准确的事件",{"2":{"224":1}}],["无法进入控制台",{"0":{"363":1}}],["无法定位程序输入点",{"0":{"362":1}}],["无法撤回",{"2":{"257":6}}],["无法插入表情",{"2":{"204":1}}],["无参数则监听全事件",{"2":{"220":1}}],["无头浏览器截图生成图片",{"2":{"185":1}}],["无头浏览器",{"2":{"185":1}}],["无论有没有返回",{"2":{"73":1}}],["无需额外的适配器",{"2":{"13":1}}],["则是mirai启动",{"2":{"380":1}}],["则请您浏览左侧的目录跳转至您需要的部分开始阅读",{"2":{"332":1}}],["则会用",{"2":{"300":1}}],["则会产出",{"2":{"219":1}}],["则必须提供对应的",{"2":{"300":1}}],["则",{"2":{"177":1}}],["则不往下继续执行并结束生命周期",{"2":{"70":1}}],["则在调用接口时",{"2":{"63":1}}],["全局级别配置表单的",{"2":{"296":1}}],["全局级别配置默认值",{"2":{"296":1}}],["全局变量",{"2":{"91":1}}],["全部执行完成后当有其中一个返回",{"2":{"70":1}}],["全域适配器的参数和用法和qq",{"2":{"17":1}}],["全域机器人指同时支持群聊",{"2":{"16":1}}],["全域机器人",{"0":{"16":1},"1":{"17":1}}],["当有更新时可到",{"2":{"393":1}}],["当有下列需求的时候",{"2":{"300":1}}],["当游戏有更新的当日",{"2":{"392":1}}],["当您试图从公网连接至控制台时",{"2":{"345":1}}],["当您试图将控制台暴露至公网时",{"2":{"343":1}}],["当您尝试使用纯数字的",{"2":{"343":1}}],["当实例状态为在线时",{"2":{"341":1}}],["当使用范围选择器时",{"2":{"322":1}}],["当",{"2":{"310":1,"318":1,"321":1}}],["当插件安装时",{"2":{"301":1}}],["当插件需要在别的插件的基础上运行",{"2":{"301":1}}],["当接收到消息时",{"2":{"260":1}}],["当关键字检查无法满足功能的触发方式时",{"2":{"239":1}}],["当关键字校验存在冲突时",{"2":{"238":1}}],["当对话内容为",{"2":{"238":1}}],["当该参数被赋值时",{"2":{"230":1}}],["当和机器人的对话中包含",{"2":{"229":1}}],["当然",{"2":{"224":1,"332":1,"396":1}}],["当一个新的等待事件创建后",{"2":{"215":1}}],["当文字超过一定长度时",{"2":{"200":1}}],["当传入的类型为字符串时",{"2":{"188":1}}],["当前qq版本太低",{"0":{"372":1}}],["当前等级",{"2":{"169":1}}],["当前页",{"2":{"42":1}}],["当消息响应获得执行权",{"2":{"239":1}}],["当消息响应器执行完毕",{"2":{"73":1}}],["当消息响应器执行完毕且存在返回时",{"2":{"71":1,"72":1}}],["当消息分配器有返回",{"2":{"70":1}}],["当存在等待事件且消息分配器无返回或等待事件属于强制等待类型时",{"2":{"69":1}}],["布尔值仅可返回",{"2":{"68":1}}],["按游戏卡池发布顺序来说",{"0":{"355":1}}],["按钮3",{"2":{"196":1}}],["按钮2",{"2":{"196":1}}],["按钮1",{"2":{"196":1}}],["按钮消息",{"0":{"194":1},"1":{"195":1,"196":1},"2":{"193":2}}],["按标签名取消定时任务",{"2":{"97":1}}],["按加载顺序逐个调用",{"2":{"67":1,"68":1,"70":1,"71":1}}],["按照",{"2":{"13":1}}],["直接删除整个",{"2":{"361":1}}],["直接将图片文件扔到文件夹内即可",{"2":{"352":1}}],["直接打包",{"0":{"309":1},"1":{"310":1}}],["直接导入插件",{"2":{"307":1}}],["直接在参数内编写",{"0":{"294":1}}],["直接访问",{"2":{"282":1}}],["直接传入",{"2":{"189":1}}],["直接引入",{"2":{"47":1}}],["直至等待事件结束后继续向下执行",{"2":{"67":1}}],["紫色的节点就是可以介入的周期",{"2":{"67":1}}],["总共会经过至少五个周期",{"2":{"67":1}}],["总条数",{"2":{"42":1}}],["消息响应器的执行结果会经由运转中心返回到适配器",{"2":{"288":1}}],["消息响应我们会在后续的文档称之为功能",{"2":{"229":1}}],["消息处理",{"0":{"288":1},"2":{"287":1}}],["消息时间",{"2":{"262":1}}],["消息触发词",{"2":{"262":1}}],["消息文本分词",{"2":{"262":1}}],["消息文本",{"2":{"262":4}}],["消息内",{"2":{"262":1}}],["消息内图片",{"2":{"262":1}}],["消息内表情",{"2":{"262":1}}],["消息id",{"2":{"256":1}}],["消息都必须由",{"2":{"228":1,"273":1}}],["消息撤回等一系列子事件",{"2":{"224":1}}],["消息体",{"2":{"222":1}}],["消息体里的",{"2":{"222":1}}],["消息过滤器",{"0":{"214":1}}],["消息才会返回到当前等待处",{"2":{"213":1}}],["消息类型",{"2":{"170":2,"172":2,"262":1,"264":1}}],["消息扩展暂仅支持",{"2":{"170":1}}],["消息通知",{"2":{"169":1}}],["消息弹窗内容",{"2":{"169":1}}],["消息的权限",{"2":{"166":1}}],["消息",{"0":{"162":1,"168":1},"1":{"163":1,"169":1},"2":{"162":1,"168":1,"178":1,"189":1,"192":1,"262":1}}],["消息创建完毕阶段",{"2":{"68":1}}],["消息生命周期",{"0":{"67":1},"1":{"68":1,"69":1,"70":1,"71":1,"72":1,"73":1}}],["消息记录和频道的消息",{"2":{"17":1}}],["消息记录和频道的机器人",{"2":{"16":1}}],["你们的鼎力支持让我们感到创作",{"2":{"408":1}}],["你对",{"2":{"406":1}}],["你就完成",{"2":{"401":1}}],["你必须部署第三方技术提供的服务才能继续部署兔兔",{"2":{"398":1}}],["你必须使用",{"2":{"217":1}}],["你仍然可以继续部署",{"2":{"396":1}}],["你仍然需要手动添加第三方包进插件",{"2":{"311":1}}],["你不能发布一个功能与官方版本相当接近的机器人",{"2":{"396":1}}],["你不能继续部署兔兔了",{"2":{"396":1}}],["你不需要手动控制",{"2":{"103":1}}],["你只需要解压更新包的",{"2":{"393":1}}],["你只需要直接调用接口即可",{"2":{"100":1}}],["你应该在控制台中填写实例配置单时相对应地修改端口值",{"2":{"377":1}}],["你应该添加一个文档并详细描述插件的使用方法",{"2":{"291":1}}],["你是否更新了插件",{"2":{"379":1}}],["你是否启动了两个mcl",{"2":{"377":1}}],["你是否人为移动了",{"2":{"371":1}}],["你是否在使用",{"2":{"362":1}}],["你是否在考虑使用可执行文件部署而不是代码部署",{"2":{"358":1}}],["你查询到的ip",{"2":{"363":1}}],["你需要修改兔兔本体的一些设置",{"2":{"363":1}}],["你已经可以使用它们了",{"2":{"349":1}}],["你可能需要克服一些困难才能顺利部署",{"2":{"398":1}}],["你可能需要将第三方库手动放进插件包内",{"2":{"309":1}}],["你可以基于",{"2":{"396":1}}],["你可以加入",{"2":{"396":1}}],["你可以直接使用官方版的兔兔啦",{"2":{"390":1}}],["你可以直接打包插件然后放到主项目中加载并使用来观察效果",{"2":{"306":1}}],["你可以选择",{"2":{"384":1}}],["你可以将它放在",{"2":{"348":1}}],["你可以根据这篇博客对你的连接进行加密",{"2":{"345":1}}],["你可以根据需要在启动前修改配置config",{"2":{"343":1}}],["你可以在插件被安装或卸载时执行一些操作",{"2":{"327":1}}],["你可以在你的插件文档内注明",{"2":{"310":1}}],["你可以在任何能获取到",{"2":{"255":1}}],["你可以通过对接控制台使用户能够使用控制台的界面管理你的插件",{"2":{"297":1}}],["你可以同时创建多个互不相关的实例",{"2":{"250":1}}],["你可以使机器人以更灵活的方式触发功能",{"2":{"246":1}}],["你可以收到如下的回复",{"2":{"205":1}}],["你可以一次插入很多张图片",{"2":{"205":1}}],["你可以创建一个独立的日志模块以标记输出",{"2":{"86":1}}],["你可以理解为使用了",{"2":{"81":1}}],["你可以介入这些周期来对业务进行进一步的调整",{"2":{"66":1}}],["你将会在诸多场景中看到",{"2":{"279":1}}],["你的快乐水带给我们快乐的同时",{"2":{"406":1}}],["你的插件将可能不支持",{"2":{"310":1}}],["你的业务逻辑必须在另一个入口文件内进行",{"2":{"302":1}}],["你的",{"2":{"245":1}}],["你预期会看到如下输出",{"2":{"245":1}}],["你都不需要实例化",{"2":{"228":1}}],["你也可以从",{"2":{"389":1}}],["你也可以调用",{"2":{"98":1}}],["你也可以全局修改日志模块",{"2":{"87":1}}],["你自定义的模块",{"2":{"87":1}}],["你几乎可以完全按照文档的开发方式进行",{"2":{"4":1}}],["统一以变量",{"2":{"65":1,"279":1}}],["更新兔兔",{"0":{"381":1}}],["更进一步",{"2":{"363":1}}],["更偏向于提供给",{"2":{"293":1}}],["更多类型请查看左侧导航消息构建元素",{"2":{"273":1}}],["更多功能",{"2":{"196":1}}],["更换云服务器镜像",{"2":{"362":1}}],["更换字体",{"0":{"206":1}}],["更换渲染",{"0":{"191":1}}],["更有助于用户灵活的管理自己的机器人功能",{"2":{"76":1}}],["更有逻辑性的机器人",{"2":{"65":1}}],["更改为使用新启动类启动浏览器",{"2":{"388":1}}],["更改适配器",{"2":{"243":1}}],["更改全局配置可以使用自己的",{"2":{"191":1}}],["更改你的实例",{"2":{"5":1}}],["更改默认适配器可以让你搭建其他平台的机器人",{"2":{"4":1}}],["这篇博文详尽的描述了部署",{"2":{"400":1}}],["这一点对mirai和兔兔两者都适用",{"2":{"380":1}}],["这种情况下",{"2":{"380":1}}],["这么一个机制",{"2":{"380":1}}],["这类报错的关键信息都在红色文本的最下方或者最上方",{"2":{"376":1}}],["这玩意儿可不兴展开来讲啊",{"2":{"373":1}}],["这就证明你配置好了",{"2":{"360":1}}],["这与设备性能等因素有关",{"2":{"354":1}}],["这并不是绝对的",{"2":{"332":1}}],["这并非",{"2":{"189":1}}],["这会使主模块的一些全局一等对象污染主体程序",{"2":{"305":1}}],["这意味着你完全可以按照",{"2":{"303":1}}],["这些消息响应器都会在插件被加载时注册到主体程序中",{"2":{"303":1}}],["这些消息事件会被归类并产出",{"2":{"219":1}}],["这些模块依赖第三方库或",{"2":{"289":1}}],["这些装饰器都来源于它们继承的工厂对象",{"2":{"284":1}}],["这非常重要",{"2":{"243":1}}],["这有点抽象",{"2":{"81":1}}],["这里将会发生另一种情况",{"2":{"81":1}}],["这是",{"2":{"360":1}}],["这是最简单的一条文本消息",{"2":{"273":1}}],["这是个人迈出的一小步",{"2":{"245":1}}],["这是符合预期的",{"2":{"215":1}}],["这是在不考虑文件大小",{"2":{"79":1}}],["这是写有插件注册代码的一个",{"2":{"79":1}}],["这是正常的做法",{"2":{"78":1}}],["这将有助于你构建一个复杂的",{"2":{"65":1}}],["这个东西吧",{"2":{"373":1}}],["这个现象大概率是因为设备的环境变量没有配置好导致的",{"2":{"360":1}}],["这个命名是固定的",{"2":{"305":1}}],["这个过程在运转中心内称为",{"2":{"288":1}}],["这个",{"2":{"48":1}}],["扩展",{"0":{"64":1}}],["扩展查询",{"0":{"36":1},"1":{"37":1,"38":1}}],["字母组合等弱口令作为",{"2":{"343":1}}],["字典",{"2":{"324":1,"325":2}}],["字体文件更换字体",{"2":{"206":1}}],["字段",{"2":{"320":1,"321":1}}],["字段定义在",{"2":{"316":1}}],["字段配置",{"2":{"315":1}}],["字段内容",{"2":{"222":1}}],["字段数据",{"2":{"169":1}}],["字段并匹配参数的值",{"2":{"63":1}}],["字符串或",{"2":{"296":1}}],["字符串",{"2":{"48":1,"237":1}}],["接入流程",{"2":{"264":1}}],["接下来",{"2":{"263":1}}],["接下来的文档将围绕",{"2":{"243":1}}],["接受",{"2":{"220":1}}],["接受一个事件名或事件名列表作为参数",{"2":{"220":1}}],["接受一个",{"2":{"5":1}}],["接收消息",{"0":{"260":1},"1":{"261":1,"262":1,"263":1}}],["接收指定前缀的消息",{"0":{"234":1}}],["接收不包含前缀的消息",{"0":{"233":1}}],["接收到符合期望的消息后再返回到等待处",{"2":{"214":1}}],["接收一个",{"2":{"185":1}}],["接收的消息和事件",{"2":{"66":1}}],["接口",{"2":{"101":1,"102":1,"103":1}}],["接口的路由将默认使用控制器类名以及方法名组成",{"2":{"62":1}}],["访问密钥",{"2":{"339":1}}],["访问测试网址并使用",{"2":{"307":1}}],["访问",{"2":{"61":1,"280":1,"328":1,"345":1}}],["页面",{"2":{"186":1,"363":1}}],["页面生成的图片",{"2":{"181":1}}],["页面注释",{"2":{"61":1}}],["页面标题",{"2":{"61":1}}],["页行数",{"2":{"42":1}}],["自定义检查的结果",{"2":{"262":1}}],["自定义检查结果",{"2":{"239":1}}],["自定义检查是一个协程函数",{"2":{"239":1}}],["自定义检查",{"0":{"239":1},"1":{"240":1,"241":1}}],["自定义校验方法",{"2":{"230":1}}],["自定义按钮通过内置的",{"2":{"196":1}}],["自定义按钮",{"0":{"196":1}}],["自定义",{"2":{"193":1}}],["自定义执行时机",{"0":{"95":1}}],["自定义定时任务时",{"2":{"94":1}}],["自定义循环规则",{"2":{"91":1}}],["自定义全局日志模块",{"0":{"87":1}}],["自定义路由",{"0":{"62":1}}],["自定义请求",{"0":{"56":1}}],["自定义资源服务",{"0":{"22":1},"1":{"23":1}}],["唯一不同的是请求体仅接受字典类型",{"2":{"54":1}}],["表情id",{"2":{"175":1}}],["表情",{"0":{"174":1},"1":{"175":1},"2":{"201":1}}],["表示已经实例化的",{"2":{"65":1,"279":1}}],["表单字段就是对应内容",{"2":{"336":1,"337":1}}],["表单tips",{"2":{"316":1}}],["表单标题",{"2":{"316":1}}],["表单提交",{"2":{"102":1}}],["表单的方式提交文件",{"2":{"55":1}}],["表单数据中存放文件的字段名",{"2":{"55":1}}],["表单数据",{"2":{"54":1}}],["表单请求",{"0":{"54":1}}],["表结构管理",{"0":{"35":1}}],["追加的请求头",{"2":{"53":1,"54":1,"55":1,"57":1,"58":1}}],["内的导入语句",{"2":{"310":1}}],["内",{"2":{"307":1}}],["内编写多余的代码",{"2":{"305":1}}],["内编写插件的注册程序",{"2":{"303":1}}],["内部的",{"2":{"305":1}}],["内导出插件的入口",{"2":{"305":1}}],["内含这则消息相关的各项属性",{"2":{"260":1}}],["内含预解析的消息内容",{"2":{"228":1}}],["内含等待事件的实例",{"2":{"216":1}}],["内需要实现以下方法获取到",{"2":{"191":1}}],["内核启动",{"2":{"388":1}}],["内核",{"2":{"182":1,"388":1}}],["内置多种适配器兼容不同的服务来源以及丰富的消息构建类型",{"2":{"281":1}}],["内置的小黄人表情",{"2":{"174":1}}],["内置了丰富的消息构建方法和适配器",{"2":{"403":1}}],["内置了全局的用户层面异常捕获让程序不会轻易崩溃",{"2":{"225":1}}],["内置了基于",{"2":{"59":1}}],["内置了异步的",{"2":{"47":1}}],["内置了部分扩展查询",{"2":{"36":1}}],["内容文本",{"2":{"200":1,"203":1}}],["内容",{"2":{"49":1}}],["但同时我们希望你量力而为",{"2":{"406":1}}],["但对比其他第三方服务",{"2":{"400":1}}],["但之中的一部分代码服务于其本身的",{"2":{"389":1}}],["但请注意",{"2":{"381":1}}],["但兔兔就是不理人",{"0":{"380":1}}],["但你仍然需要在配置里随便填写一个",{"2":{"338":1}}],["但你可以配合",{"2":{"258":1}}],["但你不希望在处理业务时错过子频道内的消息",{"2":{"218":1}}],["但后者可以通过另外的方法达到撤回效果",{"2":{"257":1}}],["但却是人类迈出的一大步",{"2":{"245":1}}],["但是在同一个局域网内",{"2":{"363":1}}],["但是在构建阶段",{"2":{"219":1}}],["但是我在黑框内输入git后还是会显示",{"2":{"360":1}}],["但是基本没插件适配",{"2":{"339":1}}],["但是",{"2":{"217":1}}],["但必须注意的事",{"2":{"87":1}}],["但如果路径已存在",{"2":{"81":1}}],["但为了方便传播",{"2":{"81":1}}],["但在设计时加入了限制",{"2":{"283":1}}],["但在本框架的设计里",{"2":{"77":1}}],["但在使用一些标准或第三方库时",{"2":{"24":1}}],["但本篇并不是作为主项目的引导文档",{"2":{"77":1}}],["但有些不一样",{"2":{"48":1}}],["但其请求方法均为同步的",{"2":{"47":1}}],["库",{"2":{"47":1}}],["库里提供的利用线程池将同步方法转变为异步方法执行的函数",{"2":{"25":1}}],["不支持",{"2":{"387":1}}],["不再继续提供支持",{"2":{"385":1,"387":1}}],["不再支持全局定义定时任务",{"2":{"91":1}}],["不过部分解决思路也可用在gocq中",{"2":{"364":1}}],["不是内部或外部命令",{"2":{"360":2}}],["不可能出现的新干员",{"0":{"355":1}}],["不可使用参数",{"2":{"94":1}}],["不推荐您使用纯数字",{"2":{"343":1}}],["不推荐使用",{"2":{"47":1}}],["不配置则使用",{"2":{"316":1}}],["不传入",{"2":{"277":1}}],["不包含触发词",{"2":{"262":3}}],["不包括",{"2":{"236":1}}],["不发送消息",{"2":{"258":1}}],["不清除消息队列",{"0":{"218":1}}],["不会像",{"2":{"217":1}}],["不用的适配器下",{"2":{"98":1}}],["不能保证其方法是异步的",{"2":{"24":1}}],["请耐心根据教程部署完",{"2":{"401":1}}],["请按照",{"2":{"399":1}}],["请按下面的配置说明进行配置",{"2":{"333":1}}],["请在",{"2":{"397":1}}],["请在安装依赖后阅读适配器文档",{"2":{"243":1}}],["请参阅",{"2":{"396":1}}],["请参考",{"2":{"339":1,"360":1}}],["请参考自定义资源服务",{"2":{"19":1}}],["请参考文档",{"2":{"17":1,"363":1}}],["请关注插件商店和频道的公告",{"2":{"394":1}}],["请关注",{"2":{"393":1}}],["请关闭一个",{"2":{"377":1}}],["请谨慎选择此方式",{"2":{"389":1}}],["请更新兔兔版本后再试",{"2":{"379":1}}],["请更新代码",{"2":{"378":1}}],["请将mcl",{"2":{"371":1}}],["请检查mirai的启动情况与配置文件",{"2":{"380":1}}],["请检查mirai是否正确登陆了bot的qq",{"2":{"365":1}}],["请检查项目官网是否有更新的版本",{"2":{"379":1}}],["请检查你的网络连接或是否开启了代理软件",{"2":{"361":1}}],["请自行配置服务密钥",{"2":{"363":1}}],["请自行百度",{"2":{"363":1}}],["请自行百度或联系百度智能云的支持服务",{"2":{"351":1}}],["请改为http后再重新尝试访问",{"2":{"363":1}}],["请根据操作系统按顺序执行以下命令",{"2":{"388":1}}],["请根据文档安装",{"2":{"360":1}}],["请根据插件文档配置相关信息",{"2":{"351":1}}],["请准确填写你部署",{"2":{"339":1,"340":1}}],["请理解为卡池在现在复刻了",{"2":{"355":1}}],["请理解",{"2":{"332":1}}],["请牢记你的密钥",{"2":{"329":1}}],["请不要在",{"2":{"305":1}}],["请阅读接下来的文档",{"2":{"389":1}}],["请阅读开发指南",{"2":{"389":1}}],["请阅读",{"2":{"297":1}}],["请移步",{"2":{"278":1}}],["请务必设定",{"2":{"343":1}}],["请务必让你的业务逻辑有机会关闭等待事件",{"2":{"217":1}}],["请务必通过反向代理加密连接",{"2":{"345":1}}],["请务必通过",{"2":{"93":1}}],["请酌情阅读",{"2":{"105":1}}],["请注意文档中提供的",{"2":{"358":1}}],["请注意可能产生的影响",{"2":{"98":1}}],["请注意",{"2":{"98":1,"217":1,"351":1}}],["请使用代码部署",{"2":{"385":1,"387":1}}],["请使用组合键",{"2":{"360":1}}],["请使用单引号",{"2":{"343":1}}],["请使用",{"2":{"94":1,"103":1}}],["请求参数",{"2":{"103":1}}],["请求头密钥",{"0":{"63":1},"2":{"61":1}}],["请求过程的",{"2":{"56":1}}],["请求方法",{"2":{"56":1}}],["请求体",{"2":{"53":1,"54":1,"55":1}}],["请求体仅接受字典或列表类型数据",{"2":{"53":1}}],["请求地址",{"2":{"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1}}],["请求工具库",{"2":{"47":1}}],["请求工具",{"2":{"47":1}}],["请求",{"0":{"47":1,"52":1,"53":1},"1":{"48":1,"49":1,"50":1,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1},"2":{"103":2,"104":1}}],["发布到插件商店",{"0":{"328":1},"1":{"329":1}}],["发布事件",{"0":{"44":1}}],["发生该事件的",{"2":{"221":1}}],["发挥你的想象",{"2":{"185":1}}],["发送合并转发消息",{"2":{"276":1}}],["发送主动消息",{"0":{"264":1},"1":{"265":1,"266":1,"267":1,"268":1,"269":1,"270":1,"271":1}}],["发送消息也存在数量限制",{"2":{"264":1}}],["发送消息",{"0":{"272":1},"1":{"273":1,"274":1,"275":1,"276":1,"277":1,"278":1},"2":{"258":1}}],["发送消息的方法",{"2":{"257":1}}],["发送的消息",{"0":{"257":1},"1":{"258":1,"259":1},"2":{"257":1}}],["发送频道跳转超链接",{"2":{"197":1}}],["发送含有消息按钮组件的消息",{"2":{"194":1}}],["发送一条主动私信",{"0":{"267":1}}],["发送一条主动子频道消息",{"0":{"266":1}}],["发送一条消息",{"2":{"263":1}}],["发送一段",{"2":{"207":1,"209":1}}],["发送一段文字消息",{"2":{"199":1}}],["发送一张",{"2":{"205":1}}],["发送一张图片",{"2":{"187":1}}],["发送一张使用",{"2":{"181":1}}],["发送一个百度首页链接分享",{"2":{"172":1}}],["发送一个点数",{"2":{"172":1}}],["发送时间",{"2":{"177":1}}],["发送请求时会被构建为",{"2":{"54":1}}],["发送",{"0":{"47":1,"173":1,"180":1},"1":{"48":1,"49":1,"50":1,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1},"2":{"162":1,"164":1,"166":1,"168":1,"173":2,"180":1,"189":2,"192":1}}],["且",{"2":{"224":1}}],["且需要保证其内存地址是一致的",{"2":{"46":1}}],["且调用",{"2":{"15":1,"248":1}}],["订阅事件",{"0":{"45":1}}],["e6",{"2":{"339":2}}],["e7",{"2":{"339":2}}],["e4",{"2":{"339":1}}],["elif",{"2":{"240":1}}],["equal",{"2":{"236":3,"237":4}}],["everyday",{"2":{"360":1}}],["everyone",{"2":{"216":1}}],["eventtype",{"2":{"74":1}}],["event",{"0":{"217":1,"221":1},"2":{"43":1,"44":1,"45":6,"46":2,"74":2,"216":7,"217":1,"219":2,"220":12,"221":1,"222":7,"223":3,"224":9,"225":2,"226":1,"227":1,"255":1,"257":1,"270":3,"271":1,"303":3}}],["embed",{"0":{"168":1,"169":1},"1":{"169":1},"2":{"168":1,"169":2}}],["empty",{"2":{"147":2,"360":1}}],["emoji",{"0":{"174":1},"1":{"175":1},"2":{"106":2,"119":2,"139":2}}],["envvar",{"2":{"360":1}}],["env=",{"2":{"360":1}}],["enum",{"2":{"300":1,"320":1}}],["enableverify",{"2":{"340":1}}],["enabled",{"2":{"339":1}}],["enable",{"2":{"253":1}}],["enter",{"2":{"165":1}}],["end",{"2":{"112":1,"151":1,"152":1,"154":1,"156":1}}],["encode",{"2":{"23":1}}],["each=60",{"2":{"92":1,"93":1,"97":1}}],["each=120",{"2":{"91":1}}],["each",{"2":{"91":1,"94":1}}],["err",{"2":{"85":3,"225":1,"226":1,"227":1,"255":1,"271":1,"363":1}}],["error",{"0":{"51":1,"375":1},"2":{"51":2,"81":1,"84":1,"85":6,"87":1}}],["e",{"2":{"85":2}}],["existing",{"2":{"360":1}}],["extend",{"0":{"171":1},"1":{"172":1},"2":{"172":2,"173":1}}],["extract",{"2":{"81":4,"307":1}}],["exec",{"2":{"360":1}}],["exe",{"2":{"90":1,"386":1,"393":1}}],["except",{"2":{"85":1}}],["exception",{"2":{"51":1,"85":5,"225":3,"226":2,"227":2,"255":2,"271":2}}],["分配到消息处理的数据",{"2":{"288":1}}],["分配器和日志",{"2":{"287":1}}],["分配器会按照加载的先后顺序选择",{"2":{"238":1}}],["分配器的工作原理",{"2":{"238":1}}],["分别是",{"2":{"225":1,"228":1}}],["分别为时间",{"2":{"84":1}}],["分",{"2":{"95":1}}],["分页查询工具",{"2":{"42":1}}],["分片插入大小",{"2":{"37":1}}],["分片总数",{"2":{"14":1,"19":1}}],["分片下标",{"2":{"14":1,"19":1}}],["分片连接loadbalance",{"2":{"14":1,"20":1}}],["一路走来离不开大家的默默支持",{"2":{"406":1}}],["一直以来",{"2":{"404":1}}],["一种是由腾讯官方运营的",{"2":{"395":1}}],["一些常见的细节我将会省略不解释",{"2":{"378":1}}],["一些内置的资源对象不会重复创建多个",{"2":{"250":1}}],["一篇通过",{"2":{"345":1}}],["一样使用它来注册你的功能",{"2":{"251":1}}],["一样的所有方法",{"2":{"251":1}}],["一般来说",{"2":{"306":1}}],["一般来说消息",{"2":{"219":1}}],["一般用于预构建消息",{"2":{"277":1}}],["一般就是通过响应用户的消息实现的",{"2":{"229":1}}],["一般功能的优先级默认为",{"2":{"213":1}}],["一般情况下应该遵循异步编程来进行开发",{"2":{"24":1}}],["一个列的列表",{"2":{"38":1}}],["构成的列表",{"2":{"237":1}}],["构成约束的列",{"2":{"38":1}}],["构建消息的方法",{"0":{"274":1},"1":{"275":1,"276":1}}],["构建浏览器渲染的图片同样也会调用一次",{"2":{"31":1}}],["构建浏览器渲染的图片并打开了页面时调用",{"2":{"31":1}}],["构建视频消息时调用",{"2":{"30":1}}],["构建语音消息时调用",{"2":{"29":1}}],["构建图片消息时调用",{"2":{"28":1}}],["构建媒体消息时的操作",{"0":{"26":1},"1":{"27":1,"28":1,"29":1,"30":1,"31":1}}],["插入并启动一个实例",{"2":{"253":1}}],["插入后立即启动",{"2":{"253":1}}],["插入一个实例",{"2":{"253":1}}],["插入图片",{"2":{"203":1}}],["插入表情",{"0":{"201":1}}],["插入或更新",{"2":{"38":1}}],["插件同样也不会自动更新",{"2":{"394":1}}],["插件更新",{"0":{"394":1}}],["插件shellgit",{"2":{"378":1}}],["插件常见问题",{"0":{"350":1},"1":{"351":1,"352":1,"353":1,"354":1,"355":1,"356":1}}],["插件通常是一个zip压缩包或是",{"2":{"348":1}}],["插件密钥",{"0":{"329":1}}],["插件商店可以实时查看有新版本的插件",{"2":{"347":1}}],["插件商店",{"2":{"328":1}}],["插件被卸载时执行的操作",{"2":{"327":1}}],["插件被安装时执行的操作",{"2":{"327":1}}],["插件生命周期",{"0":{"327":1}}],["插件对接控制台的配置文件",{"2":{"315":1}}],["插件并不强制要求在",{"2":{"312":1}}],["插件推荐发布为",{"2":{"308":1}}],["插件在加载时",{"2":{"305":1}}],["插件内静态资源的使用",{"0":{"304":1}}],["插件添加依赖后",{"2":{"301":1}}],["插件id",{"2":{"301":1}}],["插件初次安装初次加载时",{"2":{"300":1}}],["插件加载时会进行下面的校验",{"2":{"300":1}}],["插件依赖",{"2":{"296":1}}],["插件与账号实例都属于",{"2":{"283":1}}],["插件设计",{"0":{"283":1}}],["插件设计的目的是因为",{"2":{"76":1}}],["插件实例都有一个唯一",{"2":{"82":1}}],["插件实例可以直接在你的程序里定义",{"2":{"78":1}}],["插件解压后的目录名",{"2":{"81":1}}],["插件",{"2":{"81":1,"82":1}}],["插件将会",{"2":{"81":1}}],["插件还能有另外几种导入方式",{"2":{"77":1}}],["插件是一个",{"2":{"77":1}}],["插件开发文档",{"2":{"93":1}}],["插件开发详情请查看",{"2":{"93":1}}],["插件开发",{"0":{"93":1},"2":{"77":1}}],["插件的工作原理以及插件导入和卸载的方法",{"2":{"75":1}}],["插件接口修改而来的通用聊天机器人应用接口标准",{"2":{"9":1}}],["length",{"2":{"89":1,"90":1}}],["level=2",{"2":{"238":1}}],["level=1",{"2":{"238":1}}],["levelname",{"2":{"86":1}}],["level",{"2":{"86":1,"212":1,"216":1,"230":1}}],["launcher",{"2":{"388":1}}],["launch",{"2":{"88":6,"183":2,"388":1}}],["last",{"2":{"81":1,"85":1}}],["lt",{"2":{"81":2,"85":1,"185":5,"316":5,"317":1,"318":2,"319":1,"320":1,"321":1,"323":1,"324":1,"325":1,"360":12}}],["lib",{"2":{"205":1,"206":1}}],["lift",{"0":{"153":1,"155":1,"157":1}}],["limit",{"2":{"132":1,"134":1,"135":1,"139":1,"339":2}}],["linux",{"0":{"387":1},"2":{"181":2,"182":1,"382":2,"385":2,"387":3,"388":3}}],["link",{"0":{"110":1}}],["line",{"2":{"81":4,"85":1}}],["list",{"0":{"41":1},"2":{"37":1,"38":2,"41":2,"42":1,"53":1,"85":1,"109":1,"156":1,"157":1,"163":1,"169":1,"177":1,"193":1,"203":1,"262":4,"296":1}}],["load",{"2":{"81":2,"388":1}}],["logger",{"2":{"86":3,"87":1}}],["loggermanager",{"2":{"86":3}}],["logging",{"2":{"83":1,"84":1,"86":1}}],["logtest",{"2":{"85":1}}],["log",{"2":{"56":1,"81":1,"84":7,"85":5,"86":4,"87":1}}],["locator",{"2":{"31":2}}],["批量插入",{"2":{"37":1}}],["方便日常使用",{"2":{"36":1}}],["方法将返回以下内容",{"2":{"326":1}}],["方法返回",{"2":{"323":1,"324":1}}],["方法返回一个",{"2":{"257":1}}],["方法时的参数",{"2":{"316":1}}],["方法代替",{"2":{"258":1}}],["方法生成消息链",{"2":{"228":1}}],["方法名",{"2":{"216":1,"263":1}}],["方法不同的是",{"2":{"216":1}}],["方法不仅可以传入字符串",{"2":{"85":1}}],["方法用于等待子频道全体成员的回复",{"2":{"216":1}}],["方法你需要知道的事",{"0":{"215":1}}],["方法实现一个简单的连续对话",{"2":{"212":1}}],["方法实例化它的适配器",{"2":{"7":1}}],["方法会认为值为本地图片的路径并尝试读取文件",{"2":{"188":1}}],["方法内设置参数",{"2":{"183":1}}],["方法内部实现了不同平台的鉴权规则",{"2":{"100":1,"103":1}}],["方法以",{"2":{"55":1}}],["方法",{"0":{"263":1},"2":{"54":1,"56":1,"58":1,"88":1,"185":2,"216":1,"255":2,"256":1,"272":1}}],["方法类似",{"2":{"54":1}}],["方法默认在请求头内添加",{"2":{"53":1}}],["方法默认创建",{"2":{"33":1}}],["方法即可使用",{"2":{"47":1}}],["装饰器去获取事件",{"2":{"219":1}}],["装饰器",{"0":{"94":1,"229":1},"1":{"95":1,"230":1},"2":{"229":1,"279":1}}],["装饰器的",{"2":{"91":1}}],["装饰器进行表结构管理",{"2":{"33":1}}],["装饰的表模型内增加或删除字段",{"2":{"35":1}}],["文字只有一行",{"2":{"205":1}}],["文字内容",{"2":{"204":1}}],["文字生成的图片",{"0":{"202":1},"1":{"203":1,"204":1,"205":1,"206":1}}],["文字",{"0":{"199":1},"1":{"200":1,"201":1}}],["文本输入框",{"0":{"317":1},"2":{"324":1}}],["文本量大时",{"2":{"190":1}}],["文本",{"2":{"190":1,"191":1}}],["文本渲染的图片",{"2":{"189":1}}],["文件夹重新启动程序即可",{"2":{"361":1}}],["文件夹内的内容产生了变动",{"2":{"361":1}}],["文件夹",{"2":{"310":1}}],["文件夹下",{"2":{"84":1}}],["文件路径作为文档",{"2":{"292":1}}],["文件路径",{"2":{"210":1,"296":2}}],["文件路径或",{"2":{"28":1}}],["文件渲染",{"2":{"191":1}}],["文件导入这个插件",{"2":{"79":1}}],["文件名",{"2":{"55":1,"81":1}}],["文件",{"0":{"79":1,"191":1},"2":{"55":1,"79":1,"81":1,"297":1,"300":1}}],["文件上传",{"0":{"55":1},"2":{"55":1}}],["文档中的内容可能不会一直维护",{"2":{"332":1}}],["文档尚处于建设阶段",{"2":{"105":1}}],["文档",{"0":{"292":1},"2":{"33":1}}],["将快乐带给所有人",{"2":{"405":1}}],["将旧兔兔的",{"2":{"381":1}}],["将protocol更改为ipad",{"2":{"372":1}}],["将协议换为ipad",{"2":{"372":1}}],["将host的值修改为0",{"2":{"363":1}}],["将可能因类型错误无法识别",{"2":{"343":1}}],["将整个插件文件夹压缩为",{"2":{"309":1}}],["将返回",{"2":{"293":1}}],["将返回到等待处",{"2":{"214":1}}],["将被所有包含的",{"2":{"251":1}}],["将储存在",{"2":{"239":1}}],["将指定文字内容改变颜色",{"2":{"204":1}}],["将有可能不显示在图片内",{"2":{"186":1}}],["将需要渲染的数据传入模板",{"2":{"185":1}}],["将默认日志处理替换为自定义的类",{"2":{"87":1}}],["将输出如下日志",{"2":{"85":1}}],["将会使用",{"2":{"296":1}}],["将会对数据和业务模块收集的消息响应器",{"2":{"288":1}}],["将会发送主动私信消息",{"2":{"267":1}}],["将会失效",{"2":{"230":1}}],["将会触发该函数",{"2":{"229":1}}],["将会强制转换为图片",{"2":{"204":1}}],["将会输出完整的异常追踪",{"2":{"85":1}}],["将会自动创建或更新表结构",{"2":{"33":1}}],["将不会覆盖原文件",{"2":{"81":1}}],["将不会再在代码示例中出现",{"2":{"65":1,"279":1}}],["将",{"2":{"81":1,"343":1,"363":1}}],["将一些功能模块分散为插件的形式",{"2":{"76":1}}],["将结束生命周期",{"2":{"68":1}}],["将影响后续所有周期进程的参数",{"2":{"68":1}}],["将查询结果转换为字典列表",{"2":{"41":1}}],["将查询结果转换为字典",{"2":{"40":1}}],["将通过校验的候选函数列表按优先级倒序排序",{"2":{"238":1}}],["将通过",{"2":{"7":1}}],["new",{"2":{"360":1}}],["net",{"2":{"340":1,"364":3,"377":1}}],["network",{"2":{"47":2,"58":1,"363":3}}],["nginx",{"2":{"345":1}}],["number",{"2":{"318":2,"323":1,"326":2}}],["nums",{"0":{"127":1}}],["nudgeevent",{"2":{"223":3}}],["null=true",{"2":{"33":1,"35":2}}],["node",{"2":{"179":2,"362":1}}],["notify",{"2":{"224":5}}],["notice",{"2":{"224":11}}],["not",{"2":{"89":1,"90":1,"258":1}}],["normal",{"2":{"84":1}}],["no",{"2":{"81":1,"360":2}}],["none",{"2":{"19":1,"38":3,"40":1,"44":1,"45":1,"46":1,"68":1,"85":2,"94":1,"101":1,"102":1,"103":1,"108":4,"109":6,"111":2,"112":3,"114":1,"135":2,"139":1,"149":4,"150":2,"151":3,"159":2,"160":2,"161":1,"203":3,"215":1,"256":1,"257":1,"273":1,"296":6,"298":2,"299":1,"301":1}}],["nickname=",{"2":{"176":1,"177":1,"179":1}}],["nickname",{"2":{"78":1,"79":1,"173":2,"176":1,"177":3,"185":1,"204":1,"229":1,"233":1,"234":1,"235":1,"236":1,"237":1,"238":1,"239":1,"242":2,"245":1,"250":2,"251":1,"257":1,"262":1,"272":1,"280":1,"303":1}}],["namespace=",{"2":{"360":1}}],["name2",{"2":{"318":1}}],["name=",{"2":{"78":1,"79":1,"295":1,"303":1,"327":1}}],["name",{"2":{"33":1,"34":1,"44":1,"45":1,"46":1,"56":1,"61":1,"62":1,"70":1,"71":1,"72":1,"73":1,"86":2,"109":1,"111":1,"112":1,"149":1,"150":1,"151":1,"212":1,"214":1,"216":1,"221":1,"222":2,"241":4,"251":1,"258":1,"298":2,"299":2,"316":6,"317":1,"318":1,"319":1,"320":1,"321":1,"323":1,"324":1,"325":1,"326":2,"360":3,"388":1}}],["足以应对大部分的日常操作",{"2":{"33":1}}],["对小白来说",{"2":{"371":1}}],["对mcl一切配置文件的更改都应该在mcl不在运行的情况下进行",{"2":{"370":1}}],["对mirai来说",{"2":{"364":1}}],["对于可执行文件部署",{"2":{"381":1}}],["对于linux",{"2":{"353":1}}],["对于windows",{"2":{"353":1}}],["对于轻量级机器人应用",{"2":{"33":1}}],["对应的文件位置在",{"2":{"352":1}}],["对提供的",{"2":{"300":1}}],["对接控制台",{"0":{"297":1},"1":{"298":1,"299":1,"300":1}}],["对其进行了三级分类",{"2":{"224":1}}],["对其进行了分类",{"2":{"224":1}}],["对后续不产生影响",{"2":{"68":1}}],["对象数组",{"0":{"324":1}}],["对象里",{"2":{"316":1}}],["对象继承了工厂类",{"2":{"303":1}}],["对象创建插件",{"2":{"293":1}}],["对象创建一个功能组",{"2":{"231":1}}],["对象构建的",{"2":{"277":1}}],["对象时",{"2":{"277":1}}],["对象支持链式语法",{"2":{"275":1}}],["对象提供丰富的消息构建方式",{"2":{"273":1}}],["对象提供的属性完成业务逻辑",{"2":{"263":1}}],["对象是构建你的消息体的工具类",{"2":{"273":1}}],["对象是接收到消息之后预处理化的一个消息数据对象",{"2":{"260":1}}],["对象内的消息文本系列字段将不再包含触发对话的前缀",{"2":{"261":1}}],["对象内置了连续对话支持",{"2":{"211":1}}],["对象并注解在对应地方",{"2":{"260":1}}],["对象并返回",{"2":{"68":1,"71":1}}],["对象中撤回",{"0":{"255":1}}],["对象和",{"2":{"220":1}}],["对象将会调用",{"2":{"185":1}}],["对象的地方使用",{"2":{"255":1}}],["对象的",{"2":{"255":1,"272":1,"292":1}}],["对象的列表",{"2":{"205":1}}],["对象的方法",{"2":{"176":1}}],["对象的用户",{"2":{"165":1}}],["对象发送或扩展消息发送",{"2":{"173":1}}],["对象在此仅用于参数类型注解",{"2":{"228":1}}],["对象在实例化的时候",{"2":{"165":1}}],["对象在构建消息时",{"2":{"26":1,"278":1}}],["对象转换文字图片的文字长度最大值",{"2":{"89":1}}],["对象受上一个函数的执行结果影响",{"2":{"68":1,"71":1}}],["对象注册周期钩子函数",{"2":{"67":1}}],["对象或其组成的列表",{"2":{"257":1}}],["对象或等待函数",{"2":{"257":1}}],["对象或",{"2":{"67":1}}],["对象",{"0":{"221":1,"261":1,"273":1},"1":{"262":1,"263":1},"2":{"31":1,"68":1,"88":1,"92":1,"170":1,"177":1,"212":1,"216":3,"219":2,"228":1,"235":1,"239":2,"252":1,"255":1,"256":1,"262":1,"265":2,"272":1,"273":1}}],["对象拥有一个适配器参数",{"2":{"5":1}}],["温馨提示",{"2":{"32":1,"170":1,"341":1,"370":1}}],["封装了部分表结构管理以及查询转换",{"2":{"32":1}}],["基本配置",{"0":{"316":1},"2":{"324":1,"325":1}}],["基础开发指南",{"2":{"290":1}}],["基础指南",{"2":{"13":1}}],["基于异步i",{"2":{"281":1}}],["基于",{"2":{"32":1,"47":1,"91":1,"403":1}}],["支持同时启动多个账号",{"2":{"249":1}}],["支持由",{"2":{"237":1}}],["支持多种类型",{"2":{"230":1}}],["支持直接使用网站url生成图片",{"2":{"186":1}}],["支持",{"2":{"32":1}}],["queryselector",{"2":{"185":1}}],["query",{"0":{"41":1},"2":{"41":2}}],["quot",{"2":{"31":6,"81":8,"85":2,"185":2,"222":42,"223":24,"224":12,"238":2,"315":12,"316":20,"317":12,"318":22,"319":10,"320":16,"321":12,"322":4,"323":14,"324":16,"325":10,"326":54,"343":2}}],["qq群机器人",{"0":{"337":1,"339":1,"340":1}}],["qq频道机器人",{"0":{"336":1}}],["qq开放平台",{"2":{"243":1,"245":1}}],["qqgroupchainbuilderoptions",{"2":{"19":1,"21":2}}],["qqgroup",{"2":{"19":1,"21":2}}],["qqglobal",{"2":{"17":1}}],["qqguildapi",{"2":{"99":2}}],["qqguildsandboxbotinstance",{"2":{"15":2,"248":2}}],["qqguild",{"2":{"14":1,"15":1,"99":1,"248":1}}],["qqguildbotinstance",{"2":{"5":2}}],["qq",{"0":{"13":1,"16":1,"18":1,"105":1,"398":1},"1":{"14":1,"15":1,"17":1,"19":1,"20":1,"21":1,"22":1,"23":1,"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1,"115":1,"116":1,"117":1,"118":1,"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"157":1,"158":1,"159":1,"160":1,"161":1},"2":{"3":2,"5":1,"7":1,"8":2,"13":1,"14":4,"17":1,"18":3,"19":4,"20":1,"21":1,"102":1,"162":1,"163":1,"168":1,"174":1,"176":1,"177":2,"189":1,"192":1,"197":1,"201":1,"207":2,"209":2,"243":4,"245":2,"281":1,"336":1,"337":1,"339":1,"340":1,"395":1,"398":1,"403":2,"404":2}}],["函数中进行",{"2":{"300":1}}],["函数被执行时",{"2":{"260":1}}],["函数",{"2":{"31":1}}],["提示",{"2":{"31":1,"45":1,"84":1,"165":1,"167":1,"190":1,"236":1,"238":1,"269":1,"294":1,"301":1,"363":1,"392":1}}],["提供给",{"2":{"343":1}}],["提供了全局定时任务管理器",{"2":{"91":1}}],["提供了简易的全局事件总线的方法",{"2":{"43":1}}],["提供了",{"2":{"32":1,"300":1,"306":1}}],["提供了浏览器的",{"2":{"31":1}}],["提供了分片逻辑",{"2":{"14":1,"20":1}}],["提供",{"2":{"7":1,"300":1}}],["注册消息响应",{"2":{"260":1}}],["注册消息响应器",{"0":{"228":1},"1":{"229":1,"230":1,"231":1,"232":1,"233":1,"234":1,"235":1,"236":1,"237":1,"238":1,"239":1,"240":1,"241":1,"242":1}}],["注册的功能",{"2":{"251":1}}],["注册功能组",{"2":{"231":1}}],["注册事件响应",{"0":{"220":1},"1":{"221":1}}],["注入等",{"2":{"31":1}}],["注意",{"2":{"2":1,"14":1,"20":1,"81":1,"94":1,"176":1,"186":1,"189":1,"197":1,"207":1,"209":1,"216":1,"231":1,"305":1,"310":1,"311":1,"343":1,"353":1,"374":1,"377":1,"388":1}}],["进入",{"2":{"387":1}}],["进行校验",{"2":{"300":1}}],["进行封包后发送",{"2":{"288":1}}],["进行匹配",{"2":{"288":1}}],["进行中的业务将会被终止",{"2":{"215":1}}],["进行操作",{"2":{"31":1}}],["进阶开发指南",{"2":{"290":1}}],["进阶使用",{"2":{"183":1}}],["进阶指南",{"0":{"65":1},"2":{"23":1,"103":1,"104":1,"278":1}}],["传入的值均为字符串",{"2":{"296":1}}],["传入参数",{"2":{"267":1}}],["传入功能组对象设置组别",{"2":{"231":1}}],["传入功能组名称设置组别",{"2":{"231":1}}],["传入模板文件的数据",{"2":{"184":1}}],["传入",{"2":{"62":1,"85":1,"298":1,"299":1}}],["传入文件路径",{"2":{"29":1,"30":1}}],["传入一个参数",{"2":{"28":1}}],["传入辅助类实例即可介入",{"2":{"27":1}}],["每次启动时会检查资源仓库并更新新资源",{"2":{"392":1}}],["每次执行加载时都会解压一次全部文件",{"2":{"81":1}}],["每分钟的第",{"2":{"95":1}}],["每",{"2":{"92":1}}],["每个小时中的",{"2":{"95":1}}],["每个视频文件调用一次",{"2":{"30":1}}],["每个语音文件调用一次",{"2":{"29":1}}],["每个分片的启动应当按顺序缓慢进行",{"2":{"14":1,"20":1}}],["每张图片调用一次",{"2":{"28":1}}],["该设置为全局生效",{"2":{"339":1}}],["该过程发生在构造函数",{"2":{"300":1}}],["该对象主要应用在功能函数和自定义检查中",{"2":{"260":1}}],["该方法不可用于支持私信的功能里",{"2":{"216":1}}],["该",{"2":{"78":1}}],["该钩子函数可返回三种结果",{"2":{"68":1}}],["该函数会在",{"2":{"28":1,"29":1,"30":1,"31":1}}],["该标准是从原",{"2":{"9":1}}],["为所有人带来快乐",{"2":{"404":1}}],["为本框架的主体项目",{"2":{"389":1}}],["为mirai",{"2":{"364":1}}],["为你提供了一篇部署",{"2":{"400":1}}],["为你提供了",{"2":{"345":1}}],["为连接控制台时的密钥",{"2":{"343":1}}],["为登录在",{"2":{"339":1,"340":1}}],["为数组配置",{"2":{"323":1,"324":1}}],["为了防止加载插件时的全局环境变量污染",{"2":{"302":1}}],["为了减少篇幅量",{"2":{"65":1,"279":1}}],["为消息响应设置",{"2":{"231":1}}],["为机器人消息的创建工具",{"2":{"228":1}}],["为机器人实例",{"2":{"228":1}}],["为接收的消息主体",{"2":{"228":1}}],["为",{"2":{"179":1,"224":3,"318":2,"340":1,"406":1}}],["为必须参数",{"2":{"177":1}}],["为自定义的昵称",{"2":{"177":1}}],["为实际",{"2":{"177":1}}],["为什么没有",{"2":{"103":1}}],["为需要取消的定时任务传入",{"2":{"96":1}}],["为属性赋值使用辅助类",{"2":{"27":1}}],["为异步程序",{"2":{"24":1,"47":1}}],["类创建",{"2":{"228":1,"273":1}}],["类构建",{"2":{"196":1}}],["类的列表",{"2":{"301":1}}],["类的指令时",{"2":{"293":1}}],["类的",{"2":{"179":1,"228":1}}],["类的实例化代码",{"2":{"65":1,"279":1}}],["类注解",{"2":{"99":1}}],["类以注解变量",{"0":{"99":1}}],["类",{"0":{"61":1},"2":{"65":1,"279":1}}],["类并覆写其方法创建一个自定义的辅助类",{"2":{"27":1}}],["类型的数据",{"2":{"57":1}}],["类型为",{"2":{"28":1}}],["类型",{"2":{"1":1,"3":1,"8":1,"10":1,"12":1,"14":1,"19":1,"21":1,"25":1,"37":1,"38":1,"40":1,"41":1,"42":1,"44":1,"45":1,"46":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"61":1,"81":1,"82":1,"85":1,"86":1,"91":1,"94":1,"97":1,"101":1,"102":1,"103":1,"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1,"115":1,"116":1,"117":1,"118":1,"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"157":1,"158":1,"159":1,"160":1,"161":1,"163":1,"165":1,"169":1,"171":1,"175":1,"177":1,"178":1,"184":1,"188":2,"190":1,"193":1,"198":1,"200":1,"203":1,"205":1,"208":1,"210":1,"212":1,"216":2,"221":1,"230":1,"231":1,"239":1,"253":1,"256":1,"262":1,"265":1,"273":1,"296":1,"298":1,"299":1,"301":1,"316":1}}],["转变为异步执行",{"2":{"25":1}}],["原群聊机器人",{"2":{"404":1}}],["原内容",{"2":{"387":1}}],["原因是",{"2":{"362":1}}],["原",{"2":{"339":1}}],["原始文本",{"2":{"262":1}}],["原始消息字典",{"2":{"262":1}}],["原始消息类型格式数据",{"2":{"171":1}}],["原生模板",{"0":{"170":1},"1":{"171":1,"172":1,"173":1}}],["原生实现",{"2":{"2":1}}],["原方法字典参数",{"2":{"25":1}}],["原方法参数",{"2":{"25":1}}],["rt",{"2":{"366":1}}],["rm",{"2":{"360":1}}],["rate",{"2":{"339":2}}],["range",{"2":{"322":3}}],["r",{"2":{"235":1,"237":1,"388":1}}],["row2",{"2":{"196":3}}],["row",{"2":{"196":5}}],["rows",{"2":{"37":1}}],["roles",{"0":{"133":1,"134":1}}],["role",{"0":{"111":1,"117":1,"123":1,"142":1,"150":1,"159":1,"161":1},"2":{"117":1,"123":1,"134":1,"142":1,"150":1,"159":1,"161":1}}],["router",{"2":{"62":2}}],["route",{"2":{"61":2,"62":2}}],["root",{"2":{"34":1}}],["running",{"2":{"86":1}}],["run",{"0":{"25":1},"2":{"25":2,"61":1,"88":1,"94":1,"245":1,"250":1,"251":1,"280":1,"307":2,"311":2,"388":2}}],["rename",{"2":{"360":1}}],["render",{"2":{"31":1,"89":1,"90":1,"184":1,"186":2,"190":2}}],["rendered",{"0":{"31":1},"2":{"27":1,"31":1}}],["reinitialize",{"2":{"360":1}}],["repository",{"2":{"360":2}}],["replace",{"2":{"360":1}}],["reply",{"2":{"212":5,"214":4,"216":5,"255":3,"263":3}}],["readme",{"2":{"292":1,"293":2}}],["reactions",{"0":{"139":1}}],["reaction",{"0":{"106":1,"119":1}}],["reference",{"2":{"273":1}}],["re",{"2":{"235":2,"237":1}}],["required",{"2":{"315":2}}],["requirement",{"2":{"296":1,"301":5}}],["requirements=",{"2":{"301":1}}],["requirements",{"2":{"296":1,"301":1,"388":1}}],["request",{"0":{"103":1},"2":{"47":1,"52":1,"53":1,"54":1,"55":1,"56":4,"57":1,"58":1,"101":1,"102":1,"103":1}}],["requests",{"2":{"47":9,"48":1,"49":1,"50":1,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"363":2}}],["req",{"2":{"158":1}}],["remind",{"2":{"112":1,"151":1}}],["remove",{"0":{"97":1},"2":{"82":1,"97":1,"159":1,"160":1,"360":1}}],["recv",{"2":{"260":1}}],["recall",{"2":{"180":1,"255":6,"256":3,"257":4,"258":1,"263":1}}],["recipient",{"2":{"137":1}}],["recommend",{"2":{"108":1}}],["recent",{"2":{"81":1,"85":1}}],["relative",{"2":{"81":1}}],["restore",{"2":{"360":2}}],["reservedsyncid",{"2":{"340":1}}],["result",{"2":{"239":1}}],["response",{"0":{"50":1},"2":{"50":1,"61":1}}],["responsetext",{"2":{"49":1}}],["res",{"2":{"49":2,"50":1,"51":1}}],["resource",{"2":{"21":3,"361":2}}],["return",{"2":{"23":3,"27":3,"31":1,"61":2,"68":1,"70":2,"71":1,"78":1,"79":1,"88":3,"173":1,"185":1,"186":1,"204":1,"205":1,"208":1,"210":1,"212":1,"214":2,"229":1,"233":1,"234":1,"235":1,"236":1,"237":1,"238":2,"239":2,"240":3,"241":2,"242":2,"245":1,"250":2,"251":2,"257":2,"272":1,"280":1,"303":1}}],["影响业务逻辑",{"2":{"24":1}}],["阻塞的方法",{"2":{"25":2}}],["阻塞的方法容易造成线程阻塞",{"2":{"24":1}}],["阻塞的操作",{"0":{"24":1},"1":{"25":1}}],["处理阻塞操作",{"2":{"47":1}}],["处理",{"0":{"24":1},"1":{"25":1}}],["格式的音频",{"2":{"209":1}}],["格式的视频",{"2":{"207":1}}],["格式的模板",{"2":{"204":1}}],["格式的文本",{"2":{"189":1}}],["格式化的",{"2":{"49":1}}],["格式",{"2":{"23":1}}],["返回元组第三个值",{"2":{"241":1}}],["返回元组第二个值",{"2":{"240":1}}],["返回一个布尔值",{"2":{"239":1}}],["返回的不是",{"2":{"216":1}}],["返回的信息一致造成连接失败",{"2":{"14":1,"20":1}}],["返回",{"2":{"214":1,"298":1}}],["返回通过任意方式创建的",{"2":{"88":1}}],["返回值",{"0":{"48":1},"1":{"49":1,"50":1,"51":1},"2":{"104":1}}],["返回访问资源的",{"2":{"23":3}}],["上一个未使用的等待事件会被注销并引发",{"2":{"215":1}}],["上传插件时需要输入一个密钥",{"2":{"329":1}}],["上传创意插件",{"2":{"328":1}}],["上传视频文件到第三方托管服务",{"2":{"23":1}}],["上传语音文件到第三方托管服务",{"2":{"23":1}}],["上传图片到第三方托管服务",{"2":{"23":1}}],["上报数据类型",{"2":{"2":1,"339":1,"399":1}}],["use",{"0":{"377":1}}],["used",{"2":{"360":1}}],["username",{"2":{"185":3}}],["users",{"0":{"156":1,"157":1}}],["user",{"0":{"123":1,"147":1,"148":1,"154":1,"155":1,"160":1,"161":1},"2":{"109":1,"116":1,"123":1,"131":1,"148":1,"154":1,"155":1,"156":1,"157":1,"160":1,"161":1,"165":1,"173":1,"176":1,"177":4,"179":1,"222":1,"262":1,"265":1,"267":2,"307":1,"326":2,"333":1,"352":1}}],["userlogger",{"2":{"87":2}}],["user=",{"2":{"34":1}}],["usage",{"2":{"360":1}}],["ubuntu",{"2":{"181":2,"382":2,"387":1}}],["uvicorn",{"2":{"61":2}}],["upgrade",{"2":{"378":1}}],["up",{"2":{"253":1}}],["upload",{"2":{"47":1,"55":2}}],["update",{"0":{"38":1},"2":{"38":1,"220":1}}],["unsigned",{"2":{"262":1}}],["unsupported",{"2":{"85":1}}],["unsubscribe",{"2":{"46":2}}],["uninstall",{"2":{"82":2,"327":1}}],["union",{"2":{"23":3,"27":3,"101":1,"102":1,"103":1,"108":4,"109":6,"111":2,"112":3,"114":1,"135":2,"139":1,"149":4,"150":2,"151":3,"159":2,"160":2,"161":1,"225":1,"226":1,"227":1,"255":1,"271":1}}],["util",{"2":{"25":2}}],["url=target",{"2":{"188":1}}],["url",{"2":{"22":1,"23":6,"28":1,"56":1,"57":1,"58":1,"101":2,"102":2,"103":2,"169":1,"172":1,"188":2,"262":2}}],["并找到机器人",{"2":{"396":1}}],["并参照可执行文件的系统支持选择部署的操作系统",{"2":{"388":1}}],["并安装",{"2":{"383":1}}],["并重新安装插件即可解决",{"2":{"381":1}}],["并配合前文的排错食用",{"2":{"380":1}}],["并配置",{"2":{"280":1}}],["并保证同时只有一个mcl在运行",{"2":{"377":1}}],["并填写一个群号",{"2":{"342":1}}],["并点击",{"2":{"335":1}}],["并无其他含义",{"2":{"332":1}}],["并覆盖其方法",{"2":{"327":1}}],["并让代码部署的用户使用",{"2":{"310":1}}],["并拷贝进",{"2":{"310":1}}],["并且注册了",{"2":{"396":1}}],["并且操作系统内也需要设置入站规则",{"2":{"363":1}}],["并且拥有以下新参数和方法",{"2":{"295":1}}],["并且你不希望在插件的卸载方法里手动取消定时任务",{"2":{"93":1}}],["并将原来的config以及plugins文件夹移动到新安装的mirai中覆盖",{"2":{"371":1}}],["并将匹配成功的消息响应器按优先级排序",{"2":{"288":1}}],["并将其设置到",{"2":{"231":1}}],["并提供了装饰器模式",{"2":{"281":1}}],["并提供了强大的官方机器人支持",{"2":{"6":1}}],["并输入配置的地址和",{"2":{"280":1}}],["并发送消息",{"2":{"263":1}}],["并把你的机器人添加进频道里",{"2":{"245":1}}],["并在彼此之间相互提供数据",{"2":{"281":1}}],["并在里面插入一张图片",{"2":{"205":1}}],["并在等待",{"2":{"186":1}}],["并在页面内执行",{"2":{"185":1}}],["并定义全局的",{"2":{"185":1}}],["并抛出如下异常",{"2":{"81":1}}],["并执行",{"2":{"81":1}}],["并不是像上述两种方式一样相当于执行import",{"2":{"81":1}}],["并实现相关方法",{"0":{"23":1}}],["等各种将所有模块相连的处理单元",{"2":{"287":1}}],["等待子频道消息",{"2":{"263":1}}],["等待用户消息",{"2":{"263":1}}],["等待事件返回的也是",{"2":{"255":1}}],["等待事件的实例",{"2":{"216":1}}],["等待也会被注销",{"2":{"215":1}}],["等待通常不会影响消息分配器运作",{"2":{"213":1}}],["等",{"2":{"22":1,"56":1,"343":1}}],["或根据个人习惯选择虚拟环境",{"2":{"388":1}}],["或自行到官网下载合适自己系统的版本",{"2":{"383":1}}],["或较老的",{"2":{"362":2}}],["或双引号",{"2":{"343":1}}],["或是简单的数字",{"2":{"343":1}}],["或者科学手段",{"2":{"373":1}}],["或者修改了mah的配置却未更改控制台实例配置单",{"2":{"367":1}}],["或者使用云服务器部署",{"2":{"362":1}}],["或者",{"2":{"300":1}}],["或负数",{"2":{"238":1}}],["或改写",{"2":{"88":1}}],["或需要自定义更多的请求场景",{"2":{"56":1}}],["或",{"2":{"22":1,"28":1,"92":1,"181":1,"225":1,"243":1,"257":1,"279":2,"293":1,"324":1,"382":1,"384":1,"405":1}}],["或使用",{"2":{"19":1,"272":1}}],["腾讯云cos",{"2":{"22":1}}],["多个账号之间共享数据",{"2":{"334":1}}],["多实例启动时",{"2":{"250":1}}],["多数情况下我们推荐使用第三方托管服务来搭建资源服务",{"2":{"22":1}}],["多账号支持动态创建和删除里面的实例",{"2":{"252":1}}],["多账号热插拔",{"0":{"252":1},"1":{"253":1}}],["多账号",{"0":{"249":1},"1":{"250":1,"251":1,"252":1,"253":1},"2":{"19":1}}],["flags",{"2":{"363":1}}],["frequency",{"2":{"339":1}}],["fr=aladdin",{"2":{"339":1}}],["frozen",{"2":{"81":1}}],["fromid",{"2":{"223":1}}],["from",{"2":{"21":1,"23":2,"27":2,"47":1,"81":1,"88":1,"92":1,"93":1,"95":2,"97":1,"99":2,"176":1,"245":1,"250":1,"251":1,"280":2,"293":1,"307":1,"360":2,"388":1}}],["fn",{"2":{"231":2}}],["font",{"2":{"206":1}}],["fontstyle",{"2":{"206":2}}],["force=true",{"2":{"213":1}}],["force",{"0":{"213":1},"2":{"212":1,"216":1,"263":2}}],["forward2",{"2":{"179":3}}],["forwardmessage",{"2":{"179":1}}],["forward",{"2":{"176":4,"177":2,"178":1,"179":4,"180":1}}],["form",{"0":{"54":1},"2":{"47":1,"54":3,"55":1,"102":2}}],["formatter",{"2":{"86":1}}],["format",{"0":{"322":1},"2":{"2":2,"113":1,"321":2,"322":1,"339":1,"399":2}}],["for",{"0":{"42":1},"2":{"42":1,"85":1,"181":1,"257":1,"382":1}}],["ff0000",{"2":{"204":1}}],["f5f5f5",{"2":{"203":1}}],["f",{"2":{"78":1,"79":1,"81":2,"85":1,"173":2,"176":1,"204":1,"212":1,"214":1,"216":1,"229":1,"233":1,"234":1,"235":1,"236":1,"237":1,"238":1,"239":1,"242":2,"245":1,"250":2,"251":2,"257":1,"280":1,"303":1,"304":1}}],["face",{"0":{"175":1},"2":{"173":2,"175":2,"201":2,"204":1,"205":1,"262":1,"352":1}}],["factory",{"2":{"70":1,"71":1,"72":1,"73":1,"92":1,"93":1,"95":1,"97":1}}],["fastapi",{"0":{"64":1},"2":{"59":1,"61":2,"64":2}}],["false",{"2":{"57":1,"58":2,"68":2,"70":2,"81":1,"82":1,"165":1,"190":1,"212":1,"216":1,"230":2,"231":2,"240":1,"241":1,"253":1,"273":1,"301":1,"319":1,"339":1,"340":2}}],["firefox",{"2":{"88":2,"388":4}}],["fields",{"2":{"169":1}}],["field",{"2":{"55":1}}],["field3",{"2":{"35":1}}],["field2",{"2":{"33":1,"35":1}}],["field1",{"2":{"33":1,"35":1}}],["filter=my",{"2":{"214":1}}],["filter",{"0":{"214":1},"2":{"212":1,"214":3,"216":1,"263":2,"339":1}}],["fill",{"2":{"31":1}}],["files",{"2":{"360":2}}],["filename",{"2":{"55":1,"86":1}}],["file",{"2":{"23":3,"27":4,"29":1,"30":1,"55":4,"58":1,"81":4,"85":1,"206":1,"208":2,"210":2,"293":1,"296":1,"304":4,"360":2}}],["func",{"2":{"25":1,"94":1,"279":1}}],["dd",{"2":{"322":6}}],["draft",{"2":{"315":2}}],["dynamic",{"2":{"281":1}}],["d+",{"2":{"235":1,"237":1}}],["d",{"2":{"222":2}}],["dms",{"0":{"137":1}}],["dist",{"2":{"387":2}}],["disabled",{"2":{"363":1}}],["dir=",{"2":{"360":1}}],["dirname",{"2":{"293":1,"296":1,"304":1}}],["dir",{"2":{"293":4,"296":3,"304":2}}],["directory",{"2":{"360":2}}],["direct=true",{"2":{"242":2}}],["direct",{"2":{"118":1,"230":2,"231":2,"242":2,"262":1,"265":1,"267":2}}],["digits",{"2":{"262":1}}],["div",{"2":{"185":2}}],["dice",{"2":{"172":2}}],["dict",{"2":{"21":1,"37":1,"38":2,"53":2,"54":2,"55":2,"56":2,"57":1,"58":1,"61":2,"101":1,"102":1,"103":1,"112":1,"151":1,"163":1,"193":1,"221":1,"262":1}}],["date",{"2":{"322":2}}],["datetime",{"2":{"321":1,"322":2}}],["data=",{"2":{"44":1}}],["database",{"2":{"33":5,"34":4,"333":1,"381":1}}],["data",{"0":{"214":1},"2":{"31":2,"37":1,"42":2,"44":1,"45":2,"49":2,"54":1,"68":3,"69":1,"70":1,"78":3,"79":3,"102":1,"163":3,"165":1,"167":1,"169":1,"171":1,"172":3,"173":6,"175":1,"176":4,"177":1,"179":3,"184":2,"185":6,"186":2,"188":2,"190":1,"191":2,"193":1,"195":1,"196":4,"198":1,"200":1,"201":1,"203":1,"204":3,"205":2,"208":3,"210":3,"212":4,"214":8,"216":6,"218":1,"221":1,"222":3,"225":1,"226":1,"227":1,"229":3,"231":2,"233":3,"234":3,"235":3,"236":3,"237":3,"238":5,"239":5,"240":1,"241":3,"242":6,"245":3,"250":6,"251":5,"255":8,"256":1,"257":8,"258":4,"260":4,"263":2,"271":1,"272":5,"273":2,"275":1,"280":3,"303":3}}],["dark",{"2":{"190":1,"191":1}}],["days=",{"2":{"295":1}}],["days",{"2":{"116":1,"296":1}}],["document=",{"2":{"294":1}}],["document=f",{"2":{"293":2}}],["document",{"2":{"185":1,"292":1,"293":2}}],["docs",{"2":{"61":1}}],["download",{"2":{"47":4,"57":2,"58":4}}],["depth",{"2":{"388":1}}],["deprecated",{"2":{"295":1,"296":1}}],["deps",{"2":{"182":1,"353":1,"388":2}}],["demo",{"2":{"292":1,"295":1,"311":1,"312":4,"313":2}}],["decorator",{"2":{"281":1}}],["del",{"2":{"253":1}}],["delete",{"0":{"114":1,"115":1,"116":1,"117":1,"118":1,"119":1,"120":1,"121":1,"122":1,"123":1},"2":{"56":1,"116":1,"270":1,"295":1,"296":1}}],["debian",{"2":{"181":1,"382":1}}],["debug",{"2":{"84":5,"87":1,"89":2,"90":1,"307":1,"340":1}}],["desc",{"2":{"85":1,"110":1,"193":1}}],["desc=",{"2":{"85":1}}],["description=",{"2":{"78":1,"79":1,"295":1,"303":1,"327":1}}],["description",{"2":{"61":1,"112":1,"151":1,"222":2,"316":2}}],["dest",{"2":{"81":1}}],["default=f",{"2":{"296":1}}],["default=",{"2":{"295":2}}],["default",{"2":{"19":2,"21":1,"23":1,"91":1,"94":2,"296":2,"300":4,"316":2,"317":2,"318":3,"319":2,"320":2,"321":1,"323":1,"324":1,"339":2}}],["def",{"2":{"5":1,"14":1,"20":1,"23":3,"27":4,"31":2,"45":2,"61":2,"62":1,"68":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"78":1,"79":1,"85":1,"87":5,"88":2,"91":1,"92":1,"93":1,"95":2,"97":1,"173":1,"176":1,"179":1,"185":1,"186":1,"196":1,"204":1,"205":1,"208":1,"210":1,"212":1,"214":2,"216":1,"220":3,"222":1,"223":1,"224":3,"225":1,"226":1,"227":1,"229":1,"231":2,"233":1,"234":1,"235":1,"236":1,"237":1,"238":2,"239":2,"240":1,"241":2,"242":2,"245":1,"250":2,"251":2,"255":3,"257":2,"258":1,"260":2,"270":1,"271":1,"272":1,"280":1,"303":2,"307":1,"326":2,"327":2,"388":2}}],["db",{"2":{"33":2,"34":1}}],["临时文件存放目录",{"2":{"21":1}}],["同意以上部分",{"2":{"332":1}}],["同一个子频道内的同一个用户只能存在一个等待事件",{"2":{"215":1}}],["同一个端口的资源服务会相互共享",{"2":{"19":1}}],["同时关闭实例的连接",{"2":{"253":1}}],["同时",{"2":{"204":1}}],["同时开启了",{"2":{"7":1}}],["同步方式",{"2":{"85":1}}],["同步下载",{"0":{"58":1}}],["时的信息",{"2":{"339":1,"340":1}}],["时间选择器",{"2":{"324":1}}],["时间范围",{"2":{"322":1}}],["时间",{"2":{"322":1}}],["时可以输入浮点数",{"2":{"318":1}}],["时会使用默认值的",{"2":{"296":1}}],["时获得的",{"2":{"258":1}}],["时传入",{"2":{"63":1}}],["时",{"2":{"19":1,"27":1,"237":1,"238":1,"293":1,"300":1,"318":1,"321":1,"343":1}}],["默认不需要",{"2":{"343":1}}],["默认端口为",{"2":{"343":1}}],["默认中间件锚点",{"2":{"339":1}}],["默认配置为",{"2":{"200":1}}],["默认预留200ms的渲染时间",{"2":{"186":1,"190":1}}],["默认会在消息体头部添加",{"2":{"165":1}}],["默认为",{"2":{"81":1,"165":1,"344":1,"388":1}}],["默认返回",{"2":{"57":1}}],["默认的资源服务是端口单例的",{"2":{"19":1}}],["默认消息构建器参数",{"2":{"19":1}}],["默认消息构建器",{"2":{"19":1}}],["默认在公网下使用",{"2":{"19":1}}],["默认值允许使用",{"2":{"296":1}}],["默认值和",{"2":{"296":1}}],["默认值为",{"2":{"5":1}}],["默认值",{"2":{"1":1,"3":1,"8":1,"10":1,"12":1,"14":1,"19":1,"21":1,"25":1,"37":1,"38":1,"40":1,"41":1,"42":1,"44":1,"45":1,"46":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"61":1,"81":1,"82":1,"85":1,"86":1,"89":1,"91":1,"94":1,"97":1,"101":1,"102":1,"103":1,"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1,"115":1,"116":1,"117":1,"118":1,"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"157":1,"158":1,"159":1,"160":1,"161":1,"163":1,"165":1,"169":1,"171":1,"175":1,"177":1,"178":1,"184":1,"188":1,"190":1,"193":1,"198":1,"200":1,"203":1,"205":1,"208":1,"210":1,"212":1,"216":1,"230":1,"231":1,"253":1,"256":1,"265":1,"273":1,"296":1,"298":1,"299":1,"301":1,"316":1,"317":1,"318":1,"319":1,"320":1,"321":1,"323":1,"324":1}}],["群",{"2":{"207":1,"209":1}}],["群聊适配器",{"2":{"19":1}}],["群聊适配器需要在本地启动资源服务让腾讯端能够访问媒体资源",{"2":{"19":1}}],["群聊里使用的",{"2":{"18":1}}],["群机器人",{"0":{"18":1,"398":1},"1":{"19":1,"20":1,"21":1,"22":1,"23":1},"2":{"18":1,"398":1}}],["群机器人一致",{"2":{"17":1}}],["开头的一串数字",{"2":{"363":1}}],["开发者平台",{"2":{"338":1,"397":1}}],["开发指南",{"2":{"303":1,"396":1}}],["开发插件可以参考主项目的",{"2":{"77":1}}],["开发插件",{"0":{"77":1},"2":{"314":1}}],["开启",{"2":{"84":1}}],["开放平台",{"2":{"18":1,"336":1,"337":1}}],["开始程序将不再自动更新",{"2":{"393":1}}],["开始部署",{"0":{"382":1},"1":{"383":1,"384":1,"385":1,"386":1,"387":1,"388":1}}],["开始使用",{"0":{"243":1},"1":{"244":1,"245":1,"246":1,"247":1,"248":1},"2":{"405":1}}],["开始",{"2":{"14":1,"19":1,"91":1}}],["在很多方面都占有优势",{"2":{"400":1}}],["在安装时会询问是否安装java",{"2":{"375":1}}],["在安装完依赖后",{"2":{"353":1}}],["在初心佬的文章最下方有手动获取ticket的教程",{"2":{"374":1}}],["在另一台设备上访问控制台",{"2":{"363":1}}],["在跳出来的黑色框框中输入",{"2":{"360":1}}],["在插件商店安装插件",{"0":{"347":1}}],["在主界面填入你的服务地址",{"2":{"344":1}}],["在主项目中",{"2":{"306":1}}],["在主项目里",{"2":{"77":1}}],["在左侧导航选择",{"2":{"335":1}}],["在不久的将来可能都会在控制台中实现",{"2":{"332":1}}],["在不同平台下",{"2":{"100":1}}],["在你更新或下架你的插件时",{"2":{"329":1}}],["在你的业务逻辑正常结束时",{"2":{"217":1}}],["在测试脚本中调试",{"0":{"307":1}}],["在导出时都必须使用",{"2":{"305":1}}],["在读取它们时",{"2":{"304":1}}],["在控制台中点击",{"2":{"296":1}}],["在没有配置",{"2":{"293":1}}],["在本地",{"2":{"310":1}}],["在本文将忽略不谈",{"2":{"289":1}}],["在本章后续文档中",{"2":{"65":1,"279":1}}],["在与不同的运营方服务通讯过程中",{"2":{"286":1}}],["在最终构建消息的时候",{"2":{"275":1}}],["在消息响应器内返回",{"2":{"272":1}}],["在事件响应里使用",{"0":{"269":1},"1":{"270":1,"271":1}}],["在多账号实例里使用",{"0":{"268":1}}],["在上一节",{"2":{"260":1}}],["在频道里输入",{"2":{"245":1}}],["在开始之前",{"2":{"243":1}}],["在私域机器人下且不需要",{"2":{"236":1}}],["在一些特殊的情况下",{"2":{"232":1}}],["在一些使用场景里",{"2":{"211":1}}],["在执行消息响应或在消息响应筛选过程产生异常时",{"2":{"225":1}}],["在执行消息响应器前执行此钩子",{"2":{"70":1}}],["在接收到由适配器传入的消息后",{"2":{"287":1}}],["在接收到有效消息并返回后",{"2":{"217":1}}],["在接收消息到回复发送完毕",{"2":{"67":1}}],["在等待时间内使用其他功能",{"2":{"215":1}}],["在文本内使用",{"2":{"201":1,"204":1}}],["在页面加载完毕后",{"2":{"186":1}}],["在同等工作量下",{"2":{"181":1}}],["在合并消息内显示其头像",{"2":{"177":1}}],["在创作多平台机器人时",{"2":{"98":1}}],["在创建",{"2":{"63":1}}],["在版本",{"2":{"91":1}}],["在相对导入其目录下的模块时",{"2":{"81":1}}],["在加载时解压并导入",{"2":{"77":1}}],["在发送其返回结束后执行此钩子",{"2":{"72":1}}],["在发送其返回前执行此钩子",{"2":{"71":1}}],["在进入等待事件前执行此钩子",{"2":{"69":1}}],["在方法装饰器",{"2":{"62":1}}],["在构造参数里使用辅助类",{"2":{"27":1}}],["在实例化",{"2":{"27":1}}],["在机器人启动时",{"2":{"19":1}}],["在公网下使用",{"0":{"19":1}}],["在",{"0":{"90":1,"255":1},"2":{"18":1,"35":1,"81":1,"183":1,"205":1,"222":1,"245":1,"246":1,"295":1,"302":1,"303":1,"305":1,"307":1,"313":1,"333":1,"336":1,"337":1,"338":1,"363":1}}],["密钥",{"2":{"17":1,"19":1}}],["仅是用来区分可以在控制台内直接实现的操作的",{"2":{"332":1}}],["仅私信可触发",{"2":{"242":1}}],["仅当全部依赖安装成功后",{"2":{"301":1}}],["仅当",{"2":{"231":1}}],["仅在不能触发任何其他功能",{"2":{"213":1}}],["仅支持可被",{"2":{"299":1}}],["仅支持",{"2":{"197":1,"323":1,"331":1,"385":1}}],["仅支持当前频道内的子频道",{"2":{"197":1}}],["仅限",{"2":{"174":1}}],["仅",{"2":{"102":1}}],["仅捕获但不输出的异常列表",{"2":{"85":1}}],["仅仅希望异常不会终止你的程序",{"2":{"85":1}}],["仅对",{"2":{"64":1}}],["仅sqlite需要",{"2":{"38":1}}],["仅能提供有限的数据库支持",{"2":{"32":1}}],["仅能操作测试频道",{"2":{"15":1,"248":1}}],["仅作示意",{"2":{"14":1,"20":1}}],["沙箱环境只会收到测试频道的事件",{"2":{"15":1,"248":1}}],["沙箱环境",{"0":{"15":1,"248":1}}],["从",{"2":{"14":1,"19":1,"261":1,"393":1}}],["从左侧导航挑选合适的适配器",{"2":{"5":1}}],["实现上述模式的思路来源于",{"2":{"283":1}}],["实现你的创意",{"2":{"281":1}}],["实现的机器人平台",{"2":{"9":1,"11":1}}],["实际上是调用了不同平台提供的接口",{"2":{"100":1}}],["实际上每个分片应当是独立的服务",{"2":{"14":1,"20":1}}],["实例配置单中的qq号是否填写错误了",{"2":{"369":1}}],["实例的连接需要时间",{"2":{"341":1}}],["实例管理",{"2":{"335":1}}],["实例变量名不为",{"2":{"305":1}}],["实例内",{"2":{"231":1}}],["实例化",{"2":{"231":1,"277":1}}],["实例化多个",{"2":{"19":1}}],["实例两个参数",{"2":{"220":1}}],["实例",{"2":{"81":1,"245":1,"251":2,"253":1,"262":1,"334":1}}],["实例便拥有了这个插件定义的所有消息响应",{"2":{"78":1}}],["实例后参考官方文档进一步使用",{"2":{"64":1}}],["实例和",{"2":{"47":1}}],["21",{"2":{"322":1}}],["21t11",{"2":{"222":1}}],["222222",{"2":{"268":2}}],["22",{"2":{"84":2,"85":1}}],["2016",{"2":{"331":1,"385":1}}],["2012",{"2":{"181":1,"382":1,"388":1}}],["2024年6月18日",{"2":{"404":1}}],["2023",{"2":{"322":2}}],["2021",{"2":{"222":1}}],["20211029",{"2":{"163":1}}],["2022年9月14日",{"2":{"404":1}}],["2022年6月11日",{"2":{"404":1}}],["2022年5月13日重大变故后",{"2":{"404":1}}],["2022",{"2":{"84":2,"85":1,"86":1,"400":1}}],["20",{"2":{"95":2,"181":1,"205":1,"222":1,"318":1,"322":1,"382":1,"387":1}}],["200000000",{"2":{"222":1}}],["200",{"2":{"37":1,"89":1,"90":1,"184":1,"190":1}}],["259",{"2":{"81":1}}],["287",{"2":{"81":1}}],["2",{"2":{"14":3,"20":1,"31":1,"196":1,"240":1,"301":1,"400":1}}],["gamedata",{"2":{"361":2}}],["gateway",{"0":{"124":1,"125":1},"2":{"14":1,"20":1}}],["git",{"0":{"360":1,"383":1},"2":{"313":3,"360":13,"383":2,"388":1}}],["github",{"2":{"313":2,"388":1,"406":1}}],["gtimg",{"2":{"163":1}}],["gt",{"2":{"23":3,"27":3,"81":2,"85":1,"88":1,"185":6,"191":1,"316":5,"317":1,"318":2,"319":1,"320":1,"321":1,"323":1,"324":1,"325":1,"360":12}}],["getbotname",{"2":{"62":1}}],["getname",{"2":{"61":1}}],["get",{"0":{"28":1,"29":1,"30":1,"52":1,"101":1,"126":1,"127":1,"128":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"298":1},"2":{"23":3,"27":3,"31":1,"40":1,"47":1,"52":1,"61":2,"62":2,"98":1,"99":1,"101":1,"103":1,"298":1,"316":1,"323":1,"324":1,"326":1}}],["graiax",{"2":{"23":1}}],["groupconfig",{"2":{"231":3}}],["group",{"2":{"19":3,"20":2,"21":2,"23":1,"223":1,"230":1,"231":9}}],["global",{"2":{"17":2,"295":2,"296":2,"300":1}}],["guilds",{"0":{"135":1}}],["guild",{"0":{"110":1,"111":1,"116":1,"117":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":1,"150":1},"2":{"14":5,"108":1,"109":1,"110":1,"111":1,"114":1,"116":1,"117":1,"123":1,"128":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":1,"137":1,"140":1,"150":1,"152":1,"153":1,"154":1,"155":1,"156":1,"157":1,"158":2,"161":1,"220":1,"222":3,"262":2,"265":1,"267":2,"303":1}}],["got",{"0":{"368":1}}],["golang",{"2":{"2":1}}],["gocq",{"0":{"3":1},"2":{"2":1,"3":4}}],["go",{"0":{"2":1,"224":1,"399":1},"1":{"3":1},"2":{"2":2,"170":1,"172":1,"224":3,"243":1,"339":5,"398":1,"399":1}}],["创建新启动类",{"2":{"388":1}}],["创建新配置项时使用默认值的",{"2":{"296":1}}],["创建虚拟环境",{"2":{"388":1}}],["创建入口文件",{"2":{"302":1}}],["创建表单界面",{"2":{"296":1}}],["创建表模型",{"2":{"33":1}}],["创建插件",{"0":{"302":1},"1":{"303":1,"304":1,"305":1},"2":{"295":1}}],["创建多个单独实例",{"0":{"250":1}}],["创建私域机器人",{"0":{"246":1}}],["创建一个机器人应用",{"2":{"397":1}}],["创建一个空多账号",{"2":{"253":1}}],["创建一个多账号实例",{"0":{"251":1}}],["创建一个",{"2":{"245":1,"302":1}}],["创建沙箱频道",{"2":{"245":1}}],["创建你的第一个",{"0":{"245":1}}],["创建连续对话",{"0":{"211":1},"1":{"212":1,"213":1,"214":1,"215":1,"216":1,"217":1,"218":1}}],["创建文件",{"2":{"185":1}}],["创建html模板文件",{"0":{"185":1}}],["创建日志模块",{"0":{"86":1}}],["创建定时任务",{"2":{"65":1}}],["创建服务",{"0":{"60":1},"1":{"61":1}}],["创建数据库基础模型",{"2":{"33":1}}],["创建或连接一个",{"2":{"33":1}}],["创建辅助类",{"0":{"27":1}}],["创建后机器人能够同时接收到来自群聊",{"2":{"17":1}}],["创建全域适配器",{"0":{"17":1}}],["创建分片连接需要使用分片适配器",{"2":{"14":1}}],["创建的机器人即为",{"2":{"13":1}}],["考虑到开发者事件接收时可以实现负载均衡",{"2":{"14":1,"20":1}}],["如8080与8060看混",{"2":{"367":1}}],["如提示所示",{"2":{"364":1}}],["如何更新",{"0":{"391":1},"1":{"392":1,"393":1,"394":1}}],["如何部署属于自己的",{"2":{"389":1}}],["如何保留原来的数据",{"0":{"381":1}}],["如何给兔兔添加表情",{"0":{"352":1}}],["如何注册消息响应",{"2":{"228":1}}],["如需更改数据库类型为",{"2":{"333":1}}],["如需要扩展其用法",{"2":{"64":1}}],["如需要",{"2":{"10":1,"12":1}}],["如在插件内使用了库",{"2":{"310":1}}],["如下图成功运行后可以进入下一节",{"2":{"386":1}}],["如下图所示",{"2":{"67":1}}],["如下所示",{"2":{"297":1}}],["如下为",{"2":{"222":1}}],["如示例所示",{"2":{"218":1}}],["如动态增加或软删除功能时",{"2":{"78":1}}],["如某些场景需要使用同步下载",{"2":{"58":1}}],["如对页面进行",{"2":{"31":1}}],["如果可以的话",{"2":{"406":1}}],["如果没有",{"2":{"380":1}}],["如果没有频道级别的配置则返回同名全局配置",{"2":{"298":1}}],["如果最下方没有中文的提示",{"2":{"376":1}}],["如果显示",{"2":{"360":1}}],["如果显示离线可以等待几秒再刷新页面",{"2":{"341":1}}],["如果您坚持使用纯数字的",{"2":{"343":1}}],["如果您坚持这么做",{"2":{"343":1}}],["如果您已阅读并理解",{"2":{"332":1}}],["如果插件不需要使用",{"2":{"312":1}}],["如果插件有一些原文件修改的更新",{"2":{"81":1}}],["如果不这么做",{"2":{"343":1,"345":1}}],["如果不需要使用",{"2":{"313":1}}],["如果不满足条件时输出提示",{"2":{"300":1}}],["如果不指定优先级",{"2":{"238":2}}],["如果给出了",{"2":{"300":1}}],["如果也没有全局配置",{"2":{"298":1}}],["如果提供了",{"2":{"296":2}}],["如果配置了前缀触发词",{"2":{"261":1}}],["如果消息没有发送成功则返回",{"2":{"257":1}}],["如果消息响应里存在等待事件",{"2":{"67":1}}],["如果在等待过程中",{"2":{"214":1}}],["如果页面有部分元素是异步渲染的",{"2":{"186":1}}],["如果",{"2":{"177":1,"204":1}}],["如果使用其他触发方式",{"2":{"94":1}}],["如果你喜欢并支持我们",{"2":{"406":1}}],["如果你选择了",{"2":{"398":1}}],["如果你选择了频道机器人",{"2":{"396":1}}],["如果你想移动mirai",{"2":{"371":1}}],["如果你想使用第三方机器人服务",{"2":{"243":1}}],["如果你参考的是初心佬的文章",{"2":{"364":1}}],["如果你将兔兔部署在云服务器上",{"2":{"363":1}}],["如果你访问控制台的设备与部署兔兔的设备不是同一台",{"2":{"363":1}}],["如果你访问控制台的设备与部署兔兔的设备为同一台的话",{"2":{"363":1}}],["如果你的目的是开发一个完全由自己定制的机器人",{"2":{"389":1}}],["如果你的网址以https开头",{"2":{"363":1}}],["如果你的插件使用了第三方库",{"2":{"309":1}}],["如果你的插件包含静态资源",{"2":{"304":1}}],["如果你需要",{"2":{"323":1,"324":1}}],["如果你需要监听这个大类的事件时",{"2":{"224":1}}],["如果你是在",{"2":{"311":1}}],["如果你在平台创建的是私域机器人",{"2":{"246":1}}],["如果你并不了解",{"2":{"243":1}}],["如果你并不需要处理异常",{"2":{"85":1}}],["如果你希望获取这些异常",{"2":{"225":1}}],["如果你希望自己实现请求",{"2":{"103":1}}],["如果你持续调用",{"2":{"218":1}}],["如果你正在开发插件",{"2":{"93":1}}],["如果你不需要这些代码",{"2":{"389":1}}],["如果你不希望如此",{"2":{"213":1}}],["如果你不喜欢默认的日志输出",{"2":{"87":1}}],["如果你不是第一次接触脚本语言",{"2":{"76":1}}],["如果一切就绪",{"2":{"401":1}}],["如果一些插件甚至带有静态资源",{"2":{"81":1}}],["如果一个插件的逻辑非常复杂",{"2":{"80":1}}],["如果需要",{"2":{"243":1}}],["如果需要自定义路由",{"2":{"62":1}}],["如果需要发送更多类型的请求",{"2":{"56":1}}],["如果请求失败",{"2":{"51":1}}],["如果请求失败会返回空字符串",{"2":{"48":1}}],["如果是",{"2":{"396":1}}],["如果是的话",{"2":{"377":1,"379":1}}],["如果是同一台设备的话",{"2":{"364":1}}],["如果是通过在消息响应器里面返回",{"2":{"257":1}}],["如果是网络图片",{"2":{"188":1}}],["如果是无法干预的同步请求行为",{"2":{"47":1}}],["如果是更新的数据",{"2":{"38":1}}],["如果是插入的数据",{"2":{"38":1}}],["如果函数有返回值",{"2":{"28":1,"29":1,"30":1}}],["如果无法在公网下部署",{"2":{"19":1}}],["如",{"2":{"22":1,"56":1,"224":1,"243":1,"322":1,"343":1,"388":1}}],["如要使用此适配器",{"2":{"7":1}}],["可能不支持",{"2":{"388":1}}],["可能有设备被攻击的风险",{"2":{"363":1}}],["可能导致无法更新",{"2":{"361":1}}],["可能是由于你没有认真看文档根本没有安装",{"2":{"360":1}}],["可是没能跑完就闪退了",{"2":{"361":1}}],["可是我的各个限定干员都已经被设置为不可抽取了",{"2":{"356":1}}],["可接收到该实例的一些相关通知",{"2":{"342":1}}],["可控实例",{"2":{"342":1,"364":1}}],["可更改为日期时间选择器",{"2":{"321":1}}],["可输入的最大值",{"2":{"318":1}}],["可输入的最小值",{"2":{"318":1}}],["可忽略前缀检查",{"2":{"233":1}}],["可在插件配置选项卡查看并编辑",{"2":{"349":1}}],["可在",{"2":{"301":1,"339":1,"340":1}}],["可在文字图片内渲染图片",{"2":{"205":1}}],["可在此对",{"2":{"31":1}}],["可开启自动转换",{"2":{"200":1}}],["可通过更改实例的适配器使用",{"2":{"243":1}}],["可通过参数",{"2":{"186":1,"190":1}}],["可通过适配器的",{"2":{"173":1}}],["可自定义",{"2":{"177":1}}],["可自动创建数据库",{"2":{"34":1}}],["可为空",{"2":{"177":1}}],["可执行文件部署是一键部署的模式",{"2":{"384":1}}],["可执行文件部署启动时会报错",{"0":{"379":1}}],["可执行文件部署",{"2":{"90":1,"310":1,"384":1}}],["可获取",{"2":{"64":1}}],["可使用参数",{"2":{"293":1}}],["可使用同模块中的",{"2":{"58":1}}],["可使用",{"2":{"56":1}}],["可使用辅助类介入媒体消息或浏览器的构建过程",{"2":{"26":1,"278":1}}],["可以修改config",{"2":{"377":1}}],["可以手动安装一个java的jdk",{"2":{"375":1}}],["可以再次尝试打开可执行文件了",{"2":{"360":1}}],["可以前往控制台中的干员设置设定干员的限定属性",{"2":{"356":1}}],["可以为我们打赏一瓶快乐水",{"2":{"406":1}}],["可以为绝对路径",{"2":{"316":1}}],["可以为该功能设置功能组",{"2":{"231":1}}],["可以强制指定写入全局配置",{"2":{"299":1}}],["可以直接读取全局配置",{"2":{"298":1}}],["可以是",{"2":{"296":1}}],["可以是任意类型",{"2":{"241":1}}],["可以是任意人",{"2":{"177":1}}],["可以让你发送多彩的文字图片",{"2":{"273":1}}],["可以撤回",{"2":{"257":2}}],["可以创建一个多账号实例",{"2":{"251":1}}],["可以向",{"2":{"241":1}}],["可以检查对话文本是否符合正则表达式",{"2":{"235":1}}],["可以通过重启程序来获得更新",{"2":{"392":1}}],["可以通过实例化一个无",{"2":{"265":1}}],["可以通过指定优先级供消息分配器选择",{"2":{"238":1}}],["可以通过",{"2":{"232":1}}],["可以通过注册异常处理器来获得它们",{"2":{"225":1}}],["可以设置参数",{"2":{"218":1}}],["可以忽略分配器让消息强制返回到等待处",{"2":{"213":1}}],["可以重复",{"2":{"96":1}}],["可以使任务的执行时机更加灵活",{"2":{"95":1}}],["可以使用动态输入对象",{"2":{"324":1}}],["可以使用动态输入值数组",{"2":{"323":1}}],["可以使用以下事件名精确获取",{"2":{"224":1}}],["可以使用自己的",{"2":{"206":1}}],["可以使用",{"2":{"188":1,"214":1,"219":1}}],["可以使用除",{"2":{"103":1}}],["可以使用一些额外的属性",{"2":{"48":1}}],["可以使用内置的线程池方法更变为异步",{"2":{"47":1}}],["可以卸载指定的插件",{"2":{"82":1}}],["可以在编辑器",{"2":{"307":1}}],["可以在此阶段修改",{"2":{"68":1,"71":1}}],["可以在截图前先对页面进行操作",{"2":{"31":1}}],["可以调用这个属性获取异常",{"2":{"51":1}}],["可以获取请求的状态码和其他信息",{"2":{"50":1}}],["可参考",{"2":{"23":1}}],["可参考官方文档",{"2":{"14":1,"20":1}}],["可连接任何",{"2":{"9":1,"11":1}}],["可选",{"2":{"2":1,"45":1,"239":2,"301":1,"316":3,"318":2,"339":1,"399":1}}],["使功能在私信里可用",{"0":{"242":1}}],["使用火狐内核需要修改入口程序",{"2":{"388":1}}],["使用特定命令时会报错",{"0":{"378":1}}],["使用mcl",{"2":{"375":1}}],["使用代码部署",{"2":{"358":1}}],["使用可执行文件部署时",{"0":{"359":1},"1":{"360":1,"361":1}}],["使用可执行文件部署",{"2":{"358":1}}],["使用过程中向我们提问较多的问题",{"2":{"357":1}}],["使用子级对象组建多层的对象",{"2":{"325":1}}],["使用脚本打包",{"0":{"311":1}}],["使用指引文档",{"2":{"296":1}}],["使用该类创建插件时",{"2":{"295":1}}],["使用适配器",{"2":{"280":1}}],["使用适配器实例的",{"2":{"256":1}}],["使用测试实例调试",{"0":{"280":1}}],["使用辅助类扩展构建",{"0":{"278":1}}],["使用回调对象撤回",{"2":{"257":1}}],["使用前缀触发词唤醒机器人",{"0":{"247":1}}],["使用机器人的",{"2":{"245":1}}],["使用工具类",{"2":{"236":1}}],["使用参数",{"2":{"213":1}}],["使用强制等待",{"2":{"212":1,"216":1}}],["使用调色模板可以进行文字调色",{"2":{"202":1}}],["使用按钮模版",{"0":{"195":1}}],["使用原生消息模板扩展",{"2":{"170":1}}],["使用更泛用的",{"2":{"91":1}}],["使用启动参数修改一些内置变量",{"2":{"89":1}}],["使用启动参数",{"2":{"84":1}}],["使用同步请求将会阻塞主线程运行",{"2":{"47":1}}],["使用示例",{"2":{"31":1}}],["使用",{"0":{"297":1,"333":1,"399":1,"400":1},"1":{"298":1,"299":1,"300":1},"2":{"15":1,"24":1,"33":1,"83":1,"94":1,"95":1,"172":2,"189":1,"212":1,"248":1,"255":1,"258":1,"263":1,"388":1}}],["使用此适配器",{"2":{"9":1,"11":1}}],["使开发者只需编写一次业务逻辑代码即可应用到多种机器人平台",{"2":{"11":1}}],["使得在不同平台下",{"2":{"4":1}}],["平台的",{"2":{"9":1}}],["occured",{"0":{"375":1}}],["objects",{"2":{"360":1}}],["object",{"2":{"315":1,"323":1,"324":2,"325":3,"326":2}}],["ob12",{"2":{"11":1,"12":3}}],["ob11",{"2":{"9":1,"10":3}}],["other",{"2":{"301":2}}],["official",{"2":{"301":1}}],["os",{"2":{"293":2,"296":1,"304":2}}],["oserror",{"2":{"227":1}}],["o构建",{"2":{"281":1}}],["owner",{"2":{"222":1}}],["org",{"2":{"315":1}}],["original",{"2":{"262":1}}],["or",{"0":{"38":1},"2":{"40":1,"78":1,"182":1,"360":3,"388":3}}],["orm",{"2":{"32":1,"33":1,"65":1}}],["one",{"2":{"360":1}}],["onebot12",{"0":{"12":1},"2":{"12":2}}],["onebot11",{"0":{"10":1},"2":{"10":2}}],["onebot",{"0":{"9":1,"11":1},"1":{"10":1,"12":1},"2":{"2":1,"9":2,"10":1,"11":2,"12":1}}],["only=true",{"2":{"242":2}}],["only",{"2":{"230":1,"231":1}}],["online",{"0":{"127":1}}],["on",{"0":{"31":1,"229":1},"1":{"230":1},"2":{"27":1,"31":2,"78":1,"79":1,"173":1,"176":1,"179":1,"185":1,"186":1,"196":1,"204":1,"205":1,"208":1,"210":1,"212":1,"214":1,"216":1,"219":1,"220":4,"222":2,"223":1,"224":3,"225":1,"226":1,"227":1,"229":2,"231":4,"233":1,"234":1,"235":1,"236":1,"237":1,"238":2,"239":1,"241":1,"242":2,"245":1,"250":2,"251":2,"255":3,"257":2,"258":1,"260":1,"270":1,"271":1,"272":1,"279":1,"280":1,"288":1,"303":2,"360":1}}],["op",{"2":{"222":2}}],["operator",{"2":{"307":1}}],["operand",{"2":{"85":1}}],["open",{"2":{"304":1}}],["openapi",{"2":{"15":1,"248":1}}],["option3",{"2":{"320":1}}],["option2",{"2":{"320":2}}],["option1",{"2":{"320":1}}],["optional",{"2":{"73":1}}],["options=qqgroupchainbuilderoptions",{"2":{"21":1}}],["options",{"2":{"19":1,"21":1,"61":2}}],["v5",{"2":{"389":1}}],["venv",{"2":{"388":6}}],["version",{"2":{"301":1,"360":1}}],["version=",{"2":{"78":1,"79":1,"295":1,"303":1,"327":1}}],["verify=my",{"2":{"239":1,"241":1,"260":1}}],["verify",{"2":{"230":1,"239":5,"240":1,"241":3,"260":2,"262":2}}],["verifykey",{"2":{"8":1,"340":1}}],["various",{"2":{"360":1}}],["value3",{"2":{"323":1}}],["value2",{"2":{"323":1}}],["value1",{"2":{"323":1}}],["values",{"2":{"193":3,"196":1}}],["value",{"2":{"163":6,"172":1,"193":1,"298":1,"299":2,"360":1}}],["v",{"2":{"360":1}}],["vue",{"2":{"283":1}}],["vupload",{"2":{"163":1}}],["virtualenv",{"2":{"388":1}}],["vivien8261",{"2":{"185":1}}],["video",{"0":{"30":1,"208":1},"2":{"23":2,"27":3,"30":1,"208":2}}],["vfiles",{"2":{"163":1}}],["v6的插件化使得默认部署完的兔兔是没有插件的",{"2":{"380":1}}],["v6",{"0":{"90":1,"331":1},"2":{"76":1,"90":1,"185":1,"295":1,"307":1,"313":2,"314":1,"385":1,"386":1,"387":3,"389":4,"393":1,"404":1}}],["voice",{"0":{"29":1,"210":1},"2":{"23":4,"27":3,"29":1,"210":3}}],["v12",{"0":{"11":1},"1":{"12":1},"2":{"12":1}}],["v11",{"0":{"9":1},"1":{"10":1},"2":{"10":1}}],["kind",{"2":{"223":1}}],["kv",{"2":{"163":2}}],["known",{"2":{"81":1}}],["kw",{"2":{"31":1}}],["kwargs",{"2":{"21":1,"25":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"61":2,"94":3,"101":1,"102":1,"103":1,"147":1}}],["key错误",{"0":{"366":1}}],["keypoint",{"2":{"239":1,"241":1}}],["keyword",{"2":{"236":1}}],["keywords",{"0":{"237":1},"2":{"230":2,"237":1,"247":1}}],["keywords=equal",{"2":{"236":1}}],["keywords=re",{"2":{"235":1}}],["keywords=",{"2":{"31":1,"78":1,"79":1,"173":1,"176":1,"179":1,"185":1,"186":1,"196":1,"204":1,"205":1,"208":1,"210":1,"212":1,"214":1,"216":1,"229":1,"231":2,"233":1,"234":1,"237":1,"238":2,"242":2,"245":1,"250":2,"251":2,"255":2,"257":2,"258":1,"272":1,"280":1,"303":1}}],["keyerror",{"2":{"226":1}}],["keyboard=keyboard",{"2":{"196":1}}],["keyboard",{"2":{"193":2,"195":1,"196":3}}],["key=",{"2":{"63":1}}],["key",{"2":{"8":2,"61":1,"63":2,"163":6,"193":4,"196":1}}],["kook机器人",{"0":{"338":1}}],["kookapi",{"2":{"99":1}}],["kookbotinstance",{"2":{"6":1}}],["kook",{"0":{"6":1,"397":1},"2":{"6":2,"99":1,"338":3,"397":1}}],["服务器异常",{"2":{"363":1}}],["服务等",{"2":{"65":1}}],["服务监听端口",{"2":{"61":1}}],["服务监听地址",{"2":{"61":1}}],["服务",{"2":{"7":1,"343":1,"383":1}}],["服务的",{"2":{"1":3,"3":3,"8":3,"10":3,"12":3}}],["和多账号实例",{"2":{"282":1}}],["和该次返回的消息",{"2":{"216":1}}],["和基础开发指南一样",{"2":{"65":1}}],["和",{"2":{"7":1,"32":1,"65":1,"76":1,"170":2,"176":1,"177":1,"209":1,"232":1,"239":1,"245":1,"267":1}}],["机器人目前分为两种",{"2":{"395":1}}],["机器人不需要",{"2":{"338":1}}],["机器人框架",{"2":{"281":1,"403":1}}],["机器人已经可以正常运作了",{"2":{"245":1}}],["机器人官方提供的",{"2":{"189":1}}],["机器人密钥",{"2":{"19":1}}],["机器人",{"0":{"6":1,"397":1},"2":{"245":2,"246":1,"262":1,"389":1,"404":1}}],["机器人的账号",{"2":{"10":1,"12":1}}],["机器人的",{"2":{"3":1,"8":1}}],["txcaptchahelper按钮了",{"2":{"374":1}}],["txt",{"2":{"304":2,"388":1}}],["tutorial",{"2":{"360":1}}],["t",{"2":{"222":1}}],["ttf",{"2":{"206":2}}],["the",{"2":{"360":4}}],["these",{"2":{"360":1}}],["thumbnail",{"2":{"169":1}}],["this",{"2":{"86":2}}],["threads",{"0":{"146":1}}],["thread",{"0":{"25":1,"113":1,"122":1,"145":1},"2":{"25":2,"113":1,"122":1,"145":1}}],["tree",{"2":{"360":2}}],["tree=",{"2":{"360":1}}],["trigger=crontrigger",{"2":{"95":1}}],["trigger=",{"2":{"95":1}}],["triggers",{"2":{"95":1}}],["trigger",{"2":{"91":1}}],["traceback",{"2":{"81":1,"85":2}}],["true",{"2":{"70":1,"184":1,"200":1,"214":2,"216":2,"230":1,"231":1,"239":1,"240":2,"241":1,"253":1,"273":1,"340":1}}],["title",{"2":{"61":1,"113":1,"169":1,"172":1,"210":1,"316":2}}],["timestamp",{"2":{"112":2,"151":2,"152":1,"154":1,"156":1,"262":1}}],["timed",{"0":{"94":1,"97":1},"1":{"95":1},"2":{"91":2,"92":1,"93":3,"95":2,"97":2}}],["time=1000",{"2":{"31":1,"186":1}}],["time",{"2":{"14":1,"20":1,"89":1,"90":1,"177":1,"184":1,"186":1,"190":2,"212":1,"216":1,"262":1,"263":2,"322":2}}],["top",{"2":{"400":1}}],["total",{"2":{"42":1}}],["to",{"0":{"41":1,"367":1},"2":{"41":1,"360":1}}],["token=",{"2":{"14":2,"17":1,"19":1,"20":2,"21":1,"245":1,"246":1,"250":2,"251":3,"280":1}}],["token=auth",{"2":{"8":1}}],["token=ws",{"2":{"6":1}}],["token=token",{"2":{"1":1,"3":1,"10":1,"12":1}}],["token",{"2":{"1":2,"3":2,"6":4,"10":2,"12":2,"245":1,"338":1,"339":4,"340":1,"364":1}}],["tab",{"2":{"363":1}}],["tablename",{"2":{"33":2,"35":1,"37":1,"40":1,"41":1,"42":1}}],["table",{"2":{"33":2,"35":2}}],["tag=",{"2":{"97":1}}],["tag",{"0":{"198":1},"2":{"91":2,"94":3,"96":2,"97":1,"198":1}}],["target",{"2":{"38":1,"118":1,"188":2,"198":1,"223":1,"256":1,"262":1}}],["tasks",{"2":{"91":3,"388":1}}],["task",{"0":{"94":1,"97":1},"1":{"95":1},"2":{"14":2,"20":2,"91":2,"92":1,"93":3,"95":2,"97":2}}],["tell",{"2":{"212":1,"214":1,"216":1}}],["template",{"0":{"193":1},"2":{"163":1,"184":2,"191":2,"193":3,"195":2,"196":1}}],["template=false",{"2":{"31":1,"186":2}}],["test",{"2":{"84":1,"97":2,"231":2,"280":4,"307":2}}],["textamiya",{"2":{"292":1,"302":1,"304":1}}],["textplugin",{"2":{"81":1}}],["textmyplugin",{"2":{"80":1,"81":1,"310":1}}],["text",{"0":{"200":1,"203":1},"1":{"204":1,"205":1},"2":{"68":1,"78":1,"79":1,"87":5,"89":1,"90":1,"165":1,"176":1,"177":2,"190":1,"200":2,"201":1,"203":2,"204":3,"205":1,"212":3,"214":3,"216":4,"229":1,"233":1,"234":1,"235":1,"236":1,"237":1,"238":2,"239":2,"242":2,"245":1,"250":2,"251":2,"255":1,"257":1,"258":1,"260":1,"261":1,"262":6,"265":1,"266":1,"267":1,"272":2,"273":1,"275":2,"277":1,"280":1,"303":1,"317":1}}],["textfield",{"2":{"35":1}}],["tencent",{"2":{"14":1,"15":1,"17":1,"19":1,"21":2,"99":1,"248":1}}],["typing",{"2":{"23":1,"27":1}}],["type=0",{"2":{"196":1}}],["typeerror",{"2":{"85":2}}],["type",{"2":{"5":1,"53":1,"85":2,"88":1,"106":1,"108":1,"109":3,"112":1,"119":1,"139":1,"149":1,"151":1,"172":2,"223":2,"224":10,"255":1,"262":1,"311":1,"315":1,"316":2,"317":1,"318":3,"319":1,"320":1,"321":2,"323":4,"324":4,"325":3,"326":6,"388":1}}],["号",{"2":{"3":1,"8":1,"177":1,"339":1,"340":1}}],["m",{"2":{"388":2}}],["mcl所处文件夹或者其子文件夹",{"2":{"371":1}}],["mcl处于的路径中不能有任何中文字符",{"2":{"371":1}}],["mcl无法正常启动",{"0":{"370":1},"1":{"371":1,"372":1,"373":1,"374":1,"375":1,"376":1,"377":1}}],["mv",{"2":{"360":1}}],["mm",{"2":{"322":12}}],["mp4",{"2":{"207":1,"208":1}}],["md",{"2":{"189":1,"191":2,"195":1,"196":1,"292":2,"293":3}}],["mute",{"0":{"152":1,"153":1,"154":1,"155":1,"156":1,"157":1},"2":{"152":2,"154":2,"156":2}}],["multipleaccounts",{"0":{"253":1},"2":{"78":1,"92":1,"251":5,"253":1,"268":1,"279":2,"282":1}}],["middlewares",{"2":{"339":1}}],["minimum",{"2":{"318":2}}],["minute=5",{"2":{"95":1}}],["mirai登陆的qq号",{"2":{"364":1}}],["miraiforwardmessage",{"2":{"176":2,"179":2}}],["miraigo",{"2":{"2":1}}],["mirai",{"0":{"7":1,"223":1,"340":1,"367":1,"400":1},"1":{"8":1},"2":{"2":1,"7":2,"8":3,"170":3,"172":1,"176":2,"209":1,"223":2,"243":1,"340":5,"364":5,"377":1,"398":1,"400":6}}],["msg",{"2":{"116":1}}],["ms",{"2":{"89":1}}],["move",{"2":{"360":1}}],["modify",{"0":{"149":1,"150":1,"151":1}}],["mode",{"2":{"84":1}}],["modelselect",{"2":{"42":1}}],["model",{"0":{"40":1},"2":{"40":3,"41":1,"42":1}}],["modelclass",{"2":{"33":2}}],["module",{"2":{"81":4,"85":1}}],["most",{"2":{"81":1,"85":1}}],["man",{"2":{"360":1}}],["manager",{"2":{"81":1}}],["mamoe",{"2":{"340":1,"364":3,"377":1}}],["markdowntext",{"2":{"191":1}}],["markdown",{"0":{"189":1,"190":1,"191":1,"192":1,"193":1,"292":1},"1":{"190":1,"191":1,"193":1,"194":1,"195":1,"196":1},"2":{"189":4,"190":2,"191":2,"192":2,"193":1,"195":1,"196":2,"292":1}}],["macos",{"2":{"181":1,"182":1,"382":1,"388":3}}],["master",{"2":{"90":1}}],["maximum",{"2":{"318":2}}],["max",{"2":{"89":1,"90":1,"212":1,"216":1,"222":1,"263":2}}],["main",{"2":{"81":2,"292":1,"302":2,"303":1,"304":2,"305":2,"310":3,"388":1}}],["mah中所填写的的端口与某个外部应用冲突",{"2":{"377":1}}],["mah",{"0":{"8":1},"2":{"7":2,"8":4,"340":1}}],["mydarkmarkdown",{"2":{"191":1}}],["mymarkdown",{"2":{"191":1}}],["mybrowserlauncher",{"2":{"88":1}}],["mybuilder",{"2":{"23":1,"27":2}}],["mylogger",{"2":{"86":2,"87":2}}],["myplugin",{"2":{"79":3,"80":2,"81":4,"292":1,"302":1,"304":1,"327":2}}],["my",{"2":{"63":1,"78":1,"79":1,"82":1,"214":1,"239":1,"240":1,"241":3,"251":1,"260":1,"295":1,"303":1,"327":1}}],["myevent",{"2":{"44":1,"45":2,"46":1}}],["mysql=true",{"2":{"34":2}}],["mysql",{"0":{"34":1,"333":1},"2":{"32":1,"34":1,"333":2}}],["members",{"0":{"132":1,"134":1},"2":{"222":1}}],["member",{"0":{"116":1,"131":1},"2":{"222":1}}],["me",{"0":{"136":1,"137":1},"2":{"98":1,"99":1,"212":1,"214":1,"216":1}}],["metaurl",{"2":{"163":1}}],["metacover",{"2":{"163":1}}],["metasubtitle",{"2":{"163":1}}],["metatitle",{"2":{"163":1}}],["meta",{"2":{"33":1}}],["method=",{"2":{"61":2,"62":1}}],["method",{"2":{"25":2,"45":1,"46":1,"56":1,"103":3,"110":1}}],["messagecallback",{"2":{"257":2,"258":1}}],["messagechain",{"2":{"191":1}}],["message和chain",{"2":{"228":1}}],["message对象",{"2":{"216":1}}],["messagesendrequest",{"2":{"158":1}}],["message=",{"2":{"61":1}}],["message",{"0":{"68":1,"69":1,"70":1,"71":1,"72":1,"73":1,"106":1,"118":1,"119":1,"138":1,"139":1,"140":1,"158":1,"212":1,"216":1,"229":1,"255":1,"261":1,"265":1,"268":1,"269":1},"1":{"213":1,"214":1,"215":1,"217":1,"218":1,"230":1,"262":1,"263":1,"270":1,"271":1},"2":{"2":1,"31":2,"68":6,"69":2,"70":2,"71":1,"72":1,"73":1,"78":2,"79":2,"86":1,"106":1,"107":1,"108":1,"114":1,"118":1,"119":1,"120":1,"138":1,"139":1,"165":1,"173":2,"176":3,"177":3,"178":3,"179":6,"185":2,"186":2,"196":3,"204":2,"205":2,"208":2,"210":2,"211":1,"212":3,"214":3,"216":7,"219":4,"225":2,"226":1,"227":1,"228":3,"229":3,"231":6,"233":2,"234":2,"235":2,"236":2,"237":2,"238":4,"239":5,"240":1,"241":4,"242":4,"245":3,"250":5,"251":5,"255":10,"256":9,"257":9,"258":3,"260":7,"261":1,"262":3,"263":1,"265":2,"266":3,"267":4,"268":1,"270":2,"271":2,"272":3,"273":2,"277":1,"279":1,"280":3,"288":1,"303":2,"399":1}}],["yyyy",{"2":{"322":6}}],["your",{"2":{"212":1,"214":1,"216":1,"258":1}}],["y",{"2":{"205":1}}],["yield",{"2":{"81":1}}],["yml中ws下port的值",{"2":{"364":1}}],["yml中http下port的值",{"2":{"364":1}}],["yml中verifykey的值",{"2":{"364":1}}],["yml",{"2":{"2":1,"339":2,"340":1,"372":1,"377":1,"399":1}}],["yamlhost",{"2":{"343":1,"345":1}}],["yamladapters",{"2":{"340":1}}],["yamlmessage",{"2":{"339":1}}],["yamlmode",{"2":{"333":1}}],["yaml",{"2":{"2":1,"81":1,"296":2,"333":1,"339":1,"343":2,"363":2,"399":1}}],["需插件支持",{"2":{"349":1}}],["需按照类型填写",{"2":{"316":1}}],["需要你拥有一定的计算机科学基础",{"2":{"400":1}}],["需要你熟悉",{"2":{"76":1}}],["需要额外安装playwright的chromium及其依赖",{"2":{"353":1}}],["需要时可通过商店更新",{"2":{"347":1}}],["需要配置",{"2":{"339":1}}],["需要输入这个密钥校验",{"2":{"329":1}}],["需要传入一个",{"2":{"265":1}}],["需要机器人与使用者产生连续的对话",{"2":{"211":1}}],["需要机器人拥有发送",{"2":{"166":1}}],["需要注意的是",{"2":{"205":1}}],["需要使用适配器提供的工具类构建",{"2":{"176":1}}],["需要取消的定时任务的子标签名",{"2":{"97":1}}],["需要在请求头",{"2":{"63":1}}],["需要",{"2":{"7":1}}],["需更改为",{"2":{"2":1}}],["需在服务配置开启",{"2":{"0":1}}],["的认可就已经是最大的支持了",{"2":{"406":1}}],["的初衷",{"2":{"404":2}}],["的工作了",{"2":{"401":1}}],["的前期准备",{"2":{"400":1}}],["的博客",{"2":{"400":1}}],["的说明进行部署",{"2":{"399":1}}],["的基础上进行定制",{"2":{"389":1}}],["的迭代版本",{"2":{"389":1}}],["的形式",{"2":{"348":1}}],["的类型为数组",{"2":{"323":1,"324":1}}],["的类型为数字",{"2":{"318":1}}],["的类型为内容的值类型",{"2":{"320":1}}],["的类型为布尔型",{"2":{"319":1}}],["的类型为字符串或数值",{"2":{"321":1}}],["的类型为字符串",{"2":{"317":1}}],["的依赖",{"2":{"313":1}}],["的内置模块或是你在自己的目录内开发插件",{"2":{"313":1}}],["的内置模块",{"2":{"312":1}}],["的内容",{"2":{"103":1,"293":2}}],["的项目下开发",{"2":{"312":1}}],["的扩展实现",{"2":{"295":1}}],["的扩展查询方法",{"2":{"33":1}}],["的部署者查看的文档",{"2":{"293":1}}],["的标准库",{"2":{"289":1}}],["的编程方式",{"2":{"281":1}}],["的对象列表",{"2":{"262":1}}],["的私有功能",{"2":{"251":1}}],["的检查结果里添加关键值信息",{"2":{"241":1}}],["的元组",{"2":{"239":1}}],["的方式绕过检查",{"2":{"232":1}}],["的方法不尽相同",{"2":{"98":1}}],["的参数里设置",{"2":{"246":1}}],["的参数",{"2":{"231":1}}],["的事件",{"2":{"224":2}}],["的分类里",{"2":{"224":1}}],["的值并填入控制台的服务密钥中",{"2":{"363":1}}],["的值",{"2":{"223":1}}],["的值为",{"2":{"222":1}}],["的脸",{"2":{"223":1}}],["的用户自部署群聊机器人发布",{"2":{"404":1}}],["的用户在使用",{"2":{"293":1}}],["的用户id",{"2":{"165":1}}],["的用法是大致相同的",{"2":{"217":1}}],["的时候",{"2":{"213":1}}],["的文字图片",{"2":{"205":1}}],["的文本内使用了调色模板",{"2":{"204":1}}],["的消息",{"0":{"178":1},"2":{"246":1}}],["的骰子魔法表情",{"2":{"172":1}}],["的返回",{"0":{"104":1}}],["的网页窗口",{"2":{"89":1}}],["的日志同样拥有与",{"2":{"84":1}}],["的路径添加入环境变量中再次尝试开头的操作",{"2":{"360":1}}],["的路径或",{"2":{"81":1}}],["的路由注册做了简易的封装",{"2":{"64":1}}],["的导入机制",{"2":{"76":1}}],["的插件加载得益于",{"2":{"76":1}}],["的一些高级用法",{"2":{"65":1}}],["的http服务构建工具",{"2":{"59":1}}],["的实例",{"2":{"50":1,"51":1}}],["的请求均返回字符串的请求结果",{"2":{"48":1}}],["的操作",{"2":{"27":1}}],["的子类",{"2":{"5":1,"85":1}}],["的开发差异变得极其之小",{"2":{"4":1}}],["的配置中",{"2":{"2":1}}],["的",{"0":{"191":1},"2":{"2":1,"3":1,"8":1,"98":1,"179":1,"265":1,"283":1,"339":1,"340":2}}],["以确保正常使用",{"2":{"383":1}}],["以上配置调用",{"2":{"326":1}}],["以使用不同种类的选择器",{"2":{"322":1}}],["以下是兔兔的窗口中可能出现的报错信息以及相应处理方法",{"2":{"364":1}}],["以下说明默认在",{"2":{"312":1}}],["以下简称",{"2":{"2":1,"7":1,"9":1,"11":1,"389":1}}],["以适配不同运营方的连接协议",{"2":{"286":1}}],["以节约内存",{"2":{"250":1}}],["以此注册消息响应来实现你的机器人功能",{"2":{"229":1}}],["以外的一些",{"2":{"103":1}}],["以目录导入这个插件",{"2":{"80":1}}],["以",{"2":{"79":1,"81":1,"89":1}}],["以免",{"2":{"14":1,"20":1}}],["以及控制台项目",{"2":{"389":1}}],["以及插件化动态导入",{"2":{"281":1}}],["以及针对这则消息的一些操作api",{"2":{"260":1}}],["以及一些相关操作函数",{"2":{"228":1}}],["以及移除了",{"2":{"91":1}}],["以及对单独的功能进行热更新",{"2":{"76":1}}],["以及",{"2":{"2":1,"34":1,"94":1,"181":1,"323":1,"382":1}}],["bin",{"2":{"388":1}}],["big",{"2":{"181":1,"382":1}}],["b3",{"2":{"339":1}}],["b6",{"2":{"339":1}}],["bb",{"2":{"339":1}}],["break",{"2":{"216":1}}],["browser=launcher",{"2":{"388":1}}],["browser=true",{"2":{"183":2}}],["browser=mybrowserlauncher",{"2":{"88":1}}],["browserlaunchconfig",{"2":{"88":2,"388":2}}],["browser",{"2":{"88":6,"89":4,"90":2,"388":1}}],["bgcolor",{"2":{"203":1}}],["by",{"2":{"178":2}}],["bytes",{"2":{"23":3,"27":2,"28":1,"55":2,"57":2,"58":1,"188":3}}],["bf0ed01635493790634",{"2":{"163":1}}],["blacklist",{"2":{"116":1}}],["block",{"2":{"25":3,"363":2}}],["b",{"2":{"80":1,"81":1}}],["before",{"0":{"69":1,"70":1,"71":1},"2":{"69":1,"70":1,"71":1,"135":1}}],["beta",{"0":{"0":1,"9":1,"11":1,"16":1,"18":1,"176":1,"267":1},"1":{"1":1,"10":1,"12":1,"17":1,"19":1,"20":1,"21":1,"22":1,"23":1,"177":1,"178":1,"179":1,"180":1}}],["boolean",{"2":{"319":1}}],["bool",{"2":{"57":1,"58":2,"81":1,"82":1,"94":1,"102":1,"116":1,"118":2,"165":1,"184":1,"190":1,"200":1,"212":1,"216":2,"230":3,"231":3,"239":1,"253":2,"262":3,"273":2,"301":1}}],["botbasemodel",{"2":{"33":2,"35":1}}],["bot2",{"2":{"14":2,"20":2,"250":3,"251":2}}],["bot1",{"2":{"14":2,"20":1,"250":3,"251":4}}],["bothandlerfactory",{"2":{"5":1,"92":2,"93":2,"95":3,"97":2,"284":1,"303":1}}],["botadapterprotocol",{"2":{"5":2,"68":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"220":4,"222":1,"223":1,"224":3,"225":3,"226":1,"227":1,"255":1,"262":1,"270":1,"271":1,"303":1}}],["bot",{"0":{"97":1,"125":1,"245":1,"257":1},"1":{"258":1,"259":1},"2":{"1":1,"3":1,"4":1,"6":1,"8":1,"10":1,"12":1,"15":1,"17":1,"19":1,"21":1,"23":1,"31":1,"61":3,"65":1,"68":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"78":2,"79":3,"81":4,"84":2,"85":2,"88":2,"91":1,"92":2,"93":2,"95":3,"97":3,"98":1,"99":1,"103":1,"173":2,"176":1,"179":1,"183":1,"185":1,"186":1,"196":2,"204":1,"205":1,"208":1,"210":1,"212":1,"214":1,"216":1,"220":4,"221":1,"222":1,"223":1,"224":3,"225":1,"226":1,"227":1,"229":1,"231":4,"233":1,"234":1,"235":1,"236":1,"237":1,"238":2,"239":1,"241":1,"242":2,"245":3,"246":1,"247":1,"248":1,"251":3,"253":3,"255":3,"256":1,"257":2,"258":1,"260":1,"262":1,"266":1,"267":1,"268":1,"270":1,"271":1,"272":1,"279":4,"280":3,"292":1,"293":4,"295":1,"296":1,"298":1,"301":1,"302":1,"303":3,"304":1,"305":4,"307":3,"313":4,"326":1,"327":1,"364":1,"368":1,"388":3,"389":2}}],["bucket",{"2":{"339":1}}],["button",{"2":{"196":4}}],["build",{"2":{"228":1,"311":2}}],["builder=baidusearch",{"2":{"31":1}}],["builder=mybuilder",{"2":{"23":1,"27":1}}],["builder",{"2":{"19":2,"21":2,"27":1,"273":1}}],["builtin",{"2":{"191":1,"205":1,"206":1}}],["bus",{"2":{"43":1,"44":1,"45":2,"46":1}}],["bat",{"2":{"388":1}}],["batch",{"0":{"37":1},"2":{"37":1}}],["bare",{"2":{"360":1}}],["baike",{"2":{"339":1}}],["baidu",{"2":{"31":1,"172":1,"186":2,"339":1}}],["baidusearch",{"2":{"31":1}}],["bashcd",{"2":{"313":1,"387":1}}],["bashgit",{"2":{"313":1,"388":1}}],["bashpip",{"2":{"244":1,"313":1,"330":1,"388":1}}],["bashpython",{"2":{"81":1,"90":1,"311":1,"388":1}}],["bash",{"2":{"182":1,"388":4}}],["bashamiyabot",{"2":{"90":1}}],["192",{"2":{"363":1}}],["16",{"2":{"322":1}}],["1658748972",{"2":{"193":1,"195":1}}],["17",{"2":{"222":1}}],["1704356453",{"2":{"196":1}}],["1703561314",{"2":{"195":1}}],["175",{"2":{"175":1,"201":1}}],["155",{"2":{"85":1}}],["18+08",{"2":{"222":1}}],["18",{"2":{"84":2,"85":1,"86":1,"181":1,"382":1}}],["102005657",{"2":{"195":1,"196":1}}],["101993071",{"2":{"193":1,"195":1}}],["100000000",{"2":{"222":2}}],["1000ms",{"2":{"186":1}}],["1000",{"2":{"90":1}}],["100",{"2":{"89":1,"200":1}}],["10",{"2":{"42":1,"181":1,"222":1,"318":1,"331":1,"382":1,"385":1}}],["12345",{"2":{"253":2}}],["123456",{"2":{"223":3,"280":1,"343":1}}],["12345678",{"2":{"165":1,"198":1}}],["1280",{"2":{"89":1,"184":1}}],["12",{"2":{"11":2}}],["127",{"2":{"1":1,"3":1,"8":1,"10":1,"12":1,"34":1,"61":1,"280":1,"343":1,"344":1,"363":1}}],["111111",{"2":{"268":1}}],["116",{"2":{"81":1}}],["11",{"2":{"9":2,"84":2,"85":1,"86":1,"181":2,"382":2}}],["1",{"2":{"1":1,"3":1,"8":1,"10":1,"12":1,"14":1,"19":1,"34":1,"42":1,"61":1,"78":1,"79":1,"81":1,"85":4,"91":1,"196":1,"213":1,"238":1,"240":1,"241":1,"261":1,"280":1,"295":1,"303":1,"307":1,"327":1,"339":2,"340":1,"343":1,"344":1,"363":1,"364":1,"388":1}}],["08",{"2":{"322":1}}],["07",{"2":{"315":2}}],["000000",{"2":{"343":1}}],["00",{"2":{"222":1,"322":4}}],["04",{"2":{"181":2,"382":2,"387":1}}],["053",{"2":{"86":1}}],["05",{"2":{"86":1,"322":2}}],["02",{"2":{"84":2,"85":1,"86":1}}],["0",{"2":{"1":2,"3":2,"8":2,"10":2,"12":2,"14":2,"19":2,"21":8,"34":2,"61":6,"78":1,"79":1,"85":3,"177":1,"205":1,"212":1,"216":2,"222":1,"230":1,"238":1,"280":2,"295":1,"301":1,"303":1,"318":2,"327":1,"340":8,"343":2,"344":2,"345":8,"363":13,"364":2}}],["source",{"2":{"388":1}}],["some",{"2":{"279":1}}],["symlink",{"2":{"360":1}}],["sync",{"2":{"58":2,"81":1,"85":1}}],["shellplaywright",{"2":{"353":2}}],["share",{"2":{"172":1}}],["shard",{"2":{"14":1,"19":1,"20":2}}],["shards=2",{"2":{"20":2}}],["shards",{"2":{"14":6,"19":1}}],["ss",{"2":{"322":6}}],["schema",{"2":{"296":2,"300":5,"315":2}}],["schema=f",{"2":{"296":1}}],["schema=",{"2":{"295":2}}],["schedules",{"0":{"144":1}}],["schedule",{"0":{"112":1,"121":1,"143":1,"151":1},"2":{"121":1,"143":1,"151":1}}],["scheduler",{"2":{"94":2,"95":1}}],["scripts",{"2":{"388":1}}],["script",{"2":{"185":2}}],["src",{"2":{"137":1,"158":1,"262":1,"265":1,"267":2,"307":1}}],["speak",{"2":{"109":1,"149":1}}],["save",{"2":{"86":2}}],["sayhello",{"2":{"61":1}}],["say",{"2":{"61":1}}],["s",{"2":{"85":1,"86":2,"222":1,"258":1}}],["swagger",{"2":{"61":2}}],["situations",{"2":{"360":1}}],["singlemode",{"2":{"340":1}}],["since",{"2":{"144":1}}],["size=80",{"2":{"205":1}}],["size",{"2":{"37":1,"42":1,"205":1}}],["silk",{"2":{"23":1}}],["silkcoder",{"2":{"23":2}}],["sqlite",{"0":{"33":1},"2":{"32":1,"33":3}}],["suffix",{"2":{"223":1}}],["sur",{"2":{"181":1,"382":1}}],["subject",{"2":{"223":1}}],["subsystem",{"2":{"181":1,"382":1}}],["subscribe",{"2":{"45":3}}],["sub",{"2":{"91":1,"94":1,"96":2,"97":2,"109":1,"224":2}}],["super",{"2":{"88":1,"360":1,"388":1}}],["su",{"2":{"31":1}}],["sleep",{"2":{"14":1,"20":1,"31":1,"216":1}}],["stop",{"2":{"216":1}}],["star",{"2":{"406":1}}],["start",{"2":{"14":3,"20":3,"88":1,"112":1,"134":1,"151":1,"183":2,"245":1,"250":2,"251":1,"253":1,"280":1,"360":1,"388":1}}],["status",{"2":{"50":2}}],["stringify",{"2":{"57":1,"58":1}}],["string",{"2":{"2":1,"316":1,"317":1,"321":2,"323":2,"326":1,"339":1,"399":1}}],["str",{"2":{"1":1,"3":1,"8":1,"10":1,"12":1,"19":1,"21":2,"23":6,"27":6,"28":1,"44":1,"45":1,"46":1,"52":2,"53":2,"54":2,"55":4,"56":2,"57":1,"58":1,"61":4,"70":1,"71":1,"72":1,"73":1,"81":2,"82":1,"85":2,"86":4,"87":5,"91":1,"94":1,"97":1,"101":1,"102":1,"103":2,"106":3,"107":2,"108":4,"109":5,"110":5,"111":2,"112":7,"113":3,"114":2,"115":1,"116":2,"117":2,"118":2,"119":3,"120":2,"121":2,"122":2,"123":3,"126":1,"127":1,"128":1,"129":1,"130":1,"131":2,"132":2,"133":1,"134":3,"135":2,"137":2,"138":2,"139":4,"140":1,"141":1,"142":2,"143":2,"144":1,"145":2,"146":1,"148":2,"149":3,"150":3,"151":8,"152":3,"153":1,"154":4,"155":2,"156":4,"157":2,"158":3,"159":4,"160":4,"161":4,"163":1,"165":1,"169":4,"175":1,"177":1,"184":1,"188":2,"190":1,"193":2,"200":1,"203":2,"205":1,"208":1,"210":2,"221":2,"230":1,"231":1,"256":1,"262":17,"265":3,"296":5,"298":2,"299":2,"301":2}}],["see",{"2":{"360":2}}],["seconds",{"2":{"152":1,"154":1,"156":1}}],["second=30",{"2":{"95":1}}],["secret=",{"2":{"21":1}}],["secret",{"2":{"17":2,"19":3,"20":2}}],["send",{"0":{"71":1,"72":1,"265":1,"268":1,"269":1},"1":{"270":1,"271":1},"2":{"71":1,"72":1,"173":1,"176":1,"179":1,"180":1,"196":1,"216":2,"257":4,"258":4,"263":1,"265":1,"266":1,"267":2,"268":1,"270":1,"271":1,"272":2}}],["settings",{"2":{"364":3}}],["setting",{"0":{"140":1},"2":{"340":1,"377":1}}],["set",{"0":{"69":1,"159":1,"160":1,"161":1,"299":1},"2":{"69":1,"231":1,"247":1,"299":1}}],["select",{"0":{"42":1},"2":{"33":1,"40":2,"41":3,"42":2}}],["self",{"2":{"5":1,"61":2,"62":1,"87":5,"88":3,"327":2,"388":2}}],["serve",{"2":{"61":1,"388":1}}],["server",{"0":{"367":1},"2":{"21":1,"61":6,"62":1,"64":1,"181":1,"331":1,"343":1,"363":2,"382":1,"385":1,"388":1}}],["service",{"2":{"1":2,"3":2,"8":2,"10":2,"12":2}}],["==",{"2":{"216":1,"388":1}}],["=",{"2":{"1":3,"3":4,"5":1,"6":2,"8":4,"10":4,"12":4,"14":2,"15":1,"17":2,"19":2,"20":2,"21":1,"23":2,"27":2,"31":1,"33":4,"34":1,"35":3,"37":1,"40":1,"41":1,"42":1,"49":2,"50":2,"51":2,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"61":1,"63":1,"64":2,"68":1,"78":2,"79":1,"81":1,"85":3,"86":1,"87":1,"88":2,"92":1,"93":1,"95":1,"97":1,"98":1,"99":1,"103":1,"163":1,"173":1,"176":3,"179":2,"180":1,"185":3,"191":5,"193":1,"196":4,"205":1,"206":1,"212":1,"214":1,"216":2,"231":1,"241":1,"245":1,"246":1,"247":1,"248":1,"250":2,"251":3,"253":1,"255":1,"257":5,"258":2,"265":1,"266":2,"267":2,"268":1,"280":1,"293":3,"294":1,"295":1,"296":2,"298":1,"301":1,"303":1,"304":2,"327":1,"360":3,"388":1}}],["already",{"0":{"377":1}}],["also",{"2":{"360":2}}],["allow",{"2":{"230":1,"231":1,"242":2}}],["all",{"0":{"152":1,"153":1,"167":1},"2":{"167":1}}],["abcdef",{"2":{"343":1}}],["ae",{"2":{"339":1}}],["a1",{"2":{"339":1}}],["a4",{"2":{"339":1}}],["age",{"2":{"326":2}}],["autologin",{"2":{"372":1}}],["auto",{"2":{"200":2}}],["authkey",{"2":{"63":1,"340":3,"343":8,"363":1}}],["auth",{"0":{"366":1},"2":{"8":1,"61":1,"63":3}}],["activate",{"2":{"388":2}}],["action",{"2":{"196":1,"223":1}}],["access",{"2":{"1":1,"3":1,"10":1,"12":1,"339":3}}],["amy",{"2":{"247":1}}],["amp",{"0":{"180":1},"2":{"324":1,"339":1,"378":2}}],["amiya2号",{"2":{"404":2}}],["amiya",{"2":{"81":2,"85":1,"90":1,"234":1,"236":1,"237":1,"247":1,"313":4,"388":6,"389":2}}],["amiyabotplugininstance",{"0":{"295":1},"1":{"296":1,"297":1,"298":1,"299":1,"300":1,"301":1},"2":{"293":3,"295":5,"296":1,"301":2}}],["amiyabot",{"0":{"265":1,"402":1},"1":{"403":1,"404":1,"405":1},"2":{"1":2,"3":2,"4":1,"5":2,"6":2,"7":1,"8":2,"10":2,"12":2,"14":3,"15":2,"17":2,"19":3,"20":2,"21":3,"23":2,"24":1,"25":2,"27":1,"31":1,"32":2,"33":2,"34":1,"43":2,"47":4,"58":1,"59":1,"61":4,"64":1,"65":3,"66":1,"67":1,"69":1,"75":1,"76":1,"78":4,"79":1,"81":2,"83":1,"84":2,"86":1,"87":1,"88":2,"91":3,"92":4,"93":2,"95":2,"97":2,"98":2,"99":3,"173":1,"176":2,"191":1,"196":1,"205":1,"206":1,"220":1,"224":1,"225":2,"228":3,"231":1,"232":1,"236":1,"243":1,"244":1,"245":4,"246":2,"247":1,"248":2,"249":1,"250":5,"251":11,"252":1,"253":3,"256":1,"260":1,"266":1,"267":1,"268":2,"279":2,"280":5,"281":1,"282":1,"293":1,"303":1,"306":1,"307":1,"313":4,"327":1,"330":1,"344":1,"352":1,"378":1,"385":1,"386":1,"387":3,"388":2,"389":1,"396":2,"403":1,"404":4,"405":1,"406":4,"407":2,"408":2}}],["atk",{"2":{"326":2}}],["attrs",{"2":{"326":2}}],["attempted",{"2":{"81":1}}],["at",{"0":{"164":1,"165":1,"166":1,"167":1},"1":{"165":1,"167":1},"2":{"165":1,"167":1,"219":1,"222":1,"262":3,"273":1}}],["at=false",{"2":{"163":1,"169":1,"193":1,"195":1,"196":1}}],["avatar",{"0":{"147":1},"2":{"262":1}}],["admin",{"2":{"262":1}}],["address",{"0":{"377":1}}],["added",{"2":{"94":1}}],["add",{"0":{"106":1,"107":1},"2":{"94":2,"95":1,"116":1,"159":1,"160":1,"176":1,"177":3,"178":2,"179":4,"196":6,"360":2}}],["adaptive=true",{"2":{"23":1}}],["adapter=test",{"2":{"280":1}}],["adapter=qqguildsandboxbotinstance",{"2":{"15":1,"248":1}}],["adapter=qq",{"2":{"14":2,"17":1,"19":1,"20":2,"21":1,"23":1}}],["adapter=kookbotinstance",{"2":{"6":1}}],["adapter=adapter",{"2":{"1":1,"3":1,"8":1,"10":1,"12":1}}],["adapter",{"0":{"5":1},"2":{"1":1,"3":1,"5":2,"8":1,"10":1,"12":1,"285":1,"286":1}}],["adaptersettings",{"2":{"340":1}}],["adapters",{"2":{"1":1,"3":1,"8":1,"10":1,"12":1,"14":1,"15":1,"17":1,"19":1,"21":2,"99":3,"176":2,"248":1,"280":1}}],["asctime",{"2":{"86":1}}],["as",{"2":{"85":1,"305":1,"307":1}}],["assetsfolder",{"2":{"81":1}}],["async",{"2":{"23":4,"27":5,"31":2,"45":1,"47":3,"57":2,"58":1,"61":2,"62":1,"68":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"78":1,"79":1,"85":1,"88":2,"91":1,"92":1,"93":1,"95":2,"97":1,"173":1,"176":1,"179":1,"185":1,"186":1,"196":1,"204":1,"205":1,"208":1,"210":1,"212":1,"214":1,"216":1,"220":3,"222":1,"223":1,"224":3,"225":1,"226":1,"227":1,"229":1,"231":2,"233":1,"234":1,"235":1,"236":1,"237":1,"238":2,"239":1,"241":1,"242":2,"245":1,"250":2,"251":2,"255":3,"257":2,"258":1,"260":2,"270":1,"271":1,"272":1,"280":1,"303":2,"307":1}}],["asyncio",{"2":{"14":2,"20":2,"31":1,"61":1,"88":1,"216":1,"245":2,"250":3,"251":2,"280":2}}],["a",{"0":{"375":1},"2":{"80":1,"81":1,"85":7,"86":2,"360":6}}],["after",{"0":{"72":1,"73":1},"2":{"72":1,"73":1,"132":1,"135":1}}],["aiohttp",{"2":{"47":1,"50":1}}],["an",{"2":{"360":2}}],["announces",{"0":{"108":1,"114":1},"2":{"108":1}}],["and",{"2":{"85":1,"258":1,"360":1}}],["android",{"2":{"7":1}}],["any",{"2":{"44":1,"171":1,"184":1,"239":1,"299":1}}],["area",{"2":{"360":1}}],["are",{"2":{"360":1}}],["arknights",{"2":{"307":1}}],["ark",{"0":{"162":1,"163":1},"1":{"163":1},"2":{"162":2,"163":1}}],["arg3=",{"2":{"25":2}}],["arg2",{"2":{"25":2}}],["arg1",{"2":{"25":2}}],["args",{"2":{"25":1,"147":1,"360":1}}],["array",{"2":{"2":3,"323":2,"324":2,"339":3,"399":3}}],["await",{"2":{"23":1,"25":1,"31":3,"47":6,"49":1,"50":1,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"88":3,"98":1,"99":1,"103":1,"176":2,"177":1,"179":4,"180":2,"196":1,"212":1,"214":1,"216":4,"255":4,"257":7,"258":3,"266":1,"267":1,"268":1,"270":1,"271":1,"272":1}}],["apscheduler",{"2":{"91":2,"95":1}}],["append",{"0":{"253":1},"2":{"253":1}}],["app",{"2":{"64":3,"339":1,"340":1,"364":1,"388":1}}],["application",{"2":{"53":1,"109":1}}],["appid",{"2":{"6":1,"10":1,"12":1,"196":2,"221":2,"245":1,"280":1,"338":2}}],["appid=",{"2":{"14":2,"17":1,"19":1,"20":2,"21":1,"245":1,"246":1,"250":2,"251":3,"253":1,"268":2,"280":1}}],["appid=qq",{"2":{"3":1,"8":1}}],["appid=appid",{"2":{"1":1,"10":1,"12":1}}],["api限速设置",{"2":{"339":1}}],["api",{"0":{"7":1,"98":1,"99":1,"104":1,"105":1,"110":1,"130":1,"223":1,"340":1,"367":1,"400":1},"1":{"8":1,"99":1,"100":1,"101":1,"102":1,"103":1,"104":1,"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1,"115":1,"116":1,"117":1,"118":1,"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"157":1,"158":1,"159":1,"160":1,"161":1},"2":{"4":1,"7":2,"8":2,"15":1,"27":1,"88":1,"98":5,"99":9,"100":2,"103":1,"105":2,"170":3,"172":1,"173":3,"176":1,"209":1,"223":2,"243":1,"248":1,"340":4,"351":2,"364":4,"367":1,"368":1,"377":1,"398":1,"400":4}}],["has",{"0":{"375":1}}],["handle",{"0":{"70":1,"73":1},"2":{"70":1,"73":1}}],["handler=err",{"2":{"85":1}}],["handler",{"2":{"45":3,"46":1,"81":1,"85":3}}],["h",{"2":{"360":1}}],["hh",{"2":{"322":6}}],["hi",{"2":{"242":1}}],["hidetip",{"2":{"118":1}}],["history",{"2":{"116":1}}],["help",{"2":{"360":3}}],["helloworld",{"2":{"238":2}}],["hello",{"2":{"31":1,"61":2,"78":2,"79":2,"165":1,"173":3,"176":2,"179":1,"185":5,"186":1,"196":1,"200":1,"201":1,"203":1,"204":2,"205":4,"208":1,"210":1,"212":2,"214":2,"216":3,"229":3,"233":2,"234":2,"235":2,"236":2,"237":4,"238":3,"239":2,"242":2,"245":3,"250":2,"251":2,"255":2,"257":3,"258":2,"265":1,"266":1,"267":1,"272":2,"273":1,"280":2,"303":2}}],["heart",{"2":{"345":1,"400":1}}],["header",{"2":{"63":1}}],["headers",{"2":{"53":1,"54":1,"55":1,"57":1,"58":1,"103":2}}],["hey",{"2":{"237":1,"242":1,"250":2,"251":2}}],["height=100",{"2":{"205":1}}],["height",{"2":{"89":1,"184":1,"203":1}}],["html制图需要使用",{"2":{"181":1}}],["html",{"0":{"181":1,"184":1,"191":1},"1":{"182":1,"183":1,"184":1,"185":1,"186":1},"2":{"31":1,"181":1,"184":2,"185":6,"186":1,"189":2,"191":4,"275":1,"360":1}}],["http或者cq",{"2":{"368":1}}],["http或是mirai",{"2":{"364":1}}],["http中host地址与两个端口填写是否有误",{"2":{"367":1}}],["http端口",{"2":{"364":1}}],["http而不是qq",{"2":{"364":1,"368":1}}],["http服务器支持",{"0":{"59":1},"1":{"60":1,"61":1,"62":1,"63":1,"64":1}}],["httprequests",{"2":{"47":1}}],["https",{"2":{"31":1,"61":1,"163":2,"172":1,"186":2,"280":1,"313":2,"339":1,"344":1,"363":1,"388":1,"400":1}}],["httpserver",{"0":{"61":1},"2":{"21":1,"61":2,"63":2,"64":1}}],["http",{"0":{"7":1,"47":1,"223":1,"339":1,"340":1,"367":1,"400":1},"1":{"8":1,"48":1,"49":1,"50":1,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1},"2":{"1":2,"3":4,"7":3,"8":4,"10":2,"12":2,"21":1,"47":9,"48":1,"49":1,"50":1,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"61":1,"65":1,"103":1,"104":1,"170":5,"172":1,"173":1,"176":2,"209":2,"223":2,"243":1,"315":1,"339":1,"340":6,"343":1,"344":1,"363":1,"364":3,"377":1,"398":1,"400":4}}],["howtouse",{"2":{"292":1,"293":1}}],["hoist",{"2":{"111":1,"150":1}}],["host地址",{"2":{"364":1}}],["host=",{"2":{"34":1,"61":1}}],["host",{"2":{"1":1,"3":1,"8":1,"10":1,"12":1,"21":1,"61":1,"280":1,"333":1,"340":2,"345":1,"363":2}}],["hook",{"2":{"0":1}}],["端口",{"2":{"1":2,"3":2,"8":2,"10":2,"12":2}}],["items",{"2":{"323":2,"324":2}}],["item",{"2":{"253":1,"257":2,"339":1}}],["icon",{"2":{"222":1}}],["ignore=",{"2":{"85":1}}],["ignore",{"2":{"85":1}}],["ids",{"2":{"109":1,"156":1,"157":1}}],["id",{"0":{"178":1},"2":{"82":5,"94":1,"106":3,"107":2,"108":3,"109":3,"110":2,"111":1,"112":2,"113":1,"114":2,"115":1,"116":2,"117":2,"118":2,"119":3,"120":2,"121":2,"122":2,"123":3,"126":1,"127":1,"128":1,"129":1,"130":1,"131":2,"132":1,"133":1,"134":2,"137":2,"138":2,"139":3,"140":1,"141":1,"142":2,"143":2,"144":1,"145":2,"146":1,"148":2,"149":2,"150":2,"151":3,"152":1,"153":1,"154":2,"155":2,"156":1,"157":1,"158":3,"159":2,"160":2,"161":4,"163":2,"173":2,"175":1,"177":4,"178":4,"193":3,"196":1,"201":1,"204":1,"222":3,"223":1,"230":1,"231":3,"256":2,"262":11,"265":3,"267":2,"298":1,"299":1,"301":1,"338":1,"339":1,"340":1,"364":1}}],["id=none",{"2":{"298":1,"299":1}}],["id=fn",{"2":{"231":1}}],["id=data",{"2":{"196":1}}],["id=123",{"2":{"173":2}}],["id=",{"2":{"78":1,"79":1,"176":1,"177":1,"179":1,"185":1,"195":1,"231":1,"256":2,"266":1,"267":2,"295":1,"298":1,"299":1,"303":1,"327":1}}],["if",{"2":{"49":1,"68":1,"70":1,"180":1,"212":1,"214":2,"216":2,"239":1,"240":1,"241":1,"255":2,"257":2,"258":1,"388":1}}],["iso8601",{"2":{"262":1}}],["is",{"2":{"31":1,"34":1,"86":2,"102":1,"118":1,"184":1,"186":2,"190":1,"251":1,"255":1,"262":3}}],["io",{"0":{"24":1},"1":{"25":1},"2":{"24":1,"25":4}}],["ios",{"2":{"23":1}}],["imagecreator",{"2":{"205":1,"206":1}}],["imageelem",{"2":{"203":1,"205":4}}],["imagescache",{"2":{"316":1}}],["imagescachepath",{"2":{"316":1}}],["images=",{"2":{"205":1}}],["images",{"2":{"203":1,"205":1}}],["image",{"0":{"28":1,"188":1,"203":1},"1":{"204":1,"205":1},"2":{"23":2,"27":3,"28":1,"31":1,"188":3,"203":1,"204":1,"205":3,"262":1,"275":1,"277":1}}],["importerror",{"2":{"81":1}}],["importlib",{"2":{"76":1}}],["import",{"2":{"1":1,"3":1,"6":1,"8":1,"10":1,"12":1,"14":1,"15":1,"17":1,"19":1,"21":2,"23":3,"25":1,"27":3,"33":1,"34":1,"43":1,"47":2,"58":1,"61":1,"69":1,"78":1,"79":2,"80":1,"81":3,"84":1,"86":1,"87":1,"88":2,"91":1,"92":2,"93":2,"95":3,"97":2,"99":3,"173":1,"176":2,"191":1,"196":1,"205":1,"206":1,"220":1,"225":1,"231":1,"236":1,"245":1,"248":1,"250":1,"251":1,"260":1,"280":2,"281":1,"293":1,"295":1,"301":1,"303":1,"304":1,"305":1,"307":1,"310":2,"327":1,"388":1}}],["inlinekeyboard",{"2":{"193":1,"196":3}}],["innertext",{"2":{"185":1}}],["info",{"2":{"84":3,"86":3,"87":1,"241":1,"360":1}}],["insecure",{"2":{"363":2}}],["insert",{"0":{"37":1,"38":1},"2":{"37":1,"38":1}}],["instruction=f",{"2":{"293":1}}],["instruction",{"2":{"293":3,"296":1}}],["installer重新安装mcl",{"2":{"375":1}}],["installer移动到别处重新安装",{"2":{"371":1}}],["installer转移至一个没有中文字符的路径下重新安装",{"2":{"371":1}}],["install",{"2":{"78":1,"79":1,"80":1,"81":5,"182":2,"244":1,"300":1,"307":3,"310":1,"313":1,"327":1,"330":1,"353":2,"378":1,"388":5}}],["instance",{"2":{"4":1,"68":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"92":1,"93":1,"95":2,"97":1,"98":2,"99":1,"103":1,"173":3,"196":2,"220":3,"222":1,"223":1,"224":3,"225":1,"226":1,"227":1,"255":1,"256":2,"262":1,"270":2,"271":2,"280":3,"303":1}}],["in",{"0":{"25":1,"377":1},"2":{"25":2,"81":4,"85":1,"239":1,"257":1,"360":1}}],["indexerror",{"2":{"227":1}}],["index=1",{"2":{"20":1}}],["index=0",{"2":{"20":1}}],["index",{"2":{"14":1,"19":1,"134":1,"360":2}}],["initbili",{"2":{"400":1}}],["initial",{"2":{"345":1,"400":1}}],["initialize",{"2":{"84":2}}],["init",{"2":{"5":1,"80":1,"81":8,"88":2,"185":4,"191":1,"292":1,"302":1,"304":1,"305":2,"310":1,"360":1,"388":2}}],["into",{"2":{"360":1}}],["integer",{"2":{"318":2,"323":1,"326":1}}],["integerfield",{"2":{"33":1,"35":1}}],["interface",{"2":{"49":1,"50":1,"51":1,"52":1,"53":1,"54":1,"55":1,"103":1}}],["int",{"2":{"1":2,"3":2,"8":2,"10":2,"12":2,"14":2,"19":2,"21":1,"37":1,"42":2,"61":1,"85":1,"86":1,"91":1,"94":1,"106":1,"108":1,"109":5,"111":2,"113":1,"116":1,"119":1,"132":1,"134":1,"135":1,"139":2,"144":1,"149":3,"150":2,"165":1,"175":1,"177":2,"178":1,"184":3,"190":1,"198":1,"203":2,"205":3,"212":2,"216":2,"230":1,"239":1,"262":1,"296":1}}],["ip",{"2":{"1":1,"3":1,"8":1,"10":1,"12":1,"345":1}}],["p",{"2":{"360":2}}],["png",{"2":{"205":1}}],["pip",{"2":{"310":1,"378":1}}],["pil",{"2":{"181":2}}],["pins",{"0":{"141":1}}],["pin",{"0":{"107":1,"120":1}}],["permission",{"0":{"110":1,"130":1,"142":1,"148":1,"159":1,"160":1},"2":{"109":1,"149":1}}],["peewee文档",{"2":{"32":1}}],["peewee",{"2":{"32":1,"33":1,"40":2,"41":2,"42":1}}],["px",{"2":{"89":2}}],["pypyodbc",{"2":{"310":6}}],["py",{"2":{"79":2,"80":3,"81":10,"84":1,"85":1,"90":1,"292":2,"302":3,"303":1,"304":3,"305":2,"307":2,"310":6,"311":2,"388":2}}],["pythonplugin",{"2":{"296":1}}],["pythonparams",{"2":{"193":1}}],["pythonmessage",{"2":{"265":1}}],["pythonimport",{"2":{"235":1,"245":1,"250":1,"251":1,"280":1,"293":1,"388":1}}],["pythonawait",{"2":{"177":1,"178":1,"218":1,"256":1}}],["pythonasync",{"2":{"45":1,"85":1,"214":1,"239":1,"240":1,"241":1}}],["pythonconfig",{"2":{"298":1}}],["pythoncallback",{"2":{"180":1}}],["pythonchain",{"2":{"165":1,"167":1,"169":1,"172":2,"175":1,"184":1,"188":2,"190":1,"198":1,"200":1,"201":1,"203":1,"208":1,"210":1,"273":1,"275":1,"277":1}}],["pythonclass",{"2":{"5":1,"31":1}}],["pythonkv",{"2":{"163":1}}],["pythontry",{"2":{"85":1}}],["pythonbot",{"2":{"79":1,"80":1,"81":2,"82":1,"98":1,"183":1,"247":1,"266":1,"267":1,"268":1,"294":1,"299":1}}],["pythonbot1",{"2":{"20":1}}],["pythonserver",{"2":{"63":1,"64":1}}],["pythonfile",{"2":{"57":1}}],["pythonfrom",{"2":{"1":1,"3":1,"6":1,"8":1,"10":1,"12":1,"14":1,"15":1,"17":1,"19":1,"21":1,"23":1,"25":1,"27":1,"33":1,"34":1,"43":1,"47":1,"58":1,"61":1,"69":1,"78":1,"79":1,"81":1,"84":1,"86":1,"87":1,"88":1,"91":1,"92":1,"93":1,"95":1,"97":1,"99":1,"173":1,"176":1,"191":1,"196":1,"205":1,"206":1,"220":1,"225":1,"231":1,"236":1,"248":1,"260":1,"295":1,"301":1,"303":1,"305":1,"327":1}}],["pythonres",{"2":{"49":1,"50":1,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"103":1}}],["pythonevent",{"2":{"44":1,"46":1}}],["pythondata",{"2":{"37":1,"40":1,"41":1,"42":1}}],["python",{"0":{"79":1,"80":1},"2":{"14":1,"20":1,"35":1,"45":1,"47":1,"62":1,"68":1,"70":1,"71":1,"72":1,"73":1,"74":1,"76":2,"79":2,"81":1,"179":1,"185":1,"186":1,"195":1,"204":1,"208":1,"210":1,"212":1,"216":1,"222":1,"223":1,"224":2,"226":1,"227":1,"229":1,"231":1,"233":1,"234":1,"237":1,"238":1,"242":1,"246":1,"253":1,"255":3,"257":2,"258":1,"270":1,"271":1,"272":1,"279":1,"289":1,"302":1,"303":1,"304":1,"307":2,"310":2,"348":1,"388":3,"403":1}}],["please~",{"2":{"212":1,"214":1,"216":1}}],["plugin2",{"2":{"301":1}}],["plugin=true",{"2":{"81":2,"307":1}}],["pluginsdev",{"2":{"292":1,"302":2,"304":1,"307":1,"313":2}}],["plugins",{"2":{"81":1,"307":1,"311":1,"313":1,"348":1,"352":1,"388":1}}],["plugin",{"2":{"78":6,"79":3,"80":1,"81":8,"82":5,"282":1,"293":4,"295":2,"296":2,"301":2,"303":2,"304":2,"307":5,"327":2}}],["plugininstance",{"2":{"67":1,"78":2,"79":2,"81":2,"92":1,"93":4,"95":2,"97":2,"292":1,"293":2,"294":1,"295":2,"303":3,"305":1,"327":3}}],["playwright",{"0":{"88":1},"2":{"27":1,"88":8,"89":1,"181":1,"182":2,"183":1,"388":4}}],["prefix=",{"2":{"234":1,"360":1}}],["prefix=false",{"2":{"231":1,"233":2,"280":1}}],["prefix",{"2":{"230":1,"231":1,"234":1,"247":1,"261":1,"262":1}}],["preserve",{"2":{"38":1}}],["private=true",{"2":{"246":3,"250":1,"251":1}}],["private",{"2":{"109":2,"149":1,"363":2}}],["print",{"2":{"85":1,"222":2,"260":1}}],["properties",{"2":{"315":2,"316":2,"317":1,"318":1,"319":1,"320":1,"321":1,"323":1,"324":3,"325":3,"326":3}}],["prompt",{"2":{"163":1,"169":1}}],["project",{"2":{"81":2,"85":1}}],["progress",{"2":{"58":1}}],["pull",{"2":{"378":1}}],["put",{"2":{"56":1}}],["publish",{"2":{"44":2}}],["password",{"2":{"333":1}}],["password=",{"2":{"34":1}}],["para2",{"2":{"193":1}}],["para1",{"2":{"193":1}}],["params",{"2":{"101":1,"193":2,"195":1}}],["parent",{"2":{"81":1,"109":1,"149":1}}],["package",{"0":{"80":1},"2":{"80":1,"81":4,"302":1,"310":1,"348":1,"387":2}}],["pattern",{"2":{"281":1}}],["patch",{"2":{"56":1}}],["path=",{"2":{"62":1,"205":1}}],["path",{"2":{"21":1,"62":1,"86":1,"110":1,"184":1,"205":1,"293":1,"296":1,"304":1,"360":9}}],["payload",{"2":{"53":1,"54":1,"55":1,"102":1,"103":1}}],["paginate",{"0":{"42":1},"2":{"42":1,"360":1}}],["pager",{"2":{"360":1}}],["page",{"0":{"31":1},"2":{"27":4,"31":7,"42":2,"89":1,"90":1}}],["poke",{"2":{"224":3}}],["pos=",{"2":{"205":1}}],["pos",{"2":{"205":1}}],["position",{"2":{"109":1,"149":1}}],["post",{"0":{"53":1,"102":1,"158":1},"2":{"2":2,"47":3,"49":1,"50":1,"51":1,"53":2,"54":3,"55":2,"56":1,"61":1,"102":1,"103":2,"224":4,"339":1,"399":2}}],["pool",{"0":{"25":1},"2":{"25":2}}],["port=8088",{"2":{"61":1}}],["port=3306",{"2":{"34":1}}],["port",{"2":{"1":2,"3":2,"8":2,"10":2,"12":2,"21":1,"61":1,"280":1,"333":1,"340":2,"343":1}}],["pc",{"2":{"0":1}}],["working",{"2":{"360":3}}],["work",{"2":{"360":2}}],["words",{"2":{"262":1}}],["world",{"2":{"165":1,"200":1,"201":1,"203":1,"205":3,"238":1,"273":1}}],["what",{"2":{"258":1}}],["while",{"2":{"216":1}}],["when",{"2":{"94":1}}],["win32",{"2":{"386":1}}],["win10",{"2":{"362":1}}],["win7",{"2":{"362":2}}],["win+r",{"2":{"360":1}}],["window",{"2":{"185":1}}],["windows的cmd存在",{"2":{"380":1}}],["windowsserver",{"2":{"362":2}}],["windows",{"0":{"386":1},"2":{"181":3,"182":1,"331":3,"382":3,"384":1,"385":3,"388":4}}],["width",{"2":{"89":1,"184":1,"203":1}}],["with",{"2":{"81":1,"85":2,"182":1,"353":1,"374":1,"388":2}}],["waiteventcancel",{"2":{"215":1}}],["waiter",{"0":{"69":1},"2":{"69":4}}],["wait",{"0":{"212":1,"215":1,"216":1},"1":{"213":1,"214":1,"215":1,"217":1,"218":1},"2":{"212":2,"214":2,"215":1,"216":4,"217":4,"218":2,"250":1,"255":1,"257":6,"258":5,"263":2}}],["wav",{"2":{"209":1,"210":2}}],["warning",{"2":{"84":1,"87":1}}],["www",{"2":{"31":1,"61":1,"172":1,"186":2,"400":1}}],["weight",{"2":{"239":1}}],["webkit",{"2":{"88":1}}],["websocket",{"0":{"367":1},"2":{"0":1,"1":1,"3":1,"6":2,"7":1,"8":1,"10":1,"12":1,"222":2}}],["wechat",{"2":{"1":2}}],["ws端口",{"2":{"364":1}}],["wsl",{"2":{"181":1,"382":1}}],["ws",{"2":{"1":1,"3":1,"6":1,"8":1,"10":1,"12":1,"340":2}}],["地址栏中协议",{"2":{"363":1}}],["地址",{"2":{"1":1,"3":1,"8":1,"10":1,"12":1}}],["释义",{"2":{"1":1,"3":1,"8":1,"10":1,"12":1,"14":1,"19":1,"21":1,"25":1,"37":1,"38":1,"40":1,"41":1,"42":1,"44":1,"45":1,"46":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"61":1,"81":1,"82":1,"85":1,"86":1,"89":1,"91":1,"94":1,"97":1,"101":1,"102":1,"103":1,"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1,"115":1,"116":1,"117":1,"118":1,"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1,"130":1,"131":1,"132":1,"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"157":1,"158":1,"159":1,"160":1,"161":1,"163":1,"165":1,"169":1,"171":1,"175":1,"177":1,"178":1,"184":1,"188":1,"190":1,"193":1,"198":1,"200":1,"203":1,"205":1,"208":1,"210":1,"212":1,"216":3,"221":1,"230":1,"231":1,"239":1,"253":1,"256":1,"262":1,"263":1,"265":1,"273":1,"296":1,"298":1,"299":1,"301":1}}],["连接控制台",{"0":{"343":1},"1":{"344":1,"345":1}}],["连接测试服务",{"2":{"280":1}}],["连接",{"0":{"1":1,"3":1,"8":1,"10":1,"12":1,"344":1}}],["微信的协议端",{"2":{"0":1}}],["是大家共同塑造了",{"2":{"407":1}}],["是异步",{"2":{"403":1}}],["是提供给",{"2":{"389":1}}],["是提供的异步下载文件的方法",{"2":{"57":1}}],["是围绕着主体项目进行开发的",{"2":{"389":1}}],["是使用",{"2":{"316":1}}],["是业务层的主要调度模块",{"2":{"287":1}}],["是发送主动消息的方法",{"2":{"265":1}}],["是无法撤回的",{"2":{"257":1}}],["是在完成检查之后",{"2":{"238":1}}],["是实现适配器部分基础逻辑的基础",{"2":{"98":1}}],["是否未正确连接到mirai",{"2":{"380":1}}],["是否有消息推送",{"2":{"380":1}}],["是否将一些运行信息发送至特定群组",{"2":{"364":1}}],["是否启用限速",{"2":{"339":1}}],["是否官方插件",{"2":{"301":1}}],["是否回复用户",{"2":{"273":1}}],["是否是私信消息",{"2":{"262":1}}],["是否为子频道管理员",{"2":{"262":1}}],["是否为模板文件",{"2":{"184":1}}],["是否可撤回",{"2":{"257":1}}],["是否仅支持私信",{"2":{"230":1,"231":1}}],["是否支持通过私信使用该功能",{"2":{"230":1,"231":1}}],["是否校验前缀或指定需要校验的前缀",{"2":{"230":1,"231":1}}],["是否清空消息列表",{"2":{"216":1}}],["是否超出字数后转换为图片",{"2":{"200":1}}],["是否",{"2":{"165":1,"262":1,"273":1}}],["是否使用暗黑样式",{"2":{"190":1}}],["是否使用",{"2":{"102":1}}],["是否需要值",{"2":{"89":1}}],["是否删除插件的原文件",{"2":{"82":1}}],["是否解压插件",{"2":{"81":1}}],["是否显示进度条",{"2":{"58":1}}],["是否返回字符串结果",{"2":{"57":1,"58":1}}],["是著名的",{"2":{"47":1}}],["是一款",{"2":{"281":1}}],["是一款针对",{"2":{"243":1}}],["是一款免费无广告的语音沟通工具",{"2":{"6":1}}],["是一个",{"2":{"404":1}}],["是一个聊天机器人应用接口标准",{"2":{"11":1}}],["是一个在全平台下运行",{"2":{"7":1}}],["是",{"2":{"0":1,"89":4,"263":4,"295":1,"389":1}}],["cd",{"2":{"388":1}}],["centos",{"2":{"387":1}}],["centerprocessor",{"2":{"282":1}}],["current",{"2":{"360":1}}],["custom",{"2":{"62":1,"91":3}}],["c",{"2":{"360":2}}],["cmd",{"2":{"360":1}}],["cn",{"2":{"163":1}}],["creator",{"2":{"112":1,"151":1}}],["create以及direct",{"2":{"219":1}}],["created",{"0":{"68":1},"2":{"68":1,"74":1}}],["create",{"0":{"108":1,"109":1,"110":1,"111":1,"112":1,"113":1},"2":{"14":2,"20":2,"219":2,"220":2,"222":3,"303":1,"360":1}}],["crontrigger",{"2":{"95":1}}],["cron",{"2":{"95":2}}],["critical",{"2":{"84":1,"87":1}}],["cannot",{"0":{"367":1}}],["cachesize",{"2":{"340":1}}],["calc",{"2":{"85":3}}],["callback",{"2":{"180":2,"257":7,"258":3}}],["call",{"2":{"81":1,"85":1,"388":1}}],["callable",{"2":{"25":1,"45":1,"46":1,"85":1,"91":1,"212":1,"216":1,"230":1}}],["catch",{"2":{"81":1,"85":2}}],["chmod",{"2":{"387":1}}],["chrome",{"2":{"363":1}}],["chromium",{"0":{"182":1,"183":1},"2":{"88":1,"182":3,"185":1,"189":1,"253":2,"353":2,"388":4}}],["chino酱",{"2":{"357":1}}],["check",{"2":{"230":1,"231":2,"233":2,"234":2,"280":1}}],["chunk",{"2":{"37":1}}],["change",{"2":{"360":1}}],["channelwaitevent",{"2":{"216":1}}],["channelmessagesitem",{"2":{"216":2}}],["channels",{"0":{"128":1},"2":{"108":1}}],["channel",{"0":{"109":1,"115":1,"126":1,"127":1,"149":1,"216":1},"1":{"217":1,"218":1},"2":{"106":1,"107":1,"108":1,"109":3,"110":1,"112":2,"113":1,"115":1,"119":1,"120":1,"121":1,"122":1,"126":1,"127":1,"138":1,"139":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"148":1,"149":2,"151":2,"158":1,"159":1,"160":1,"161":1,"173":1,"196":2,"216":3,"217":2,"218":2,"220":2,"257":2,"262":1,"263":1,"265":1,"266":1,"295":2,"296":4,"298":3,"299":3,"300":1}}],["charfield",{"2":{"33":1,"35":1}}],["chainconfig",{"2":{"191":3}}],["chainbuilder",{"0":{"23":1},"2":{"22":1,"23":2,"27":3,"31":1,"273":2}}],["chain",{"0":{"26":1,"163":1,"165":1,"167":1,"169":1,"171":1,"175":1,"184":1,"188":1,"190":1,"193":1,"198":1,"200":1,"203":1,"208":1,"210":1,"273":1,"277":1},"1":{"27":1,"28":1,"29":1,"30":1,"31":1,"172":1,"204":1,"205":1},"2":{"19":2,"21":1,"23":1,"26":1,"27":7,"28":2,"29":2,"30":2,"31":5,"71":5,"72":2,"73":2,"78":1,"79":1,"89":1,"163":1,"165":1,"170":1,"173":1,"176":4,"177":8,"179":1,"185":2,"186":1,"193":1,"195":1,"196":3,"204":2,"205":1,"208":1,"210":1,"212":4,"214":2,"216":4,"228":3,"229":1,"233":1,"234":1,"235":1,"236":1,"237":1,"238":2,"239":1,"242":2,"245":2,"250":3,"251":3,"255":1,"257":8,"258":1,"265":7,"266":1,"267":1,"272":3,"273":5,"275":2,"277":3,"278":1,"280":2,"303":1}}],["clone",{"2":{"313":2,"360":2,"388":1}}],["close",{"0":{"217":1},"2":{"89":1,"90":1,"216":2,"217":1}}],["clean=false",{"2":{"218":2}}],["clean",{"2":{"216":1,"263":1}}],["cle",{"2":{"204":2}}],["cl",{"2":{"204":2}}],["click",{"2":{"31":1}}],["clientresponse",{"2":{"50":1}}],["client",{"0":{"0":1},"1":{"1":1},"2":{"0":1,"17":2,"19":3,"20":2,"21":1,"338":1}}],["cls",{"2":{"23":3,"27":4,"31":1}}],["classmethod",{"2":{"23":3,"27":4,"31":1}}],["class",{"2":{"23":1,"27":1,"33":3,"35":1,"61":1,"87":1,"88":1,"327":1,"388":1}}],["ckyu",{"2":{"9":1}}],["coroutine",{"2":{"388":1}}],["cors",{"2":{"340":1}}],["core",{"2":{"81":2,"85":1,"295":1,"301":1,"389":1}}],["count",{"2":{"222":1}}],["code",{"0":{"368":1},"2":{"173":1}}],["cookie",{"2":{"139":1}}],["color",{"2":{"111":1,"150":1}}],["console2",{"2":{"389":1}}],["console",{"2":{"280":1,"340":1,"344":1,"372":1}}],["const",{"2":{"191":1}}],["control",{"2":{"91":3}}],["controller",{"2":{"61":1}}],["contents",{"2":{"360":1}}],["content",{"2":{"53":1,"113":1,"185":2,"190":1,"191":1,"196":1}}],["convert=true",{"2":{"200":1}}],["convert",{"0":{"40":1},"2":{"40":1,"200":1}}],["conflict",{"2":{"38":1}}],["config=mysqlconfig",{"2":{"34":1}}],["config",{"0":{"298":1,"299":1},"2":{"2":1,"34":1,"61":1,"81":1,"231":1,"295":5,"296":8,"298":2,"299":3,"300":2,"316":7,"317":1,"318":2,"319":1,"320":1,"321":1,"323":2,"324":2,"325":1,"326":1,"333":2,"339":2,"340":1,"360":1,"363":1,"364":3,"399":1}}],["connect",{"0":{"367":1},"2":{"33":2,"34":2}}],["common",{"2":{"360":1}}],["commands",{"2":{"360":1}}],["command",{"2":{"360":1}}],["commit",{"2":{"261":1}}],["compile",{"2":{"235":2,"237":1}}],["completed",{"2":{"84":2}}],["com",{"2":{"1":2,"31":1,"61":1,"163":1,"172":1,"186":2,"280":1,"313":2,"339":1,"344":1,"388":1}}],["comwechat",{"2":{"1":1}}],["comwechatbot",{"0":{"0":1,"1":1},"1":{"1":1},"2":{"0":1}}],["cqcode",{"2":{"173":2}}],["cq",{"0":{"173":1,"339":1},"2":{"2":1,"3":2,"170":2,"173":5,"176":1,"209":1,"339":1}}],["cqhttpforwardmessage",{"2":{"176":2}}],["cqhttpbotinstance",{"2":{"173":2}}],["cqhttpapi",{"2":{"99":1}}],["cqhttp",{"0":{"2":1,"224":1,"399":1},"1":{"3":1},"2":{"2":1,"3":1,"9":1,"99":1,"170":1,"172":1,"176":1,"224":3,"243":1,"339":6,"398":1,"399":1}}]],"serializationVersion":2}';export{e as default}; diff --git a/assets/chunks/VPLocalSearchBox.61311459.js b/assets/chunks/VPLocalSearchBox.61311459.js new file mode 100644 index 00000000..5ae58e57 --- /dev/null +++ b/assets/chunks/VPLocalSearchBox.61311459.js @@ -0,0 +1,7 @@ +import{M as vt,j as ie,w as ze,d as kt,v as de,p as Te,q as Nt,k as Ie,l as he,aj as Tt,ak as It,o as Z,D as Dt,C as F,a3 as _t,b as W,al as Ot,am as Rt,s as Mt,c as ee,n as Xe,G as we,R as et,F as tt,a as ve,t as pe,an as Lt,S as Pt,U as zt,ao as rt,ap as Bt,a8 as Vt,ae as $t,_ as Wt}from"./framework.63f12d77.js";import{u as jt,a as Kt,b as Jt,c as nt,d as Ut,e as Gt,w as Ht,o as xe,f as qt,g as Qt,h as Yt}from"./theme.e23c65ce.js";const Zt={root:()=>vt(()=>import("./@localSearchIndexroot.13a295e8.js"),[])};/*! +* tabbable 6.2.0 +* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE +*/var pt=["input:not([inert])","select:not([inert])","textarea:not([inert])","a[href]:not([inert])","button:not([inert])","[tabindex]:not(slot):not([inert])","audio[controls]:not([inert])","video[controls]:not([inert])",'[contenteditable]:not([contenteditable="false"]):not([inert])',"details>summary:first-of-type:not([inert])","details:not([inert])"],Se=pt.join(","),yt=typeof Element>"u",se=yt?function(){}:Element.prototype.matches||Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector,Ae=!yt&&Element.prototype.getRootNode?function(o){var e;return o==null||(e=o.getRootNode)===null||e===void 0?void 0:e.call(o)}:function(o){return o==null?void 0:o.ownerDocument},Ce=function o(e,t){var r;t===void 0&&(t=!0);var a=e==null||(r=e.getAttribute)===null||r===void 0?void 0:r.call(e,"inert"),n=a===""||a==="true",i=n||t&&e&&o(e.parentNode);return i},Xt=function(e){var t,r=e==null||(t=e.getAttribute)===null||t===void 0?void 0:t.call(e,"contenteditable");return r===""||r==="true"},mt=function(e,t,r){if(Ce(e))return[];var a=Array.prototype.slice.apply(e.querySelectorAll(Se));return t&&se.call(e,Se)&&a.unshift(e),a=a.filter(r),a},gt=function o(e,t,r){for(var a=[],n=Array.from(e);n.length;){var i=n.shift();if(!Ce(i,!1))if(i.tagName==="SLOT"){var s=i.assignedElements(),u=s.length?s:i.children,l=o(u,!0,r);r.flatten?a.push.apply(a,l):a.push({scopeParent:i,candidates:l})}else{var d=se.call(i,Se);d&&r.filter(i)&&(t||!e.includes(i))&&a.push(i);var h=i.shadowRoot||typeof r.getShadowRoot=="function"&&r.getShadowRoot(i),v=!Ce(h,!1)&&(!r.shadowRootFilter||r.shadowRootFilter(i));if(h&&v){var y=o(h===!0?i.children:h.children,!0,r);r.flatten?a.push.apply(a,y):a.push({scopeParent:i,candidates:y})}else n.unshift.apply(n,i.children)}}return a},bt=function(e){return!isNaN(parseInt(e.getAttribute("tabindex"),10))},oe=function(e){if(!e)throw new Error("No node provided");return e.tabIndex<0&&(/^(AUDIO|VIDEO|DETAILS)$/.test(e.tagName)||Xt(e))&&!bt(e)?0:e.tabIndex},er=function(e,t){var r=oe(e);return r<0&&t&&!bt(e)?0:r},tr=function(e,t){return e.tabIndex===t.tabIndex?e.documentOrder-t.documentOrder:e.tabIndex-t.tabIndex},wt=function(e){return e.tagName==="INPUT"},rr=function(e){return wt(e)&&e.type==="hidden"},nr=function(e){var t=e.tagName==="DETAILS"&&Array.prototype.slice.apply(e.children).some(function(r){return r.tagName==="SUMMARY"});return t},ar=function(e,t){for(var r=0;rsummary:first-of-type"),i=n?e.parentElement:e;if(se.call(i,"details:not([open]) *"))return!0;if(!r||r==="full"||r==="legacy-full"){if(typeof a=="function"){for(var s=e;e;){var u=e.parentElement,l=Ae(e);if(u&&!u.shadowRoot&&a(u)===!0)return at(e);e.assignedSlot?e=e.assignedSlot:!u&&l!==e.ownerDocument?e=l.host:e=u}e=s}if(ur(e))return!e.getClientRects().length;if(r!=="legacy-full")return!0}else if(r==="non-zero-area")return at(e);return!1},cr=function(e){if(/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(e.tagName))for(var t=e.parentElement;t;){if(t.tagName==="FIELDSET"&&t.disabled){for(var r=0;r=0)},dr=function o(e){var t=[],r=[];return e.forEach(function(a,n){var i=!!a.scopeParent,s=i?a.scopeParent:a,u=er(s,i),l=i?o(a.candidates):s;u===0?i?t.push.apply(t,l):t.push(s):r.push({documentOrder:n,tabIndex:u,item:a,isScope:i,content:l})}),r.sort(tr).reduce(function(a,n){return n.isScope?a.push.apply(a,n.content):a.push(n.content),a},[]).concat(t)},hr=function(e,t){t=t||{};var r;return t.getShadowRoot?r=gt([e],t.includeContainer,{filter:Be.bind(null,t),flatten:!1,getShadowRoot:t.getShadowRoot,shadowRootFilter:fr}):r=mt(e,t.includeContainer,Be.bind(null,t)),dr(r)},vr=function(e,t){t=t||{};var r;return t.getShadowRoot?r=gt([e],t.includeContainer,{filter:ke.bind(null,t),flatten:!0,getShadowRoot:t.getShadowRoot}):r=mt(e,t.includeContainer,ke.bind(null,t)),r},ue=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return se.call(e,Se)===!1?!1:Be(t,e)},pr=pt.concat("iframe").join(","),De=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return se.call(e,pr)===!1?!1:ke(t,e)};/*! +* focus-trap 7.5.4 +* @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE +*/function it(o,e){var t=Object.keys(o);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(o);e&&(r=r.filter(function(a){return Object.getOwnPropertyDescriptor(o,a).enumerable})),t.push.apply(t,r)}return t}function ot(o){for(var e=1;e0){var r=e[e.length-1];r!==t&&r.pause()}var a=e.indexOf(t);a===-1||e.splice(a,1),e.push(t)},deactivateTrap:function(e,t){var r=e.indexOf(t);r!==-1&&e.splice(r,1),e.length>0&&e[e.length-1].unpause()}},br=function(e){return e.tagName&&e.tagName.toLowerCase()==="input"&&typeof e.select=="function"},wr=function(e){return(e==null?void 0:e.key)==="Escape"||(e==null?void 0:e.key)==="Esc"||(e==null?void 0:e.keyCode)===27},ge=function(e){return(e==null?void 0:e.key)==="Tab"||(e==null?void 0:e.keyCode)===9},xr=function(e){return ge(e)&&!e.shiftKey},Fr=function(e){return ge(e)&&e.shiftKey},ut=function(e){return setTimeout(e,0)},lt=function(e,t){var r=-1;return e.every(function(a,n){return t(a)?(r=n,!1):!0}),r},ye=function(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),a=1;a1?p-1:0),N=1;N=0)c=r.activeElement;else{var f=i.tabbableGroups[0],p=f&&f.firstTabbableNode;c=p||d("fallbackFocus")}if(!c)throw new Error("Your focus-trap needs to have at least one focusable element");return c},v=function(){if(i.containerGroups=i.containers.map(function(c){var f=hr(c,n.tabbableOptions),p=vr(c,n.tabbableOptions),T=f.length>0?f[0]:void 0,N=f.length>0?f[f.length-1]:void 0,M=p.find(function(P){return ue(P)}),m=p.slice().reverse().find(function(P){return ue(P)}),w=!!f.find(function(P){return oe(P)>0});return{container:c,tabbableNodes:f,focusableNodes:p,posTabIndexesFound:w,firstTabbableNode:T,lastTabbableNode:N,firstDomTabbableNode:M,lastDomTabbableNode:m,nextTabbableNode:function(U){var Q=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,K=f.indexOf(U);return K<0?Q?p.slice(p.indexOf(U)+1).find(function(V){return ue(V)}):p.slice(0,p.indexOf(U)).reverse().find(function(V){return ue(V)}):f[K+(Q?1:-1)]}}}),i.tabbableGroups=i.containerGroups.filter(function(c){return c.tabbableNodes.length>0}),i.tabbableGroups.length<=0&&!d("fallbackFocus"))throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times");if(i.containerGroups.find(function(c){return c.posTabIndexesFound})&&i.containerGroups.length>1)throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.")},y=function x(c){var f=c.activeElement;if(f)return f.shadowRoot&&f.shadowRoot.activeElement!==null?x(f.shadowRoot):f},g=function x(c){if(c!==!1&&c!==y(document)){if(!c||!c.focus){x(h());return}c.focus({preventScroll:!!n.preventScroll}),i.mostRecentlyFocusedNode=c,br(c)&&c.select()}},E=function(c){var f=d("setReturnFocus",c);return f||(f===!1?!1:c)},b=function(c){var f=c.target,p=c.event,T=c.isBackward,N=T===void 0?!1:T;f=f||Fe(p),v();var M=null;if(i.tabbableGroups.length>0){var m=l(f,p),w=m>=0?i.containerGroups[m]:void 0;if(m<0)N?M=i.tabbableGroups[i.tabbableGroups.length-1].lastTabbableNode:M=i.tabbableGroups[0].firstTabbableNode;else if(N){var P=lt(i.tabbableGroups,function(H){var te=H.firstTabbableNode;return f===te});if(P<0&&(w.container===f||De(f,n.tabbableOptions)&&!ue(f,n.tabbableOptions)&&!w.nextTabbableNode(f,!1))&&(P=m),P>=0){var U=P===0?i.tabbableGroups.length-1:P-1,Q=i.tabbableGroups[U];M=oe(f)>=0?Q.lastTabbableNode:Q.lastDomTabbableNode}else ge(p)||(M=w.nextTabbableNode(f,!1))}else{var K=lt(i.tabbableGroups,function(H){var te=H.lastTabbableNode;return f===te});if(K<0&&(w.container===f||De(f,n.tabbableOptions)&&!ue(f,n.tabbableOptions)&&!w.nextTabbableNode(f))&&(K=m),K>=0){var V=K===i.tabbableGroups.length-1?0:K+1,G=i.tabbableGroups[V];M=oe(f)>=0?G.firstTabbableNode:G.firstDomTabbableNode}else ge(p)||(M=w.nextTabbableNode(f))}}else M=d("fallbackFocus");return M},A=function(c){var f=Fe(c);if(!(l(f,c)>=0)){if(ye(n.clickOutsideDeactivates,c)){s.deactivate({returnFocus:n.returnFocusOnDeactivate});return}ye(n.allowOutsideClick,c)||c.preventDefault()}},k=function(c){var f=Fe(c),p=l(f,c)>=0;if(p||f instanceof Document)p&&(i.mostRecentlyFocusedNode=f);else{c.stopImmediatePropagation();var T,N=!0;if(i.mostRecentlyFocusedNode)if(oe(i.mostRecentlyFocusedNode)>0){var M=l(i.mostRecentlyFocusedNode),m=i.containerGroups[M].tabbableNodes;if(m.length>0){var w=m.findIndex(function(P){return P===i.mostRecentlyFocusedNode});w>=0&&(n.isKeyForward(i.recentNavEvent)?w+1=0&&(T=m[w-1],N=!1))}}else i.containerGroups.some(function(P){return P.tabbableNodes.some(function(U){return oe(U)>0})})||(N=!1);else N=!1;N&&(T=b({target:i.mostRecentlyFocusedNode,isBackward:n.isKeyBackward(i.recentNavEvent)})),g(T||i.mostRecentlyFocusedNode||h())}i.recentNavEvent=void 0},C=function(c){var f=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;i.recentNavEvent=c;var p=b({event:c,isBackward:f});p&&(ge(c)&&c.preventDefault(),g(p))},R=function(c){if(wr(c)&&ye(n.escapeDeactivates,c)!==!1){c.preventDefault(),s.deactivate();return}(n.isKeyForward(c)||n.isKeyBackward(c))&&C(c,n.isKeyBackward(c))},L=function(c){var f=Fe(c);l(f,c)>=0||ye(n.clickOutsideDeactivates,c)||ye(n.allowOutsideClick,c)||(c.preventDefault(),c.stopImmediatePropagation())},z=function(){if(i.active)return st.activateTrap(a,s),i.delayInitialFocusTimer=n.delayInitialFocus?ut(function(){g(h())}):g(h()),r.addEventListener("focusin",k,!0),r.addEventListener("mousedown",A,{capture:!0,passive:!1}),r.addEventListener("touchstart",A,{capture:!0,passive:!1}),r.addEventListener("click",L,{capture:!0,passive:!1}),r.addEventListener("keydown",R,{capture:!0,passive:!1}),s},I=function(){if(i.active)return r.removeEventListener("focusin",k,!0),r.removeEventListener("mousedown",A,!0),r.removeEventListener("touchstart",A,!0),r.removeEventListener("click",L,!0),r.removeEventListener("keydown",R,!0),s},S=function(c){var f=c.some(function(p){var T=Array.from(p.removedNodes);return T.some(function(N){return N===i.mostRecentlyFocusedNode})});f&&g(h())},_=typeof window<"u"&&"MutationObserver"in window?new MutationObserver(S):void 0,O=function(){_&&(_.disconnect(),i.active&&!i.paused&&i.containers.map(function(c){_.observe(c,{subtree:!0,childList:!0})}))};return s={get active(){return i.active},get paused(){return i.paused},activate:function(c){if(i.active)return this;var f=u(c,"onActivate"),p=u(c,"onPostActivate"),T=u(c,"checkCanFocusTrap");T||v(),i.active=!0,i.paused=!1,i.nodeFocusedBeforeActivation=r.activeElement,f==null||f();var N=function(){T&&v(),z(),O(),p==null||p()};return T?(T(i.containers.concat()).then(N,N),this):(N(),this)},deactivate:function(c){if(!i.active)return this;var f=ot({onDeactivate:n.onDeactivate,onPostDeactivate:n.onPostDeactivate,checkCanReturnFocus:n.checkCanReturnFocus},c);clearTimeout(i.delayInitialFocusTimer),i.delayInitialFocusTimer=void 0,I(),i.active=!1,i.paused=!1,O(),st.deactivateTrap(a,s);var p=u(f,"onDeactivate"),T=u(f,"onPostDeactivate"),N=u(f,"checkCanReturnFocus"),M=u(f,"returnFocus","returnFocusOnDeactivate");p==null||p();var m=function(){ut(function(){M&&g(E(i.nodeFocusedBeforeActivation)),T==null||T()})};return M&&N?(N(E(i.nodeFocusedBeforeActivation)).then(m,m),this):(m(),this)},pause:function(c){if(i.paused||!i.active)return this;var f=u(c,"onPause"),p=u(c,"onPostPause");return i.paused=!0,f==null||f(),I(),O(),p==null||p(),this},unpause:function(c){if(!i.paused||!i.active)return this;var f=u(c,"onUnpause"),p=u(c,"onPostUnpause");return i.paused=!1,f==null||f(),v(),z(),O(),p==null||p(),this},updateContainerElements:function(c){var f=[].concat(c).filter(Boolean);return i.containers=f.map(function(p){return typeof p=="string"?r.querySelector(p):p}),i.active&&v(),O(),this}},s.updateContainerElements(e),s};function Ar(o,e={}){let t;const{immediate:r,...a}=e,n=ie(!1),i=ie(!1),s=h=>t&&t.activate(h),u=h=>t&&t.deactivate(h),l=()=>{t&&(t.pause(),i.value=!0)},d=()=>{t&&(t.unpause(),i.value=!1)};return ze(()=>jt(o),h=>{h&&(t=Sr(h,{...a,onActivate(){n.value=!0,e.onActivate&&e.onActivate()},onDeactivate(){n.value=!1,e.onDeactivate&&e.onDeactivate()}}),r&&s())},{flush:"post"}),Kt(()=>u()),{hasFocus:n,isPaused:i,activate:s,deactivate:u,pause:l,unpause:d}}class ce{constructor(e,t=!0,r=[],a=5e3){this.ctx=e,this.iframes=t,this.exclude=r,this.iframesTimeout=a}static matches(e,t){const r=typeof t=="string"?[t]:t,a=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(a){let n=!1;return r.every(i=>a.call(e,i)?(n=!0,!1):!0),n}else return!1}getContexts(){let e,t=[];return typeof this.ctx>"u"||!this.ctx?e=[]:NodeList.prototype.isPrototypeOf(this.ctx)?e=Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?e=this.ctx:typeof this.ctx=="string"?e=Array.prototype.slice.call(document.querySelectorAll(this.ctx)):e=[this.ctx],e.forEach(r=>{const a=t.filter(n=>n.contains(r)).length>0;t.indexOf(r)===-1&&!a&&t.push(r)}),t}getIframeContents(e,t,r=()=>{}){let a;try{const n=e.contentWindow;if(a=n.document,!n||!a)throw new Error("iframe inaccessible")}catch{r()}a&&t(a)}isIframeBlank(e){const t="about:blank",r=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&r!==t&&r}observeIframeLoad(e,t,r){let a=!1,n=null;const i=()=>{if(!a){a=!0,clearTimeout(n);try{this.isIframeBlank(e)||(e.removeEventListener("load",i),this.getIframeContents(e,t,r))}catch{r()}}};e.addEventListener("load",i),n=setTimeout(i,this.iframesTimeout)}onIframeReady(e,t,r){try{e.contentWindow.document.readyState==="complete"?this.isIframeBlank(e)?this.observeIframeLoad(e,t,r):this.getIframeContents(e,t,r):this.observeIframeLoad(e,t,r)}catch{r()}}waitForIframes(e,t){let r=0;this.forEachIframe(e,()=>!0,a=>{r++,this.waitForIframes(a.querySelector("html"),()=>{--r||t()})},a=>{a||t()})}forEachIframe(e,t,r,a=()=>{}){let n=e.querySelectorAll("iframe"),i=n.length,s=0;n=Array.prototype.slice.call(n);const u=()=>{--i<=0&&a(s)};i||u(),n.forEach(l=>{ce.matches(l,this.exclude)?u():this.onIframeReady(l,d=>{t(l)&&(s++,r(d)),u()},u)})}createIterator(e,t,r){return document.createNodeIterator(e,t,r,!1)}createInstanceOnIframe(e){return new ce(e.querySelector("html"),this.iframes)}compareNodeIframe(e,t,r){const a=e.compareDocumentPosition(r),n=Node.DOCUMENT_POSITION_PRECEDING;if(a&n)if(t!==null){const i=t.compareDocumentPosition(r),s=Node.DOCUMENT_POSITION_FOLLOWING;if(i&s)return!0}else return!0;return!1}getIteratorNode(e){const t=e.previousNode();let r;return t===null?r=e.nextNode():r=e.nextNode()&&e.nextNode(),{prevNode:t,node:r}}checkIframeFilter(e,t,r,a){let n=!1,i=!1;return a.forEach((s,u)=>{s.val===r&&(n=u,i=s.handled)}),this.compareNodeIframe(e,t,r)?(n===!1&&!i?a.push({val:r,handled:!0}):n!==!1&&!i&&(a[n].handled=!0),!0):(n===!1&&a.push({val:r,handled:!1}),!1)}handleOpenIframes(e,t,r,a){e.forEach(n=>{n.handled||this.getIframeContents(n.val,i=>{this.createInstanceOnIframe(i).forEachNode(t,r,a)})})}iterateThroughNodes(e,t,r,a,n){const i=this.createIterator(t,e,a);let s=[],u=[],l,d,h=()=>({prevNode:d,node:l}=this.getIteratorNode(i),l);for(;h();)this.iframes&&this.forEachIframe(t,v=>this.checkIframeFilter(l,d,v,s),v=>{this.createInstanceOnIframe(v).forEachNode(e,y=>u.push(y),a)}),u.push(l);u.forEach(v=>{r(v)}),this.iframes&&this.handleOpenIframes(s,e,r,a),n()}forEachNode(e,t,r,a=()=>{}){const n=this.getContexts();let i=n.length;i||a(),n.forEach(s=>{const u=()=>{this.iterateThroughNodes(e,s,t,r,()=>{--i<=0&&a()})};this.iframes?this.waitForIframes(s,u):u()})}}let Cr=class{constructor(e){this.ctx=e,this.ie=!1;const t=window.navigator.userAgent;(t.indexOf("MSIE")>-1||t.indexOf("Trident")>-1)&&(this.ie=!0)}set opt(e){this._opt=Object.assign({},{element:"",className:"",exclude:[],iframes:!1,iframesTimeout:5e3,separateWordSearch:!0,diacritics:!0,synonyms:{},accuracy:"partially",acrossElements:!1,caseSensitive:!1,ignoreJoiners:!1,ignoreGroups:0,ignorePunctuation:[],wildcards:"disabled",each:()=>{},noMatch:()=>{},filter:()=>!0,done:()=>{},debug:!1,log:window.console},e)}get opt(){return this._opt}get iterator(){return new ce(this.ctx,this.opt.iframes,this.opt.exclude,this.opt.iframesTimeout)}log(e,t="debug"){const r=this.opt.log;this.opt.debug&&typeof r=="object"&&typeof r[t]=="function"&&r[t](`mark.js: ${e}`)}escapeStr(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}createRegExp(e){return this.opt.wildcards!=="disabled"&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),this.opt.wildcards!=="disabled"&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e),e}createSynonymsRegExp(e){const t=this.opt.synonyms,r=this.opt.caseSensitive?"":"i",a=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(let n in t)if(t.hasOwnProperty(n)){const i=t[n],s=this.opt.wildcards!=="disabled"?this.setupWildcardsRegExp(n):this.escapeStr(n),u=this.opt.wildcards!=="disabled"?this.setupWildcardsRegExp(i):this.escapeStr(i);s!==""&&u!==""&&(e=e.replace(new RegExp(`(${this.escapeStr(s)}|${this.escapeStr(u)})`,`gm${r}`),a+`(${this.processSynomyms(s)}|${this.processSynomyms(u)})`+a))}return e}processSynomyms(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}setupWildcardsRegExp(e){return e=e.replace(/(?:\\)*\?/g,t=>t.charAt(0)==="\\"?"?":""),e.replace(/(?:\\)*\*/g,t=>t.charAt(0)==="\\"?"*":"")}createWildcardsRegExp(e){let t=this.opt.wildcards==="withSpaces";return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}setupIgnoreJoinersRegExp(e){return e.replace(/[^(|)\\]/g,(t,r,a)=>{let n=a.charAt(r+1);return/[(|)\\]/.test(n)||n===""?t:t+"\0"})}createJoinersRegExp(e){let t=[];const r=this.opt.ignorePunctuation;return Array.isArray(r)&&r.length&&t.push(this.escapeStr(r.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join(`[${t.join("")}]*`):e}createDiacriticsRegExp(e){const t=this.opt.caseSensitive?"":"i",r=this.opt.caseSensitive?["aàáảãạăằắẳẵặâầấẩẫậäåāą","AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćč","CÇĆČ","dđď","DĐĎ","eèéẻẽẹêềếểễệëěēę","EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïī","IÌÍỈĨỊÎÏĪ","lł","LŁ","nñňń","NÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøō","OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rř","RŘ","sšśșş","SŠŚȘŞ","tťțţ","TŤȚŢ","uùúủũụưừứửữựûüůū","UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿ","YÝỲỶỸỴŸ","zžżź","ZŽŻŹ"]:["aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćčCÇĆČ","dđďDĐĎ","eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïīIÌÍỈĨỊÎÏĪ","lłLŁ","nñňńNÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rřRŘ","sšśșşSŠŚȘŞ","tťțţTŤȚŢ","uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿYÝỲỶỸỴŸ","zžżźZŽŻŹ"];let a=[];return e.split("").forEach(n=>{r.every(i=>{if(i.indexOf(n)!==-1){if(a.indexOf(i)>-1)return!1;e=e.replace(new RegExp(`[${i}]`,`gm${t}`),`[${i}]`),a.push(i)}return!0})}),e}createMergedBlanksRegExp(e){return e.replace(/[\s]+/gmi,"[\\s]+")}createAccuracyRegExp(e){const t="!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿";let r=this.opt.accuracy,a=typeof r=="string"?r:r.value,n=typeof r=="string"?[]:r.limiters,i="";switch(n.forEach(s=>{i+=`|${this.escapeStr(s)}`}),a){case"partially":default:return`()(${e})`;case"complementary":return i="\\s"+(i||this.escapeStr(t)),`()([^${i}]*${e}[^${i}]*)`;case"exactly":return`(^|\\s${i})(${e})(?=$|\\s${i})`}}getSeparatedKeywords(e){let t=[];return e.forEach(r=>{this.opt.separateWordSearch?r.split(" ").forEach(a=>{a.trim()&&t.indexOf(a)===-1&&t.push(a)}):r.trim()&&t.indexOf(r)===-1&&t.push(r)}),{keywords:t.sort((r,a)=>a.length-r.length),length:t.length}}isNumeric(e){return Number(parseFloat(e))==e}checkRanges(e){if(!Array.isArray(e)||Object.prototype.toString.call(e[0])!=="[object Object]")return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];const t=[];let r=0;return e.sort((a,n)=>a.start-n.start).forEach(a=>{let{start:n,end:i,valid:s}=this.callNoMatchOnInvalidRanges(a,r);s&&(a.start=n,a.length=i-n,t.push(a),r=i)}),t}callNoMatchOnInvalidRanges(e,t){let r,a,n=!1;return e&&typeof e.start<"u"?(r=parseInt(e.start,10),a=r+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&a-t>0&&a-r>0?n=!0:(this.log(`Ignoring invalid or overlapping range: ${JSON.stringify(e)}`),this.opt.noMatch(e))):(this.log(`Ignoring invalid range: ${JSON.stringify(e)}`),this.opt.noMatch(e)),{start:r,end:a,valid:n}}checkWhitespaceRanges(e,t,r){let a,n=!0,i=r.length,s=t-i,u=parseInt(e.start,10)-s;return u=u>i?i:u,a=u+parseInt(e.length,10),a>i&&(a=i,this.log(`End range automatically set to the max value of ${i}`)),u<0||a-u<0||u>i||a>i?(n=!1,this.log(`Invalid range: ${JSON.stringify(e)}`),this.opt.noMatch(e)):r.substring(u,a).replace(/\s+/g,"")===""&&(n=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:u,end:a,valid:n}}getTextNodes(e){let t="",r=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,a=>{r.push({start:t.length,end:(t+=a.textContent).length,node:a})},a=>this.matchesExclude(a.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT,()=>{e({value:t,nodes:r})})}matchesExclude(e){return ce.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}wrapRangeInTextNode(e,t,r){const a=this.opt.element?this.opt.element:"mark",n=e.splitText(t),i=n.splitText(r-t);let s=document.createElement(a);return s.setAttribute("data-markjs","true"),this.opt.className&&s.setAttribute("class",this.opt.className),s.textContent=n.textContent,n.parentNode.replaceChild(s,n),i}wrapRangeInMappedTextNode(e,t,r,a,n){e.nodes.every((i,s)=>{const u=e.nodes[s+1];if(typeof u>"u"||u.start>t){if(!a(i.node))return!1;const l=t-i.start,d=(r>i.end?i.end:r)-i.start,h=e.value.substr(0,i.start),v=e.value.substr(d+i.start);if(i.node=this.wrapRangeInTextNode(i.node,l,d),e.value=h+v,e.nodes.forEach((y,g)=>{g>=s&&(e.nodes[g].start>0&&g!==s&&(e.nodes[g].start-=d),e.nodes[g].end-=d)}),r-=d,n(i.node.previousSibling,i.start),r>i.end)t=i.end;else return!1}return!0})}wrapMatches(e,t,r,a,n){const i=t===0?0:t+1;this.getTextNodes(s=>{s.nodes.forEach(u=>{u=u.node;let l;for(;(l=e.exec(u.textContent))!==null&&l[i]!=="";){if(!r(l[i],u))continue;let d=l.index;if(i!==0)for(let h=1;h{let u;for(;(u=e.exec(s.value))!==null&&u[i]!=="";){let l=u.index;if(i!==0)for(let h=1;hr(u[i],h),(h,v)=>{e.lastIndex=v,a(h)})}n()})}wrapRangeFromIndex(e,t,r,a){this.getTextNodes(n=>{const i=n.value.length;e.forEach((s,u)=>{let{start:l,end:d,valid:h}=this.checkWhitespaceRanges(s,i,n.value);h&&this.wrapRangeInMappedTextNode(n,l,d,v=>t(v,s,n.value.substring(l,d),u),v=>{r(v,s)})}),a()})}unwrapMatches(e){const t=e.parentNode;let r=document.createDocumentFragment();for(;e.firstChild;)r.appendChild(e.removeChild(e.firstChild));t.replaceChild(r,e),this.ie?this.normalizeTextNode(t):t.normalize()}normalizeTextNode(e){if(e){if(e.nodeType===3)for(;e.nextSibling&&e.nextSibling.nodeType===3;)e.nodeValue+=e.nextSibling.nodeValue,e.parentNode.removeChild(e.nextSibling);else this.normalizeTextNode(e.firstChild);this.normalizeTextNode(e.nextSibling)}}markRegExp(e,t){this.opt=t,this.log(`Searching with expression "${e}"`);let r=0,a="wrapMatches";const n=i=>{r++,this.opt.each(i)};this.opt.acrossElements&&(a="wrapMatchesAcrossElements"),this[a](e,this.opt.ignoreGroups,(i,s)=>this.opt.filter(s,i,r),n,()=>{r===0&&this.opt.noMatch(e),this.opt.done(r)})}mark(e,t){this.opt=t;let r=0,a="wrapMatches";const{keywords:n,length:i}=this.getSeparatedKeywords(typeof e=="string"?[e]:e),s=this.opt.caseSensitive?"":"i",u=l=>{let d=new RegExp(this.createRegExp(l),`gm${s}`),h=0;this.log(`Searching with expression "${d}"`),this[a](d,1,(v,y)=>this.opt.filter(y,l,r,h),v=>{h++,r++,this.opt.each(v)},()=>{h===0&&this.opt.noMatch(l),n[i-1]===l?this.opt.done(r):u(n[n.indexOf(l)+1])})};this.opt.acrossElements&&(a="wrapMatchesAcrossElements"),i===0?this.opt.done(r):u(n[0])}markRanges(e,t){this.opt=t;let r=0,a=this.checkRanges(e);a&&a.length?(this.log("Starting to mark with the following ranges: "+JSON.stringify(a)),this.wrapRangeFromIndex(a,(n,i,s,u)=>this.opt.filter(n,i,s,u),(n,i)=>{r++,this.opt.each(n,i)},()=>{this.opt.done(r)})):this.opt.done(r)}unmark(e){this.opt=e;let t=this.opt.element?this.opt.element:"*";t+="[data-markjs]",this.opt.className&&(t+=`.${this.opt.className}`),this.log(`Removal selector "${t}"`),this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT,r=>{this.unwrapMatches(r)},r=>{const a=ce.matches(r,t),n=this.matchesExclude(r);return!a||n?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},this.opt.done)}};function kr(o){const e=new Cr(o);return this.mark=(t,r)=>(e.mark(t,r),this),this.markRegExp=(t,r)=>(e.markRegExp(t,r),this),this.markRanges=(t,r)=>(e.markRanges(t,r),this),this.unmark=t=>(e.unmark(t),this),this}var B=function(){return B=Object.assign||function(e){for(var t,r=1,a=arguments.length;r0&&n[n.length-1])&&(l[0]===6||l[0]===2)){t=0;continue}if(l[0]===3&&(!n||l[1]>n[0]&&l[1]=o.length&&(o=void 0),{value:o&&o[r++],done:!o}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function $(o,e){var t=typeof Symbol=="function"&&o[Symbol.iterator];if(!t)return o;var r=t.call(o),a,n=[],i;try{for(;(e===void 0||e-- >0)&&!(a=r.next()).done;)n.push(a.value)}catch(s){i={error:s}}finally{try{a&&!a.done&&(t=r.return)&&t.call(r)}finally{if(i)throw i.error}}return n}var Ir="ENTRIES",xt="KEYS",Ft="VALUES",j="",_e=function(){function o(e,t){var r=e._tree,a=Array.from(r.keys());this.set=e,this._type=t,this._path=a.length>0?[{node:r,keys:a}]:[]}return o.prototype.next=function(){var e=this.dive();return this.backtrack(),e},o.prototype.dive=function(){if(this._path.length===0)return{done:!0,value:void 0};var e=le(this._path),t=e.node,r=e.keys;if(le(r)===j)return{done:!1,value:this.result()};var a=t.get(le(r));return this._path.push({node:a,keys:Array.from(a.keys())}),this.dive()},o.prototype.backtrack=function(){if(this._path.length!==0){var e=le(this._path).keys;e.pop(),!(e.length>0)&&(this._path.pop(),this.backtrack())}},o.prototype.key=function(){return this.set._prefix+this._path.map(function(e){var t=e.keys;return le(t)}).filter(function(e){return e!==j}).join("")},o.prototype.value=function(){return le(this._path).node.get(j)},o.prototype.result=function(){switch(this._type){case Ft:return this.value();case xt:return this.key();default:return[this.key(),this.value()]}},o.prototype[Symbol.iterator]=function(){return this},o}(),le=function(o){return o[o.length-1]},Dr=function(o,e,t){var r=new Map;if(e===void 0)return r;for(var a=e.length+1,n=a+t,i=new Uint8Array(n*a).fill(t+1),s=0;st)continue e}Et(o.get(y),e,t,r,a,E,i,s+y)}}}catch(f){u={error:f}}finally{try{v&&!v.done&&(l=h.return)&&l.call(h)}finally{if(u)throw u.error}}},Oe=function(){function o(e,t){e===void 0&&(e=new Map),t===void 0&&(t=""),this._size=void 0,this._tree=e,this._prefix=t}return o.prototype.atPrefix=function(e){var t,r;if(!e.startsWith(this._prefix))throw new Error("Mismatched prefix");var a=$(Ne(this._tree,e.slice(this._prefix.length)),2),n=a[0],i=a[1];if(n===void 0){var s=$(je(i),2),u=s[0],l=s[1];try{for(var d=D(u.keys()),h=d.next();!h.done;h=d.next()){var v=h.value;if(v!==j&&v.startsWith(l)){var y=new Map;return y.set(v.slice(l.length),u.get(v)),new o(y,e)}}}catch(g){t={error:g}}finally{try{h&&!h.done&&(r=d.return)&&r.call(d)}finally{if(t)throw t.error}}}return new o(n,e)},o.prototype.clear=function(){this._size=void 0,this._tree.clear()},o.prototype.delete=function(e){return this._size=void 0,_r(this._tree,e)},o.prototype.entries=function(){return new _e(this,Ir)},o.prototype.forEach=function(e){var t,r;try{for(var a=D(this),n=a.next();!n.done;n=a.next()){var i=$(n.value,2),s=i[0],u=i[1];e(s,u,this)}}catch(l){t={error:l}}finally{try{n&&!n.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}},o.prototype.fuzzyGet=function(e,t){return Dr(this._tree,e,t)},o.prototype.get=function(e){var t=Ve(this._tree,e);return t!==void 0?t.get(j):void 0},o.prototype.has=function(e){var t=Ve(this._tree,e);return t!==void 0&&t.has(j)},o.prototype.keys=function(){return new _e(this,xt)},o.prototype.set=function(e,t){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;var r=Re(this._tree,e);return r.set(j,t),this},Object.defineProperty(o.prototype,"size",{get:function(){if(this._size)return this._size;this._size=0;for(var e=this.entries();!e.next().done;)this._size+=1;return this._size},enumerable:!1,configurable:!0}),o.prototype.update=function(e,t){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;var r=Re(this._tree,e);return r.set(j,t(r.get(j))),this},o.prototype.fetch=function(e,t){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;var r=Re(this._tree,e),a=r.get(j);return a===void 0&&r.set(j,a=t()),a},o.prototype.values=function(){return new _e(this,Ft)},o.prototype[Symbol.iterator]=function(){return this.entries()},o.from=function(e){var t,r,a=new o;try{for(var n=D(e),i=n.next();!i.done;i=n.next()){var s=$(i.value,2),u=s[0],l=s[1];a.set(u,l)}}catch(d){t={error:d}}finally{try{i&&!i.done&&(r=n.return)&&r.call(n)}finally{if(t)throw t.error}}return a},o.fromObject=function(e){return o.from(Object.entries(e))},o}(),Ne=function(o,e,t){var r,a;if(t===void 0&&(t=[]),e.length===0||o==null)return[o,t];try{for(var n=D(o.keys()),i=n.next();!i.done;i=n.next()){var s=i.value;if(s!==j&&e.startsWith(s))return t.push([o,s]),Ne(o.get(s),e.slice(s.length),t)}}catch(u){r={error:u}}finally{try{i&&!i.done&&(a=n.return)&&a.call(n)}finally{if(r)throw r.error}}return t.push([o,e]),Ne(void 0,"",t)},Ve=function(o,e){var t,r;if(e.length===0||o==null)return o;try{for(var a=D(o.keys()),n=a.next();!n.done;n=a.next()){var i=n.value;if(i!==j&&e.startsWith(i))return Ve(o.get(i),e.slice(i.length))}}catch(s){t={error:s}}finally{try{n&&!n.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}},Re=function(o,e){var t,r,a=e.length;e:for(var n=0;o&&n0)throw new Error("Expected documents to be present. Omit the argument to remove all documents.");this._index=new Oe,this._documentCount=0,this._documentIds=new Map,this._idToShortId=new Map,this._fieldLength=new Map,this._avgFieldLength=[],this._storedFields=new Map,this._nextId=0}},o.prototype.discard=function(e){var t=this,r=this._idToShortId.get(e);if(r==null)throw new Error("MiniSearch: cannot discard document with ID ".concat(e,": it is not in the index"));this._idToShortId.delete(e),this._documentIds.delete(r),this._storedFields.delete(r),(this._fieldLength.get(r)||[]).forEach(function(a,n){t.removeFieldLength(r,n,t._documentCount,a)}),this._fieldLength.delete(r),this._documentCount-=1,this._dirtCount+=1,this.maybeAutoVacuum()},o.prototype.maybeAutoVacuum=function(){if(this._options.autoVacuum!==!1){var e=this._options.autoVacuum,t=e.minDirtFactor,r=e.minDirtCount,a=e.batchSize,n=e.batchWait;this.conditionalVacuum({batchSize:a,batchWait:n},{minDirtCount:r,minDirtFactor:t})}},o.prototype.discardAll=function(e){var t,r,a=this._options.autoVacuum;try{this._options.autoVacuum=!1;try{for(var n=D(e),i=n.next();!i.done;i=n.next()){var s=i.value;this.discard(s)}}catch(u){t={error:u}}finally{try{i&&!i.done&&(r=n.return)&&r.call(n)}finally{if(t)throw t.error}}}finally{this._options.autoVacuum=a}this.maybeAutoVacuum()},o.prototype.replace=function(e){var t=this._options,r=t.idField,a=t.extractField,n=a(e,r);this.discard(n),this.add(e)},o.prototype.vacuum=function(e){return e===void 0&&(e={}),this.conditionalVacuum(e)},o.prototype.conditionalVacuum=function(e,t){var r=this;return this._currentVacuum?(this._enqueuedVacuumConditions=this._enqueuedVacuumConditions&&t,this._enqueuedVacuum!=null?this._enqueuedVacuum:(this._enqueuedVacuum=this._currentVacuum.then(function(){var a=r._enqueuedVacuumConditions;return r._enqueuedVacuumConditions=We,r.performVacuuming(e,a)}),this._enqueuedVacuum)):this.vacuumConditionsMet(t)===!1?Promise.resolve():(this._currentVacuum=this.performVacuuming(e),this._currentVacuum)},o.prototype.performVacuuming=function(e,t){return Nr(this,void 0,void 0,function(){var r,a,n,i,s,u,l,d,h,v,y,g,E,b,A,k,C,R,L,z,I,S,_,O,x;return Tr(this,function(c){switch(c.label){case 0:if(r=this._dirtCount,!this.vacuumConditionsMet(t))return[3,10];a=e.batchSize||$e.batchSize,n=e.batchWait||$e.batchWait,i=1,c.label=1;case 1:c.trys.push([1,7,8,9]),s=D(this._index),u=s.next(),c.label=2;case 2:if(u.done)return[3,6];l=$(u.value,2),d=l[0],h=l[1];try{for(v=(S=void 0,D(h)),y=v.next();!y.done;y=v.next()){g=$(y.value,2),E=g[0],b=g[1];try{for(A=(O=void 0,D(b)),k=A.next();!k.done;k=A.next())C=$(k.value,1),R=C[0],!this._documentIds.has(R)&&(b.size<=1?h.delete(E):b.delete(R))}catch(f){O={error:f}}finally{try{k&&!k.done&&(x=A.return)&&x.call(A)}finally{if(O)throw O.error}}}}catch(f){S={error:f}}finally{try{y&&!y.done&&(_=v.return)&&_.call(v)}finally{if(S)throw S.error}}return this._index.get(d).size===0&&this._index.delete(d),i%a!==0?[3,4]:[4,new Promise(function(f){return setTimeout(f,n)})];case 3:c.sent(),c.label=4;case 4:i+=1,c.label=5;case 5:return u=s.next(),[3,2];case 6:return[3,9];case 7:return L=c.sent(),z={error:L},[3,9];case 8:try{u&&!u.done&&(I=s.return)&&I.call(s)}finally{if(z)throw z.error}return[7];case 9:this._dirtCount-=r,c.label=10;case 10:return[4,null];case 11:return c.sent(),this._currentVacuum=this._enqueuedVacuum,this._enqueuedVacuum=null,[2]}})})},o.prototype.vacuumConditionsMet=function(e){if(e==null)return!0;var t=e.minDirtCount,r=e.minDirtFactor;return t=t||Pe.minDirtCount,r=r||Pe.minDirtFactor,this.dirtCount>=t&&this.dirtFactor>=r},Object.defineProperty(o.prototype,"isVacuuming",{get:function(){return this._currentVacuum!=null},enumerable:!1,configurable:!0}),Object.defineProperty(o.prototype,"dirtCount",{get:function(){return this._dirtCount},enumerable:!1,configurable:!0}),Object.defineProperty(o.prototype,"dirtFactor",{get:function(){return this._dirtCount/(1+this._documentCount+this._dirtCount)},enumerable:!1,configurable:!0}),o.prototype.has=function(e){return this._idToShortId.has(e)},o.prototype.getStoredFields=function(e){var t=this._idToShortId.get(e);if(t!=null)return this._storedFields.get(t)},o.prototype.search=function(e,t){var r,a;t===void 0&&(t={});var n=this.executeQuery(e,t),i=[];try{for(var s=D(n),u=s.next();!u.done;u=s.next()){var l=$(u.value,2),d=l[0],h=l[1],v=h.score,y=h.terms,g=h.match,E=y.length||1,b={id:this._documentIds.get(d),score:v*E,terms:Object.keys(g),queryTerms:y,match:g};Object.assign(b,this._storedFields.get(d)),(t.filter==null||t.filter(b))&&i.push(b)}}catch(A){r={error:A}}finally{try{u&&!u.done&&(a=s.return)&&a.call(s)}finally{if(r)throw r.error}}return e===o.wildcard&&t.boostDocument==null&&this._options.searchOptions.boostDocument==null||i.sort(dt),i},o.prototype.autoSuggest=function(e,t){var r,a,n,i;t===void 0&&(t={}),t=B(B({},this._options.autoSuggestOptions),t);var s=new Map;try{for(var u=D(this.search(e,t)),l=u.next();!l.done;l=u.next()){var d=l.value,h=d.score,v=d.terms,y=v.join(" "),g=s.get(y);g!=null?(g.score+=h,g.count+=1):s.set(y,{score:h,terms:v,count:1})}}catch(L){r={error:L}}finally{try{l&&!l.done&&(a=u.return)&&a.call(u)}finally{if(r)throw r.error}}var E=[];try{for(var b=D(s),A=b.next();!A.done;A=b.next()){var k=$(A.value,2),g=k[0],C=k[1],h=C.score,v=C.terms,R=C.count;E.push({suggestion:g,terms:v,score:h/R})}}catch(L){n={error:L}}finally{try{A&&!A.done&&(i=b.return)&&i.call(b)}finally{if(n)throw n.error}}return E.sort(dt),E},Object.defineProperty(o.prototype,"documentCount",{get:function(){return this._documentCount},enumerable:!1,configurable:!0}),Object.defineProperty(o.prototype,"termCount",{get:function(){return this._index.size},enumerable:!1,configurable:!0}),o.loadJSON=function(e,t){if(t==null)throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");return this.loadJS(JSON.parse(e),t)},o.getDefault=function(e){if(Le.hasOwnProperty(e))return Me(Le,e);throw new Error('MiniSearch: unknown option "'.concat(e,'"'))},o.loadJS=function(e,t){var r,a,n,i,s,u,l=e.index,d=e.documentCount,h=e.nextId,v=e.documentIds,y=e.fieldIds,g=e.fieldLength,E=e.averageFieldLength,b=e.storedFields,A=e.dirtCount,k=e.serializationVersion;if(k!==1&&k!==2)throw new Error("MiniSearch: cannot deserialize an index created with an incompatible version");var C=new o(t);C._documentCount=d,C._nextId=h,C._documentIds=Ee(v),C._idToShortId=new Map,C._fieldIds=y,C._fieldLength=Ee(g),C._avgFieldLength=E,C._storedFields=Ee(b),C._dirtCount=A||0,C._index=new Oe;try{for(var R=D(C._documentIds),L=R.next();!L.done;L=R.next()){var z=$(L.value,2),I=z[0],S=z[1];C._idToShortId.set(S,I)}}catch(w){r={error:w}}finally{try{L&&!L.done&&(a=R.return)&&a.call(R)}finally{if(r)throw r.error}}try{for(var _=D(l),O=_.next();!O.done;O=_.next()){var x=$(O.value,2),c=x[0],f=x[1],p=new Map;try{for(var T=(s=void 0,D(Object.keys(f))),N=T.next();!N.done;N=T.next()){var M=N.value,m=f[M];k===1&&(m=m.ds),p.set(parseInt(M,10),Ee(m))}}catch(w){s={error:w}}finally{try{N&&!N.done&&(u=T.return)&&u.call(T)}finally{if(s)throw s.error}}C._index.set(c,p)}}catch(w){n={error:w}}finally{try{O&&!O.done&&(i=_.return)&&i.call(_)}finally{if(n)throw n.error}}return C},o.prototype.executeQuery=function(e,t){var r=this;if(t===void 0&&(t={}),e===o.wildcard)return this.executeWildcardQuery(t);if(typeof e!="string"){var a=B(B(B({},t),e),{queries:void 0}),n=e.queries.map(function(b){return r.executeQuery(b,a)});return this.combineResults(n,a.combineWith)}var i=this._options,s=i.tokenize,u=i.processTerm,l=i.searchOptions,d=B(B({tokenize:s,processTerm:u},l),t),h=d.tokenize,v=d.processTerm,y=h(e).flatMap(function(b){return v(b)}).filter(function(b){return!!b}),g=y.map(zr(d)),E=g.map(function(b){return r.executeQuerySpec(b,d)});return this.combineResults(E,d.combineWith)},o.prototype.executeQuerySpec=function(e,t){var r,a,n,i,s=B(B({},this._options.searchOptions),t),u=(s.fields||this._options.fields).reduce(function(M,m){var w;return B(B({},M),(w={},w[m]=Me(s.boost,m)||1,w))},{}),l=s.boostDocument,d=s.weights,h=s.maxFuzzy,v=s.bm25,y=B(B({},ct.weights),d),g=y.fuzzy,E=y.prefix,b=this._index.get(e.term),A=this.termResults(e.term,e.term,1,b,u,l,v),k,C;if(e.prefix&&(k=this._index.atPrefix(e.term)),e.fuzzy){var R=e.fuzzy===!0?.2:e.fuzzy,L=R<1?Math.min(h,Math.round(e.term.length*R)):R;L&&(C=this._index.fuzzyGet(e.term,L))}if(k)try{for(var z=D(k),I=z.next();!I.done;I=z.next()){var S=$(I.value,2),_=S[0],O=S[1],x=_.length-e.term.length;if(x){C==null||C.delete(_);var c=E*_.length/(_.length+.3*x);this.termResults(e.term,_,c,O,u,l,v,A)}}}catch(M){r={error:M}}finally{try{I&&!I.done&&(a=z.return)&&a.call(z)}finally{if(r)throw r.error}}if(C)try{for(var f=D(C.keys()),p=f.next();!p.done;p=f.next()){var _=p.value,T=$(C.get(_),2),N=T[0],x=T[1];if(x){var c=g*_.length/(_.length+x);this.termResults(e.term,_,c,N,u,l,v,A)}}}catch(M){n={error:M}}finally{try{p&&!p.done&&(i=f.return)&&i.call(f)}finally{if(n)throw n.error}}return A},o.prototype.executeWildcardQuery=function(e){var t,r,a=new Map,n=B(B({},this._options.searchOptions),e);try{for(var i=D(this._documentIds),s=i.next();!s.done;s=i.next()){var u=$(s.value,2),l=u[0],d=u[1],h=n.boostDocument?n.boostDocument(d,"",this._storedFields.get(l)):1;a.set(l,{score:h,terms:[],match:{}})}}catch(v){t={error:v}}finally{try{s&&!s.done&&(r=i.return)&&r.call(i)}finally{if(t)throw t.error}}return a},o.prototype.combineResults=function(e,t){if(t===void 0&&(t=Ke),e.length===0)return new Map;var r=t.toLowerCase();return e.reduce(Mr[r])||new Map},o.prototype.toJSON=function(){var e,t,r,a,n=[];try{for(var i=D(this._index),s=i.next();!s.done;s=i.next()){var u=$(s.value,2),l=u[0],d=u[1],h={};try{for(var v=(r=void 0,D(d)),y=v.next();!y.done;y=v.next()){var g=$(y.value,2),E=g[0],b=g[1];h[E]=Object.fromEntries(b)}}catch(A){r={error:A}}finally{try{y&&!y.done&&(a=v.return)&&a.call(v)}finally{if(r)throw r.error}}n.push([l,h])}}catch(A){e={error:A}}finally{try{s&&!s.done&&(t=i.return)&&t.call(i)}finally{if(e)throw e.error}}return{documentCount:this._documentCount,nextId:this._nextId,documentIds:Object.fromEntries(this._documentIds),fieldIds:this._fieldIds,fieldLength:Object.fromEntries(this._fieldLength),averageFieldLength:this._avgFieldLength,storedFields:Object.fromEntries(this._storedFields),dirtCount:this._dirtCount,index:n,serializationVersion:2}},o.prototype.termResults=function(e,t,r,a,n,i,s,u){var l,d,h,v,y;if(u===void 0&&(u=new Map),a==null)return u;try{for(var g=D(Object.keys(n)),E=g.next();!E.done;E=g.next()){var b=E.value,A=n[b],k=this._fieldIds[b],C=a.get(k);if(C!=null){var R=C.size,L=this._avgFieldLength[k];try{for(var z=(h=void 0,D(C.keys())),I=z.next();!I.done;I=z.next()){var S=I.value;if(!this._documentIds.has(S)){this.removeTerm(k,S,t),R-=1;continue}var _=i?i(this._documentIds.get(S),t,this._storedFields.get(S)):1;if(_){var O=C.get(S),x=this._fieldLength.get(S)[k],c=Pr(O,R,this._documentCount,x,L,s),f=r*A*_*c,p=u.get(S);if(p){p.score+=f,Vr(p.terms,e);var T=Me(p.match,t);T?T.push(b):p.match[t]=[b]}else u.set(S,{score:f,terms:[e],match:(y={},y[t]=[b],y)})}}}catch(N){h={error:N}}finally{try{I&&!I.done&&(v=z.return)&&v.call(z)}finally{if(h)throw h.error}}}}}catch(N){l={error:N}}finally{try{E&&!E.done&&(d=g.return)&&d.call(g)}finally{if(l)throw l.error}}return u},o.prototype.addTerm=function(e,t,r){var a=this._index.fetch(r,ht),n=a.get(e);if(n==null)n=new Map,n.set(t,1),a.set(e,n);else{var i=n.get(t);n.set(t,(i||0)+1)}},o.prototype.removeTerm=function(e,t,r){if(!this._index.has(r)){this.warnDocumentChanged(t,e,r);return}var a=this._index.fetch(r,ht),n=a.get(e);n==null||n.get(t)==null?this.warnDocumentChanged(t,e,r):n.get(t)<=1?n.size<=1?a.delete(e):n.delete(t):n.set(t,n.get(t)-1),this._index.get(r).size===0&&this._index.delete(r)},o.prototype.warnDocumentChanged=function(e,t,r){var a,n;try{for(var i=D(Object.keys(this._fieldIds)),s=i.next();!s.done;s=i.next()){var u=s.value;if(this._fieldIds[u]===t){this._options.logger("warn","MiniSearch: document with ID ".concat(this._documentIds.get(e),' has changed before removal: term "').concat(r,'" was not present in field "').concat(u,'". Removing a document after it has changed can corrupt the index!'),"version_conflict");return}}}catch(l){a={error:l}}finally{try{s&&!s.done&&(n=i.return)&&n.call(i)}finally{if(a)throw a.error}}},o.prototype.addDocumentId=function(e){var t=this._nextId;return this._idToShortId.set(e,t),this._documentIds.set(t,e),this._documentCount+=1,this._nextId+=1,t},o.prototype.addFields=function(e){for(var t=0;t(Pt("data-v-36d7e60a"),o=o(),zt(),o),Wr=["aria-owns"],jr={class:"shell"},Kr=["title"],Jr=q(()=>F("svg",{class:"search-icon",width:"18",height:"18",viewBox:"0 0 24 24","aria-hidden":"true"},[F("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[F("circle",{cx:"11",cy:"11",r:"8"}),F("path",{d:"m21 21l-4.35-4.35"})])],-1)),Ur=[Jr],Gr={class:"search-actions before"},Hr=["title"],qr=q(()=>F("svg",{width:"18",height:"18",viewBox:"0 0 24 24","aria-hidden":"true"},[F("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M19 12H5m7 7l-7-7l7-7"})],-1)),Qr=[qr],Yr=["placeholder"],Zr={class:"search-actions"},Xr=["title"],en=q(()=>F("svg",{width:"18",height:"18",viewBox:"0 0 24 24","aria-hidden":"true"},[F("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M3 14h7v7H3zM3 3h7v7H3zm11 1h7m-7 5h7m-7 6h7m-7 5h7"})],-1)),tn=[en],rn=["disabled","title"],nn=q(()=>F("svg",{width:"18",height:"18",viewBox:"0 0 24 24","aria-hidden":"true"},[F("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M20 5H9l-7 7l7 7h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2Zm-2 4l-6 6m0-6l6 6"})],-1)),an=[nn],on=["id","role","aria-labelledby"],sn=["aria-selected"],un=["href","aria-label","onMouseenter","onFocusin"],ln={class:"titles"},cn=q(()=>F("span",{class:"title-icon"},"#",-1)),fn=["innerHTML"],dn=q(()=>F("svg",{width:"18",height:"18",viewBox:"0 0 24 24"},[F("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m9 18l6-6l-6-6"})],-1)),hn={class:"title main"},vn=["innerHTML"],pn={key:0,class:"excerpt-wrapper"},yn={key:0,class:"excerpt",inert:""},mn=["innerHTML"],gn=q(()=>F("div",{class:"excerpt-gradient-bottom"},null,-1)),bn=q(()=>F("div",{class:"excerpt-gradient-top"},null,-1)),wn={key:0,class:"no-results"},xn={class:"search-keyboard-shortcuts"},Fn=["aria-label"],En=q(()=>F("svg",{width:"14",height:"14",viewBox:"0 0 24 24"},[F("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 19V5m-7 7l7-7l7 7"})],-1)),Sn=[En],An=["aria-label"],Cn=q(()=>F("svg",{width:"14",height:"14",viewBox:"0 0 24 24"},[F("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 5v14m7-7l-7 7l-7-7"})],-1)),kn=[Cn],Nn=["aria-label"],Tn=q(()=>F("svg",{width:"14",height:"14",viewBox:"0 0 24 24"},[F("g",{fill:"none",stroke:"currentcolor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[F("path",{d:"m9 10l-5 5l5 5"}),F("path",{d:"M20 4v7a4 4 0 0 1-4 4H4"})])],-1)),In=[Tn],Dn=["aria-label"],_n=kt({__name:"VPLocalSearchBox",props:{placeholder:{}},emits:["close"],setup(o,{emit:e}){var M;const t=e,r=de(),a=de(),n=de(),i=de(Zt),s=Jt(),{activate:u}=Ar(r,{immediate:!0,allowOutsideClick:!0,clickOutsideDeactivates:!0,escapeDeactivates:!0}),{localeIndex:l,theme:d}=s,h=nt(async()=>{var m,w,P;return rt(Rr.loadJSON((P=await((w=(m=i.value)[l.value])==null?void 0:w.call(m)))==null?void 0:P.default,{fields:["title","titles","text"],storeFields:["title","titles"],searchOptions:{fuzzy:.2,prefix:!0,boost:{title:4,text:2,titles:1}}}))}),y=Te(()=>{var m,w;return((m=d.value.search)==null?void 0:m.provider)==="local"&&((w=d.value.search.options)==null?void 0:w.disableQueryPersistence)===!0}).value?ie(""):Ut("vitepress:local-search-filter",""),g=Gt("vitepress:local-search-detailed-list",!1),E=Te(()=>{var m,w;return((m=d.value.search)==null?void 0:m.provider)==="local"&&((w=d.value.search.options)==null?void 0:w.disableDetailedView)===!0});Nt(()=>{E.value&&(g.value=!1)});const b=de([]),A=ie(!1);ze(y,()=>{A.value=!1});const k=nt(async()=>{if(a.value)return rt(new kr(a.value))},null);Ht(()=>[h.value,y.value,g.value],async([m,w,P],U,Q)=>{var Je,Ue,Ge,He;let K=!1;if(Q(()=>{K=!0}),!m)return;b.value=m.search(w).slice(0,16),A.value=!0;const V=P?await Promise.all(b.value.map(J=>C(J.id))):[];if(K)return;const G=new Map;for(const{id:J,mod:re}of V){const ne=J.slice(0,J.indexOf("#"));let X=G.get(ne);if(X)continue;X=new Map,G.set(ne,X);const Y=re.default??re;if(Y!=null&&Y.render||Y!=null&&Y.setup){const ae=Bt(Y);ae.config.warnHandler=()=>{},ae.provide(Vt,s),Object.defineProperties(ae.config.globalProperties,{$frontmatter:{get(){return s.frontmatter.value}},$params:{get(){return s.page.value.params}}});const qe=document.createElement("div");ae.mount(qe),qe.querySelectorAll("h1, h2, h3, h4, h5, h6").forEach(fe=>{var Ze;const be=(Ze=fe.querySelector("a"))==null?void 0:Ze.getAttribute("href"),Qe=(be==null?void 0:be.startsWith("#"))&&be.slice(1);if(!Qe)return;let Ye="";for(;(fe=fe.nextElementSibling)&&!/^h[1-6]$/i.test(fe.tagName);)Ye+=fe.outerHTML;X.set(Qe,Ye)}),ae.unmount()}if(K)return}const H=new Set;if(b.value=b.value.map(J=>{const[re,ne]=J.id.split("#"),X=G.get(re),Y=(X==null?void 0:X.get(ne))??"";for(const ae in J.match)H.add(ae);return{...J,text:Y}}),await he(),K)return;await new Promise(J=>{var re;(re=k.value)==null||re.unmark({done:()=>{var ne;(ne=k.value)==null||ne.markRegExp(N(H),{done:J})}})});const te=((Je=r.value)==null?void 0:Je.querySelectorAll(".result .excerpt"))??[];for(const J of te)(Ue=J.querySelector('mark[data-markjs="true"]'))==null||Ue.scrollIntoView({block:"center"});(He=(Ge=a.value)==null?void 0:Ge.firstElementChild)==null||He.scrollIntoView({block:"start"})},{debounce:200,immediate:!0});async function C(m){const w=$t(m.slice(0,m.indexOf("#")));try{return{id:m,mod:await vt(()=>import(w),[])}}catch(P){return console.error(P),{id:m,mod:{}}}}const R=ie(),L=Te(()=>{var m;return((m=y.value)==null?void 0:m.length)<=0});function z(m=!0){var w,P;(w=R.value)==null||w.focus(),m&&((P=R.value)==null||P.select())}Ie(()=>{z()});function I(m){m.pointerType==="mouse"&&z()}const S=ie(-1),_=ie(!1);ze(b,m=>{S.value=m.length?0:-1,O()});function O(){he(()=>{const m=document.querySelector(".result.selected");m&&m.scrollIntoView({block:"nearest"})})}xe("ArrowUp",m=>{m.preventDefault(),S.value--,S.value<0&&(S.value=b.value.length-1),_.value=!0,O()}),xe("ArrowDown",m=>{m.preventDefault(),S.value++,S.value>=b.value.length&&(S.value=0),_.value=!0,O()});const x=Tt();xe("Enter",()=>{const m=b.value[S.value];m&&(x.go(m.id),t("close"))}),xe("Escape",()=>{t("close")});const c={modal:{displayDetails:"Display detailed list",resetButtonTitle:"Reset search",backButtonTitle:"Close search",noResultsText:"No results for",footer:{selectText:"to select",selectKeyAriaLabel:"enter",navigateText:"to navigate",navigateUpKeyAriaLabel:"up arrow",navigateDownKeyAriaLabel:"down arrow",closeText:"to close",closeKeyAriaLabel:"escape"}}},f=qt((M=d.value.search)==null?void 0:M.options,c);Ie(()=>{window.history.pushState(null,"",null)}),Qt("popstate",m=>{m.preventDefault(),t("close")});const p=Yt(n);Ie(()=>{n.value=document.body,he(()=>{p.value=!0,he().then(()=>u())})}),It(()=>{p.value=!1});function T(){y.value="",he().then(()=>z(!1))}function N(m){return new RegExp([...m].sort((w,P)=>P.length-w.length).map(w=>`(${w.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")})`).join("|"),"gi")}return(m,w)=>{var P,U,Q,K;return Z(),Dt(Lt,{to:"body"},[F("div",{ref_key:"el",ref:r,role:"button","aria-owns":(P=b.value)!=null&&P.length?"localsearch-list":void 0,"aria-expanded":"true","aria-haspopup":"listbox","aria-labelledby":"localsearch-label",class:"VPLocalSearchBox"},[F("div",{class:"backdrop",onClick:w[0]||(w[0]=V=>m.$emit("close"))}),F("div",jr,[F("form",{class:"search-bar",onPointerup:w[4]||(w[4]=V=>I(V)),onSubmit:w[5]||(w[5]=_t(()=>{},["prevent"]))},[F("label",{title:m.placeholder,id:"localsearch-label",for:"localsearch-input"},Ur,8,Kr),F("div",Gr,[F("button",{class:"back-button",title:W(f)("modal.backButtonTitle"),onClick:w[1]||(w[1]=V=>S.value>-1&&m.$emit("close"))},Qr,8,Hr)]),Ot(F("input",{ref_key:"searchInput",ref:R,"onUpdate:modelValue":w[2]||(w[2]=V=>Mt(y)?y.value=V:null),placeholder:m.placeholder,id:"localsearch-input","aria-labelledby":"localsearch-label",class:"search-input"},null,8,Yr),[[Rt,W(y)]]),F("div",Zr,[E.value?we("",!0):(Z(),ee("button",{key:0,class:Xe(["toggle-layout-button",{"detailed-list":W(g)}]),title:W(f)("modal.displayDetails"),onClick:w[3]||(w[3]=V=>S.value>-1&&(g.value=!W(g)))},tn,10,Xr)),F("button",{class:"clear-button",type:"reset",disabled:L.value,title:W(f)("modal.resetButtonTitle"),onClick:T},an,8,rn)])],32),F("ul",{ref_key:"resultsEl",ref:a,id:(U=b.value)!=null&&U.length?"localsearch-list":void 0,role:(Q=b.value)!=null&&Q.length?"listbox":void 0,"aria-labelledby":(K=b.value)!=null&&K.length?"localsearch-label":void 0,class:"results",onMousemove:w[7]||(w[7]=V=>_.value=!1)},[(Z(!0),ee(tt,null,et(b.value,(V,G)=>(Z(),ee("li",{key:V.id,role:"option","aria-selected":S.value===G?"true":"false"},[F("a",{href:V.id,class:Xe(["result",{selected:S.value===G}]),"aria-label":[...V.titles,V.title].join(" > "),onMouseenter:H=>!_.value&&(S.value=G),onFocusin:H=>S.value=G,onClick:w[6]||(w[6]=H=>m.$emit("close"))},[F("div",null,[F("div",ln,[cn,(Z(!0),ee(tt,null,et(V.titles,(H,te)=>(Z(),ee("span",{key:te,class:"title"},[F("span",{class:"text",innerHTML:H},null,8,fn),dn]))),128)),F("span",hn,[F("span",{class:"text",innerHTML:V.title},null,8,vn)])]),W(g)?(Z(),ee("div",pn,[V.text?(Z(),ee("div",yn,[F("div",{class:"vp-doc",innerHTML:V.text},null,8,mn)])):we("",!0),gn,bn])):we("",!0)])],42,un)],8,sn))),128)),W(y)&&!b.value.length&&A.value?(Z(),ee("li",wn,[ve(pe(W(f)("modal.noResultsText"))+' "',1),F("strong",null,pe(W(y)),1),ve('" ')])):we("",!0)],40,on),F("div",xn,[F("span",null,[F("kbd",{"aria-label":W(f)("modal.footer.navigateUpKeyAriaLabel")},Sn,8,Fn),F("kbd",{"aria-label":W(f)("modal.footer.navigateDownKeyAriaLabel")},kn,8,An),ve(" "+pe(W(f)("modal.footer.navigateText")),1)]),F("span",null,[F("kbd",{"aria-label":W(f)("modal.footer.selectKeyAriaLabel")},In,8,Nn),ve(" "+pe(W(f)("modal.footer.selectText")),1)]),F("span",null,[F("kbd",{"aria-label":W(f)("modal.footer.closeKeyAriaLabel")},"esc",8,Dn),ve(" "+pe(W(f)("modal.footer.closeText")),1)])])])],8,Wr)])}}});const Pn=Wt(_n,[["__scopeId","data-v-36d7e60a"]]);export{Pn as default}; diff --git a/assets/chunks/bots.0d794bf3.js b/assets/chunks/bots.0d794bf3.js new file mode 100644 index 00000000..2eab8718 --- /dev/null +++ b/assets/chunks/bots.0d794bf3.js @@ -0,0 +1 @@ +import{_ as a,o as t,c as o,V as s}from"./framework.63f12d77.js";const c={name:"bots"},e={class:"bots"},b=s(' 群机器人一号 群机器人二号(可私聊) 频道机器人(可私聊) ',3),p=[b];function _(r,n,d,i,m,u){return t(),o("div",e,p)}const l=a(c,[["render",_],["__scopeId","data-v-b04cb2a5"]]);export{l as b}; diff --git a/assets/chunks/download.1cbae1cc.js b/assets/chunks/download.1cbae1cc.js new file mode 100644 index 00000000..de3ebfc5 --- /dev/null +++ b/assets/chunks/download.1cbae1cc.js @@ -0,0 +1 @@ +import{a as d}from"./index.ca03c6e9.js";import{_ as c,o as l,c as p,t as a}from"./framework.63f12d77.js";const n="https://cos.amiyabot.com/package/release",_={name:"download",props:{version:String,text:String},data(){return{latest:""}},methods:{download:function(){window.open(`${n}/AmiyaBot-${this.latest}-${this.version}.zip`)}},mounted(){d.get(`${n}/latest-${this.version}.txt?time=${new Date().getTime()}`).then(t=>{this.latest=t.data.toString().replace(/\r\n/g,"").replace(/\n/g,"")})}};function m(t,e,s,g,i,o){return l(),p("a",{onClick:e[0]||(e[0]=(...r)=>o.download&&o.download(...r))},"AmiyaBot-"+a(i.latest)+"-"+a(s.version)+".zip",1)}const f=c(_,[["render",m],["__scopeId","data-v-5030966d"]]);export{f as d}; diff --git a/assets/chunks/framework.63f12d77.js b/assets/chunks/framework.63f12d77.js new file mode 100644 index 00000000..98bceec3 --- /dev/null +++ b/assets/chunks/framework.63f12d77.js @@ -0,0 +1,18 @@ +/** +* @vue/shared v3.4.35 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**//*! #__NO_SIDE_EFFECTS__ */function rs(e,t){const n=new Set(e.split(","));return t?s=>n.has(s.toLowerCase()):s=>n.has(s)}const ne={},ht=[],be=()=>{},eo=()=>!1,jt=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),is=e=>e.startsWith("onUpdate:"),fe=Object.assign,os=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},to=Object.prototype.hasOwnProperty,X=(e,t)=>to.call(e,t),V=Array.isArray,pt=e=>yn(e)==="[object Map]",Sr=e=>yn(e)==="[object Set]",U=e=>typeof e=="function",re=e=>typeof e=="string",Ye=e=>typeof e=="symbol",Q=e=>e!==null&&typeof e=="object",Ar=e=>(Q(e)||U(e))&&U(e.then)&&U(e.catch),Rr=Object.prototype.toString,yn=e=>Rr.call(e),no=e=>yn(e).slice(8,-1),Mr=e=>yn(e)==="[object Object]",ls=e=>re(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,gt=rs(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),bn=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},so=/-(\w)/g,Re=bn(e=>e.replace(so,(t,n)=>n?n.toUpperCase():"")),ro=/\B([A-Z])/g,Je=bn(e=>e.replace(ro,"-$1").toLowerCase()),wn=bn(e=>e.charAt(0).toUpperCase()+e.slice(1)),nn=bn(e=>e?`on${wn(e)}`:""),qe=(e,t)=>!Object.is(e,t),sn=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:s,value:n})},Wn=e=>{const t=parseFloat(e);return isNaN(t)?e:t},io=e=>{const t=re(e)?Number(e):NaN;return isNaN(t)?e:t};let Ls;const Or=()=>Ls||(Ls=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function cs(e){if(V(e)){const t={};for(let n=0;n{if(n){const s=n.split(lo);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function fs(e){let t="";if(re(e))t=e;else if(V(e))for(let n=0;n!!(e&&e.__v_isRef===!0),ho=e=>re(e)?e:e==null?"":V(e)||Q(e)&&(e.toString===Rr||!U(e.toString))?Pr(e)?ho(e.value):JSON.stringify(e,Fr,2):String(e),Fr=(e,t)=>Pr(t)?Fr(e,t.value):pt(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,r],i)=>(n[Fn(s,i)+" =>"]=r,n),{})}:Sr(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>Fn(n))}:Ye(t)?Fn(t):Q(t)&&!V(t)&&!Mr(t)?String(t):t,Fn=(e,t="")=>{var n;return Ye(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** +* @vue/reactivity v3.4.35 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let ye;class po{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=ye,!t&&ye&&(this.index=(ye.scopes||(ye.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=ye;try{return ye=this,t()}finally{ye=n}}}on(){ye=this}off(){ye=this.parent}stop(t){if(this._active){let n,s;for(n=0,s=this.effects.length;n=4))break}this._dirtyLevel===1&&(this._dirtyLevel=0),ze()}return this._dirtyLevel>=4}set dirty(t){this._dirtyLevel=t?4:0}run(){if(this._dirtyLevel=0,!this.active)return this.fn();let t=ke,n=it;try{return ke=!0,it=this,this._runnings++,Os(this),this.fn()}finally{Is(this),this._runnings--,it=n,ke=t}}stop(){this.active&&(Os(this),Is(this),this.onStop&&this.onStop(),this.active=!1)}}function _o(e){return e.value}function Os(e){e._trackId++,e._depsLength=0}function Is(e){if(e.deps.length>e._depsLength){for(let t=e._depsLength;t{const n=new Map;return n.cleanup=e,n.computed=t,n},an=new WeakMap,ot=Symbol(""),Yn=Symbol("");function me(e,t,n){if(ke&&it){let s=an.get(e);s||an.set(e,s=new Map);let r=s.get(n);r||s.set(n,r=Vr(()=>s.delete(n))),Hr(it,r)}}function Ne(e,t,n,s,r,i){const o=an.get(e);if(!o)return;let l=[];if(t==="clear")l=[...o.values()];else if(n==="length"&&V(e)){const c=Number(s);o.forEach((u,d)=>{(d==="length"||!Ye(d)&&d>=c)&&l.push(u)})}else switch(n!==void 0&&l.push(o.get(n)),t){case"add":V(e)?ls(n)&&l.push(o.get("length")):(l.push(o.get(ot)),pt(e)&&l.push(o.get(Yn)));break;case"delete":V(e)||(l.push(o.get(ot)),pt(e)&&l.push(o.get(Yn)));break;case"set":pt(e)&&l.push(o.get(ot));break}us();for(const c of l)c&&jr(c,4);ds()}function yo(e,t){const n=an.get(e);return n&&n.get(t)}const bo=rs("__proto__,__v_isRef,__isVue"),Ur=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Ye)),Ps=wo();function wo(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const s=z(this);for(let i=0,o=this.length;i{e[t]=function(...n){Xe(),us();const s=z(this)[t].apply(this,n);return ds(),ze(),s}}),e}function vo(e){Ye(e)||(e=String(e));const t=z(this);return me(t,"has",e),t.hasOwnProperty(e)}class Br{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,s){const r=this._isReadonly,i=this._isShallow;if(n==="__v_isReactive")return!r;if(n==="__v_isReadonly")return r;if(n==="__v_isShallow")return i;if(n==="__v_raw")return s===(r?i?Fo:Wr:i?kr:Kr).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(s)?t:void 0;const o=V(t);if(!r){if(o&&X(Ps,n))return Reflect.get(Ps,n,s);if(n==="hasOwnProperty")return vo}const l=Reflect.get(t,n,s);return(Ye(n)?Ur.has(n):bo(n))||(r||me(t,"get",n),i)?l:ue(l)?o&&ls(n)?l:l.value:Q(l)?r?qr(l):Cn(l):l}}class Dr extends Br{constructor(t=!1){super(!1,t)}set(t,n,s,r){let i=t[n];if(!this._isShallow){const c=ct(i);if(!vt(s)&&!ct(s)&&(i=z(i),s=z(s)),!V(t)&&ue(i)&&!ue(s))return c?!1:(i.value=s,!0)}const o=V(t)&&ls(n)?Number(n)e,vn=e=>Reflect.getPrototypeOf(e);function Wt(e,t,n=!1,s=!1){e=e.__v_raw;const r=z(e),i=z(t);n||(qe(t,i)&&me(r,"get",t),me(r,"get",i));const{has:o}=vn(r),l=s?hs:n?ms:Pt;if(o.call(r,t))return l(e.get(t));if(o.call(r,i))return l(e.get(i));e!==r&&e.get(t)}function qt(e,t=!1){const n=this.__v_raw,s=z(n),r=z(e);return t||(qe(e,r)&&me(s,"has",e),me(s,"has",r)),e===r?n.has(e):n.has(e)||n.has(r)}function Gt(e,t=!1){return e=e.__v_raw,!t&&me(z(e),"iterate",ot),Reflect.get(e,"size",e)}function Fs(e,t=!1){!t&&!vt(e)&&!ct(e)&&(e=z(e));const n=z(this);return vn(n).has.call(n,e)||(n.add(e),Ne(n,"add",e,e)),this}function Ns(e,t,n=!1){!n&&!vt(t)&&!ct(t)&&(t=z(t));const s=z(this),{has:r,get:i}=vn(s);let o=r.call(s,e);o||(e=z(e),o=r.call(s,e));const l=i.call(s,e);return s.set(e,t),o?qe(t,l)&&Ne(s,"set",e,t):Ne(s,"add",e,t),this}function $s(e){const t=z(this),{has:n,get:s}=vn(t);let r=n.call(t,e);r||(e=z(e),r=n.call(t,e)),s&&s.call(t,e);const i=t.delete(e);return r&&Ne(t,"delete",e,void 0),i}function Hs(){const e=z(this),t=e.size!==0,n=e.clear();return t&&Ne(e,"clear",void 0,void 0),n}function Yt(e,t){return function(s,r){const i=this,o=i.__v_raw,l=z(o),c=t?hs:e?ms:Pt;return!e&&me(l,"iterate",ot),o.forEach((u,d)=>s.call(r,c(u),c(d),i))}}function Jt(e,t,n){return function(...s){const r=this.__v_raw,i=z(r),o=pt(i),l=e==="entries"||e===Symbol.iterator&&o,c=e==="keys"&&o,u=r[e](...s),d=n?hs:t?ms:Pt;return!t&&me(i,"iterate",c?Yn:ot),{next(){const{value:h,done:m}=u.next();return m?{value:h,done:m}:{value:l?[d(h[0]),d(h[1])]:d(h),done:m}},[Symbol.iterator](){return this}}}}function He(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function So(){const e={get(i){return Wt(this,i)},get size(){return Gt(this)},has:qt,add:Fs,set:Ns,delete:$s,clear:Hs,forEach:Yt(!1,!1)},t={get(i){return Wt(this,i,!1,!0)},get size(){return Gt(this)},has:qt,add(i){return Fs.call(this,i,!0)},set(i,o){return Ns.call(this,i,o,!0)},delete:$s,clear:Hs,forEach:Yt(!1,!0)},n={get(i){return Wt(this,i,!0)},get size(){return Gt(this,!0)},has(i){return qt.call(this,i,!0)},add:He("add"),set:He("set"),delete:He("delete"),clear:He("clear"),forEach:Yt(!0,!1)},s={get(i){return Wt(this,i,!0,!0)},get size(){return Gt(this,!0)},has(i){return qt.call(this,i,!0)},add:He("add"),set:He("set"),delete:He("delete"),clear:He("clear"),forEach:Yt(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(i=>{e[i]=Jt(i,!1,!1),n[i]=Jt(i,!0,!1),t[i]=Jt(i,!1,!0),s[i]=Jt(i,!0,!0)}),[e,n,t,s]}const[Ao,Ro,Mo,Lo]=So();function ps(e,t){const n=t?e?Lo:Mo:e?Ro:Ao;return(s,r,i)=>r==="__v_isReactive"?!e:r==="__v_isReadonly"?e:r==="__v_raw"?s:Reflect.get(X(n,r)&&r in s?n:s,r,i)}const Oo={get:ps(!1,!1)},Io={get:ps(!1,!0)},Po={get:ps(!0,!1)};const Kr=new WeakMap,kr=new WeakMap,Wr=new WeakMap,Fo=new WeakMap;function No(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function $o(e){return e.__v_skip||!Object.isExtensible(e)?0:No(no(e))}function Cn(e){return ct(e)?e:gs(e,!1,Eo,Oo,Kr)}function Ho(e){return gs(e,!1,To,Io,kr)}function qr(e){return gs(e,!0,xo,Po,Wr)}function gs(e,t,n,s,r){if(!Q(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const i=r.get(e);if(i)return i;const o=$o(e);if(o===0)return e;const l=new Proxy(e,o===2?s:n);return r.set(e,l),l}function mt(e){return ct(e)?mt(e.__v_raw):!!(e&&e.__v_isReactive)}function ct(e){return!!(e&&e.__v_isReadonly)}function vt(e){return!!(e&&e.__v_isShallow)}function Gr(e){return e?!!e.__v_raw:!1}function z(e){const t=e&&e.__v_raw;return t?z(t):e}function rn(e){return Object.isExtensible(e)&&Lr(e,"__v_skip",!0),e}const Pt=e=>Q(e)?Cn(e):e,ms=e=>Q(e)?qr(e):e;class Yr{constructor(t,n,s,r){this.getter=t,this._setter=n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this.effect=new as(()=>t(this._value),()=>St(this,this.effect._dirtyLevel===2?2:3)),this.effect.computed=this,this.effect.active=this._cacheable=!r,this.__v_isReadonly=s}get value(){const t=z(this);return(!t._cacheable||t.effect.dirty)&&qe(t._value,t._value=t.effect.run())&&St(t,4),_s(t),t.effect._dirtyLevel>=2&&St(t,2),t._value}set value(t){this._setter(t)}get _dirty(){return this.effect.dirty}set _dirty(t){this.effect.dirty=t}}function jo(e,t,n=!1){let s,r;const i=U(e);return i?(s=e,r=be):(s=e.get,r=e.set),new Yr(s,r,i||!r,n)}function _s(e){var t;ke&&it&&(e=z(e),Hr(it,(t=e.dep)!=null?t:e.dep=Vr(()=>e.dep=void 0,e instanceof Yr?e:void 0)))}function St(e,t=4,n,s){e=z(e);const r=e.dep;r&&jr(r,t)}function ue(e){return!!(e&&e.__v_isRef===!0)}function _t(e){return Jr(e,!1)}function Vo(e){return Jr(e,!0)}function Jr(e,t){return ue(e)?e:new Uo(e,t)}class Uo{constructor(t,n){this.__v_isShallow=n,this.dep=void 0,this.__v_isRef=!0,this._rawValue=n?t:z(t),this._value=n?t:Pt(t)}get value(){return _s(this),this._value}set value(t){const n=this.__v_isShallow||vt(t)||ct(t);t=n?t:z(t),qe(t,this._rawValue)&&(this._rawValue,this._rawValue=t,this._value=n?t:Pt(t),St(this,4))}}function Bo(e){return ue(e)?e.value:e}const Do={get:(e,t,n)=>Bo(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const r=e[t];return ue(r)&&!ue(n)?(r.value=n,!0):Reflect.set(e,t,n,s)}};function Xr(e){return mt(e)?e:new Proxy(e,Do)}class Ko{constructor(t){this.dep=void 0,this.__v_isRef=!0;const{get:n,set:s}=t(()=>_s(this),()=>St(this));this._get=n,this._set=s}get value(){return this._get()}set value(t){this._set(t)}}function ff(e){return new Ko(e)}class ko{constructor(t,n,s){this._object=t,this._key=n,this._defaultValue=s,this.__v_isRef=!0}get value(){const t=this._object[this._key];return t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return yo(z(this._object),this._key)}}class Wo{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0}get value(){return this._getter()}}function af(e,t,n){return ue(e)?e:U(e)?new Wo(e):Q(e)&&arguments.length>1?qo(e,t,n):_t(e)}function qo(e,t,n){const s=e[t];return ue(s)?s:new ko(e,t,n)}/** +* @vue/runtime-core v3.4.35 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function We(e,t,n,s){try{return s?e(...s):e()}catch(r){Vt(r,t,n)}}function Te(e,t,n,s){if(U(e)){const r=We(e,t,n,s);return r&&Ar(r)&&r.catch(i=>{Vt(i,t,n)}),r}if(V(e)){const r=[];for(let i=0;i>>1,r=ae[s],i=Nt(r);iIe&&ae.splice(t,1)}function Xo(e){V(e)?yt.push(...e):(!Ue||!Ue.includes(e,e.allowRecurse?nt+1:nt))&&yt.push(e),Qr()}function js(e,t,n=Ft?Ie+1:0){for(;nNt(n)-Nt(s));if(yt.length=0,Ue){Ue.push(...t);return}for(Ue=t,nt=0;nte.id==null?1/0:e.id,zo=(e,t)=>{const n=Nt(e)-Nt(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function ei(e){Jn=!1,Ft=!0,ae.sort(zo);const t=be;try{for(Ie=0;Ie{s._d&&zs(-1);const i=dn(t);let o;try{o=e(...r)}finally{dn(i),s._d&&zs(1)}return o};return s._n=!0,s._c=!0,s._d=!0,s}function hf(e,t){if(ce===null)return e;const n=Ln(ce),s=e.dirs||(e.dirs=[]);for(let r=0;r{e.isMounted=!0}),oi(()=>{e.isUnmounting=!0}),e}const ve=[Function,Array],ti={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:ve,onEnter:ve,onAfterEnter:ve,onEnterCancelled:ve,onBeforeLeave:ve,onLeave:ve,onAfterLeave:ve,onLeaveCancelled:ve,onBeforeAppear:ve,onAppear:ve,onAfterAppear:ve,onAppearCancelled:ve},ni=e=>{const t=e.subTree;return t.component?ni(t.component):t},el={name:"BaseTransition",props:ti,setup(e,{slots:t}){const n=$i(),s=Qo();return()=>{const r=t.default&&ri(t.default(),!0);if(!r||!r.length)return;let i=r[0];if(r.length>1){for(const m of r)if(m.type!==he){i=m;break}}const o=z(e),{mode:l}=o;if(s.isLeaving)return Nn(i);const c=Vs(i);if(!c)return Nn(i);let u=Xn(c,o,s,n,m=>u=m);hn(c,u);const d=n.subTree,h=d&&Vs(d);if(h&&h.type!==he&&!st(c,h)&&ni(n).type!==he){const m=Xn(h,o,s,n);if(hn(h,m),l==="out-in"&&c.type!==he)return s.isLeaving=!0,m.afterLeave=()=>{s.isLeaving=!1,n.update.active!==!1&&(n.effect.dirty=!0,n.update())},Nn(i);l==="in-out"&&c.type!==he&&(m.delayLeave=(C,E,I)=>{const D=si(s,h);D[String(h.key)]=h,C[Be]=()=>{E(),C[Be]=void 0,delete u.delayedLeave},u.delayedLeave=I})}return i}}},tl=el;function si(e,t){const{leavingVNodes:n}=e;let s=n.get(t.type);return s||(s=Object.create(null),n.set(t.type,s)),s}function Xn(e,t,n,s,r){const{appear:i,mode:o,persisted:l=!1,onBeforeEnter:c,onEnter:u,onAfterEnter:d,onEnterCancelled:h,onBeforeLeave:m,onLeave:C,onAfterLeave:E,onLeaveCancelled:I,onBeforeAppear:D,onAppear:q,onAfterAppear:K,onAppearCancelled:g}=t,v=String(e.key),P=si(n,e),S=(L,M)=>{L&&Te(L,s,9,M)},j=(L,M)=>{const B=M[1];S(L,M),V(L)?L.every(A=>A.length<=1)&&B():L.length<=1&&B()},k={mode:o,persisted:l,beforeEnter(L){let M=c;if(!n.isMounted)if(i)M=D||c;else return;L[Be]&&L[Be](!0);const B=P[v];B&&st(e,B)&&B.el[Be]&&B.el[Be](),S(M,[L])},enter(L){let M=u,B=d,A=h;if(!n.isMounted)if(i)M=q||u,B=K||d,A=g||h;else return;let G=!1;const ee=L[Xt]=se=>{G||(G=!0,se?S(A,[L]):S(B,[L]),k.delayedLeave&&k.delayedLeave(),L[Xt]=void 0)};M?j(M,[L,ee]):ee()},leave(L,M){const B=String(e.key);if(L[Xt]&&L[Xt](!0),n.isUnmounting)return M();S(m,[L]);let A=!1;const G=L[Be]=ee=>{A||(A=!0,M(),ee?S(I,[L]):S(E,[L]),L[Be]=void 0,P[B]===e&&delete P[B])};P[B]=e,C?j(C,[L,G]):G()},clone(L){const M=Xn(L,t,n,s,r);return r&&r(M),M}};return k}function Nn(e){if(Ut(e))return e=Ge(e),e.children=null,e}function Vs(e){if(!Ut(e))return e;const{shapeFlag:t,children:n}=e;if(n){if(t&16)return n[0];if(t&32&&U(n.default))return n.default()}}function hn(e,t){e.shapeFlag&6&&e.component?hn(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function ri(e,t=!1,n){let s=[],r=0;for(let i=0;i1)for(let i=0;ife({name:e.name},t,{setup:e}))():e}const bt=e=>!!e.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function pf(e){U(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:s,delay:r=200,timeout:i,suspensible:o=!0,onError:l}=e;let c=null,u,d=0;const h=()=>(d++,c=null,m()),m=()=>{let C;return c||(C=c=t().catch(E=>{if(E=E instanceof Error?E:new Error(String(E)),l)return new Promise((I,D)=>{l(E,()=>I(h()),()=>D(E),d+1)});throw E}).then(E=>C!==c&&c?c:(E&&(E.__esModule||E[Symbol.toStringTag]==="Module")&&(E=E.default),u=E,E)))};return bs({name:"AsyncComponentWrapper",__asyncLoader:m,get __asyncResolved(){return u},setup(){const C=le;if(u)return()=>$n(u,C);const E=K=>{c=null,Vt(K,C,13,!s)};if(o&&C.suspense||Dt)return m().then(K=>()=>$n(K,C)).catch(K=>(E(K),()=>s?ie(s,{error:K}):null));const I=_t(!1),D=_t(),q=_t(!!r);return r&&setTimeout(()=>{q.value=!1},r),i!=null&&setTimeout(()=>{if(!I.value&&!D.value){const K=new Error(`Async component timed out after ${i}ms.`);E(K),D.value=K}},i),m().then(()=>{I.value=!0,C.parent&&Ut(C.parent.vnode)&&(C.parent.effect.dirty=!0,En(C.parent.update))}).catch(K=>{E(K),D.value=K}),()=>{if(I.value&&u)return $n(u,C);if(D.value&&s)return ie(s,{error:D.value});if(n&&!q.value)return ie(n)}}})}function $n(e,t){const{ref:n,props:s,children:r,ce:i}=t.vnode,o=ie(e,s,r);return o.ref=n,o.ce=i,delete t.vnode.ce,o}const Ut=e=>e.type.__isKeepAlive;function nl(e,t){ii(e,"a",t)}function sl(e,t){ii(e,"da",t)}function ii(e,t,n=le){const s=e.__wdc||(e.__wdc=()=>{let r=n;for(;r;){if(r.isDeactivated)return;r=r.parent}return e()});if(Tn(t,s,n),n){let r=n.parent;for(;r&&r.parent;)Ut(r.parent.vnode)&&rl(s,t,n,r),r=r.parent}}function rl(e,t,n,s){const r=Tn(t,e,s,!0);An(()=>{os(s[t],r)},n)}function Tn(e,t,n=le,s=!1){if(n){const r=n[e]||(n[e]=[]),i=t.__weh||(t.__weh=(...o)=>{Xe();const l=Bt(n),c=Te(t,n,e,o);return l(),ze(),c});return s?r.unshift(i):r.push(i),i}}const $e=e=>(t,n=le)=>{(!Dt||e==="sp")&&Tn(e,(...s)=>t(...s),n)},il=$e("bm"),Sn=$e("m"),ol=$e("bu"),ll=$e("u"),oi=$e("bum"),An=$e("um"),cl=$e("sp"),fl=$e("rtg"),al=$e("rtc");function ul(e,t=le){Tn("ec",e,t)}const ws="components";function gf(e,t){return ci(ws,e,!0,t)||e}const li=Symbol.for("v-ndc");function mf(e){return re(e)?ci(ws,e,!1)||e:e||li}function ci(e,t,n=!0,s=!1){const r=ce||le;if(r){const i=r.type;if(e===ws){const l=rc(i,!1);if(l&&(l===t||l===Re(t)||l===wn(Re(t))))return i}const o=Us(r[e]||i[e],t)||Us(r.appContext[e],t);return!o&&s?i:o}}function Us(e,t){return e&&(e[t]||e[Re(t)]||e[wn(Re(t))])}function _f(e,t,n,s){let r;const i=n&&n[s];if(V(e)||re(e)){r=new Array(e.length);for(let o=0,l=e.length;ot(o,l,void 0,i&&i[l]));else{const o=Object.keys(e);r=new Array(o.length);for(let l=0,c=o.length;lmn(t)?!(t.type===he||t.type===ge&&!fi(t.children)):!0)?e:null}function bf(e,t){const n={};for(const s in e)n[t&&/[A-Z]/.test(s)?`on:${s}`:nn(s)]=e[s];return n}const zn=e=>e?Hi(e)?Ln(e):zn(e.parent):null,At=fe(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>zn(e.parent),$root:e=>zn(e.root),$emit:e=>e.emit,$options:e=>vs(e),$forceUpdate:e=>e.f||(e.f=()=>{e.effect.dirty=!0,En(e.update)}),$nextTick:e=>e.n||(e.n=Zr.bind(e.proxy)),$watch:e=>Ul.bind(e)}),Hn=(e,t)=>e!==ne&&!e.__isScriptSetup&&X(e,t),dl={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:s,data:r,props:i,accessCache:o,type:l,appContext:c}=e;let u;if(t[0]!=="$"){const C=o[t];if(C!==void 0)switch(C){case 1:return s[t];case 2:return r[t];case 4:return n[t];case 3:return i[t]}else{if(Hn(s,t))return o[t]=1,s[t];if(r!==ne&&X(r,t))return o[t]=2,r[t];if((u=e.propsOptions[0])&&X(u,t))return o[t]=3,i[t];if(n!==ne&&X(n,t))return o[t]=4,n[t];Zn&&(o[t]=0)}}const d=At[t];let h,m;if(d)return t==="$attrs"&&me(e.attrs,"get",""),d(e);if((h=l.__cssModules)&&(h=h[t]))return h;if(n!==ne&&X(n,t))return o[t]=4,n[t];if(m=c.config.globalProperties,X(m,t))return m[t]},set({_:e},t,n){const{data:s,setupState:r,ctx:i}=e;return Hn(r,t)?(r[t]=n,!0):s!==ne&&X(s,t)?(s[t]=n,!0):X(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(i[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:r,propsOptions:i}},o){let l;return!!n[o]||e!==ne&&X(e,o)||Hn(t,o)||(l=i[0])&&X(l,o)||X(s,o)||X(At,o)||X(r.config.globalProperties,o)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:X(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function wf(){return hl().slots}function hl(){const e=$i();return e.setupContext||(e.setupContext=Vi(e))}function Bs(e){return V(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Zn=!0;function pl(e){const t=vs(e),n=e.proxy,s=e.ctx;Zn=!1,t.beforeCreate&&Ds(t.beforeCreate,e,"bc");const{data:r,computed:i,methods:o,watch:l,provide:c,inject:u,created:d,beforeMount:h,mounted:m,beforeUpdate:C,updated:E,activated:I,deactivated:D,beforeDestroy:q,beforeUnmount:K,destroyed:g,unmounted:v,render:P,renderTracked:S,renderTriggered:j,errorCaptured:k,serverPrefetch:L,expose:M,inheritAttrs:B,components:A,directives:G,filters:ee}=t;if(u&&gl(u,s,null),o)for(const J in o){const N=o[J];U(N)&&(s[J]=N.bind(n))}if(r){const J=r.call(n,n);Q(J)&&(e.data=Cn(J))}if(Zn=!0,i)for(const J in i){const N=i[J],Pe=U(N)?N.bind(n,n):U(N.get)?N.get.bind(n,n):be,Kt=!U(N)&&U(N.set)?N.set.bind(n):be,Ze=Ae({get:Pe,set:Kt});Object.defineProperty(s,J,{enumerable:!0,configurable:!0,get:()=>Ze.value,set:Me=>Ze.value=Me})}if(l)for(const J in l)ai(l[J],s,n,J);if(c){const J=U(c)?c.call(n):c;Reflect.ownKeys(J).forEach(N=>{vl(N,J[N])})}d&&Ds(d,e,"c");function H(J,N){V(N)?N.forEach(Pe=>J(Pe.bind(n))):N&&J(N.bind(n))}if(H(il,h),H(Sn,m),H(ol,C),H(ll,E),H(nl,I),H(sl,D),H(ul,k),H(al,S),H(fl,j),H(oi,K),H(An,v),H(cl,L),V(M))if(M.length){const J=e.exposed||(e.exposed={});M.forEach(N=>{Object.defineProperty(J,N,{get:()=>n[N],set:Pe=>n[N]=Pe})})}else e.exposed||(e.exposed={});P&&e.render===be&&(e.render=P),B!=null&&(e.inheritAttrs=B),A&&(e.components=A),G&&(e.directives=G)}function gl(e,t,n=be){V(e)&&(e=Qn(e));for(const s in e){const r=e[s];let i;Q(r)?"default"in r?i=wt(r.from||s,r.default,!0):i=wt(r.from||s):i=wt(r),ue(i)?Object.defineProperty(t,s,{enumerable:!0,configurable:!0,get:()=>i.value,set:o=>i.value=o}):t[s]=i}}function Ds(e,t,n){Te(V(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function ai(e,t,n,s){const r=s.includes(".")?Ai(n,s):()=>n[s];if(re(e)){const i=t[e];U(i)&&on(r,i)}else if(U(e))on(r,e.bind(n));else if(Q(e))if(V(e))e.forEach(i=>ai(i,t,n,s));else{const i=U(e.handler)?e.handler.bind(n):t[e.handler];U(i)&&on(r,i,e)}}function vs(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:r,optionsCache:i,config:{optionMergeStrategies:o}}=e.appContext,l=i.get(t);let c;return l?c=l:!r.length&&!n&&!s?c=t:(c={},r.length&&r.forEach(u=>pn(c,u,o,!0)),pn(c,t,o)),Q(t)&&i.set(t,c),c}function pn(e,t,n,s=!1){const{mixins:r,extends:i}=t;i&&pn(e,i,n,!0),r&&r.forEach(o=>pn(e,o,n,!0));for(const o in t)if(!(s&&o==="expose")){const l=ml[o]||n&&n[o];e[o]=l?l(e[o],t[o]):t[o]}return e}const ml={data:Ks,props:ks,emits:ks,methods:Tt,computed:Tt,beforeCreate:de,created:de,beforeMount:de,mounted:de,beforeUpdate:de,updated:de,beforeDestroy:de,beforeUnmount:de,destroyed:de,unmounted:de,activated:de,deactivated:de,errorCaptured:de,serverPrefetch:de,components:Tt,directives:Tt,watch:yl,provide:Ks,inject:_l};function Ks(e,t){return t?e?function(){return fe(U(e)?e.call(this,this):e,U(t)?t.call(this,this):t)}:t:e}function _l(e,t){return Tt(Qn(e),Qn(t))}function Qn(e){if(V(e)){const t={};for(let n=0;n1)return n&&U(t)?t.call(s&&s.proxy):t}}const di={},hi=()=>Object.create(di),pi=e=>Object.getPrototypeOf(e)===di;function Cl(e,t,n,s=!1){const r={},i=hi();e.propsDefaults=Object.create(null),gi(e,t,r,i);for(const o in e.propsOptions[0])o in r||(r[o]=void 0);n?e.props=s?r:Ho(r):e.type.props?e.props=r:e.props=i,e.attrs=i}function El(e,t,n,s){const{props:r,attrs:i,vnode:{patchFlag:o}}=e,l=z(r),[c]=e.propsOptions;let u=!1;if((s||o>0)&&!(o&16)){if(o&8){const d=e.vnode.dynamicProps;for(let h=0;h{c=!0;const[m,C]=mi(h,t,!0);fe(o,m),C&&l.push(...C)};!n&&t.mixins.length&&t.mixins.forEach(d),e.extends&&d(e.extends),e.mixins&&e.mixins.forEach(d)}if(!i&&!c)return Q(e)&&s.set(e,ht),ht;if(V(i))for(let d=0;de[0]==="_"||e==="$stable",Cs=e=>V(e)?e.map(Ee):[Ee(e)],Tl=(e,t,n)=>{if(t._n)return t;const s=Zo((...r)=>Cs(t(...r)),n);return s._c=!1,s},yi=(e,t,n)=>{const s=e._ctx;for(const r in e){if(_i(r))continue;const i=e[r];if(U(i))t[r]=Tl(r,i,s);else if(i!=null){const o=Cs(i);t[r]=()=>o}}},bi=(e,t)=>{const n=Cs(t);e.slots.default=()=>n},wi=(e,t,n)=>{for(const s in t)(n||s!=="_")&&(e[s]=t[s])},Sl=(e,t,n)=>{const s=e.slots=hi();if(e.vnode.shapeFlag&32){const r=t._;r?(wi(s,t,n),n&&Lr(s,"_",r,!0)):yi(t,s)}else t&&bi(e,t)},Al=(e,t,n)=>{const{vnode:s,slots:r}=e;let i=!0,o=ne;if(s.shapeFlag&32){const l=t._;l?n&&l===1?i=!1:wi(r,t,n):(i=!t.$stable,yi(t,r)),o=t}else t&&(bi(e,t),o={default:1});if(i)for(const l in r)!_i(l)&&o[l]==null&&delete r[l]};function gn(e,t,n,s,r=!1){if(V(e)){e.forEach((m,C)=>gn(m,t&&(V(t)?t[C]:t),n,s,r));return}if(bt(s)&&!r)return;const i=s.shapeFlag&4?Ln(s.component):s.el,o=r?null:i,{i:l,r:c}=e,u=t&&t.r,d=l.refs===ne?l.refs={}:l.refs,h=l.setupState;if(u!=null&&u!==c&&(re(u)?(d[u]=null,X(h,u)&&(h[u]=null)):ue(u)&&(u.value=null)),U(c))We(c,l,12,[o,d]);else{const m=re(c),C=ue(c);if(m||C){const E=()=>{if(e.f){const I=m?X(h,c)?h[c]:d[c]:c.value;r?V(I)&&os(I,i):V(I)?I.includes(i)||I.push(i):m?(d[c]=[i],X(h,c)&&(h[c]=d[c])):(c.value=[i],e.k&&(d[e.k]=c.value))}else m?(d[c]=o,X(h,c)&&(h[c]=o)):C&&(c.value=o,e.k&&(d[e.k]=o))};o?(E.id=-1,pe(E,n)):E()}}}const vi=Symbol("_vte"),Rl=e=>e.__isTeleport,Mt=e=>e&&(e.disabled||e.disabled===""),qs=e=>typeof SVGElement<"u"&&e instanceof SVGElement,Gs=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,ts=(e,t)=>{const n=e&&e.to;return re(n)?t?t(n):null:n},Ml={name:"Teleport",__isTeleport:!0,process(e,t,n,s,r,i,o,l,c,u){const{mc:d,pc:h,pbc:m,o:{insert:C,querySelector:E,createText:I,createComment:D}}=u,q=Mt(t.props);let{shapeFlag:K,children:g,dynamicChildren:v}=t;if(e==null){const P=t.el=I(""),S=t.anchor=I("");C(P,n,s),C(S,n,s);const j=t.target=ts(t.props,E),k=Ei(j,t,I,C);j&&(o==="svg"||qs(j)?o="svg":(o==="mathml"||Gs(j))&&(o="mathml"));const L=(M,B)=>{K&16&&d(g,M,B,r,i,o,l,c)};q?L(n,S):j&&L(j,k)}else{t.el=e.el,t.targetStart=e.targetStart;const P=t.anchor=e.anchor,S=t.target=e.target,j=t.targetAnchor=e.targetAnchor,k=Mt(e.props),L=k?n:S,M=k?P:j;if(o==="svg"||qs(S)?o="svg":(o==="mathml"||Gs(S))&&(o="mathml"),v?(m(e.dynamicChildren,v,L,r,i,o,l),Es(e,t,!0)):c||h(e,t,L,M,r,i,o,l,!1),q)k?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):zt(t,n,P,u,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const B=t.target=ts(t.props,E);B&&zt(t,B,null,u,0)}else k&&zt(t,S,j,u,1)}Ci(t)},remove(e,t,n,{um:s,o:{remove:r}},i){const{shapeFlag:o,children:l,anchor:c,targetStart:u,targetAnchor:d,target:h,props:m}=e;if(h&&(r(u),r(d)),i&&r(c),o&16){const C=i||!Mt(m);for(let E=0;E{Ys||(console.error("Hydration completed but contains mismatches."),Ys=!0)},Ol=e=>e.namespaceURI.includes("svg")&&e.tagName!=="foreignObject",Il=e=>e.namespaceURI.includes("MathML"),Zt=e=>{if(Ol(e))return"svg";if(Il(e))return"mathml"},Qt=e=>e.nodeType===8;function Pl(e){const{mt:t,p:n,o:{patchProp:s,createText:r,nextSibling:i,parentNode:o,remove:l,insert:c,createComment:u}}=e,d=(g,v)=>{if(!v.hasChildNodes()){n(null,g,v),un(),v._vnode=g;return}h(v.firstChild,g,null,null,null),un(),v._vnode=g},h=(g,v,P,S,j,k=!1)=>{k=k||!!v.dynamicChildren;const L=Qt(g)&&g.data==="[",M=()=>I(g,v,P,S,j,L),{type:B,ref:A,shapeFlag:G,patchFlag:ee}=v;let se=g.nodeType;v.el=g,ee===-2&&(k=!1,v.dynamicChildren=null);let H=null;switch(B){case lt:se!==3?v.children===""?(c(v.el=r(""),o(g),g),H=g):H=M():(g.data!==v.children&&(ut(),g.data=v.children),H=i(g));break;case he:K(g)?(H=i(g),q(v.el=g.content.firstChild,g,P)):se!==8||L?H=M():H=i(g);break;case Lt:if(L&&(g=i(g),se=g.nodeType),se===1||se===3){H=g;const J=!v.children.length;for(let N=0;N{k=k||!!v.dynamicChildren;const{type:L,props:M,patchFlag:B,shapeFlag:A,dirs:G,transition:ee}=v,se=L==="input"||L==="option";if(se||B!==-1){G&&Oe(v,null,P,"created");let H=!1;if(K(g)){H=Ti(S,ee)&&P&&P.vnode.props&&P.vnode.props.appear;const N=g.content.firstChild;H&&ee.beforeEnter(N),q(N,g,P),v.el=g=N}if(A&16&&!(M&&(M.innerHTML||M.textContent))){let N=C(g.firstChild,v,g,P,S,j,k);for(;N;){ut();const Pe=N;N=N.nextSibling,l(Pe)}}else A&8&&g.textContent!==v.children&&(ut(),g.textContent=v.children);if(M){if(se||!k||B&48)for(const N in M)(se&&(N.endsWith("value")||N==="indeterminate")||jt(N)&&!gt(N)||N[0]===".")&&s(g,N,null,M[N],void 0,P);else if(M.onClick)s(g,"onClick",null,M.onClick,void 0,P);else if(B&4&&mt(M.style))for(const N in M.style)M.style[N]}let J;(J=M&&M.onVnodeBeforeMount)&&Ce(J,P,v),G&&Oe(v,null,P,"beforeMount"),((J=M&&M.onVnodeMounted)||G||H)&&Mi(()=>{J&&Ce(J,P,v),H&&ee.enter(g),G&&Oe(v,null,P,"mounted")},S)}return g.nextSibling},C=(g,v,P,S,j,k,L)=>{L=L||!!v.dynamicChildren;const M=v.children,B=M.length;for(let A=0;A{const{slotScopeIds:L}=v;L&&(j=j?j.concat(L):L);const M=o(g),B=C(i(g),v,M,P,S,j,k);return B&&Qt(B)&&B.data==="]"?i(v.anchor=B):(ut(),c(v.anchor=u("]"),M,B),B)},I=(g,v,P,S,j,k)=>{if(ut(),v.el=null,k){const B=D(g);for(;;){const A=i(g);if(A&&A!==B)l(A);else break}}const L=i(g),M=o(g);return l(g),n(null,v,M,L,P,S,Zt(M),j),L},D=(g,v="[",P="]")=>{let S=0;for(;g;)if(g=i(g),g&&Qt(g)&&(g.data===v&&S++,g.data===P)){if(S===0)return i(g);S--}return g},q=(g,v,P)=>{const S=v.parentNode;S&&S.replaceChild(g,v);let j=P;for(;j;)j.vnode.el===v&&(j.vnode.el=j.subTree.el=g),j=j.parent},K=g=>g.nodeType===1&&g.tagName.toLowerCase()==="template";return[d,h]}const pe=Mi;function Fl(e){return xi(e)}function Nl(e){return xi(e,Pl)}function xi(e,t){const n=Or();n.__VUE__=!0;const{insert:s,remove:r,patchProp:i,createElement:o,createText:l,createComment:c,setText:u,setElementText:d,parentNode:h,nextSibling:m,setScopeId:C=be,insertStaticContent:E}=e,I=(f,a,p,b=null,_=null,w=null,R=void 0,x=null,T=!!a.dynamicChildren)=>{if(f===a)return;f&&!st(f,a)&&(b=kt(f),Me(f,_,w,!0),f=null),a.patchFlag===-2&&(T=!1,a.dynamicChildren=null);const{type:y,ref:O,shapeFlag:$}=a;switch(y){case lt:D(f,a,p,b);break;case he:q(f,a,p,b);break;case Lt:f==null&&K(a,p,b,R);break;case ge:A(f,a,p,b,_,w,R,x,T);break;default:$&1?P(f,a,p,b,_,w,R,x,T):$&6?G(f,a,p,b,_,w,R,x,T):($&64||$&128)&&y.process(f,a,p,b,_,w,R,x,T,ft)}O!=null&&_&&gn(O,f&&f.ref,w,a||f,!a)},D=(f,a,p,b)=>{if(f==null)s(a.el=l(a.children),p,b);else{const _=a.el=f.el;a.children!==f.children&&u(_,a.children)}},q=(f,a,p,b)=>{f==null?s(a.el=c(a.children||""),p,b):a.el=f.el},K=(f,a,p,b)=>{[f.el,f.anchor]=E(f.children,a,p,b,f.el,f.anchor)},g=({el:f,anchor:a},p,b)=>{let _;for(;f&&f!==a;)_=m(f),s(f,p,b),f=_;s(a,p,b)},v=({el:f,anchor:a})=>{let p;for(;f&&f!==a;)p=m(f),r(f),f=p;r(a)},P=(f,a,p,b,_,w,R,x,T)=>{a.type==="svg"?R="svg":a.type==="math"&&(R="mathml"),f==null?S(a,p,b,_,w,R,x,T):L(f,a,_,w,R,x,T)},S=(f,a,p,b,_,w,R,x)=>{let T,y;const{props:O,shapeFlag:$,transition:F,dirs:W}=f;if(T=f.el=o(f.type,w,O&&O.is,O),$&8?d(T,f.children):$&16&&k(f.children,T,null,b,_,jn(f,w),R,x),W&&Oe(f,null,b,"created"),j(T,f,f.scopeId,R,b),O){for(const te in O)te!=="value"&&!gt(te)&&i(T,te,null,O[te],w,b);"value"in O&&i(T,"value",null,O.value,w),(y=O.onVnodeBeforeMount)&&Ce(y,b,f)}W&&Oe(f,null,b,"beforeMount");const Y=Ti(_,F);Y&&F.beforeEnter(T),s(T,a,p),((y=O&&O.onVnodeMounted)||Y||W)&&pe(()=>{y&&Ce(y,b,f),Y&&F.enter(T),W&&Oe(f,null,b,"mounted")},_)},j=(f,a,p,b,_)=>{if(p&&C(f,p),b)for(let w=0;w{for(let y=T;y{const x=a.el=f.el;let{patchFlag:T,dynamicChildren:y,dirs:O}=a;T|=f.patchFlag&16;const $=f.props||ne,F=a.props||ne;let W;if(p&&Qe(p,!1),(W=F.onVnodeBeforeUpdate)&&Ce(W,p,a,f),O&&Oe(a,f,p,"beforeUpdate"),p&&Qe(p,!0),($.innerHTML&&F.innerHTML==null||$.textContent&&F.textContent==null)&&d(x,""),y?M(f.dynamicChildren,y,x,p,b,jn(a,_),w):R||N(f,a,x,null,p,b,jn(a,_),w,!1),T>0){if(T&16)B(x,$,F,p,_);else if(T&2&&$.class!==F.class&&i(x,"class",null,F.class,_),T&4&&i(x,"style",$.style,F.style,_),T&8){const Y=a.dynamicProps;for(let te=0;te{W&&Ce(W,p,a,f),O&&Oe(a,f,p,"updated")},b)},M=(f,a,p,b,_,w,R)=>{for(let x=0;x{if(a!==p){if(a!==ne)for(const w in a)!gt(w)&&!(w in p)&&i(f,w,a[w],null,_,b);for(const w in p){if(gt(w))continue;const R=p[w],x=a[w];R!==x&&w!=="value"&&i(f,w,x,R,_,b)}"value"in p&&i(f,"value",a.value,p.value,_)}},A=(f,a,p,b,_,w,R,x,T)=>{const y=a.el=f?f.el:l(""),O=a.anchor=f?f.anchor:l("");let{patchFlag:$,dynamicChildren:F,slotScopeIds:W}=a;W&&(x=x?x.concat(W):W),f==null?(s(y,p,b),s(O,p,b),k(a.children||[],p,O,_,w,R,x,T)):$>0&&$&64&&F&&f.dynamicChildren?(M(f.dynamicChildren,F,p,_,w,R,x),(a.key!=null||_&&a===_.subTree)&&Es(f,a,!0)):N(f,a,p,O,_,w,R,x,T)},G=(f,a,p,b,_,w,R,x,T)=>{a.slotScopeIds=x,f==null?a.shapeFlag&512?_.ctx.activate(a,p,b,R,T):ee(a,p,b,_,w,R,T):se(f,a,T)},ee=(f,a,p,b,_,w,R)=>{const x=f.component=ec(f,b,_);if(Ut(f)&&(x.ctx.renderer=ft),tc(x,!1,R),x.asyncDep){if(_&&_.registerDep(x,H,R),!f.el){const T=x.subTree=ie(he);q(null,T,a,p)}}else H(x,f,a,p,_,w,R)},se=(f,a,p)=>{const b=a.component=f.component;if(Wl(f,a,p))if(b.asyncDep&&!b.asyncResolved){J(b,a,p);return}else b.next=a,Jo(b.update),b.effect.dirty=!0,b.update();else a.el=f.el,b.vnode=a},H=(f,a,p,b,_,w,R)=>{const x=()=>{if(f.isMounted){let{next:O,bu:$,u:F,parent:W,vnode:Y}=f;{const at=Si(f);if(at){O&&(O.el=Y.el,J(f,O,R)),at.asyncDep.then(()=>{f.isUnmounted||x()});return}}let te=O,Z;Qe(f,!1),O?(O.el=Y.el,J(f,O,R)):O=Y,$&&sn($),(Z=O.props&&O.props.onVnodeBeforeUpdate)&&Ce(Z,W,O,Y),Qe(f,!0);const oe=Vn(f),Se=f.subTree;f.subTree=oe,I(Se,oe,h(Se.el),kt(Se),f,_,w),O.el=oe.el,te===null&&ql(f,oe.el),F&&pe(F,_),(Z=O.props&&O.props.onVnodeUpdated)&&pe(()=>Ce(Z,W,O,Y),_)}else{let O;const{el:$,props:F}=a,{bm:W,m:Y,parent:te}=f,Z=bt(a);if(Qe(f,!1),W&&sn(W),!Z&&(O=F&&F.onVnodeBeforeMount)&&Ce(O,te,a),Qe(f,!0),$&&Pn){const oe=()=>{f.subTree=Vn(f),Pn($,f.subTree,f,_,null)};Z?a.type.__asyncLoader().then(()=>!f.isUnmounted&&oe()):oe()}else{const oe=f.subTree=Vn(f);I(null,oe,p,b,f,_,w),a.el=oe.el}if(Y&&pe(Y,_),!Z&&(O=F&&F.onVnodeMounted)){const oe=a;pe(()=>Ce(O,te,oe),_)}(a.shapeFlag&256||te&&bt(te.vnode)&&te.vnode.shapeFlag&256)&&f.a&&pe(f.a,_),f.isMounted=!0,a=p=b=null}},T=f.effect=new as(x,be,()=>En(y),f.scope),y=f.update=()=>{T.dirty&&T.run()};y.i=f,y.id=f.uid,Qe(f,!0),y()},J=(f,a,p)=>{a.component=f;const b=f.vnode.props;f.vnode=a,f.next=null,El(f,a.props,b,p),Al(f,a.children,p),Xe(),js(f),ze()},N=(f,a,p,b,_,w,R,x,T=!1)=>{const y=f&&f.children,O=f?f.shapeFlag:0,$=a.children,{patchFlag:F,shapeFlag:W}=a;if(F>0){if(F&128){Kt(y,$,p,b,_,w,R,x,T);return}else if(F&256){Pe(y,$,p,b,_,w,R,x,T);return}}W&8?(O&16&&Ct(y,_,w),$!==y&&d(p,$)):O&16?W&16?Kt(y,$,p,b,_,w,R,x,T):Ct(y,_,w,!0):(O&8&&d(p,""),W&16&&k($,p,b,_,w,R,x,T))},Pe=(f,a,p,b,_,w,R,x,T)=>{f=f||ht,a=a||ht;const y=f.length,O=a.length,$=Math.min(y,O);let F;for(F=0;F<$;F++){const W=a[F]=T?De(a[F]):Ee(a[F]);I(f[F],W,p,null,_,w,R,x,T)}y>O?Ct(f,_,w,!0,!1,$):k(a,p,b,_,w,R,x,T,$)},Kt=(f,a,p,b,_,w,R,x,T)=>{let y=0;const O=a.length;let $=f.length-1,F=O-1;for(;y<=$&&y<=F;){const W=f[y],Y=a[y]=T?De(a[y]):Ee(a[y]);if(st(W,Y))I(W,Y,p,null,_,w,R,x,T);else break;y++}for(;y<=$&&y<=F;){const W=f[$],Y=a[F]=T?De(a[F]):Ee(a[F]);if(st(W,Y))I(W,Y,p,null,_,w,R,x,T);else break;$--,F--}if(y>$){if(y<=F){const W=F+1,Y=WF)for(;y<=$;)Me(f[y],_,w,!0),y++;else{const W=y,Y=y,te=new Map;for(y=Y;y<=F;y++){const _e=a[y]=T?De(a[y]):Ee(a[y]);_e.key!=null&&te.set(_e.key,y)}let Z,oe=0;const Se=F-Y+1;let at=!1,As=0;const Et=new Array(Se);for(y=0;y=Se){Me(_e,_,w,!0);continue}let Le;if(_e.key!=null)Le=te.get(_e.key);else for(Z=Y;Z<=F;Z++)if(Et[Z-Y]===0&&st(_e,a[Z])){Le=Z;break}Le===void 0?Me(_e,_,w,!0):(Et[Le-Y]=y+1,Le>=As?As=Le:at=!0,I(_e,a[Le],p,null,_,w,R,x,T),oe++)}const Rs=at?$l(Et):ht;for(Z=Rs.length-1,y=Se-1;y>=0;y--){const _e=Y+y,Le=a[_e],Ms=_e+1{const{el:w,type:R,transition:x,children:T,shapeFlag:y}=f;if(y&6){Ze(f.component.subTree,a,p,b);return}if(y&128){f.suspense.move(a,p,b);return}if(y&64){R.move(f,a,p,ft);return}if(R===ge){s(w,a,p);for(let $=0;$x.enter(w),_);else{const{leave:$,delayLeave:F,afterLeave:W}=x,Y=()=>s(w,a,p),te=()=>{$(w,()=>{Y(),W&&W()})};F?F(w,Y,te):te()}else s(w,a,p)},Me=(f,a,p,b=!1,_=!1)=>{const{type:w,props:R,ref:x,children:T,dynamicChildren:y,shapeFlag:O,patchFlag:$,dirs:F,cacheIndex:W}=f;if($===-2&&(_=!1),x!=null&&gn(x,null,p,f,!0),W!=null&&(a.renderCache[W]=void 0),O&256){a.ctx.deactivate(f);return}const Y=O&1&&F,te=!bt(f);let Z;if(te&&(Z=R&&R.onVnodeBeforeUnmount)&&Ce(Z,a,f),O&6)Qi(f.component,p,b);else{if(O&128){f.suspense.unmount(p,b);return}Y&&Oe(f,null,a,"beforeUnmount"),O&64?f.type.remove(f,a,p,ft,b):y&&!y.hasOnce&&(w!==ge||$>0&&$&64)?Ct(y,a,p,!1,!0):(w===ge&&$&384||!_&&O&16)&&Ct(T,a,p),b&&Ts(f)}(te&&(Z=R&&R.onVnodeUnmounted)||Y)&&pe(()=>{Z&&Ce(Z,a,f),Y&&Oe(f,null,a,"unmounted")},p)},Ts=f=>{const{type:a,el:p,anchor:b,transition:_}=f;if(a===ge){Zi(p,b);return}if(a===Lt){v(f);return}const w=()=>{r(p),_&&!_.persisted&&_.afterLeave&&_.afterLeave()};if(f.shapeFlag&1&&_&&!_.persisted){const{leave:R,delayLeave:x}=_,T=()=>R(p,w);x?x(f.el,w,T):T()}else w()},Zi=(f,a)=>{let p;for(;f!==a;)p=m(f),r(f),f=p;r(a)},Qi=(f,a,p)=>{const{bum:b,scope:_,update:w,subTree:R,um:x,m:T,a:y}=f;Js(T),Js(y),b&&sn(b),_.stop(),w&&(w.active=!1,Me(R,f,a,p)),x&&pe(x,a),pe(()=>{f.isUnmounted=!0},a),a&&a.pendingBranch&&!a.isUnmounted&&f.asyncDep&&!f.asyncResolved&&f.suspenseId===a.pendingId&&(a.deps--,a.deps===0&&a.resolve())},Ct=(f,a,p,b=!1,_=!1,w=0)=>{for(let R=w;R{if(f.shapeFlag&6)return kt(f.component.subTree);if(f.shapeFlag&128)return f.suspense.next();const a=m(f.anchor||f.el),p=a&&a[vi];return p?m(p):a};let On=!1;const Ss=(f,a,p)=>{f==null?a._vnode&&Me(a._vnode,null,null,!0):I(a._vnode||null,f,a,null,null,null,p),On||(On=!0,js(),un(),On=!1),a._vnode=f},ft={p:I,um:Me,m:Ze,r:Ts,mt:ee,mc:k,pc:N,pbc:M,n:kt,o:e};let In,Pn;return t&&([In,Pn]=t(ft)),{render:Ss,hydrate:In,createApp:wl(Ss,In)}}function jn({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function Qe({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function Ti(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function Es(e,t,n=!1){const s=e.children,r=t.children;if(V(s)&&V(r))for(let i=0;i>1,e[n[l]]0&&(t[s]=n[i-1]),n[i]=s)}}for(i=n.length,o=n[i-1];i-- >0;)n[i]=o,o=t[o];return n}function Si(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:Si(t)}function Js(e){if(e)for(let t=0;twt(Hl);function Vl(e,t){return Rn(e,null,t)}function Cf(e,t){return Rn(e,null,{flush:"post"})}const en={};function on(e,t,n){return Rn(e,t,n)}function Rn(e,t,{immediate:n,deep:s,flush:r,once:i,onTrack:o,onTrigger:l}=ne){if(t&&i){const S=t;t=(...j)=>{S(...j),P()}}const c=le,u=S=>s===!0?S:Ke(S,s===!1?1:void 0);let d,h=!1,m=!1;if(ue(e)?(d=()=>e.value,h=vt(e)):mt(e)?(d=()=>u(e),h=!0):V(e)?(m=!0,h=e.some(S=>mt(S)||vt(S)),d=()=>e.map(S=>{if(ue(S))return S.value;if(mt(S))return u(S);if(U(S))return We(S,c,2)})):U(e)?t?d=()=>We(e,c,2):d=()=>(C&&C(),Te(e,c,3,[E])):d=be,t&&s){const S=d;d=()=>Ke(S())}let C,E=S=>{C=g.onStop=()=>{We(S,c,4),C=g.onStop=void 0}},I;if(Dt)if(E=be,t?n&&Te(t,c,3,[d(),m?[]:void 0,E]):d(),r==="sync"){const S=jl();I=S.__watcherHandles||(S.__watcherHandles=[])}else return be;let D=m?new Array(e.length).fill(en):en;const q=()=>{if(!(!g.active||!g.dirty))if(t){const S=g.run();(s||h||(m?S.some((j,k)=>qe(j,D[k])):qe(S,D)))&&(C&&C(),Te(t,c,3,[S,D===en?void 0:m&&D[0]===en?[]:D,E]),D=S)}else g.run()};q.allowRecurse=!!t;let K;r==="sync"?K=q:r==="post"?K=()=>pe(q,c&&c.suspense):(q.pre=!0,c&&(q.id=c.uid),K=()=>En(q));const g=new as(d,be,K),v=mo(),P=()=>{g.stop(),v&&os(v.effects,g)};return t?n?q():D=g.run():r==="post"?pe(g.run.bind(g),c&&c.suspense):g.run(),I&&I.push(P),P}function Ul(e,t,n){const s=this.proxy,r=re(e)?e.includes(".")?Ai(s,e):()=>s[e]:e.bind(s,s);let i;U(t)?i=t:(i=t.handler,n=t);const o=Bt(this),l=Rn(r,i.bind(s),n);return o(),l}function Ai(e,t){const n=t.split(".");return()=>{let s=e;for(let r=0;r{Ke(s,t,n)});else if(Mr(e)){for(const s in e)Ke(e[s],t,n);for(const s of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,s)&&Ke(e[s],t,n)}return e}const Bl=(e,t)=>t==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${Re(t)}Modifiers`]||e[`${Je(t)}Modifiers`];function Dl(e,t,...n){if(e.isUnmounted)return;const s=e.vnode.props||ne;let r=n;const i=t.startsWith("update:"),o=i&&Bl(s,t.slice(7));o&&(o.trim&&(r=n.map(d=>re(d)?d.trim():d)),o.number&&(r=n.map(Wn)));let l,c=s[l=nn(t)]||s[l=nn(Re(t))];!c&&i&&(c=s[l=nn(Je(t))]),c&&Te(c,e,6,r);const u=s[l+"Once"];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,Te(u,e,6,r)}}function Ri(e,t,n=!1){const s=t.emitsCache,r=s.get(e);if(r!==void 0)return r;const i=e.emits;let o={},l=!1;if(!U(e)){const c=u=>{const d=Ri(u,t,!0);d&&(l=!0,fe(o,d))};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}return!i&&!l?(Q(e)&&s.set(e,null),null):(V(i)?i.forEach(c=>o[c]=null):fe(o,i),Q(e)&&s.set(e,o),o)}function Mn(e,t){return!e||!jt(t)?!1:(t=t.slice(2).replace(/Once$/,""),X(e,t[0].toLowerCase()+t.slice(1))||X(e,Je(t))||X(e,t))}function Vn(e){const{type:t,vnode:n,proxy:s,withProxy:r,propsOptions:[i],slots:o,attrs:l,emit:c,render:u,renderCache:d,props:h,data:m,setupState:C,ctx:E,inheritAttrs:I}=e,D=dn(e);let q,K;try{if(n.shapeFlag&4){const v=r||s,P=v;q=Ee(u.call(P,v,d,h,C,m,E)),K=l}else{const v=t;q=Ee(v.length>1?v(h,{attrs:l,slots:o,emit:c}):v(h,null)),K=t.props?l:Kl(l)}}catch(v){Ot.length=0,Vt(v,e,1),q=ie(he)}let g=q;if(K&&I!==!1){const v=Object.keys(K),{shapeFlag:P}=g;v.length&&P&7&&(i&&v.some(is)&&(K=kl(K,i)),g=Ge(g,K,!1,!0))}return n.dirs&&(g=Ge(g,null,!1,!0),g.dirs=g.dirs?g.dirs.concat(n.dirs):n.dirs),n.transition&&(g.transition=n.transition),q=g,dn(D),q}const Kl=e=>{let t;for(const n in e)(n==="class"||n==="style"||jt(n))&&((t||(t={}))[n]=e[n]);return t},kl=(e,t)=>{const n={};for(const s in e)(!is(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function Wl(e,t,n){const{props:s,children:r,component:i}=e,{props:o,children:l,patchFlag:c}=t,u=i.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&c>=0){if(c&1024)return!0;if(c&16)return s?Xs(s,o,u):!!o;if(c&8){const d=t.dynamicProps;for(let h=0;he.__isSuspense;function Mi(e,t){t&&t.pendingBranch?V(e)?t.effects.push(...e):t.effects.push(e):Xo(e)}const ge=Symbol.for("v-fgt"),lt=Symbol.for("v-txt"),he=Symbol.for("v-cmt"),Lt=Symbol.for("v-stc"),Ot=[];let we=null;function Li(e=!1){Ot.push(we=e?null:[])}function Yl(){Ot.pop(),we=Ot[Ot.length-1]||null}let $t=1;function zs(e){$t+=e,e<0&&we&&(we.hasOnce=!0)}function Oi(e){return e.dynamicChildren=$t>0?we||ht:null,Yl(),$t>0&&we&&we.push(e),e}function Ef(e,t,n,s,r,i){return Oi(Fi(e,t,n,s,r,i,!0))}function Ii(e,t,n,s,r){return Oi(ie(e,t,n,s,r,!0))}function mn(e){return e?e.__v_isVNode===!0:!1}function st(e,t){return e.type===t.type&&e.key===t.key}const Pi=({key:e})=>e??null,ln=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?re(e)||ue(e)||U(e)?{i:ce,r:e,k:t,f:!!n}:e:null);function Fi(e,t=null,n=null,s=0,r=null,i=e===ge?0:1,o=!1,l=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Pi(t),ref:t&&ln(t),scopeId:xn,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:i,patchFlag:s,dynamicProps:r,dynamicChildren:null,appContext:null,ctx:ce};return l?(xs(c,n),i&128&&e.normalize(c)):n&&(c.shapeFlag|=re(n)?8:16),$t>0&&!o&&we&&(c.patchFlag>0||i&6)&&c.patchFlag!==32&&we.push(c),c}const ie=Jl;function Jl(e,t=null,n=null,s=0,r=null,i=!1){if((!e||e===li)&&(e=he),mn(e)){const l=Ge(e,t,!0);return n&&xs(l,n),$t>0&&!i&&we&&(l.shapeFlag&6?we[we.indexOf(e)]=l:we.push(l)),l.patchFlag=-2,l}if(ic(e)&&(e=e.__vccOpts),t){t=Xl(t);let{class:l,style:c}=t;l&&!re(l)&&(t.class=fs(l)),Q(c)&&(Gr(c)&&!V(c)&&(c=fe({},c)),t.style=cs(c))}const o=re(e)?1:Gl(e)?128:Rl(e)?64:Q(e)?4:U(e)?2:0;return Fi(e,t,n,s,r,o,i,!0)}function Xl(e){return e?Gr(e)||pi(e)?fe({},e):e:null}function Ge(e,t,n=!1,s=!1){const{props:r,ref:i,patchFlag:o,children:l,transition:c}=e,u=t?zl(r||{},t):r,d={__v_isVNode:!0,__v_skip:!0,type:e.type,props:u,key:u&&Pi(u),ref:t&&t.ref?n&&i?V(i)?i.concat(ln(t)):[i,ln(t)]:ln(t):i,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==ge?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:c,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Ge(e.ssContent),ssFallback:e.ssFallback&&Ge(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return c&&s&&hn(d,c.clone(d)),d}function Ni(e=" ",t=0){return ie(lt,null,e,t)}function xf(e,t){const n=ie(Lt,null,e);return n.staticCount=t,n}function Tf(e="",t=!1){return t?(Li(),Ii(he,null,e)):ie(he,null,e)}function Ee(e){return e==null||typeof e=="boolean"?ie(he):V(e)?ie(ge,null,e.slice()):typeof e=="object"?De(e):ie(lt,null,String(e))}function De(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Ge(e)}function xs(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(V(t))n=16;else if(typeof t=="object")if(s&65){const r=t.default;r&&(r._c&&(r._d=!1),xs(e,r()),r._c&&(r._d=!0));return}else{n=32;const r=t._;!r&&!pi(t)?t._ctx=ce:r===3&&ce&&(ce.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else U(t)?(t={default:t,_ctx:ce},n=32):(t=String(t),s&64?(n=16,t=[Ni(t)]):n=8);e.children=t,e.shapeFlag|=n}function zl(...e){const t={};for(let n=0;nle||ce;let _n,ns;{const e=Or(),t=(n,s)=>{let r;return(r=e[n])||(r=e[n]=[]),r.push(s),i=>{r.length>1?r.forEach(o=>o(i)):r[0](i)}};_n=t("__VUE_INSTANCE_SETTERS__",n=>le=n),ns=t("__VUE_SSR_SETTERS__",n=>Dt=n)}const Bt=e=>{const t=le;return _n(e),e.scope.on(),()=>{e.scope.off(),_n(t)}},Zs=()=>{le&&le.scope.off(),_n(null)};function Hi(e){return e.vnode.shapeFlag&4}let Dt=!1;function tc(e,t=!1,n=!1){t&&ns(t);const{props:s,children:r}=e.vnode,i=Hi(e);Cl(e,s,i,t),Sl(e,r,n);const o=i?nc(e,t):void 0;return t&&ns(!1),o}function nc(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,dl);const{setup:s}=n;if(s){const r=e.setupContext=s.length>1?Vi(e):null,i=Bt(e);Xe();const o=We(s,e,0,[e.props,r]);if(ze(),i(),Ar(o)){if(o.then(Zs,Zs),t)return o.then(l=>{Qs(e,l,t)}).catch(l=>{Vt(l,e,0)});e.asyncDep=o}else Qs(e,o,t)}else ji(e,t)}function Qs(e,t,n){U(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Q(t)&&(e.setupState=Xr(t)),ji(e,n)}let er;function ji(e,t,n){const s=e.type;if(!e.render){if(!t&&er&&!s.render){const r=s.template||vs(e).template;if(r){const{isCustomElement:i,compilerOptions:o}=e.appContext.config,{delimiters:l,compilerOptions:c}=s,u=fe(fe({isCustomElement:i,delimiters:l},o),c);s.render=er(r,u)}}e.render=s.render||be}{const r=Bt(e);Xe();try{pl(e)}finally{ze(),r()}}}const sc={get(e,t){return me(e,"get",""),e[t]}};function Vi(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,sc),slots:e.slots,emit:e.emit,expose:t}}function Ln(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Xr(rn(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in At)return At[n](e)},has(t,n){return n in t||n in At}})):e.proxy}function rc(e,t=!0){return U(e)?e.displayName||e.name:e.name||t&&e.__name}function ic(e){return U(e)&&"__vccOpts"in e}const Ae=(e,t)=>jo(e,t,Dt);function ss(e,t,n){const s=arguments.length;return s===2?Q(t)&&!V(t)?mn(t)?ie(e,null,[t]):ie(e,t):ie(e,null,t):(s>3?n=Array.prototype.slice.call(arguments,2):s===3&&mn(n)&&(n=[n]),ie(e,t,n))}const oc="3.4.35";/** +* @vue/runtime-dom v3.4.35 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/const lc="http://www.w3.org/2000/svg",cc="http://www.w3.org/1998/Math/MathML",Fe=typeof document<"u"?document:null,tr=Fe&&Fe.createElement("template"),fc={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const r=t==="svg"?Fe.createElementNS(lc,e):t==="mathml"?Fe.createElementNS(cc,e):n?Fe.createElement(e,{is:n}):Fe.createElement(e);return e==="select"&&s&&s.multiple!=null&&r.setAttribute("multiple",s.multiple),r},createText:e=>Fe.createTextNode(e),createComment:e=>Fe.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Fe.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,r,i){const o=n?n.previousSibling:t.lastChild;if(r&&(r===i||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),!(r===i||!(r=r.nextSibling)););else{tr.innerHTML=s==="svg"?`${e}`:s==="mathml"?`${e}`:e;const l=tr.content;if(s==="svg"||s==="mathml"){const c=l.firstChild;for(;c.firstChild;)l.appendChild(c.firstChild);l.removeChild(c)}t.insertBefore(l,n)}return[o?o.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},je="transition",xt="animation",Ht=Symbol("_vtc"),Ui=(e,{slots:t})=>ss(tl,ac(e),t);Ui.displayName="Transition";const Bi={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String};Ui.props=fe({},ti,Bi);const et=(e,t=[])=>{V(e)?e.forEach(n=>n(...t)):e&&e(...t)},nr=e=>e?V(e)?e.some(t=>t.length>1):e.length>1:!1;function ac(e){const t={};for(const A in e)A in Bi||(t[A]=e[A]);if(e.css===!1)return t;const{name:n="v",type:s,duration:r,enterFromClass:i=`${n}-enter-from`,enterActiveClass:o=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:c=i,appearActiveClass:u=o,appearToClass:d=l,leaveFromClass:h=`${n}-leave-from`,leaveActiveClass:m=`${n}-leave-active`,leaveToClass:C=`${n}-leave-to`}=e,E=uc(r),I=E&&E[0],D=E&&E[1],{onBeforeEnter:q,onEnter:K,onEnterCancelled:g,onLeave:v,onLeaveCancelled:P,onBeforeAppear:S=q,onAppear:j=K,onAppearCancelled:k=g}=t,L=(A,G,ee)=>{tt(A,G?d:l),tt(A,G?u:o),ee&&ee()},M=(A,G)=>{A._isLeaving=!1,tt(A,h),tt(A,C),tt(A,m),G&&G()},B=A=>(G,ee)=>{const se=A?j:K,H=()=>L(G,A,ee);et(se,[G,H]),sr(()=>{tt(G,A?c:i),Ve(G,A?d:l),nr(se)||rr(G,s,I,H)})};return fe(t,{onBeforeEnter(A){et(q,[A]),Ve(A,i),Ve(A,o)},onBeforeAppear(A){et(S,[A]),Ve(A,c),Ve(A,u)},onEnter:B(!1),onAppear:B(!0),onLeave(A,G){A._isLeaving=!0;const ee=()=>M(A,G);Ve(A,h),Ve(A,m),pc(),sr(()=>{A._isLeaving&&(tt(A,h),Ve(A,C),nr(v)||rr(A,s,D,ee))}),et(v,[A,ee])},onEnterCancelled(A){L(A,!1),et(g,[A])},onAppearCancelled(A){L(A,!0),et(k,[A])},onLeaveCancelled(A){M(A),et(P,[A])}})}function uc(e){if(e==null)return null;if(Q(e))return[Un(e.enter),Un(e.leave)];{const t=Un(e);return[t,t]}}function Un(e){return io(e)}function Ve(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Ht]||(e[Ht]=new Set)).add(t)}function tt(e,t){t.split(/\s+/).forEach(s=>s&&e.classList.remove(s));const n=e[Ht];n&&(n.delete(t),n.size||(e[Ht]=void 0))}function sr(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let dc=0;function rr(e,t,n,s){const r=e._endId=++dc,i=()=>{r===e._endId&&s()};if(n)return setTimeout(i,n);const{type:o,timeout:l,propCount:c}=hc(e,t);if(!o)return s();const u=o+"end";let d=0;const h=()=>{e.removeEventListener(u,m),i()},m=C=>{C.target===e&&++d>=c&&h()};setTimeout(()=>{d(n[E]||"").split(", "),r=s(`${je}Delay`),i=s(`${je}Duration`),o=ir(r,i),l=s(`${xt}Delay`),c=s(`${xt}Duration`),u=ir(l,c);let d=null,h=0,m=0;t===je?o>0&&(d=je,h=o,m=i.length):t===xt?u>0&&(d=xt,h=u,m=c.length):(h=Math.max(o,u),d=h>0?o>u?je:xt:null,m=d?d===je?i.length:c.length:0);const C=d===je&&/\b(transform|all)(,|$)/.test(s(`${je}Property`).toString());return{type:d,timeout:h,propCount:m,hasTransform:C}}function ir(e,t){for(;e.lengthor(n)+or(e[s])))}function or(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function pc(){return document.body.offsetHeight}function gc(e,t,n){const s=e[Ht];s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const lr=Symbol("_vod"),mc=Symbol("_vsh"),_c=Symbol(""),yc=/(^|;)\s*display\s*:/;function bc(e,t,n){const s=e.style,r=re(n);let i=!1;if(n&&!r){if(t)if(re(t))for(const o of t.split(";")){const l=o.slice(0,o.indexOf(":")).trim();n[l]==null&&cn(s,l,"")}else for(const o in t)n[o]==null&&cn(s,o,"");for(const o in n)o==="display"&&(i=!0),cn(s,o,n[o])}else if(r){if(t!==n){const o=s[_c];o&&(n+=";"+o),s.cssText=n,i=yc.test(n)}}else t&&e.removeAttribute("style");lr in e&&(e[lr]=i?s.display:"",e[mc]&&(s.display="none"))}const cr=/\s*!important$/;function cn(e,t,n){if(V(n))n.forEach(s=>cn(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const s=wc(e,t);cr.test(n)?e.setProperty(Je(s),n.replace(cr,""),"important"):e[s]=n}}const fr=["Webkit","Moz","ms"],Bn={};function wc(e,t){const n=Bn[t];if(n)return n;let s=Re(t);if(s!=="filter"&&s in e)return Bn[t]=s;s=wn(s);for(let r=0;rDn||(Tc.then(()=>Dn=0),Dn=Date.now());function Ac(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;Te(Rc(s,n.value),t,5,[s])};return n.value=e,n.attached=Sc(),n}function Rc(e,t){if(V(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(s=>r=>!r._stopped&&s&&s(r))}else return t}const pr=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Mc=(e,t,n,s,r,i)=>{const o=r==="svg";t==="class"?gc(e,s,o):t==="style"?bc(e,n,s):jt(t)?is(t)||Ec(e,t,n,s,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Lc(e,t,s,o))?(vc(e,t,s),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&ur(e,t,s,o,i,t!=="value")):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),ur(e,t,s,o))};function Lc(e,t,n,s){if(s)return!!(t==="innerHTML"||t==="textContent"||t in e&&pr(t)&&U(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const r=e.tagName;if(r==="IMG"||r==="VIDEO"||r==="CANVAS"||r==="SOURCE")return!1}return pr(t)&&re(n)?!1:t in e}const gr=e=>{const t=e.props["onUpdate:modelValue"]||!1;return V(t)?n=>sn(t,n):t};function Oc(e){e.target.composing=!0}function mr(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Kn=Symbol("_assign"),Sf={created(e,{modifiers:{lazy:t,trim:n,number:s}},r){e[Kn]=gr(r);const i=s||r.props&&r.props.type==="number";dt(e,t?"change":"input",o=>{if(o.target.composing)return;let l=e.value;n&&(l=l.trim()),i&&(l=Wn(l)),e[Kn](l)}),n&&dt(e,"change",()=>{e.value=e.value.trim()}),t||(dt(e,"compositionstart",Oc),dt(e,"compositionend",mr),dt(e,"change",mr))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:s,trim:r,number:i}},o){if(e[Kn]=gr(o),e.composing)return;const l=(i||e.type==="number")&&!/^0\d/.test(e.value)?Wn(e.value):e.value,c=t??"";l!==c&&(document.activeElement===e&&e.type!=="range"&&(s&&t===n||r&&e.value.trim()===c)||(e.value=c))}},Ic=["ctrl","shift","alt","meta"],Pc={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>Ic.some(n=>e[`${n}Key`]&&!t.includes(n))},Af=(e,t)=>{const n=e._withMods||(e._withMods={}),s=t.join(".");return n[s]||(n[s]=(r,...i)=>{for(let o=0;o{const n=e._withKeys||(e._withKeys={}),s=t.join(".");return n[s]||(n[s]=r=>{if(!("key"in r))return;const i=Je(r.key);if(t.some(o=>o===i||Fc[o]===i))return e(r)})},Di=fe({patchProp:Mc},fc);let It,_r=!1;function Nc(){return It||(It=Fl(Di))}function $c(){return It=_r?It:Nl(Di),_r=!0,It}const Mf=(...e)=>{const t=Nc().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=ki(s);if(!r)return;const i=t._component;!U(i)&&!i.render&&!i.template&&(i.template=r.innerHTML),r.innerHTML="";const o=n(r,!1,Ki(r));return r instanceof Element&&(r.removeAttribute("v-cloak"),r.setAttribute("data-v-app","")),o},t},Lf=(...e)=>{const t=$c().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=ki(s);if(r)return n(r,!0,Ki(r))},t};function Ki(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function ki(e){return re(e)?document.querySelector(e):e}const Of=(e,t)=>{const n=e.__vccOpts||e;for(const[s,r]of t)n[s]=r;return n},Hc="modulepreload",jc=function(e){return"/"+e},yr={},If=function(t,n,s){if(!n||n.length===0)return t();const r=document.getElementsByTagName("link");return Promise.all(n.map(i=>{if(i=jc(i),i in yr)return;yr[i]=!0;const o=i.endsWith(".css"),l=o?'[rel="stylesheet"]':"";if(!!s)for(let d=r.length-1;d>=0;d--){const h=r[d];if(h.href===i&&(!o||h.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${i}"]${l}`))return;const u=document.createElement("link");if(u.rel=o?"stylesheet":Hc,o||(u.as="script",u.crossOrigin=""),u.href=i,document.head.appendChild(u),o)return new Promise((d,h)=>{u.addEventListener("load",d),u.addEventListener("error",()=>h(new Error(`Unable to preload CSS for ${i}`)))})})).then(()=>t()).catch(i=>{const o=new Event("vite:preloadError",{cancelable:!0});if(o.payload=i,window.dispatchEvent(o),!o.defaultPrevented)throw i})},Vc=window.__VP_SITE_DATA__,Wi=/^[a-z]+:/i,Pf=/^pathname:\/\//,Ff="vitepress-theme-appearance",qi=/#.*$/,Uc=/(index)?\.(md|html)$/,xe=typeof document<"u",Gi={relativePath:"",filePath:"",title:"404",description:"Not Found",headers:[],frontmatter:{sidebar:!1,layout:"page"},lastUpdated:0,isNotFound:!0};function Bc(e,t,n=!1){if(t===void 0)return!1;if(e=br(`/${e}`),n)return new RegExp(t).test(e);if(br(t)!==e)return!1;const s=t.match(qi);return s?(xe?location.hash:"")===s[0]:!0}function br(e){return decodeURI(e).replace(qi,"").replace(Uc,"")}function Dc(e){return Wi.test(e)}function Kc(e,t){var s,r,i,o,l,c,u;const n=Object.keys(e.locales).find(d=>d!=="root"&&!Dc(d)&&Bc(t,`/${d}/`,!0))||"root";return Object.assign({},e,{localeIndex:n,lang:((s=e.locales[n])==null?void 0:s.lang)??e.lang,dir:((r=e.locales[n])==null?void 0:r.dir)??e.dir,title:((i=e.locales[n])==null?void 0:i.title)??e.title,titleTemplate:((o=e.locales[n])==null?void 0:o.titleTemplate)??e.titleTemplate,description:((l=e.locales[n])==null?void 0:l.description)??e.description,head:Ji(e.head,((c=e.locales[n])==null?void 0:c.head)??[]),themeConfig:{...e.themeConfig,...(u=e.locales[n])==null?void 0:u.themeConfig}})}function Yi(e,t){const n=t.title||e.title,s=t.titleTemplate??e.titleTemplate;if(typeof s=="string"&&s.includes(":title"))return s.replace(/:title/g,n);const r=kc(e.title,s);return`${n}${r}`}function kc(e,t){return t===!1?"":t===!0||t===void 0?` | ${e}`:e===t?"":` | ${t}`}function Wc(e,t){const[n,s]=t;if(n!=="meta")return!1;const r=Object.entries(s)[0];return r==null?!1:e.some(([i,o])=>i===n&&o[r[0]]===r[1])}function Ji(e,t){return[...e.filter(n=>!Wc(t,n)),...t]}const qc=/[\u0000-\u001F"#$&*+,:;<=>?[\]^`{|}\u007F]/g,Gc=/^[a-z]:/i;function wr(e){const t=Gc.exec(e),n=t?t[0]:"";return n+e.slice(n.length).replace(qc,"_").replace(/(^|\/)_+(?=[^/]*$)/,"$1")}const Yc=Symbol(),rt=Vo(Vc);function Nf(e){const t=Ae(()=>Kc(rt.value,e.data.relativePath));return{site:t,theme:Ae(()=>t.value.themeConfig),page:Ae(()=>e.data),frontmatter:Ae(()=>e.data.frontmatter),params:Ae(()=>e.data.params),lang:Ae(()=>t.value.lang),dir:Ae(()=>t.value.dir),localeIndex:Ae(()=>t.value.localeIndex||"root"),title:Ae(()=>Yi(t.value,e.data)),description:Ae(()=>e.data.description||t.value.description),isDark:_t(!1)}}function $f(){const e=wt(Yc);if(!e)throw new Error("vitepress data not properly injected in app");return e}function Jc(e,t){return`${e}${t}`.replace(/\/+/g,"/")}function vr(e){return Wi.test(e)||e.startsWith(".")?e:Jc(rt.value.base,e)}function Xc(e){let t=e.replace(/\.html$/,"");if(t=decodeURIComponent(t),t=t.replace(/\/$/,"/index"),xe){const n="/";t=wr(t.slice(n.length).replace(/\//g,"_")||"index")+".md";let s=__VP_HASH_MAP__[t.toLowerCase()];s||(t=t.endsWith("_index.md")?t.slice(0,-9)+".md":t.slice(0,-3)+"_index.md",s=__VP_HASH_MAP__[t.toLowerCase()]),t=`${n}assets/${t}.${s}.js`}else t=`./${wr(t.slice(1).replace(/\//g,"_"))}.md.js`;return t}let fn=[];function Hf(e){fn.push(e),An(()=>{fn=fn.filter(t=>t!==e)})}const zc=Symbol(),Cr="http://a.com",Zc=()=>({path:"/",component:null,data:Gi});function jf(e,t){const n=Cn(Zc()),s={route:n,go:r};async function r(l=xe?location.href:"/"){var u,d;await((u=s.onBeforeRouteChange)==null?void 0:u.call(s,l));const c=new URL(l,Cr);rt.value.cleanUrls||!c.pathname.endsWith("/")&&!c.pathname.endsWith(".html")&&(c.pathname+=".html",l=c.pathname+c.search+c.hash),xe&&l!==location.href&&(history.replaceState({scrollPosition:window.scrollY},document.title),history.pushState(null,"",l)),await o(l),await((d=s.onAfterRouteChanged)==null?void 0:d.call(s,l))}let i=null;async function o(l,c=0,u=!1){const d=new URL(l,Cr),h=i=d.pathname;try{let m=await e(h);if(i===h){i=null;const{default:C,__pageData:E}=m;if(!C)throw new Error(`Invalid route component: ${C}`);n.path=xe?h:vr(h),n.component=rn(C),n.data=rn(E),xe&&Zr(()=>{let I=rt.value.base+E.relativePath.replace(/(?:(^|\/)index)?\.md$/,"$1");if(!rt.value.cleanUrls&&!I.endsWith("/")&&(I+=".html"),I!==d.pathname&&(d.pathname=I,l=I+d.search+d.hash,history.replaceState(null,"",l)),d.hash&&!c){let D=null;try{D=document.querySelector(decodeURIComponent(d.hash))}catch(q){console.warn(q)}if(D){Er(D,d.hash);return}}window.scrollTo(0,c)})}}catch(m){if(!/fetch/.test(m.message)&&!/^\/404(\.html|\/)?$/.test(l)&&console.error(m),!u)try{const C=await fetch(rt.value.base+"hashmap.json");window.__VP_HASH_MAP__=await C.json(),await o(l,c,!0);return}catch{}i===h&&(i=null,n.path=xe?h:vr(h),n.component=t?rn(t):null,n.data=Gi)}}return xe&&(window.addEventListener("click",l=>{if(l.target.closest("button"))return;const u=l.target.closest("a");if(u&&!u.closest(".vp-raw")&&(u instanceof SVGElement||!u.download)){const{target:d}=u,{href:h,origin:m,pathname:C,hash:E,search:I}=new URL(u.href instanceof SVGAnimatedString?u.href.animVal:u.href,u.baseURI),D=window.location,q=C.match(/\.\w+$/);!l.ctrlKey&&!l.shiftKey&&!l.altKey&&!l.metaKey&&d!=="_blank"&&m===D.origin&&!(q&&q[0]!==".html")&&(l.preventDefault(),C===D.pathname&&I===D.search?E&&(E!==D.hash&&(history.pushState(null,"",E),window.dispatchEvent(new Event("hashchange"))),Er(u,E,u.classList.contains("header-anchor"))):r(h))}},{capture:!0}),window.addEventListener("popstate",l=>{o(location.href,l.state&&l.state.scrollPosition||0)}),window.addEventListener("hashchange",l=>{l.preventDefault()})),s}function Qc(){const e=wt(zc);if(!e)throw new Error("useRouter() is called without provider.");return e}function Xi(){return Qc().route}function Er(e,t,n=!1){let s=null;try{s=e.classList.contains("header-anchor")?e:document.querySelector(decodeURIComponent(t))}catch(r){console.warn(r)}if(s){const r=rt.value.scrollOffset;let i=0;if(typeof r=="number")i=r;else if(typeof r=="string")i=xr(r);else if(Array.isArray(r))for(const c of r){const u=xr(c);if(u){i=u;break}}const o=parseInt(window.getComputedStyle(s).paddingTop,10),l=window.scrollY+s.getBoundingClientRect().top-i+o;!n||Math.abs(l-window.scrollY)>window.innerHeight?window.scrollTo(0,l):window.scrollTo({left:0,top:l,behavior:"smooth"})}}function xr(e){const t=document.querySelector(e);if(!t)return 0;const n=t.getBoundingClientRect().bottom;return n<0?0:n+24}const Tr=()=>fn.forEach(e=>e()),Vf=bs({name:"VitePressContent",props:{as:{type:[Object,String],default:"div"}},setup(e){const t=Xi();return()=>ss(e.as,{style:{position:"relative"}},[t.component?ss(t.component,{onVnodeMounted:Tr,onVnodeUpdated:Tr}):"404 Page Not Found"])}});function Uf(e,t){let n=[],s=!0;const r=i=>{if(s){s=!1;return}n.forEach(o=>document.head.removeChild(o)),n=[],i.forEach(o=>{const l=ef(o);document.head.appendChild(l),n.push(l)})};Vl(()=>{const i=e.data,o=t.value,l=i&&i.description,c=i&&i.frontmatter.head||[];document.title=Yi(o,i),document.querySelector("meta[name=description]").setAttribute("content",l||o.description),r(Ji(o.head,nf(c)))})}function ef([e,t,n]){const s=document.createElement(e);for(const r in t)s.setAttribute(r,t[r]);return n&&(s.innerHTML=n),s}function tf(e){return e[0]==="meta"&&e[1]&&e[1].name==="description"}function nf(e){return e.filter(t=>!tf(t))}const kn=new Set,zi=()=>document.createElement("link"),sf=e=>{const t=zi();t.rel="prefetch",t.href=e,document.head.appendChild(t)},rf=e=>{const t=new XMLHttpRequest;t.open("GET",e,t.withCredentials=!0),t.send()};let tn;const of=xe&&(tn=zi())&&tn.relList&&tn.relList.supports&&tn.relList.supports("prefetch")?sf:rf;function Bf(){if(!xe||!window.IntersectionObserver)return;let e;if((e=navigator.connection)&&(e.saveData||/2g/.test(e.effectiveType)))return;const t=window.requestIdleCallback||setTimeout;let n=null;const s=()=>{n&&n.disconnect(),n=new IntersectionObserver(i=>{i.forEach(o=>{if(o.isIntersecting){const l=o.target;n.unobserve(l);const{pathname:c}=l;if(!kn.has(c)){kn.add(c);const u=Xc(c);of(u)}}})}),t(()=>{document.querySelectorAll("#app a").forEach(i=>{const{target:o}=i,{hostname:l,pathname:c}=new URL(i.href instanceof SVGAnimatedString?i.href.animVal:i.href,i.baseURI),u=c.match(/\.\w+$/);u&&u[0]!==".html"||o!=="_blank"&&l===location.hostname&&(c!==location.pathname?n.observe(i):kn.add(c))})})};Sn(s);const r=Xi();on(()=>r.path,s),An(()=>{n&&n.disconnect()})}const Df=bs({setup(e,{slots:t}){const n=_t(!1);return Sn(()=>{n.value=!0}),()=>n.value&&t.default?t.default():null}});function Kf(){if(xe){const e=new Map;window.addEventListener("click",t=>{var s;const n=t.target;if(n.matches('div[class*="language-"] > button.copy')){const r=n.parentElement,i=(s=n.nextElementSibling)==null?void 0:s.nextElementSibling;if(!r||!i)return;const o=/language-(shellscript|shell|bash|sh|zsh)/.test(r.className);let l="";i.querySelectorAll("span.line:not(.diff.remove)").forEach(c=>l+=(c.textContent||"")+` +`),l=l.slice(0,-1),o&&(l=l.replace(/^ *(\$|>) /gm,"").trim()),lf(l).then(()=>{n.classList.add("copied"),clearTimeout(e.get(n));const c=setTimeout(()=>{n.classList.remove("copied"),n.blur(),e.delete(n)},2e3);e.set(n,c)})}})}}async function lf(e){try{return navigator.clipboard.writeText(e)}catch{const t=document.createElement("textarea"),n=document.activeElement;t.value=e,t.setAttribute("readonly",""),t.style.contain="strict",t.style.position="absolute",t.style.left="-9999px",t.style.fontSize="12pt";const s=document.getSelection(),r=s?s.rangeCount>0&&s.getRangeAt(0):null;document.body.appendChild(t),t.select(),t.selectionStart=0,t.selectionEnd=e.length,document.execCommand("copy"),document.body.removeChild(t),r&&(s.removeAllRanges(),s.addRange(r)),n&&n.focus()}}function kf(){xe&&window.addEventListener("click",e=>{var n,s;const t=e.target;if(t.matches(".vp-code-group input")){const r=(n=t.parentElement)==null?void 0:n.parentElement,i=Array.from((r==null?void 0:r.querySelectorAll("input"))||[]).indexOf(t),o=r==null?void 0:r.querySelector('div[class*="language-"].active'),l=(s=r==null?void 0:r.querySelectorAll('div[class*="language-"]:not(.language-id)'))==null?void 0:s[i];o&&l&&o!==l&&(o.classList.remove("active"),l.classList.add("active"))}})}export{Hf as $,Xi as A,An as B,Fi as C,Ii as D,Zo as E,ge as F,Tf as G,gf as H,zl as I,ie as J,cs as K,pf as L,If as M,mf as N,Wi as O,Pf as P,xe as Q,_f as R,uf as S,Ui as T,df as U,xf as V,Ff as W,wt as X,vl as Y,ll as Z,Of as _,Ni as a,Rf as a0,bf as a1,Cf as a2,Af as a3,wf as a4,Uf as a5,zc as a6,Nf as a7,Yc as a8,Vf as a9,Df as aa,rt as ab,Lf as ac,jf as ad,Xc as ae,Bf as af,Kf as ag,kf as ah,ss as ai,Qc as aj,oi as ak,hf as al,Sf as am,vf as an,rn as ao,Mf as ap,Bo as b,Ef as c,bs as d,cf as e,af as f,mo as g,qr as h,ff as i,_t as j,Sn as k,Zr as l,$i as m,fs as n,Li as o,Ae as p,Vl as q,yf as r,ue as s,ho as t,$f as u,Vo as v,on as w,Dc as x,vr as y,Bc as z}; diff --git a/assets/chunks/index.ca03c6e9.js b/assets/chunks/index.ca03c6e9.js new file mode 100644 index 00000000..27e5df81 --- /dev/null +++ b/assets/chunks/index.ca03c6e9.js @@ -0,0 +1,2 @@ +function or(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var oe={exports:{}},ke=function(r,t){return function(){for(var n=new Array(arguments.length),a=0;a"u"}function fr(e){return e!==null&&!F(e)&&e.constructor!==null&&!F(e.constructor)&&typeof e.constructor.isBuffer=="function"&&e.constructor.isBuffer(e)}var Me=A("ArrayBuffer");function lr(e){var r;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?r=ArrayBuffer.isView(e):r=e&&e.buffer&&Me(e.buffer),r}function cr(e){return typeof e=="string"}function dr(e){return typeof e=="number"}function He(e){return e!==null&&typeof e=="object"}function g(e){if(fe(e)!=="object")return!1;var r=Object.getPrototypeOf(e);return r===null||r===Object.prototype}var hr=A("Date"),pr=A("File"),vr=A("Blob"),mr=A("FileList");function ce(e){return ue.call(e)==="[object Function]"}function Er(e){return He(e)&&ce(e.pipe)}function Rr(e){var r="[object FormData]";return e&&(typeof FormData=="function"&&e instanceof FormData||ue.call(e)===r||ce(e.toString)&&e.toString()===r)}var yr=A("URLSearchParams");function wr(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function br(){return typeof navigator<"u"&&(navigator.product==="ReactNative"||navigator.product==="NativeScript"||navigator.product==="NS")?!1:typeof window<"u"&&typeof document<"u"}function de(e,r){if(!(e===null||typeof e>"u"))if(typeof e!="object"&&(e=[e]),le(e))for(var t=0,i=e.length;t0;)a=i[n],s[a]||(r[a]=e[a],s[a]=!0);e=Object.getPrototypeOf(e)}while(e&&(!t||t(e,r))&&e!==Object.prototype);return r}function xr(e,r,t){e=String(e),(t===void 0||t>e.length)&&(t=e.length),t-=r.length;var i=e.indexOf(r,t);return i!==-1&&i===t}function Pr(e){if(!e)return null;var r=e.length;if(F(r))return null;for(var t=new Array(r);r-- >0;)t[r]=e[r];return t}var Tr=function(e){return function(r){return e&&r instanceof e}}(typeof Uint8Array<"u"&&Object.getPrototypeOf(Uint8Array)),v={isArray:le,isArrayBuffer:Me,isBuffer:fr,isFormData:Rr,isArrayBufferView:lr,isString:cr,isNumber:dr,isObject:He,isPlainObject:g,isUndefined:F,isDate:hr,isFile:pr,isBlob:vr,isFunction:ce,isStream:Er,isURLSearchParams:yr,isStandardBrowserEnv:br,forEach:de,merge:se,extend:Or,trim:wr,stripBOM:Ar,inherits:Sr,toFlatObject:Cr,kindOf:fe,kindOfTest:A,endsWith:xr,toArray:Pr,isTypedArray:Tr,isFileList:mr},P=v;function Re(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}var Je=function(r,t,i){if(!t)return r;var n;if(i)n=i(t);else if(P.isURLSearchParams(t))n=t.toString();else{var a=[];P.forEach(t,function(f,d){f===null||typeof f>"u"||(P.isArray(f)?d=d+"[]":f=[f],P.forEach(f,function(h){P.isDate(h)?h=h.toISOString():P.isObject(h)&&(h=JSON.stringify(h)),a.push(Re(d)+"="+Re(h))}))}),n=a.join("&")}if(n){var s=r.indexOf("#");s!==-1&&(r=r.slice(0,s)),r+=(r.indexOf("?")===-1?"?":"&")+n}return r},_r=v;function $(){this.handlers=[]}$.prototype.use=function(r,t,i){return this.handlers.push({fulfilled:r,rejected:t,synchronous:i?i.synchronous:!1,runWhen:i?i.runWhen:null}),this.handlers.length-1};$.prototype.eject=function(r){this.handlers[r]&&(this.handlers[r]=null)};$.prototype.forEach=function(r){_r.forEach(this.handlers,function(i){i!==null&&r(i)})};var Nr=$,Dr=v,Ur=function(r,t){Dr.forEach(r,function(n,a){a!==t&&a.toUpperCase()===t.toUpperCase()&&(r[t]=n,delete r[a])})},Ve=v;function _(e,r,t,i,n){Error.call(this),this.message=e,this.name="AxiosError",r&&(this.code=r),t&&(this.config=t),i&&(this.request=i),n&&(this.response=n)}Ve.inherits(_,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:this.config,code:this.code,status:this.response&&this.response.status?this.response.status:null}}});var We=_.prototype,ze={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED"].forEach(function(e){ze[e]={value:e}});Object.defineProperties(_,ze);Object.defineProperty(We,"isAxiosError",{value:!0});_.from=function(e,r,t,i,n,a){var s=Object.create(We);return Ve.toFlatObject(e,s,function(f){return f!==Error.prototype}),_.call(s,e.message,r,t,i,n),s.name=e.name,a&&Object.assign(s,a),s};var D=_,Xe={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},w=v;function qr(e,r){r=r||new FormData;var t=[];function i(a){return a===null?"":w.isDate(a)?a.toISOString():w.isArrayBuffer(a)||w.isTypedArray(a)?typeof Blob=="function"?new Blob([a]):Buffer.from(a):a}function n(a,s){if(w.isPlainObject(a)||w.isArray(a)){if(t.indexOf(a)!==-1)throw Error("Circular reference detected in "+s);t.push(a),w.forEach(a,function(f,d){if(!w.isUndefined(f)){var c=s?s+"."+d:d,h;if(f&&!s&&typeof f=="object"){if(w.endsWith(d,"{}"))f=JSON.stringify(f);else if(w.endsWith(d,"[]")&&(h=w.toArray(f))){h.forEach(function(u){!w.isUndefined(u)&&r.append(c,i(u))});return}}n(f,c)}}),t.pop()}else r.append(s,i(a))}return n(e),r}var Ke=qr,V,ye;function Br(){if(ye)return V;ye=1;var e=D;return V=function(t,i,n){var a=n.config.validateStatus;!n.status||!a||a(n.status)?t(n):i(new e("Request failed with status code "+n.status,[e.ERR_BAD_REQUEST,e.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))},V}var W,we;function gr(){if(we)return W;we=1;var e=v;return W=e.isStandardBrowserEnv()?function(){return{write:function(i,n,a,s,o,f){var d=[];d.push(i+"="+encodeURIComponent(n)),e.isNumber(a)&&d.push("expires="+new Date(a).toGMTString()),e.isString(s)&&d.push("path="+s),e.isString(o)&&d.push("domain="+o),f===!0&&d.push("secure"),document.cookie=d.join("; ")},read:function(i){var n=document.cookie.match(new RegExp("(^|;\\s*)("+i+")=([^;]*)"));return n?decodeURIComponent(n[3]):null},remove:function(i){this.write(i,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}(),W}var Lr=function(r){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(r)},Fr=function(r,t){return t?r.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):r},$r=Lr,jr=Fr,Qe=function(r,t){return r&&!$r(t)?jr(r,t):t},z,be;function Ir(){if(be)return z;be=1;var e=v,r=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"];return z=function(i){var n={},a,s,o;return i&&e.forEach(i.split(` +`),function(d){if(o=d.indexOf(":"),a=e.trim(d.substr(0,o)).toLowerCase(),s=e.trim(d.substr(o+1)),a){if(n[a]&&r.indexOf(a)>=0)return;a==="set-cookie"?n[a]=(n[a]?n[a]:[]).concat([s]):n[a]=n[a]?n[a]+", "+s:s}}),n},z}var X,Oe;function kr(){if(Oe)return X;Oe=1;var e=v;return X=e.isStandardBrowserEnv()?function(){var t=/(msie|trident)/i.test(navigator.userAgent),i=document.createElement("a"),n;function a(s){var o=s;return t&&(i.setAttribute("href",o),o=i.href),i.setAttribute("href",o),{href:i.href,protocol:i.protocol?i.protocol.replace(/:$/,""):"",host:i.host,search:i.search?i.search.replace(/^\?/,""):"",hash:i.hash?i.hash.replace(/^#/,""):"",hostname:i.hostname,port:i.port,pathname:i.pathname.charAt(0)==="/"?i.pathname:"/"+i.pathname}}return n=a(window.location.href),function(o){var f=e.isString(o)?a(o):o;return f.protocol===n.protocol&&f.host===n.host}}():function(){return function(){return!0}}(),X}var K,Ae;function j(){if(Ae)return K;Ae=1;var e=D,r=v;function t(i){e.call(this,i??"canceled",e.ERR_CANCELED),this.name="CanceledError"}return r.inherits(t,e,{__CANCEL__:!0}),K=t,K}var Q,Se;function Mr(){return Se||(Se=1,Q=function(r){var t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(r);return t&&t[1]||""}),Q}var Y,Ce;function xe(){if(Ce)return Y;Ce=1;var e=v,r=Br(),t=gr(),i=Je,n=Qe,a=Ir(),s=kr(),o=Xe,f=D,d=j(),c=Mr();return Y=function(u){return new Promise(function(nr,S){var U=u.data,q=u.headers,B=u.responseType,C;function ve(){u.cancelToken&&u.cancelToken.unsubscribe(C),u.signal&&u.signal.removeEventListener("abort",C)}e.isFormData(U)&&e.isStandardBrowserEnv()&&delete q["Content-Type"];var l=new XMLHttpRequest;if(u.auth){var ir=u.auth.username||"",ar=u.auth.password?unescape(encodeURIComponent(u.auth.password)):"";q.Authorization="Basic "+btoa(ir+":"+ar)}var M=n(u.baseURL,u.url);l.open(u.method.toUpperCase(),i(M,u.params,u.paramsSerializer),!0),l.timeout=u.timeout;function me(){if(l){var y="getAllResponseHeaders"in l?a(l.getAllResponseHeaders()):null,x=!B||B==="text"||B==="json"?l.responseText:l.response,O={data:x,status:l.status,statusText:l.statusText,headers:y,config:u,request:l};r(function(J){nr(J),ve()},function(J){S(J),ve()},O),l=null}}if("onloadend"in l?l.onloadend=me:l.onreadystatechange=function(){!l||l.readyState!==4||l.status===0&&!(l.responseURL&&l.responseURL.indexOf("file:")===0)||setTimeout(me)},l.onabort=function(){l&&(S(new f("Request aborted",f.ECONNABORTED,u,l)),l=null)},l.onerror=function(){S(new f("Network Error",f.ERR_NETWORK,u,l,l)),l=null},l.ontimeout=function(){var x=u.timeout?"timeout of "+u.timeout+"ms exceeded":"timeout exceeded",O=u.transitional||o;u.timeoutErrorMessage&&(x=u.timeoutErrorMessage),S(new f(x,O.clarifyTimeoutError?f.ETIMEDOUT:f.ECONNABORTED,u,l)),l=null},e.isStandardBrowserEnv()){var Ee=(u.withCredentials||s(M))&&u.xsrfCookieName?t.read(u.xsrfCookieName):void 0;Ee&&(q[u.xsrfHeaderName]=Ee)}"setRequestHeader"in l&&e.forEach(q,function(x,O){typeof U>"u"&&O.toLowerCase()==="content-type"?delete q[O]:l.setRequestHeader(O,x)}),e.isUndefined(u.withCredentials)||(l.withCredentials=!!u.withCredentials),B&&B!=="json"&&(l.responseType=u.responseType),typeof u.onDownloadProgress=="function"&&l.addEventListener("progress",u.onDownloadProgress),typeof u.onUploadProgress=="function"&&l.upload&&l.upload.addEventListener("progress",u.onUploadProgress),(u.cancelToken||u.signal)&&(C=function(y){l&&(S(!y||y&&y.type?new d:y),l.abort(),l=null)},u.cancelToken&&u.cancelToken.subscribe(C),u.signal&&(u.signal.aborted?C():u.signal.addEventListener("abort",C))),U||(U=null);var H=c(M);if(H&&["http","https","file"].indexOf(H)===-1){S(new f("Unsupported protocol "+H+":",f.ERR_BAD_REQUEST,u));return}l.send(U)})},Y}var G,Pe;function Hr(){return Pe||(Pe=1,G=null),G}var p=v,Te=Ur,_e=D,Jr=Xe,Vr=Ke,Wr={"Content-Type":"application/x-www-form-urlencoded"};function Ne(e,r){!p.isUndefined(e)&&p.isUndefined(e["Content-Type"])&&(e["Content-Type"]=r)}function zr(){var e;return(typeof XMLHttpRequest<"u"||typeof process<"u"&&Object.prototype.toString.call(process)==="[object process]")&&(e=xe()),e}function Xr(e,r,t){if(p.isString(e))try{return(r||JSON.parse)(e),p.trim(e)}catch(i){if(i.name!=="SyntaxError")throw i}return(t||JSON.stringify)(e)}var I={transitional:Jr,adapter:zr(),transformRequest:[function(r,t){if(Te(t,"Accept"),Te(t,"Content-Type"),p.isFormData(r)||p.isArrayBuffer(r)||p.isBuffer(r)||p.isStream(r)||p.isFile(r)||p.isBlob(r))return r;if(p.isArrayBufferView(r))return r.buffer;if(p.isURLSearchParams(r))return Ne(t,"application/x-www-form-urlencoded;charset=utf-8"),r.toString();var i=p.isObject(r),n=t&&t["Content-Type"],a;if((a=p.isFileList(r))||i&&n==="multipart/form-data"){var s=this.env&&this.env.FormData;return Vr(a?{"files[]":r}:r,s&&new s)}else if(i||n==="application/json")return Ne(t,"application/json"),Xr(r);return r}],transformResponse:[function(r){var t=this.transitional||I.transitional,i=t&&t.silentJSONParsing,n=t&&t.forcedJSONParsing,a=!i&&this.responseType==="json";if(a||n&&p.isString(r)&&r.length)try{return JSON.parse(r)}catch(s){if(a)throw s.name==="SyntaxError"?_e.from(s,_e.ERR_BAD_RESPONSE,this,null,this.response):s}return r}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:Hr()},validateStatus:function(r){return r>=200&&r<300},headers:{common:{Accept:"application/json, text/plain, */*"}}};p.forEach(["delete","get","head"],function(r){I.headers[r]={}});p.forEach(["post","put","patch"],function(r){I.headers[r]=p.merge(Wr)});var he=I,Kr=v,Qr=he,Yr=function(r,t,i){var n=this||Qr;return Kr.forEach(i,function(s){r=s.call(n,r,t)}),r},Z,De;function Ye(){return De||(De=1,Z=function(r){return!!(r&&r.__CANCEL__)}),Z}var Ue=v,ee=Yr,Gr=Ye(),Zr=he,et=j();function re(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new et}var rt=function(r){re(r),r.headers=r.headers||{},r.data=ee.call(r,r.data,r.headers,r.transformRequest),r.headers=Ue.merge(r.headers.common||{},r.headers[r.method]||{},r.headers),Ue.forEach(["delete","get","head","post","put","patch","common"],function(n){delete r.headers[n]});var t=r.adapter||Zr.adapter;return t(r).then(function(n){return re(r),n.data=ee.call(r,n.data,n.headers,r.transformResponse),n},function(n){return Gr(n)||(re(r),n&&n.response&&(n.response.data=ee.call(r,n.response.data,n.response.headers,r.transformResponse))),Promise.reject(n)})},E=v,Ge=function(r,t){t=t||{};var i={};function n(c,h){return E.isPlainObject(c)&&E.isPlainObject(h)?E.merge(c,h):E.isPlainObject(h)?E.merge({},h):E.isArray(h)?h.slice():h}function a(c){if(E.isUndefined(t[c])){if(!E.isUndefined(r[c]))return n(void 0,r[c])}else return n(r[c],t[c])}function s(c){if(!E.isUndefined(t[c]))return n(void 0,t[c])}function o(c){if(E.isUndefined(t[c])){if(!E.isUndefined(r[c]))return n(void 0,r[c])}else return n(void 0,t[c])}function f(c){if(c in t)return n(r[c],t[c]);if(c in r)return n(void 0,r[c])}var d={url:s,method:s,data:s,baseURL:o,transformRequest:o,transformResponse:o,paramsSerializer:o,timeout:o,timeoutMessage:o,withCredentials:o,adapter:o,responseType:o,xsrfCookieName:o,xsrfHeaderName:o,onUploadProgress:o,onDownloadProgress:o,decompress:o,maxContentLength:o,maxBodyLength:o,beforeRedirect:o,transport:o,httpAgent:o,httpsAgent:o,cancelToken:o,socketPath:o,responseEncoding:o,validateStatus:f};return E.forEach(Object.keys(r).concat(Object.keys(t)),function(h){var u=d[h]||a,R=u(h);E.isUndefined(R)&&u!==f||(i[h]=R)}),i},te,qe;function Ze(){return qe||(qe=1,te={version:"0.27.2"}),te}var tt=Ze().version,b=D,pe={};["object","boolean","number","function","string","symbol"].forEach(function(e,r){pe[e]=function(i){return typeof i===e||"a"+(r<1?"n ":" ")+e}});var Be={};pe.transitional=function(r,t,i){function n(a,s){return"[Axios v"+tt+"] Transitional option '"+a+"'"+s+(i?". "+i:"")}return function(a,s,o){if(r===!1)throw new b(n(s," has been removed"+(t?" in "+t:"")),b.ERR_DEPRECATED);return t&&!Be[s]&&(Be[s]=!0,console.warn(n(s," has been deprecated since v"+t+" and will be removed in the near future"))),r?r(a,s,o):!0}};function nt(e,r,t){if(typeof e!="object")throw new b("options must be an object",b.ERR_BAD_OPTION_VALUE);for(var i=Object.keys(e),n=i.length;n-- >0;){var a=i[n],s=r[a];if(s){var o=e[a],f=o===void 0||s(o,a,e);if(f!==!0)throw new b("option "+a+" must be "+f,b.ERR_BAD_OPTION_VALUE);continue}if(t!==!0)throw new b("Unknown option "+a,b.ERR_BAD_OPTION)}}var it={assertOptions:nt,validators:pe},er=v,at=Je,ge=Nr,Le=rt,k=Ge,st=Qe,rr=it,T=rr.validators;function N(e){this.defaults=e,this.interceptors={request:new ge,response:new ge}}N.prototype.request=function(r,t){typeof r=="string"?(t=t||{},t.url=r):t=r||{},t=k(this.defaults,t),t.method?t.method=t.method.toLowerCase():this.defaults.method?t.method=this.defaults.method.toLowerCase():t.method="get";var i=t.transitional;i!==void 0&&rr.assertOptions(i,{silentJSONParsing:T.transitional(T.boolean),forcedJSONParsing:T.transitional(T.boolean),clarifyTimeoutError:T.transitional(T.boolean)},!1);var n=[],a=!0;this.interceptors.request.forEach(function(R){typeof R.runWhen=="function"&&R.runWhen(t)===!1||(a=a&&R.synchronous,n.unshift(R.fulfilled,R.rejected))});var s=[];this.interceptors.response.forEach(function(R){s.push(R.fulfilled,R.rejected)});var o;if(!a){var f=[Le,void 0];for(Array.prototype.unshift.apply(f,n),f=f.concat(s),o=Promise.resolve(t);f.length;)o=o.then(f.shift(),f.shift());return o}for(var d=t;n.length;){var c=n.shift(),h=n.shift();try{d=c(d)}catch(u){h(u);break}}try{o=Le(d)}catch(u){return Promise.reject(u)}for(;s.length;)o=o.then(s.shift(),s.shift());return o};N.prototype.getUri=function(r){r=k(this.defaults,r);var t=st(r.baseURL,r.url);return at(t,r.params,r.paramsSerializer)};er.forEach(["delete","get","head","options"],function(r){N.prototype[r]=function(t,i){return this.request(k(i||{},{method:r,url:t,data:(i||{}).data}))}});er.forEach(["post","put","patch"],function(r){function t(i){return function(a,s,o){return this.request(k(o||{},{method:r,headers:i?{"Content-Type":"multipart/form-data"}:{},url:a,data:s}))}}N.prototype[r]=t(),N.prototype[r+"Form"]=t(!0)});var ot=N,ne,Fe;function ut(){if(Fe)return ne;Fe=1;var e=j();function r(t){if(typeof t!="function")throw new TypeError("executor must be a function.");var i;this.promise=new Promise(function(s){i=s});var n=this;this.promise.then(function(a){if(n._listeners){var s,o=n._listeners.length;for(s=0;s(a(),l("span",{class:B(["VPBadge",e.type??"tip"])},[d(e.$slots,"default",{},()=>[x(A(e.text),1)],!0)],2))}});const Ft=m(Ot,[["__scopeId","data-v-350d3852"]]),C=wt;function Be(t){return Pt()?(Vt(t),!0):!1}function F(t){return typeof t=="function"?t():i(t)}const st=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const Gt=Object.prototype.toString,jt=t=>Gt.call(t)==="[object Object]",re=()=>{},Ke=Wt();function Wt(){var t,e;return st&&((t=window==null?void 0:window.navigator)==null?void 0:t.userAgent)&&(/iP(?:ad|hone|od)/.test(window.navigator.userAgent)||((e=window==null?void 0:window.navigator)==null?void 0:e.maxTouchPoints)>2&&/iPad|Macintosh/.test(window==null?void 0:window.navigator.userAgent))}function Rt(t,e){function n(...o){return new Promise((s,r)=>{Promise.resolve(t(()=>e.apply(this,o),{fn:e,thisArg:this,args:o})).then(s).catch(r)})}return n}const at=t=>t();function Ut(t,e={}){let n,o,s=re;const r=v=>{clearTimeout(v),s(),s=re};return v=>{const u=F(t),f=F(e.maxWait);return n&&r(n),u<=0||f!==void 0&&f<=0?(o&&(r(o),o=null),Promise.resolve(v())):new Promise(($,P)=>{s=e.rejectOnCancel?P:$,f&&!o&&(o=setTimeout(()=>{n&&r(n),o=null,$(v())},f)),n=setTimeout(()=>{o&&r(o),o=null,$(v())},u)})}}function qt(t=at){const e=L(!0);function n(){e.value=!1}function o(){e.value=!0}const s=(...r)=>{e.value&&t(...r)};return{isActive:Me(e),pause:n,resume:o,eventFilter:s}}function Kt(t){return t||et()}function Yt(...t){if(t.length!==1)return St(...t);const e=t[0];return typeof e=="function"?Me(Lt(()=>({get:e,set:re}))):L(e)}function rt(t,e,n={}){const{eventFilter:o=at,...s}=n;return K(t,Rt(o,e),s)}function Xt(t,e,n={}){const{eventFilter:o,...s}=n,{eventFilter:r,pause:c,resume:v,isActive:u}=qt(o);return{stop:rt(t,e,{...s,eventFilter:r}),pause:c,resume:v,isActive:u}}function Jt(t,e=!0,n){Kt()?W(t,n):e?t():Ce(t)}function $l(t,e,n={}){const{debounce:o=0,maxWait:s=void 0,...r}=n;return rt(t,e,{...r,eventFilter:Ut(o,{maxWait:s})})}function kl(t,e,n){let o;Mt(n)?o={evaluating:n}:o=n||{};const{lazy:s=!1,evaluating:r=void 0,shallow:c=!0,onError:v=re}=o,u=L(!s),f=c?ce(e):L(e);let $=0;return ee(async P=>{if(!u.value)return;$++;const M=$;let y=!1;r&&Promise.resolve().then(()=>{r.value=!0});try{const S=await t(T=>{P(()=>{r&&(r.value=!1),y||T()})});M===$&&(f.value=S)}catch(S){v(S)}finally{r&&M===$&&(r.value=!1),y=!0}}),s?k(()=>(u.value=!0,f.value)):f}function Qt(t){var e;const n=F(t);return(e=n==null?void 0:n.$el)!=null?e:n}const q=st?window:void 0;function ie(...t){let e,n,o,s;if(typeof t[0]=="string"||Array.isArray(t[0])?([n,o,s]=t,e=q):[e,n,o,s]=t,!e)return re;Array.isArray(n)||(n=[n]),Array.isArray(o)||(o=[o]);const r=[],c=()=>{r.forEach($=>$()),r.length=0},v=($,P,M,y)=>($.addEventListener(P,M,y),()=>$.removeEventListener(P,M,y)),u=K(()=>[Qt(e),F(s)],([$,P])=>{if(c(),!$)return;const M=jt(P)?{...P}:P;r.push(...n.flatMap(y=>o.map(S=>v($,y,S,M))))},{immediate:!0,flush:"post"}),f=()=>{u(),c()};return Be(f),f}function Zt(t){return typeof t=="function"?t:typeof t=="string"?e=>e.key===t:Array.isArray(t)?e=>t.includes(e.key):()=>!0}function Ye(...t){let e,n,o={};t.length===3?(e=t[0],n=t[1],o=t[2]):t.length===2?typeof t[1]=="object"?(e=!0,n=t[0],o=t[1]):(e=t[0],n=t[1]):(e=!0,n=t[0]);const{target:s=q,eventName:r="keydown",passive:c=!1,dedupe:v=!1}=o,u=Zt(e);return ie(s,r,$=>{$.repeat&&F(v)||u($)&&n($)},c)}function en(){const t=L(!1),e=et();return e&&W(()=>{t.value=!0},e),t}function tn(t){const e=en();return k(()=>(e.value,!!t()))}function Ve(t,e={}){const{window:n=q}=e,o=tn(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function");let s;const r=L(!1),c=f=>{r.value=f.matches},v=()=>{s&&("removeEventListener"in s?s.removeEventListener("change",c):s.removeListener(c))},u=ee(()=>{o.value&&(v(),s=n.matchMedia(F(t)),"addEventListener"in s?s.addEventListener("change",c):s.addListener(c),r.value=s.matches)});return Be(()=>{u(),v(),s=void 0}),r}const ve=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},pe="__vueuse_ssr_handlers__",nn=on();function on(){return pe in ve||(ve[pe]=ve[pe]||{}),ve[pe]}function sn(t,e){return nn[t]||e}function an(t){return t==null?"any":t instanceof Set?"set":t instanceof Map?"map":t instanceof Date?"date":typeof t=="boolean"?"boolean":typeof t=="string"?"string":typeof t=="object"?"object":Number.isNaN(t)?"any":"number"}const rn={boolean:{read:t=>t==="true",write:t=>String(t)},object:{read:t=>JSON.parse(t),write:t=>JSON.stringify(t)},number:{read:t=>Number.parseFloat(t),write:t=>String(t)},any:{read:t=>t,write:t=>String(t)},string:{read:t=>t,write:t=>String(t)},map:{read:t=>new Map(JSON.parse(t)),write:t=>JSON.stringify(Array.from(t.entries()))},set:{read:t=>new Set(JSON.parse(t)),write:t=>JSON.stringify(Array.from(t))},date:{read:t=>new Date(t),write:t=>t.toISOString()}},Xe="vueuse-storage";function it(t,e,n,o={}){var s;const{flush:r="pre",deep:c=!0,listenToStorageChanges:v=!0,writeDefaults:u=!0,mergeDefaults:f=!1,shallow:$,window:P=q,eventFilter:M,onError:y=N=>{console.error(N)},initOnMounted:S}=o,T=($?ce:L)(typeof e=="function"?e():e);if(!n)try{n=sn("getDefaultStorage",()=>{var N;return(N=q)==null?void 0:N.localStorage})()}catch(N){y(N)}if(!n)return T;const V=F(e),E=an(V),z=(s=o.serializer)!=null?s:rn[E],{pause:O,resume:ne}=Xt(T,()=>bt(T.value),{flush:r,deep:c,eventFilter:M});P&&v&&Jt(()=>{ie(P,"storage",_e),ie(P,Xe,kt),S&&_e()}),S||_e();function Ue(N,H){P&&P.dispatchEvent(new CustomEvent(Xe,{detail:{key:t,oldValue:N,newValue:H,storageArea:n}}))}function bt(N){try{const H=n.getItem(t);if(N==null)Ue(H,null),n.removeItem(t);else{const U=z.write(N);H!==U&&(n.setItem(t,U),Ue(H,U))}}catch(H){y(H)}}function $t(N){const H=N?N.newValue:n.getItem(t);if(H==null)return u&&V!=null&&n.setItem(t,z.write(V)),V;if(!N&&f){const U=z.read(H);return typeof f=="function"?f(U,V):E==="object"&&!Array.isArray(U)?{...V,...U}:U}else return typeof H!="string"?H:z.read(H)}function _e(N){if(!(N&&N.storageArea!==n)){if(N&&N.key==null){T.value=V;return}if(!(N&&N.key!==t)){O();try{(N==null?void 0:N.newValue)!==z.write(T.value)&&(T.value=$t(N))}catch(H){y(H)}finally{N?Ce(ne):ne()}}}}function kt(N){_e(N.detail)}return T}function ke(t){return typeof Window<"u"&&t instanceof Window?t.document.documentElement:typeof Document<"u"&&t instanceof Document?t.documentElement:t}function wl(t,e,n={}){const{window:o=q}=n;return it(t,e,o==null?void 0:o.localStorage,n)}function lt(t){const e=window.getComputedStyle(t);if(e.overflowX==="scroll"||e.overflowY==="scroll"||e.overflowX==="auto"&&t.clientWidth1?!0:(e.preventDefault&&e.preventDefault(),!1)}const we=new WeakMap;function Pl(t,e=!1){const n=L(e);let o=null,s="";K(Yt(t),v=>{const u=ke(F(v));if(u){const f=u;if(we.get(f)||we.set(f,f.style.overflow),f.style.overflow!=="hidden"&&(s=f.style.overflow),f.style.overflow==="hidden")return n.value=!0;if(n.value)return f.style.overflow="hidden"}},{immediate:!0});const r=()=>{const v=ke(F(t));!v||n.value||(Ke&&(o=ie(v,"touchmove",u=>{ln(u)},{passive:!1})),v.style.overflow="hidden",n.value=!0)},c=()=>{const v=ke(F(t));!v||!n.value||(Ke&&(o==null||o()),v.style.overflow=s,we.delete(v),n.value=!1)};return Be(c),k({get(){return n.value},set(v){v?r():c()}})}function Vl(t,e,n={}){const{window:o=q}=n;return it(t,e,o==null?void 0:o.sessionStorage,n)}function ct(t={}){const{window:e=q,behavior:n="auto"}=t;if(!e)return{x:L(0),y:L(0)};const o=L(e.scrollX),s=L(e.scrollY),r=k({get(){return o.value},set(v){scrollTo({left:v,behavior:n})}}),c=k({get(){return s.value},set(v){scrollTo({top:v,behavior:n})}});return ie(e,"scroll",()=>{o.value=e.scrollX,s.value=e.scrollY},{capture:!1,passive:!0}),{x:r,y:c}}function cn(t,e){let n,o=!1;return()=>{n&&clearTimeout(n),o?n=setTimeout(t,e):(t(),o=!0,setTimeout(()=>{o=!1},e))}}function Se(t){return/^\//.test(t)?t:`/${t}`}function le(t){if(Ct(t))return t.replace(Tt,"");const{site:e}=C(),{pathname:n,search:o,hash:s}=new URL(t,"http://example.com"),r=n.endsWith("/")||n.endsWith(".html")?t:t.replace(/(?:(^\.+)\/)?.*$/,`$1${n.replace(/(\.md)?$/,e.value.cleanUrls?"":".html")}${o}${s}`);return Te(r)}function ut(t,e){if(Array.isArray(t))return t;if(t==null)return[];e=Se(e);const n=Object.keys(t).sort((o,s)=>s.split("/").length-o.split("/").length).find(o=>e.startsWith(Se(o)));return n?t[n]:[]}function un(t){const e=[];let n=0;for(const o in t){const s=t[o];if(s.items){n=e.push(s);continue}e[n]||e.push({items:[]}),e[n].items.push(s)}return e}function dn(t){const e=[];function n(o){for(const s of o)s.text&&s.link&&e.push({text:s.text,link:s.link}),s.items&&n(s.items)}return n(t),e}function Le(t,e){return Array.isArray(e)?e.some(n=>Le(t,n)):te(t,e.link)?!0:e.items?Le(t,e.items):!1}function R(){const t=ue(),{theme:e,frontmatter:n}=C(),o=Ve("(min-width: 960px)"),s=L(!1),r=k(()=>{const S=e.value.sidebar,T=t.data.relativePath;return S?ut(S,T):[]}),c=k(()=>n.value.sidebar!==!1&&r.value.length>0&&n.value.layout!=="home"),v=k(()=>u?n.value.aside==null?e.value.aside==="left":n.value.aside==="left":!1),u=k(()=>n.value.layout==="home"?!1:n.value.aside!=null?!!n.value.aside:e.value.aside!==!1),f=k(()=>c.value&&o.value),$=k(()=>c.value?un(r.value):[]);function P(){s.value=!0}function M(){s.value=!1}function y(){s.value?M():P()}return{isOpen:s,sidebar:r,sidebarGroups:$,hasSidebar:c,hasAside:u,leftAside:v,isSidebarEnabled:f,open:P,close:M,toggle:y}}function _n(t,e){let n;ee(()=>{n=t.value?document.activeElement:void 0}),W(()=>{window.addEventListener("keyup",o)}),Ae(()=>{window.removeEventListener("keyup",o)});function o(s){s.key==="Escape"&&t.value&&(e(),n==null||n.focus())}}function vn(t){const{page:e}=C(),n=L(!1),o=k(()=>t.value.collapsed!=null),s=k(()=>!!t.value.link),r=k(()=>te(e.value.relativePath,t.value.link)),c=k(()=>r.value?!0:t.value.items?Le(e.value.relativePath,t.value.items):!1),v=k(()=>!!(t.value.items&&t.value.items.length));ee(()=>{n.value=!!(o.value&&t.value.collapsed)}),ee(()=>{(r.value||c.value)&&(n.value=!1)});function u(){o.value&&(n.value=!n.value)}return{collapsed:n,collapsible:o,isLink:s,isActiveLink:r,hasActiveLink:c,hasChildren:v,toggle:u}}const pn=b({__name:"VPSkipLink",setup(t){const e=ue(),n=L();K(()=>e.path,()=>n.value.focus());function o({target:s}){const r=document.querySelector(decodeURIComponent(s.hash));if(r){const c=()=>{r.removeAttribute("tabindex"),r.removeEventListener("blur",c)};r.setAttribute("tabindex","-1"),r.addEventListener("blur",c),r.focus(),window.scrollTo(0,0)}}return(s,r)=>(a(),l(I,null,[_("span",{ref_key:"backToTop",ref:n,tabindex:"-1"},null,512),_("a",{href:"#VPContent",class:"VPSkipLink visually-hidden",onClick:o}," Skip to content ")],64))}});const fn=m(pn,[["__scopeId","data-v-b8b11faa"]]),hn={key:0,class:"VPBackdrop"},mn=b({__name:"VPBackdrop",props:{show:{type:Boolean}},setup(t){return(e,n)=>(a(),w(Ne,{name:"fade"},{default:p(()=>[e.show?(a(),l("div",hn)):g("",!0)]),_:1}))}});const gn=m(mn,[["__scopeId","data-v-c79a1216"]]);function yn(){const t=L(!1);function e(){t.value=!0,window.addEventListener("resize",s)}function n(){t.value=!1,window.removeEventListener("resize",s)}function o(){t.value?n():e()}function s(){window.outerWidth>=768&&n()}const r=ue();return K(()=>r.path,n),{isScreenOpen:t,openScreen:e,closeScreen:n,toggleScreen:o}}function de({removeCurrent:t=!0,correspondingLink:e=!1}={}){const{site:n,localeIndex:o,page:s,theme:r}=C(),c=k(()=>{var u,f;return{label:(u=n.value.locales[o.value])==null?void 0:u.label,link:((f=n.value.locales[o.value])==null?void 0:f.link)||(o.value==="root"?"/":`/${o.value}/`)}});return{localeLinks:k(()=>Object.entries(n.value.locales).flatMap(([u,f])=>t&&c.value.label===f.label?[]:{text:f.label,link:bn(f.link||(u==="root"?"/":`/${u}/`),r.value.i18nRouting!==!1&&e,s.value.relativePath.slice(c.value.link.length-1),!n.value.cleanUrls)})),currentLang:c}}function bn(t,e,n,o){return e?t.replace(/\/$/,"")+Se(n.replace(/(^|\/)?index.md$/,"$1").replace(/\.md$/,o?".html":"")):t}const $n=["src","alt"],kn={inheritAttrs:!1},wn=b({...kn,__name:"VPImage",props:{image:{},alt:{}},setup(t){return(e,n)=>{const o=J("VPImage",!0);return e.image?(a(),l(I,{key:0},[typeof e.image=="string"||"src"in e.image?(a(),l("img",fe({key:0,class:"VPImage"},typeof e.image=="string"?e.$attrs:{...e.image,...e.$attrs},{src:i(Te)(typeof e.image=="string"?e.image:e.image.src),alt:e.alt??(typeof e.image=="string"?"":e.image.alt||"")}),null,16,$n)):(a(),l(I,{key:1},[h(o,fe({class:"dark",image:e.image.dark,alt:e.image.alt},e.$attrs),null,16,["image","alt"]),h(o,fe({class:"light",image:e.image.light,alt:e.image.alt},e.$attrs),null,16,["image","alt"])],64))],64)):g("",!0)}}});const xe=m(wn,[["__scopeId","data-v-6db2186b"]]),Pn=["href"],Vn=b({__name:"VPNavBarTitle",setup(t){const{site:e,theme:n}=C(),{hasSidebar:o}=R(),{currentLang:s}=de();return(r,c)=>(a(),l("div",{class:B(["VPNavBarTitle",{"has-sidebar":i(o)}])},[_("a",{class:"title",href:i(le)(i(s).link)},[d(r.$slots,"nav-bar-title-before",{},void 0,!0),i(n).logo?(a(),w(xe,{key:0,class:"logo",image:i(n).logo},null,8,["image"])):g("",!0),i(n).siteTitle?(a(),l(I,{key:1},[x(A(i(n).siteTitle),1)],64)):i(n).siteTitle===void 0?(a(),l(I,{key:2},[x(A(i(e).title),1)],64)):g("",!0),d(r.$slots,"nav-bar-title-after",{},void 0,!0)],8,Pn)],2))}});const Sn=m(Vn,[["__scopeId","data-v-4d981103"]]);const Ln={type:"button",class:"DocSearch DocSearch-Button","aria-label":"Search"},Mn={class:"DocSearch-Button-Container"},Cn=_("svg",{class:"DocSearch-Search-Icon",width:"20",height:"20",viewBox:"0 0 20 20","aria-label":"search icon"},[_("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none","fill-rule":"evenodd","stroke-linecap":"round","stroke-linejoin":"round"})],-1),Tn={class:"DocSearch-Button-Placeholder"},An=_("span",{class:"DocSearch-Button-Keys"},[_("kbd",{class:"DocSearch-Button-Key"}),_("kbd",{class:"DocSearch-Button-Key"},"K")],-1),Je=b({__name:"VPNavBarSearchButton",props:{placeholder:{}},setup(t){return(e,n)=>(a(),l("button",Ln,[_("span",Mn,[Cn,_("span",Tn,A(e.placeholder),1)]),An]))}});const Nn={id:"local-search"},In={key:1,id:"docsearch"},Bn=b({__name:"VPNavBarSearch",setup(t){const e=At(()=>Nt(()=>import("./VPLocalSearchBox.61311459.js"),["assets/chunks/VPLocalSearchBox.61311459.js","assets/chunks/framework.63f12d77.js"])),n=()=>null,{theme:o,localeIndex:s}=C(),r=L(!1),c=k(()=>{var S,T,V,E,z,O,ne;const y=((S=o.value.search)==null?void 0:S.options)??o.value.algolia;return((z=(E=(V=(T=y==null?void 0:y.locales)==null?void 0:T[s.value])==null?void 0:V.translations)==null?void 0:E.button)==null?void 0:z.buttonText)||((ne=(O=y==null?void 0:y.translations)==null?void 0:O.button)==null?void 0:ne.buttonText)||"Search"});W(()=>{});function v(){r.value||(r.value=!0,setTimeout(u,16))}function u(){const y=new Event("keydown");y.key="k",y.metaKey=!0,window.dispatchEvent(y),setTimeout(()=>{document.querySelector(".DocSearch-Modal")||u()},16)}function f(y){const S=y.target,T=S.tagName;return S.isContentEditable||T==="INPUT"||T==="SELECT"||T==="TEXTAREA"}const $=L(!1);Ye("k",y=>{(y.ctrlKey||y.metaKey)&&(y.preventDefault(),$.value=!0)}),Ye("/",y=>{f(y)||(y.preventDefault(),$.value=!0)});const P=L("'Meta'");W(()=>{P.value=/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?"'⌘'":"'Ctrl'"});const M="local";return(y,S)=>{var T;return a(),l("div",{class:"VPNavBarSearch",style:tt({"--vp-meta-key":P.value})},[i(M)==="local"?(a(),l(I,{key:0},[$.value?(a(),w(i(e),{key:0,placeholder:c.value,onClose:S[0]||(S[0]=V=>$.value=!1)},null,8,["placeholder"])):g("",!0),_("div",Nn,[h(Je,{placeholder:c.value,onClick:S[1]||(S[1]=V=>$.value=!0)},null,8,["placeholder"])])],64)):i(M)==="algolia"?(a(),l(I,{key:1},[r.value?(a(),w(i(n),{key:0,algolia:((T=i(o).search)==null?void 0:T.options)??i(o).algolia},null,8,["algolia"])):(a(),l("div",In,[h(Je,{placeholder:c.value,onClick:v},null,8,["placeholder"])]))],64)):g("",!0)],4)}}});const xn={},En={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",height:"24px",viewBox:"0 0 24 24",width:"24px"},Hn=_("path",{d:"M0 0h24v24H0V0z",fill:"none"},null,-1),Dn=_("path",{d:"M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5H9z"},null,-1),zn=[Hn,Dn];function On(t,e){return a(),l("svg",En,zn)}const Fn=m(xn,[["render",On]]),Gn=b({__name:"VPLink",props:{tag:{},href:{},noIcon:{type:Boolean},target:{},rel:{}},setup(t){const e=t,n=k(()=>e.tag??e.href?"a":"span"),o=k(()=>e.href&&nt.test(e.href));return(s,r)=>(a(),w(Q(n.value),{class:B(["VPLink",{link:s.href}]),href:s.href?i(le)(s.href):void 0,target:s.target||(o.value?"_blank":void 0),rel:s.rel||(o.value?"noreferrer":void 0)},{default:p(()=>[d(s.$slots,"default",{},void 0,!0),o.value&&!s.noIcon?(a(),w(Fn,{key:0,class:"icon"})):g("",!0)]),_:3},8,["class","href","target","rel"]))}});const Y=m(Gn,[["__scopeId","data-v-8f4dc553"]]),jn=b({__name:"VPNavBarMenuLink",props:{item:{}},setup(t){const{page:e}=C();return(n,o)=>(a(),w(Y,{class:B({VPNavBarMenuLink:!0,active:i(te)(i(e).relativePath,n.item.activeMatch||n.item.link,!!n.item.activeMatch)}),href:n.item.link,target:n.item.target,rel:n.item.rel,tabindex:"0"},{default:p(()=>[x(A(n.item.text),1)]),_:1},8,["class","href","target","rel"]))}});const Wn=m(jn,[["__scopeId","data-v-5e623618"]]),Ee=L();let dt=!1,Pe=0;function Rn(t){const e=L(!1);if(ot){!dt&&Un(),Pe++;const n=K(Ee,o=>{var s,r,c;o===t.el.value||(s=t.el.value)!=null&&s.contains(o)?(e.value=!0,(r=t.onFocus)==null||r.call(t)):(e.value=!1,(c=t.onBlur)==null||c.call(t))});Ae(()=>{n(),Pe--,Pe||qn()})}return Me(e)}function Un(){document.addEventListener("focusin",_t),dt=!0,Ee.value=document.activeElement}function qn(){document.removeEventListener("focusin",_t)}function _t(){Ee.value=document.activeElement}const Kn={},Yn={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24"},Xn=_("path",{d:"M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"},null,-1),Jn=[Xn];function Qn(t,e){return a(),l("svg",Yn,Jn)}const vt=m(Kn,[["render",Qn]]),Zn={},eo={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24"},to=_("circle",{cx:"12",cy:"12",r:"2"},null,-1),no=_("circle",{cx:"19",cy:"12",r:"2"},null,-1),oo=_("circle",{cx:"5",cy:"12",r:"2"},null,-1),so=[to,no,oo];function ao(t,e){return a(),l("svg",eo,so)}const ro=m(Zn,[["render",ao]]),io={class:"VPMenuLink"},lo=b({__name:"VPMenuLink",props:{item:{}},setup(t){const{page:e}=C();return(n,o)=>(a(),l("div",io,[h(Y,{class:B({active:i(te)(i(e).relativePath,n.item.activeMatch||n.item.link,!!n.item.activeMatch)}),href:n.item.link,target:n.item.target,rel:n.item.rel},{default:p(()=>[x(A(n.item.text),1)]),_:1},8,["class","href","target","rel"])]))}});const be=m(lo,[["__scopeId","data-v-2f2cfafc"]]),co={class:"VPMenuGroup"},uo={key:0,class:"title"},_o=b({__name:"VPMenuGroup",props:{text:{},items:{}},setup(t){return(e,n)=>(a(),l("div",co,[e.text?(a(),l("p",uo,A(e.text),1)):g("",!0),(a(!0),l(I,null,D(e.items,o=>(a(),l(I,null,["link"in o?(a(),w(be,{key:0,item:o},null,8,["item"])):g("",!0)],64))),256))]))}});const vo=m(_o,[["__scopeId","data-v-69e747b5"]]),po={class:"VPMenu"},fo={key:0,class:"items"},ho=b({__name:"VPMenu",props:{items:{}},setup(t){return(e,n)=>(a(),l("div",po,[e.items?(a(),l("div",fo,[(a(!0),l(I,null,D(e.items,o=>(a(),l(I,{key:o.text},["link"in o?(a(),w(be,{key:0,item:o},null,8,["item"])):(a(),w(vo,{key:1,text:o.text,items:o.items},null,8,["text","items"]))],64))),128))])):g("",!0),d(e.$slots,"default",{},void 0,!0)]))}});const mo=m(ho,[["__scopeId","data-v-e7ea1737"]]),go=["aria-expanded","aria-label"],yo={key:0,class:"text"},bo={class:"menu"},$o=b({__name:"VPFlyout",props:{icon:{},button:{},label:{},items:{}},setup(t){const e=L(!1),n=L();Rn({el:n,onBlur:o});function o(){e.value=!1}return(s,r)=>(a(),l("div",{class:"VPFlyout",ref_key:"el",ref:n,onMouseenter:r[1]||(r[1]=c=>e.value=!0),onMouseleave:r[2]||(r[2]=c=>e.value=!1)},[_("button",{type:"button",class:"button","aria-haspopup":"true","aria-expanded":e.value,"aria-label":s.label,onClick:r[0]||(r[0]=c=>e.value=!e.value)},[s.button||s.icon?(a(),l("span",yo,[s.icon?(a(),w(Q(s.icon),{key:0,class:"option-icon"})):g("",!0),x(" "+A(s.button)+" ",1),h(vt,{class:"text-icon"})])):(a(),w(ro,{key:1,class:"icon"}))],8,go),_("div",bo,[h(mo,{items:s.items},{default:p(()=>[d(s.$slots,"default",{},void 0,!0)]),_:3},8,["items"])])],544))}});const He=m($o,[["__scopeId","data-v-764effdf"]]),ko=b({__name:"VPNavBarMenuGroup",props:{item:{}},setup(t){const{page:e}=C();return(n,o)=>(a(),w(He,{class:B({VPNavBarMenuGroup:!0,active:i(te)(i(e).relativePath,n.item.activeMatch,!!n.item.activeMatch)}),button:n.item.text,items:n.item.items},null,8,["class","button","items"]))}}),wo=t=>(G("data-v-7f418b0f"),t=t(),j(),t),Po={key:0,"aria-labelledby":"main-nav-aria-label",class:"VPNavBarMenu"},Vo=wo(()=>_("span",{id:"main-nav-aria-label",class:"visually-hidden"},"Main Navigation",-1)),So=b({__name:"VPNavBarMenu",setup(t){const{theme:e}=C();return(n,o)=>i(e).nav?(a(),l("nav",Po,[Vo,(a(!0),l(I,null,D(i(e).nav,s=>(a(),l(I,{key:s.text},["link"in s?(a(),w(Wn,{key:0,item:s},null,8,["item"])):(a(),w(ko,{key:1,item:s},null,8,["item"]))],64))),128))])):g("",!0)}});const Lo=m(So,[["__scopeId","data-v-7f418b0f"]]),Mo={},Co={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24"},To=_("path",{d:"M0 0h24v24H0z",fill:"none"},null,-1),Ao=_("path",{d:" M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z ",class:"css-c4d79v"},null,-1),No=[To,Ao];function Io(t,e){return a(),l("svg",Co,No)}const pt=m(Mo,[["render",Io]]),Bo={class:"items"},xo={class:"title"},Eo=b({__name:"VPNavBarTranslations",setup(t){const{theme:e}=C(),{localeLinks:n,currentLang:o}=de({correspondingLink:!0});return(s,r)=>i(n).length&&i(o).label?(a(),w(He,{key:0,class:"VPNavBarTranslations",icon:pt,label:i(e).langMenuLabel||"Change language"},{default:p(()=>[_("div",Bo,[_("p",xo,A(i(o).label),1),(a(!0),l(I,null,D(i(n),c=>(a(),w(be,{key:c.link,item:c},null,8,["item"]))),128))])]),_:1},8,["label"])):g("",!0)}});const Ho=m(Eo,[["__scopeId","data-v-74abcbb9"]]);const Do={},zo={class:"VPSwitch",type:"button",role:"switch"},Oo={class:"check"},Fo={key:0,class:"icon"};function Go(t,e){return a(),l("button",zo,[_("span",Oo,[t.$slots.default?(a(),l("span",Fo,[d(t.$slots,"default",{},void 0,!0)])):g("",!0)])])}const jo=m(Do,[["render",Go],["__scopeId","data-v-f3c41672"]]),Wo={},Ro={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24"},Uo=It('',9),qo=[Uo];function Ko(t,e){return a(),l("svg",Ro,qo)}const Yo=m(Wo,[["render",Ko]]),Xo={},Jo={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24"},Qo=_("path",{d:"M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"},null,-1),Zo=[Qo];function es(t,e){return a(),l("svg",Jo,Zo)}const ts=m(Xo,[["render",es]]),ns=b({__name:"VPSwitchAppearance",setup(t){const{site:e,isDark:n}=C(),o=L(!1),s=ot?r():()=>{};W(()=>{o.value=document.documentElement.classList.contains("dark")});function r(){const c=window.matchMedia("(prefers-color-scheme: dark)"),v=document.documentElement.classList;let u=localStorage.getItem(qe),f=e.value.appearance==="dark"&&u==null||(u==="auto"||u==null?c.matches:u==="dark");c.onchange=M=>{u==="auto"&&P(f=M.matches)};function $(){P(f=!f),u=f?c.matches?"auto":"dark":c.matches?"light":"auto",localStorage.setItem(qe,u)}function P(M){const y=document.createElement("style");y.type="text/css",y.appendChild(document.createTextNode(`:not(.VPSwitchAppearance):not(.VPSwitchAppearance *) { + -webkit-transition: none !important; + -moz-transition: none !important; + -o-transition: none !important; + -ms-transition: none !important; + transition: none !important; +}`)),document.head.appendChild(y),o.value=M,v[M?"add":"remove"]("dark"),window.getComputedStyle(y).opacity,document.head.removeChild(y)}return $}return K(o,c=>{n.value=c}),(c,v)=>(a(),w(jo,{title:"toggle dark mode",class:"VPSwitchAppearance","aria-checked":o.value,onClick:i(s)},{default:p(()=>[h(Yo,{class:"sun"}),h(ts,{class:"moon"})]),_:1},8,["aria-checked","onClick"]))}});const De=m(ns,[["__scopeId","data-v-82b282f1"]]),os={key:0,class:"VPNavBarAppearance"},ss=b({__name:"VPNavBarAppearance",setup(t){const{site:e}=C();return(n,o)=>i(e).appearance?(a(),l("div",os,[h(De)])):g("",!0)}});const as=m(ss,[["__scopeId","data-v-f6a63727"]]),rs={discord:'Discord',facebook:'Facebook',github:'GitHub',instagram:'Instagram',linkedin:'LinkedIn',mastodon:'Mastodon',slack:'Slack',twitter:'Twitter',youtube:'YouTube'},is=["href","aria-label","innerHTML"],ls=b({__name:"VPSocialLink",props:{icon:{},link:{},ariaLabel:{}},setup(t){const e=t,n=k(()=>typeof e.icon=="object"?e.icon.svg:rs[e.icon]);return(o,s)=>(a(),l("a",{class:"VPSocialLink",href:o.link,"aria-label":o.ariaLabel??(typeof o.icon=="string"?o.icon:""),target:"_blank",rel:"noopener",innerHTML:n.value},null,8,is))}});const cs=m(ls,[["__scopeId","data-v-36371990"]]),us={class:"VPSocialLinks"},ds=b({__name:"VPSocialLinks",props:{links:{}},setup(t){return(e,n)=>(a(),l("div",us,[(a(!0),l(I,null,D(e.links,({link:o,icon:s,ariaLabel:r})=>(a(),w(cs,{key:o,icon:s,link:o,ariaLabel:r},null,8,["icon","link","ariaLabel"]))),128))]))}});const ze=m(ds,[["__scopeId","data-v-7bc22406"]]),_s=b({__name:"VPNavBarSocialLinks",setup(t){const{theme:e}=C();return(n,o)=>i(e).socialLinks?(a(),w(ze,{key:0,class:"VPNavBarSocialLinks",links:i(e).socialLinks},null,8,["links"])):g("",!0)}});const vs=m(_s,[["__scopeId","data-v-0394ad82"]]),ps={key:0,class:"group translations"},fs={class:"trans-title"},hs={key:1,class:"group"},ms={class:"item appearance"},gs={class:"label"},ys={class:"appearance-action"},bs={key:2,class:"group"},$s={class:"item social-links"},ks=b({__name:"VPNavBarExtra",setup(t){const{site:e,theme:n}=C(),{localeLinks:o,currentLang:s}=de({correspondingLink:!0}),r=k(()=>o.value.length&&s.value.label||e.value.appearance||n.value.socialLinks);return(c,v)=>r.value?(a(),w(He,{key:0,class:"VPNavBarExtra",label:"extra navigation"},{default:p(()=>[i(o).length&&i(s).label?(a(),l("div",ps,[_("p",fs,A(i(s).label),1),(a(!0),l(I,null,D(i(o),u=>(a(),w(be,{key:u.link,item:u},null,8,["item"]))),128))])):g("",!0),i(e).appearance?(a(),l("div",hs,[_("div",ms,[_("p",gs,A(i(n).darkModeSwitchLabel||"Appearance"),1),_("div",ys,[h(De)])])])):g("",!0),i(n).socialLinks?(a(),l("div",bs,[_("div",$s,[h(ze,{class:"social-links-list",links:i(n).socialLinks},null,8,["links"])])])):g("",!0)]),_:1})):g("",!0)}});const ws=m(ks,[["__scopeId","data-v-40855f84"]]),Ps=t=>(G("data-v-e5dd9c1c"),t=t(),j(),t),Vs=["aria-expanded"],Ss=Ps(()=>_("span",{class:"container"},[_("span",{class:"top"}),_("span",{class:"middle"}),_("span",{class:"bottom"})],-1)),Ls=[Ss],Ms=b({__name:"VPNavBarHamburger",props:{active:{type:Boolean}},emits:["click"],setup(t){return(e,n)=>(a(),l("button",{type:"button",class:B(["VPNavBarHamburger",{active:e.active}]),"aria-label":"mobile navigation","aria-expanded":e.active,"aria-controls":"VPNavScreen",onClick:n[0]||(n[0]=o=>e.$emit("click"))},Ls,10,Vs))}});const Cs=m(Ms,[["__scopeId","data-v-e5dd9c1c"]]),Ts=t=>(G("data-v-7683ced7"),t=t(),j(),t),As={class:"container"},Ns={class:"title"},Is={class:"content"},Bs=Ts(()=>_("div",{class:"curtain"},null,-1)),xs={class:"content-body"},Es=b({__name:"VPNavBar",props:{isScreenOpen:{type:Boolean}},emits:["toggle-screen"],setup(t){const{y:e}=ct(),{hasSidebar:n}=R(),o=k(()=>({"has-sidebar":n.value,fill:e.value>0}));return(s,r)=>(a(),l("div",{class:B(["VPNavBar",o.value])},[_("div",As,[_("div",Ns,[h(Sn,null,{"nav-bar-title-before":p(()=>[d(s.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":p(()=>[d(s.$slots,"nav-bar-title-after",{},void 0,!0)]),_:3})]),_("div",Is,[Bs,_("div",xs,[d(s.$slots,"nav-bar-content-before",{},void 0,!0),h(Bn,{class:"search"}),h(Lo,{class:"menu"}),h(Ho,{class:"translations"}),h(as,{class:"appearance"}),h(vs,{class:"social-links"}),h(ws,{class:"extra"}),d(s.$slots,"nav-bar-content-after",{},void 0,!0),h(Cs,{class:"hamburger",active:s.isScreenOpen,onClick:r[0]||(r[0]=c=>s.$emit("toggle-screen"))},null,8,["active"])])])])],2))}});const Hs=m(Es,[["__scopeId","data-v-7683ced7"]]);function Ds(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e1),Z=[],ge=!1,Fe=-1,oe=void 0,X=void 0,se=void 0,ft=function(e){return Z.some(function(n){return!!(n.options.allowTouchMove&&n.options.allowTouchMove(e))})},ye=function(e){var n=e||window.event;return ft(n.target)||n.touches.length>1?!0:(n.preventDefault&&n.preventDefault(),!1)},zs=function(e){if(se===void 0){var n=!!e&&e.reserveScrollBarGap===!0,o=window.innerWidth-document.documentElement.clientWidth;if(n&&o>0){var s=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right"),10);se=document.body.style.paddingRight,document.body.style.paddingRight=s+o+"px"}}oe===void 0&&(oe=document.body.style.overflow,document.body.style.overflow="hidden")},Os=function(){se!==void 0&&(document.body.style.paddingRight=se,se=void 0),oe!==void 0&&(document.body.style.overflow=oe,oe=void 0)},Fs=function(){return window.requestAnimationFrame(function(){if(X===void 0){X={position:document.body.style.position,top:document.body.style.top,left:document.body.style.left};var e=window,n=e.scrollY,o=e.scrollX,s=e.innerHeight;document.body.style.position="fixed",document.body.style.top=-n,document.body.style.left=-o,setTimeout(function(){return window.requestAnimationFrame(function(){var r=s-window.innerHeight;r&&n>=s&&(document.body.style.top=-(n+r))})},300)}})},Gs=function(){if(X!==void 0){var e=-parseInt(document.body.style.top,10),n=-parseInt(document.body.style.left,10);document.body.style.position=X.position,document.body.style.top=X.top,document.body.style.left=X.left,window.scrollTo(n,e),X=void 0}},js=function(e){return e?e.scrollHeight-e.scrollTop<=e.clientHeight:!1},Ws=function(e,n){var o=e.targetTouches[0].clientY-Fe;return ft(e.target)?!1:n&&n.scrollTop===0&&o>0||js(n)&&o<0?ye(e):(e.stopPropagation(),!0)},ht=function(e,n){if(!e){console.error("disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.");return}if(!Z.some(function(s){return s.targetElement===e})){var o={targetElement:e,options:n||{}};Z=[].concat(Ds(Z),[o]),me?Fs():zs(n),me&&(e.ontouchstart=function(s){s.targetTouches.length===1&&(Fe=s.targetTouches[0].clientY)},e.ontouchmove=function(s){s.targetTouches.length===1&&Ws(s,e)},ge||(document.addEventListener("touchmove",ye,Oe?{passive:!1}:void 0),ge=!0))}},mt=function(){me&&(Z.forEach(function(e){e.targetElement.ontouchstart=null,e.targetElement.ontouchmove=null}),ge&&(document.removeEventListener("touchmove",ye,Oe?{passive:!1}:void 0),ge=!1),Fe=-1),me?Gs():Os(),Z=[]};const Rs=b({__name:"VPNavScreenMenuLink",props:{item:{}},setup(t){const e=Ie("close-screen");return(n,o)=>(a(),w(Y,{class:"VPNavScreenMenuLink",href:n.item.link,target:n.item.target,rel:n.item.rel,onClick:i(e)},{default:p(()=>[x(A(n.item.text),1)]),_:1},8,["href","target","rel","onClick"]))}});const Us=m(Rs,[["__scopeId","data-v-30be0acb"]]),qs={},Ks={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24"},Ys=_("path",{d:"M18.9,10.9h-6v-6c0-0.6-0.4-1-1-1s-1,0.4-1,1v6h-6c-0.6,0-1,0.4-1,1s0.4,1,1,1h6v6c0,0.6,0.4,1,1,1s1-0.4,1-1v-6h6c0.6,0,1-0.4,1-1S19.5,10.9,18.9,10.9z"},null,-1),Xs=[Ys];function Js(t,e){return a(),l("svg",Ks,Xs)}const Qs=m(qs,[["render",Js]]),Zs=b({__name:"VPNavScreenMenuGroupLink",props:{item:{}},setup(t){const e=Ie("close-screen");return(n,o)=>(a(),w(Y,{class:"VPNavScreenMenuGroupLink",href:n.item.link,target:n.item.target,rel:n.item.rel,onClick:i(e)},{default:p(()=>[x(A(n.item.text),1)]),_:1},8,["href","target","rel","onClick"]))}});const gt=m(Zs,[["__scopeId","data-v-6656c42a"]]),ea={class:"VPNavScreenMenuGroupSection"},ta={key:0,class:"title"},na=b({__name:"VPNavScreenMenuGroupSection",props:{text:{},items:{}},setup(t){return(e,n)=>(a(),l("div",ea,[e.text?(a(),l("p",ta,A(e.text),1)):g("",!0),(a(!0),l(I,null,D(e.items,o=>(a(),w(gt,{key:o.text,item:o},null,8,["item"]))),128))]))}});const oa=m(na,[["__scopeId","data-v-8133b170"]]),sa=["aria-controls","aria-expanded"],aa={class:"button-text"},ra=["id"],ia={key:1,class:"group"},la=b({__name:"VPNavScreenMenuGroup",props:{text:{},items:{}},setup(t){const e=t,n=L(!1),o=k(()=>`NavScreenGroup-${e.text.replace(" ","-").toLowerCase()}`);function s(){n.value=!n.value}return(r,c)=>(a(),l("div",{class:B(["VPNavScreenMenuGroup",{open:n.value}])},[_("button",{class:"button","aria-controls":o.value,"aria-expanded":n.value,onClick:s},[_("span",aa,A(r.text),1),h(Qs,{class:"button-icon"})],8,sa),_("div",{id:o.value,class:"items"},[(a(!0),l(I,null,D(r.items,v=>(a(),l(I,{key:v.text},["link"in v?(a(),l("div",{key:v.text,class:"item"},[h(gt,{item:v},null,8,["item"])])):(a(),l("div",ia,[h(oa,{text:v.text,items:v.items},null,8,["text","items"])]))],64))),128))],8,ra)],2))}});const ca=m(la,[["__scopeId","data-v-338a1689"]]),ua={key:0,class:"VPNavScreenMenu"},da=b({__name:"VPNavScreenMenu",setup(t){const{theme:e}=C();return(n,o)=>i(e).nav?(a(),l("nav",ua,[(a(!0),l(I,null,D(i(e).nav,s=>(a(),l(I,{key:s.text},["link"in s?(a(),w(Us,{key:0,item:s},null,8,["item"])):(a(),w(ca,{key:1,text:s.text||"",items:s.items},null,8,["text","items"]))],64))),128))])):g("",!0)}}),_a={key:0,class:"VPNavScreenAppearance"},va={class:"text"},pa=b({__name:"VPNavScreenAppearance",setup(t){const{site:e,theme:n}=C();return(o,s)=>i(e).appearance?(a(),l("div",_a,[_("p",va,A(i(n).darkModeSwitchLabel||"Appearance"),1),h(De)])):g("",!0)}});const fa=m(pa,[["__scopeId","data-v-add8f686"]]),ha={class:"list"},ma=b({__name:"VPNavScreenTranslations",setup(t){const{localeLinks:e,currentLang:n}=de({correspondingLink:!0}),o=L(!1);function s(){o.value=!o.value}return(r,c)=>i(e).length&&i(n).label?(a(),l("div",{key:0,class:B(["VPNavScreenTranslations",{open:o.value}])},[_("button",{class:"title",onClick:s},[h(pt,{class:"icon lang"}),x(" "+A(i(n).label)+" ",1),h(vt,{class:"icon chevron"})]),_("ul",ha,[(a(!0),l(I,null,D(i(e),v=>(a(),l("li",{key:v.link,class:"item"},[h(Y,{class:"link",href:v.link},{default:p(()=>[x(A(v.text),1)]),_:2},1032,["href"])]))),128))])],2)):g("",!0)}});const ga=m(ma,[["__scopeId","data-v-d72aa483"]]),ya=b({__name:"VPNavScreenSocialLinks",setup(t){const{theme:e}=C();return(n,o)=>i(e).socialLinks?(a(),w(ze,{key:0,class:"VPNavScreenSocialLinks",links:i(e).socialLinks},null,8,["links"])):g("",!0)}}),ba={class:"container"},$a=b({__name:"VPNavScreen",props:{open:{type:Boolean}},setup(t){const e=L(null);function n(){ht(e.value,{reserveScrollBarGap:!0})}function o(){mt()}return(s,r)=>(a(),w(Ne,{name:"fade",onEnter:n,onAfterLeave:o},{default:p(()=>[s.open?(a(),l("div",{key:0,class:"VPNavScreen",ref_key:"screen",ref:e},[_("div",ba,[d(s.$slots,"nav-screen-content-before",{},void 0,!0),h(da,{class:"menu"}),h(ga,{class:"translations"}),h(fa,{class:"appearance"}),h(ya,{class:"social-links"}),d(s.$slots,"nav-screen-content-after",{},void 0,!0)])],512)):g("",!0)]),_:3}))}});const ka=m($a,[["__scopeId","data-v-724636ae"]]),wa={class:"VPNav"},Pa=b({__name:"VPNav",setup(t){const{isScreenOpen:e,closeScreen:n,toggleScreen:o}=yn();return he("close-screen",n),(s,r)=>(a(),l("header",wa,[h(Hs,{"is-screen-open":i(e),onToggleScreen:i(o)},{"nav-bar-title-before":p(()=>[d(s.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":p(()=>[d(s.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":p(()=>[d(s.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":p(()=>[d(s.$slots,"nav-bar-content-after",{},void 0,!0)]),_:3},8,["is-screen-open","onToggleScreen"]),h(ka,{open:i(e)},{"nav-screen-content-before":p(()=>[d(s.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":p(()=>[d(s.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3},8,["open"])]))}});const Va=m(Pa,[["__scopeId","data-v-7e5bc4a5"]]);function Sa(){const{hasSidebar:t}=R(),e=Ve("(min-width: 960px)"),n=Ve("(min-width: 1280px)");return{isAsideEnabled:k(()=>!n.value&&!e.value?!1:t.value?n.value:e.value)}}const La=71;function Ge(t){return typeof t.outline=="object"&&!Array.isArray(t.outline)&&t.outline.label||t.outlineTitle||"On this page"}function je(t){const e=[...document.querySelectorAll(".VPDoc h2,h3,h4,h5,h6")].filter(n=>n.id&&n.hasChildNodes()).map(n=>{const o=Number(n.tagName[1]);return{title:Ma(n),link:"#"+n.id,level:o}});return Ca(e,t)}function Ma(t){let e="";for(const n of t.childNodes)if(n.nodeType===1){if(n.classList.contains("VPBadge")||n.classList.contains("header-anchor"))continue;e+=n.textContent}else n.nodeType===3&&(e+=n.textContent);return e.trim()}function Ca(t,e){if(e===!1)return[];const n=(typeof e=="object"&&!Array.isArray(e)?e.level:e)||2,[o,s]=typeof n=="number"?[n,n]:n==="deep"?[2,6]:n;t=t.filter(c=>c.level>=o&&c.level<=s);const r=[];e:for(let c=0;c=0;u--){const f=t[u];if(f.level{requestAnimationFrame(r),window.addEventListener("scroll",o)}),Bt(()=>{c(location.hash)}),Ae(()=>{window.removeEventListener("scroll",o)});function r(){if(!n.value)return;const v=[].slice.call(t.value.querySelectorAll(".outline-link")),u=[].slice.call(document.querySelectorAll(".content .header-anchor")).filter(y=>v.some(S=>S.hash===y.hash&&y.offsetParent!==null)),f=window.scrollY,$=window.innerHeight,P=document.body.offsetHeight,M=Math.abs(f+$-P)<1;if(u.length&&M){c(u[u.length-1].hash);return}for(let y=0;y{const s=J("VPDocOutlineItem",!0);return a(),l("ul",{class:B(n.root?"root":"nested")},[(a(!0),l(I,null,D(n.headers,({children:r,link:c,title:v})=>(a(),l("li",null,[_("a",{class:"outline-link",href:c,onClick:e,title:v},A(v),9,Na),r!=null&&r.length?(a(),w(s,{key:0,headers:r},null,8,["headers"])):g("",!0)]))),256))],2)}}});const We=m(Ia,[["__scopeId","data-v-9a431c33"]]),Ba={},xa={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24"},Ea=_("path",{d:"M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"},null,-1),Ha=[Ea];function Da(t,e){return a(),l("svg",xa,Ha)}const Re=m(Ba,[["render",Da]]),za=b({__name:"VPLocalNavOutlineDropdown",props:{headers:{}},setup(t){const{theme:e}=C(),n=L(!1),o=L(0),s=L();ae(()=>{n.value=!1});function r(){n.value=!n.value,o.value=window.innerHeight+Math.min(window.scrollY-64,0)}function c(u){u.target.classList.contains("outline-link")&&(s.value&&(s.value.style.transition="none"),Ce(()=>{n.value=!1}))}function v(){n.value=!1,window.scrollTo({top:0,left:0,behavior:"smooth"})}return(u,f)=>(a(),l("div",{class:"VPLocalNavOutlineDropdown",style:tt({"--vp-vh":o.value+"px"})},[u.headers.length>0?(a(),l("button",{key:0,onClick:r,class:B({open:n.value})},[x(A(i(Ge)(i(e)))+" ",1),h(Re,{class:"icon"})],2)):(a(),l("button",{key:1,onClick:v},A(i(e).returnToTopLabel||"Return to top"),1)),h(Ne,{name:"flyout"},{default:p(()=>[n.value?(a(),l("div",{key:0,ref_key:"items",ref:s,class:"items",onClick:c},[_("a",{class:"top-link",href:"#",onClick:v},A(i(e).returnToTopLabel||"Return to top"),1),h(We,{headers:u.headers},null,8,["headers"])],512)):g("",!0)]),_:1})],4))}});const Oa=m(za,[["__scopeId","data-v-687955bc"]]),Fa={},Ga={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24"},ja=_("path",{d:"M17,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,11,17,11z"},null,-1),Wa=_("path",{d:"M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z"},null,-1),Ra=_("path",{d:"M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z"},null,-1),Ua=_("path",{d:"M17,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,19,17,19z"},null,-1),qa=[ja,Wa,Ra,Ua];function Ka(t,e){return a(),l("svg",Ga,qa)}const Ya=m(Fa,[["render",Ka]]),Xa=["aria-expanded"],Ja={class:"menu-text"},Qa=b({__name:"VPLocalNav",props:{open:{type:Boolean}},emits:["open-menu"],setup(t){const{theme:e,frontmatter:n}=C(),{hasSidebar:o}=R(),{y:s}=ct(),r=ce([]);ae(()=>{r.value=je(n.value.outline??e.value.outline)});const c=k(()=>r.value.length===0&&!o.value),v=k(()=>({VPLocalNav:!0,fixed:c.value,"reached-top":s.value>=64}));return(u,f)=>i(n).layout!=="home"&&(!c.value||i(s)>=64)?(a(),l("div",{key:0,class:B(v.value)},[i(o)?(a(),l("button",{key:0,class:"menu","aria-expanded":u.open,"aria-controls":"VPSidebarNav",onClick:f[0]||(f[0]=$=>u.$emit("open-menu"))},[h(Ya,{class:"menu-icon"}),_("span",Ja,A(i(e).sidebarMenuLabel||"Menu"),1)],8,Xa)):g("",!0),h(Oa,{headers:r.value},null,8,["headers"])],2)):g("",!0)}});const Za=m(Qa,[["__scopeId","data-v-9074c407"]]),er=t=>(G("data-v-c4656e6d"),t=t(),j(),t),tr=["role","tabindex"],nr=er(()=>_("div",{class:"indicator"},null,-1)),or={key:1,class:"items"},sr=b({__name:"VPSidebarItem",props:{item:{},depth:{}},setup(t){const e=t,{collapsed:n,collapsible:o,isLink:s,isActiveLink:r,hasActiveLink:c,hasChildren:v,toggle:u}=vn(k(()=>e.item)),f=k(()=>v.value?"section":"div"),$=k(()=>s.value?"a":"div"),P=k(()=>v.value?e.depth+2===7?"p":`h${e.depth+2}`:"p"),M=k(()=>s.value?void 0:"button"),y=k(()=>[[`level-${e.depth}`],{collapsible:o.value},{collapsed:n.value},{"is-link":s.value},{"is-active":r.value},{"has-active":c.value}]);function S(V){"key"in V&&V.key!=="Enter"||!e.item.link&&u()}function T(){e.item.link&&u()}return(V,E)=>{const z=J("VPSidebarItem",!0);return a(),w(Q(f.value),{class:B(["VPSidebarItem",y.value])},{default:p(()=>[V.item.text?(a(),l("div",fe({key:0,class:"item",role:M.value},Et(V.item.items?{click:S,keydown:S}:{},!0),{tabindex:V.item.items&&0}),[nr,V.item.link?(a(),w(Y,{key:0,tag:$.value,class:"link",href:V.item.link},{default:p(()=>[(a(),w(Q(P.value),{class:"text",innerHTML:V.item.text},null,8,["innerHTML"]))]),_:1},8,["tag","href"])):(a(),w(Q(P.value),{key:1,class:"text",innerHTML:V.item.text},null,8,["innerHTML"])),V.item.collapsed!=null?(a(),l("div",{key:2,class:"caret",role:"button","aria-label":"toggle section",onClick:T,onKeydown:xt(T,["enter"]),tabindex:"0"},[h(Re,{class:"caret-icon"})],32)):g("",!0)],16,tr)):g("",!0),V.item.items&&V.item.items.length?(a(),l("div",or,[V.depth<5?(a(!0),l(I,{key:0},D(V.item.items,O=>(a(),w(z,{key:O.text,item:O,depth:V.depth+1},null,8,["item","depth"]))),128)):g("",!0)])):g("",!0)]),_:1},8,["class"])}}});const ar=m(sr,[["__scopeId","data-v-c4656e6d"]]),yt=t=>(G("data-v-af16598e"),t=t(),j(),t),rr=yt(()=>_("div",{class:"curtain"},null,-1)),ir={class:"nav",id:"VPSidebarNav","aria-labelledby":"sidebar-aria-label",tabindex:"-1"},lr=yt(()=>_("span",{class:"visually-hidden",id:"sidebar-aria-label"}," Sidebar Navigation ",-1)),cr=b({__name:"VPSidebar",props:{open:{type:Boolean}},setup(t){const{sidebarGroups:e,hasSidebar:n}=R(),o=t;let s=L(null);function r(){ht(s.value,{reserveScrollBarGap:!0})}function c(){mt()}return Ht(async()=>{var v;o.open?(r(),(v=s.value)==null||v.focus()):c()}),(v,u)=>i(n)?(a(),l("aside",{key:0,class:B(["VPSidebar",{open:v.open}]),ref_key:"navEl",ref:s,onClick:u[0]||(u[0]=Dt(()=>{},["stop"]))},[rr,_("nav",ir,[lr,d(v.$slots,"sidebar-nav-before",{},void 0,!0),(a(!0),l(I,null,D(i(e),f=>(a(),l("div",{key:f.text,class:"group"},[h(ar,{item:f,depth:0},null,8,["item"])]))),128)),d(v.$slots,"sidebar-nav-after",{},void 0,!0)])],2)):g("",!0)}});const ur=m(cr,[["__scopeId","data-v-af16598e"]]),dr={},_r={class:"VPPage"};function vr(t,e){const n=J("Content");return a(),l("div",_r,[d(t.$slots,"page-top"),h(n),d(t.$slots,"page-bottom")])}const pr=m(dr,[["render",vr]]),fr=b({__name:"VPButton",props:{tag:{},size:{},theme:{},text:{},href:{}},setup(t){const e=t,n=k(()=>[e.size??"medium",e.theme??"brand"]),o=k(()=>e.href&&nt.test(e.href)),s=k(()=>e.tag?e.tag:e.href?"a":"button");return(r,c)=>(a(),w(Q(s.value),{class:B(["VPButton",n.value]),href:r.href?i(le)(r.href):void 0,target:o.value?"_blank":void 0,rel:o.value?"noreferrer":void 0},{default:p(()=>[x(A(r.text),1)]),_:1},8,["class","href","target","rel"]))}});const hr=m(fr,[["__scopeId","data-v-567ba664"]]),mr=t=>(G("data-v-fd2650d5"),t=t(),j(),t),gr={class:"container"},yr={class:"main"},br={key:0,class:"name"},$r={class:"clip"},kr={key:1,class:"text"},wr={key:2,class:"tagline"},Pr={key:0,class:"actions"},Vr={key:0,class:"image"},Sr={class:"image-container"},Lr=mr(()=>_("div",{class:"image-bg"},null,-1)),Mr=b({__name:"VPHero",props:{name:{},text:{},tagline:{},image:{},actions:{}},setup(t){const e=Ie("hero-image-slot-exists");return(n,o)=>(a(),l("div",{class:B(["VPHero",{"has-image":n.image||i(e)}])},[_("div",gr,[_("div",yr,[d(n.$slots,"home-hero-info",{},()=>[n.name?(a(),l("h1",br,[_("span",$r,A(n.name),1)])):g("",!0),n.text?(a(),l("p",kr,A(n.text),1)):g("",!0),n.tagline?(a(),l("p",wr,A(n.tagline),1)):g("",!0)],!0),n.actions?(a(),l("div",Pr,[(a(!0),l(I,null,D(n.actions,s=>(a(),l("div",{key:s.link,class:"action"},[h(hr,{tag:"a",size:"medium",theme:s.theme,text:s.text,href:s.link},null,8,["theme","text","href"])]))),128))])):g("",!0)]),n.image||i(e)?(a(),l("div",Vr,[_("div",Sr,[Lr,d(n.$slots,"home-hero-image",{},()=>[n.image?(a(),w(xe,{key:0,class:"image-src",image:n.image},null,8,["image"])):g("",!0)],!0)])])):g("",!0)])],2))}});const Cr=m(Mr,[["__scopeId","data-v-fd2650d5"]]),Tr=b({__name:"VPHomeHero",setup(t){const{frontmatter:e}=C();return(n,o)=>i(e).hero?(a(),w(Cr,{key:0,class:"VPHomeHero",name:i(e).hero.name,text:i(e).hero.text,tagline:i(e).hero.tagline,image:i(e).hero.image,actions:i(e).hero.actions},{"home-hero-info":p(()=>[d(n.$slots,"home-hero-info")]),"home-hero-image":p(()=>[d(n.$slots,"home-hero-image")]),_:3},8,["name","text","tagline","image","actions"])):g("",!0)}}),Ar={},Nr={xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Ir=_("path",{d:"M19.9,12.4c0.1-0.2,0.1-0.5,0-0.8c-0.1-0.1-0.1-0.2-0.2-0.3l-7-7c-0.4-0.4-1-0.4-1.4,0s-0.4,1,0,1.4l5.3,5.3H5c-0.6,0-1,0.4-1,1s0.4,1,1,1h11.6l-5.3,5.3c-0.4,0.4-0.4,1,0,1.4c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3l7-7C19.8,12.6,19.9,12.5,19.9,12.4z"},null,-1),Br=[Ir];function xr(t,e){return a(),l("svg",Nr,Br)}const Er=m(Ar,[["render",xr]]),Hr={class:"box"},Dr=["innerHTML"],zr=["innerHTML"],Or=["innerHTML"],Fr={key:3,class:"link-text"},Gr={class:"link-text-value"},jr=b({__name:"VPFeature",props:{icon:{},title:{},details:{},link:{},linkText:{}},setup(t){return(e,n)=>(a(),w(Y,{class:"VPFeature",href:e.link,"no-icon":!0},{default:p(()=>[_("article",Hr,[typeof e.icon=="object"?(a(),w(xe,{key:0,image:e.icon,alt:e.icon.alt,height:e.icon.height,width:e.icon.width},null,8,["image","alt","height","width"])):e.icon?(a(),l("div",{key:1,class:"icon",innerHTML:e.icon},null,8,Dr)):g("",!0),_("h2",{class:"title",innerHTML:e.title},null,8,zr),e.details?(a(),l("p",{key:2,class:"details",innerHTML:e.details},null,8,Or)):g("",!0),e.linkText?(a(),l("div",Fr,[_("p",Gr,[x(A(e.linkText)+" ",1),h(Er,{class:"link-text-icon"})])])):g("",!0)])]),_:1},8,["href"]))}});const Wr=m(jr,[["__scopeId","data-v-837f6cca"]]),Rr={key:0,class:"VPFeatures"},Ur={class:"container"},qr={class:"items"},Kr=b({__name:"VPFeatures",props:{features:{}},setup(t){const e=t,n=k(()=>{const o=e.features.length;if(o){if(o===2)return"grid-2";if(o===3)return"grid-3";if(o%3===0)return"grid-6";if(o>3)return"grid-4"}else return});return(o,s)=>o.features?(a(),l("div",Rr,[_("div",Ur,[_("div",qr,[(a(!0),l(I,null,D(o.features,r=>(a(),l("div",{key:r.title,class:B(["item",[n.value]])},[h(Wr,{icon:r.icon,title:r.title,details:r.details,link:r.link,"link-text":r.linkText},null,8,["icon","title","details","link","link-text"])],2))),128))])])])):g("",!0)}});const Yr=m(Kr,[["__scopeId","data-v-ba861f23"]]),Xr=b({__name:"VPHomeFeatures",setup(t){const{frontmatter:e}=C();return(n,o)=>i(e).features?(a(),w(Yr,{key:0,class:"VPHomeFeatures",features:i(e).features},null,8,["features"])):g("",!0)}}),Jr={class:"VPHome"},Qr=b({__name:"VPHome",setup(t){return(e,n)=>{const o=J("Content");return a(),l("div",Jr,[d(e.$slots,"home-hero-before",{},void 0,!0),h(Tr,null,{"home-hero-info":p(()=>[d(e.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-image":p(()=>[d(e.$slots,"home-hero-image",{},void 0,!0)]),_:3}),d(e.$slots,"home-hero-after",{},void 0,!0),d(e.$slots,"home-features-before",{},void 0,!0),h(Xr),d(e.$slots,"home-features-after",{},void 0,!0),h(o)])}}});const Zr=m(Qr,[["__scopeId","data-v-d82743a8"]]),ei=t=>(G("data-v-ff0f39c8"),t=t(),j(),t),ti={class:"content"},ni={class:"outline-title"},oi={"aria-labelledby":"doc-outline-aria-label"},si=ei(()=>_("span",{class:"visually-hidden",id:"doc-outline-aria-label"}," Table of Contents for current page ",-1)),ai=b({__name:"VPDocAsideOutline",setup(t){const{frontmatter:e,theme:n}=C(),o=ce([]);ae(()=>{o.value=je(e.value.outline??n.value.outline)});const s=L(),r=L();return Ta(s,r),(c,v)=>(a(),l("div",{class:B(["VPDocAsideOutline",{"has-outline":o.value.length>0}]),ref_key:"container",ref:s},[_("div",ti,[_("div",{class:"outline-marker",ref_key:"marker",ref:r},null,512),_("div",ni,A(i(Ge)(i(n))),1),_("nav",oi,[si,h(We,{headers:o.value,root:!0},null,8,["headers"])])])],2))}});const ri=m(ai,[["__scopeId","data-v-ff0f39c8"]]),ii={class:"VPDocAsideCarbonAds"},li=b({__name:"VPDocAsideCarbonAds",props:{carbonAds:{}},setup(t){const e=()=>null;return(n,o)=>(a(),l("div",ii,[h(i(e),{"carbon-ads":n.carbonAds},null,8,["carbon-ads"])]))}}),ci=t=>(G("data-v-3f215769"),t=t(),j(),t),ui={class:"VPDocAside"},di=ci(()=>_("div",{class:"spacer"},null,-1)),_i=b({__name:"VPDocAside",setup(t){const{theme:e}=C();return(n,o)=>(a(),l("div",ui,[d(n.$slots,"aside-top",{},void 0,!0),d(n.$slots,"aside-outline-before",{},void 0,!0),h(ri),d(n.$slots,"aside-outline-after",{},void 0,!0),di,d(n.$slots,"aside-ads-before",{},void 0,!0),i(e).carbonAds?(a(),w(li,{key:0,"carbon-ads":i(e).carbonAds},null,8,["carbon-ads"])):g("",!0),d(n.$slots,"aside-ads-after",{},void 0,!0),d(n.$slots,"aside-bottom",{},void 0,!0)]))}});const vi=m(_i,[["__scopeId","data-v-3f215769"]]);function pi(){const{theme:t,page:e}=C();return k(()=>{const{text:n="Edit this page",pattern:o=""}=t.value.editLink||{};let s;return typeof o=="function"?s=o(e.value):s=o.replace(/:path/g,e.value.filePath),{url:s,text:n}})}function fi(){const{page:t,theme:e,frontmatter:n}=C();return k(()=>{var u,f,$,P,M,y;const o=ut(e.value.sidebar,t.value.relativePath),s=dn(o),r=s.findIndex(S=>te(t.value.relativePath,S.link)),c=((u=e.value.docFooter)==null?void 0:u.prev)===!1&&!n.value.prev||n.value.prev===!1,v=((f=e.value.docFooter)==null?void 0:f.next)===!1&&!n.value.next||n.value.next===!1;return{prev:c?void 0:{text:(typeof n.value.prev=="string"?n.value.prev:typeof n.value.prev=="object"?n.value.prev.text:void 0)??(($=s[r-1])==null?void 0:$.text),link:(typeof n.value.prev=="object"?n.value.prev.link:void 0)??((P=s[r-1])==null?void 0:P.link)},next:v?void 0:{text:(typeof n.value.next=="string"?n.value.next:typeof n.value.next=="object"?n.value.next.text:void 0)??((M=s[r+1])==null?void 0:M.text),link:(typeof n.value.next=="object"?n.value.next.link:void 0)??((y=s[r+1])==null?void 0:y.link)}}})}const hi={},mi={xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},gi=_("path",{d:"M18,23H4c-1.7,0-3-1.3-3-3V6c0-1.7,1.3-3,3-3h7c0.6,0,1,0.4,1,1s-0.4,1-1,1H4C3.4,5,3,5.4,3,6v14c0,0.6,0.4,1,1,1h14c0.6,0,1-0.4,1-1v-7c0-0.6,0.4-1,1-1s1,0.4,1,1v7C21,21.7,19.7,23,18,23z"},null,-1),yi=_("path",{d:"M8,17c-0.3,0-0.5-0.1-0.7-0.3C7,16.5,6.9,16.1,7,15.8l1-4c0-0.2,0.1-0.3,0.3-0.5l9.5-9.5c1.2-1.2,3.2-1.2,4.4,0c1.2,1.2,1.2,3.2,0,4.4l-9.5,9.5c-0.1,0.1-0.3,0.2-0.5,0.3l-4,1C8.2,17,8.1,17,8,17zM9.9,12.5l-0.5,2.1l2.1-0.5l9.3-9.3c0.4-0.4,0.4-1.1,0-1.6c-0.4-0.4-1.2-0.4-1.6,0l0,0L9.9,12.5z M18.5,2.5L18.5,2.5L18.5,2.5z"},null,-1),bi=[gi,yi];function $i(t,e){return a(),l("svg",mi,bi)}const ki=m(hi,[["render",$i]]),wi={class:"VPLastUpdated"},Pi=["datetime"],Vi=b({__name:"VPDocFooterLastUpdated",setup(t){const{theme:e,page:n,lang:o}=C(),s=k(()=>new Date(n.value.lastUpdated)),r=k(()=>s.value.toISOString()),c=L("");return W(()=>{ee(()=>{c.value=s.value.toLocaleString(o.value)})}),(v,u)=>(a(),l("p",wi,[x(A(i(e).lastUpdatedText||"Last updated")+": ",1),_("time",{datetime:r.value},A(c.value),9,Pi)]))}});const Si=m(Vi,[["__scopeId","data-v-7b3ebfe1"]]),Li={key:0,class:"VPDocFooter"},Mi={key:0,class:"edit-info"},Ci={key:0,class:"edit-link"},Ti={key:1,class:"last-updated"},Ai={key:1,class:"prev-next"},Ni={class:"pager"},Ii=["href"],Bi=["innerHTML"],xi=["innerHTML"],Ei=["href"],Hi=["innerHTML"],Di=["innerHTML"],zi=b({__name:"VPDocFooter",setup(t){const{theme:e,page:n,frontmatter:o}=C(),s=pi(),r=fi(),c=k(()=>e.value.editLink&&o.value.editLink!==!1),v=k(()=>n.value.lastUpdated&&o.value.lastUpdated!==!1),u=k(()=>c.value||v.value||r.value.prev||r.value.next);return(f,$)=>{var P,M,y,S,T,V,E;return u.value?(a(),l("footer",Li,[d(f.$slots,"doc-footer-before",{},void 0,!0),c.value||v.value?(a(),l("div",Mi,[c.value?(a(),l("div",Ci,[h(Y,{class:"edit-link-button",href:i(s).url,"no-icon":!0},{default:p(()=>[h(ki,{class:"edit-link-icon","aria-label":"edit icon"}),x(" "+A(i(s).text),1)]),_:1},8,["href"])])):g("",!0),v.value?(a(),l("div",Ti,[h(Si)])):g("",!0)])):g("",!0),(P=i(r).prev)!=null&&P.link||(M=i(r).next)!=null&&M.link?(a(),l("div",Ai,[_("div",Ni,[(y=i(r).prev)!=null&&y.link?(a(),l("a",{key:0,class:"pager-link prev",href:i(le)(i(r).prev.link)},[_("span",{class:"desc",innerHTML:((S=i(e).docFooter)==null?void 0:S.prev)||"Previous page"},null,8,Bi),_("span",{class:"title",innerHTML:i(r).prev.text},null,8,xi)],8,Ii)):g("",!0)]),_("div",{class:B(["pager",{"has-prev":(T=i(r).prev)==null?void 0:T.link}])},[(V=i(r).next)!=null&&V.link?(a(),l("a",{key:0,class:"pager-link next",href:i(le)(i(r).next.link)},[_("span",{class:"desc",innerHTML:((E=i(e).docFooter)==null?void 0:E.next)||"Next page"},null,8,Hi),_("span",{class:"title",innerHTML:i(r).next.text},null,8,Di)],8,Ei)):g("",!0)],2)])):g("",!0)])):g("",!0)}}});const Oi=m(zi,[["__scopeId","data-v-face870a"]]),Fi={key:0,class:"VPDocOutlineDropdown"},Gi={key:0,class:"items"},ji=b({__name:"VPDocOutlineDropdown",setup(t){const{frontmatter:e,theme:n}=C(),o=L(!1);ae(()=>{o.value=!1});const s=ce([]);return ae(()=>{s.value=je(e.value.outline??n.value.outline)}),(r,c)=>s.value.length>0?(a(),l("div",Fi,[_("button",{onClick:c[0]||(c[0]=v=>o.value=!o.value),class:B({open:o.value})},[x(A(i(Ge)(i(n)))+" ",1),h(Re,{class:"icon"})],2),o.value?(a(),l("div",Gi,[h(We,{headers:s.value},null,8,["headers"])])):g("",!0)])):g("",!0)}});const Wi=m(ji,[["__scopeId","data-v-2edece88"]]),Ri=t=>(G("data-v-c4b0d3cf"),t=t(),j(),t),Ui={class:"container"},qi=Ri(()=>_("div",{class:"aside-curtain"},null,-1)),Ki={class:"aside-container"},Yi={class:"aside-content"},Xi={class:"content"},Ji={class:"content-container"},Qi={class:"main"},Zi=b({__name:"VPDoc",setup(t){const e=ue(),{hasSidebar:n,hasAside:o,leftAside:s}=R(),r=k(()=>e.path.replace(/[./]+/g,"_").replace(/_html$/,""));return(c,v)=>{const u=J("Content");return a(),l("div",{class:B(["VPDoc",{"has-sidebar":i(n),"has-aside":i(o)}])},[d(c.$slots,"doc-top",{},void 0,!0),_("div",Ui,[i(o)?(a(),l("div",{key:0,class:B(["aside",{"left-aside":i(s)}])},[qi,_("div",Ki,[_("div",Yi,[h(vi,null,{"aside-top":p(()=>[d(c.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":p(()=>[d(c.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":p(()=>[d(c.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":p(()=>[d(c.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":p(()=>[d(c.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":p(()=>[d(c.$slots,"aside-ads-after",{},void 0,!0)]),_:3})])])],2)):g("",!0),_("div",Xi,[_("div",Ji,[d(c.$slots,"doc-before",{},void 0,!0),h(Wi),_("main",Qi,[h(u,{class:B(["vp-doc",r.value])},null,8,["class"])]),h(Oi,null,{"doc-footer-before":p(()=>[d(c.$slots,"doc-footer-before",{},void 0,!0)]),_:3}),d(c.$slots,"doc-after",{},void 0,!0)])])]),d(c.$slots,"doc-bottom",{},void 0,!0)],2)}}});const el=m(Zi,[["__scopeId","data-v-c4b0d3cf"]]),$e=t=>(G("data-v-c70503b8"),t=t(),j(),t),tl={class:"NotFound"},nl=$e(()=>_("p",{class:"code"},"404",-1)),ol=$e(()=>_("h1",{class:"title"},"PAGE NOT FOUND",-1)),sl=$e(()=>_("div",{class:"divider"},null,-1)),al=$e(()=>_("blockquote",{class:"quote"}," But if you don't change your direction, and if you keep looking, you may end up where you are heading. ",-1)),rl={class:"action"},il=["href"],ll=b({__name:"NotFound",setup(t){const{site:e}=C(),{localeLinks:n}=de({removeCurrent:!1}),o=L("/");return W(()=>{var r;const s=window.location.pathname.replace(e.value.base,"").replace(/(^.*?\/).*$/,"/$1");n.value.length&&(o.value=((r=n.value.find(({link:c})=>c.startsWith(s)))==null?void 0:r.link)||n.value[0].link)}),(s,r)=>(a(),l("div",tl,[nl,ol,sl,al,_("div",rl,[_("a",{class:"link",href:i(Te)(o.value),"aria-label":"go to home"}," Take me home ",8,il)])]))}});const cl=m(ll,[["__scopeId","data-v-c70503b8"]]),ul=b({__name:"VPContent",setup(t){const{page:e,frontmatter:n}=C(),{hasSidebar:o}=R();return(s,r)=>(a(),l("div",{class:B(["VPContent",{"has-sidebar":i(o),"is-home":i(n).layout==="home"}]),id:"VPContent"},[i(e).isNotFound?d(s.$slots,"not-found",{key:0},()=>[h(cl)],!0):i(n).layout==="page"?(a(),w(pr,{key:1},{"page-top":p(()=>[d(s.$slots,"page-top",{},void 0,!0)]),"page-bottom":p(()=>[d(s.$slots,"page-bottom",{},void 0,!0)]),_:3})):i(n).layout==="home"?(a(),w(Zr,{key:2},{"home-hero-before":p(()=>[d(s.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info":p(()=>[d(s.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-image":p(()=>[d(s.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":p(()=>[d(s.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":p(()=>[d(s.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":p(()=>[d(s.$slots,"home-features-after",{},void 0,!0)]),_:3})):(a(),w(el,{key:3},{"doc-top":p(()=>[d(s.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":p(()=>[d(s.$slots,"doc-bottom",{},void 0,!0)]),"doc-footer-before":p(()=>[d(s.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":p(()=>[d(s.$slots,"doc-before",{},void 0,!0)]),"doc-after":p(()=>[d(s.$slots,"doc-after",{},void 0,!0)]),"aside-top":p(()=>[d(s.$slots,"aside-top",{},void 0,!0)]),"aside-outline-before":p(()=>[d(s.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":p(()=>[d(s.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":p(()=>[d(s.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":p(()=>[d(s.$slots,"aside-ads-after",{},void 0,!0)]),"aside-bottom":p(()=>[d(s.$slots,"aside-bottom",{},void 0,!0)]),_:3}))],2))}});const dl=m(ul,[["__scopeId","data-v-a494bd1d"]]),_l={class:"container"},vl=["innerHTML"],pl=["innerHTML"],fl=b({__name:"VPFooter",setup(t){const{theme:e}=C(),{hasSidebar:n}=R();return(o,s)=>i(e).footer?(a(),l("footer",{key:0,class:B(["VPFooter",{"has-sidebar":i(n)}])},[_("div",_l,[i(e).footer.message?(a(),l("p",{key:0,class:"message",innerHTML:i(e).footer.message},null,8,vl)):g("",!0),i(e).footer.copyright?(a(),l("p",{key:1,class:"copyright",innerHTML:i(e).footer.copyright},null,8,pl)):g("",!0)])],2)):g("",!0)}});const hl=m(fl,[["__scopeId","data-v-f7fc41f4"]]),ml={key:0,class:"Layout"},gl=b({__name:"Layout",setup(t){const{isOpen:e,open:n,close:o}=R(),s=ue();K(()=>s.path,o),_n(e,o),he("close-sidebar",o),he("is-sidebar-open",e);const{frontmatter:r}=C(),c=zt(),v=k(()=>!!c["home-hero-image"]);return he("hero-image-slot-exists",v),(u,f)=>{const $=J("Content");return i(r).layout!==!1?(a(),l("div",ml,[d(u.$slots,"layout-top",{},void 0,!0),h(fn),h(gn,{class:"backdrop",show:i(e),onClick:i(o)},null,8,["show","onClick"]),h(Va,null,{"nav-bar-title-before":p(()=>[d(u.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":p(()=>[d(u.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":p(()=>[d(u.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":p(()=>[d(u.$slots,"nav-bar-content-after",{},void 0,!0)]),"nav-screen-content-before":p(()=>[d(u.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":p(()=>[d(u.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3}),h(Za,{open:i(e),onOpenMenu:i(n)},null,8,["open","onOpenMenu"]),h(ur,{open:i(e)},{"sidebar-nav-before":p(()=>[d(u.$slots,"sidebar-nav-before",{},void 0,!0)]),"sidebar-nav-after":p(()=>[d(u.$slots,"sidebar-nav-after",{},void 0,!0)]),_:3},8,["open"]),h(dl,null,{"page-top":p(()=>[d(u.$slots,"page-top",{},void 0,!0)]),"page-bottom":p(()=>[d(u.$slots,"page-bottom",{},void 0,!0)]),"not-found":p(()=>[d(u.$slots,"not-found",{},void 0,!0)]),"home-hero-before":p(()=>[d(u.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info":p(()=>[d(u.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-image":p(()=>[d(u.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":p(()=>[d(u.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":p(()=>[d(u.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":p(()=>[d(u.$slots,"home-features-after",{},void 0,!0)]),"doc-footer-before":p(()=>[d(u.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":p(()=>[d(u.$slots,"doc-before",{},void 0,!0)]),"doc-after":p(()=>[d(u.$slots,"doc-after",{},void 0,!0)]),"doc-top":p(()=>[d(u.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":p(()=>[d(u.$slots,"doc-bottom",{},void 0,!0)]),"aside-top":p(()=>[d(u.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":p(()=>[d(u.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":p(()=>[d(u.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":p(()=>[d(u.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":p(()=>[d(u.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":p(()=>[d(u.$slots,"aside-ads-after",{},void 0,!0)]),_:3}),h(hl),d(u.$slots,"layout-bottom",{},void 0,!0)])):(a(),w($,{key:1}))}}});const yl=m(gl,[["__scopeId","data-v-b2cf3e0b"]]);const Sl={Layout:yl,enhanceApp:({app:t})=>{t.component("Badge",Ft)}};function Ll(t,e){const{localeIndex:n}=C();function o(s){var y,S;const r=s.split("."),c=t&&typeof t=="object",v=c&&((S=(y=t.locales)==null?void 0:y[n.value])==null?void 0:S.translations)||null,u=c&&t.translations||null;let f=v,$=u,P=e;const M=r.pop();for(const T of r){let V=null;const E=P==null?void 0:P[T];E&&(V=P=E);const z=$==null?void 0:$[T];z&&(V=$=z);const O=f==null?void 0:f[T];O&&(V=f=O),E||(P=V),z||($=V),O||(f=V)}return(f==null?void 0:f[M])??($==null?void 0:$[M])??(P==null?void 0:P[M])??""}return o}export{Be as a,C as b,kl as c,Vl as d,wl as e,Ll as f,ie as g,Pl as h,Ye as o,Sl as t,Qt as u,$l as w}; diff --git a/assets/develop_adapters_comwechat.md.1ec4e8a3.js b/assets/develop_adapters_comwechat.md.1ec4e8a3.js new file mode 100644 index 00000000..31e0bd8f --- /dev/null +++ b/assets/develop_adapters_comwechat.md.1ec4e8a3.js @@ -0,0 +1,7 @@ +import{_ as t,o as a,c as s,V as o}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"ComWeChatBot Client Beta","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/comwechat.md","filePath":"develop/adapters/comwechat.md","lastUpdated":1722566694000}'),e={name:"develop/adapters/comwechat.md"},n=o(`

ComWeChatBot Client Beta

ComWeChatBot Client 是 PC hook 微信的协议端。

需在服务配置开启 正向 websocket

连接 ComWeChatBot

参数名类型释义默认值
hoststr服务的 ip 地址
ws_portint服务的 websocket 端口
http_portint服务的 http 端口
python
from amiyabot.adapters.comwechat import com_wechat
+
+token = '******' # access-token
+
+adapter_service = com_wechat('127.0.0.1', 8080, 8060)
+
+bot = AmiyaBot(appid=appid, token=token, adapter=adapter_service)
`,6),l=[n];function p(c,r,i,d,y,F){return a(),s("div",null,l)}const B=t(e,[["render",p]]);export{h as __pageData,B as default}; diff --git a/assets/develop_adapters_comwechat.md.1ec4e8a3.lean.js b/assets/develop_adapters_comwechat.md.1ec4e8a3.lean.js new file mode 100644 index 00000000..aca8e158 --- /dev/null +++ b/assets/develop_adapters_comwechat.md.1ec4e8a3.lean.js @@ -0,0 +1 @@ +import{_ as t,o as a,c as s,V as o}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"ComWeChatBot Client Beta","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/comwechat.md","filePath":"develop/adapters/comwechat.md","lastUpdated":1722566694000}'),e={name:"develop/adapters/comwechat.md"},n=o("",6),l=[n];function p(c,r,i,d,y,F){return a(),s("div",null,l)}const B=t(e,[["render",p]]);export{h as __pageData,B as default}; diff --git a/assets/develop_adapters_gocq.md.42ef6fb0.js b/assets/develop_adapters_gocq.md.42ef6fb0.js new file mode 100644 index 00000000..3873d8f9 --- /dev/null +++ b/assets/develop_adapters_gocq.md.42ef6fb0.js @@ -0,0 +1,12 @@ +import{_ as s,o as a,c as t,V as o}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"go-cqhttp","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/gocq.md","filePath":"develop/adapters/gocq.md","lastUpdated":1722566694000}'),n={name:"develop/adapters/gocq.md"},l=o(`

go-cqhttp

go-cqhttp 以下简称 gocq。它是基于 Mirai 以及 MiraiGo 的 OneBot Golang 原生实现。

注意

go-cq 的配置中,post-format 需更改为 array

yaml
# config.yml
+message:
+    # 上报数据类型
+    # 可选: string, array
+    post-format: array

连接 gocq

参数名类型释义默认值
hoststrgocq 服务的 ip 地址
ws_portintgocq 服务的 websocket 端口
http_portintgocq 服务的 http 端口
python
from amiyabot.adapters.cqhttp import cq_http
+
+qq = '******'    # 机器人的 QQ 号
+token = '******' # gocq 的 access-token
+
+adapter_service = cq_http('127.0.0.1', 8080, 5700)
+
+bot = AmiyaBot(appid=qq, token=token, adapter=adapter_service)
`,6),p=[l];function e(c,r,y,i,D,F){return a(),t("div",null,p)}const B=s(n,[["render",e]]);export{h as __pageData,B as default}; diff --git a/assets/develop_adapters_gocq.md.42ef6fb0.lean.js b/assets/develop_adapters_gocq.md.42ef6fb0.lean.js new file mode 100644 index 00000000..0b3c563f --- /dev/null +++ b/assets/develop_adapters_gocq.md.42ef6fb0.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as t,V as o}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"go-cqhttp","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/gocq.md","filePath":"develop/adapters/gocq.md","lastUpdated":1722566694000}'),n={name:"develop/adapters/gocq.md"},l=o("",6),p=[l];function e(c,r,y,i,D,F){return a(),t("div",null,p)}const B=s(n,[["render",e]]);export{h as __pageData,B as default}; diff --git a/assets/develop_adapters_index.md.80074c45.js b/assets/develop_adapters_index.md.80074c45.js new file mode 100644 index 00000000..74aee304 --- /dev/null +++ b/assets/develop_adapters_index.md.80074c45.js @@ -0,0 +1,5 @@ +import{_ as a,o as s,c as e,V as n}from"./chunks/framework.63f12d77.js";const _=JSON.parse('{"title":"适配器","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/index.md","filePath":"develop/adapters/index.md","lastUpdated":1722566694000}'),o={name:"develop/adapters/index.md"},t=n(`

适配器

更改默认适配器可以让你搭建其他平台的机器人,除了 bot.instance.api 有差异外,你几乎可以完全按照文档的开发方式进行。我们尽量为所有适配器的基本逻辑实现了相同的效果,使得在不同平台下 AmiyaBot 的开发差异变得极其之小。

适配器参数 adapter

AmiyaBot 对象拥有一个适配器参数 adapter,接受一个 BotAdapterProtocol 的子类。默认值为 QQ 频道机器人的适配器 QQGuildBotInstance

python
class AmiyaBot(BotHandlerFactory):
+    def __init__(self,
+                 ...
+                 adapter: Type[BotAdapterProtocol] = QQGuildBotInstance):
+        ...

从左侧导航挑选合适的适配器,更改你的实例。

`,6),p=[t];function l(c,r,d,i,y,B){return s(),e("div",null,p)}const F=a(o,[["render",l]]);export{_ as __pageData,F as default}; diff --git a/assets/develop_adapters_index.md.80074c45.lean.js b/assets/develop_adapters_index.md.80074c45.lean.js new file mode 100644 index 00000000..10302f44 --- /dev/null +++ b/assets/develop_adapters_index.md.80074c45.lean.js @@ -0,0 +1 @@ +import{_ as a,o as s,c as e,V as n}from"./chunks/framework.63f12d77.js";const _=JSON.parse('{"title":"适配器","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/index.md","filePath":"develop/adapters/index.md","lastUpdated":1722566694000}'),o={name:"develop/adapters/index.md"},t=n("",6),p=[t];function l(c,r,d,i,y,B){return s(),e("div",null,p)}const F=a(o,[["render",l]]);export{_ as __pageData,F as default}; diff --git a/assets/develop_adapters_kook.md.17d969b2.js b/assets/develop_adapters_kook.md.17d969b2.js new file mode 100644 index 00000000..cdbd09e7 --- /dev/null +++ b/assets/develop_adapters_kook.md.17d969b2.js @@ -0,0 +1,5 @@ +import{_ as s,o as a,c as o,V as e}from"./chunks/framework.63f12d77.js";const F=JSON.parse('{"title":"KOOK 机器人","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/kook.md","filePath":"develop/adapters/kook.md","lastUpdated":1722566694000}'),n={name:"develop/adapters/kook.md"},t=e(`

KOOK 机器人

KOOK 是一款免费无广告的语音沟通工具,并提供了强大的官方机器人支持。

KOOK 适配器不需要 appid,只需要传入 应用的 websocket token 参数即可。

python
from amiyabot import KOOKBotInstance
+
+ws_token = '******' # websocket Token
+
+bot = AmiyaBot(token=ws_token, adapter=KOOKBotInstance)
`,4),p=[t];function l(r,c,i,y,d,D){return a(),o("div",null,p)}const k=s(n,[["render",l]]);export{F as __pageData,k as default}; diff --git a/assets/develop_adapters_kook.md.17d969b2.lean.js b/assets/develop_adapters_kook.md.17d969b2.lean.js new file mode 100644 index 00000000..e4e3a11a --- /dev/null +++ b/assets/develop_adapters_kook.md.17d969b2.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as o,V as e}from"./chunks/framework.63f12d77.js";const F=JSON.parse('{"title":"KOOK 机器人","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/kook.md","filePath":"develop/adapters/kook.md","lastUpdated":1722566694000}'),n={name:"develop/adapters/kook.md"},t=e("",4),p=[t];function l(r,c,i,y,d,D){return a(),o("div",null,p)}const k=s(n,[["render",l]]);export{F as __pageData,k as default}; diff --git a/assets/develop_adapters_mah.md.099962a3.js b/assets/develop_adapters_mah.md.099962a3.js new file mode 100644 index 00000000..1db316ab --- /dev/null +++ b/assets/develop_adapters_mah.md.099962a3.js @@ -0,0 +1,8 @@ +import{_ as a,o as s,c as t,V as p}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"mirai-api-http","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/mah.md","filePath":"develop/adapters/mah.md","lastUpdated":1722566694000}'),n={name:"develop/adapters/mah.md"},o=p(`

mirai-api-http

mirai-api-http 以下简称 mah。是一个在全平台下运行,提供 QQ Android 协议支持的高效率机器人库。

如要使用此适配器,需要 mah 同时开启了 websocket 和 http 服务。AmiyaBot 将通过 mirai_api_http 方法实例化它的适配器。

连接 mah

参数名类型释义默认值
hoststrmah 服务的 ip 地址
ws_portintmah 服务的 websocket 端口
http_portintmah 服务的 http 端口
python
from amiyabot.adapters.mirai import mirai_api_http
+
+qq = '******'       # 机器人的 QQ 号
+auth_key = '******' # mah 的 verifyKey
+
+adapter_service = mirai_api_http('127.0.0.1', 8060, 8080)
+
+bot = AmiyaBot(appid=qq, token=auth_key, adapter=adapter_service)
`,6),l=[o];function e(r,c,i,y,D,F){return s(),t("div",null,l)}const m=a(n,[["render",e]]);export{h as __pageData,m as default}; diff --git a/assets/develop_adapters_mah.md.099962a3.lean.js b/assets/develop_adapters_mah.md.099962a3.lean.js new file mode 100644 index 00000000..fbd4c2e9 --- /dev/null +++ b/assets/develop_adapters_mah.md.099962a3.lean.js @@ -0,0 +1 @@ +import{_ as a,o as s,c as t,V as p}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"mirai-api-http","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/mah.md","filePath":"develop/adapters/mah.md","lastUpdated":1722566694000}'),n={name:"develop/adapters/mah.md"},o=p("",6),l=[o];function e(r,c,i,y,D,F){return s(),t("div",null,l)}const m=a(n,[["render",e]]);export{h as __pageData,m as default}; diff --git a/assets/develop_adapters_onebot11.md.2dcd662d.js b/assets/develop_adapters_onebot11.md.2dcd662d.js new file mode 100644 index 00000000..798d35a6 --- /dev/null +++ b/assets/develop_adapters_onebot11.md.2dcd662d.js @@ -0,0 +1,8 @@ +import{_ as s,o as a,c as t,V as o}from"./chunks/framework.63f12d77.js";const B=JSON.parse('{"title":"OneBot v11 Beta","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/onebot11.md","filePath":"develop/adapters/onebot11.md","lastUpdated":1722566694000}'),n={name:"develop/adapters/onebot11.md"},e=o(`

OneBot v11 Beta

OneBot 11 以下简称 ob11。该标准是从原 CKYU 平台的 CQHTTP 插件接口修改而来的通用聊天机器人应用接口标准。
使用此适配器,可连接任何 OneBot 11 实现的机器人平台。

连接 onebot11

参数名类型释义默认值
hoststrob11 服务的 ip 地址
ws_portintob11 服务的 websocket 端口
http_portintob11 服务的 http 端口
python
from amiyabot.adapters.onebot.v11 import onebot11
+
+appid = '******'    # 机器人的账号(如需要)
+token = '******' # access-token
+
+adapter_service = onebot11('127.0.0.1', 8080, 8060)
+
+bot = AmiyaBot(appid=appid, token=token, adapter=adapter_service)
`,5),l=[e];function p(r,c,y,D,F,d){return a(),t("div",null,l)}const A=s(n,[["render",p]]);export{B as __pageData,A as default}; diff --git a/assets/develop_adapters_onebot11.md.2dcd662d.lean.js b/assets/develop_adapters_onebot11.md.2dcd662d.lean.js new file mode 100644 index 00000000..acf4eb0b --- /dev/null +++ b/assets/develop_adapters_onebot11.md.2dcd662d.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as t,V as o}from"./chunks/framework.63f12d77.js";const B=JSON.parse('{"title":"OneBot v11 Beta","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/onebot11.md","filePath":"develop/adapters/onebot11.md","lastUpdated":1722566694000}'),n={name:"develop/adapters/onebot11.md"},e=o("",5),l=[e];function p(r,c,y,D,F,d){return a(),t("div",null,l)}const A=s(n,[["render",p]]);export{B as __pageData,A as default}; diff --git a/assets/develop_adapters_onebot12.md.8cb31022.js b/assets/develop_adapters_onebot12.md.8cb31022.js new file mode 100644 index 00000000..31fee144 --- /dev/null +++ b/assets/develop_adapters_onebot12.md.8cb31022.js @@ -0,0 +1,8 @@ +import{_ as s,o as a,c as t,V as o}from"./chunks/framework.63f12d77.js";const B=JSON.parse('{"title":"OneBot v12 Beta","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/onebot12.md","filePath":"develop/adapters/onebot12.md","lastUpdated":1722566694000}'),n={name:"develop/adapters/onebot12.md"},e=o(`

OneBot v12 Beta

OneBot 12 以下简称 ob12 。是一个聊天机器人应用接口标准,旨在统一不同聊天平台上的机器人应用开发接口,使开发者只需编写一次业务逻辑代码即可应用到多种机器人平台。
使用此适配器,可连接任何 OneBot 12 实现的机器人平台。

连接 onebot12

参数名类型释义默认值
hoststrob12 服务的 ip 地址
ws_portintob12 服务的 websocket 端口
http_portintob12 服务的 http 端口
python
from amiyabot.adapters.onebot.v12 import onebot12
+
+appid = '******'    # 机器人的账号(如需要)
+token = '******' # access-token
+
+adapter_service = onebot12('127.0.0.1', 8080, 8060)
+
+bot = AmiyaBot(appid=appid, token=token, adapter=adapter_service)
`,5),l=[e];function p(r,c,y,D,F,d){return a(),t("div",null,l)}const A=s(n,[["render",p]]);export{B as __pageData,A as default}; diff --git a/assets/develop_adapters_onebot12.md.8cb31022.lean.js b/assets/develop_adapters_onebot12.md.8cb31022.lean.js new file mode 100644 index 00000000..247b73de --- /dev/null +++ b/assets/develop_adapters_onebot12.md.8cb31022.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as t,V as o}from"./chunks/framework.63f12d77.js";const B=JSON.parse('{"title":"OneBot v12 Beta","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/onebot12.md","filePath":"develop/adapters/onebot12.md","lastUpdated":1722566694000}'),n={name:"develop/adapters/onebot12.md"},e=o("",5),l=[e];function p(r,c,y,D,F,d){return a(),t("div",null,l)}const A=s(n,[["render",p]]);export{B as __pageData,A as default}; diff --git a/assets/develop_adapters_qqChannel.md.42bbea52.js b/assets/develop_adapters_qqChannel.md.42bbea52.js new file mode 100644 index 00000000..1a2d4af7 --- /dev/null +++ b/assets/develop_adapters_qqChannel.md.42bbea52.js @@ -0,0 +1,10 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"QQ 频道机器人","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/qqChannel.md","filePath":"develop/adapters/qqChannel.md","lastUpdated":1722566694000}'),o={name:"develop/adapters/qqChannel.md"},p=l(`

QQ 频道机器人

按照 基础指南 创建的机器人即为 QQ 频道机器人,无需额外的适配器。

事件分片

考虑到开发者事件接收时可以实现负载均衡,QQ 提供了分片逻辑,事件通知会落在不同的分片上,可参考官方文档 分片连接LoadBalance 了解分片机制。

创建分片连接需要使用分片适配器 qq_guild_shards

python
from amiyabot.adapters.tencent.qqGuild import qq_guild_shards
+
+bot1 = AmiyaBot(appid='...', token='...', adapter=qq_guild_shards(0, 2))
+bot2 = AmiyaBot(appid='...', token='...', adapter=qq_guild_shards(1, 2))

注意

每个分片的启动应当按顺序缓慢进行,切勿同时启动,以免 gateway 返回的信息一致造成连接失败。

python
# 仅作示意,实际上每个分片应当是独立的服务。
+def start():
+    asyncio.create_task(bot1.start())
+    time.sleep(2)
+    asyncio.create_task(bot2.start())

qq_guild_shards 参数

参数名类型释义默认值
shard_indexint分片下标,从 0 开始
shardsint分片总数

沙箱环境

使用 QQGuildSandboxBotInstance 适配器将 API 调用更改为沙箱环境。沙箱环境只会收到测试频道的事件,且调用 openapi 仅能操作测试频道。

python
from amiyabot.adapters.tencent.qqGuild import QQGuildSandboxBotInstance
+
+bot = AmiyaBot(..., adapter=QQGuildSandboxBotInstance)
`,12),t=[p];function e(c,r,F,y,D,i){return a(),n("div",null,t)}const B=s(o,[["render",e]]);export{A as __pageData,B as default}; diff --git a/assets/develop_adapters_qqChannel.md.42bbea52.lean.js b/assets/develop_adapters_qqChannel.md.42bbea52.lean.js new file mode 100644 index 00000000..c95ad998 --- /dev/null +++ b/assets/develop_adapters_qqChannel.md.42bbea52.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"QQ 频道机器人","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/qqChannel.md","filePath":"develop/adapters/qqChannel.md","lastUpdated":1722566694000}'),o={name:"develop/adapters/qqChannel.md"},p=l("",12),t=[p];function e(c,r,F,y,D,i){return a(),n("div",null,t)}const B=s(o,[["render",e]]);export{A as __pageData,B as default}; diff --git a/assets/develop_adapters_qqGlobal.md.51606d6f.js b/assets/develop_adapters_qqGlobal.md.51606d6f.js new file mode 100644 index 00000000..5574db22 --- /dev/null +++ b/assets/develop_adapters_qqGlobal.md.51606d6f.js @@ -0,0 +1,5 @@ +import{_ as s,o as a,c as l,V as n}from"./chunks/framework.63f12d77.js";const B=JSON.parse('{"title":"QQ 全域机器人 Beta","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/qqGlobal.md","filePath":"develop/adapters/qqGlobal.md","lastUpdated":1722566694000}'),o={name:"develop/adapters/qqGlobal.md"},t=n(`

QQ 全域机器人 Beta

全域机器人指同时支持群聊、消息记录和频道的机器人

创建全域适配器

全域适配器的参数和用法和QQ 群机器人一致,请参考文档。

创建后机器人能够同时接收到来自群聊、消息记录和频道的消息。

python
from amiyabot.adapters.tencent.qqGlobal import qq_global
+
+client_secret = '******' # 密钥
+
+bot = AmiyaBot(appid='******', token='******', adapter=qq_global(client_secret))
`,6),p=[t];function e(c,r,D,y,F,i){return a(),l("div",null,p)}const _=s(o,[["render",e]]);export{B as __pageData,_ as default}; diff --git a/assets/develop_adapters_qqGlobal.md.51606d6f.lean.js b/assets/develop_adapters_qqGlobal.md.51606d6f.lean.js new file mode 100644 index 00000000..bb96be15 --- /dev/null +++ b/assets/develop_adapters_qqGlobal.md.51606d6f.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as l,V as n}from"./chunks/framework.63f12d77.js";const B=JSON.parse('{"title":"QQ 全域机器人 Beta","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/qqGlobal.md","filePath":"develop/adapters/qqGlobal.md","lastUpdated":1722566694000}'),o={name:"develop/adapters/qqGlobal.md"},t=n("",6),p=[t];function e(c,r,D,y,F,i){return a(),l("div",null,p)}const _=s(o,[["render",e]]);export{B as __pageData,_ as default}; diff --git a/assets/develop_adapters_qqGroup.md.a8bb1495.js b/assets/develop_adapters_qqGroup.md.a8bb1495.js new file mode 100644 index 00000000..3ad47a6c --- /dev/null +++ b/assets/develop_adapters_qqGroup.md.a8bb1495.js @@ -0,0 +1,49 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"QQ 群机器人 Beta","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/qqGroup.md","filePath":"develop/adapters/qqGroup.md","lastUpdated":1722566694000}'),o={name:"develop/adapters/qqGroup.md"},p=l(`

QQ 群机器人 Beta

QQ 开放平台 完成企业主体入驻,即可创建可在 QQ 群聊里使用的 QQ 群机器人。

在公网下使用

QQ 群聊适配器需要在本地启动资源服务让腾讯端能够访问媒体资源,默认在公网下使用。如果无法在公网下部署,请参考自定义资源服务

python
from amiyabot.adapters.tencent.qqGroup import qq_group
+
+client_secret = '******' # 密钥
+
+bot = AmiyaBot(appid='******', token='******', adapter=qq_group(client_secret))

qq_group 参数

参数名类型释义默认值
client_secretstr机器人密钥
default_chain_builder默认消息构建器None
default_chain_builder_options默认消息构建器参数QQGroupChainBuilderOptions()
shard_indexint分片下标,从 0 开始0
shardsint分片总数1
  • 在机器人启动时,资源服务也会一同启动。
  • 默认的资源服务是端口单例的,实例化多个 QQ 群聊适配器 AmiyaBot 或使用 多账号 时,同一个端口的资源服务会相互共享。

事件分片

考虑到开发者事件接收时可以实现负载均衡,QQ 提供了分片逻辑,事件通知会落在不同的分片上,可参考官方文档 分片连接LoadBalance 了解分片机制。

python
bot1 = AmiyaBot(appid='...', token='...', adapter=qq_group(client_secret, shard_index=0, shards=2))
+bot2 = AmiyaBot(appid='...', token='...', adapter=qq_group(client_secret, shard_index=1, shards=2))

注意

每个分片的启动应当按顺序缓慢进行,切勿同时启动,以免 gateway 返回的信息一致造成连接失败。

python
# 仅作示意,实际上每个分片应当是独立的服务。
+def start():
+    asyncio.create_task(bot1.start())
+    time.sleep(2)
+    asyncio.create_task(bot2.start())

修改资源服务配置

引入 QQGroupChainBuilderOptions 修改默认的资源服务配置。

参数名类型释义默认值
hoststr资源服务监听地址0.0.0.0
portint资源服务监听端口8086
resource_pathstr临时文件存放目录./resource
http_server_optionsdictHttpServer **kwargs
python
from amiyabot.adapters.tencent.qqGroup import qq_group
+from amiyabot.adapters.tencent.qqGroup.builder import QQGroupChainBuilderOptions
+
+bot = AmiyaBot(
+    appid='******',
+    token='******',
+    adapter=qq_group(
+        client_secret='******',
+        default_chain_builder_options=QQGroupChainBuilderOptions(
+            '0.0.0.0',
+            8086,
+            './resource',
+        ),
+    ),
+)

自定义资源服务

多数情况下我们推荐使用第三方托管服务来搭建资源服务,如 腾讯云COS阿里云OSS 等。

通过自定义默认的 ChainBuilder,来实现上传文件到托管服务以及返回生成的 url。

继承 ChainBuilder 并实现相关方法。

可参考 进阶指南 - 介入媒体消息的构建过程

python
from typing import Union
+from graiax import silkcoder
+from amiyabot import ChainBuilder
+
+class MyBuilder(ChainBuilder):
+    @classmethod
+    async def get_image(cls, image: Union[str, bytes]) -> Union[str, bytes]:
+        # 上传图片到第三方托管服务
+        ...
+        return url # 返回访问资源的 URL
+
+    @classmethod
+    async def get_voice(cls, voice_file: str) -> str:
+        # 上传语音文件到第三方托管服务,语音文件必须是 silk 格式
+        voice: bytes = await silkcoder.async_encode(voice_file, ios_adaptive=True)
+        ...
+        return url # 返回访问资源的 URL
+
+    @classmethod
+    async def get_video(cls, video_file: str) -> str:
+        # 上传视频文件到第三方托管服务
+        ...
+        return url # 返回访问资源的 URL
+
+
+bot = AmiyaBot(..., adapter=qq_group(default_chain_builder=MyBuilder()))
`,22),t=[p];function e(c,r,y,F,D,i){return a(),n("div",null,t)}const d=s(o,[["render",e]]);export{A as __pageData,d as default}; diff --git a/assets/develop_adapters_qqGroup.md.a8bb1495.lean.js b/assets/develop_adapters_qqGroup.md.a8bb1495.lean.js new file mode 100644 index 00000000..29df666a --- /dev/null +++ b/assets/develop_adapters_qqGroup.md.a8bb1495.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"QQ 群机器人 Beta","description":"","frontmatter":{},"headers":[],"relativePath":"develop/adapters/qqGroup.md","filePath":"develop/adapters/qqGroup.md","lastUpdated":1722566694000}'),o={name:"develop/adapters/qqGroup.md"},p=l("",22),t=[p];function e(c,r,y,F,D,i){return a(),n("div",null,t)}const d=s(o,[["render",e]]);export{A as __pageData,d as default}; diff --git a/assets/develop_advanced_blockingIO.md.70c4539f.js b/assets/develop_advanced_blockingIO.md.70c4539f.js new file mode 100644 index 00000000..030f7384 --- /dev/null +++ b/assets/develop_advanced_blockingIO.md.70c4539f.js @@ -0,0 +1,7 @@ +import{_ as a,o as s,c as t,V as n}from"./chunks/framework.63f12d77.js";const _=JSON.parse('{"title":"处理 IO 阻塞的操作","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/blockingIO.md","filePath":"develop/advanced/blockingIO.md","lastUpdated":1722566694000}'),o={name:"develop/advanced/blockingIO.md"},l=n(`

处理 IO 阻塞的操作

AmiyaBot 为异步程序,一般情况下应该遵循异步编程来进行开发。但在使用一些标准或第三方库时,不能保证其方法是异步的,使用 IO 阻塞的方法容易造成线程阻塞,影响业务逻辑。

run_in_thread_pool

AmiyaBot util 库里提供的利用线程池将同步方法转变为异步方法执行的函数。

参数名类型释义默认值
block_funcCallableIO 阻塞的方法
*args原方法参数
**kwargs原方法字典参数
python
from amiyabot.util import run_in_thread_pool
+
+# IO 阻塞的方法
+block_io_method(arg1, arg2, arg3='xxx')
+
+# 转变为异步执行
+await run_in_thread_pool(block_io_method, arg1, arg2, arg3='xxx')
`,6),e=[l];function p(r,c,d,i,F,y){return s(),t("div",null,e)}const h=a(o,[["render",p]]);export{_ as __pageData,h as default}; diff --git a/assets/develop_advanced_blockingIO.md.70c4539f.lean.js b/assets/develop_advanced_blockingIO.md.70c4539f.lean.js new file mode 100644 index 00000000..8e8cf9d1 --- /dev/null +++ b/assets/develop_advanced_blockingIO.md.70c4539f.lean.js @@ -0,0 +1 @@ +import{_ as a,o as s,c as t,V as n}from"./chunks/framework.63f12d77.js";const _=JSON.parse('{"title":"处理 IO 阻塞的操作","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/blockingIO.md","filePath":"develop/advanced/blockingIO.md","lastUpdated":1722566694000}'),o={name:"develop/advanced/blockingIO.md"},l=n("",6),e=[l];function p(r,c,d,i,F,y){return s(),t("div",null,e)}const h=a(o,[["render",p]]);export{_ as __pageData,h as default}; diff --git a/assets/develop_advanced_chainBuilder.md.43e1e2e4.js b/assets/develop_advanced_chainBuilder.md.43e1e2e4.js new file mode 100644 index 00000000..11a794c2 --- /dev/null +++ b/assets/develop_advanced_chainBuilder.md.43e1e2e4.js @@ -0,0 +1,49 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"介入 Chain 构建媒体消息时的操作","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/chainBuilder.md","filePath":"develop/advanced/chainBuilder.md","lastUpdated":1722566694000}'),o={name:"develop/advanced/chainBuilder.md"},p=l(`

介入 Chain 构建媒体消息时的操作

Chain 对象在构建消息时,可使用辅助类介入媒体消息或浏览器的构建过程。

创建辅助类

继承 ChainBuilder 类并覆写其方法创建一个自定义的辅助类。在实例化 Chain 时,传入辅助类实例即可介入 Chain 的操作。

python
from typing import Union
+from amiyabot import Chain, ChainBuilder
+from playwright.async_api import Page
+
+class MyBuilder(ChainBuilder):
+    @classmethod
+    async def get_image(cls, image: Union[str, bytes]) -> Union[str, bytes]:
+        ...
+        return image
+
+    @classmethod
+    async def get_voice(cls, voice_file: str) -> str:
+        ...
+        return voice_file
+
+    @classmethod
+    async def get_video(cls, video_file: str) -> str:
+        ...
+        return video_file
+
+    @classmethod
+    async def on_page_rendered(cls, page: Page):
+        ...
+
+
+# 在构造参数里使用辅助类
+chain = Chain(..., chain_builder=MyBuilder())
+
+# 为属性赋值使用辅助类
+chain.builder = MyBuilder()

get_image

该函数会在 chain 构建图片消息时调用,每张图片调用一次。传入一个参数 image ,类型为 str(文件路径或 url) 或 bytes(图片字节数据)。
如果函数有返回值(必须是以上两种类型),chain 会使用返回值构建图片消息。

get_voice

该函数会在 chain 构建语音消息时调用,每个语音文件调用一次。传入文件路径 voice_file
如果函数有返回值,chain 会使用返回值构建语音消息。

get_video

该函数会在 chain 构建视频消息时调用,每个视频文件调用一次。传入文件路径 video_file
如果函数有返回值,chain 会使用返回值构建视频消息。

on_page_rendered

该函数会在 chain 构建浏览器渲染的图片并打开了页面时调用,提供了浏览器的 Page 对象,可在此对 Page 进行操作(如对页面进行 JS 注入等)。

提示

构建浏览器渲染的图片同样也会调用一次 get_image 函数。

使用示例

python
class BaiduSearch(ChainBuilder):
+    @classmethod
+    async def on_page_rendered(cls, page: Page):
+        """
+        可以在截图前先对页面进行操作,比如 ”百度一下“
+        """
+        await page.locator('#kw').fill('AmiyaBot')
+        await page.locator('#su').click()
+        await asyncio.sleep(2)
+
+
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    chain = Chain(data, chain_builder=BaiduSearch())
+
+    return chain.html(
+        'https://www.baidu.com/',
+        is_template=False,
+        render_time=1000,
+    )
`,16),e=[p];function t(c,r,y,D,F,i){return a(),n("div",null,e)}const d=s(o,[["render",t]]);export{A as __pageData,d as default}; diff --git a/assets/develop_advanced_chainBuilder.md.43e1e2e4.lean.js b/assets/develop_advanced_chainBuilder.md.43e1e2e4.lean.js new file mode 100644 index 00000000..d8e4de70 --- /dev/null +++ b/assets/develop_advanced_chainBuilder.md.43e1e2e4.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"介入 Chain 构建媒体消息时的操作","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/chainBuilder.md","filePath":"develop/advanced/chainBuilder.md","lastUpdated":1722566694000}'),o={name:"develop/advanced/chainBuilder.md"},p=l("",16),e=[p];function t(c,r,y,D,F,i){return a(),n("div",null,e)}const d=s(o,[["render",t]]);export{A as __pageData,d as default}; diff --git a/assets/develop_advanced_databaseSupport.md.91220591.js b/assets/develop_advanced_databaseSupport.md.91220591.js new file mode 100644 index 00000000..352443b8 --- /dev/null +++ b/assets/develop_advanced_databaseSupport.md.91220591.js @@ -0,0 +1,40 @@ +import{_ as s,o as a,c as n,V as t}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"数据库支持","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/databaseSupport.md","filePath":"develop/advanced/databaseSupport.md","lastUpdated":1722566694000}'),l={name:"develop/advanced/databaseSupport.md"},e=t(`

数据库支持

AmiyaBot 提供了 Sqlite 和 MySQL 数据库的 ORM 支持。基于 peewee ,封装了部分表结构管理以及查询转换。日常使用的查询操作详见 peewee文档

温馨提示

AmiyaBot 仅能提供有限的数据库支持,推荐你使用自己的更优的数据库解决方案

Sqlite

对于轻量级机器人应用,Sqlite 足以应对大部分的日常操作,connect_database 方法默认创建 Sqlite 数据库。

python
from amiyabot.database import *  # 引入数据库模块
+
+db = connect_database('database_name')  # 创建或连接一个 Sqlite 数据库文件
+
+
+# 创建数据库基础模型,继承 ModelClass 获得 AmiyaBot 的扩展查询方法
+class BotBaseModel(ModelClass):
+    class Meta:
+        database = db
+
+
+# 创建表模型,使用 table 装饰器进行表结构管理,将会自动创建或更新表结构
+@table
+class TableName(BotBaseModel):
+    field1 = CharField()
+    field2 = IntegerField(null=True)
+
+
+TableName.select()  # ORM 操作详见 peewee 文档

MySQL

connect_database 参数设置 mysql=True 以及 config 即可更改为 MySQL 数据库。

可自动创建数据库。

python
from amiyabot.database import *
+
+db = connect_database('database_name', is_mysql=True, config=MysqlConfig(
+    host='127.0.0.1',
+    port=3306,
+    user='root',
+    password=''
+))

表结构管理

在 table 装饰的表模型内增加或删除字段,启动程序时会自动修改到数据库表结构中。暂不支持更新字段类型。

python
@table
+class TableName(BotBaseModel):
+    field1 = CharField()
+    field2 = IntegerField(null=True)
+    field3 = TextField(null=True)
+    ...

扩展查询

内置了部分扩展查询,方便日常使用。

batch_insert

批量插入

参数名类型释义默认值
rowsList[dict]数据列表
chunk_sizeint分片插入大小200
python
data = [
+    {...},
+    {...},
+    {...}, ...
+]
+
+TableName.batch_insert(data)

insert_or_update

插入或更新(适配Sqlite和MySQL)

参数名类型释义默认值
insertdict如果是插入的数据
updatedict如果是更新的数据None
conflict_targetlist构成约束的列(仅Sqlite需要)None
preservelist一个列的列表,其值应从原始插入中保留None

查询转换工具

convert_model

将查询结果转换为字典

参数名类型释义默认值
modelpeewee 查询结果
select_modelSelectpeewee 查询对象
python
data = convert_model(TableName.get_or_none())

query_to_list

将查询结果转换为字典列表

参数名类型释义默认值
querylistpeewee 查询结果
select_modelSelectpeewee 查询对象
python
data = query_to_list(TableName.select())

select_for_paginate

分页查询工具

参数名类型释义默认值
modelModelSelectpeewee 查询对象
pageint当前页
page_sizeint页行数
python
data = select_for_paginate(TableName.select(), 1, 10)
+
+data['list']  # 查询结果
+data['total'] # 总条数
`,35),o=[e];function p(c,r,y,d,F,i){return a(),n("div",null,o)}const B=s(l,[["render",p]]);export{h as __pageData,B as default}; diff --git a/assets/develop_advanced_databaseSupport.md.91220591.lean.js b/assets/develop_advanced_databaseSupport.md.91220591.lean.js new file mode 100644 index 00000000..c7dc430d --- /dev/null +++ b/assets/develop_advanced_databaseSupport.md.91220591.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as t}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"数据库支持","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/databaseSupport.md","filePath":"develop/advanced/databaseSupport.md","lastUpdated":1722566694000}'),l={name:"develop/advanced/databaseSupport.md"},e=t("",35),o=[e];function p(c,r,y,d,F,i){return a(),n("div",null,o)}const B=s(l,[["render",p]]);export{h as __pageData,B as default}; diff --git a/assets/develop_advanced_eventBus.md.885a83aa.js b/assets/develop_advanced_eventBus.md.885a83aa.js new file mode 100644 index 00000000..5239c7aa --- /dev/null +++ b/assets/develop_advanced_eventBus.md.885a83aa.js @@ -0,0 +1,6 @@ +import{_ as s,o as t,c as a,V as n}from"./chunks/framework.63f12d77.js";const D=JSON.parse('{"title":"事件总线","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/eventBus.md","filePath":"develop/advanced/eventBus.md","lastUpdated":1722566694000}'),e={name:"develop/advanced/eventBus.md"},l=n(`

事件总线

AmiyaBot 提供了简易的全局事件总线的方法

python
from amiyabot import event_bus

发布事件

publish

参数名类型释义默认值
event_namestr事件名
dataAny事件数据None
python
event_bus.publish('myEvent', data=...)

订阅事件

subscribe

参数名类型释义默认值
event_namestr事件名
methodCallable响应方法(可选)None

提示

响应方法同时支持异步同步函数

通过装饰器订阅事件

python
@event_bus.subscribe('myEvent')
+async def event_handler(data):
+    ...

也可以通过传入响应函数订阅事件

python
async def event_handler(data):
+    ...
+
+event_bus.subscribe('myEvent', event_handler)

取消订阅

取消订阅需要传入订阅时的响应方法对象(且需要保证其内存地址是一致的)

unsubscribe

参数名类型释义默认值
event_namestr事件名
methodCallable响应方法None
python
event_bus.unsubscribe('myEvent', event_handler)
`,20),o=[l];function p(r,c,d,y,i,h){return t(),a("div",null,o)}const b=s(e,[["render",p]]);export{D as __pageData,b as default}; diff --git a/assets/develop_advanced_eventBus.md.885a83aa.lean.js b/assets/develop_advanced_eventBus.md.885a83aa.lean.js new file mode 100644 index 00000000..8d1e2792 --- /dev/null +++ b/assets/develop_advanced_eventBus.md.885a83aa.lean.js @@ -0,0 +1 @@ +import{_ as s,o as t,c as a,V as n}from"./chunks/framework.63f12d77.js";const D=JSON.parse('{"title":"事件总线","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/eventBus.md","filePath":"develop/advanced/eventBus.md","lastUpdated":1722566694000}'),e={name:"develop/advanced/eventBus.md"},l=n("",20),o=[l];function p(r,c,d,y,i,h){return t(),a("div",null,o)}const b=s(e,[["render",p]]);export{D as __pageData,b as default}; diff --git a/assets/develop_advanced_httpRequests.md.d5ec3c2e.js b/assets/develop_advanced_httpRequests.md.d5ec3c2e.js new file mode 100644 index 00000000..06ac20c6 --- /dev/null +++ b/assets/develop_advanced_httpRequests.md.d5ec3c2e.js @@ -0,0 +1,17 @@ +import{_ as t,o as s,c as a,V as o}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"发送 HTTP 请求","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/httpRequests.md","filePath":"develop/advanced/httpRequests.md","lastUpdated":1722566694000}'),n={name:"develop/advanced/httpRequests.md"},l=o(`

发送 HTTP 请求

AmiyaBot 内置了异步的 HTTP 请求工具,基于 aiohttp

不推荐使用 requests 库

requests 是著名的 python http 请求工具库。但其请求方法均为同步的。AmiyaBot 为异步程序,使用同步请求将会阻塞主线程运行。

如果是无法干预的同步请求行为,可以使用内置的线程池方法更变为异步。详见 处理阻塞操作

直接引入 http_requests 实例和 download_async 方法即可使用。

python
from amiyabot.network.httpRequests import http_requests
+from amiyabot.network.download import download_async
+
+await http_requests.get()
+await http_requests.post()
+await http_requests.post_form()
+await http_requests.post_upload()
+await http_requests.request()
+await download_async()

返回值

http_requests 的请求均返回字符串的请求结果(如果请求失败会返回空字符串),但有些不一样。这个 “字符串” 可以使用一些额外的属性。

json

调用这个属性会尝试返回 json 格式化的 responseText 内容。

python
res = await http_requests.post('/interface', {...})
+if res:
+    data = res.json['data']

response

调用这个属性可以返回请求结果(aiohttp.ClientResponse 的实例),可以获取请求的状态码和其他信息。

python
res = await http_requests.post('/interface', {...})
+
+status = res.response.status

error

如果请求失败,可以调用这个属性获取异常(Exception 的实例)。

python
res = await http_requests.post('/interface', {...})
+
+error = res.error

GET 请求

python
res: str = await http_requests.get()
参数名类型释义默认值
interfacestr请求地址
**kwargsrequest 参数

POST 请求

post 方法默认在请求头内添加 'Content-Type': 'application/json',请求体仅接受字典或列表类型数据

python
res: str = await http_requests.post()
参数名类型释义默认值
interfacestr请求地址
payloaddict, list请求体
headersdict追加的请求头
**kwargsrequest 参数

FORM 表单请求

post_form 方法类似 post 方法。唯一不同的是请求体仅接受字典类型,发送请求时会被构建为 form data 表单数据。

python
res: str = await http_requests.post_form()
参数名类型释义默认值
interfacestr请求地址
payloaddict请求体
headersdict追加的请求头
**kwargsrequest 参数

文件上传

文件上传 post_upload 方法以 form 表单的方式提交文件。

python
res: str = await http_requests.post_upload()
参数名类型释义默认值
interfacestr请求地址
filebytes文件 bytes
filenamestr文件名file
file_fieldstr表单数据中存放文件的字段名file
payloaddict请求体
headersdict追加的请求头
**kwargsrequest 参数

自定义请求

如果需要发送更多类型的请求,如 PUTPATCHDELETE 等,或需要自定义更多的请求场景,可使用 request 方法。

python
res: str = await http_requests.request()
参数名类型释义默认值
urlstr请求地址
methoddict请求方法post
request_namedict请求过程的 LOG 标识
**kwargsrequest 参数

下载文件

download_async 是提供的异步下载文件的方法。默认返回 bytes 类型的数据。

python
file: bytes = await download_async()
参数名类型释义默认值
urlstr请求地址
headersdict追加的请求头
stringifybool是否返回字符串结果False
**kwargsrequest 参数

同步下载

如某些场景需要使用同步下载,可使用同模块中的 download_async 方法。

python
from amiyabot.network.download import download_sync
+
+file: bytes = download_sync()
参数名类型释义默认值
urlstr请求地址
headersdict追加的请求头
stringifybool是否返回字符串结果False
progressbool是否显示进度条False
**kwargsrequest 参数
`,43),e=[l];function p(r,d,c,y,i,D){return s(),a("div",null,e)}const B=t(n,[["render",p]]);export{h as __pageData,B as default}; diff --git a/assets/develop_advanced_httpRequests.md.d5ec3c2e.lean.js b/assets/develop_advanced_httpRequests.md.d5ec3c2e.lean.js new file mode 100644 index 00000000..3537fb39 --- /dev/null +++ b/assets/develop_advanced_httpRequests.md.d5ec3c2e.lean.js @@ -0,0 +1 @@ +import{_ as t,o as s,c as a,V as o}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"发送 HTTP 请求","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/httpRequests.md","filePath":"develop/advanced/httpRequests.md","lastUpdated":1722566694000}'),n={name:"develop/advanced/httpRequests.md"},l=o("",43),e=[l];function p(r,d,c,y,i,D){return s(),a("div",null,e)}const B=t(n,[["render",p]]);export{h as __pageData,B as default}; diff --git a/assets/develop_advanced_httpSupport.md.82709c73.js b/assets/develop_advanced_httpSupport.md.82709c73.js new file mode 100644 index 00000000..5d6687e4 --- /dev/null +++ b/assets/develop_advanced_httpSupport.md.82709c73.js @@ -0,0 +1,21 @@ +import{_ as s,o as a,c as n,V as t}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"HTTP服务器支持","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/httpSupport.md","filePath":"develop/advanced/httpSupport.md","lastUpdated":1722566694000}'),l={name:"develop/advanced/httpSupport.md"},o=t(`

HTTP服务器支持

AmiyaBot 内置了基于 FastApi 的HTTP服务构建工具。

创建服务

HttpServer 类

参数名类型释义默认值
hoststr服务监听地址
portint服务监听端口
titlestrswagger 页面标题AmiyaBot
descriptionstrswagger 页面注释https://www.amiyabot.com
auth_keystr请求头密钥
fastapi_optionsdictFastAPI **kwargs
uvicorn_optionsdictuvicorn.Config **kwargs
python
from amiyabot import HttpServer
+
+server = HttpServer(host='0.0.0.0', port=8088)
+
+
+@server.controller
+class Bot:
+    @server.route(method='get')
+    async def get_name(self):
+        return 'AmiyaBot'
+
+    @server.route(method='post')
+    async def say_hello(self):
+        return server.response(message='hello')
+
+
+asyncio.run(server.serve())

运行代码,访问 http://127.0.0.1:8088/docs 即可看到生成了如下两个接口。

/bot/getName
+/bot/sayHello

自定义路由

接口的路由将默认使用控制器类名以及方法名组成,如果需要自定义路由,在方法装饰器 route 传入 router_path 参数即可。

python
@server.route(method='get', router_path='/custom/getBotName')
+async def get_name(self):
+    ...

请求头密钥

在创建 HttpServer 时传入 auth_key 参数,则在调用接口时,需要在请求头(Header)里添加 authKey 字段并匹配参数的值,才允许访问。

python
server = HttpServer(..., auth_key='my_auth_key')

FastApi 扩展

AmiyaBot 仅对 FastApi 的路由注册做了简易的封装。如需要扩展其用法,可获取 app 实例后参考官方文档进一步使用。

python
server = HttpServer()
+app: FastAPI = server.app
`,17),p=[o];function e(r,c,y,F,D,i){return a(),n("div",null,p)}const A=s(l,[["render",e]]);export{h as __pageData,A as default}; diff --git a/assets/develop_advanced_httpSupport.md.82709c73.lean.js b/assets/develop_advanced_httpSupport.md.82709c73.lean.js new file mode 100644 index 00000000..9b1c5b7f --- /dev/null +++ b/assets/develop_advanced_httpSupport.md.82709c73.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as t}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"HTTP服务器支持","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/httpSupport.md","filePath":"develop/advanced/httpSupport.md","lastUpdated":1722566694000}'),l={name:"develop/advanced/httpSupport.md"},o=t("",17),p=[o];function e(r,c,y,F,D,i){return a(),n("div",null,p)}const A=s(l,[["render",e]]);export{h as __pageData,A as default}; diff --git a/assets/develop_advanced_index.md.5155177e.js b/assets/develop_advanced_index.md.5155177e.js new file mode 100644 index 00000000..e11e63ce --- /dev/null +++ b/assets/develop_advanced_index.md.5155177e.js @@ -0,0 +1 @@ +import{_ as t,o,c as d,C as e,a}from"./chunks/framework.63f12d77.js";const v=JSON.parse('{"title":"进阶指南","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/index.md","filePath":"develop/advanced/index.md","lastUpdated":1722566694000}'),n={name:"develop/advanced/index.md"},s=e("h1",{id:"进阶指南",tabindex:"-1"},[a("进阶指南 "),e("a",{class:"header-anchor",href:"#进阶指南","aria-label":'Permalink to "进阶指南"'},"​")],-1),c=e("p",null,"本篇章将会深入讲解 AmiyaBot 的一些高级用法。包括如何控制日志、介入生命周期、创建定时任务、加载插件以及额外支持的数据库 ORM 和 HTTP 服务等。这将有助于你构建一个复杂的,更有逻辑性的机器人。",-1),i=e("p",null,[a("和基础开发指南一样,在本章后续文档中,为了减少篇幅量,将不会再在代码示例中出现 AmiyaBot 类的实例化代码。统一以变量 "),e("code",null,"bot"),a(" 表示已经实例化的 AmiyaBot 类。")],-1),r=[s,c,i];function l(_,p,m,h,f,x){return o(),d("div",null,r)}const B=t(n,[["render",l]]);export{v as __pageData,B as default}; diff --git a/assets/develop_advanced_index.md.5155177e.lean.js b/assets/develop_advanced_index.md.5155177e.lean.js new file mode 100644 index 00000000..e11e63ce --- /dev/null +++ b/assets/develop_advanced_index.md.5155177e.lean.js @@ -0,0 +1 @@ +import{_ as t,o,c as d,C as e,a}from"./chunks/framework.63f12d77.js";const v=JSON.parse('{"title":"进阶指南","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/index.md","filePath":"develop/advanced/index.md","lastUpdated":1722566694000}'),n={name:"develop/advanced/index.md"},s=e("h1",{id:"进阶指南",tabindex:"-1"},[a("进阶指南 "),e("a",{class:"header-anchor",href:"#进阶指南","aria-label":'Permalink to "进阶指南"'},"​")],-1),c=e("p",null,"本篇章将会深入讲解 AmiyaBot 的一些高级用法。包括如何控制日志、介入生命周期、创建定时任务、加载插件以及额外支持的数据库 ORM 和 HTTP 服务等。这将有助于你构建一个复杂的,更有逻辑性的机器人。",-1),i=e("p",null,[a("和基础开发指南一样,在本章后续文档中,为了减少篇幅量,将不会再在代码示例中出现 AmiyaBot 类的实例化代码。统一以变量 "),e("code",null,"bot"),a(" 表示已经实例化的 AmiyaBot 类。")],-1),r=[s,c,i];function l(_,p,m,h,f,x){return o(),d("div",null,r)}const B=t(n,[["render",l]]);export{v as __pageData,B as default}; diff --git a/assets/develop_advanced_lifeCycle.md.05397678.js b/assets/develop_advanced_lifeCycle.md.05397678.js new file mode 100644 index 00000000..c65a8907 --- /dev/null +++ b/assets/develop_advanced_lifeCycle.md.05397678.js @@ -0,0 +1,22 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const e="/assets/lifeCycle.3a881ce1.svg",d=JSON.parse('{"title":"生命周期","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/lifeCycle.md","filePath":"develop/advanced/lifeCycle.md","lastUpdated":1722566694000}'),o={name:"develop/advanced/lifeCycle.md"},p=l('

生命周期

AmiyaBot 接收的消息和事件,都会历经一个完整的生命周期。你可以介入这些周期来对业务进行进一步的调整。

消息生命周期

在接收消息到回复发送完毕,总共会经过至少五个周期,如下图所示,紫色的节点就是可以介入的周期。

如果消息响应里存在等待事件,那么周期将会延长,再次从消息接收开始,直至等待事件结束后继续向下执行。

通过 AmiyaBot 对象或 PluginInstance 对象注册周期钩子函数。

所有钩子均可以同时存在多个,按加载顺序逐个调用。

message_created

消息创建完毕阶段,可以在此阶段修改 Message 对象并返回。存在多个此钩子时,按加载顺序逐个调用,参数接受的 Message 对象受上一个函数的执行结果影响。

该钩子函数可返回三种结果:

  • None:对后续不产生影响
  • Message:修改 Message 对象,将影响后续所有周期进程的参数
  • False:布尔值仅可返回 False,将结束生命周期(包括此周期后续的钩子函数)
python
@bot.message_created
+async def _(data: Message, instance: BotAdapterProtocol):
+    if ...:
+        data.text = ...
+        return data

message_before_waiter_set

当存在等待事件且消息分配器无返回或等待事件属于强制等待类型时,在进入等待事件前执行此钩子。

python
from amiyabot import Waiter
+
+@bot.message_before_waiter_set
+async def _(data: Message, waiter: Waiter, instance: BotAdapterProtocol):
+    ...

message_before_handle

当消息分配器有返回,在执行消息响应器前执行此钩子。存在多个此钩子时,按加载顺序逐个调用。全部执行完成后当有其中一个返回 False,则不往下继续执行并结束生命周期。

python
@bot.message_before_handle
+async def _(data: Message, factory_name: str, instance: BotAdapterProtocol):
+    if ...:
+        return False
+    return True

message_before_send

当消息响应器执行完毕且存在返回时,在发送其返回前执行此钩子。可以在此阶段修改 Chain 对象并返回。存在多个此钩子时,按加载顺序逐个调用,参数接受的 Chain 对象受上一个函数的执行结果影响。

python
@bot.message_before_send
+async def _(chain: Chain, factory_name: str, instance: BotAdapterProtocol):
+    ...
+    return chain

message_after_send

当消息响应器执行完毕且存在返回时,在发送其返回结束后执行此钩子。

python
@bot.message_after_send
+async def _(chain: Chain, factory_name: str, instance: BotAdapterProtocol):
+    ...

message_after_handle

当消息响应器执行完毕(无论有没有返回)后执行此钩子。

python
@bot.message_after_handle
+async def _(chain: Optional[Chain], factory_name: str, instance: BotAdapterProtocol):
+    ...

事件生命周期

目前事件生命周期只有一个。

python
@bot.event_created
+async def _(event: EventType, instance: BotAdapterProtocol):
+    ...
`,31),t=[p];function c(r,y,D,i,F,B){return a(),n("div",null,t)}const h=s(o,[["render",c]]);export{d as __pageData,h as default}; diff --git a/assets/develop_advanced_lifeCycle.md.05397678.lean.js b/assets/develop_advanced_lifeCycle.md.05397678.lean.js new file mode 100644 index 00000000..950cdaaf --- /dev/null +++ b/assets/develop_advanced_lifeCycle.md.05397678.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const e="/assets/lifeCycle.3a881ce1.svg",d=JSON.parse('{"title":"生命周期","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/lifeCycle.md","filePath":"develop/advanced/lifeCycle.md","lastUpdated":1722566694000}'),o={name:"develop/advanced/lifeCycle.md"},p=l("",31),t=[p];function c(r,y,D,i,F,B){return a(),n("div",null,t)}const h=s(o,[["render",c]]);export{d as __pageData,h as default}; diff --git a/assets/develop_advanced_loadPlugins.md.05064a96.js b/assets/develop_advanced_loadPlugins.md.05064a96.js new file mode 100644 index 00000000..e75a6f63 --- /dev/null +++ b/assets/develop_advanced_loadPlugins.md.05064a96.js @@ -0,0 +1,48 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"加载插件","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/loadPlugins.md","filePath":"develop/advanced/loadPlugins.md","lastUpdated":1722566694000}'),p={name:"develop/advanced/loadPlugins.md"},o=l(`

加载插件

本篇将会讲解 AmiyaBot 插件的工作原理以及插件导入和卸载的方法。

前言

插件设计的目的是因为 兔兔-v6 通常会以可执行文件的形式发布,将一些功能模块分散为插件的形式,更有助于用户灵活的管理自己的机器人功能,以及对单独的功能进行热更新。

AmiyaBot 的插件加载得益于 Python 作为脚本语言的一个优点:动态执行代码,配合标准库的 importlibzipimport,就能够很好的完成外部代码的导入与执行,理解这一原理,需要你熟悉 Python 的导入机制。而“动态执行代码”,如果你不是第一次接触脚本语言,想必你对其应有了一定的了解。

开发插件

开发插件可以参考主项目的 插件开发 形式,但本篇并不是作为主项目的引导文档。在主项目里,插件是一个 zip 压缩包,在加载时解压并导入,完成代码的动态执行。

但在本框架的设计里,插件还能有另外几种导入方式。

导入插件实例

插件实例可以直接在你的程序里定义,这是正常的做法,事实上这对你的功能管理(如动态增加或软删除功能时)有很大帮助。

python
from amiyabot import AmiyaBot, PluginInstance
+
+plugin = PluginInstance(
+    name='我的插件',
+    version='1.0',
+    plugin_id='my-plugin',
+    description='我的第一个插件'
+)
+
+@plugin.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')
+
+
+bot = AmiyaBot(...)  # or MultipleAccounts
+bot.install_plugin(plugin)

此时,该 AmiyaBot 实例便拥有了这个插件定义的所有消息响应、事件或定时任务等功能。

导入 Python 文件

这是写有插件注册代码的一个 Python 文件 myPlugin.py

python
from amiyabot import PluginInstance
+
+# bot 变量名是必须的,详见插件开发文档。
+bot = PluginInstance(
+    name='我的插件',
+    version='1.0',
+    plugin_id='my-plugin',
+    description='我的第一个插件'
+)
+
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')

以 Python 文件导入这个插件

python
bot.install_plugin('myPlugin.py') # 相当于执行了代码:import myPlugin

单文件插件是最简单的开发方式,这是在不考虑文件大小、静态资源或变量污染的前提下。

导入 Python Package 目录

如果一个插件的逻辑非常复杂,它可能会是以 Package 目录的形式存在。此时插件的目录应如下所示。

text
myPlugin
+├── __init__.py
+├── a.py
+├── b.py
+│   ...
+...

以目录导入这个插件

python
bot.install_plugin('myPlugin') # 相当于执行了代码:import myPlugin

导入 zip 压缩包

如果一些插件甚至带有静态资源,虽然 Package 目录同样能实现,但为了方便传播,它可能会是一个 zip 压缩文件。

text
myPlugin.zip
+├── assetsFolder
+├── config.yaml
+├── __init__.py
+├── a.py
+├── b.py
+│   ...
+...

以 zip 导入这个插件

python
bot.install_plugin('myPlugin.zip')

这里将会发生另一种情况,在 zip 导入时,并不是像上述两种方式一样相当于执行
import myPlugin 语句。而是通过标准库 zipimport,读取了此压缩包,并执行 __init__.py

这有点抽象,你可以理解为使用了 python 命令执行了 __init__.py

bash
python __init__.py

那么当 __init__.py 在相对导入其目录下的模块时,由于它属于顶级模块,插件将会 加载失败 并抛出如下异常。

python
from .main import bot
text
plugin install error: Traceback (most recent call last):
+  File "F:\\Project\\Amiya-Bot-core\\amiyabot\\log\\manager.py", line 116, in sync_catch
+    yield
+  File "F:\\Project\\Amiya-Bot-core\\amiyabot\\handler\\__init__.py", line 287, in install_plugin
+    module = zipimport.zipimporter(plugin).load_module('__init__')
+  File "<frozen zipimport>", line 259, in load_module
+  File "plugins\\myPlugin.zip\\__init__.py", line 1, in <module>
+    from .main import bot
+ImportError: attempted relative import with no known parent package

install_plugin 里提供了参数解决这一问题。先看看这个方法的参数列表。

参数名类型释义默认值
pluginstr, PluginInstance插件(文件、package 的路径或 PluginInstance 实例)
extract_pluginbool是否解压插件False
extract_plugin_deststr插件解压后的目录名(默认为 zip 文件名)

解决上述问题,我们只需要添加参数 extract_plugin=True,将 zip 导入转换为 Package 目录导入。

python
bot.install_plugin('myPlugin.zip', extract_plugin=True)

注意

每次执行加载时都会解压一次全部文件,但如果路径已存在,将不会覆盖原文件。如果插件有一些原文件修改的更新,应注意这一特性。

卸载插件

插件实例都有一个唯一 ID(属性 plugin_id),通过这个 ID 可以卸载指定的插件。

uninstall_plugin

参数名类型释义默认值
plugin_idstr插件 ID
removebool是否删除插件的原文件False
python
bot.uninstall_plugin('my-plugin')
`,44),t=[o];function e(c,r,i,y,F,D){return a(),n("div",null,t)}const A=s(p,[["render",e]]);export{h as __pageData,A as default}; diff --git a/assets/develop_advanced_loadPlugins.md.05064a96.lean.js b/assets/develop_advanced_loadPlugins.md.05064a96.lean.js new file mode 100644 index 00000000..314362f0 --- /dev/null +++ b/assets/develop_advanced_loadPlugins.md.05064a96.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"加载插件","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/loadPlugins.md","filePath":"develop/advanced/loadPlugins.md","lastUpdated":1722566694000}'),p={name:"develop/advanced/loadPlugins.md"},o=l("",44),t=[o];function e(c,r,i,y,F,D){return a(),n("div",null,t)}const A=s(p,[["render",e]]);export{h as __pageData,A as default}; diff --git a/assets/develop_advanced_logger.md.58165055.js b/assets/develop_advanced_logger.md.58165055.js new file mode 100644 index 00000000..ec29e172 --- /dev/null +++ b/assets/develop_advanced_logger.md.58165055.js @@ -0,0 +1,49 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const B=JSON.parse('{"title":"日志模块","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/logger.md","filePath":"develop/advanced/logger.md","lastUpdated":1722566694000}'),o={name:"develop/advanced/logger.md"},p=l(`

日志模块

AmiyaBot 使用 logging 模块构建日志体系。

输出日志

AmiyaBot 的日志同样拥有与 logging 相同的等级输出。输出的日志会储存在 log 文件夹下。

python
from amiyabot import log
+
+log.info(...)
+log.error(...)
+log.debug(...)
+log.warning(...)
+log.critical(...)

日志的固有格式如下所示,分别为时间日志模块名日志等级日志内容。DEBUG 模式下会显示日志的输出文件名和位置。

normal:
+2022-11-02 18:22:40,425 [     Bot][    INFO] initialize completed.
+
+debug mode:
+2022-11-02 18:22:40,425 [     Bot][    INFO][test.py:5] initialize completed.

提示

使用启动参数 --debug 开启 DEBUG 模式。

输出异常日志

log.error() 方法不仅可以传入字符串,也支持传入 Exception 的子类。传入 Exception 子类时,将会输出完整的异常追踪(Traceback)。

python
try:
+    a = 0
+    a += '1'
+except Exception as e:
+    log.error(e, desc='calc error:')

将输出如下日志

2022-11-02 18:44:22,155 [     Bot][   ERROR] calc error: Traceback (most recent call last):
+  File "F:\\Project\\Amiya-Bot-core\\logTest.py", line 5, in <module>
+    a += '1'
+TypeError: unsupported operand type(s) for +=: 'int' and 'str'

如果你并不需要处理异常,仅仅希望异常不会终止你的程序,log 模块提供了上下文管理的方式,来捕获并输出在上下文中产出的异常。

参数名类型释义默认值
descstr异常标题
ignoreList[Type[Exception]]仅捕获但不输出的异常列表None
handlerCallable捕获异常后执行的方法None
python
async def err_handler(err: Exception):
+    print(err)
+
+# 异步方式
+async with log.catch('calc error:', ignore=[TypeError, ...], handler=err_handler):
+    a = 0
+    a += '1'
+
+# 同步方式
+with log.sync_catch(...):
+    a = 0
+    a += '1'

创建日志模块

你可以创建一个独立的日志模块以标记输出。

python
from amiyabot.log import LoggerManager
+
+logger = LoggerManager('MyLogger')
+logger.info('this is a log.')
+
+# 2022-11-02 18:32:05,053 [MyLogger][    INFO] this is a log.

LoggerManager

参数名类型释义默认值
namestrlogger 模块名称
levelint日志等级logging.INFO
formatterstr日志格式%(asctime)s [%(name)8s][%(levelname)8s]%(message)s
save_pathstr日志文件保存目录log
save_filenamestr日志文件名running

自定义全局日志模块

如果你不喜欢默认的日志输出,你也可以全局修改日志模块。但必须注意的事,你自定义的模块,必须包含常规的几个等级输出方法。

python
from amiyabot.log import UserLogger
+
+
+class Mylogger:
+    def info(self, text: str): ...
+
+    def error(self, text: str): ...
+
+    def debug(self, text: str): ...
+
+    def warning(self, text: str): ...
+
+    def critical(self, text: str): ...
+
+
+UserLogger.logger = Mylogger() # 将默认日志处理替换为自定义的类
`,24),t=[p];function e(c,r,y,F,D,i){return a(),n("div",null,t)}const A=s(o,[["render",e]]);export{B as __pageData,A as default}; diff --git a/assets/develop_advanced_logger.md.58165055.lean.js b/assets/develop_advanced_logger.md.58165055.lean.js new file mode 100644 index 00000000..ed300ab9 --- /dev/null +++ b/assets/develop_advanced_logger.md.58165055.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const B=JSON.parse('{"title":"日志模块","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/logger.md","filePath":"develop/advanced/logger.md","lastUpdated":1722566694000}'),o={name:"develop/advanced/logger.md"},p=l("",24),t=[p];function e(c,r,y,F,D,i){return a(),n("div",null,t)}const A=s(o,[["render",e]]);export{B as __pageData,A as default}; diff --git a/assets/develop_advanced_playwright.md.8235080e.js b/assets/develop_advanced_playwright.md.8235080e.js new file mode 100644 index 00000000..ded1109c --- /dev/null +++ b/assets/develop_advanced_playwright.md.8235080e.js @@ -0,0 +1,24 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"改变 Playwright 启动","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/playwright.md","filePath":"develop/advanced/playwright.md","lastUpdated":1722566694000}'),p={name:"develop/advanced/playwright.md"},o=l(`

改变 Playwright 启动

改变默认的 Playwright 启动行为。

python
from playwright.async_api import Playwright, Browser
+from amiyabot import BrowserLaunchConfig
+
+
+class MyBrowserLauncher(BrowserLaunchConfig):
+    def __init__(self):
+        super().__init__()
+
+        self.browser_type = 'firefox'  # 修改浏览器属性
+
+    # 或改写 launch_browser 方法
+    async def launch_browser(self, playwright: Playwright) -> Browser:
+        ...
+
+        # 返回通过任意方式创建的 Browser 对象
+        # return await playwright.webkit.launch()
+        # return await playwright.chromium.launch()
+        return await playwright.firefox.launch()
+
+
+bot = AmiyaBot()
+asyncio.run(
+    bot.start(launch_browser=MyBrowserLauncher())
+)
`,3),t=[o];function e(c,r,y,i,D,F){return a(),n("div",null,t)}const E=s(p,[["render",e]]);export{A as __pageData,E as default}; diff --git a/assets/develop_advanced_playwright.md.8235080e.lean.js b/assets/develop_advanced_playwright.md.8235080e.lean.js new file mode 100644 index 00000000..a42f2cb2 --- /dev/null +++ b/assets/develop_advanced_playwright.md.8235080e.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"改变 Playwright 启动","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/playwright.md","filePath":"develop/advanced/playwright.md","lastUpdated":1722566694000}'),p={name:"develop/advanced/playwright.md"},o=l("",3),t=[o];function e(c,r,y,i,D,F){return a(),n("div",null,t)}const E=s(p,[["render",e]]);export{A as __pageData,E as default}; diff --git a/assets/develop_advanced_startupParameter.md.ca7b0373.js b/assets/develop_advanced_startupParameter.md.ca7b0373.js new file mode 100644 index 00000000..1b0f452d --- /dev/null +++ b/assets/develop_advanced_startupParameter.md.ca7b0373.js @@ -0,0 +1 @@ +import{_ as t,o as a,c as e,V as s}from"./chunks/framework.63f12d77.js";const _=JSON.parse('{"title":"启动参数","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/startupParameter.md","filePath":"develop/advanced/startupParameter.md","lastUpdated":1722566694000}'),d={name:"develop/advanced/startupParameter.md"},r=s('

启动参数

使用启动参数修改一些内置变量

参数是否需要值默认值释义
--debug以 DEBUG 模式启动程序
--browser-width1280浏览器视窗默认宽度(px)
--browser-height720浏览器视窗默认高度(px)
--browser-render-time200浏览器默认渲染时间(ms)
--text-max-length100Chain 对象转换文字图片的文字长度最大值
--browser-page-not-close取消自动关闭 playwright 的网页窗口

在 兔兔-v6 下使用

代码部署

bash
python amiya.py --text-max-length 200 --browser-render-time 1000

可执行文件部署

bash
AmiyaBot-v6.x.x-master.exe --debug --browser-page-not-close
',8),o=[r];function n(l,p,c,i,h,m){return a(),e("div",null,o)}const b=t(d,[["render",n]]);export{_ as __pageData,b as default}; diff --git a/assets/develop_advanced_startupParameter.md.ca7b0373.lean.js b/assets/develop_advanced_startupParameter.md.ca7b0373.lean.js new file mode 100644 index 00000000..e14b6917 --- /dev/null +++ b/assets/develop_advanced_startupParameter.md.ca7b0373.lean.js @@ -0,0 +1 @@ +import{_ as t,o as a,c as e,V as s}from"./chunks/framework.63f12d77.js";const _=JSON.parse('{"title":"启动参数","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/startupParameter.md","filePath":"develop/advanced/startupParameter.md","lastUpdated":1722566694000}'),d={name:"develop/advanced/startupParameter.md"},r=s("",8),o=[r];function n(l,p,c,i,h,m){return a(),e("div",null,o)}const b=t(d,[["render",n]]);export{_ as __pageData,b as default}; diff --git a/assets/develop_advanced_timedTask.md.891d290c.js b/assets/develop_advanced_timedTask.md.891d290c.js new file mode 100644 index 00000000..94595727 --- /dev/null +++ b/assets/develop_advanced_timedTask.md.891d290c.js @@ -0,0 +1,42 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const B=JSON.parse('{"title":"定时任务","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/timedTask.md","filePath":"develop/advanced/timedTask.md","lastUpdated":1722566694000}'),t={name:"develop/advanced/timedTask.md"},o=l(`

定时任务

AmiyaBot 提供了全局定时任务管理器,基于 apscheduler

⚠️注意⚠️不兼容的更新

在版本 1.6.9 开始,不再支持全局定义定时任务,以及移除了 custom 参数,使用更泛用的 apscheduler trigger 控制任务执行时机。

此方法已不再支持,全局变量 tasks_control 已删除。

python
from amiyabot import AmiyaBot, tasks_control
+
+@tasks_control.timed_task(each=120)
+async def _():
+    ...

bot.timed_task 装饰器的 custom 参数已删除。

参数名类型释义默认值
eachint循环执行间隔时间,单位(秒)
customCallable自定义循环规则
sub_tagstr子标签default_tag

简单使用

python
from amiyabot import AmiyaBot
+from amiyabot.factory import BotHandlerFactory
+
+bot = AmiyaBot(...)  # 或 MultipleAccounts / PluginInstance 对象
+
+# 每 60 秒执行一次任务
+@bot.timed_task(each=60)
+async def _(instance: BotHandlerFactory):
+    ...

插件开发

如果你正在开发插件,并且你不希望在插件的卸载方法里手动取消定时任务,请务必通过 PluginInstance.timed_task 定义任务。

通过 PluginInstance.timed_task 定义的任务可以在插件被卸载时自动取消。

python
from amiyabot import PluginInstance
+from amiyabot.factory import BotHandlerFactory
+
+bot = PluginInstance(...)
+
+@bot.timed_task(each=60)
+async def _(instance: BotHandlerFactory):
+    ...

插件开发详情请查看 插件开发文档

timed_task 装饰器

参数名类型释义默认值
eachint循环执行间隔时间,单位(秒),如果使用其他触发方式,请使用 kwargs 形式的 scheduler.add_job 参数None
sub_tagstr子标签default_tag
run_when_addedbool添加时立即执行一次任务default_tag
**kwargsscheduler.add_job 参数

注意

使用 kwargs 自定义定时任务时,不可使用参数 func 以及 id

自定义执行时机

使用 scheduler.add_job 参数定义任务,可以使任务的执行时机更加灵活。

python
from amiyabot import PluginInstance
+from amiyabot.factory import BotHandlerFactory
+from apscheduler.triggers.cron import CronTrigger
+
+bot = PluginInstance(...)
+
+# 每个小时中的 5 分 30 秒时执行
+@bot.timed_task(trigger='cron', minute=5, second=30)
+async def _(instance: BotHandlerFactory):
+    ...
+
+# 每分钟的第 20 秒和 40 秒时执行
+@bot.timed_task(trigger=CronTrigger('20,40'))
+async def _(instance: BotHandlerFactory):
+    ...

取消定时任务

为需要取消的定时任务传入 sub_tag 参数,可以重复,重复的 sub_tag 会被整合为一组。

bot.remove_timed_task()

按标签名取消定时任务

参数名类型释义默认值
sub_tagstr需要取消的定时任务的子标签名

示例:执行一次后取消任务

python
from amiyabot import PluginInstance
+from amiyabot.factory import BotHandlerFactory
+
+bot = PluginInstance(...)
+
+@bot.timed_task(each=60, sub_tag='test')
+async def _(instance: BotHandlerFactory):
+    ...
+    bot.remove_timed_task('test')
`,23),p=[o];function e(c,r,y,D,F,i){return a(),n("div",null,p)}const A=s(t,[["render",e]]);export{B as __pageData,A as default}; diff --git a/assets/develop_advanced_timedTask.md.891d290c.lean.js b/assets/develop_advanced_timedTask.md.891d290c.lean.js new file mode 100644 index 00000000..21c99492 --- /dev/null +++ b/assets/develop_advanced_timedTask.md.891d290c.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const B=JSON.parse('{"title":"定时任务","description":"","frontmatter":{},"headers":[],"relativePath":"develop/advanced/timedTask.md","filePath":"develop/advanced/timedTask.md","lastUpdated":1722566694000}'),t={name:"develop/advanced/timedTask.md"},o=l("",23),p=[o];function e(c,r,y,D,F,i){return a(),n("div",null,p)}const A=s(t,[["render",e]]);export{B as __pageData,A as default}; diff --git a/assets/develop_basic_api_index.md.c8b00309.js b/assets/develop_basic_api_index.md.c8b00309.js new file mode 100644 index 00000000..0d6b98ad --- /dev/null +++ b/assets/develop_basic_api_index.md.c8b00309.js @@ -0,0 +1,9 @@ +import{_ as t,o as a,c as s,V as e}from"./chunks/framework.63f12d77.js";const D=JSON.parse('{"title":"API","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/api/index.md","filePath":"develop/basic/api/index.md","lastUpdated":1722566694000}'),o={name:"develop/basic/api/index.md"},l=e(`

API

API 是实现适配器部分基础逻辑的基础,你也可以调用 API 来进一步完成你的业务逻辑。

api 属性位于 AmiyaBotinstance 属性下。

python
bot = AmiyaBot(...)
+
+await bot.instance.api.get_me()

请注意

不用的适配器下,api 的方法不尽相同,在创作多平台机器人时,请注意可能产生的影响。

引入 API 类以注解变量

我们强烈建议在使用不同的适配器时,引入相应的 API 类注解 api 属性。它们通常在适配器模块的 api 模块下。

python
from amiyabot.adapters.tencent.qqGuild.api import QQGuildAPI
+# from amiyabot.adapters.cqhttp.api import CQHttpAPI
+# from amiyabot.adapters.kook.api import KOOKAPI
+
+
+api: QQGuildAPI = bot.instance.api
+await api.get_me()

共同的方法

api 实际上是调用了不同平台提供的接口。在不同平台下,调用接口的鉴权规则也不一样。所有适配器的 api 都存在以下三个方法,参数也是一样的。方法内部实现了不同平台的鉴权规则,你只需要直接调用接口即可。

get

参数名类型释义默认值
urlstr接口 url
paramsUnion[dict, None]get 参数
**kwargsrequest 参数

post

参数名类型释义默认值
urlstr接口 url
payloadUnion[dict, None]post 参数
is_form_databool是否使用 form 表单提交(仅 QQ 频道拥有此参数)
**kwargsrequest 参数

request

可以使用除 get、post 以外的一些 method 调用接口。

参数名类型释义默认值
urlstr接口 url
methodstr请求 method
payloadUnion[dict, None]请求参数
**kwargsrequest 参数
python
res = await bot.instance.api.post('/interface', {...})

为什么没有 headers 参数

方法内部实现了不同平台的鉴权规则,控制了 headers 的内容,你不需要手动控制。如果你希望自己实现请求,请使用 👉 进阶指南 - HTTP 请求

api 的返回

参考 进阶指南 - HTTP 请求 - 返回值

`,21),n=[l];function p(r,d,c,i,h,y){return a(),s("div",null,n)}const b=t(o,[["render",p]]);export{D as __pageData,b as default}; diff --git a/assets/develop_basic_api_index.md.c8b00309.lean.js b/assets/develop_basic_api_index.md.c8b00309.lean.js new file mode 100644 index 00000000..ec82c943 --- /dev/null +++ b/assets/develop_basic_api_index.md.c8b00309.lean.js @@ -0,0 +1 @@ +import{_ as t,o as a,c as s,V as e}from"./chunks/framework.63f12d77.js";const D=JSON.parse('{"title":"API","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/api/index.md","filePath":"develop/basic/api/index.md","lastUpdated":1722566694000}'),o={name:"develop/basic/api/index.md"},l=e("",21),n=[l];function p(r,d,c,i,h,y){return a(),s("div",null,n)}const b=t(o,[["render",p]]);export{D as __pageData,b as default}; diff --git a/assets/develop_basic_api_qqbot.md.068658d1.js b/assets/develop_basic_api_qqbot.md.068658d1.js new file mode 100644 index 00000000..7bb5de03 --- /dev/null +++ b/assets/develop_basic_api_qqbot.md.068658d1.js @@ -0,0 +1 @@ +import{_ as t,o as d,c as e,V as r}from"./chunks/framework.63f12d77.js";const m=JSON.parse('{"title":"QQ 频道 API","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/api/qqbot.md","filePath":"develop/basic/api/qqbot.md","lastUpdated":1722566694000}'),a={name:"develop/basic/api/qqbot.md"},h=r('

QQ 频道 API

🚧 API 文档尚处于建设阶段,缺少 api 说明和参数释义,请酌情阅读。🚧

add_message_reaction

参数名类型释义默认值
channel_idstr
message_idstr
emoji_typeint
emoji_idstr

add_pin

参数名类型释义默认值
channel_idstr
message_idstr

create_announces

参数名类型释义默认值
guild_idstr
message_idUnion[str, None]
channel_idUnion[str, None]
announces_typeUnion[int, None]
recommend_channelsUnion[str, None]

create_channel

参数名类型释义默认值
guild_idstr
channel_namestr
channel_typeint
channel_sub_typeint
positionUnion[int, None]
parent_idUnion[str, None]
private_typeUnion[int, None]
private_user_idsUnion[List[str], None]
speak_permissionUnion[int, None]
application_idUnion[str, None]
参数名类型释义默认值
guild_idstr
channel_idstr
pathstr
methodstr
descstr

create_guild_role

参数名类型释义默认值
guild_idstr
nameUnion[str, None]
colorUnion[int, None]
hoistint

create_schedule

参数名类型释义默认值
channel_idstr
namestr
descriptionstr
start_timestampstr
end_timestampstr
creatorUnion[dict, None]
jump_channel_idUnion[str, None]
remind_typeUnion[str, None]

create_thread

参数名类型释义默认值
channel_idstr
titlestr
contentstr
thread_formatint

delete_announces

参数名类型释义默认值
guild_idstr
message_idUnion[str, None]

delete_channel

参数名类型释义默认值
channel_idstr

delete_guild_member

参数名类型释义默认值
guild_idstr
user_idstr
add_blacklistbool
delete_history_msg_daysint

delete_guild_role

参数名类型释义默认值
guild_idstr
role_idstr

delete_message

参数名类型释义默认值
message_idstr
target_idstr
is_directbool
hidetipbool

delete_message_reaction

参数名类型释义默认值
channel_idstr
message_idstr
emoji_typeint
emoji_idstr

delete_pin

参数名类型释义默认值
channel_idstr
message_idstr

delete_schedule

参数名类型释义默认值
channel_idstr
schedule_idstr

delete_thread

参数名类型释义默认值
channel_idstr
thread_idstr

delete_user_role

参数名类型释义默认值
guild_idstr
user_idstr
role_idstr

gateway

参数名类型释义默认值

gateway_bot

参数名类型释义默认值

get_channel

参数名类型释义默认值
channel_idstr

get_channel_online_nums

参数名类型释义默认值
channel_idstr

get_channels

参数名类型释义默认值
guild_idstr

get_guild

参数名类型释义默认值
guild_idstr

get_guild_api_permission

参数名类型释义默认值
guild_idstr

get_guild_member

参数名类型释义默认值
guild_idstr
user_idstr

get_guild_members

参数名类型释义默认值
guild_idstr
afterstr
limitint

get_guild_roles

参数名类型释义默认值
guild_idstr

get_guild_roles_members

参数名类型释义默认值
guild_idstr
role_idstr
start_indexstr
limitint

get_guilds

参数名类型释义默认值
beforeUnion[str, None]
afterUnion[str, None]
limitint

get_me

参数名类型释义默认值

get_me_dms

参数名类型释义默认值
recipient_idstr
src_guild_idstr

get_message

参数名类型释义默认值
channel_idstr
message_idstr

get_message_reactions

参数名类型释义默认值
channel_idstr
message_idstr
emoji_typeint
emoji_idstr
cookieUnion[str, None]
limitint

get_message_setting

参数名类型释义默认值
guild_idstr

get_pins

参数名类型释义默认值
channel_idstr

get_role_permission

参数名类型释义默认值
channel_idstr
role_idstr

get_schedule

参数名类型释义默认值
channel_idstr
schedule_idstr

get_schedules

参数名类型释义默认值
channel_idstr
sinceint

get_thread

参数名类型释义默认值
channel_idstr
thread_idstr

get_threads

参数名类型释义默认值
channel_idstr

get_user_avatar

参数名类型释义默认值
args_empty
kwargs_empty

get_user_permission

参数名类型释义默认值
channel_idstr
user_idstr

modify_channel

参数名类型释义默认值
channel_idstr
channel_namestr
positionUnion[int, None]
parent_idUnion[str, None]
private_typeUnion[int, None]
speak_permissionUnion[int, None]

modify_guild_role

参数名类型释义默认值
guild_idstr
role_idstr
nameUnion[str, None]
colorUnion[int, None]
hoistint

modify_schedule

参数名类型释义默认值
channel_idstr
schedule_idstr
namestr
descriptionstr
start_timestampstr
end_timestampstr
creatorUnion[dict, None]
jump_channel_idUnion[str, None]
remind_typeUnion[str, None]

mute_all

参数名类型释义默认值
guild_idstr
mute_end_timestampstr
mute_secondsstr

mute_all_lift

参数名类型释义默认值
guild_idstr

mute_user

参数名类型释义默认值
guild_idstr
user_idstr
mute_end_timestampstr
mute_secondsstr

mute_user_lift

参数名类型释义默认值
guild_idstr
user_idstr

mute_users

参数名类型释义默认值
guild_idstr
user_idsList[str]
mute_end_timestampstr
mute_secondsstr

mute_users_lift

参数名类型释义默认值
guild_idstr
user_idsList[str]

post_message

参数名类型释义默认值
guild_idstr
src_guild_idstr
channel_idstr
reqMessageSendRequest

set_role_permission

参数名类型释义默认值
channel_idstr
role_idstr
addUnion[str, None]
removeUnion[str, None]

set_user_permission

参数名类型释义默认值
channel_idstr
user_idstr
addUnion[str, None]
removeUnion[str, None]

set_user_role

参数名类型释义默认值
guild_idstr
user_idstr
role_idstr
channel_idUnion[str, None]
',114),i=[h];function l(s,o,n,b,_,u){return d(),e("div",null,i)}const g=t(a,[["render",l]]);export{m as __pageData,g as default}; diff --git a/assets/develop_basic_api_qqbot.md.068658d1.lean.js b/assets/develop_basic_api_qqbot.md.068658d1.lean.js new file mode 100644 index 00000000..60c5da5f --- /dev/null +++ b/assets/develop_basic_api_qqbot.md.068658d1.lean.js @@ -0,0 +1 @@ +import{_ as t,o as d,c as e,V as r}from"./chunks/framework.63f12d77.js";const m=JSON.parse('{"title":"QQ 频道 API","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/api/qqbot.md","filePath":"develop/basic/api/qqbot.md","lastUpdated":1722566694000}'),a={name:"develop/basic/api/qqbot.md"},h=r("",114),i=[h];function l(s,o,n,b,_,u){return d(),e("div",null,i)}const g=t(a,[["render",l]]);export{m as __pageData,g as default}; diff --git a/assets/develop_basic_chainBuild_ark.md.4bf94265.js b/assets/develop_basic_chainBuild_ark.md.4bf94265.js new file mode 100644 index 00000000..3e0c9f02 --- /dev/null +++ b/assets/develop_basic_chainBuild_ark.md.4bf94265.js @@ -0,0 +1,9 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const B=JSON.parse('{"title":"Ark 消息","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/ark.md","filePath":"develop/basic/chainBuild/ark.md","lastUpdated":1722566694000}'),p={name:"develop/basic/chainBuild/ark.md"},o=l(`

Ark 消息

发送 QQ 频道 ARK 模板消息,详情请查看发送 ark 消息

Chain().ark()

参数名类型释义默认值
template_idstr模版 ID
kvList[dict]模版 key-value 数据
python
kv_data = [
+    {'key': '#PROMPT#', 'value': '通知提醒'},
+    {'key': '#METATITLE#', 'value': '标题'},
+    {'key': '#METASUBTITLE#', 'value': '子标题'},
+    {'key': '#METACOVER#', 'value': 'https://vfiles.gtimg.cn/vupload/20211029/bf0ed01635493790634.jpg'},
+    {'key': '#METAURL#', 'value': 'https://qq.com'},
+]
+
+Chain(data, at=False).ark(37, kv_data)

`,6),t=[o];function e(D,r,c,F,y,i){return a(),n("div",null,t)}const E=s(p,[["render",e]]);export{B as __pageData,E as default}; diff --git a/assets/develop_basic_chainBuild_ark.md.4bf94265.lean.js b/assets/develop_basic_chainBuild_ark.md.4bf94265.lean.js new file mode 100644 index 00000000..e8f392cd --- /dev/null +++ b/assets/develop_basic_chainBuild_ark.md.4bf94265.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const B=JSON.parse('{"title":"Ark 消息","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/ark.md","filePath":"develop/basic/chainBuild/ark.md","lastUpdated":1722566694000}'),p={name:"develop/basic/chainBuild/ark.md"},o=l("",6),t=[o];function e(D,r,c,F,y,i){return a(),n("div",null,t)}const E=s(p,[["render",e]]);export{B as __pageData,E as default}; diff --git a/assets/develop_basic_chainBuild_at.md.50524660.js b/assets/develop_basic_chainBuild_at.md.50524660.js new file mode 100644 index 00000000..24db82ed --- /dev/null +++ b/assets/develop_basic_chainBuild_at.md.50524660.js @@ -0,0 +1 @@ +import{_ as t,o as a,c as s,V as e}from"./chunks/framework.63f12d77.js";const y=JSON.parse('{"title":"At","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/at.md","filePath":"develop/basic/chainBuild/at.md","lastUpdated":1722566694000}'),o={name:"develop/basic/chainBuild/at.md"},l=e('

At

发送 @XXX

Chain().at()

提示

私信回复里无效

参数名类型释义默认值
userint, str@ 的用户ID,默认为 Message 对象的用户
enterbool是否 @ 用户后换行False
python
Chain(data).at(12345678).text('hello, world')

Chain 对象在实例化的时候,默认会在消息体头部添加 @XXX

',7),n=[l];function c(p,d,r,i,h,_){return a(),s("div",null,n)}const D=t(o,[["render",c]]);export{y as __pageData,D as default}; diff --git a/assets/develop_basic_chainBuild_at.md.50524660.lean.js b/assets/develop_basic_chainBuild_at.md.50524660.lean.js new file mode 100644 index 00000000..9f4d9814 --- /dev/null +++ b/assets/develop_basic_chainBuild_at.md.50524660.lean.js @@ -0,0 +1 @@ +import{_ as t,o as a,c as s,V as e}from"./chunks/framework.63f12d77.js";const y=JSON.parse('{"title":"At","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/at.md","filePath":"develop/basic/chainBuild/at.md","lastUpdated":1722566694000}'),o={name:"develop/basic/chainBuild/at.md"},l=e("",7),n=[l];function c(p,d,r,i,h,_){return a(),s("div",null,n)}const D=t(o,[["render",c]]);export{y as __pageData,D as default}; diff --git a/assets/develop_basic_chainBuild_atAll.md.b0aa82d9.js b/assets/develop_basic_chainBuild_atAll.md.b0aa82d9.js new file mode 100644 index 00000000..d113c8b5 --- /dev/null +++ b/assets/develop_basic_chainBuild_atAll.md.b0aa82d9.js @@ -0,0 +1 @@ +import{_ as a,o as t,c as e,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"At 所有人","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/atAll.md","filePath":"develop/basic/chainBuild/atAll.md","lastUpdated":1722566694000}'),s={name:"develop/basic/chainBuild/atAll.md"},o=l('

At 所有人

发送 @所有人,需要机器人拥有发送 @所有人 消息的权限

Chain().at_all()

提示

私信回复里无效

python
Chain(data).at_all()
',5),n=[o];function c(i,p,d,r,_,h){return t(),e("div",null,n)}const m=a(s,[["render",c]]);export{A as __pageData,m as default}; diff --git a/assets/develop_basic_chainBuild_atAll.md.b0aa82d9.lean.js b/assets/develop_basic_chainBuild_atAll.md.b0aa82d9.lean.js new file mode 100644 index 00000000..0a4831f0 --- /dev/null +++ b/assets/develop_basic_chainBuild_atAll.md.b0aa82d9.lean.js @@ -0,0 +1 @@ +import{_ as a,o as t,c as e,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"At 所有人","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/atAll.md","filePath":"develop/basic/chainBuild/atAll.md","lastUpdated":1722566694000}'),s={name:"develop/basic/chainBuild/atAll.md"},o=l("",5),n=[o];function c(i,p,d,r,_,h){return t(),e("div",null,n)}const m=a(s,[["render",c]]);export{A as __pageData,m as default}; diff --git a/assets/develop_basic_chainBuild_embed.md.ae4a3957.js b/assets/develop_basic_chainBuild_embed.md.ae4a3957.js new file mode 100644 index 00000000..91596e47 --- /dev/null +++ b/assets/develop_basic_chainBuild_embed.md.ae4a3957.js @@ -0,0 +1,6 @@ +import{_ as s,o as a,c as t,V as e}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"Embed 消息","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/embed.md","filePath":"develop/basic/chainBuild/embed.md","lastUpdated":1722566694000}'),n={name:"develop/basic/chainBuild/embed.md"},l=e(`

Embed 消息

发送 QQ 频道卡片消息,详情请查看 embed 消息

Chain().embed()

参数名类型释义默认值
titlestr标题
promptstr消息弹窗内容
thumbnailstr缩略图 url
fieldsList[str]embed 字段数据
python
Chain(data, at=False).embed(
+    '标题',
+    '消息通知',
+    'xxxxxx',
+    ['当前等级:黄金', '之前等级:白银', '😁继续努力'],
+)

`,6),o=[l];function p(r,d,c,F,i,D){return a(),t("div",null,o)}const m=s(n,[["render",p]]);export{h as __pageData,m as default}; diff --git a/assets/develop_basic_chainBuild_embed.md.ae4a3957.lean.js b/assets/develop_basic_chainBuild_embed.md.ae4a3957.lean.js new file mode 100644 index 00000000..43b0af48 --- /dev/null +++ b/assets/develop_basic_chainBuild_embed.md.ae4a3957.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as t,V as e}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"Embed 消息","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/embed.md","filePath":"develop/basic/chainBuild/embed.md","lastUpdated":1722566694000}'),n={name:"develop/basic/chainBuild/embed.md"},l=e("",6),o=[l];function p(r,d,c,F,i,D){return a(),t("div",null,o)}const m=s(n,[["render",p]]);export{h as __pageData,m as default}; diff --git a/assets/develop_basic_chainBuild_extend.md.d4c803dd.js b/assets/develop_basic_chainBuild_extend.md.d4c803dd.js new file mode 100644 index 00000000..c47313b0 --- /dev/null +++ b/assets/develop_basic_chainBuild_extend.md.d4c803dd.js @@ -0,0 +1,29 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"原生模板","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/extend.md","filePath":"develop/basic/chainBuild/extend.md","lastUpdated":1722566694000}'),p={name:"develop/basic/chainBuild/extend.md"},o=l(`

原生模板

使用原生消息模板扩展 Chain 对象

温馨提示

消息扩展暂仅支持 mirai-api-httpcq-http

除了以上内置的消息类型外,mirai-api-httpcq-http 还提供了多种消息类型用于发送丰富的消息内容。

Chain().extend()

参数名类型释义默认值
dataAny原始消息类型格式数据

示例

使用 mirai-api-http 消息类型 Dice 发送一个点数 6 的骰子魔法表情

python
Chain(data).extend(
+    {
+        'type': 'Dice',
+        'value': 6
+    }
+)

使用 go-cqhttp 消息类型 链接分享 发送一个百度首页链接分享

python
Chain(data).extend(
+    {
+        'type': 'share',
+        'data': {
+            'url': 'https://www.baidu.com',
+            'title': '百度'
+        }
+    }
+)

发送 CQ 码

发送 CQ 码目前仅支持 cq-http 适配器。可通过适配器的 API 对象发送或扩展消息发送。

python
from amiyabot import CQCode, CQHttpBotInstance
+
+instance: CQHttpBotInstance = bot.instance
+
+
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    # 通过 API 发送
+    instance.api.send_cq_code(data.user_id,
+                              data.channel_id,
+                              f'hello, {data.nickname} [CQ:face,id=123]')
+
+    # 通过扩展消息发送
+    return Chain(data).extend(
+        CQCode(f'hello, {data.nickname} [CQ:face,id=123]')
+    )
`,15),e=[o];function t(c,r,F,y,D,i){return a(),n("div",null,e)}const h=s(p,[["render",t]]);export{A as __pageData,h as default}; diff --git a/assets/develop_basic_chainBuild_extend.md.d4c803dd.lean.js b/assets/develop_basic_chainBuild_extend.md.d4c803dd.lean.js new file mode 100644 index 00000000..dab3199e --- /dev/null +++ b/assets/develop_basic_chainBuild_extend.md.d4c803dd.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"原生模板","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/extend.md","filePath":"develop/basic/chainBuild/extend.md","lastUpdated":1722566694000}'),p={name:"develop/basic/chainBuild/extend.md"},o=l("",15),e=[o];function t(c,r,F,y,D,i){return a(),n("div",null,e)}const h=s(p,[["render",t]]);export{A as __pageData,h as default}; diff --git a/assets/develop_basic_chainBuild_face.md.57e44a04.js b/assets/develop_basic_chainBuild_face.md.57e44a04.js new file mode 100644 index 00000000..7a1fb32e --- /dev/null +++ b/assets/develop_basic_chainBuild_face.md.57e44a04.js @@ -0,0 +1 @@ +import{_ as a,o as t,c as e,V as s}from"./chunks/framework.63f12d77.js";const m=JSON.parse('{"title":"emoji 表情","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/face.md","filePath":"develop/basic/chainBuild/face.md","lastUpdated":1722566694000}'),o={name:"develop/basic/chainBuild/face.md"},n=s('

emoji 表情

仅限 QQ 内置的小黄人表情

Chain().face()

参数名类型释义默认值
face_idint, str表情ID
python
Chain(data).face(175)
',5),c=[n];function l(i,d,r,p,h,_){return t(),e("div",null,c)}const u=a(o,[["render",l]]);export{m as __pageData,u as default}; diff --git a/assets/develop_basic_chainBuild_face.md.57e44a04.lean.js b/assets/develop_basic_chainBuild_face.md.57e44a04.lean.js new file mode 100644 index 00000000..e34cc07e --- /dev/null +++ b/assets/develop_basic_chainBuild_face.md.57e44a04.lean.js @@ -0,0 +1 @@ +import{_ as a,o as t,c as e,V as s}from"./chunks/framework.63f12d77.js";const m=JSON.parse('{"title":"emoji 表情","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/face.md","filePath":"develop/basic/chainBuild/face.md","lastUpdated":1722566694000}'),o={name:"develop/basic/chainBuild/face.md"},n=s("",5),c=[n];function l(i,d,r,p,h,_){return t(),e("div",null,c)}const u=a(o,[["render",l]]);export{m as __pageData,u as default}; diff --git a/assets/develop_basic_chainBuild_forward.md.8fc44648.js b/assets/develop_basic_chainBuild_forward.md.8fc44648.js new file mode 100644 index 00000000..989ccb46 --- /dev/null +++ b/assets/develop_basic_chainBuild_forward.md.8fc44648.js @@ -0,0 +1,27 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"合并转发消息 Beta","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/forward.md","filePath":"develop/basic/chainBuild/forward.md","lastUpdated":1722566694000}'),o={name:"develop/basic/chainBuild/forward.md"},p=l(`

合并转发消息 Beta

合并转发消息不是 Chain 对象的方法,需要使用适配器提供的工具类构建。

注意

QQ 频道机器人暂时不支持发送合并转发消息,目前仅支持 mirai-api-httpcq-http

python
from amiyabot.adapters.mirai import MiraiForwardMessage
+# from amiyabot.adapters.cqhttp import CQHTTPForwardMessage
+
+...
+
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    forward = MiraiForwardMessage(data)
+    # forward = CQHTTPForwardMessage(data)
+
+    chain = Chain().text(f'hello, {data.nickname}')
+
+    await forward.add_message(chain, user_id=..., nickname='...')
+    await forward.send()

添加自定义消息

add_message

参数名类型释义默认值
chainChain, listChain 对象,可为空 Chain
user_idint用户 ID
nicknamestr用户昵称(可自定义)
timeint发送时间0
  • user_id 为实际 QQ 用户的 QQ 号,可以是任意人,在合并消息内显示其头像。
  • nickname 为自定义的昵称。

如果 chain 参数传入了空 Chain,则 user_idnickname 为必须参数。

python
await forward.add_message(Chain(data).text(...))
+await forward.add_message(Chain().text(...), user_id=..., nickname='...')

添加指定 ID 的消息

add_message_by_id

参数名类型释义默认值
message_idint消息 ID
python
await forward.add_message_by_id(5128)

添加嵌套的合并转发消息

add_messagechain 参数传入 ForwardMessage 类的 node 属性,即可完成合并消息嵌套。

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    forward = MiraiForwardMessage(data)
+
+    await forward.add_message(...)
+    await forward.add_message(...)
+
+    forward2 = MiraiForwardMessage(data)
+
+    await forward2.add_message(forward.node, user_id=..., nickname='...')
+    await forward2.send()

发送 & 撤回

python
callback = await forward.send()  # 发送
+if callback:
+    await callback.recall()  # 撤回
`,19),t=[p];function e(c,r,F,y,D,i){return a(),n("div",null,t)}const B=s(o,[["render",e]]);export{A as __pageData,B as default}; diff --git a/assets/develop_basic_chainBuild_forward.md.8fc44648.lean.js b/assets/develop_basic_chainBuild_forward.md.8fc44648.lean.js new file mode 100644 index 00000000..2fbb1f44 --- /dev/null +++ b/assets/develop_basic_chainBuild_forward.md.8fc44648.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"合并转发消息 Beta","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/forward.md","filePath":"develop/basic/chainBuild/forward.md","lastUpdated":1722566694000}'),o={name:"develop/basic/chainBuild/forward.md"},p=l("",19),t=[p];function e(c,r,F,y,D,i){return a(),n("div",null,t)}const B=s(o,[["render",e]]);export{A as __pageData,B as default}; diff --git a/assets/develop_basic_chainBuild_html.md.b5f77581.js b/assets/develop_basic_chainBuild_html.md.b5f77581.js new file mode 100644 index 00000000..cf9ca775 --- /dev/null +++ b/assets/develop_basic_chainBuild_html.md.b5f77581.js @@ -0,0 +1,18 @@ +import{_ as s,o as a,c as l,V as n}from"./chunks/framework.63f12d77.js";const t="/assets/hello7.8e9afac1.png",o="/assets/awesome1.7d49a140.png",A=JSON.parse('{"title":"HTML 生成的图片","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/html.md","filePath":"develop/basic/chainBuild/html.md","lastUpdated":1722566694000}'),p={name:"develop/basic/chainBuild/html.md"},e=n(`

HTML 生成的图片

发送一张使用 html 页面生成的图片,在同等工作量下,它通常比使用 PIL 合成的图片更加生动,技术难度也比 PIL 要低得多。

操作系统支持

HTML制图需要使用 playwright 模块,所以仅支持以下操作系统:

  • Windows 10、Windows Subsystem for Linux (WSL) 或 Windows Server 2012 及以上系统
  • MacOS 11 (Big Sur) 及以上系统
  • Linux 系统官方支持 Debian 11、Ubuntu 18.04 以及 Ubuntu 20.04

安装 Chromium

命令行执行以下命令安装 Chromium 内核:

bash
# Windows or MacOS
+playwright install chromium
+# Linux
+playwright install --with-deps chromium

启动时打开 Chromium

在 bot(包括多账号实例)启动的 start 方法内设置参数 launch_browser=True

python
bot.start(launch_browser=True)

进阶使用:改变默认的 Playwright 启动行为

Chain().html()

参数名类型释义默认值
pathstr模板文件路径或网站URL
dataAny传入模板文件的数据(数据可被 json 序列化)
widthint浏览器视窗宽度1280
heightint浏览器视窗高度720
is_templatebool是否为模板文件True
render_timeint渲染时间(毫秒)200
python
Chain(data).html('template.html', {...})

创建html模板文件

创建文件 hello.html 并定义全局的 init 方法。

html
<!-- hello.html -->
+<div id="content"></div>
+
+<script>
+    // 必须定义全局的 init 方法,接收一个 data 参数
+    window.init = (data) => {
+        document.querySelector('#content').innerText = data.username
+    }
+</script>

将需要渲染的数据传入模板:

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).html('hello.html', {'username': data.nickname})

示例在触发会话并开始发送消息时,Chain 对象将会调用 Chromium 无头浏览器,渲染 hello.html 并在页面内执行 JavaScript 语句 init({'username': 'vivien8261'})
渲染结束后,无头浏览器截图生成图片,然后执行常规的图片发送方法。

image

发挥你的想象,写出更美观的页面!

兔兔-v6 效果
image

通过网站URL制图

支持直接使用网站URL生成图片。

注意

在页面加载完毕后,默认预留200ms的渲染时间。如果页面有部分元素是异步渲染的,将有可能不显示在图片内。可通过参数 render_time 设置需要的时间。

设置参数 is_template=False

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).html('https://www.baidu.com/',
+                            is_template=False,
+                            render_time=1000)

触发会话时,渲染 https://www.baidu.com/ 页面,并在等待 1000ms 后截图发送图片。

`,28),c=[e];function r(i,y,F,D,d,h){return a(),l("div",null,c)}const u=s(p,[["render",r]]);export{A as __pageData,u as default}; diff --git a/assets/develop_basic_chainBuild_html.md.b5f77581.lean.js b/assets/develop_basic_chainBuild_html.md.b5f77581.lean.js new file mode 100644 index 00000000..46ec92e5 --- /dev/null +++ b/assets/develop_basic_chainBuild_html.md.b5f77581.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as l,V as n}from"./chunks/framework.63f12d77.js";const t="/assets/hello7.8e9afac1.png",o="/assets/awesome1.7d49a140.png",A=JSON.parse('{"title":"HTML 生成的图片","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/html.md","filePath":"develop/basic/chainBuild/html.md","lastUpdated":1722566694000}'),p={name:"develop/basic/chainBuild/html.md"},e=n("",28),c=[e];function r(i,y,F,D,d,h){return a(),l("div",null,c)}const u=s(p,[["render",r]]);export{A as __pageData,u as default}; diff --git a/assets/develop_basic_chainBuild_image.md.3716f519.js b/assets/develop_basic_chainBuild_image.md.3716f519.js new file mode 100644 index 00000000..e98d89a9 --- /dev/null +++ b/assets/develop_basic_chainBuild_image.md.3716f519.js @@ -0,0 +1 @@ +import{_ as a,o as t,c as s,V as e}from"./chunks/framework.63f12d77.js";const _=JSON.parse('{"title":"图片","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/image.md","filePath":"develop/basic/chainBuild/image.md","lastUpdated":1722566694000}'),n={name:"develop/basic/chainBuild/image.md"},o=e('

图片

发送一张图片

Chain().image()

参数名类型释义默认值
targetstr, bytes图片文件路径或图片 bytes
urlstr网络图片的URL
python
Chain(data).image(target)

当传入的类型为字符串时,image 方法会认为值为本地图片的路径并尝试读取文件。也可以直接传入 bytes 类型。
如果是网络图片,可以使用 url 参数传入。

python
Chain(data).image(url=target)
',7),l=[o];function p(r,c,i,d,h,F){return t(),s("div",null,l)}const m=a(n,[["render",p]]);export{_ as __pageData,m as default}; diff --git a/assets/develop_basic_chainBuild_image.md.3716f519.lean.js b/assets/develop_basic_chainBuild_image.md.3716f519.lean.js new file mode 100644 index 00000000..557aa2f7 --- /dev/null +++ b/assets/develop_basic_chainBuild_image.md.3716f519.lean.js @@ -0,0 +1 @@ +import{_ as a,o as t,c as s,V as e}from"./chunks/framework.63f12d77.js";const _=JSON.parse('{"title":"图片","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/image.md","filePath":"develop/basic/chainBuild/image.md","lastUpdated":1722566694000}'),n={name:"develop/basic/chainBuild/image.md"},o=e("",7),l=[o];function p(r,c,i,d,h,F){return t(),s("div",null,l)}const m=a(n,[["render",p]]);export{_ as __pageData,m as default}; diff --git a/assets/develop_basic_chainBuild_markdown.md.2f3e8203.js b/assets/develop_basic_chainBuild_markdown.md.2f3e8203.js new file mode 100644 index 00000000..42ed6ad2 --- /dev/null +++ b/assets/develop_basic_chainBuild_markdown.md.2f3e8203.js @@ -0,0 +1,6 @@ +import{_ as a,o as s,c as n,V as o}from"./chunks/framework.63f12d77.js";const m=JSON.parse('{"title":"Markdown 生成的图片","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/markdown.md","filePath":"develop/basic/chainBuild/markdown.md","lastUpdated":1722566694000}'),t={name:"develop/basic/chainBuild/markdown.md"},l=o(`

Markdown 生成的图片

添加一张由 Markdown 文本渲染的图片,直接传入 md 格式的文本,使用 HTML 模式渲染。建议先阅读 发送 html 生成的图片 了解如何启动 Chromium。

注意

这并非 QQ 机器人官方提供的 发送 markdown 消息 ,要发送官方的 Markdown 模版消息请查看 Markdown 模版

Chain().markdown()

参数名类型释义默认值
contentstrmarkdown 文本
render_timeint渲染时间(毫秒)200
is_darkbool是否使用暗黑样式False
python
Chain(data).markdown(text)

提示

文本量大时,渲染将会耗费较长时间,默认预留200ms的渲染时间。可通过参数 render_time 设置需要的时间。

更换渲染 Markdown 的 HTML 文件

更改全局配置可以使用自己的 HTML 文件渲染 Markdown

python
from amiyabot.builtin.messageChain import ChainConfig
+
+ChainConfig.md_template = './myMarkdown.html'
+ChainConfig.md_template_dark = './myDarkMarkdown.html'

HTML 内需要实现以下方法获取到 Markdown 文本

js
window.init = (data) => {
+    const markdownText = data['content']
+}
`,12),e=[l];function p(r,c,d,i,y,D){return s(),n("div",null,e)}const F=a(t,[["render",p]]);export{m as __pageData,F as default}; diff --git a/assets/develop_basic_chainBuild_markdown.md.2f3e8203.lean.js b/assets/develop_basic_chainBuild_markdown.md.2f3e8203.lean.js new file mode 100644 index 00000000..a2f744b1 --- /dev/null +++ b/assets/develop_basic_chainBuild_markdown.md.2f3e8203.lean.js @@ -0,0 +1 @@ +import{_ as a,o as s,c as n,V as o}from"./chunks/framework.63f12d77.js";const m=JSON.parse('{"title":"Markdown 生成的图片","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/markdown.md","filePath":"develop/basic/chainBuild/markdown.md","lastUpdated":1722566694000}'),t={name:"develop/basic/chainBuild/markdown.md"},l=o("",12),e=[l];function p(r,c,d,i,y,D){return s(),n("div",null,e)}const F=a(t,[["render",p]]);export{m as __pageData,F as default}; diff --git a/assets/develop_basic_chainBuild_mdTemplate.md.6ba5c9fa.js b/assets/develop_basic_chainBuild_mdTemplate.md.6ba5c9fa.js new file mode 100644 index 00000000..5e03adc7 --- /dev/null +++ b/assets/develop_basic_chainBuild_mdTemplate.md.6ba5c9fa.js @@ -0,0 +1,36 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"Markdown 模版消息","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/mdTemplate.md","filePath":"develop/basic/chainBuild/mdTemplate.md","lastUpdated":1722566694000}'),p={name:"develop/basic/chainBuild/mdTemplate.md"},o=l(`

Markdown 模版消息

发送 QQ 频道 Markdown 模板消息,详情请查看发送 markdown 消息

Chain().markdown_template()

参数名类型释义默认值
template_idstr模版 ID
paramsList[dict]模版 key-value 数据
keyboardInlineKeyboard按钮消息(自定义)
keyboard_template_idstr按钮消息(模版)
python
params = [
+    {'key': 'para1', 'values': ['段落1']},
+    {'key': 'para2', 'values': ['段落2']},
+    {'key': 'desc', 'values': ['简介']},
+]
+
+Chain(data, at=False).markdown_template('101993071_1658748972', params)

按钮消息

发送含有消息按钮组件的消息

使用按钮模版

python
# 必须跟随 md 模版发送
+Chain(data, at=False).markdown_template(
+    '101993071_1658748972',
+    params,
+    keyboard_template_id='102005657_1703561314',
+)

自定义按钮

自定义按钮通过内置的 InlineKeyboard 类构建。

python
from amiyabot import InlineKeyboard
+
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    keyboard = InlineKeyboard(data.instance.appid)
+
+    # 添加第一行按钮组
+    row = keyboard.add_row()
+    row.add_button('1', '按钮1')
+    row.add_button('2', '按钮2')
+
+    # 添加第二行按钮组
+    row2 = keyboard.add_row()
+    row2.add_button('3', '按钮3')
+    row2.add_button('4', '更多功能...', action_type=0)
+
+    # 必须跟随 md 模版发送
+    chain = Chain(data, at=False).markdown_template(
+        '102005657_1704356453',
+        [{'key': 'content', 'values': ['Markdown 测试']}],
+        keyboard=keyboard,
+    )
+
+    # 通过主动消息发送
+    await bot[data.instance.appid].send_message(chain, channel_id=data.channel_id)
`,12),t=[o];function e(c,r,F,D,y,i){return a(),n("div",null,t)}const B=s(p,[["render",e]]);export{A as __pageData,B as default}; diff --git a/assets/develop_basic_chainBuild_mdTemplate.md.6ba5c9fa.lean.js b/assets/develop_basic_chainBuild_mdTemplate.md.6ba5c9fa.lean.js new file mode 100644 index 00000000..b25d6eed --- /dev/null +++ b/assets/develop_basic_chainBuild_mdTemplate.md.6ba5c9fa.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"Markdown 模版消息","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/mdTemplate.md","filePath":"develop/basic/chainBuild/mdTemplate.md","lastUpdated":1722566694000}'),p={name:"develop/basic/chainBuild/mdTemplate.md"},o=l("",12),t=[o];function e(c,r,F,D,y,i){return a(),n("div",null,t)}const B=s(p,[["render",e]]);export{A as __pageData,B as default}; diff --git a/assets/develop_basic_chainBuild_tag.md.c0a92925.js b/assets/develop_basic_chainBuild_tag.md.c0a92925.js new file mode 100644 index 00000000..440f3ad5 --- /dev/null +++ b/assets/develop_basic_chainBuild_tag.md.c0a92925.js @@ -0,0 +1 @@ +import{_ as a,o as t,c as e,V as s}from"./chunks/framework.63f12d77.js";const b=JSON.parse('{"title":"频道跳转超链接","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/tag.md","filePath":"develop/basic/chainBuild/tag.md","lastUpdated":1722566694000}'),o={name:"develop/basic/chainBuild/tag.md"},n=s('

频道跳转超链接

发送频道跳转超链接 #子频道,点击可以跳转至子频道,仅支持当前频道内的子频道

注意

仅支持 QQ 频道

Chain().tag()

参数名类型释义默认值
targetint子频道ID
python
Chain(data).tag(12345678)
',6),l=[n];function c(d,p,i,r,h,_){return t(),e("div",null,l)}const g=a(o,[["render",c]]);export{b as __pageData,g as default}; diff --git a/assets/develop_basic_chainBuild_tag.md.c0a92925.lean.js b/assets/develop_basic_chainBuild_tag.md.c0a92925.lean.js new file mode 100644 index 00000000..41d4735f --- /dev/null +++ b/assets/develop_basic_chainBuild_tag.md.c0a92925.lean.js @@ -0,0 +1 @@ +import{_ as a,o as t,c as e,V as s}from"./chunks/framework.63f12d77.js";const b=JSON.parse('{"title":"频道跳转超链接","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/tag.md","filePath":"develop/basic/chainBuild/tag.md","lastUpdated":1722566694000}'),o={name:"develop/basic/chainBuild/tag.md"},n=s("",6),l=[n];function c(d,p,i,r,h,_){return t(),e("div",null,l)}const g=a(o,[["render",c]]);export{b as __pageData,g as default}; diff --git a/assets/develop_basic_chainBuild_text.md.76e8530f.js b/assets/develop_basic_chainBuild_text.md.76e8530f.js new file mode 100644 index 00000000..670fa197 --- /dev/null +++ b/assets/develop_basic_chainBuild_text.md.76e8530f.js @@ -0,0 +1 @@ +import{_ as t,o as a,c as e,V as s}from"./chunks/framework.63f12d77.js";const D=JSON.parse('{"title":"文字","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/text.md","filePath":"develop/basic/chainBuild/text.md","lastUpdated":1722566694000}'),o={name:"develop/basic/chainBuild/text.md"},n=s('

文字

发送一段文字消息

Chain().text()

参数名类型释义默认值
textstr内容文本
auto_convertbool是否超出字数后转换为图片True
python
Chain(data).text('hello, world')

设置 auto_convert=True 可开启自动转换,当文字超过一定长度时(默认配置为 100),会自动将本段落转换为图片发送。

插入表情

在文本内使用 [face:ID] 模板也可以插入 QQ 表情。

python
Chain(data).text('hello, world[face:175]')
',9),l=[n];function p(c,r,d,i,h,F){return a(),e("div",null,l)}const _=t(o,[["render",p]]);export{D as __pageData,_ as default}; diff --git a/assets/develop_basic_chainBuild_text.md.76e8530f.lean.js b/assets/develop_basic_chainBuild_text.md.76e8530f.lean.js new file mode 100644 index 00000000..d2be3ef3 --- /dev/null +++ b/assets/develop_basic_chainBuild_text.md.76e8530f.lean.js @@ -0,0 +1 @@ +import{_ as t,o as a,c as e,V as s}from"./chunks/framework.63f12d77.js";const D=JSON.parse('{"title":"文字","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/text.md","filePath":"develop/basic/chainBuild/text.md","lastUpdated":1722566694000}'),o={name:"develop/basic/chainBuild/text.md"},n=s("",9),l=[n];function p(c,r,d,i,h,F){return a(),e("div",null,l)}const _=t(o,[["render",p]]);export{D as __pageData,_ as default}; diff --git a/assets/develop_basic_chainBuild_textImage.md.e1fe255d.js b/assets/develop_basic_chainBuild_textImage.md.e1fe255d.js new file mode 100644 index 00000000..89aabbb0 --- /dev/null +++ b/assets/develop_basic_chainBuild_textImage.md.e1fe255d.js @@ -0,0 +1,12 @@ +import{_ as s,o as a,c as t,V as n}from"./chunks/framework.63f12d77.js";const l="/assets/hello5.472a7f7b.png",o="/assets/hello6.f4a06bfe.png",B=JSON.parse('{"title":"文字生成的图片","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/textImage.md","filePath":"develop/basic/chainBuild/textImage.md","lastUpdated":1722566694000}'),p={name:"develop/basic/chainBuild/textImage.md"},e=n(`

文字生成的图片

此方法可以将文字转换为图片发送,使用调色模板可以进行文字调色,亦可插入图片渲染。

Chain().text_image()

参数名类型释义默认值
textstr内容文本
imagesList[ImageElem]插入图片None
widthint图片宽度None
heightint图片高度None
bgcolorstr图片背景色#F5F5F5
python
Chain(data).text_image('hello, world')

调色模板

在文本内使用 [cl 文字内容@#颜色代码 cle] 格式的模板,将指定文字内容改变颜色。

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).text(f'hello [cl {data.nickname}@#ff0000 cle]')
image

text_image 无法插入表情

如果 Chain.text 的文本内使用了调色模板,将会强制转换为图片。同时 [face:ID] 模板也会失效。

渲染图片

在 images 参数内传入一个包含 ImageElem 对象的列表,可在文字图片内渲染图片。

ImageElem

参数名类型释义默认值
pathstr图片路径
sizeint图片大小
pos(int, int)图片渲染位置 (x, y)

简单尝试一下,发送一张 hello, world 的文字图片,并在里面插入一张图片。
需要注意的是,因为 hello, world 文字只有一行,所以需要指定一下图片高度。否则插入的图片可能会显示不全。
你可以一次插入很多张图片,所以任何时候,都请把握好你的文字图片宽高与插入的图片的大小、坐标之间的影响。

python
from amiyabot.builtin.lib.imageCreator import ImageElem
+
+
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    image = ImageElem(path='face.png', size=80, pos=(0, 20))
+
+    return Chain(data).text_image('hello,world', images=[image], height=100)

你可以收到如下的回复

image

更换字体

可以使用自己的 ttf 字体文件更换字体

python
from amiyabot.builtin.lib.imageCreator import FontStyle
+
+FontStyle.file = './font.ttf'
`,21),c=[e];function r(y,F,D,i,d,h){return a(),t("div",null,c)}const g=s(p,[["render",r]]);export{B as __pageData,g as default}; diff --git a/assets/develop_basic_chainBuild_textImage.md.e1fe255d.lean.js b/assets/develop_basic_chainBuild_textImage.md.e1fe255d.lean.js new file mode 100644 index 00000000..e890672f --- /dev/null +++ b/assets/develop_basic_chainBuild_textImage.md.e1fe255d.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as t,V as n}from"./chunks/framework.63f12d77.js";const l="/assets/hello5.472a7f7b.png",o="/assets/hello6.f4a06bfe.png",B=JSON.parse('{"title":"文字生成的图片","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/textImage.md","filePath":"develop/basic/chainBuild/textImage.md","lastUpdated":1722566694000}'),p={name:"develop/basic/chainBuild/textImage.md"},e=n("",21),c=[e];function r(y,F,D,i,d,h){return a(),t("div",null,c)}const g=s(p,[["render",r]]);export{B as __pageData,g as default}; diff --git a/assets/develop_basic_chainBuild_video.md.fb39365f.js b/assets/develop_basic_chainBuild_video.md.fb39365f.js new file mode 100644 index 00000000..0811773d --- /dev/null +++ b/assets/develop_basic_chainBuild_video.md.fb39365f.js @@ -0,0 +1,3 @@ +import{_ as s,o as a,c as o,V as n}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"视频","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/video.md","filePath":"develop/basic/chainBuild/video.md","lastUpdated":1722566694000}'),t={name:"develop/basic/chainBuild/video.md"},l=n(`

视频

发送一段 mp4 格式的视频

注意

QQ 频道机器人暂时不支持发送视频,目前仅支持官方 QQ 群。

Chain().video()

参数名类型释义默认值
filestr视频文件路径
python
Chain(data).video(file)
python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).video('xxxxxx.mp4')
`,7),e=[l];function p(c,r,i,d,F,y){return a(),o("div",null,e)}const A=s(t,[["render",p]]);export{h as __pageData,A as default}; diff --git a/assets/develop_basic_chainBuild_video.md.fb39365f.lean.js b/assets/develop_basic_chainBuild_video.md.fb39365f.lean.js new file mode 100644 index 00000000..8f08e916 --- /dev/null +++ b/assets/develop_basic_chainBuild_video.md.fb39365f.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as o,V as n}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"视频","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/video.md","filePath":"develop/basic/chainBuild/video.md","lastUpdated":1722566694000}'),t={name:"develop/basic/chainBuild/video.md"},l=n("",7),e=[l];function p(c,r,i,d,F,y){return a(),o("div",null,e)}const A=s(t,[["render",p]]);export{h as __pageData,A as default}; diff --git a/assets/develop_basic_chainBuild_voice.md.efe611ec.js b/assets/develop_basic_chainBuild_voice.md.efe611ec.js new file mode 100644 index 00000000..f5412353 --- /dev/null +++ b/assets/develop_basic_chainBuild_voice.md.efe611ec.js @@ -0,0 +1,3 @@ +import{_ as s,o as a,c as t,V as o}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"语音","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/voice.md","filePath":"develop/basic/chainBuild/voice.md","lastUpdated":1722566694000}'),n={name:"develop/basic/chainBuild/voice.md"},e=o(`

语音

发送一段 wav 格式的音频

注意

QQ 频道机器人暂时不支持发送语音,目前仅支持官方 QQ 群、 mirai-api-httpcq-http

Chain().voice()

参数名类型释义默认值
filestr语音 wav 文件路径
titlestr语音标题voice
python
Chain(data).voice(file)
python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).voice('阿米娅_问候.wav')
`,7),l=[e];function p(c,r,i,d,F,y){return a(),t("div",null,l)}const A=s(n,[["render",p]]);export{h as __pageData,A as default}; diff --git a/assets/develop_basic_chainBuild_voice.md.efe611ec.lean.js b/assets/develop_basic_chainBuild_voice.md.efe611ec.lean.js new file mode 100644 index 00000000..66b28364 --- /dev/null +++ b/assets/develop_basic_chainBuild_voice.md.efe611ec.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as t,V as o}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"语音","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/chainBuild/voice.md","filePath":"develop/basic/chainBuild/voice.md","lastUpdated":1722566694000}'),n={name:"develop/basic/chainBuild/voice.md"},e=o("",7),l=[e];function p(c,r,i,d,F,y){return a(),t("div",null,l)}const A=s(n,[["render",p]]);export{h as __pageData,A as default}; diff --git a/assets/develop_basic_continuityMessage.md.f8d8bfa7.js b/assets/develop_basic_continuityMessage.md.f8d8bfa7.js new file mode 100644 index 00000000..e11dcfe6 --- /dev/null +++ b/assets/develop_basic_continuityMessage.md.f8d8bfa7.js @@ -0,0 +1,30 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const t="/assets/hello4.58f3a96c.png",A=JSON.parse('{"title":"创建连续对话","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/continuityMessage.md","filePath":"develop/basic/continuityMessage.md","lastUpdated":1722566694000}'),o={name:"develop/basic/continuityMessage.md"},e=l(`

创建连续对话

在一些使用场景里,需要机器人与使用者产生连续的对话。比如询问使用者以获取信息等。

Message 对象内置了连续对话支持。

Message.wait()

参数列表

参数名类型释义默认值
replyChainChain 对象
forcebool使用强制等待False
max_timeint最长等待时间(秒数)30
data_filterCallableMessage 过滤器
levelint优先级0

使用 wait 方法实现一个简单的连续对话

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+
+    reply = await data.wait(Chain(data).text('tell me your name please~'))
+
+    if reply:
+        return Chain(reply).text(f'hello,{reply.text}')
image

force 强制等待

等待通常不会影响消息分配器运作,也就是说 仅在不能触发任何其他功能 的时候,消息才会返回到当前等待处。(也包括本功能的初始触发方式,一般功能的优先级默认为 1,比等待事件的默认优先级高)

如果你不希望如此,使用参数 force=True,可以忽略分配器让消息强制返回到等待处。

data_filter 消息过滤器

如果在等待过程中,希望 wait 接收到符合期望的消息后再返回到等待处,可以使用 data_filter 参数过滤消息。

python
async def my_data_filter(data: Message):
+    if ...:
+        return True # 返回 True 代表此则消息符合期望,将返回到等待处
+
+
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    reply = await data.wait(Chain(data).text('tell me your name please~'), data_filter=my_data_filter)
+
+    if reply:
+        return Chain(reply).text(f'hello,{reply.text}')

关于 wait 方法你需要知道的事

  • 若用户超过最长等待时间未回复,wait 会返回 None

同一个子频道内的同一个用户只能存在一个等待事件,当一个新的等待事件创建后,上一个未使用的等待事件会被注销并引发 WaitEventCancel 异常,进行中的业务将会被终止,这是符合预期的,通常这个异常会被全局异常捕捉器过滤。

  • 在等待时间内使用其他功能,等待也会被注销。

Message.wait_channel()

注意

该方法不可用于支持私信的功能里

参数列表

参数名类型释义默认值
replyChainChain 对象
forcebool使用强制等待False
cleanbool是否清空消息列表True
max_timeint最长等待时间(秒数)30
data_filterCallableMessage 过滤器
levelint优先级0

wait_channel 方法用于等待子频道全体成员的回复

与 wait 方法不同的是,wait_channel 返回的不是 Message 对象,而是 ChannelMessagesItem 对象。内含等待事件的实例,和该次返回的消息。

ChannelMessagesItem

属性

属性类型释义
eventChannelWaitEvent等待事件的实例
messageMessageMessage对象

方法

方法名参数释义异步
close_event关闭等待事件

下面来看一个简单的例子

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    await data.send(Chain(data).text('hello everyone, tell me your name please~'))
+    while True:
+        await asyncio.sleep(0)
+        event = await data.wait_channel()
+        if event:
+            reply = event.message
+
+            if reply.text == 'stop':
+                event.close_event() # 关闭等待事件
+                break
+
+            await data.send(Chain(reply).text(f'hello,{reply.text}'))

close_event()

关闭等待事件

wait_channel 与 wait 的用法是大致相同的,但是 wait_channel 在接收到有效消息并返回后,不会像 wait 那样关闭事件,而是保持接收子频道的消息。在你的业务逻辑正常结束时,你必须使用 close_event 关闭它。

请注意

请务必让你的业务逻辑有机会关闭等待事件,否则等待事件没有被正常关闭时,它可能会持续拦截子频道消息直至超时自动关闭。

不清除消息队列

如果你持续调用 wait_channel(如示例所示),但你不希望在处理业务时错过子频道内的消息,可以设置参数 clean=False 让事件不清除消息队列。让你可以按顺序获取到子频道内的消息。

python
await data.wait_channel(clean=False)
`,39),p=[e];function c(r,y,F,D,i,d){return a(),n("div",null,p)}const B=s(o,[["render",c]]);export{A as __pageData,B as default}; diff --git a/assets/develop_basic_continuityMessage.md.f8d8bfa7.lean.js b/assets/develop_basic_continuityMessage.md.f8d8bfa7.lean.js new file mode 100644 index 00000000..e44ddf54 --- /dev/null +++ b/assets/develop_basic_continuityMessage.md.f8d8bfa7.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const t="/assets/hello4.58f3a96c.png",A=JSON.parse('{"title":"创建连续对话","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/continuityMessage.md","filePath":"develop/basic/continuityMessage.md","lastUpdated":1722566694000}'),o={name:"develop/basic/continuityMessage.md"},e=l("",39),p=[e];function c(r,y,F,D,i,d){return a(),n("div",null,p)}const B=s(o,[["render",c]]);export{A as __pageData,B as default}; diff --git a/assets/develop_basic_handleEvents.md.1fa0bea7.js b/assets/develop_basic_handleEvents.md.1fa0bea7.js new file mode 100644 index 00000000..5aa3f3c0 --- /dev/null +++ b/assets/develop_basic_handleEvents.md.1fa0bea7.js @@ -0,0 +1,60 @@ +import{_ as s,o as n,c as a,V as o}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"事件监听","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/handleEvents.md","filePath":"develop/basic/handleEvents.md","lastUpdated":1722566694000}'),l={name:"develop/basic/handleEvents.md"},p=o(`

事件监听

监听频道发生的事件。
一般来说消息(MESSAGE_CREATEAT_MESSAGE_CREATE以及DIRECT_MESSAGE_CREATE)也属于事件,但是在构建阶段,这些消息事件会被归类并产出 Message 对象。剩下的事件类型,则会产出 Event 对象。可以使用 on_event 装饰器去获取事件。

注册事件响应

python
from amiyabot import Event, BotAdapterProtocol
+
+...
+
+@bot.on_event()
+async def _(event: Event, instance: BotAdapterProtocol):
+    ...
+
+@bot.on_event('GUILD_CREATE')
+async def _(event: Event, instance: BotAdapterProtocol):
+    ...
+
+@bot.on_event(['CHANNEL_CREATE', 'CHANNEL_UPDATE'])
+async def _(event: Event, instance: BotAdapterProtocol):
+    ...
  • on_event 接受一个事件名或事件名列表作为参数(无参数则监听全事件)。事件名可参阅对应适配器服务的官方文档。
  • 响应函数是一个协程,接受 Event 对象和 bot 实例两个参数。

Event 对象

属性类型释义
appidstr发生该事件的 Bot AppId
event_namestr事件名
datadict事件的内容字典

频道事件

频道事件 Event.data 的值为 websocket 消息体里的 d 字段内容。

如下为 频道事件 - GUILD_CREATE 官方文档示例的 websocket 消息体。

json
{
+    "op": 0,
+    "s": 6,
+    "t": "GUILD_CREATE",
+    "d": {
+        "description": "频道介绍",
+        "icon": "",
+        "id": "200000000",
+        "joined_at": "2021-10-21T11:20:18+08:00",
+        "max_members": 300,
+        "member_count": 17,
+        "name": "频道名称",
+        "op_user_id": "100000000",
+        "owner_id": "100000000"
+    }
+}

在 on_event 里接收到时

python
@bot.on_event('GUILD_CREATE')
+async def _(event: Event, instance: BotAdapterProtocol):
+
+    print(event.data['name'])        // 频道名称
+    print(event.data['description']) // 频道介绍

频道的事件名和内容可以查看官方文档 事件订阅

mirai-api-http 事件

mirai-api-http 戳一戳事件推送的消息。

json
{
+    "type": "NudgeEvent",
+    "fromId": 123456,
+    "subject": {
+        "id": 123456,
+        "kind": "Group"
+    },
+    "action": "戳了戳",
+    "suffix": "的脸",
+    "target": 123456
+}

监听 type 的值 NudgeEvent 即可。

python
@bot.on_event('NudgeEvent')
+async def _(event: Event, instance: BotAdapterProtocol):
+    ...

go-cqhttp 事件

针对 go-cqhttp 事件的 数据结构,AmiyaBot 对其进行了分类,可以使用以下事件名精确获取。

如:戳一戳事件中 go-cqhttp 对其进行了三级分类。

json
{
+    "post_type": "notice",
+    "notice_type": "notify",
+    "sub_type": "poke"
+}

监听 notice 事件时,无法获得准确的事件。因为在 notice_type 的分类里,还包含了好友添加、消息撤回等一系列子事件。
当然,如果你需要监听这个大类的事件时,仍然可以监听这个事件名。

python
# 监听 post_type 为 notice 的事件
+@bot.on_event('notice')
+async def _(event: Event, instance: BotAdapterProtocol):
+    ...
+
+# 监听 post_type 为 notice 且 notice_type 为 notify 的事件
+@bot.on_event('notice.notify')
+async def _(event: Event, instance: BotAdapterProtocol):
+    ...

通过事件名 notice.notify.poke,即可监听到准确的戳一戳事件。

python
@bot.on_event('notice.notify.poke')
+async def _(event: Event, instance: BotAdapterProtocol):
+    ...

其他类别的事件同理,通过事件数据中的 post_type.xxxxx_type.sub_type 定义事件监听名即可。

`,30),t=[p];function e(c,r,D,F,y,i){return n(),a("div",null,t)}const E=s(l,[["render",e]]);export{A as __pageData,E as default}; diff --git a/assets/develop_basic_handleEvents.md.1fa0bea7.lean.js b/assets/develop_basic_handleEvents.md.1fa0bea7.lean.js new file mode 100644 index 00000000..59ca95f4 --- /dev/null +++ b/assets/develop_basic_handleEvents.md.1fa0bea7.lean.js @@ -0,0 +1 @@ +import{_ as s,o as n,c as a,V as o}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"事件监听","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/handleEvents.md","filePath":"develop/basic/handleEvents.md","lastUpdated":1722566694000}'),l={name:"develop/basic/handleEvents.md"},p=o("",30),t=[p];function e(c,r,D,F,y,i){return n(),a("div",null,t)}const E=s(l,[["render",e]]);export{A as __pageData,E as default}; diff --git a/assets/develop_basic_handleException.md.501ddbf6.js b/assets/develop_basic_handleException.md.501ddbf6.js new file mode 100644 index 00000000..14bf16db --- /dev/null +++ b/assets/develop_basic_handleException.md.501ddbf6.js @@ -0,0 +1,15 @@ +import{_ as s,o as a,c as n,V as o}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"异常监听","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/handleException.md","filePath":"develop/basic/handleException.md","lastUpdated":1722566694000}'),l={name:"develop/basic/handleException.md"},p=o(`

异常监听

AmiyaBot 内置了全局的用户层面异常捕获让程序不会轻易崩溃。如果你希望获取这些异常,可以通过注册异常处理器来获得它们。在执行消息响应或在消息响应筛选过程产生异常时,会执行这些注册的异常处理函数。

异常处理函数接受三个参数,分别是 异常类型实例 Exception适配器实例 BotAdapterProtocol产生异常的数据MessageEvent

python
from amiyabot import BotAdapterProtocol
+
+@bot.on_exception()
+async def _(err: Exception,
+            instance: BotAdapterProtocol,
+            data: Union[Message, Event]):
+    ...

指定异常类型

python
@bot.on_exception(KeyError)
+async def _(err: Exception,
+            instance: BotAdapterProtocol,
+            data: Union[Message, Event]):
+    ...

指定多种异常类型

python
@bot.on_exception([OSError, IndexError])
+async def _(err: Exception,
+            instance: BotAdapterProtocol,
+            data: Union[Message, Event]):
+    ...
`,8),e=[p];function t(c,r,y,D,F,i){return a(),n("div",null,e)}const d=s(l,[["render",t]]);export{A as __pageData,d as default}; diff --git a/assets/develop_basic_handleException.md.501ddbf6.lean.js b/assets/develop_basic_handleException.md.501ddbf6.lean.js new file mode 100644 index 00000000..5a936456 --- /dev/null +++ b/assets/develop_basic_handleException.md.501ddbf6.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as o}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"异常监听","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/handleException.md","filePath":"develop/basic/handleException.md","lastUpdated":1722566694000}'),l={name:"develop/basic/handleException.md"},p=o("",8),e=[p];function t(c,r,y,D,F,i){return a(),n("div",null,e)}const d=s(l,[["render",t]]);export{A as __pageData,d as default}; diff --git a/assets/develop_basic_index.md.52c59217.js b/assets/develop_basic_index.md.52c59217.js new file mode 100644 index 00000000..8d47ba94 --- /dev/null +++ b/assets/develop_basic_index.md.52c59217.js @@ -0,0 +1,19 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const o="/assets/hello.3b081946.png",p="/assets/hello2.56460902.png",h=JSON.parse('{"title":"开始使用","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/index.md","filePath":"develop/basic/index.md","lastUpdated":1722566694000}'),e={name:"develop/basic/index.md"},t=l(`

开始使用

在开始之前,我们希望你知道 AmiyaBot 是一款针对 QQ 频道机器人的框架。如果你想使用第三方机器人服务(如 mirai-api-http 或 go-cqhttp),可通过更改实例的适配器使用。
接下来的文档将围绕 QQ 频道机器人展开。如果需要 更改适配器 请在安装依赖后阅读适配器文档

我们建议你先在 QQ开放平台 了解 QQ 频道机器人的运营规则,这非常重要,因为在本文档里,关于这部分的内容将会非常少。如果你并不了解 QQ 频道机器人,后续的文档可能会对你造成疑惑。

安装依赖

amiyabot

bash
pip install amiyabot

创建你的第一个 Bot

  1. QQ开放平台 申请并创建你的 QQ 机器人。创建沙箱频道,并把你的机器人添加进频道里。(此处不作详细说明)
  2. 使用机器人的 appidtoken 创建一个 AmiyaBot 实例
python
import asyncio
+
+from amiyabot import AmiyaBot, Message, Chain
+
+bot = AmiyaBot(appid='******', token='******')
+
+
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')
+
+
+asyncio.run(bot.start())
  1. 运行代码,在频道里输入 @机器人 hello,你预期会看到如下输出。
image

那么恭喜你,你的 QQ 机器人已经可以正常运作了。

「这是个人迈出的一小步,但却是人类迈出的一大步。」—— 阿姆斯特朗

创建私域机器人

如果你在平台创建的是私域机器人,在 AmiyaBot 的参数里设置 private=True 来开启私域模式,私域机器人支持接收非 @机器人 的消息,你可以使机器人以更灵活的方式触发功能。

python
# 配置 private=True 让实例改为私域
+bot = AmiyaBot(appid='******', token='******', private=True)

使用前缀触发词唤醒机器人

python
bot = AmiyaBot(...)
+
+# 添加前缀触发词
+bot.set_prefix_keywords(['amiya', 'amy'])

此时机器人只能接收指定前缀的对话

image

沙箱环境

使用 QQGuildSandboxBotInstance 适配器将 API 调用更改为沙箱环境。沙箱环境只会收到测试频道的事件,且调用 openapi 仅能操作测试频道。

python
from amiyabot.adapters.tencent.qqGuild import QQGuildSandboxBotInstance
+
+bot = AmiyaBot(..., adapter=QQGuildSandboxBotInstance)
`,23),c=[t];function r(y,i,F,D,d,A){return a(),n("div",null,c)}const m=s(e,[["render",r]]);export{h as __pageData,m as default}; diff --git a/assets/develop_basic_index.md.52c59217.lean.js b/assets/develop_basic_index.md.52c59217.lean.js new file mode 100644 index 00000000..8fef9c20 --- /dev/null +++ b/assets/develop_basic_index.md.52c59217.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const o="/assets/hello.3b081946.png",p="/assets/hello2.56460902.png",h=JSON.parse('{"title":"开始使用","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/index.md","filePath":"develop/basic/index.md","lastUpdated":1722566694000}'),e={name:"develop/basic/index.md"},t=l("",23),c=[t];function r(y,i,F,D,d,A){return a(),n("div",null,c)}const m=s(e,[["render",r]]);export{h as __pageData,m as default}; diff --git a/assets/develop_basic_messageHandler.md.1199dda3.js b/assets/develop_basic_messageHandler.md.1199dda3.js new file mode 100644 index 00000000..22f67b5b --- /dev/null +++ b/assets/develop_basic_messageHandler.md.1199dda3.js @@ -0,0 +1,77 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const d=JSON.parse('{"title":"注册消息响应器","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/messageHandler.md","filePath":"develop/basic/messageHandler.md","lastUpdated":1722566694000}'),o={name:"develop/basic/messageHandler.md"},p=l(`

注册消息响应器

AmiyaBot 功能开发的关键模块一共有三个,分别是 AmiyaBotMessageChain

  • AmiyaBot 为机器人实例,包含了消息和事件的注册器。
  • Message 为接收的消息主体,内含预解析的消息内容,以及一些相关操作函数。Message 对象在此仅用于参数类型注解,供编辑器智能提示使用,任何时候,你都不需要实例化 Message 对象。
  • Chain 为机器人消息的创建工具。任何需要发送消息的时候,消息都必须由 Chain 类创建。核心会调用 Chain 类的 build 方法生成消息链。

首先需要知道的是,如何注册消息响应

on_message 装饰器

何为机器人的功能?

消息响应我们会在后续的文档称之为功能,因为机器人的主要功能,一般就是通过响应用户的消息实现的。

装饰器 on_message 作用于你的业务逻辑主体函数,以此注册消息响应来实现你的机器人功能。

python
# 当和机器人的对话中包含 'hello' 关键字时,将会触发该函数
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')

参数列表

参数名类型释义默认值
group_idstr功能组ID
keywords触发关键字,支持多种类型,详见本章文档
verifyCallable自定义校验方法,当该参数被赋值时,keywords 将会失效
check_prefixbool是否校验前缀或指定需要校验的前缀True
allow_directbool是否支持通过私信使用该功能False
direct_onlybool是否仅支持私信False
levelint关键字校验成功后函数的候选默认等级0

功能组

参数 group_id 可以为该功能设置功能组。功能组可以批量为功能设置参数。

实例化 GroupConfig 对象创建一个功能组,并将其设置到 bot 实例内。

参数名类型释义默认值
group_idstr功能组ID
check_prefixbool是否校验前缀或指定需要校验的前缀True
allow_directbool是否支持通过私信使用该功能False
direct_onlybool是否仅支持私信False
python
from amiyabot import GroupConfig
+
+fn_group = GroupConfig('test', check_prefix=False)
+bot.set_group_config(fn_group)  # 注册功能组

为消息响应设置 group_id 参数

python
# 传入功能组名称设置组别
+@bot.on_message(group_id='test', keywords='...')
+async def _(data: Message):
+    ...
+
+
+# 传入功能组对象设置组别(效果相同)
+@bot.on_message(group_id=fn_group, keywords='...')
+async def _(data: Message):
+    ...

注意

仅当 on_message 里没有设置该参数时,功能组的参数才会对其生效。否则优先使用 on_message 的参数。

私域模式的前缀校验

AmiyaBot 私域模式建议在对话中包含指定前缀才能进入消息分配器。设置前缀触发词后,在一些特殊的情况下,可以通过 忽略前缀检查校验完全匹配 的方式绕过检查。

接收不包含前缀的消息

添加参数 check_prefix=False 可忽略前缀检查

python
@bot.on_message(keywords='hello', check_prefix=False)
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')

接收指定前缀的消息

check_prefix 参数改为字符串列表可以临时修改前缀检查为指定单词

python
@bot.on_message(keywords='hello', check_prefix=['amiya', '🐰'])
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')

校验符合正则检查的句式

关键字传入 re.compile 对象,可以检查对话文本是否符合正则表达式。

python
import re
+...
+
+@bot.on_message(keywords=re.compile(r'hello,\\d+'))
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')

校验完全匹配的句式

完全匹配的句式指对话的文本内容全等于 keyword 关键字(不包括 @ 部分),使用工具类 Equal 即可达到效果。

python
from amiyabot import Equal
+...
+
+@bot.on_message(keywords=Equal('hello, amiya'))
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')

提示

在私域机器人下且不需要 @ 唤起的场合,Equal 会无视前缀检查。

组合多个和多种 keywords

keywords 支持由 字符串、正则、Equal 构成的列表,组合中包含 Equal 时,Equal 依然会无视前缀检查。

python
@bot.on_message(
+    keywords=[
+        'hello',
+        'hey',
+        Equal('hello, amiya'),
+        re.compile(r'hello,(\\d+)'),
+    ]
+)
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')

功能优先级

当关键字校验存在冲突时,可以通过指定优先级供消息分配器选择。
分配器的工作原理,是在完成检查之后,将通过校验的候选函数列表按优先级倒序排序,然后选取第一个执行。
所有函数的默认优先级都为 1,如果不指定优先级,分配器会按照加载的先后顺序选择。

python
# 如果不指定优先级,当对话内容为 "helloworld" 时,第一个函数会首先通过校验并输出。
+# 因为在模块加载阶段,第一个函数更早注册完毕。
+
+@bot.on_message(keywords='hello', level=1)
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')
+
+
+@bot.on_message(keywords='helloworld', level=2)
+async def _(data: Message):
+    return Chain(data).text('hello,world')

提示

优先级允许为 0 或负数

自定义检查

当关键字检查无法满足功能的触发方式时,就需要使用自定义检查。
自定义检查是一个协程函数,参数为 Message 对象,返回一个布尔值(必选)优先级(可选)关键值(可选)的元组。

python
async def my_verify(data: Message):
+    if 'hello' in data.text:
+        return True
+
+
+@bot.on_message(verify=my_verify)
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')

当消息响应获得执行权,自定义检查结果(Verify)将储存在 Message.verify 中。

Verify 对象

属性类型释义
resultbool检查结果
weightint优先级
keypointAny关键值信息

动态输出优先级的值

返回元组第二个值,即可以指定动态优先级。

python
async def my_verify(data: Message):
+    if ...:
+        return True, 2
+    elif ...:
+        return True, 1
+    return False

输出关键值

返回元组第三个值,可以向 Message 的检查结果里添加关键值信息。可以是任意类型。

python
async def my_verify(data: Message):
+    if ...:
+        return True, 1, {'name': 'my name'}
+    return False
+
+
+@bot.on_message(verify=my_verify)
+async def _(data: Message):
+    info = data.verify.keypoint # {'name': 'my name'}

使功能在私信里可用

设置参数 allow_direct=True,允许功能在私信里触发。
设置参数 direct_only=True,功能仅私信可触发。

python
@bot.on_message(keywords='hello', allow_direct=True)
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')
+
+
+# 仅私信可触发
+@bot.on_message(keywords='hi', direct_only=True)
+async def _(data: Message):
+    return Chain(data).text(f'hey, {data.nickname}')
`,55),t=[p];function e(c,r,y,F,D,i){return a(),n("div",null,t)}const B=s(o,[["render",e]]);export{d as __pageData,B as default}; diff --git a/assets/develop_basic_messageHandler.md.1199dda3.lean.js b/assets/develop_basic_messageHandler.md.1199dda3.lean.js new file mode 100644 index 00000000..d03fbe7f --- /dev/null +++ b/assets/develop_basic_messageHandler.md.1199dda3.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const d=JSON.parse('{"title":"注册消息响应器","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/messageHandler.md","filePath":"develop/basic/messageHandler.md","lastUpdated":1722566694000}'),o={name:"develop/basic/messageHandler.md"},p=l("",55),t=[p];function e(c,r,y,F,D,i){return a(),n("div",null,t)}const B=s(o,[["render",e]]);export{d as __pageData,B as default}; diff --git a/assets/develop_basic_multipleAccounts.md.86504678.js b/assets/develop_basic_multipleAccounts.md.86504678.js new file mode 100644 index 00000000..8999ce64 --- /dev/null +++ b/assets/develop_basic_multipleAccounts.md.86504678.js @@ -0,0 +1,51 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const B=JSON.parse('{"title":"多账号","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/multipleAccounts.md","filePath":"develop/basic/multipleAccounts.md","lastUpdated":1722566694000}'),o={name:"develop/basic/multipleAccounts.md"},p=l(`

多账号

AmiyaBot 支持同时启动多个账号,所有账号之间可以共享资源以及功能。

创建多个单独实例

你可以同时创建多个互不相关的实例,只需要实例化多个 AmiyaBot。多实例启动时,一些内置的资源对象不会重复创建多个,而是被它们共享,以节约内存。

python
import asyncio
+
+from amiyabot import AmiyaBot, Message, Chain
+
+bot1 = AmiyaBot(appid='******', token='******', private=True)
+bot2 = AmiyaBot(appid='******', token='******')
+
+
+@bot1.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')
+
+
+@bot2.on_message(keywords='hey')
+async def _(data: Message):
+    return Chain(data).text(f'hey, {data.nickname}')
+
+
+asyncio.run(
+    asyncio.wait([
+        bot1.start(),
+        bot2.start()
+    ])
+)

创建一个多账号实例

MultipleAccounts

MultipleAccounts 可以创建一个多账号实例,参数是多个 AmiyaBot 实例。它拥有与 AmiyaBot 一样的所有方法,所以你可以像 AmiyaBot 一样使用它来注册你的功能。
通过 MultipleAccounts 注册的功能,将被所有包含的 AmiyaBot 共享。而其中的 AmiyaBot 实例,仍能单独注册属于自己的私有功能。

python
import asyncio
+
+from amiyabot import AmiyaBot, MultipleAccounts, Message, Chain
+
+bot1 = AmiyaBot(appid='******', token='******', private=True)
+bot2 = AmiyaBot(appid='******', token='******')
+
+bot = MultipleAccounts(bot1, bot2, AmiyaBot(appid='******', token='******'), ...)
+
+
+# 公共功能
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')
+
+
+# bot1 的私有功能
+@bot1.on_message(keywords='hey')
+async def _(data: Message):
+    return Chain(data).text(f'hey, my name is Amiyabot')
+
+
+asyncio.run(bot.start())

多账号热插拔

多账号支持动态创建和删除里面的实例,也允许先创建空多账号实例。随后往里面插入 AmiyaBot 对象。

MultipleAccounts.append()

插入一个实例

参数名类型释义默认值
itemAmiyaBotAmiyaBot 实例
enable_chromiumbool启动时开启 chromiumFalse
start_upbool插入后立即启动True

示例

python
# 创建一个空多账号
+bot = MultipleAccounts()
+# 插入并启动一个实例
+bot.append(AmiyaBot(appid='12345', ...))
+# 删除实例,同时关闭实例的连接
+del bot['12345']
`,16),t=[p];function e(c,F,r,y,D,i){return a(),n("div",null,t)}const d=s(o,[["render",e]]);export{B as __pageData,d as default}; diff --git a/assets/develop_basic_multipleAccounts.md.86504678.lean.js b/assets/develop_basic_multipleAccounts.md.86504678.lean.js new file mode 100644 index 00000000..d0131a32 --- /dev/null +++ b/assets/develop_basic_multipleAccounts.md.86504678.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const B=JSON.parse('{"title":"多账号","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/multipleAccounts.md","filePath":"develop/basic/multipleAccounts.md","lastUpdated":1722566694000}'),o={name:"develop/basic/multipleAccounts.md"},p=l("",16),t=[p];function e(c,F,r,y,D,i){return a(),n("div",null,t)}const d=s(o,[["render",e]]);export{B as __pageData,d as default}; diff --git a/assets/develop_basic_recallMessage.md.35c06f76.js b/assets/develop_basic_recallMessage.md.35c06f76.js new file mode 100644 index 00000000..ed8638d4 --- /dev/null +++ b/assets/develop_basic_recallMessage.md.35c06f76.js @@ -0,0 +1,40 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const B=JSON.parse('{"title":"撤回消息","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/recallMessage.md","filePath":"develop/basic/recallMessage.md","lastUpdated":1722566694000}'),o={name:"develop/basic/recallMessage.md"},p=l(`

撤回消息

撤回一条消息。

在 Message 对象中撤回

使用 Message 对象的 recall 方法,撤回当前消息。

Message.recall()

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    await data.recall()

你可以在任何能获取到 Message 对象的地方使用 recall 方法。比如在连续对话或异常监听里。

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    # 等待事件返回的也是 Message 对象
+    reply = await data.wait(Chain(data).text('...'))
+    if reply:
+        await reply.recall()
python
@bot.on_exception()
+async def _(err: Exception,
+            instance: BotAdapterProtocol,
+            data: Union[Message, Event]):
+    if type(data) is Message:
+        await data.recall()

手动撤回

使用适配器实例的 recall_message 方法

AmiyaBot.instance.recall_message()

参数名类型释义默认值
message_idstr消息ID(通常可以在 Message.message_id 获取到)
dataMessageMessage 对象None
python
await bot.instance.recall_message(message_id='......', target_id='......')

撤回 Bot 发送的消息

如果是通过在消息响应器里面返回 Chain 对象或等待函数 Message.wait() 发送的消息,是无法撤回的,但后者可以通过另外的方法达到撤回效果。

发送消息的方法是否可撤回
Message.send()✅ 可以撤回
Message.wait()❌ 无法撤回
Message.wait_channel()❌ 无法撤回
return Chain()❌ 无法撤回
python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    chain = Chain(data).text(f'hello, {data.nickname}')
+
+    callback = await data.send(chain)  # ✅ 可以撤回
+    if callback:
+        await callback.recall() # 使用回调对象撤回
+
+    wait = await data.wait(chain)  # ❌ 无法撤回
+    event = await data.wait_channel(chain)  # ❌ 无法撤回
+
+    return chain  # ❌ 无法撤回

Message.send() 方法返回一个 MessageCallback 对象或其组成的列表(语音或频道多图消息会产生分开发送的结果)。如果消息没有发送成功则返回 None

调用 MessageCallback.recall() 即可撤回发送的消息。

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+
+    callback = await data.send(...)
+    if callback:
+        await callback.recall()
+        # 或
+        # for item in callback:
+        #     await item.recall()

撤回等待的消息

Message.wait() 没有返回执行 send 时获得的 MessageCallback,因此你无法在使用该方法发送消息的情况下撤回,但你可以配合 send 达到这个效果。

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    callback = await data.send(Chain(data).text('hello, what\\'s your name?'))  # 使用 send 方法代替 wait 发送消息
+    wait = await data.wait()  # 只等待,不发送消息
+
+    if callback and not wait:
+        await callback.recall()
+
+    ...

撤回合并转发的消息

撤回合并转发

`,26),t=[p];function e(c,r,y,D,F,i){return a(),n("div",null,t)}const d=s(o,[["render",e]]);export{B as __pageData,d as default}; diff --git a/assets/develop_basic_recallMessage.md.35c06f76.lean.js b/assets/develop_basic_recallMessage.md.35c06f76.lean.js new file mode 100644 index 00000000..a3dbbe75 --- /dev/null +++ b/assets/develop_basic_recallMessage.md.35c06f76.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const B=JSON.parse('{"title":"撤回消息","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/recallMessage.md","filePath":"develop/basic/recallMessage.md","lastUpdated":1722566694000}'),o={name:"develop/basic/recallMessage.md"},p=l("",26),t=[p];function e(c,r,y,D,F,i){return a(),n("div",null,t)}const d=s(o,[["render",e]]);export{B as __pageData,d as default}; diff --git a/assets/develop_basic_recvMessage.md.4e302953.js b/assets/develop_basic_recvMessage.md.4e302953.js new file mode 100644 index 00000000..5547702d --- /dev/null +++ b/assets/develop_basic_recvMessage.md.4e302953.js @@ -0,0 +1,11 @@ +import{_ as t,o as s,c as a,V as e}from"./chunks/framework.63f12d77.js";const _=JSON.parse('{"title":"接收消息","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/recvMessage.md","filePath":"develop/basic/recvMessage.md","lastUpdated":1722566694000}'),d={name:"develop/basic/recvMessage.md"},r=e(`

接收消息

在上一节 注册消息响应 中讲述了如何注册一个接收指定消息的函数,当接收到消息时,函数被执行时,参数 data: Message 就是接收到的消息的内容。

Message 对象是接收到消息之后预处理化的一个消息数据对象。内含这则消息相关的各项属性,以及针对这则消息的一些操作API。
该对象主要应用在功能函数和自定义检查中。建议在开发时引入 Message 对象并注解在对应地方。

python
from amiyabot import Message
+
+
+async def my_verify(data: Message):
+    ...
+
+
+@bot.on_message(verify=my_verify)
+async def _(data: Message):
+    print('recv:', data.text)
+    ...

Message 对象

重要变动

1.9.8 起,如果配置了前缀触发词,Message 对象内的消息文本系列字段将不再包含触发对话的前缀(Commit 99ada6b), 前缀在对话文本中被移除后将赋值到 text_prefix 属性内。

属性

属性类型释义
instanceBotAdapterProtocolbot 实例
messagedict原始消息字典
message_idstr消息 ID
message_typestr消息类型(适用于群聊适配器)
faceList[str]消息内表情 ID 列表
imageList[str]消息内图片 URL 列表
textstr消息文本(不包含触发词、中间件处理)
text_digitsstr消息文本(不包含触发词、中间件处理、中文转数字处理)
text_unsignedstr消息文本(不包含触发词、去字符处理)
text_originalstr消息文本(原始文本)
text_wordsList[str]消息文本分词
text_prefixstr消息触发词
at_targetList[str]消息内 @ 的对象列表
is_atbool是否 @ 机器人
is_adminbool是否为子频道管理员
is_directbool是否是私信消息
user_idstr用户 ID
guild_idstr频道 ID
src_guild_idstr来源频道 ID,私信下有效
channel_idstr子频道 ID
nicknamestr用户昵称
avatarstr用户头像的 URL
joined_atISO8601 timestamp用户加入频道的时间
verifyVerify 对象自定义检查的结果
timeint消息时间

方法

方法名参数释义异步
sendreply发送一条消息
waitreply,force,max_time,data_filter等待用户消息
wait_channelreply,force,clean,max_time,data_filter等待子频道消息
recall撤回消息

接下来,使用 Message 对象提供的属性完成业务逻辑,并发送消息

`,11),n=[r];function l(o,p,c,i,y,h){return s(),a("div",null,n)}const F=t(d,[["render",l]]);export{_ as __pageData,F as default}; diff --git a/assets/develop_basic_recvMessage.md.4e302953.lean.js b/assets/develop_basic_recvMessage.md.4e302953.lean.js new file mode 100644 index 00000000..dfe6957f --- /dev/null +++ b/assets/develop_basic_recvMessage.md.4e302953.lean.js @@ -0,0 +1 @@ +import{_ as t,o as s,c as a,V as e}from"./chunks/framework.63f12d77.js";const _=JSON.parse('{"title":"接收消息","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/recvMessage.md","filePath":"develop/basic/recvMessage.md","lastUpdated":1722566694000}'),d={name:"develop/basic/recvMessage.md"},r=e("",11),n=[r];function l(o,p,c,i,y,h){return s(),a("div",null,n)}const F=t(d,[["render",l]]);export{_ as __pageData,F as default}; diff --git a/assets/develop_basic_sendActiveMessage.md.6174eebb.js b/assets/develop_basic_sendActiveMessage.md.6174eebb.js new file mode 100644 index 00000000..eaf8e536 --- /dev/null +++ b/assets/develop_basic_sendActiveMessage.md.6174eebb.js @@ -0,0 +1,22 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"发送主动消息","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/sendActiveMessage.md","filePath":"develop/basic/sendActiveMessage.md","lastUpdated":1722566694000}'),o={name:"develop/basic/sendActiveMessage.md"},p=l(`

发送主动消息

主动消息限制

主动消息需要频道设置允许机器人推送,发送消息也存在数量限制。
详见官方文档 接入流程-语料配置-消息类型

AmiyaBot.send_message()

send_message 是发送主动消息的方法,它的第一个参数 chain 需要传入一个 Chain 对象。可以通过实例化一个无 Message 的 Chain 得到。

python
message = Chain().text('hello')
参数名类型释义默认值
chainChainChain 对象
user_idstr用户ID
channel_idstr子频道ID
direct_src_guild_idstr来源频道ID

发送一条主动子频道消息

python
bot = AmiyaBot(...)
+message = Chain().text('hello')
+
+await bot.send_message(message, channel_id='******')

发送一条主动私信 Beta

传入参数 user_id(用户ID)和 direct_src_guild_id(来源频道ID),send_message 将会发送主动私信消息。

python
bot = AmiyaBot(...)
+message = Chain().text('hello')
+
+await bot.send_message(message,
+                       user_id='*******',
+                       direct_src_guild_id='*******')

在多账号实例里使用 send_message

python
bot = MultipleAccounts(
+    [
+        AmiyaBot(appid='111111', ...),
+        AmiyaBot(appid='222222', ...),
+    ]
+)
+
+await bot['222222'].send_message(...)

在事件响应里使用 send_message

提示

事件响应的方法通常可以返回触发了该事件的实例。

事件监听

python
@bot.on_event('MESSAGE_DELETE')
+async def _(event: Event, instance: BotAdapterProtocol):
+    await instance.send_message(...)

异常监听

python
@bot.on_exception()
+async def _(err: Exception,
+            instance: BotAdapterProtocol,
+            data: Union[Message, Event]):
+    await instance.send_message(...)
`,19),e=[p];function t(c,r,F,D,y,i){return a(),n("div",null,e)}const B=s(o,[["render",t]]);export{A as __pageData,B as default}; diff --git a/assets/develop_basic_sendActiveMessage.md.6174eebb.lean.js b/assets/develop_basic_sendActiveMessage.md.6174eebb.lean.js new file mode 100644 index 00000000..dac46569 --- /dev/null +++ b/assets/develop_basic_sendActiveMessage.md.6174eebb.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"发送主动消息","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/sendActiveMessage.md","filePath":"develop/basic/sendActiveMessage.md","lastUpdated":1722566694000}'),o={name:"develop/basic/sendActiveMessage.md"},p=l("",19),e=[p];function t(c,r,F,D,y,i){return a(),n("div",null,e)}const B=s(o,[["render",t]]);export{A as __pageData,B as default}; diff --git a/assets/develop_basic_sendMessage.md.2be0a78a.js b/assets/develop_basic_sendMessage.md.2be0a78a.js new file mode 100644 index 00000000..a7aa1b4f --- /dev/null +++ b/assets/develop_basic_sendMessage.md.2be0a78a.js @@ -0,0 +1,5 @@ +import{_ as a,o as s,c as n,V as l}from"./chunks/framework.63f12d77.js";const t="/assets/hello3.bbe26c93.png",A=JSON.parse('{"title":"发送消息","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/sendMessage.md","filePath":"develop/basic/sendMessage.md","lastUpdated":1722566694000}'),e={name:"develop/basic/sendMessage.md"},o=l(`

发送消息

在消息响应器内返回 Chain 对象,或使用 Message 对象的 send 方法,均可发送消息。

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    await data.send(Chain(data).text('hello'))
+
+    return Chain(data).text(data.nickname)
image

Chain 对象

参数名类型释义默认值
dataMessageMessage 对象None
atbool是否 @ 用户True
referencebool是否回复用户(引用消息)False
chain_builderChainBuilderChain 辅助构建实例ChainBuilder()

Chain 对象是构建你的消息体的工具类。任何需要发送消息的时候,消息都必须由 Chain 类创建。
Chain 对象提供丰富的消息构建方式,可以让你发送多彩的文字图片,甚至是html模板。

这是最简单的一条文本消息:

python
Chain(data).text('hello, world')

更多类型请查看左侧导航消息构建元素

构建消息的方法

普通消息

Chain 对象支持链式语法,用于构建复杂的消息结构。
只需要按顺序以链式使用上述方法,即可拼接出内容丰富的消息。Chain 在最终构建消息的时候,会优化图片与文字的组成,减少消息的请求数量。

python
Chain(data).text(...).image(...).text(...).html(...)

合并转发消息

合并转发消息需要使用独立的工具类创建

空 Chain

实例化 Chain 对象时,不传入 Message 对象构建的。本文称之为 “空 Chain”。空 Chain 一般用于预构建消息。

python
Chain().text(...).image(...)

使用辅助类扩展构建

Chain 对象在构建消息时,可使用辅助类介入媒体消息或浏览器的构建过程。请移步 进阶指南 - 介入媒体消息的构建过程

',22),p=[o];function r(c,F,i,d,h,y){return s(),n("div",null,p)}const g=a(e,[["render",r]]);export{A as __pageData,g as default}; diff --git a/assets/develop_basic_sendMessage.md.2be0a78a.lean.js b/assets/develop_basic_sendMessage.md.2be0a78a.lean.js new file mode 100644 index 00000000..6ad8d1cc --- /dev/null +++ b/assets/develop_basic_sendMessage.md.2be0a78a.lean.js @@ -0,0 +1 @@ +import{_ as a,o as s,c as n,V as l}from"./chunks/framework.63f12d77.js";const t="/assets/hello3.bbe26c93.png",A=JSON.parse('{"title":"发送消息","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/sendMessage.md","filePath":"develop/basic/sendMessage.md","lastUpdated":1722566694000}'),e={name:"develop/basic/sendMessage.md"},o=l("",22),p=[o];function r(c,F,i,d,h,y){return s(),n("div",null,p)}const g=a(e,[["render",r]]);export{A as __pageData,g as default}; diff --git a/assets/develop_basic_statement.md.9327bd3e.js b/assets/develop_basic_statement.md.9327bd3e.js new file mode 100644 index 00000000..73e88dd1 --- /dev/null +++ b/assets/develop_basic_statement.md.9327bd3e.js @@ -0,0 +1,7 @@ +import{_ as s,o as a,c as e,V as n}from"./chunks/framework.63f12d77.js";const m=JSON.parse('{"title":"声明","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/statement.md","filePath":"develop/basic/statement.md","lastUpdated":1722566694000}'),t={name:"develop/basic/statement.md"},o=n(`

声明

在本章后续文档中,为了减少篇幅量,将不会再在代码示例中出现 AmiyaBotMultipleAccounts 类的实例化代码。统一以变量 bot 表示已经实例化的 AmiyaBotMultipleAccounts 类。

你将会在诸多场景中看到 bot 变量的存在。

python
# 装饰器
+@bot.on_message(...)
+
+# 调用方法
+bot.some_func(...)
+
+...
`,4),l=[o];function p(c,r,i,d,_,y){return a(),e("div",null,l)}const A=s(t,[["render",p]]);export{m as __pageData,A as default}; diff --git a/assets/develop_basic_statement.md.9327bd3e.lean.js b/assets/develop_basic_statement.md.9327bd3e.lean.js new file mode 100644 index 00000000..e050131c --- /dev/null +++ b/assets/develop_basic_statement.md.9327bd3e.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as e,V as n}from"./chunks/framework.63f12d77.js";const m=JSON.parse('{"title":"声明","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/statement.md","filePath":"develop/basic/statement.md","lastUpdated":1722566694000}'),t={name:"develop/basic/statement.md"},o=n("",4),l=[o];function p(c,r,i,d,_,y){return a(),e("div",null,l)}const A=s(t,[["render",p]]);export{m as __pageData,A as default}; diff --git a/assets/develop_basic_testInstance.md.9912ed2d.js b/assets/develop_basic_testInstance.md.9912ed2d.js new file mode 100644 index 00000000..0986e51f --- /dev/null +++ b/assets/develop_basic_testInstance.md.9912ed2d.js @@ -0,0 +1,16 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const o="/assets/test.6cd83df6.png",d=JSON.parse('{"title":"使用测试实例调试","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/testInstance.md","filePath":"develop/basic/testInstance.md","lastUpdated":1722566694000}'),p={name:"develop/basic/testInstance.md"},t=l(`

使用测试实例调试

使用适配器 test_instance 并配置 host、port 参数即可启动一个测试实例。

python
import asyncio
+
+from amiyabot import AmiyaBot, Message, Chain
+from amiyabot.adapters.test import test_instance
+
+bot = AmiyaBot(appid='123456',
+               token='',
+               adapter=test_instance('127.0.0.1', 32001))
+
+
+@bot.on_message(keywords='hello', check_prefix=False)
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')
+
+
+asyncio.run(bot.start())

运行实例,访问 https://console.amiyabot.com/#/test 并输入配置的地址和 appid 连接测试服务,即可模拟测试对话。

test.png

',5),e=[t];function c(r,F,y,D,i,A){return a(),n("div",null,e)}const _=s(p,[["render",c]]);export{d as __pageData,_ as default}; diff --git a/assets/develop_basic_testInstance.md.9912ed2d.lean.js b/assets/develop_basic_testInstance.md.9912ed2d.lean.js new file mode 100644 index 00000000..7bac337a --- /dev/null +++ b/assets/develop_basic_testInstance.md.9912ed2d.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const o="/assets/test.6cd83df6.png",d=JSON.parse('{"title":"使用测试实例调试","description":"","frontmatter":{},"headers":[],"relativePath":"develop/basic/testInstance.md","filePath":"develop/basic/testInstance.md","lastUpdated":1722566694000}'),p={name:"develop/basic/testInstance.md"},t=l("",5),e=[t];function c(r,F,y,D,i,A){return a(),n("div",null,e)}const _=s(p,[["render",c]]);export{d as __pageData,_ as default}; diff --git a/assets/develop_design.md.6a51dd3e.js b/assets/develop_design.md.6a51dd3e.js new file mode 100644 index 00000000..02cf8fc3 --- /dev/null +++ b/assets/develop_design.md.6a51dd3e.js @@ -0,0 +1 @@ +import{_ as e,o as a,c as t,V as o}from"./chunks/framework.63f12d77.js";const r="/assets/account.d1c96da5.svg",s="/assets/handlerFactory.f4bc05d9.svg",d="/assets/adapter.b252f80a.svg",n="/assets/centerProcessor.46a8ea9e.svg",q=JSON.parse('{"title":"设计","description":"","frontmatter":{},"headers":[],"relativePath":"develop/design.md","filePath":"develop/design.md","lastUpdated":1722566694000}'),c={name:"develop/design.md"},i=o('

设计

AmiyaBot 是一款 QQ 机器人框架,基于异步I/O构建,并提供了装饰器模式(Decorator Pattern)以及插件化动态导入(Dynamic import)的编程方式。 内置多种适配器兼容不同的服务来源以及丰富的消息构建类型,旨在帮助你更高效地编写业务逻辑,实现你的创意。

框架结构可分为业务模块通讯模块数据处理模块存储模块运转中心五个组成部分。它们独立运作,并在彼此之间相互提供数据。

业务模块

业务模块由插件(Plugin)账号实例(AmiyaBot)多账号实例(MultipleAccounts) 组成。它们一般会被组织成层层嵌套的树状结构。账号实例和多账号实例是同质的,它们均可以被运转中心(CenterProcessor)直接访问,运转中心无法访问插件。

运转中心在访问这些对象时,顶级对象会组合所有子级对象的属性提供给运转中心。

插件设计

实现上述模式的思路来源于 Vue 的 组件设计 ,所以在代码层面,插件与账号实例都属于“组件”,理论上账号实例之间也能互相嵌套。但在设计时加入了限制,防止这种关系的出现。

业务设计

业务模块通过各种装饰器来定义业务逻辑以及规则。这些装饰器都来源于它们继承的工厂对象(BotHandlerFactory),工厂对象是业务模块与运转中心的桥梁,业务函数会被工厂对象收集并封装,最终提供给运转中心调用。

账号实例图解

通讯与数据处理模块

通讯模块主要形式为适配器(Adapter),用于对接由机器人运营方提供的服务。

适配器

账号实例里面有一个重要参数:adapter,它指定了通讯模块的运行方式(选择适配器)以适配不同运营方的连接协议。

通讯模块负责解决对接收和发送的数据进行解包与封包,所以它与数据处理模块紧密相连。适配器必须为数据处理模块提供统一的接口,在与不同的运营方服务通讯过程中,运转中心获取到的源数据格式都必须是一致的。而接收到运转中心需要发出的数据时,适配器需要把数据封包为运营方协定的格式,完成发送。

账号实例也可以脱离运转中心的调控随时调用适配器与运营方服务通讯,完成一些特殊情况下的操作。

运转中心

运转中心包含事件处理消息处理分配器日志 等各种将所有模块相连的处理单元,是业务层的主要调度模块。在接收到由适配器传入的消息后,运转中心会将消息归类并分发到不同的处理模块。

消息处理

分配到消息处理的数据,将会对数据和业务模块收集的消息响应器(on_message)进行匹配,并将匹配成功的消息响应器按优先级排序,选取最高优先级的执行。

消息响应器的执行结果会经由运转中心返回到适配器,进行封包后发送。

这个过程在运转中心内称为“生命周期”,工厂对象可以介入这些周期影响消息处理的分配与执行结果。

结语

存储模块以及运转中心的日志等模块,在本文将忽略不谈。这些模块依赖第三方库或 Python 的标准库,本框架仅对其做了适度的封装。

',29),l=[i];function h(p,_,m,u,g,b){return a(),t("div",null,l)}const P=e(c,[["render",h]]);export{q as __pageData,P as default}; diff --git a/assets/develop_design.md.6a51dd3e.lean.js b/assets/develop_design.md.6a51dd3e.lean.js new file mode 100644 index 00000000..c0fec390 --- /dev/null +++ b/assets/develop_design.md.6a51dd3e.lean.js @@ -0,0 +1 @@ +import{_ as e,o as a,c as t,V as o}from"./chunks/framework.63f12d77.js";const r="/assets/account.d1c96da5.svg",s="/assets/handlerFactory.f4bc05d9.svg",d="/assets/adapter.b252f80a.svg",n="/assets/centerProcessor.46a8ea9e.svg",q=JSON.parse('{"title":"设计","description":"","frontmatter":{},"headers":[],"relativePath":"develop/design.md","filePath":"develop/design.md","lastUpdated":1722566694000}'),c={name:"develop/design.md"},i=o("",29),l=[i];function h(p,_,m,u,g,b){return a(),t("div",null,l)}const P=e(c,[["render",h]]);export{q as __pageData,P as default}; diff --git a/assets/develop_index.md.cb06d4cf.js b/assets/develop_index.md.cb06d4cf.js new file mode 100644 index 00000000..9002b0a4 --- /dev/null +++ b/assets/develop_index.md.cb06d4cf.js @@ -0,0 +1 @@ +import{_ as a,o as t,c as d,C as e,a as o}from"./chunks/framework.63f12d77.js";const x=JSON.parse('{"title":"欢迎访问开发文档","description":"","frontmatter":{"sidebar":false},"headers":[],"relativePath":"develop/index.md","filePath":"develop/index.md","lastUpdated":1722566694000}'),s={name:"develop/index.md"},n=e("h1",{id:"欢迎访问开发文档",tabindex:"-1"},[o("欢迎访问开发文档 "),e("a",{class:"header-anchor",href:"#欢迎访问开发文档","aria-label":'Permalink to "欢迎访问开发文档"'},"​")],-1),l=e("ul",null,[e("li",null,[e("a",{href:"/develop/basic/"},"基础开发指南")]),e("li",null,[e("a",{href:"/develop/advanced/"},"进阶开发指南")])],-1),r=[n,l];function i(c,p,_,h,f,m){return t(),d("div",null,r)}const v=a(s,[["render",i]]);export{x as __pageData,v as default}; diff --git a/assets/develop_index.md.cb06d4cf.lean.js b/assets/develop_index.md.cb06d4cf.lean.js new file mode 100644 index 00000000..9002b0a4 --- /dev/null +++ b/assets/develop_index.md.cb06d4cf.lean.js @@ -0,0 +1 @@ +import{_ as a,o as t,c as d,C as e,a as o}from"./chunks/framework.63f12d77.js";const x=JSON.parse('{"title":"欢迎访问开发文档","description":"","frontmatter":{"sidebar":false},"headers":[],"relativePath":"develop/index.md","filePath":"develop/index.md","lastUpdated":1722566694000}'),s={name:"develop/index.md"},n=e("h1",{id:"欢迎访问开发文档",tabindex:"-1"},[o("欢迎访问开发文档 "),e("a",{class:"header-anchor",href:"#欢迎访问开发文档","aria-label":'Permalink to "欢迎访问开发文档"'},"​")],-1),l=e("ul",null,[e("li",null,[e("a",{href:"/develop/basic/"},"基础开发指南")]),e("li",null,[e("a",{href:"/develop/advanced/"},"进阶开发指南")])],-1),r=[n,l];function i(c,p,_,h,f,m){return t(),d("div",null,r)}const v=a(s,[["render",i]]);export{x as __pageData,v as default}; diff --git a/assets/develop_plugin_addDoc.md.53e3a292.js b/assets/develop_plugin_addDoc.md.53e3a292.js new file mode 100644 index 00000000..64c49cfc --- /dev/null +++ b/assets/develop_plugin_addDoc.md.53e3a292.js @@ -0,0 +1,26 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"添加插件文档","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/addDoc.md","filePath":"develop/plugin/addDoc.md","lastUpdated":1722566694000}'),o={name:"develop/plugin/addDoc.md"},p=l(`

添加插件文档

你应该添加一个文档并详细描述插件的使用方法

添加一个 markdown 文档

text
Amiya-Bot
+├── pluginsDev
+│   ├── myPlugin
+│   │   ├── __init__.py
+│   │   ├── main.py
+│   │   ├── README.md
+│   │   └── HOWTOUSE.md
+│   ...
+...

demo 允许直接使用 markdown 文件路径作为文档,只需要把路径传入到 PluginInstance 对象的 document 参数。

添加使用指引文档

若使用了 AmiyaBotPluginInstance 对象创建插件,可使用参数 instruction,其作用是当 bot 的用户在使用 “查看功能指引” 类的指令时,向其展示 instruction 的内容。document 更偏向于提供给 bot 的部署者查看的文档。在没有配置 instruction 时,“查看功能指引” 将返回 document 的内容。

python
import os
+
+from amiyabot import PluginInstance, AmiyaBotPluginInstance
+
+plugin_dir = os.path.dirname(__file__)
+
+bot = PluginInstance(
+    document=f'{plugin_dir}/README.md'
+)
+# 或
+bot = AmiyaBotPluginInstance(
+    document=f'{plugin_dir}/README.md',
+    instruction=f'{plugin_dir}/HOWTOUSE.md'
+)

直接在参数内编写

提示

我们不推荐这种做法,除非你的插件文档只有少量文本。

python
bot = PluginInstance(
+    document='''
+        ...
+    '''
+)
`,11),e=[p];function t(c,r,i,y,d,D){return a(),n("div",null,e)}const u=s(o,[["render",t]]);export{h as __pageData,u as default}; diff --git a/assets/develop_plugin_addDoc.md.53e3a292.lean.js b/assets/develop_plugin_addDoc.md.53e3a292.lean.js new file mode 100644 index 00000000..82f1207c --- /dev/null +++ b/assets/develop_plugin_addDoc.md.53e3a292.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const h=JSON.parse('{"title":"添加插件文档","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/addDoc.md","filePath":"develop/plugin/addDoc.md","lastUpdated":1722566694000}'),o={name:"develop/plugin/addDoc.md"},p=l("",11),e=[p];function t(c,r,i,y,d,D){return a(),n("div",null,e)}const u=s(o,[["render",t]]);export{h as __pageData,u as default}; diff --git a/assets/develop_plugin_amiyaBotPluginInstance.md.9e3e1e87.js b/assets/develop_plugin_amiyaBotPluginInstance.md.9e3e1e87.js new file mode 100644 index 00000000..2b2c54dd --- /dev/null +++ b/assets/develop_plugin_amiyaBotPluginInstance.md.9e3e1e87.js @@ -0,0 +1,25 @@ +import{_ as s}from"./chunks/plugin3.7807f651.js";import{_ as a,o as n,c as t,V as l}from"./chunks/framework.63f12d77.js";const g=JSON.parse('{"title":"AmiyaBotPluginInstance","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/amiyaBotPluginInstance.md","filePath":"develop/plugin/amiyaBotPluginInstance.md","lastUpdated":1722566694000}'),o={name:"develop/plugin/amiyaBotPluginInstance.md"},e=l(`

AmiyaBotPluginInstance

AmiyaBotPluginInstance 是 兔兔-v6 项目中的对插件类 PluginInstance 的扩展实现。使用该类创建插件时,能够获得更多的能力。

在 demo 项目里导入 AmiyaBotPluginInstance 创建插件。

python
from core import AmiyaBotPluginInstance
+
+bot = AmiyaBotPluginInstance(
+    name='我的插件',
+    version='1.0',
+    plugin_id='my-plugin',
+    description='我的第一个插件',
+    channel_config_default=...,
+    channel_config_schema=...,
+    global_config_default=...,
+    global_config_schema=...,
+    deprecated_config_delete_days=...,
+)

AmiyaBotPluginInstance 继承了 PluginInstance,并且拥有以下新参数和方法

参数

参数名类型释义默认值
instructionstr使用指引文档None
requirementsList[Requirement]插件依赖None
channel_config_defaultstr频道级别配置默认值None
channel_config_schemastr频道级别配置表单的 JsonSchemaNone
global_config_defaultstr全局级别配置默认值None
global_config_schemastr全局级别配置表单的 JsonSchemaNone
deprecated_config_delete_daysint旧配置项失效的天数7
  • 默认值和 JsonSchema 传入的值均为字符串,可以是 JSON 字符串或 json 文件路径。(默认值允许使用 yaml 文件路径)
  • 在控制台中点击 重置为默认 时会使用默认值的 JSON 数据覆盖,创建新配置项时使用默认值的 JSON 数据填充。
  • 如果提供了 JsonSchema,将会使用 JsonSchema 创建表单界面,否则使用默认值的 JSON 数据。
  • 如果提供了 JsonSchema,必须同时提供默认值数据。
python
plugin_dir = os.path.dirname(__file__)
+
+bot = AmiyaBotPluginInstance(
+    channel_config_default=f'{plugin_dir}/config.yaml',
+    channel_config_schema=f'{plugin_dir}/jsonSchema.json'
+)

使用 JsonSchema 对接控制台

你可以通过对接控制台使用户能够使用控制台的界面管理你的插件。如下所示。

请阅读 介绍文档 了解如何编辑 jsonSchema.json 文件。

get_config

读取一个指定名称的配置项,如果没有频道级别的配置则返回同名全局配置,如果也没有全局配置,返回 None。传入 channel_id=None 可以直接读取全局配置。

参数名类型释义默认值
config_namestr配置名称
channel_idstr频道IDNone
python
config_value = bot.get_config('name', channel_id='...')

set_config

写入配置,传入 channel_id=None 可以强制指定写入全局配置。

参数名类型释义默认值
config_namestr配置名称
config_valueAny配置值,仅支持可被 JSON 序列化的值类型
channel_idstr频道IDNone
python
bot.set_config('name', 'value', channel_id='...')

说明

插件加载时会进行下面的校验,校验不通过则会报错:

  • 提供了 schema 则必须提供对应的 default,反之则不必。
  • 如果给出了 schema,则会用 schema 对提供的 default 进行校验。

当有下列需求的时候,建议考虑提供 schema 文件:

  • 您想要使用下拉列表框。schema 中指定 enum 元素时,界面会生成下拉列表框。
  • 您想要对用户的配置进行校验,如果不满足条件时输出提示。

提供 channel_config_default 时,界面可以新建频道配置。

插件初次安装初次加载时,会将 global_config_default 作为默认全局配置写入数据库。
该过程发生在构造函数,因此您如果需要对全局配置进行初始化操作,您需要在您的插件实例的构造函数,或者 install 函数中进行。

添加插件依赖

当插件需要在别的插件的基础上运行,可在 requirements 参数内传入 Requirement 类的列表,当插件安装时,会从插件市场服务尝试寻找对应的插件依赖并一同安装。

Requirement

参数名类型释义默认值
plugin_idstr插件ID
versionstr版本号(可选)None
officialbool是否官方插件False
python
from core import AmiyaBotPluginInstance, Requirement
+
+bot = AmiyaBotPluginInstance(
+    requirements=[
+        Requirement('other-plugin'),
+        Requirement('other-plugin2', '2.0'),
+    ]
+)

提示

插件添加依赖后,仅当全部依赖安装成功后,才会进行自身的安装。

`,34),p=[e];function c(r,i,d,y,F,D){return n(),t("div",null,p)}const m=a(o,[["render",c]]);export{g as __pageData,m as default}; diff --git a/assets/develop_plugin_amiyaBotPluginInstance.md.9e3e1e87.lean.js b/assets/develop_plugin_amiyaBotPluginInstance.md.9e3e1e87.lean.js new file mode 100644 index 00000000..fdfe6a60 --- /dev/null +++ b/assets/develop_plugin_amiyaBotPluginInstance.md.9e3e1e87.lean.js @@ -0,0 +1 @@ +import{_ as s}from"./chunks/plugin3.7807f651.js";import{_ as a,o as n,c as t,V as l}from"./chunks/framework.63f12d77.js";const g=JSON.parse('{"title":"AmiyaBotPluginInstance","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/amiyaBotPluginInstance.md","filePath":"develop/plugin/amiyaBotPluginInstance.md","lastUpdated":1722566694000}'),o={name:"develop/plugin/amiyaBotPluginInstance.md"},e=l("",34),p=[e];function c(r,i,d,y,F,D){return n(),t("div",null,p)}const m=a(o,[["render",c]]);export{g as __pageData,m as default}; diff --git a/assets/develop_plugin_build.md.86d0a5fe.js b/assets/develop_plugin_build.md.86d0a5fe.js new file mode 100644 index 00000000..f2c8d55a --- /dev/null +++ b/assets/develop_plugin_build.md.86d0a5fe.js @@ -0,0 +1,7 @@ +import{_ as a,o as s,c as e,V as p}from"./chunks/framework.63f12d77.js";const u=JSON.parse('{"title":"打包插件","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/build.md","filePath":"develop/plugin/build.md","lastUpdated":1722566694000}'),n={name:"develop/plugin/build.md"},l=p(`

打包插件

插件推荐发布为 zip 压缩包

直接打包

将整个插件文件夹压缩为 zip 包即可。如果你的插件使用了第三方库,你可能需要将第三方库手动放进插件包内。

示例

如在插件内使用了库 pypyodbc,在本地 python 环境内找到 pypyodbc.py(有时候会是 package 文件夹),并拷贝进 zip 包内。

python
# main.py
+import pypyodbc
+
+...
text
myPlugin.zip
+├── __init__.py
+├── main.py
+└── pypyodbc.py

main.py 内的导入语句 import pypyodbc 被执行时,优先使用插件内的 pypyodbc 包。

注意

若无法通过上述手段将第三方包添加进插件包,你的插件将可能不支持 可执行文件部署 。你可以在你的插件文档内注明,并让代码部署的用户使用 pip install xxx 安装第三方依赖。

使用脚本打包

如果你是在 demo 下开发的插件,运行脚本 run_build.py 即可自动打包。

bash
python run_build.py --type plugins

注意

脚本打包尚处于试验阶段,你仍然需要手动添加第三方包进插件

`,14),t=[l];function o(c,i,d,r,h,y){return s(),e("div",null,t)}const _=a(n,[["render",o]]);export{u as __pageData,_ as default}; diff --git a/assets/develop_plugin_build.md.86d0a5fe.lean.js b/assets/develop_plugin_build.md.86d0a5fe.lean.js new file mode 100644 index 00000000..1c98bdb1 --- /dev/null +++ b/assets/develop_plugin_build.md.86d0a5fe.lean.js @@ -0,0 +1 @@ +import{_ as a,o as s,c as e,V as p}from"./chunks/framework.63f12d77.js";const u=JSON.parse('{"title":"打包插件","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/build.md","filePath":"develop/plugin/build.md","lastUpdated":1722566694000}'),n={name:"develop/plugin/build.md"},l=p("",14),t=[l];function o(c,i,d,r,h,y){return s(),e("div",null,t)}const _=a(n,[["render",o]]);export{u as __pageData,_ as default}; diff --git a/assets/develop_plugin_create.md.0387968a.js b/assets/develop_plugin_create.md.0387968a.js new file mode 100644 index 00000000..e6bb12ba --- /dev/null +++ b/assets/develop_plugin_create.md.0387968a.js @@ -0,0 +1,31 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"创建插件","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/create.md","filePath":"develop/plugin/create.md","lastUpdated":1722566694000}'),p={name:"develop/plugin/create.md"},o=l(`

创建插件

在 pluginsDev 目录内,创建一个 Python package 形式的模块。为了防止加载插件时的全局环境变量污染。你的业务逻辑必须在另一个入口文件内进行。

创建入口文件 main.py

text
Amiya-Bot
+├── pluginsDev
+│   ├── myPlugin
+│   │   ├── __init__.py
+│   │   └── main.py
+│   ...
+...

编写插件程序

main.py 内编写插件的注册程序

python
from amiyabot import PluginInstance
+
+bot = PluginInstance(
+    name='我的插件',
+    version='1.0',
+    plugin_id='my-plugin',
+    description='我的第一个插件'
+)

PluginInstance 对象继承了工厂类 BotHandlerFactory,这意味着你完全可以按照 开发指南 去编写你的插件功能。

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')
+
+@bot.on_event('GUILD_CREATE')
+async def _(event: Event, instance: BotAdapterProtocol):
+    ...

这些消息响应器都会在插件被加载时注册到主体程序中。

插件内静态资源的使用

如果你的插件包含静态资源,在读取它们时,应该以插件的绝对目录读取。

text
Amiya-Bot
+├── pluginsDev
+│   ├── myPlugin
+│   │   ├── __init__.py
+│   │   ├── main.py
+│   │   └── file.txt
+│   ...
+...
python
# main.py
+import os
+
+plugin_dir = os.path.dirname(__file__)
+file = open(f'{plugin_dir}/file.txt')

导出插件的实例

__init__.py 内导出插件的入口,命名为 bot。这个命名是固定的,即使 main 内部的 PluginInstance 实例变量名不为 bot,在导出时都必须使用 as bot 重命名。

python
from .main import bot

注意

请不要在 __init__.py 内编写多余的代码,我们希望这个文件有且只有上面的一行。插件在加载时,会临时添加插件目录为系统路径,这会使主模块的一些全局一等对象污染主体程序,导致不可预测的后果。

`,18),e=[o];function t(c,r,i,y,D,F){return a(),n("div",null,e)}const h=s(p,[["render",t]]);export{A as __pageData,h as default}; diff --git a/assets/develop_plugin_create.md.0387968a.lean.js b/assets/develop_plugin_create.md.0387968a.lean.js new file mode 100644 index 00000000..c0f36374 --- /dev/null +++ b/assets/develop_plugin_create.md.0387968a.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"创建插件","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/create.md","filePath":"develop/plugin/create.md","lastUpdated":1722566694000}'),p={name:"develop/plugin/create.md"},o=l("",18),e=[o];function t(c,r,i,y,D,F){return a(),n("div",null,e)}const h=s(p,[["render",t]]);export{A as __pageData,h as default}; diff --git a/assets/develop_plugin_debug.md.495c0873.js b/assets/develop_plugin_debug.md.495c0873.js new file mode 100644 index 00000000..8bc46b00 --- /dev/null +++ b/assets/develop_plugin_debug.md.495c0873.js @@ -0,0 +1,9 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const u=JSON.parse('{"title":"调试插件","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/debug.md","filePath":"develop/plugin/debug.md","lastUpdated":1722566694000}'),t={name:"develop/plugin/debug.md"},e=l(`

调试插件

调试插件的方法有很多种,一般来说,你可以直接打包插件然后放到主项目中加载并使用来观察效果,显然这不够效率。AmiyaBot 提供了 测试实例,在主项目中,有现成的示例脚本。

在测试脚本中调试

在 兔兔-v6 根目录下的 run_test.py 内,修改如下位置的代码。

python
# 显式导入插件开发目录,可以在编辑器 DEBUG 调试。
+from pluginsDev.src.user import bot as plugin
+
+
+async def install_plugin():
+    # 导入插件
+    bot.install_plugin(plugin)
+    # 直接导入插件 zip 包
+    # bot.install_plugin('plugins/amiyabot-arknights-operator-1.5.zip', extract_plugin=True)

运行 python run_test.py,访问测试网址并使用。详见 测试实例

`,6),p=[e];function o(c,r,i,y,d,D){return a(),n("div",null,p)}const h=s(t,[["render",o]]);export{u as __pageData,h as default}; diff --git a/assets/develop_plugin_debug.md.495c0873.lean.js b/assets/develop_plugin_debug.md.495c0873.lean.js new file mode 100644 index 00000000..1d9854de --- /dev/null +++ b/assets/develop_plugin_debug.md.495c0873.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const u=JSON.parse('{"title":"调试插件","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/debug.md","filePath":"develop/plugin/debug.md","lastUpdated":1722566694000}'),t={name:"develop/plugin/debug.md"},e=l("",6),p=[e];function o(c,r,i,y,d,D){return a(),n("div",null,p)}const h=s(t,[["render",o]]);export{u as __pageData,h as default}; diff --git a/assets/develop_plugin_env.md.d6dd6f2b.js b/assets/develop_plugin_env.md.d6dd6f2b.js new file mode 100644 index 00000000..2d4221e3 --- /dev/null +++ b/assets/develop_plugin_env.md.d6dd6f2b.js @@ -0,0 +1,6 @@ +import{_ as s,o as a,c as n,V as e}from"./chunks/framework.63f12d77.js";const g=JSON.parse('{"title":"准备开发环境","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/env.md","filePath":"develop/plugin/env.md","lastUpdated":1722566694000}'),l={name:"develop/plugin/env.md"},o=e(`

准备开发环境

插件并不强制要求在 demo 的项目下开发,如果插件不需要使用 demo 的内置模块,那么你可以在自己任意的目录内开发而不需要克隆 demo 项目以及插件仓库的代码。

以下说明默认在 demo 项目内。

克隆仓库

克隆 兔兔-v6

bash
git clone https://github.com/AmiyaBot/Amiya-Bot.git

在 demo 项目内克隆插件开发仓库

bash
cd Amiya-Bot
+git clone https://github.com/AmiyaBot/Amiya-Bot-plugins.git pluginsDev

此时的目录结构应为

Amiya-Bot
+├── pluginsDev
+│   │
+│   ...
+...

建议安装 兔兔-v6 的依赖,如果不需要使用 demo 的内置模块或是你在自己的目录内开发插件。那么只需要安装 amiyabot 即可。

bash
pip install amiyabot
`,12),p=[o];function t(c,i,r,d,y,h){return a(),n("div",null,p)}const b=s(l,[["render",t]]);export{g as __pageData,b as default}; diff --git a/assets/develop_plugin_env.md.d6dd6f2b.lean.js b/assets/develop_plugin_env.md.d6dd6f2b.lean.js new file mode 100644 index 00000000..4e6f3468 --- /dev/null +++ b/assets/develop_plugin_env.md.d6dd6f2b.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as e}from"./chunks/framework.63f12d77.js";const g=JSON.parse('{"title":"准备开发环境","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/env.md","filePath":"develop/plugin/env.md","lastUpdated":1722566694000}'),l={name:"develop/plugin/env.md"},o=e("",12),p=[o];function t(c,i,r,d,y,h){return a(),n("div",null,p)}const b=s(l,[["render",t]]);export{g as __pageData,b as default}; diff --git a/assets/develop_plugin_index.md.44c66f5a.js b/assets/develop_plugin_index.md.44c66f5a.js new file mode 100644 index 00000000..cab0c645 --- /dev/null +++ b/assets/develop_plugin_index.md.44c66f5a.js @@ -0,0 +1 @@ +import{_ as t,o,c as n,C as e,a}from"./chunks/framework.63f12d77.js";const x=JSON.parse('{"title":"简要说明","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/index.md","filePath":"develop/plugin/index.md","lastUpdated":1722566694000}'),d={name:"develop/plugin/index.md"},s=e("h1",{id:"简要说明",tabindex:"-1"},[a("简要说明 "),e("a",{class:"header-anchor",href:"#简要说明","aria-label":'Permalink to "简要说明"'},"​")],-1),r=e("p",null,[a("本文档将讲述如何为 "),e("a",{href:"/guide/deploy/"},"兔兔-v6"),a(" 开发插件。")],-1),i=[s,r];function l(c,p,_,h,f,m){return o(),n("div",null,i)}const v=t(d,[["render",l]]);export{x as __pageData,v as default}; diff --git a/assets/develop_plugin_index.md.44c66f5a.lean.js b/assets/develop_plugin_index.md.44c66f5a.lean.js new file mode 100644 index 00000000..cab0c645 --- /dev/null +++ b/assets/develop_plugin_index.md.44c66f5a.lean.js @@ -0,0 +1 @@ +import{_ as t,o,c as n,C as e,a}from"./chunks/framework.63f12d77.js";const x=JSON.parse('{"title":"简要说明","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/index.md","filePath":"develop/plugin/index.md","lastUpdated":1722566694000}'),d={name:"develop/plugin/index.md"},s=e("h1",{id:"简要说明",tabindex:"-1"},[a("简要说明 "),e("a",{class:"header-anchor",href:"#简要说明","aria-label":'Permalink to "简要说明"'},"​")],-1),r=e("p",null,[a("本文档将讲述如何为 "),e("a",{href:"/guide/deploy/"},"兔兔-v6"),a(" 开发插件。")],-1),i=[s,r];function l(c,p,_,h,f,m){return o(),n("div",null,i)}const v=t(d,[["render",l]]);export{x as __pageData,v as default}; diff --git a/assets/develop_plugin_jsonSchema.md.6567afac.js b/assets/develop_plugin_jsonSchema.md.6567afac.js new file mode 100644 index 00000000..eede336b --- /dev/null +++ b/assets/develop_plugin_jsonSchema.md.6567afac.js @@ -0,0 +1,123 @@ +import{_ as s,o as a,c as n,V as o}from"./chunks/framework.63f12d77.js";const u=JSON.parse('{"title":"JsonSchema 解释","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/jsonSchema.md","filePath":"develop/plugin/jsonSchema.md","lastUpdated":1722566694000}'),l={name:"develop/plugin/jsonSchema.md"},p=o(`

JsonSchema 解释

本篇介绍如何使用 draft-07 版本的 JsonSchema 规范编辑 插件对接控制台的配置文件

json
{
+    "$schema": "http://json-schema.org/draft-07/schema#",
+    "type": "object",
+    "required": [],
+    "properties": {}
+}
  • required:必填字段(暂未支持前端校验,敬请期待...)
  • properties:字段配置

基本配置

字段定义在 properties 对象里:

  • <config_name>配置名称,是使用 get_config 方法时的参数
  • <config_name>.type:类型
  • <config_name>.title(可选):表单标题,不配置则使用 config_name
  • <config_name>.description(可选):表单tips,鼠标移动到页面的问号图标时显示的内容
  • <config_name>.default(可选):默认值,需按照类型填写。

示例

json
{
+    "properties": {
+        "imagesCachePath": {
+            "title": "图片缓存目录",
+            "description": "图片缓存的目录路径,可以为绝对路径",
+            "type": "string",
+            "default": "./imagesCache"
+        }
+    }
+}

文本输入框

默认值 default 的类型为字符串

json
{
+    "properties": {
+        "<config_name>": {
+            "type": "string",
+            "default": "text"
+        }
+    }
+}

数字输入框

默认值 default 的类型为数字

  • minimum(可选): 可输入的最小值
  • maximum(可选): 可输入的最大值

当 type 为 integer 时,只能输入整数,为 number 时可以输入浮点数。

json
{
+    "properties": {
+        "<config_name>": {
+            "type": "integer",
+            "minimum": -10,
+            "maximum": 20,
+            "default": 0
+        },
+        "<config_name2>": {
+            "type": "number",
+            "default": 0.5
+        }
+    }
+}

切换按钮

默认值 default 的类型为布尔型

json
{
+    "properties": {
+        "<config_name>": {
+            "type": "boolean",
+            "default": false
+        }
+    }
+}

下拉选择框

下拉选择框不需要 type 字段,默认值 default 的类型为内容的值类型

json
{
+    "properties": {
+        "<config_name>": {
+            "enum": [
+                "option1",
+                "option2",
+                "option3"
+            ],
+            "default": "option2"
+        }
+    }
+}

日期时间选择器

type 配置为 string 时,若配置了对应的 format 字段,可更改为日期时间选择器。
默认值 default 的类型为字符串或数值

json
{
+    "properties": {
+        "<config_name>": {
+            "type": "string",
+            "format": "datetime"
+        }
+    }
+}

format 选项

配置相应的 format 以使用不同种类的选择器

  • date:日期 YYYY-MM-DD
  • time:时间 HH:mm:ss
  • datetime:日期时间 YYYY-MM-DD HH:mm:ss
  • date-range:日期范围 [ YYYY-MM-DD, YYYY-MM-DD ]
  • time-range:时间范围 [ HH:mm:ss, HH:mm:ss ]
  • datetime-range:日期时间范围 [ YYYY-MM-DD HH:mm:ss, YYYY-MM-DD HH:mm:ss ]

当使用范围选择器时,数据为数组类型,代表范围,如

json
[
+    "2023-05-20 08:00:00",
+    "2023-05-21 16:00:00"
+]

动态输入-值数组

如果你需要 get_config 方法返回 [value1, value2, value3, ...] 形式的值数值,可以使用动态输入值数组。
默认值 default 的类型为数组

  • type 配置为 array
  • items 为数组配置
    • type:值类型,仅支持 stringintegernumber 以及 object
json
{
+    "properties": {
+        "<config_name>": {
+            "type": "array",
+            "items": {
+                "type": "string"
+            }
+        }
+    }
+}

动态输入-对象数组

如果你需要 get_config 方法返回 [{...}, {...}, {...}, ...] 形式的值数值,可以使用动态输入对象(字典)数组。
默认值 default 的类型为数组

json
{
+    "properties": {
+        "<config_name>": {
+            "type": "array",
+            "items": {
+                "type": "object",
+                "properties": {}
+            }
+        }
+    }
+}

子级对象

有时候有些复杂配置不能用只有一级的对象(字典)存放,使用子级对象组建多层的对象(字典)。

  • type 配置为 object
  • properties 根据上文 基本配置 添加任意输入类型或将 type 配置为 object 继续作为新的子级对象
json
{
+    "properties": {
+        "<config_name>": {
+            "type": "object",
+            "properties": {}
+        }
+    }
+}

示例

json
{
+    "properties": {
+        "user": {
+            "type": "object",
+            "properties": {
+                "name": {
+                    "type": "string"
+                },
+                "age": {
+                    "type": "integer"
+                },
+                "attrs": {
+                    "type": "object",
+                    "properties": {
+                        "atk": {
+                            "type": "number"
+                        },
+                        "def": {
+                            "type": "number"
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

以上配置调用 bot.get_config() 方法将返回以下内容

json
{
+    "user": {
+        "name": ...,
+        "age": ...,
+        "attrs": {
+            "atk": ...,
+            "def": ...
+        }
+    }
+}
`,47),e=[p];function t(c,D,r,F,y,i){return a(),n("div",null,e)}const d=s(l,[["render",t]]);export{u as __pageData,d as default}; diff --git a/assets/develop_plugin_jsonSchema.md.6567afac.lean.js b/assets/develop_plugin_jsonSchema.md.6567afac.lean.js new file mode 100644 index 00000000..bc2d93e7 --- /dev/null +++ b/assets/develop_plugin_jsonSchema.md.6567afac.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as o}from"./chunks/framework.63f12d77.js";const u=JSON.parse('{"title":"JsonSchema 解释","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/jsonSchema.md","filePath":"develop/plugin/jsonSchema.md","lastUpdated":1722566694000}'),l={name:"develop/plugin/jsonSchema.md"},p=o("",47),e=[p];function t(c,D,r,F,y,i){return a(),n("div",null,e)}const d=s(l,[["render",t]]);export{u as __pageData,d as default}; diff --git a/assets/develop_plugin_life.md.c42d477f.js b/assets/develop_plugin_life.md.c42d477f.js new file mode 100644 index 00000000..8cf5ed39 --- /dev/null +++ b/assets/develop_plugin_life.md.c42d477f.js @@ -0,0 +1,19 @@ +import{_ as s,o as n,c as a,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"插件生命周期","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/life.md","filePath":"develop/plugin/life.md","lastUpdated":1722566694000}'),p={name:"develop/plugin/life.md"},o=l(`

插件生命周期

你可以在插件被安装或卸载时执行一些操作,只需要继承 PluginInstance 并覆盖其方法。

python
from amiyabot import PluginInstance
+
+
+class MyPlugin(PluginInstance):
+    def install(self):
+        # 插件被安装时执行的操作
+        ...
+
+    def uninstall(self):
+        # 插件被卸载时执行的操作
+        ...
+
+
+bot = MyPlugin(
+    name='我的插件',
+    version='1.0',
+    plugin_id='my-plugin',
+    description='我的第一个插件'
+)
`,3),e=[o];function t(c,r,i,y,D,F){return n(),a("div",null,e)}const d=s(p,[["render",t]]);export{A as __pageData,d as default}; diff --git a/assets/develop_plugin_life.md.c42d477f.lean.js b/assets/develop_plugin_life.md.c42d477f.lean.js new file mode 100644 index 00000000..81956f57 --- /dev/null +++ b/assets/develop_plugin_life.md.c42d477f.lean.js @@ -0,0 +1 @@ +import{_ as s,o as n,c as a,V as l}from"./chunks/framework.63f12d77.js";const A=JSON.parse('{"title":"插件生命周期","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/life.md","filePath":"develop/plugin/life.md","lastUpdated":1722566694000}'),p={name:"develop/plugin/life.md"},o=l("",3),e=[o];function t(c,r,i,y,D,F){return n(),a("div",null,e)}const d=s(p,[["render",t]]);export{A as __pageData,d as default}; diff --git a/assets/develop_plugin_publish.md.28cda1dc.js b/assets/develop_plugin_publish.md.28cda1dc.js new file mode 100644 index 00000000..ab3b0849 --- /dev/null +++ b/assets/develop_plugin_publish.md.28cda1dc.js @@ -0,0 +1 @@ +import{_ as e,o as a,c as t,V as o}from"./chunks/framework.63f12d77.js";const m=JSON.parse('{"title":"发布到插件商店","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/publish.md","filePath":"develop/plugin/publish.md","lastUpdated":1722566694000}'),r={name:"develop/plugin/publish.md"},s=o('

发布到插件商店

访问 控制台-插件商店,点击【上传创意插件】完成流程即可发布到商店。

插件密钥

上传插件时需要输入一个密钥,在你更新或下架你的插件时,需要输入这个密钥校验。请牢记你的密钥。

',4),n=[s];function l(i,p,_,c,d,h){return a(),t("div",null,n)}const f=e(r,[["render",l]]);export{m as __pageData,f as default}; diff --git a/assets/develop_plugin_publish.md.28cda1dc.lean.js b/assets/develop_plugin_publish.md.28cda1dc.lean.js new file mode 100644 index 00000000..ce1570d9 --- /dev/null +++ b/assets/develop_plugin_publish.md.28cda1dc.lean.js @@ -0,0 +1 @@ +import{_ as e,o as a,c as t,V as o}from"./chunks/framework.63f12d77.js";const m=JSON.parse('{"title":"发布到插件商店","description":"","frontmatter":{},"headers":[],"relativePath":"develop/plugin/publish.md","filePath":"develop/plugin/publish.md","lastUpdated":1722566694000}'),r={name:"develop/plugin/publish.md"},s=o("",4),n=[s];function l(i,p,_,c,d,h){return a(),t("div",null,n)}const f=e(r,[["render",l]]);export{m as __pageData,f as default}; diff --git a/assets/download.md.0155255c.js b/assets/download.md.0155255c.js new file mode 100644 index 00000000..4766eca2 --- /dev/null +++ b/assets/download.md.0155255c.js @@ -0,0 +1 @@ +import{d as t}from"./chunks/download.1cbae1cc.js";import{o as e,c as s,C as a,J as l,V as o}from"./chunks/framework.63f12d77.js";import"./chunks/index.ca03c6e9.js";const n=o('

下载

amiyabot

bash
pip install amiyabot

兔兔-v6

',4),r=a("thead",null,[a("tr",null,[a("th",null,"操作系统"),a("th",null,"下载"),a("th",null,"备注")])],-1),i=a("td",null,"Windows",-1),d=a("td",null,"仅支持 Windows 10、Windows Server 2016 及以上系统",-1),y=JSON.parse('{"title":"下载","description":"","frontmatter":{"aside":false},"headers":[],"relativePath":"download.md","filePath":"download.md","lastUpdated":1722566694000}'),p={name:"download.md"},f=Object.assign(p,{setup(c){return(_,h)=>(e(),s("div",null,[n,a("table",null,[r,a("tbody",null,[a("tr",null,[i,a("td",null,[l(t,{version:"win32"})]),d])])])]))}});export{y as __pageData,f as default}; diff --git a/assets/download.md.0155255c.lean.js b/assets/download.md.0155255c.lean.js new file mode 100644 index 00000000..ce35c567 --- /dev/null +++ b/assets/download.md.0155255c.lean.js @@ -0,0 +1 @@ +import{d as t}from"./chunks/download.1cbae1cc.js";import{o as e,c as s,C as a,J as l,V as o}from"./chunks/framework.63f12d77.js";import"./chunks/index.ca03c6e9.js";const n=o("",4),r=a("thead",null,[a("tr",null,[a("th",null,"操作系统"),a("th",null,"下载"),a("th",null,"备注")])],-1),i=a("td",null,"Windows",-1),d=a("td",null,"仅支持 Windows 10、Windows Server 2016 及以上系统",-1),y=JSON.parse('{"title":"下载","description":"","frontmatter":{"aside":false},"headers":[],"relativePath":"download.md","filePath":"download.md","lastUpdated":1722566694000}'),p={name:"download.md"},f=Object.assign(p,{setup(c){return(_,h)=>(e(),s("div",null,[n,a("table",null,[r,a("tbody",null,[a("tr",null,[i,a("td",null,[l(t,{version:"win32"})]),d])])])]))}});export{y as __pageData,f as default}; diff --git a/assets/guide_deploy_advanced_index.md.bfe56c56.js b/assets/guide_deploy_advanced_index.md.bfe56c56.js new file mode 100644 index 00000000..b074df0d --- /dev/null +++ b/assets/guide_deploy_advanced_index.md.bfe56c56.js @@ -0,0 +1 @@ +import{_ as a,o as t,c as d,C as e,a as n}from"./chunks/framework.63f12d77.js";const g=JSON.parse('{"title":"说明","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/advanced/index.md","filePath":"guide/deploy/advanced/index.md","lastUpdated":1722566694000}'),o={name:"guide/deploy/advanced/index.md"},s=e("h1",{id:"说明",tabindex:"-1"},[n("说明 "),e("a",{class:"header-anchor",href:"#说明","aria-label":'Permalink to "说明"'},"​")],-1),c=e("p",null,"本部分文档可能只是对控制台暂未支持的部分的一种补充,文档中的内容可能不会一直维护,也不会一直有效,在不久的将来可能都会在控制台中实现。届时对应的文档也会从这里删去。当然,这并不是绝对的,部分功能可能无法或者不会在控制台中实现,那么控制台将可能会有指向这些文档的链接。目录名称“高级使用”仅是用来区分可以在控制台内直接实现的操作的,并无其他含义。",-1),i=e("p",null,"请理解:由于本部分的特殊性,我们可能不会高频率的维护这些文档以至于它们可能无法与最新的版本相匹配,甚至可能随时删除或停止维护这些文档。您使用过期文档导致生产事故等的情况我们不负任何责任,也不对其造成的影响负责。",-1),r=e("p",null,"如果您已阅读并理解,同意以上部分,则请您浏览左侧的目录跳转至您需要的部分开始阅读。",-1),l=[s,c,i,r];function _(p,h,u,m,f,x){return t(),d("div",null,l)}const $=a(o,[["render",_]]);export{g as __pageData,$ as default}; diff --git a/assets/guide_deploy_advanced_index.md.bfe56c56.lean.js b/assets/guide_deploy_advanced_index.md.bfe56c56.lean.js new file mode 100644 index 00000000..b074df0d --- /dev/null +++ b/assets/guide_deploy_advanced_index.md.bfe56c56.lean.js @@ -0,0 +1 @@ +import{_ as a,o as t,c as d,C as e,a as n}from"./chunks/framework.63f12d77.js";const g=JSON.parse('{"title":"说明","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/advanced/index.md","filePath":"guide/deploy/advanced/index.md","lastUpdated":1722566694000}'),o={name:"guide/deploy/advanced/index.md"},s=e("h1",{id:"说明",tabindex:"-1"},[n("说明 "),e("a",{class:"header-anchor",href:"#说明","aria-label":'Permalink to "说明"'},"​")],-1),c=e("p",null,"本部分文档可能只是对控制台暂未支持的部分的一种补充,文档中的内容可能不会一直维护,也不会一直有效,在不久的将来可能都会在控制台中实现。届时对应的文档也会从这里删去。当然,这并不是绝对的,部分功能可能无法或者不会在控制台中实现,那么控制台将可能会有指向这些文档的链接。目录名称“高级使用”仅是用来区分可以在控制台内直接实现的操作的,并无其他含义。",-1),i=e("p",null,"请理解:由于本部分的特殊性,我们可能不会高频率的维护这些文档以至于它们可能无法与最新的版本相匹配,甚至可能随时删除或停止维护这些文档。您使用过期文档导致生产事故等的情况我们不负任何责任,也不对其造成的影响负责。",-1),r=e("p",null,"如果您已阅读并理解,同意以上部分,则请您浏览左侧的目录跳转至您需要的部分开始阅读。",-1),l=[s,c,i,r];function _(p,h,u,m,f,x){return t(),d("div",null,l)}const $=a(o,[["render",_]]);export{g as __pageData,$ as default}; diff --git a/assets/guide_deploy_advanced_mysql.md.55d14788.js b/assets/guide_deploy_advanced_mysql.md.55d14788.js new file mode 100644 index 00000000..58a89ad1 --- /dev/null +++ b/assets/guide_deploy_advanced_mysql.md.55d14788.js @@ -0,0 +1,6 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const _=JSON.parse('{"title":"使用 Mysql","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/advanced/mysql.md","filePath":"guide/deploy/advanced/mysql.md","lastUpdated":1722566694000}'),o={name:"guide/deploy/advanced/mysql.md"},p=l(`

使用 Mysql

config\\database.yaml 中可以配置使用的数据库,如需更改数据库类型为 Mysql,请按下面的配置说明进行配置:

yaml
mode: 'mysql'
+config:
+    host: '数据库地址'
+    port: 数据库端口
+    user: '登录用户名'
+    password: '数据库密码'
`,3),e=[p];function t(c,r,y,D,d,i){return a(),n("div",null,e)}const m=s(o,[["render",t]]);export{_ as __pageData,m as default}; diff --git a/assets/guide_deploy_advanced_mysql.md.55d14788.lean.js b/assets/guide_deploy_advanced_mysql.md.55d14788.lean.js new file mode 100644 index 00000000..a9d94e44 --- /dev/null +++ b/assets/guide_deploy_advanced_mysql.md.55d14788.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const _=JSON.parse('{"title":"使用 Mysql","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/advanced/mysql.md","filePath":"guide/deploy/advanced/mysql.md","lastUpdated":1722566694000}'),o={name:"guide/deploy/advanced/mysql.md"},p=l("",3),e=[p];function t(c,r,y,D,d,i){return a(),n("div",null,e)}const m=s(o,[["render",t]]);export{_ as __pageData,m as default}; diff --git a/assets/guide_deploy_console_configure.md.50610948.js b/assets/guide_deploy_console_configure.md.50610948.js new file mode 100644 index 00000000..12f8c92c --- /dev/null +++ b/assets/guide_deploy_console_configure.md.50610948.js @@ -0,0 +1,34 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const p="/assets/addBot.c3c3627e.png",o="/assets/online.f82e5764.png",e="/assets/mainBot.0344269a.png",g=JSON.parse('{"title":"配置实例","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/console/configure.md","filePath":"guide/deploy/console/configure.md","lastUpdated":1722566694000}'),t={name:"guide/deploy/console/configure.md"},c=l('

配置实例

“实例”指的是机器人的账号,兔兔支持登录多个机器人账号同时使用,多个账号之间共享数据。

添加实例

在左侧导航选择“实例管理”,并点击“添加实例”

QQ频道机器人(官方)

QQ 开放平台 查看并在实例配置填写你注册的频道机器人信息,表单字段就是对应内容。

QQ群机器人(官方)

QQ 开放平台 查看并在实例配置填写你注册的群机器人信息,表单字段就是对应内容。

KOOK机器人

KOOK 开发者平台 查看并在实例配置填写你创建的机器人应用的 Token 即可。KOOK 机器人不需要 appid,但你仍然需要在配置里随便填写一个 appid,推荐使用 KOOK 应用的 Client Id

CQ-Http QQ群机器人

APP ID 为登录在 go-cqhttp 的 QQ 号
TOKEN 填写配置的 access-token,没有配置则不需要填写。
CQ-Http 配置 请准确填写你部署 go-cqhttp 时的信息。

需要配置 go-cqhttp 目录下的文件 config.yml 里数据类型为 array,修改完后重启 go-cqhttp 生效。

yaml
message:
+    # 上报数据类型
+    # 可选: string,array
+    post-format: array

access-token 可在 go-cqhttp 目录下的文件 config.yml 找到

yaml
# 默认中间件锚点
+default-middlewares: &default
+    # 访问密钥, 强烈推荐在公网的服务器设置
+    access-token: '*******'
+    # 事件过滤器文件目录
+    filter: ''
+    # API限速设置
+    # 该设置为全局生效
+    # 原 cqhttp 虽然启用了 rate_limit 后缀, 但是基本没插件适配
+    # 目前该限速设置为令牌桶算法, 请参考:
+    # https://baike.baidu.com/item/%E4%BB%A4%E7%89%8C%E6%A1%B6%E7%AE%97%E6%B3%95/6597000?fr=aladdin
+    rate-limit:
+        enabled: false # 是否启用限速
+        frequency: 1  # 令牌回复频率, 单位秒
+        bucket: 1     # 令牌桶大小

Mirai-api-http QQ群机器人

APP ID 为登录在 mirai-api-http 的 QQ 号
TOKEN 为 mirai-api-http 的 AuthKey
Mirai-api-http 配置 请准确填写你部署 mah 时的信息。

AuthKey 可在 mirai-console 目录下的文件 config/net.mamoe.mirai-api-http/setting.yml 找到

yaml
adapters:
+    - http
+    - ws
+debug: false
+enableVerify: true
+verifyKey: ******* # 此处即是 AuthKey
+singleMode: false
+cacheSize: 4096
+adapterSettings:
+    http:
+        host: 0.0.0.0
+        port: 8080
+        cors: [ * ]
+    ws:
+        host: 0.0.0.0
+        port: 8060
+        reservedSyncId: -1

运行实例

点击“保存并启动”运行实例,当实例状态为在线时,即启动成功。

image

温馨提示

实例的连接需要时间,通常只需要几秒钟不到。如果显示离线可以等待几秒再刷新页面。

配置可控实例

配置时打开选项 可控实例,并填写一个群号。可接收到该实例的一些相关通知。

image',28),r=[c];function i(y,D,F,d,h,B){return a(),n("div",null,r)}const m=s(t,[["render",i]]);export{g as __pageData,m as default}; diff --git a/assets/guide_deploy_console_configure.md.50610948.lean.js b/assets/guide_deploy_console_configure.md.50610948.lean.js new file mode 100644 index 00000000..aca08561 --- /dev/null +++ b/assets/guide_deploy_console_configure.md.50610948.lean.js @@ -0,0 +1 @@ +import{_ as s,o as a,c as n,V as l}from"./chunks/framework.63f12d77.js";const p="/assets/addBot.c3c3627e.png",o="/assets/online.f82e5764.png",e="/assets/mainBot.0344269a.png",g=JSON.parse('{"title":"配置实例","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/console/configure.md","filePath":"guide/deploy/console/configure.md","lastUpdated":1722566694000}'),t={name:"guide/deploy/console/configure.md"},c=l("",28),r=[c];function i(y,D,F,d,h,B){return a(),n("div",null,r)}const m=s(t,[["render",i]]);export{g as __pageData,m as default}; diff --git a/assets/guide_deploy_console_index.md.175af869.js b/assets/guide_deploy_console_index.md.175af869.js new file mode 100644 index 00000000..8c95d868 --- /dev/null +++ b/assets/guide_deploy_console_index.md.175af869.js @@ -0,0 +1,3 @@ +import{_ as a,o as s,c as e,V as o}from"./chunks/framework.63f12d77.js";const t="/assets/link.e0d1dd67.png",m=JSON.parse('{"title":"连接控制台","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/console/index.md","filePath":"guide/deploy/console/index.md","lastUpdated":1722566694000}'),n={name:"guide/deploy/console/index.md"},r=o(`

连接控制台

兔兔在启动后会开启一个 HTTP 服务,默认端口为 8088。提供给 控制台 调用。你可以根据需要在启动前修改配置config/server.yaml

yaml
host: 127.0.0.1
+port: 8088
+authKey:

authKey 为连接控制台时的密钥,默认不需要。

危险

当您试图将控制台暴露至公网时,请务必设定 authKey!
如果不这么做,您的服务将可能面临极大的安全风险!因此造成的一切后果与项目组无关,由您自行承担!

注意

不推荐您使用纯数字,或是简单的数字、字母组合等弱口令作为 authKey(如 123456, 000000, abcdef 等)。
如果您坚持这么做,您的服务将可能面临较大的安全风险!因此造成的一切后果与项目组无关,由您自行承担!
特别的,当您尝试使用纯数字的 authKey 时,由于 YAML 规范定义其为整数类型,您的 authKey 将可能因类型错误无法识别。如果您坚持使用纯数字的 authKey,请使用单引号 '' 或双引号 "" 将 authKey 括起。

连接

浏览器打开控制台 https://console.amiyabot.com,在主界面填入你的服务地址。
默认为 http://127.0.0.1:8088

点击“测试并连接”,成功进入后即可开始配置。

公网/局域网访问

host 配置为 0.0.0.0 即可让服务通过本机 IP 访问

yaml
host: 0.0.0.0

危险

当您试图从公网连接至控制台时,请务必通过反向代理加密连接!
如果不这么做,您的服务将面临极大的安全风险!因此造成的一切后果与项目组无关,由您自行承担!

我们的团队成员 Initial-heart 为你提供了 一篇通过 Nginx 反向代理加密连接的博客,你可以根据这篇博客对你的连接进行加密。

',15),l=[r];function c(p,i,d,h,g,y){return s(),e("div",null,l)}const b=a(n,[["render",c]]);export{m as __pageData,b as default}; diff --git a/assets/guide_deploy_console_index.md.175af869.lean.js b/assets/guide_deploy_console_index.md.175af869.lean.js new file mode 100644 index 00000000..8b269ebe --- /dev/null +++ b/assets/guide_deploy_console_index.md.175af869.lean.js @@ -0,0 +1 @@ +import{_ as a,o as s,c as e,V as o}from"./chunks/framework.63f12d77.js";const t="/assets/link.e0d1dd67.png",m=JSON.parse('{"title":"连接控制台","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/console/index.md","filePath":"guide/deploy/console/index.md","lastUpdated":1722566694000}'),n={name:"guide/deploy/console/index.md"},r=o("",15),l=[r];function c(p,i,d,h,g,y){return s(),e("div",null,l)}const b=a(n,[["render",c]]);export{m as __pageData,b as default}; diff --git a/assets/guide_deploy_console_plugin.md.6a874539.js b/assets/guide_deploy_console_plugin.md.6a874539.js new file mode 100644 index 00000000..b2413ba1 --- /dev/null +++ b/assets/guide_deploy_console_plugin.md.6a874539.js @@ -0,0 +1 @@ +import{_ as a}from"./chunks/plugin3.7807f651.js";import{_ as e,o as t,c as o,V as s}from"./chunks/framework.63f12d77.js";const r="/assets/plugin.88ce690c.png",i="/assets/plugin2.14fbd7cf.png",b=JSON.parse('{"title":"安装插件","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/console/plugin.md","filePath":"guide/deploy/console/plugin.md","lastUpdated":1722566694000}'),n={name:"guide/deploy/console/plugin.md"},p=s('

安装插件

选择安装你需要的功能插件

在插件商店安装插件

插件商店可以实时查看有新版本的插件,需要时可通过商店更新。

通过插件包自动安装

插件通常是一个zip压缩包或是 Python Package 的形式,你可以将它放在 plugins 目录下,启动时可以自动安装。

管理插件

安装好的插件可以在插件管理查看,现在,你已经可以使用它们了。

部分插件可能存在需要配置的信息,可在插件配置选项卡查看并编辑(需插件支持)。

🎉 恭喜你,到这里你已经部署完成了!快去体验兔兔吧!🎉

',13),l=[p];function c(d,_,h,u,m,g){return t(),o("div",null,l)}const q=e(n,[["render",c]]);export{b as __pageData,q as default}; diff --git a/assets/guide_deploy_console_plugin.md.6a874539.lean.js b/assets/guide_deploy_console_plugin.md.6a874539.lean.js new file mode 100644 index 00000000..ce0d706d --- /dev/null +++ b/assets/guide_deploy_console_plugin.md.6a874539.lean.js @@ -0,0 +1 @@ +import{_ as a}from"./chunks/plugin3.7807f651.js";import{_ as e,o as t,c as o,V as s}from"./chunks/framework.63f12d77.js";const r="/assets/plugin.88ce690c.png",i="/assets/plugin2.14fbd7cf.png",b=JSON.parse('{"title":"安装插件","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/console/plugin.md","filePath":"guide/deploy/console/plugin.md","lastUpdated":1722566694000}'),n={name:"guide/deploy/console/plugin.md"},p=s("",13),l=[p];function c(d,_,h,u,m,g){return t(),o("div",null,l)}const q=e(n,[["render",c]]);export{b as __pageData,q as default}; diff --git a/assets/guide_deploy_faq_PluginProblem.md.ccf6151b.js b/assets/guide_deploy_faq_PluginProblem.md.ccf6151b.js new file mode 100644 index 00000000..fcaa4c77 --- /dev/null +++ b/assets/guide_deploy_faq_PluginProblem.md.ccf6151b.js @@ -0,0 +1 @@ +import{_ as a,o as l,c as e,V as s}from"./chunks/framework.63f12d77.js";const b=JSON.parse('{"title":"插件常见问题","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/faq/PluginProblem.md","filePath":"guide/deploy/faq/PluginProblem.md","lastUpdated":1722566694000}'),o={name:"guide/deploy/faq/PluginProblem.md"},t=s('

插件常见问题

本章收录了用户在使用官方插件时向我们提问较多的问题。

公招图片识别没法用

请注意

公招图片识别功能需要申请并配置相应的百度智能云 API

请根据插件文档配置相关信息。

我不知道如何申请百度云 api

  • 请自行百度或联系百度智能云的支持服务。

如何给兔兔添加表情

  • 对应的文件位置在 plugins/amiyabot-user*/face 下,直接将图片文件扔到文件夹内即可。

代码部署后部分插件无法正常产生图片

  • 在安装完依赖后 需要额外安装playwright的chromium及其依赖
    • 对于windows:
    shell
    playwright install chromium
    • 对于linux:
    shell
    playwright install --with-deps chromium

注意

若使用的操作系统不在 官方支持列表 中,您可能无法正确执行该操作,也无法获得官方的任何支持。

有时候公招图/专精材料图显示不完整

偶现该情况是正常现象,这与设备性能等因素有关,通常再请求一次即可正常返回图片。

抽卡时出现了(按游戏卡池发布顺序来说)不可能出现的新干员

请理解为卡池在现在复刻了。复刻的卡池中显然会出现任何非限定或特殊干员。

抽卡时出现了黑色的人物条/出现了限定/赠送/肉鸽干员

  • 可以前往控制台中的干员设置设定干员的限定属性(黑色的条一般是各个预备干员)

可是我的各个限定干员都已经被设置为不可抽取了

  • 有时你可能更新了卡池却没有更新干员数据也会导致这个问题
  • 此时重启兔兔本体或点击按钮【应用干员设置】即可更新干员数据
',20),i=[t];function n(r,p,c,d,u,h){return l(),e("div",null,i)}const _=a(o,[["render",n]]);export{b as __pageData,_ as default}; diff --git a/assets/guide_deploy_faq_PluginProblem.md.ccf6151b.lean.js b/assets/guide_deploy_faq_PluginProblem.md.ccf6151b.lean.js new file mode 100644 index 00000000..dfd0971c --- /dev/null +++ b/assets/guide_deploy_faq_PluginProblem.md.ccf6151b.lean.js @@ -0,0 +1 @@ +import{_ as a,o as l,c as e,V as s}from"./chunks/framework.63f12d77.js";const b=JSON.parse('{"title":"插件常见问题","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/faq/PluginProblem.md","filePath":"guide/deploy/faq/PluginProblem.md","lastUpdated":1722566694000}'),o={name:"guide/deploy/faq/PluginProblem.md"},t=s("",20),i=[t];function n(r,p,c,d,u,h){return l(),e("div",null,i)}const _=a(o,[["render",n]]);export{b as __pageData,_ as default}; diff --git a/assets/guide_deploy_faq_commonProblem.md.66ab12e1.js b/assets/guide_deploy_faq_commonProblem.md.66ab12e1.js new file mode 100644 index 00000000..48ca74f9 --- /dev/null +++ b/assets/guide_deploy_faq_commonProblem.md.66ab12e1.js @@ -0,0 +1,21 @@ +import{_ as a,o as e,c as l,V as o}from"./chunks/framework.63f12d77.js";const b=JSON.parse('{"title":"常见问题","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/faq/commonProblem.md","filePath":"guide/deploy/faq/commonProblem.md","lastUpdated":1722566694000}'),t={name:"guide/deploy/faq/commonProblem.md"},i=o(`

常见问题

本章收录了用户在部署/使用过程中向我们提问较多的问题。

作者:晓月君
修饰:Chino酱

我看不懂什么是克隆仓库/代码部署的指令会报错

  • 你是否在考虑使用可执行文件部署而不是代码部署?
  • 请注意文档中提供的“使用可执行文件部署”与“使用代码部署”任选其一进行即可,执行完即可进入下一步骤,而不是两者都要进行。

使用可执行文件部署时,兔兔的窗口闪现了一下/出现了一小段时间又消失了(闪退)

git 未正确配置

请使用组合键 win+R 输入 cmd 后回车,在跳出来的黑色框框中输入 git 后回车,如果显示

'git'不是内部或外部命令,也不是可运行的程序或批处理文件。

通常情况下,这是 git 未正确安装导致的,可能是由于你没有认真看文档根本没有安装 git 所导致。请根据文档安装 git

安装完成后,再次重复上述操作,此时应该会显示如下的文本,这就证明你配置好了 git,可以再次尝试打开可执行文件了。

usage: git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]
+           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
+           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
+           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
+           [--super-prefix=<path>] [--config-env=<name>=<envvar>]
+           <command> [<args>]
+
+These are common Git commands used in various situations:
+
+start a working area (see also: git help tutorial)
+   clone     Clone a repository into a new directory
+   init      Create an empty Git repository or reinitialize an existing one
+
+work on the current change (see also: git help everyday)
+   add       Add file contents to the index
+   mv        Move or rename a file, a directory, or a symlink
+   restore   Restore working tree files
+   rm        Remove files from the working tree and from the index
+
+...

我很确定我已经安装了git,但是我在黑框内输入git后还是会显示“不是内部或外部命令”

这个现象大概率是因为设备的环境变量没有配置好导致的,请参考 此文章 尝试将 git 的路径添加入环境变量中再次尝试开头的操作。

资源包没能完成下载

我在窗口最上方看到了一些进度条,可是没能跑完就闪退了

  • 请检查你的网络连接或是否开启了代理软件。
  • 若你有意或无意地导致了 resource/gamedata 文件夹内的内容产生了变动,可能导致无法更新。直接删除整个 resource/gamedata 文件夹重新启动程序即可

启动时弹窗提示“无法定位程序输入点...”

  • 你是否在使用 win7 或较老的 WindowsServer 版本?
  • 就结论而言 win7 或较老的 WindowsServer 版本无法运行兔兔 原因是 node 版本不兼容 推荐升级 win10(若情况允许)或者使用云服务器部署/更换云服务器镜像

无法进入控制台

我尝试进入控制台时出现了 ERR_NETWORK 服务器异常

  • 检查浏览器顶端的地址栏 通常,地址栏中协议(也就是网址最开头的http/https)应该使用http 如果你的网址以https开头,请改为http后再重新尝试访问

  • 部分内核的浏览器可能会拦截公网对私网不安全的访问请求

    • 打开 tab 页面 chrome://flags/#block-insecure-private-network-requests
    • Block insecure private network requests 设置为 Disabled, 然后重启 zukVk6.png
  • 若你访问控制台的设备与运行兔兔的设备不是同一台设备 你需要修改兔兔本体的一些设置

    • 前往兔兔的config/server.yaml
    • host的值修改为0.0.0.0
    • 重新启动兔兔

我不知道服务地址应该填什么

  • 如果你访问控制台的设备与部署兔兔的设备为同一台的话,通常你应该填写的就是http://127.0.0.1:8088,而服务密钥留空
  • 如果你访问控制台的设备与部署兔兔的设备不是同一台,但是在同一个局域网内(通常指在同一个家里)
    • 参照文档host 修改为 0.0.0.0
    • 参考此文章查询你部署兔兔的设备的局域网ip(通常是以 192 开头的一串数字)
    • 控制台中应填写 http://[你查询到的ip]:8088
    • 而服务密钥留空
  • 如果你将兔兔部署在云服务器上,在另一台设备上访问控制台,那么事情将会变得有些棘手,首先你需要参照上面的指示将 host 修改为 0.0.0.0,其次你需要给云服务器运营商的防火墙设置一个入站规则(关于如何做到这一点,请自行百度),通常端口是 8088,协议为tcp,并且操作系统内也需要设置入站规则(也请自行百度)
    • 提示:通过公网访问,可能有设备被攻击的风险,请自行配置服务密钥(在 config/server.yaml 中修改 authKey 的值并填入控制台的服务密钥中)。更进一步,推荐使用Nginx反代服务提供更高的安全性,请参考文档

控制台中实例无法连接

由于作者仅涉足过mirai,本处仅将提供mirai相关问题的解决思路,不过部分解决思路也可用在gocq中

我们先来对配置单的具体内容进行一些解释

  • APP ID:mirai登陆的qq号,也就是你bot的qq号
  • TOKEN:对mirai来说,为mirai/config/net.mamoe.mirai-api-http/settings.ymlverifyKey的值
  • 适配器类型:通常你应该选择CQ-Http或是Mirai-api-http而不是QQ-Bot
  • 可控实例:是否将一些运行信息发送至特定群组 (若是勾选了,控制台群组id应为你希望运行信息出现在的群聊的群聊号中)
  • Host地址:如提示所示,如果是同一台设备的话 填写127.0.0.1
  • HTTP端口:mirai/config/net.mamoe.mirai-api-http/settings.ymlhttpport的值
  • WS端口:mirai/config/net.mamoe.mirai-api-http/settings.ymlwsport的值 (如果你参考的是初心佬的文章,那这两项应该分别为80808060)

以下是兔兔的窗口中可能出现的报错信息以及相应处理方法

指定bot不存在

请检查mirai是否正确登陆了bot的qq

Auth Key错误

rt,检查mirai本体配置中authKey的值与控制台填写的是否一致

Cannot connect to mirai-api-http websocket server

  • 检查mirai是否启动
  • 检查mirai-api-http中host地址与两个端口填写是否有误
  • 常见错误为看错并填写错端口(如8080与8060看混 或者修改了mah的配置却未更改控制台实例配置单)

Got code 401

适配器类型应该是Mirai-api-http或者CQ-Http而不是QQ-Bot

无效参数

实例配置单中的qq号是否填写错误了

mcl无法正常启动

温馨提示:对mcl一切配置文件的更改都应该在mcl不在运行的情况下进行

系统找不到指定的路径

  • mcl处于的路径中不能有任何中文字符(包括汉字与中文标点)
  • 请将mcl-installer转移至一个没有中文字符的路径下重新安装

我很确定我的路径中没有中文字符

  • 你是否人为移动了(有意或无意)mcl所处文件夹或者其子文件夹?
  • 对小白来说,如果你想移动mirai,最好的方法其实是将mcl-installer移动到别处重新安装 并将原来的config以及plugins文件夹移动到新安装的mirai中覆盖

当前qq版本太低

  • 升级mcl本体
  • 将协议换为IPAD 前往config/Console/AutoLogin.ymlprotocol更改为IPAD
  • 删除bots文件夹下所有内容

登录存在安全风险

  • 这个东西吧...挺玄学的,通常是云服务器上部署的mirai才会有这个问题,要通过这个验证,通常需要手机与电脑在同一网络环境下,而如果你使用了云服务器,那么除了使用一些玄学手段(指过两天再试就好了)或者科学手段(这玩意儿可不兴展开来讲啊 哥)外别无他法。

苹果手机无法安装滑块助手

  • 初心佬的文章最下方有手动获取ticket的教程
  • 注意,此时你不需要再点击Open with TxCaptchaHelper按钮了,而是直接将教程中获取到的ticket填入ticket栏中即可

A JNI error has occured.

  • 通常这是由于java版本太低导致的
  • 两个解决方案
    1. 可以手动安装一个java的jdk(建议版本为17或18 安装方法请自行百度)
    2. 使用mcl installer重新安装mcl 在安装时会询问是否安装java jdk 选择安装即可

有大段看不懂/完全没有中文信息的红色报错

  • 通常,这类报错的关键信息都在红色文本的最下方或者最上方
  • 如果最下方没有中文的提示,那么请前往红色文本的最上方查找关键信息

Address already in use

  • 你是否启动了两个mcl? 如果是的话,请关闭一个,并保证同时只有一个mcl在运行
  • mah中所填写的的端口与某个外部应用冲突,可以修改config/net.mamoe.mirai-api-http/setting.yml 中两个端口的值解决,值理论上可以是1024~65535中的任何一个数字

注意

若是在此处修改了端口值,你应该在控制台中填写实例配置单时相对应地修改端口值

代码部署启动时/使用特定命令时会报错

既然你是代码部署的,一些常见的细节我将会省略不解释,希望你能看懂

  • 请更新代码 & 依赖 & 插件
    shell
    git pull
    +pip install --upgrade amiyabot

可执行文件部署启动时会报错

  • 你是否更新了插件? 我通常称这种行为叫旧瓶装新酒
  • 请检查项目官网是否有更新的版本
  • 如果是的话,请更新兔兔版本后再试

部署过程看起来一切都很正常,但兔兔就是不理人

  • 检查是否有安装插件,v6的插件化使得默认部署完的兔兔是没有插件的 也就无法对常见的互动进行回应

我已经安装好插件了

  • 查看mirai窗口,检查是否有消息推送的提示,如果没有,则是mirai启动/配置有问题,导致mirai这一步就收不到消息,请检查mirai的启动情况与配置文件,并配合前文的排错食用
  • 查看兔兔窗口 是否有消息推送 通常 有的话还不回应就见鬼了
    • 检查报错,是否未正确连接到mirai

划重点

windows的cmd存在 单击窗体内黑色部分进入快速选择 这么一个机制 标志是窗口标题最前面出现了选择二字 而进入了快速选择 应用本体的运行将会被冻结 产生应用卡住不动的表象 这种情况下 只要敲击回车就可以推出快速选择 这一点对mirai和兔兔两者都适用

更新兔兔/迁移兔兔时,如何保留原来的数据

  • 将旧兔兔的 database 整个覆盖至新兔兔的根目录下即可
  • 对于可执行文件部署,也可以选择用新的可执行文件覆盖旧的可执行文件,便可以不用迁移数据库文件,但请注意,有时这会导致插件与本体版本不一致的问题,通常使用上一个方案,并重新安装插件即可解决
`,70),s=[i];function n(r,c,d,p,h,u){return e(),l("div",null,s)}const g=a(t,[["render",n]]);export{b as __pageData,g as default}; diff --git a/assets/guide_deploy_faq_commonProblem.md.66ab12e1.lean.js b/assets/guide_deploy_faq_commonProblem.md.66ab12e1.lean.js new file mode 100644 index 00000000..6ddfea94 --- /dev/null +++ b/assets/guide_deploy_faq_commonProblem.md.66ab12e1.lean.js @@ -0,0 +1 @@ +import{_ as a,o as e,c as l,V as o}from"./chunks/framework.63f12d77.js";const b=JSON.parse('{"title":"常见问题","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/faq/commonProblem.md","filePath":"guide/deploy/faq/commonProblem.md","lastUpdated":1722566694000}'),t={name:"guide/deploy/faq/commonProblem.md"},i=o("",70),s=[i];function n(r,c,d,p,h,u){return e(),l("div",null,s)}const g=a(t,[["render",n]]);export{b as __pageData,g as default}; diff --git a/assets/guide_deploy_getStarted.md.86630331.js b/assets/guide_deploy_getStarted.md.86630331.js new file mode 100644 index 00000000..643234d2 --- /dev/null +++ b/assets/guide_deploy_getStarted.md.86630331.js @@ -0,0 +1,36 @@ +import{d as n}from"./chunks/download.1cbae1cc.js";import{o as l,c as o,C as s,J as p,V as a}from"./chunks/framework.63f12d77.js";import"./chunks/index.ca03c6e9.js";const e="/assets/running.f2502c35.png",t=a('

开始部署

操作系统支持

  • Windows 10、Windows Subsystem for Linux (WSL) 或 Windows Server 2012 及以上系统
  • MacOS 11 (Big Sur) 及以上系统
  • Linux 系统官方支持 Debian 11、Ubuntu 18.04 以及 Ubuntu 20.04

安装 Git

部分插件依赖本地的 Git 服务,必须安装 Git 以确保正常使用。点击下载 并安装。或自行到官网下载合适自己系统的版本。

部署

根据你的设备系统或习惯,你可以选择 可执行文件部署 代码部署 两种方式其一

Windows 系统推荐使用可执行文件部署,可执行文件部署是一键部署的模式,部署难度低。

通过可执行文件部署

',8),c=s("thead",null,[s("tr",null,[s("th",null,"操作系统"),s("th",null,"下载"),s("th",null,"备注")])],-1),r=s("td",null,"Windows",-1),i=s("td",null,"仅支持 Windows 10、Windows Server 2016 及以上系统",-1),y=s("tr",null,[s("td",null,"Linux"),s("td",null,[s("del",null,"AmiyaBot-v6.4.6-linux.zip")]),s("td",null,"不再继续提供支持,请使用代码部署")],-1),d=a('

Windows

下载并解压,运行 AmiyaBot-v6.x.x-win32.exe,如下图成功运行后可以进入下一节

img.png

Linux

不再继续提供支持,请使用代码部署

原内容

不支持 Centos,目前在 Ubuntu 20.04 测试可用。

下载并解压,进入 package/dist 目录,运行 AmiyaBot-v6.x.x-linux

bash
cd package/dist/
+chmod 777 ./AmiyaBot-v6.x.x-linux
+./AmiyaBot-v6.x.x-linux

通过代码部署

请根据操作系统按顺序执行以下命令。

注意

推荐使用 Python 3.8 ~ 3.9 运行本项目代码,并参照可执行文件的系统支持选择部署的操作系统。

  1. 克隆仓库
bash
git clone --depth 1 https://github.com/AmiyaBot/Amiya-Bot.git
+cd Amiya-Bot
  1. 使用 virtualenv 创建虚拟环境(非必须,或根据个人习惯选择虚拟环境)
bash
# Windows
+python -m venv venv
+call venv/Scripts/activate.bat
bash
# Linux or MacOS
+python -m venv venv
+source venv/bin/activate
  1. 安装依赖
bash
pip install -r requirements.txt
  1. 安装浏览器内核

默认为 Chromium

bash
# Windows or MacOS
+playwright install chromium
+# Linux
+playwright install --with-deps chromium

部分系统由于版本过低(如 Windows Server 2012),可能不支持 chromium 内核。推荐修改为火狐(firefox)内核启动。

bash
# Windows or MacOS
+playwright install firefox
+# Linux
+playwright install --with-deps firefox
使用火狐内核需要修改入口程序 amiya.py,点击查看代码
python
import ...
+
+from amiyabot import BrowserLaunchConfig  # 导入浏览器启动配置类
+
+
+# 创建新启动类
+class Launcher(BrowserLaunchConfig):
+    def __init__(self):
+        super().__init__()
+
+        self.browser_type = 'firefox'  # 设定浏览器属性
+
+
+def run_amiya(*tasks: Coroutine):
+    ...
+
+
+if __name__ == '__main__':
+    run_amiya(
+        bot.start(launch_browser=Launcher()),  # 更改为使用新启动类启动浏览器
+        app.serve(),
+        load_plugins()
+    )
  1. 运行代码
bash
python amiya.py

日志显示同可执行文件部署,成功后可以进入下一节。

`,25),g=JSON.parse('{"title":"开始部署","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/getStarted.md","filePath":"guide/deploy/getStarted.md","lastUpdated":1722566694000}'),h={name:"guide/deploy/getStarted.md"},E=Object.assign(h,{setup(B){return(D,F)=>(l(),o("div",null,[t,s("table",null,[c,s("tbody",null,[s("tr",null,[r,s("td",null,[p(n,{version:"win32"})]),i]),y])]),d]))}});export{g as __pageData,E as default}; diff --git a/assets/guide_deploy_getStarted.md.86630331.lean.js b/assets/guide_deploy_getStarted.md.86630331.lean.js new file mode 100644 index 00000000..52ab2afb --- /dev/null +++ b/assets/guide_deploy_getStarted.md.86630331.lean.js @@ -0,0 +1 @@ +import{d as n}from"./chunks/download.1cbae1cc.js";import{o as l,c as o,C as s,J as p,V as a}from"./chunks/framework.63f12d77.js";import"./chunks/index.ca03c6e9.js";const e="/assets/running.f2502c35.png",t=a("",8),c=s("thead",null,[s("tr",null,[s("th",null,"操作系统"),s("th",null,"下载"),s("th",null,"备注")])],-1),r=s("td",null,"Windows",-1),i=s("td",null,"仅支持 Windows 10、Windows Server 2016 及以上系统",-1),y=s("tr",null,[s("td",null,"Linux"),s("td",null,[s("del",null,"AmiyaBot-v6.4.6-linux.zip")]),s("td",null,"不再继续提供支持,请使用代码部署")],-1),d=a("",25),g=JSON.parse('{"title":"开始部署","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/getStarted.md","filePath":"guide/deploy/getStarted.md","lastUpdated":1722566694000}'),h={name:"guide/deploy/getStarted.md"},E=Object.assign(h,{setup(B){return(D,F)=>(l(),o("div",null,[t,s("table",null,[c,s("tbody",null,[s("tr",null,[r,s("td",null,[p(n,{version:"win32"})]),i]),y])]),d]))}});export{g as __pageData,E as default}; diff --git a/assets/guide_deploy_index.md.bcece2d5.js b/assets/guide_deploy_index.md.bcece2d5.js new file mode 100644 index 00000000..f6ef3747 --- /dev/null +++ b/assets/guide_deploy_index.md.bcece2d5.js @@ -0,0 +1 @@ +import{b as e}from"./chunks/bots.0d794bf3.js";import{o as a,c as t,J as o,V as r}from"./chunks/framework.63f12d77.js";const i=r('

简要说明

《明日方舟》机器人 兔兔-v6 为本框架的主体项目。是 Amiya-Bot V5 的迭代版本。本框架原名为 AmiyaBot-core,是围绕着主体项目进行开发的。

本章接下来的文档,是提供给 兔兔-v6 部署用户的指引,如果你的目的是开发一个完全由自己定制的机器人,请阅读开发指南

你也可以从 兔兔-v6 的基础上进行定制。但之中的一部分代码服务于其本身的《明日方舟》功能系列插件,以及控制台项目 Amiya-Bot-console2,如果你不需要这些代码,也许你难以将它们抽离。请谨慎选择此方式。

那么,如何部署属于自己的 兔兔-v6(以下简称“兔兔”),请阅读接下来的文档。

官方版兔兔

现在,你可以直接使用官方版的兔兔啦!🎉🎉🎉

',7),c=JSON.parse('{"title":"简要说明","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/index.md","filePath":"guide/deploy/index.md","lastUpdated":1722566694000}'),n={name:"guide/deploy/index.md"},h=Object.assign(n,{setup(s){return(l,d)=>(a(),t("div",null,[i,o(e,{style:{"padding-top":"10px"}})]))}});export{c as __pageData,h as default}; diff --git a/assets/guide_deploy_index.md.bcece2d5.lean.js b/assets/guide_deploy_index.md.bcece2d5.lean.js new file mode 100644 index 00000000..b9e4fc13 --- /dev/null +++ b/assets/guide_deploy_index.md.bcece2d5.lean.js @@ -0,0 +1 @@ +import{b as e}from"./chunks/bots.0d794bf3.js";import{o as a,c as t,J as o,V as r}from"./chunks/framework.63f12d77.js";const i=r("",7),c=JSON.parse('{"title":"简要说明","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/index.md","filePath":"guide/deploy/index.md","lastUpdated":1722566694000}'),n={name:"guide/deploy/index.md"},h=Object.assign(n,{setup(s){return(l,d)=>(a(),t("div",null,[i,o(e,{style:{"padding-top":"10px"}})]))}});export{c as __pageData,h as default}; diff --git a/assets/guide_deploy_maintain_upgrade.md.cf23d537.js b/assets/guide_deploy_maintain_upgrade.md.cf23d537.js new file mode 100644 index 00000000..af4b6079 --- /dev/null +++ b/assets/guide_deploy_maintain_upgrade.md.cf23d537.js @@ -0,0 +1 @@ +import{_ as a,o as e,c as t,V as r}from"./chunks/framework.63f12d77.js";const u=JSON.parse('{"title":"如何更新","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/maintain/upgrade.md","filePath":"guide/deploy/maintain/upgrade.md","lastUpdated":1722566694000}'),o={name:"guide/deploy/maintain/upgrade.md"},n=r('

如何更新

游戏资源更新

每次启动时会检查资源仓库并更新新资源。
当游戏有更新的当日,可以通过重启程序来获得更新。

提示

资源的解包需要一定时间,无法获取更新时可稍后再试。

程序更新

从 V6 开始程序将不再自动更新,也不会推送更新消息。请关注 官方频道 获取最新的通知。

当有更新时可到 下载页面 下载更新包。
通常情况下,你只需要解压更新包的 exe 程序到你原来的目录下并启动新的程序就可以了。

插件更新

插件同样也不会自动更新。请关注插件商店和频道的公告。

',9),p=[n];function s(i,d,l,h,c,_){return e(),t("div",null,p)}const b=a(o,[["render",s]]);export{u as __pageData,b as default}; diff --git a/assets/guide_deploy_maintain_upgrade.md.cf23d537.lean.js b/assets/guide_deploy_maintain_upgrade.md.cf23d537.lean.js new file mode 100644 index 00000000..a367bdcd --- /dev/null +++ b/assets/guide_deploy_maintain_upgrade.md.cf23d537.lean.js @@ -0,0 +1 @@ +import{_ as a,o as e,c as t,V as r}from"./chunks/framework.63f12d77.js";const u=JSON.parse('{"title":"如何更新","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/maintain/upgrade.md","filePath":"guide/deploy/maintain/upgrade.md","lastUpdated":1722566694000}'),o={name:"guide/deploy/maintain/upgrade.md"},n=r("",9),p=[n];function s(i,d,l,h,c,_){return e(),t("div",null,p)}const b=a(o,[["render",s]]);export{u as __pageData,b as default}; diff --git a/assets/guide_deploy_yourChoose.md.579635ff.js b/assets/guide_deploy_yourChoose.md.579635ff.js new file mode 100644 index 00000000..3172e467 --- /dev/null +++ b/assets/guide_deploy_yourChoose.md.579635ff.js @@ -0,0 +1,5 @@ +import{_ as a,o as e,c as t,V as r}from"./chunks/framework.63f12d77.js";const b=JSON.parse('{"title":"选择你的运营方","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/yourChoose.md","filePath":"guide/deploy/yourChoose.md","lastUpdated":1722566694000}'),o={name:"guide/deploy/yourChoose.md"},p=r(`

选择你的运营方

QQ 机器人目前分为两种,一种是由腾讯官方运营的 频道机器人,另一种则是由第三方技术提供支持的QQ群机器人。

频道机器人

如果你选择了频道机器人,并且注册了“公域机器人”,很遗憾地告诉你,你不能继续部署兔兔了。因为兔兔有官方版本,你不能发布一个功能与官方版本相当接近的机器人。你可以加入 官方频道 并找到机器人“AmiyaBot”,点开资料卡添加到自己的频道里。

当然,你可以基于 AmiyaBot 框架开发自己的机器人并发布。请参阅 开发指南

如果是“私域机器人”,你仍然可以继续部署。

KOOK 机器人

请在 KOOK 开发者平台,创建一个机器人应用。

QQ 群机器人

如果你选择了 QQ 群机器人,你可能需要克服一些困难才能顺利部署。你必须部署第三方技术提供的服务才能继续部署兔兔。

第三方技术目前支持:

选择其中一个进行部署即可。

使用 go-cqhttp

请按照 go-cqhttp 官网 的说明进行部署。

修改配置中的 post-format: array

yaml
# config.yml
+message:
+    # 上报数据类型
+    # 可选: string, array
+    post-format: array

使用 mirai-api-http

mirai-api-http 有一定的部署难度,需要你拥有一定的计算机科学基础。但对比其他第三方服务,mirai 在很多方面都占有优势。

我们的团队成员 Initial-heart 为你提供了一篇部署 mirai-api-http 的博客,这篇博文详尽的描述了部署 mirai-api-http 的前期准备、部署、配置等整套部署 mirai-api-http 所需的流程。

https://www.initbili.top/2022/8d92a2feb3e2/#2-部署-mirai

结语

非常重要

请耐心根据教程部署完。部署完第三方服务,你就完成 80% 的工作了!务必部署成功再往下继续,否则后续的操作将毫无意义。

如果一切就绪,那么接着来看开始部署部分。

`,24),s=[p];function i(n,l,h,c,d,m){return e(),t("div",null,s)}const u=a(o,[["render",i]]);export{b as __pageData,u as default}; diff --git a/assets/guide_deploy_yourChoose.md.579635ff.lean.js b/assets/guide_deploy_yourChoose.md.579635ff.lean.js new file mode 100644 index 00000000..2c9491bf --- /dev/null +++ b/assets/guide_deploy_yourChoose.md.579635ff.lean.js @@ -0,0 +1 @@ +import{_ as a,o as e,c as t,V as r}from"./chunks/framework.63f12d77.js";const b=JSON.parse('{"title":"选择你的运营方","description":"","frontmatter":{},"headers":[],"relativePath":"guide/deploy/yourChoose.md","filePath":"guide/deploy/yourChoose.md","lastUpdated":1722566694000}'),o={name:"guide/deploy/yourChoose.md"},p=r("",24),s=[p];function i(n,l,h,c,d,m){return e(),t("div",null,s)}const u=a(o,[["render",i]]);export{b as __pageData,u as default}; diff --git a/assets/guide_index.md.4a06ec29.js b/assets/guide_index.md.4a06ec29.js new file mode 100644 index 00000000..e29b3340 --- /dev/null +++ b/assets/guide_index.md.4a06ec29.js @@ -0,0 +1 @@ +import{_ as a,o as e,c as r,V as t}from"./chunks/framework.63f12d77.js";const f=JSON.parse('{"title":"AmiyaBot 简介","description":"","frontmatter":{"aside":false},"headers":[],"relativePath":"guide/index.md","filePath":"guide/index.md","lastUpdated":1722566694000}'),o={name:"guide/index.md"},i=t('

AmiyaBot 简介

介绍

AmiyaBot 是异步 Python QQ 机器人框架。基于 QQ 官方API 。内置了丰富的消息构建方法和适配器,让你轻松实现你的创意。

她的过去...

AmiyaBot 诞生于2019年,是一个《明日方舟》民间 QQ 机器人,至本框架发布时已迭代了 5 个里程碑版本。一直以来,AmiyaBot 都秉着 “为所有人带来快乐” 的初衷,跌跌撞撞到现在,依旧坚持开源、免费为用户提供服务。

2022年5月13日重大变故后,AmiyaBot 决定迁移至 QQ 频道成为正式的机器人。原群聊机器人(Amiya2号)终止服务。
2022年6月11日,剥离出其核心部分成为框架,也就是本文档所指的 AmiyaBot
2022年9月14日,V6 版本 的用户自部署群聊机器人发布,由用户延续原群聊机器人(Amiya2号)的初衷。
2024年6月18日,官方全域机器人正式发布。

现在

AmiyaBot 依旧坚持初心,将快乐带给所有人。加入我们的 官方群官方频道开始使用

',8),n=[i];function h(s,p,d,l,m,_){return e(),r("div",null,n)}const u=a(o,[["render",h]]);export{f as __pageData,u as default}; diff --git a/assets/guide_index.md.4a06ec29.lean.js b/assets/guide_index.md.4a06ec29.lean.js new file mode 100644 index 00000000..2dd4e8af --- /dev/null +++ b/assets/guide_index.md.4a06ec29.lean.js @@ -0,0 +1 @@ +import{_ as a,o as e,c as r,V as t}from"./chunks/framework.63f12d77.js";const f=JSON.parse('{"title":"AmiyaBot 简介","description":"","frontmatter":{"aside":false},"headers":[],"relativePath":"guide/index.md","filePath":"guide/index.md","lastUpdated":1722566694000}'),o={name:"guide/index.md"},i=t("",8),n=[i];function h(s,p,d,l,m,_){return e(),r("div",null,n)}const u=a(o,[["render",h]]);export{f as __pageData,u as default}; diff --git a/assets/handlerFactory.f4bc05d9.svg b/assets/handlerFactory.f4bc05d9.svg new file mode 100644 index 00000000..7f4e2916 --- /dev/null +++ b/assets/handlerFactory.f4bc05d9.svg @@ -0,0 +1 @@ +AmiyaBot@bot.on_event@bot.on_message@bot.on_messageevent_handlersmessage_handlersexception_handlersCenterProcessorBotHandlerFactory \ No newline at end of file diff --git a/assets/hello.3b081946.png b/assets/hello.3b081946.png new file mode 100644 index 00000000..98514847 Binary files /dev/null and b/assets/hello.3b081946.png differ diff --git a/assets/hello2.56460902.png b/assets/hello2.56460902.png new file mode 100644 index 00000000..c95d8f84 Binary files /dev/null and b/assets/hello2.56460902.png differ diff --git a/assets/hello3.bbe26c93.png b/assets/hello3.bbe26c93.png new file mode 100644 index 00000000..c76ea270 Binary files /dev/null and b/assets/hello3.bbe26c93.png differ diff --git a/assets/hello4.58f3a96c.png b/assets/hello4.58f3a96c.png new file mode 100644 index 00000000..3ecf93c8 Binary files /dev/null and b/assets/hello4.58f3a96c.png differ diff --git a/assets/hello5.472a7f7b.png b/assets/hello5.472a7f7b.png new file mode 100644 index 00000000..a52ce838 Binary files /dev/null and b/assets/hello5.472a7f7b.png differ diff --git a/assets/hello6.f4a06bfe.png b/assets/hello6.f4a06bfe.png new file mode 100644 index 00000000..e7de80f1 Binary files /dev/null and b/assets/hello6.f4a06bfe.png differ diff --git a/assets/hello7.8e9afac1.png b/assets/hello7.8e9afac1.png new file mode 100644 index 00000000..c3a111f6 Binary files /dev/null and b/assets/hello7.8e9afac1.png differ diff --git a/assets/index.md.27207959.js b/assets/index.md.27207959.js new file mode 100644 index 00000000..cf4b1ab4 --- /dev/null +++ b/assets/index.md.27207959.js @@ -0,0 +1 @@ +import{b as e}from"./chunks/bots.0d794bf3.js";import{o as t,c as a,C as o,J as i}from"./chunks/framework.63f12d77.js";const s={class:"main-container"},p=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"home","hero":{"name":"AmiyaBot","text":"Progressive Python QQ Bot Framework","tagline":"渐进式 QQ 机器人框架,可使用内置适配器对接官方 QQ 群、OneBot v11/12、KOOK 等机器人平台。","image":{"src":"/logo.svg","alt":"AmiyaBot"},"actions":[{"theme":"brand","text":"开始使用","link":"/develop/basic/"},{"theme":"alt","text":"添加兔兔机器人到你的群聊","link":"/guide/deploy/#官方版兔兔"},{"theme":"alt","text":"部署兔兔机器人","link":"/guide/deploy/"}]},"features":[{"icon":"🚀","title":"简洁高效","details":"采用异步 I/O,摆脱官方 API 繁杂的操作,以更加简洁和可读性更高的代码让你专注于你的业务逻辑。"},{"icon":"🎭","title":"多账号 & 热插拔","details":"支持同时创建多个机器人实例,为所有实例注册共享的消息处理方法,以及在多账号实例内动态增删机器人。"},{"icon":"🧩","title":"适配器 & 插件支持","details":"通过适配器来更改机器人的服务来源,提供更大的灵活性和可扩展性。支持插件开发方案,将业务和主程序分离,使机器人更加生态化和可定制化。"},{"icon":"🎉","title":"丰富的消息类型","details":"内置的 PIL 图像合成模块以及 HTML 转换器,支持合成文字图片或通过渲染 WEB 和 Markdown 合成图片,轻松实现你的绝佳创意。"}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1722566694000}'),n={name:"index.md"},_=Object.assign(n,{setup(l){return(d,r)=>(t(),a("div",null,[o("div",s,[i(e,{style:{"padding-top":"10px"}})])]))}});export{p as __pageData,_ as default}; diff --git a/assets/index.md.27207959.lean.js b/assets/index.md.27207959.lean.js new file mode 100644 index 00000000..cf4b1ab4 --- /dev/null +++ b/assets/index.md.27207959.lean.js @@ -0,0 +1 @@ +import{b as e}from"./chunks/bots.0d794bf3.js";import{o as t,c as a,C as o,J as i}from"./chunks/framework.63f12d77.js";const s={class:"main-container"},p=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"home","hero":{"name":"AmiyaBot","text":"Progressive Python QQ Bot Framework","tagline":"渐进式 QQ 机器人框架,可使用内置适配器对接官方 QQ 群、OneBot v11/12、KOOK 等机器人平台。","image":{"src":"/logo.svg","alt":"AmiyaBot"},"actions":[{"theme":"brand","text":"开始使用","link":"/develop/basic/"},{"theme":"alt","text":"添加兔兔机器人到你的群聊","link":"/guide/deploy/#官方版兔兔"},{"theme":"alt","text":"部署兔兔机器人","link":"/guide/deploy/"}]},"features":[{"icon":"🚀","title":"简洁高效","details":"采用异步 I/O,摆脱官方 API 繁杂的操作,以更加简洁和可读性更高的代码让你专注于你的业务逻辑。"},{"icon":"🎭","title":"多账号 & 热插拔","details":"支持同时创建多个机器人实例,为所有实例注册共享的消息处理方法,以及在多账号实例内动态增删机器人。"},{"icon":"🧩","title":"适配器 & 插件支持","details":"通过适配器来更改机器人的服务来源,提供更大的灵活性和可扩展性。支持插件开发方案,将业务和主程序分离,使机器人更加生态化和可定制化。"},{"icon":"🎉","title":"丰富的消息类型","details":"内置的 PIL 图像合成模块以及 HTML 转换器,支持合成文字图片或通过渲染 WEB 和 Markdown 合成图片,轻松实现你的绝佳创意。"}]},"headers":[],"relativePath":"index.md","filePath":"index.md","lastUpdated":1722566694000}'),n={name:"index.md"},_=Object.assign(n,{setup(l){return(d,r)=>(t(),a("div",null,[o("div",s,[i(e,{style:{"padding-top":"10px"}})])]))}});export{p as __pageData,_ as default}; diff --git a/assets/inter-italic-cyrillic-ext.33bd5a8e.woff2 b/assets/inter-italic-cyrillic-ext.33bd5a8e.woff2 new file mode 100644 index 00000000..2a687296 Binary files /dev/null and b/assets/inter-italic-cyrillic-ext.33bd5a8e.woff2 differ diff --git a/assets/inter-italic-cyrillic.ea42a392.woff2 b/assets/inter-italic-cyrillic.ea42a392.woff2 new file mode 100644 index 00000000..f6403515 Binary files /dev/null and b/assets/inter-italic-cyrillic.ea42a392.woff2 differ diff --git a/assets/inter-italic-greek-ext.4fbe9427.woff2 b/assets/inter-italic-greek-ext.4fbe9427.woff2 new file mode 100644 index 00000000..00218960 Binary files /dev/null and b/assets/inter-italic-greek-ext.4fbe9427.woff2 differ diff --git a/assets/inter-italic-greek.8f4463c4.woff2 b/assets/inter-italic-greek.8f4463c4.woff2 new file mode 100644 index 00000000..71c265f8 Binary files /dev/null and b/assets/inter-italic-greek.8f4463c4.woff2 differ diff --git a/assets/inter-italic-latin-ext.bd8920cc.woff2 b/assets/inter-italic-latin-ext.bd8920cc.woff2 new file mode 100644 index 00000000..9c1b9440 Binary files /dev/null and b/assets/inter-italic-latin-ext.bd8920cc.woff2 differ diff --git a/assets/inter-italic-latin.bd3b6f56.woff2 b/assets/inter-italic-latin.bd3b6f56.woff2 new file mode 100644 index 00000000..01fcf207 Binary files /dev/null and b/assets/inter-italic-latin.bd3b6f56.woff2 differ diff --git a/assets/inter-italic-vietnamese.6ce511fb.woff2 b/assets/inter-italic-vietnamese.6ce511fb.woff2 new file mode 100644 index 00000000..e4f788ee Binary files /dev/null and b/assets/inter-italic-vietnamese.6ce511fb.woff2 differ diff --git a/assets/inter-roman-cyrillic-ext.e75737ce.woff2 b/assets/inter-roman-cyrillic-ext.e75737ce.woff2 new file mode 100644 index 00000000..28593ccb Binary files /dev/null and b/assets/inter-roman-cyrillic-ext.e75737ce.woff2 differ diff --git a/assets/inter-roman-cyrillic.5f2c6c8c.woff2 b/assets/inter-roman-cyrillic.5f2c6c8c.woff2 new file mode 100644 index 00000000..a20adc16 Binary files /dev/null and b/assets/inter-roman-cyrillic.5f2c6c8c.woff2 differ diff --git a/assets/inter-roman-greek-ext.ab0619bc.woff2 b/assets/inter-roman-greek-ext.ab0619bc.woff2 new file mode 100644 index 00000000..e3b0be76 Binary files /dev/null and b/assets/inter-roman-greek-ext.ab0619bc.woff2 differ diff --git a/assets/inter-roman-greek.d5a6d92a.woff2 b/assets/inter-roman-greek.d5a6d92a.woff2 new file mode 100644 index 00000000..f790e047 Binary files /dev/null and b/assets/inter-roman-greek.d5a6d92a.woff2 differ diff --git a/assets/inter-roman-latin-ext.0030eebd.woff2 b/assets/inter-roman-latin-ext.0030eebd.woff2 new file mode 100644 index 00000000..715bd903 Binary files /dev/null and b/assets/inter-roman-latin-ext.0030eebd.woff2 differ diff --git a/assets/inter-roman-latin.2ed14f66.woff2 b/assets/inter-roman-latin.2ed14f66.woff2 new file mode 100644 index 00000000..a540b7af Binary files /dev/null and b/assets/inter-roman-latin.2ed14f66.woff2 differ diff --git a/assets/inter-roman-vietnamese.14ce25a6.woff2 b/assets/inter-roman-vietnamese.14ce25a6.woff2 new file mode 100644 index 00000000..5a9f9cb9 Binary files /dev/null and b/assets/inter-roman-vietnamese.14ce25a6.woff2 differ diff --git a/assets/lifeCycle.3a881ce1.svg b/assets/lifeCycle.3a881ce1.svg new file mode 100644 index 00000000..2091429b --- /dev/null +++ b/assets/lifeCycle.3a881ce1.svg @@ -0,0 +1 @@ +message_createdmessage_before_handlemessage_before_sendmessage_after_sendmessage_after_handlemessage_before_waiter_setmessage_recvchoice_handlersNo choiceForce waitmessage_sendwaiter_setWait eventKeep waiting \ No newline at end of file diff --git a/assets/link.e0d1dd67.png b/assets/link.e0d1dd67.png new file mode 100644 index 00000000..798760a3 Binary files /dev/null and b/assets/link.e0d1dd67.png differ diff --git a/assets/mainBot.0344269a.png b/assets/mainBot.0344269a.png new file mode 100644 index 00000000..b4197cc8 Binary files /dev/null and b/assets/mainBot.0344269a.png differ diff --git a/assets/online.f82e5764.png b/assets/online.f82e5764.png new file mode 100644 index 00000000..2e4b084b Binary files /dev/null and b/assets/online.f82e5764.png differ diff --git a/assets/plugin.88ce690c.png b/assets/plugin.88ce690c.png new file mode 100644 index 00000000..de9bdbde Binary files /dev/null and b/assets/plugin.88ce690c.png differ diff --git a/assets/plugin2.14fbd7cf.png b/assets/plugin2.14fbd7cf.png new file mode 100644 index 00000000..68482b42 Binary files /dev/null and b/assets/plugin2.14fbd7cf.png differ diff --git a/assets/plugin3.ff94cfe4.png b/assets/plugin3.ff94cfe4.png new file mode 100644 index 00000000..7f9a9d60 Binary files /dev/null and b/assets/plugin3.ff94cfe4.png differ diff --git a/assets/running.f2502c35.png b/assets/running.f2502c35.png new file mode 100644 index 00000000..9084d6ee Binary files /dev/null and b/assets/running.f2502c35.png differ diff --git a/assets/sponsor.md.b1d18c44.js b/assets/sponsor.md.b1d18c44.js new file mode 100644 index 00000000..1b5d43e1 --- /dev/null +++ b/assets/sponsor.md.b1d18c44.js @@ -0,0 +1 @@ +import{_ as p,o as t,c as e,V as u,F as l,R as f,n as g,C as a,t as i,G as _,J as m,a as r}from"./chunks/framework.63f12d77.js";import{a as y}from"./chunks/index.ca03c6e9.js";const q="/assets/5a4a07cc67f556288d3df2e9029fc14.f485e307.jpg";const b={name:"specialThanks"},k={class:"user-list"},x=u('
幕后大佬顶级的存在!支撑兔兔的所有!
Initial heart社区风纪委员、Logo 贡献者
hsyhhssyy插件作者、兔兔 AI 维护人
天基插件作者、插件服务器贡献者
.Tdp插件作者、百度图像识别接口贡献者
',5),A=[x];function B(c,o,s,v,d,h){return t(),e("div",k,A)}const N=p(b,[["render",B],["__scopeId","data-v-6c6a5107"]]);const T={name:"chargeThanks",props:{displayUserName:Boolean,min:{type:Number,default:0},max:{type:Number,default:1/0}},methods:{get_sponsors:function(){y.get("https://server.amiyabot.com:10001/get_sponsors").then(c=>{this.data=JSON.parse(c.data),this.data.sort((o,s)=>s.all_sum_amount-o.all_sum_amount)})}},data(){return{data:[]}},mounted(){this.get_sponsors()}},$={class:"user-list"},V=["src","alt"],I={key:0,class:"user-name"},P={class:"name"},S={class:"amount"};function C(c,o,s,v,d,h){return t(),e("div",$,[(t(!0),e(l,null,f(d.data,n=>(t(),e(l,null,[n.all_sum_amount>=s.min&&n.all_sum_amount赞助

AmiyaBot 一路走来离不开大家的默默支持,如果你喜欢并支持我们,可以为我们打赏一瓶快乐水。我相信快乐是可以互相传递的,你的快乐水带给我们快乐的同时,想必 AmiyaBot 也给你带去了快乐吧。

但同时我们希望你量力而为,你对 AmiyaBot 的认可就已经是最大的支持了。如果可以的话,恳请你在 Github 为 AmiyaBot 点上一颗小小的️ ⭐ star。

特别鸣谢

感谢各位对 AmiyaBot 社区做出的贡献,是大家共同塑造了 AmiyaBot 社区的繁荣。期待未来我们能携手创造更多可能!🌹

',5),J=a("h2",{id:"充电鸣谢",tabindex:"-1"},[r("充电鸣谢 "),a("a",{class:"header-anchor",href:"#充电鸣谢","aria-label":'Permalink to "充电鸣谢"'},"​")],-1),O=a("p",null,"你们的鼎力支持让我们感到创作 AmiyaBot 项目是值得的。感谢有你,让 AmiyaBot 秉承初衷。❤️",-1),j=a("p",null,[r("打赏请前往"),a("a",{href:"https://afdian.com/a/amiyabot",target:"_blank",rel:"noreferrer"},"爱发电主页"),r("。")],-1),z=a("img",{style:{width:"400px"},src:q,alt:"image"},null,-1),L=JSON.parse('{"title":"赞助","description":"","frontmatter":{"aside":false},"headers":[],"relativePath":"sponsor.md","filePath":"sponsor.md","lastUpdated":1722566694000}'),E={name:"sponsor.md"},R=Object.assign(E,{setup(c){return(o,s)=>(t(),e("div",null,[D,m(N),J,O,m(U,{min:0,displayUserName:!0}),j,z]))}});export{L as __pageData,R as default}; diff --git a/assets/sponsor.md.b1d18c44.lean.js b/assets/sponsor.md.b1d18c44.lean.js new file mode 100644 index 00000000..c7f79239 --- /dev/null +++ b/assets/sponsor.md.b1d18c44.lean.js @@ -0,0 +1 @@ +import{_ as p,o as t,c as e,V as u,F as l,R as f,n as g,C as a,t as i,G as _,J as m,a as r}from"./chunks/framework.63f12d77.js";import{a as y}from"./chunks/index.ca03c6e9.js";const q="/assets/5a4a07cc67f556288d3df2e9029fc14.f485e307.jpg";const b={name:"specialThanks"},k={class:"user-list"},x=u('
幕后大佬顶级的存在!支撑兔兔的所有!
Initial heart社区风纪委员、Logo 贡献者
hsyhhssyy插件作者、兔兔 AI 维护人
天基插件作者、插件服务器贡献者
.Tdp插件作者、百度图像识别接口贡献者
',5),A=[x];function B(c,o,s,v,d,h){return t(),e("div",k,A)}const N=p(b,[["render",B],["__scopeId","data-v-6c6a5107"]]);const T={name:"chargeThanks",props:{displayUserName:Boolean,min:{type:Number,default:0},max:{type:Number,default:1/0}},methods:{get_sponsors:function(){y.get("https://server.amiyabot.com:10001/get_sponsors").then(c=>{this.data=JSON.parse(c.data),this.data.sort((o,s)=>s.all_sum_amount-o.all_sum_amount)})}},data(){return{data:[]}},mounted(){this.get_sponsors()}},$={class:"user-list"},V=["src","alt"],I={key:0,class:"user-name"},P={class:"name"},S={class:"amount"};function C(c,o,s,v,d,h){return t(),e("div",$,[(t(!0),e(l,null,f(d.data,n=>(t(),e(l,null,[n.all_sum_amount>=s.min&&n.all_sum_amount(t(),e("div",null,[D,m(N),J,O,m(U,{min:0,displayUserName:!0}),j,z]))}});export{L as __pageData,R as default}; diff --git a/assets/style.9e96967a.css b/assets/style.9e96967a.css new file mode 100644 index 00000000..8b38f423 --- /dev/null +++ b/assets/style.9e96967a.css @@ -0,0 +1 @@ +@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/assets/inter-roman-cyrillic.5f2c6c8c.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/assets/inter-roman-cyrillic-ext.e75737ce.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/assets/inter-roman-greek.d5a6d92a.woff2) format("woff2");unicode-range:U+0370-03FF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/assets/inter-roman-greek-ext.ab0619bc.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/assets/inter-roman-latin.2ed14f66.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/assets/inter-roman-latin-ext.0030eebd.woff2) format("woff2");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/assets/inter-roman-vietnamese.14ce25a6.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/assets/inter-italic-cyrillic.ea42a392.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/assets/inter-italic-cyrillic-ext.33bd5a8e.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/assets/inter-italic-greek.8f4463c4.woff2) format("woff2");unicode-range:U+0370-03FF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/assets/inter-italic-greek-ext.4fbe9427.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/assets/inter-italic-latin.bd3b6f56.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/assets/inter-italic-latin-ext.bd8920cc.woff2) format("woff2");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/assets/inter-italic-vietnamese.6ce511fb.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:Chinese Quotes;src:local("PingFang SC Regular"),local("PingFang SC"),local("SimHei"),local("Source Han Sans SC");unicode-range:U+2018,U+2019,U+201C,U+201D}:root{--vp-c-white: #ffffff;--vp-c-black: #000000;--vp-c-gray: #8e8e93;--vp-c-text-light-1: rgba(60, 60, 67);--vp-c-text-light-2: rgba(60, 60, 67, .75);--vp-c-text-light-3: rgba(60, 60, 67, .33);--vp-c-text-dark-1: rgba(255, 255, 245, .86);--vp-c-text-dark-2: rgba(235, 235, 245, .6);--vp-c-text-dark-3: rgba(235, 235, 245, .38);--vp-c-green: #10b981;--vp-c-green-light: #34d399;--vp-c-green-lighter: #6ee7b7;--vp-c-green-dark: #059669;--vp-c-green-darker: #047857;--vp-c-green-dimm-1: rgba(16, 185, 129, .05);--vp-c-green-dimm-2: rgba(16, 185, 129, .2);--vp-c-green-dimm-3: rgba(16, 185, 129, .5);--vp-c-yellow: #d97706;--vp-c-yellow-light: #f59e0b;--vp-c-yellow-lighter: #fbbf24;--vp-c-yellow-dark: #b45309;--vp-c-yellow-darker: #92400e;--vp-c-yellow-dimm-1: rgba(234, 179, 8, .05);--vp-c-yellow-dimm-2: rgba(234, 179, 8, .2);--vp-c-yellow-dimm-3: rgba(234, 179, 8, .5);--vp-c-red: #f43f5e;--vp-c-red-light: #fb7185;--vp-c-red-lighter: #fda4af;--vp-c-red-dark: #e11d48;--vp-c-red-darker: #be123c;--vp-c-red-dimm-1: rgba(244, 63, 94, .05);--vp-c-red-dimm-2: rgba(244, 63, 94, .2);--vp-c-red-dimm-3: rgba(244, 63, 94, .5);--vp-c-sponsor: #db2777}:root{--vp-c-bg: #ffffff;--vp-c-bg-elv: #ffffff;--vp-c-bg-elv-up: #ffffff;--vp-c-bg-elv-down: #f6f6f7;--vp-c-bg-elv-mute: #f6f6f7;--vp-c-bg-soft: #f6f6f7;--vp-c-bg-soft-up: #f9f9fa;--vp-c-bg-soft-down: #e3e3e5;--vp-c-bg-soft-mute: #e3e3e5;--vp-c-bg-alt: #f6f6f7;--vp-c-border: rgba(60, 60, 67, .29);--vp-c-divider: rgba(60, 60, 67, .12);--vp-c-gutter: rgba(60, 60, 67, .12);--vp-c-neutral: var(--vp-c-black);--vp-c-neutral-inverse: var(--vp-c-white);--vp-c-text-1: var(--vp-c-text-light-1);--vp-c-text-2: var(--vp-c-text-light-2);--vp-c-text-3: var(--vp-c-text-light-3);--vp-c-text-inverse-1: var(--vp-c-text-dark-1);--vp-c-text-inverse-2: var(--vp-c-text-dark-2);--vp-c-text-inverse-3: var(--vp-c-text-dark-3);--vp-c-text-code: #476582;--vp-c-brand: var(--vp-c-green);--vp-c-brand-light: var(--vp-c-green-light);--vp-c-brand-lighter: var(--vp-c-green-lighter);--vp-c-brand-dark: var(--vp-c-green-dark);--vp-c-brand-darker: var(--vp-c-green-darker);--vp-c-mute: #f6f6f7;--vp-c-mute-light: #f9f9fc;--vp-c-mute-lighter: #ffffff;--vp-c-mute-dark: #e3e3e5;--vp-c-mute-darker: #d7d7d9}.dark{--vp-c-bg: #1e1e20;--vp-c-bg-elv: #252529;--vp-c-bg-elv-up: #313136;--vp-c-bg-elv-down: #1e1e20;--vp-c-bg-elv-mute: #313136;--vp-c-bg-soft: #252529;--vp-c-bg-soft-up: #313136;--vp-c-bg-soft-down: #1e1e20;--vp-c-bg-soft-mute: #313136;--vp-c-bg-alt: #161618;--vp-c-border: rgba(82, 82, 89, .68);--vp-c-divider: rgba(82, 82, 89, .32);--vp-c-gutter: #000000;--vp-c-neutral: var(--vp-c-white);--vp-c-neutral-inverse: var(--vp-c-black);--vp-c-text-1: var(--vp-c-text-dark-1);--vp-c-text-2: var(--vp-c-text-dark-2);--vp-c-text-3: var(--vp-c-text-dark-3);--vp-c-text-inverse-1: var(--vp-c-text-light-1);--vp-c-text-inverse-2: var(--vp-c-text-light-2);--vp-c-text-inverse-3: var(--vp-c-text-light-3);--vp-c-text-code: #c9def1;--vp-c-mute: #313136;--vp-c-mute-light: #3a3a3c;--vp-c-mute-lighter: #505053;--vp-c-mute-dark: #2c2c30;--vp-c-mute-darker: #252529}:root{--vp-font-family-base: "Chinese Quotes", "Inter var", "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Helvetica, Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--vp-font-family-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace}:root{--vp-shadow-1: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--vp-shadow-2: 0 3px 12px rgba(0, 0, 0, .07), 0 1px 4px rgba(0, 0, 0, .07);--vp-shadow-3: 0 12px 32px rgba(0, 0, 0, .1), 0 2px 6px rgba(0, 0, 0, .08);--vp-shadow-4: 0 14px 44px rgba(0, 0, 0, .12), 0 3px 9px rgba(0, 0, 0, .12);--vp-shadow-5: 0 18px 56px rgba(0, 0, 0, .16), 0 4px 12px rgba(0, 0, 0, .16)}:root{--vp-z-index-local-nav: 10;--vp-z-index-nav: 20;--vp-z-index-layout-top: 30;--vp-z-index-backdrop: 40;--vp-z-index-sidebar: 50;--vp-z-index-footer: 60}:root{--vp-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' height='20' width='20' stroke='rgba(128,128,128,1)' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2'/%3E%3C/svg%3E");--vp-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' height='20' width='20' stroke='rgba(128,128,128,1)' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2m-6 9 2 2 4-4'/%3E%3C/svg%3E")}:root{--vp-layout-max-width: 1440px}:root{--vp-header-anchor-symbol: "#"}:root{--vp-code-line-height: 1.7;--vp-code-font-size: .875em;--vp-c-code-dimm: var(--vp-c-text-dark-3);--vp-code-block-color: var(--vp-c-text-dark-1);--vp-code-block-bg: #292b30;--vp-code-block-bg-light: #1e1e20;--vp-code-block-divider-color: #000000;--vp-code-line-highlight-color: rgba(0, 0, 0, .5);--vp-code-line-number-color: var(--vp-c-code-dimm);--vp-code-line-diff-add-color: var(--vp-c-green-dimm-2);--vp-code-line-diff-add-symbol-color: var(--vp-c-green);--vp-code-line-diff-remove-color: var(--vp-c-red-dimm-2);--vp-code-line-diff-remove-symbol-color: var(--vp-c-red);--vp-code-line-warning-color: var(--vp-c-yellow-dimm-2);--vp-code-line-error-color: var(--vp-c-red-dimm-2);--vp-code-copy-code-border-color: transparent;--vp-code-copy-code-bg: var(--vp-code-block-bg-light);--vp-code-copy-code-hover-border-color: var(--vp-c-divider);--vp-code-copy-code-hover-bg: var(--vp-code-block-bg-light);--vp-code-copy-code-active-text: var(--vp-c-text-dark-2);--vp-code-tab-divider: var(--vp-code-block-divider-color);--vp-code-tab-text-color: var(--vp-c-text-dark-2);--vp-code-tab-bg: var(--vp-code-block-bg);--vp-code-tab-hover-text-color: var(--vp-c-text-dark-1);--vp-code-tab-active-text-color: var(--vp-c-text-dark-1);--vp-code-tab-active-bar-color: var(--vp-c-brand)}.dark{--vp-code-block-bg: #161618}:root:not(.dark) .vp-adaptive-theme{--vp-c-code-dimm: var(--vp-c-text-2);--vp-code-block-color: var(--vp-c-text-1);--vp-code-block-bg: #f8f8f8;--vp-code-block-divider-color: var(--vp-c-divider);--vp-code-line-highlight-color: #ececec;--vp-code-line-number-color: var(--vp-c-code-dimm);--vp-code-copy-code-bg: #e2e2e2;--vp-code-copy-code-hover-bg: #dcdcdc;--vp-code-copy-code-active-text: var(--vp-c-text-2);--vp-code-tab-divider: var(--vp-c-divider);--vp-code-tab-text-color: var(--vp-c-text-2);--vp-code-tab-bg: var(--vp-code-block-bg);--vp-code-tab-hover-text-color: var(--vp-c-text-1);--vp-code-tab-active-text-color: var(--vp-c-text-1)}:root{--vp-button-brand-border: var(--vp-c-brand-lighter);--vp-button-brand-text: var(--vp-c-white);--vp-button-brand-bg: var(--vp-c-brand);--vp-button-brand-hover-border: var(--vp-c-brand-lighter);--vp-button-brand-hover-text: var(--vp-c-white);--vp-button-brand-hover-bg: var(--vp-c-brand-dark);--vp-button-brand-active-border: var(--vp-c-brand-lighter);--vp-button-brand-active-text: var(--vp-c-white);--vp-button-brand-active-bg: var(--vp-c-brand-darker);--vp-button-alt-border: var(--vp-c-border);--vp-button-alt-text: var(--vp-c-neutral);--vp-button-alt-bg: var(--vp-c-mute);--vp-button-alt-hover-border: var(--vp-c-border);--vp-button-alt-hover-text: var(--vp-c-neutral);--vp-button-alt-hover-bg: var(--vp-c-mute-dark);--vp-button-alt-active-border: var(--vp-c-border);--vp-button-alt-active-text: var(--vp-c-neutral);--vp-button-alt-active-bg: var(--vp-c-mute-darker);--vp-button-sponsor-border: var(--vp-c-gray-light-3);--vp-button-sponsor-text: var(--vp-c-text-light-2);--vp-button-sponsor-bg: transparent;--vp-button-sponsor-hover-border: var(--vp-c-sponsor);--vp-button-sponsor-hover-text: var(--vp-c-sponsor);--vp-button-sponsor-hover-bg: transparent;--vp-button-sponsor-active-border: var(--vp-c-sponsor);--vp-button-sponsor-active-text: var(--vp-c-sponsor);--vp-button-sponsor-active-bg: transparent}.dark{--vp-button-sponsor-border: var(--vp-c-gray-dark-1);--vp-button-sponsor-text: var(--vp-c-text-dark-2)}:root{--vp-custom-block-font-size: 14px;--vp-custom-block-code-font-size: 13px;--vp-custom-block-info-border: var(--vp-c-border);--vp-custom-block-info-text: var(--vp-c-text-2);--vp-custom-block-info-bg: var(--vp-c-bg-soft-up);--vp-custom-block-info-code-bg: var(--vp-c-bg-soft);--vp-custom-block-tip-border: var(--vp-c-green);--vp-custom-block-tip-text: var(--vp-c-green-dark);--vp-custom-block-tip-bg: var(--vp-c-bg-soft-up);--vp-custom-block-tip-code-bg: var(--vp-c-bg-soft);--vp-custom-block-warning-border: var(--vp-c-yellow);--vp-custom-block-warning-text: var(--vp-c-yellow);--vp-custom-block-warning-bg: var(--vp-c-bg-soft-up);--vp-custom-block-warning-code-bg: var(--vp-c-bg-soft);--vp-custom-block-danger-border: var(--vp-c-red);--vp-custom-block-danger-text: var(--vp-c-red);--vp-custom-block-danger-bg: var(--vp-c-bg-soft-up);--vp-custom-block-danger-code-bg: var(--vp-c-bg-soft);--vp-custom-block-details-border: var(--vp-custom-block-info-border);--vp-custom-block-details-text: var(--vp-custom-block-info-text);--vp-custom-block-details-bg: var(--vp-custom-block-info-bg);--vp-custom-block-details-code-bg: var(--vp-custom-block-details-bg)}:root{--vp-input-border-color: var(--vp-c-border);--vp-input-bg-color: var(--vp-c-bg-alt);--vp-input-hover-border-color: var(--vp-c-gray);--vp-input-switch-bg-color: var(--vp-c-mute)}:root{--vp-nav-height: 64px;--vp-nav-bg-color: var(--vp-c-bg);--vp-nav-screen-bg-color: var(--vp-c-bg)}:root{--vp-local-nav-bg-color: var(--vp-c-bg)}:root{--vp-sidebar-width: 272px;--vp-sidebar-bg-color: var(--vp-c-bg-alt)}:root{--vp-backdrop-bg-color: rgba(0, 0, 0, .6)}:root{--vp-home-hero-name-color: var(--vp-c-brand);--vp-home-hero-name-background: transparent;--vp-home-hero-image-background-image: none;--vp-home-hero-image-filter: none}:root{--vp-badge-info-border: var(--vp-c-border);--vp-badge-info-text: var(--vp-c-text-2);--vp-badge-info-bg: var(--vp-c-bg-soft-up);--vp-badge-tip-border: var(--vp-c-green-dark);--vp-badge-tip-text: var(--vp-c-green);--vp-badge-tip-bg: var(--vp-c-green-dimm-1);--vp-badge-warning-border: var(--vp-c-yellow-dark);--vp-badge-warning-text: var(--vp-c-yellow);--vp-badge-warning-bg: var(--vp-c-yellow-dimm-1);--vp-badge-danger-border: var(--vp-c-red-dark);--vp-badge-danger-text: var(--vp-c-red);--vp-badge-danger-bg: var(--vp-c-red-dimm-1)}:root{--vp-carbon-ads-text-color: var(--vp-c-text-1);--vp-carbon-ads-poweredby-color: var(--vp-c-text-2);--vp-carbon-ads-bg-color: var(--vp-c-bg-soft);--vp-carbon-ads-hover-text-color: var(--vp-c-brand);--vp-carbon-ads-hover-poweredby-color: var(--vp-c-text-1)}:root{--vp-local-search-bg: var(--vp-c-bg);--vp-local-search-result-bg: var(--vp-c-bg);--vp-local-search-result-border: var(--vp-c-divider);--vp-local-search-result-selected-bg: var(--vp-c-bg);--vp-local-search-result-selected-border: var(--vp-c-brand);--vp-local-search-highlight-bg: var(--vp-c-green-lighter);--vp-local-search-highlight-text: var(--vp-c-black)}*,:before,:after{box-sizing:border-box}html{line-height:1.4;font-size:16px;-webkit-text-size-adjust:100%}html.dark{color-scheme:dark}body{margin:0;width:100%;min-width:320px;min-height:100vh;line-height:24px;font-family:var(--vp-font-family-base);font-size:16px;font-weight:400;color:var(--vp-c-text-1);background-color:var(--vp-c-bg);direction:ltr;font-synthesis:style;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}main{display:block}h1,h2,h3,h4,h5,h6{margin:0;line-height:24px;font-size:16px;font-weight:400}p{margin:0}strong,b{font-weight:600}a,area,button,[role=button],input,label,select,summary,textarea{touch-action:manipulation}a{color:inherit;text-decoration:inherit}ol,ul{list-style:none;margin:0;padding:0}blockquote{margin:0}pre,code,kbd,samp{font-family:var(--vp-font-family-mono)}img,svg,video,canvas,audio,iframe,embed,object{display:block}figure{margin:0}img,video{max-width:100%;height:auto}button,input,optgroup,select,textarea{border:0;padding:0;line-height:inherit;color:inherit}button{padding:0;font-family:inherit;background-color:transparent;background-image:none}button:enabled,[role=button]:enabled{cursor:pointer}button:focus,button:focus-visible{outline:1px dotted;outline:4px auto -webkit-focus-ring-color}button:focus:not(:focus-visible){outline:none!important}input:focus,textarea:focus,select:focus{outline:none}table{border-collapse:collapse}input{background-color:transparent}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:var(--vp-c-text-3)}input::-ms-input-placeholder,textarea::-ms-input-placeholder{color:var(--vp-c-text-3)}input::placeholder,textarea::placeholder{color:var(--vp-c-text-3)}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield}textarea{resize:vertical}select{-webkit-appearance:none}fieldset{margin:0;padding:0}h1,h2,h3,h4,h5,h6,li,p{overflow-wrap:break-word}vite-error-overlay{z-index:9999}.visually-hidden{position:absolute;width:1px;height:1px;white-space:nowrap;clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden}.custom-block{border:1px solid transparent;border-radius:8px;padding:16px 16px 8px;line-height:24px;font-size:var(--vp-custom-block-font-size);color:var(--vp-c-text-2)}.custom-block.info{border-color:var(--vp-custom-block-info-border);color:var(--vp-custom-block-info-text);background-color:var(--vp-custom-block-info-bg)}.custom-block.custom-block th,.custom-block.custom-block blockquote>p{font-size:var(--vp-custom-block-font-size);color:inherit}.custom-block.info code{background-color:var(--vp-custom-block-info-code-bg)}.custom-block.tip{border-color:var(--vp-custom-block-tip-border);color:var(--vp-custom-block-tip-text);background-color:var(--vp-custom-block-tip-bg)}.custom-block.tip code{background-color:var(--vp-custom-block-tip-code-bg)}.custom-block.warning{border-color:var(--vp-custom-block-warning-border);color:var(--vp-custom-block-warning-text);background-color:var(--vp-custom-block-warning-bg)}.custom-block.warning code{background-color:var(--vp-custom-block-warning-code-bg)}.custom-block.danger{border-color:var(--vp-custom-block-danger-border);color:var(--vp-custom-block-danger-text);background-color:var(--vp-custom-block-danger-bg)}.custom-block.danger code{background-color:var(--vp-custom-block-danger-code-bg)}.custom-block.details{border-color:var(--vp-custom-block-details-border);color:var(--vp-custom-block-details-text);background-color:var(--vp-custom-block-details-bg)}.custom-block.details code{background-color:var(--vp-custom-block-details-code-bg)}.custom-block-title{font-weight:600}.custom-block p+p{margin:8px 0}.custom-block.details summary{margin:0 0 8px;font-weight:700;cursor:pointer}.custom-block.details summary+p{margin:8px 0}.custom-block a{color:inherit;font-weight:600}.custom-block a:hover{text-decoration:underline}.custom-block code{font-size:var(--vp-custom-block-code-font-size)}.dark .vp-code-light{display:none}html:not(.dark) .vp-code-dark{display:none}.vp-code-group{margin-top:16px}.vp-code-group .tabs{position:relative;display:flex;margin-right:-24px;margin-left:-24px;padding:0 12px;background-color:var(--vp-code-tab-bg);overflow-x:auto;overflow-y:hidden}.vp-code-group .tabs:after{position:absolute;right:0;bottom:0;left:0;height:1px;background-color:var(--vp-code-tab-divider);content:""}@media (min-width: 640px){.vp-code-group .tabs{margin-right:0;margin-left:0;border-radius:8px 8px 0 0}}.vp-code-group .tabs input{position:absolute;opacity:0;pointer-events:none}.vp-code-group .tabs label{position:relative;display:inline-block;border-bottom:1px solid transparent;padding:0 12px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-code-tab-text-color);white-space:nowrap;cursor:pointer;transition:color .25s}.vp-code-group .tabs label:after{position:absolute;right:8px;bottom:-1px;left:8px;z-index:1;height:1px;content:"";background-color:transparent;transition:background-color .25s}.vp-code-group label:hover{color:var(--vp-code-tab-hover-text-color)}.vp-code-group input:checked+label{color:var(--vp-code-tab-active-text-color)}.vp-code-group input:checked+label:after{background-color:var(--vp-code-tab-active-bar-color)}.vp-code-group div[class*=language-]{display:none;margin-top:0!important;border-top-left-radius:0!important;border-top-right-radius:0!important}.vp-code-group div[class*=language-].active{display:block}.vp-doc h1,.vp-doc h2,.vp-doc h3,.vp-doc h4,.vp-doc h5,.vp-doc h6{position:relative;font-weight:600;outline:none}.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:28px}.vp-doc h2{margin:48px 0 16px;border-top:1px solid var(--vp-c-divider);padding-top:24px;letter-spacing:-.02em;line-height:32px;font-size:24px}.vp-doc h3{margin:32px 0 0;letter-spacing:-.01em;line-height:28px;font-size:20px}.vp-doc .header-anchor{float:left;margin-left:-.87em;padding-right:.23em;font-weight:500;-webkit-user-select:none;user-select:none;opacity:0;transition:color .25s,opacity .25s}.vp-doc .header-anchor:before{content:var(--vp-header-anchor-symbol)}.vp-doc h1:hover .header-anchor,.vp-doc h1 .header-anchor:focus,.vp-doc h2:hover .header-anchor,.vp-doc h2 .header-anchor:focus,.vp-doc h3:hover .header-anchor,.vp-doc h3 .header-anchor:focus,.vp-doc h4:hover .header-anchor,.vp-doc h4 .header-anchor:focus,.vp-doc h5:hover .header-anchor,.vp-doc h5 .header-anchor:focus,.vp-doc h6:hover .header-anchor,.vp-doc h6 .header-anchor:focus{opacity:1}@media (min-width: 768px){.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:32px}}.vp-doc p,.vp-doc summary{margin:16px 0}.vp-doc p{line-height:28px}.vp-doc blockquote{margin:16px 0;border-left:2px solid var(--vp-c-divider);padding-left:16px;transition:border-color .5s}.vp-doc blockquote>p{margin:0;font-size:16px;color:var(--vp-c-text-2);transition:color .5s}.vp-doc a{font-weight:500;color:var(--vp-c-brand);text-decoration-style:dotted;transition:color .25s}.vp-doc a:hover{text-decoration:underline}.vp-doc strong{font-weight:600}.vp-doc ul,.vp-doc ol{padding-left:1.25rem;margin:16px 0}.vp-doc ul{list-style:disc}.vp-doc ol{list-style:decimal}.vp-doc li+li{margin-top:8px}.vp-doc li>ol,.vp-doc li>ul{margin:8px 0 0}.vp-doc table{display:block;border-collapse:collapse;margin:20px 0;overflow-x:auto}.vp-doc tr{border-top:1px solid var(--vp-c-divider);transition:background-color .5s}.vp-doc tr:nth-child(2n){background-color:var(--vp-c-bg-soft)}.vp-doc th,.vp-doc td{border:1px solid var(--vp-c-divider);padding:8px 16px}.vp-doc th{text-align:left;font-size:14px;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-doc td{font-size:14px}.vp-doc hr{margin:16px 0;border:none;border-top:1px solid var(--vp-c-divider)}.vp-doc .custom-block{margin:16px 0}.vp-doc .custom-block p{margin:8px 0;line-height:24px}.vp-doc .custom-block p:first-child{margin:0}.vp-doc .custom-block a{color:inherit;font-weight:600}.vp-doc .custom-block a:hover{text-decoration:underline}.vp-doc .custom-block code{font-size:var(--vp-custom-block-code-font-size);font-weight:700;color:inherit}.vp-doc .custom-block div[class*=language-]{margin:8px 0}.vp-doc .custom-block div[class*=language-] code{font-weight:400;background-color:transparent}.vp-doc :not(pre,h1,h2,h3,h4,h5,h6)>code{font-size:var(--vp-code-font-size)}.vp-doc :not(pre)>code{border-radius:4px;padding:3px 6px;color:var(--vp-c-text-code);background-color:var(--vp-c-mute);transition:color .5s,background-color .5s}.vp-doc h1>code,.vp-doc h2>code,.vp-doc h3>code{font-size:.9em}.vp-doc a>code{color:var(--vp-c-brand);transition:color .25s}.vp-doc a:hover>code{color:var(--vp-c-brand-dark)}.vp-doc div[class*=language-]{position:relative;margin:16px -24px;background-color:var(--vp-code-block-bg);overflow-x:auto;transition:background-color .5s}@media (min-width: 640px){.vp-doc div[class*=language-]{border-radius:8px;margin:16px 0}}@media (max-width: 639px){.vp-doc li div[class*=language-]{border-radius:8px 0 0 8px}}.vp-doc div[class*=language-]+div[class*=language-],.vp-doc div[class$=-api]+div[class*=language-],.vp-doc div[class*=language-]+div[class$=-api]>div[class*=language-]{margin-top:-8px}.vp-doc [class*=language-] pre,.vp-doc [class*=language-] code{direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}.vp-doc [class*=language-] pre{position:relative;z-index:1;margin:0;padding:20px 0;background:transparent;overflow-x:auto}.vp-doc [class*=language-] code{display:block;padding:0 24px;width:fit-content;min-width:100%;line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-block-color);transition:color .5s}.vp-doc [class*=language-] code .highlighted{background-color:var(--vp-code-line-highlight-color);transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .highlighted.error{background-color:var(--vp-code-line-error-color)}.vp-doc [class*=language-] code .highlighted.warning{background-color:var(--vp-code-line-warning-color)}.vp-doc [class*=language-] code .diff{transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .diff:before{position:absolute;left:10px}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){filter:blur(.095rem);opacity:.4;transition:filter .35s,opacity .35s}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){opacity:.7;transition:filter .35s,opacity .35s}.vp-doc [class*=language-]:hover .has-focused-lines .line:not(.has-focus){filter:blur(0);opacity:1}.vp-doc [class*=language-] code .diff.remove{background-color:var(--vp-code-line-diff-remove-color);opacity:.7}.vp-doc [class*=language-] code .diff.remove:before{content:"-";color:var(--vp-code-line-diff-remove-symbol-color)}.vp-doc [class*=language-] code .diff.add{background-color:var(--vp-code-line-diff-add-color)}.vp-doc [class*=language-] code .diff.add:before{content:"+";color:var(--vp-code-line-diff-add-symbol-color)}.vp-doc div[class*=language-].line-numbers-mode{padding-left:32px}.vp-doc .line-numbers-wrapper{position:absolute;top:0;bottom:0;left:0;z-index:3;border-right:1px solid var(--vp-code-block-divider-color);padding-top:20px;width:32px;text-align:center;font-family:var(--vp-font-family-mono);line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-line-number-color);transition:border-color .5s,color .5s}.vp-doc [class*=language-]>button.copy{direction:ltr;position:absolute;top:12px;right:12px;z-index:3;border:1px solid var(--vp-code-copy-code-border-color);border-radius:4px;width:40px;height:40px;background-color:var(--vp-code-copy-code-bg);opacity:0;cursor:pointer;background-image:var(--vp-icon-copy);background-position:50%;background-size:20px;background-repeat:no-repeat;transition:border-color .25s,background-color .25s,opacity .25s}.vp-doc [class*=language-]:hover>button.copy,.vp-doc [class*=language-]>button.copy:focus{opacity:1}.vp-doc [class*=language-]>button.copy:hover,.vp-doc [class*=language-]>button.copy.copied{border-color:var(--vp-code-copy-code-hover-border-color);background-color:var(--vp-code-copy-code-hover-bg)}.vp-doc [class*=language-]>button.copy.copied,.vp-doc [class*=language-]>button.copy:hover.copied{border-radius:0 4px 4px 0;background-color:var(--vp-code-copy-code-hover-bg);background-image:var(--vp-icon-copied)}.vp-doc [class*=language-]>button.copy.copied:before,.vp-doc [class*=language-]>button.copy:hover.copied:before{position:relative;top:-1px;left:-65px;display:flex;justify-content:center;align-items:center;border:1px solid var(--vp-code-copy-code-hover-border-color);border-right:0;border-radius:4px 0 0 4px;width:64px;height:40px;text-align:center;font-size:12px;font-weight:500;color:var(--vp-code-copy-code-active-text);background-color:var(--vp-code-copy-code-hover-bg);white-space:nowrap;content:"Copied"}.vp-doc [class*=language-]>span.lang{position:absolute;top:2px;right:8px;z-index:2;font-size:12px;font-weight:500;color:var(--vp-c-code-dimm);transition:color .4s,opacity .4s}.vp-doc [class*=language-]:hover>button.copy+span.lang,.vp-doc [class*=language-]>button.copy:focus+span.lang{opacity:0}.vp-doc .VPTeamMembers{margin-top:24px}.vp-doc .VPTeamMembers.small.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}.vp-doc .VPTeamMembers.small.count-2 .container,.vp-doc .VPTeamMembers.small.count-3 .container{max-width:100%!important}.vp-doc .VPTeamMembers.medium.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}.vp-sponsor{border-radius:16px;overflow:hidden}.vp-sponsor.aside{border-radius:12px}.vp-sponsor-section+.vp-sponsor-section{margin-top:4px}.vp-sponsor-tier{margin-bottom:4px;text-align:center;letter-spacing:1px;line-height:24px;width:100%;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-sponsor.normal .vp-sponsor-tier{padding:13px 0 11px;font-size:14px}.vp-sponsor.aside .vp-sponsor-tier{padding:9px 0 7px;font-size:12px}.vp-sponsor-grid+.vp-sponsor-tier{margin-top:4px}.vp-sponsor-grid{display:flex;flex-wrap:wrap;gap:4px}.vp-sponsor-grid.xmini .vp-sponsor-grid-link{height:64px}.vp-sponsor-grid.xmini .vp-sponsor-grid-image{max-width:64px;max-height:22px}.vp-sponsor-grid.mini .vp-sponsor-grid-link{height:72px}.vp-sponsor-grid.mini .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.small .vp-sponsor-grid-link{height:96px}.vp-sponsor-grid.small .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.medium .vp-sponsor-grid-link{height:112px}.vp-sponsor-grid.medium .vp-sponsor-grid-image{max-width:120px;max-height:36px}.vp-sponsor-grid.big .vp-sponsor-grid-link{height:184px}.vp-sponsor-grid.big .vp-sponsor-grid-image{max-width:192px;max-height:56px}.vp-sponsor-grid[data-vp-grid="2"] .vp-sponsor-grid-item{width:calc((100% - 4px)/2)}.vp-sponsor-grid[data-vp-grid="3"] .vp-sponsor-grid-item{width:calc((100% - 4px * 2) / 3)}.vp-sponsor-grid[data-vp-grid="4"] .vp-sponsor-grid-item{width:calc((100% - 12px)/4)}.vp-sponsor-grid[data-vp-grid="5"] .vp-sponsor-grid-item{width:calc((100% - 16px)/5)}.vp-sponsor-grid[data-vp-grid="6"] .vp-sponsor-grid-item{width:calc((100% - 4px * 5) / 6)}.vp-sponsor-grid-item{flex-shrink:0;width:100%;background-color:var(--vp-c-bg-soft);transition:background-color .25s}.vp-sponsor-grid-item:hover{background-color:var(--vp-c-bg-soft-down)}.vp-sponsor-grid-item:hover .vp-sponsor-grid-image{filter:grayscale(0) invert(0)}.vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.dark .vp-sponsor-grid-item:hover{background-color:var(--vp-c-white)}.dark .vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.vp-sponsor-grid-link{display:flex}.vp-sponsor-grid-box{display:flex;justify-content:center;align-items:center;width:100%}.vp-sponsor-grid-image{max-width:100%;filter:grayscale(1);transition:filter .25s}.dark .vp-sponsor-grid-image{filter:grayscale(1) invert(1)}.VPBadge[data-v-350d3852]{display:inline-block;margin-left:2px;border:1px solid transparent;border-radius:10px;padding:0 8px;line-height:18px;font-size:12px;font-weight:600;transform:translateY(-2px)}h1 .VPBadge[data-v-350d3852],h2 .VPBadge[data-v-350d3852],h3 .VPBadge[data-v-350d3852],h4 .VPBadge[data-v-350d3852],h5 .VPBadge[data-v-350d3852],h6 .VPBadge[data-v-350d3852]{vertical-align:top}h2 .VPBadge[data-v-350d3852]{border-radius:11px;line-height:20px}.VPBadge.info[data-v-350d3852]{border-color:var(--vp-badge-info-border);color:var(--vp-badge-info-text);background-color:var(--vp-badge-info-bg)}.VPBadge.tip[data-v-350d3852]{border-color:var(--vp-badge-tip-border);color:var(--vp-badge-tip-text);background-color:var(--vp-badge-tip-bg)}.VPBadge.warning[data-v-350d3852]{border-color:var(--vp-badge-warning-border);color:var(--vp-badge-warning-text);background-color:var(--vp-badge-warning-bg)}.VPBadge.danger[data-v-350d3852]{border-color:var(--vp-badge-danger-border);color:var(--vp-badge-danger-text);background-color:var(--vp-badge-danger-bg)}.VPSkipLink[data-v-b8b11faa]{top:8px;left:8px;padding:8px 16px;z-index:999;border-radius:8px;font-size:12px;font-weight:700;text-decoration:none;color:var(--vp-c-brand);box-shadow:var(--vp-shadow-3);background-color:var(--vp-c-bg)}.VPSkipLink[data-v-b8b11faa]:focus{height:auto;width:auto;clip:auto;clip-path:none}@media (min-width: 1280px){.VPSkipLink[data-v-b8b11faa]{top:14px;left:16px}}.VPBackdrop[data-v-c79a1216]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--vp-z-index-backdrop);background:var(--vp-backdrop-bg-color);transition:opacity .5s}.VPBackdrop.fade-enter-from[data-v-c79a1216],.VPBackdrop.fade-leave-to[data-v-c79a1216]{opacity:0}.VPBackdrop.fade-leave-active[data-v-c79a1216]{transition-duration:.25s}@media (min-width: 1280px){.VPBackdrop[data-v-c79a1216]{display:none}}html:not(.dark) .VPImage.dark[data-v-6db2186b]{display:none}.dark .VPImage.light[data-v-6db2186b]{display:none}.title[data-v-4d981103]{display:flex;align-items:center;border-bottom:1px solid transparent;width:100%;height:var(--vp-nav-height);font-size:16px;font-weight:600;color:var(--vp-c-text-1);transition:opacity .25s}@media (min-width: 960px){.title[data-v-4d981103]{flex-shrink:0}.VPNavBarTitle.has-sidebar .title[data-v-4d981103]{border-bottom-color:var(--vp-c-divider)}}[data-v-4d981103] .logo{margin-right:8px;height:24px}/*! @docsearch/css 3.6.1 | MIT License | © Algolia, Inc. and contributors | https://docsearch.algolia.com */:root{--docsearch-primary-color:#5468ff;--docsearch-text-color:#1c1e21;--docsearch-spacing:12px;--docsearch-icon-stroke-width:1.4;--docsearch-highlight-color:var(--docsearch-primary-color);--docsearch-muted-color:#969faf;--docsearch-container-background:rgba(101,108,133,.8);--docsearch-logo-color:#5468ff;--docsearch-modal-width:560px;--docsearch-modal-height:600px;--docsearch-modal-background:#f5f6f7;--docsearch-modal-shadow:inset 1px 1px 0 0 hsla(0,0%,100%,.5),0 3px 8px 0 #555a64;--docsearch-searchbox-height:56px;--docsearch-searchbox-background:#ebedf0;--docsearch-searchbox-focus-background:#fff;--docsearch-searchbox-shadow:inset 0 0 0 2px var(--docsearch-primary-color);--docsearch-hit-height:56px;--docsearch-hit-color:#444950;--docsearch-hit-active-color:#fff;--docsearch-hit-background:#fff;--docsearch-hit-shadow:0 1px 3px 0 #d4d9e1;--docsearch-key-gradient:linear-gradient(-225deg,#d5dbe4,#f8f8f8);--docsearch-key-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 1px 0 rgba(30,35,90,.4);--docsearch-footer-height:44px;--docsearch-footer-background:#fff;--docsearch-footer-shadow:0 -1px 0 0 #e0e3e8,0 -3px 6px 0 rgba(69,98,155,.12)}html[data-theme=dark]{--docsearch-text-color:#f5f6f7;--docsearch-container-background:rgba(9,10,17,.8);--docsearch-modal-background:#15172a;--docsearch-modal-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--docsearch-searchbox-background:#090a11;--docsearch-searchbox-focus-background:#000;--docsearch-hit-color:#bec3c9;--docsearch-hit-shadow:none;--docsearch-hit-background:#090a11;--docsearch-key-gradient:linear-gradient(-26.5deg,#565872,#31355b);--docsearch-key-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 2px 2px 0 rgba(3,4,9,.3);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 1px 1px 0 rgba(3,4,9,.30196078431372547);--docsearch-footer-background:#1e2136;--docsearch-footer-shadow:inset 0 1px 0 0 rgba(73,76,106,.5),0 -4px 8px 0 rgba(0,0,0,.2);--docsearch-logo-color:#fff;--docsearch-muted-color:#7f8497}.DocSearch-Button{align-items:center;background:var(--docsearch-searchbox-background);border:0;border-radius:40px;color:var(--docsearch-muted-color);cursor:pointer;display:flex;font-weight:500;height:36px;justify-content:space-between;margin:0 0 0 16px;padding:0 8px;-webkit-user-select:none;user-select:none}.DocSearch-Button:active,.DocSearch-Button:focus,.DocSearch-Button:hover{background:var(--docsearch-searchbox-focus-background);box-shadow:var(--docsearch-searchbox-shadow);color:var(--docsearch-text-color);outline:none}.DocSearch-Button-Container{align-items:center;display:flex}.DocSearch-Search-Icon{stroke-width:1.6}.DocSearch-Button .DocSearch-Search-Icon{color:var(--docsearch-text-color)}.DocSearch-Button-Placeholder{font-size:1rem;padding:0 12px 0 6px}.DocSearch-Button-Keys{display:flex;min-width:calc(40px + .8em)}.DocSearch-Button-Key{align-items:center;background:var(--docsearch-key-gradient);border-radius:3px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;position:relative;padding:0 0 2px;border:0;top:-1px;width:20px}.DocSearch-Button-Key--pressed{transform:translate3d(0,1px,0);box-shadow:var(--docsearch-key-pressed-shadow)}@media (max-width:768px){.DocSearch-Button-Keys,.DocSearch-Button-Placeholder{display:none}}.DocSearch--active{overflow:hidden!important}.DocSearch-Container,.DocSearch-Container *{box-sizing:border-box}.DocSearch-Container{background-color:var(--docsearch-container-background);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:200}.DocSearch-Container a{text-decoration:none}.DocSearch-Link{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;font:inherit;margin:0;padding:0}.DocSearch-Modal{background:var(--docsearch-modal-background);border-radius:6px;box-shadow:var(--docsearch-modal-shadow);flex-direction:column;margin:60px auto auto;max-width:var(--docsearch-modal-width);position:relative}.DocSearch-SearchBar{display:flex;padding:var(--docsearch-spacing) var(--docsearch-spacing) 0}.DocSearch-Form{align-items:center;background:var(--docsearch-searchbox-focus-background);border-radius:4px;box-shadow:var(--docsearch-searchbox-shadow);display:flex;height:var(--docsearch-searchbox-height);margin:0;padding:0 var(--docsearch-spacing);position:relative;width:100%}.DocSearch-Input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;color:var(--docsearch-text-color);flex:1;font:inherit;font-size:1.2em;height:100%;outline:none;padding:0 0 0 8px;width:80%}.DocSearch-Input::placeholder{color:var(--docsearch-muted-color);opacity:1}.DocSearch-Input::-webkit-search-cancel-button,.DocSearch-Input::-webkit-search-decoration,.DocSearch-Input::-webkit-search-results-button,.DocSearch-Input::-webkit-search-results-decoration{display:none}.DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{margin:0;padding:0}.DocSearch-MagnifierLabel,.DocSearch-Reset{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}.DocSearch-Container--Stalled .DocSearch-MagnifierLabel,.DocSearch-LoadingIndicator{display:none}.DocSearch-Container--Stalled .DocSearch-LoadingIndicator{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Reset{animation:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;right:0;stroke-width:var(--docsearch-icon-stroke-width)}}.DocSearch-Reset{animation:fade-in .1s ease-in forwards;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;padding:2px;right:0;stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Reset[hidden]{display:none}.DocSearch-Reset:hover{color:var(--docsearch-highlight-color)}.DocSearch-LoadingIndicator svg,.DocSearch-MagnifierLabel svg{height:24px;width:24px}.DocSearch-Cancel{display:none}.DocSearch-Dropdown{max-height:calc(var(--docsearch-modal-height) - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height));min-height:var(--docsearch-spacing);overflow-y:auto;overflow-y:overlay;padding:0 var(--docsearch-spacing);scrollbar-color:var(--docsearch-muted-color) var(--docsearch-modal-background);scrollbar-width:thin}.DocSearch-Dropdown::-webkit-scrollbar{width:12px}.DocSearch-Dropdown::-webkit-scrollbar-track{background:transparent}.DocSearch-Dropdown::-webkit-scrollbar-thumb{background-color:var(--docsearch-muted-color);border:3px solid var(--docsearch-modal-background);border-radius:20px}.DocSearch-Dropdown ul{list-style:none;margin:0;padding:0}.DocSearch-Label{font-size:.75em;line-height:1.6em}.DocSearch-Help,.DocSearch-Label{color:var(--docsearch-muted-color)}.DocSearch-Help{font-size:.9em;margin:0;-webkit-user-select:none;user-select:none}.DocSearch-Title{font-size:1.2em}.DocSearch-Logo a{display:flex}.DocSearch-Logo svg{color:var(--docsearch-logo-color);margin-left:8px}.DocSearch-Hits:last-of-type{margin-bottom:24px}.DocSearch-Hits mark{background:none;color:var(--docsearch-highlight-color)}.DocSearch-HitsFooter{color:var(--docsearch-muted-color);display:flex;font-size:.85em;justify-content:center;margin-bottom:var(--docsearch-spacing);padding:var(--docsearch-spacing)}.DocSearch-HitsFooter a{border-bottom:1px solid;color:inherit}.DocSearch-Hit{border-radius:4px;display:flex;padding-bottom:4px;position:relative}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--deleting{transition:none}}.DocSearch-Hit--deleting{opacity:0;transition:all .25s linear}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--favoriting{transition:none}}.DocSearch-Hit--favoriting{transform:scale(0);transform-origin:top center;transition:all .25s linear;transition-delay:.25s}.DocSearch-Hit a{background:var(--docsearch-hit-background);border-radius:4px;box-shadow:var(--docsearch-hit-shadow);display:block;padding-left:var(--docsearch-spacing);width:100%}.DocSearch-Hit-source{background:var(--docsearch-modal-background);color:var(--docsearch-highlight-color);font-size:.85em;font-weight:600;line-height:32px;margin:0 -4px;padding:8px 4px 0;position:sticky;top:0;z-index:10}.DocSearch-Hit-Tree{color:var(--docsearch-muted-color);height:var(--docsearch-hit-height);opacity:.5;stroke-width:var(--docsearch-icon-stroke-width);width:24px}.DocSearch-Hit[aria-selected=true] a{background-color:var(--docsearch-highlight-color)}.DocSearch-Hit[aria-selected=true] mark{text-decoration:underline}.DocSearch-Hit-Container{align-items:center;color:var(--docsearch-hit-color);display:flex;flex-direction:row;height:var(--docsearch-hit-height);padding:0 var(--docsearch-spacing) 0 0}.DocSearch-Hit-icon{height:20px;width:20px}.DocSearch-Hit-action,.DocSearch-Hit-icon{color:var(--docsearch-muted-color);stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Hit-action{align-items:center;display:flex;height:22px;width:22px}.DocSearch-Hit-action svg{display:block;height:18px;width:18px}.DocSearch-Hit-action+.DocSearch-Hit-action{margin-left:6px}.DocSearch-Hit-action-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:inherit;cursor:pointer;padding:2px}svg.DocSearch-Hit-Select-Icon{display:none}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Select-Icon{display:block}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:rgba(0,0,0,.2);transition:background-color .1s ease-in}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{transition:none}}.DocSearch-Hit-action-button:focus path,.DocSearch-Hit-action-button:hover path{fill:#fff}.DocSearch-Hit-content-wrapper{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;line-height:1.2em;margin:0 8px;overflow-x:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap;width:80%}.DocSearch-Hit-title{font-size:.9em}.DocSearch-Hit-path{color:var(--docsearch-muted-color);font-size:.75em}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-action,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-icon,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-path,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-text,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-title,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Tree,.DocSearch-Hit[aria-selected=true] mark{color:var(--docsearch-hit-active-color)!important}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:rgba(0,0,0,.2);transition:none}}.DocSearch-ErrorScreen,.DocSearch-NoResults,.DocSearch-StartScreen{font-size:.9em;margin:0 auto;padding:36px 0;text-align:center;width:80%}.DocSearch-Screen-Icon{color:var(--docsearch-muted-color);padding-bottom:12px}.DocSearch-NoResults-Prefill-List{display:inline-block;padding-bottom:24px;text-align:left}.DocSearch-NoResults-Prefill-List ul{display:inline-block;padding:8px 0 0}.DocSearch-NoResults-Prefill-List li{list-style-position:inside;list-style-type:"» "}.DocSearch-Prefill{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:1em;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;font-size:1em;font-weight:700;padding:0}.DocSearch-Prefill:focus,.DocSearch-Prefill:hover{outline:none;text-decoration:underline}.DocSearch-Footer{align-items:center;background:var(--docsearch-footer-background);border-radius:0 0 8px 8px;box-shadow:var(--docsearch-footer-shadow);display:flex;flex-direction:row-reverse;flex-shrink:0;height:var(--docsearch-footer-height);justify-content:space-between;padding:0 var(--docsearch-spacing);position:relative;-webkit-user-select:none;user-select:none;width:100%;z-index:300}.DocSearch-Commands{color:var(--docsearch-muted-color);display:flex;list-style:none;margin:0;padding:0}.DocSearch-Commands li{align-items:center;display:flex}.DocSearch-Commands li:not(:last-of-type){margin-right:.8em}.DocSearch-Commands-Key{align-items:center;background:var(--docsearch-key-gradient);border-radius:2px;box-shadow:var(--docsearch-key-shadow);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 1px;color:var(--docsearch-muted-color);border:0;width:20px}.DocSearch-VisuallyHiddenForAccessibility{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}@media (max-width:768px){:root{--docsearch-spacing:10px;--docsearch-footer-height:40px}.DocSearch-Dropdown{height:100%}.DocSearch-Container{height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);position:absolute}.DocSearch-Footer{border-radius:0;bottom:0;position:absolute}.DocSearch-Hit-content-wrapper{display:flex;position:relative;width:80%}.DocSearch-Modal{border-radius:0;box-shadow:none;height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);margin:0;max-width:100%;width:100%}.DocSearch-Dropdown{max-height:calc(var(--docsearch-vh, 1vh)*100 - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height))}.DocSearch-Cancel{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;flex:none;font:inherit;font-size:1em;font-weight:500;margin-left:var(--docsearch-spacing);outline:none;overflow:hidden;padding:0;-webkit-user-select:none;user-select:none;white-space:nowrap}.DocSearch-Commands,.DocSearch-Hit-Tree{display:none}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}.DocSearch{--docsearch-primary-color: var(--vp-c-brand);--docsearch-highlight-color: var(--docsearch-primary-color);--docsearch-text-color: var(--vp-c-text-1);--docsearch-muted-color: var(--vp-c-text-2);--docsearch-searchbox-shadow: none;--docsearch-searchbox-focus-background: transparent;--docsearch-key-gradient: transparent;--docsearch-key-shadow: none;--docsearch-modal-background: var(--vp-c-bg-soft);--docsearch-footer-background: var(--vp-c-bg)}.dark .DocSearch{--docsearch-modal-shadow: none;--docsearch-footer-shadow: none;--docsearch-logo-color: var(--vp-c-text-2);--docsearch-hit-background: var(--vp-c-bg-soft-mute);--docsearch-hit-color: var(--vp-c-text-2);--docsearch-hit-shadow: none}.DocSearch-Button{display:flex;justify-content:center;align-items:center;margin:0;padding:0;width:48px;height:55px;background:transparent;transition:border-color .25s}.DocSearch-Button:hover{background:transparent}.DocSearch-Button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.DocSearch-Button:focus:not(:focus-visible){outline:none!important}@media (min-width: 768px){.DocSearch-Button{justify-content:flex-start;border:1px solid transparent;border-radius:8px;padding:0 10px 0 12px;width:100%;height:40px;background-color:var(--vp-c-bg-alt)}.DocSearch-Button:hover{border-color:var(--vp-c-brand);background:var(--vp-c-bg-alt)}}.DocSearch-Button .DocSearch-Button-Container{display:flex;align-items:center}.DocSearch-Button .DocSearch-Search-Icon{position:relative;width:16px;height:16px;color:var(--vp-c-text-1);fill:currentColor;transition:color .5s}.DocSearch-Button:hover .DocSearch-Search-Icon{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Search-Icon{top:1px;margin-right:8px;width:14px;height:14px;color:var(--vp-c-text-2)}}.DocSearch-Button .DocSearch-Button-Placeholder{display:none;margin-top:2px;padding:0 16px 0 0;font-size:13px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.DocSearch-Button:hover .DocSearch-Button-Placeholder{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Placeholder{display:inline-block}}.DocSearch-Button .DocSearch-Button-Keys{direction:ltr;display:none;min-width:auto}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Keys{display:flex;align-items:center}}.DocSearch-Button .DocSearch-Button-Key{display:block;margin:2px 0 0;border:1px solid var(--vp-c-divider);border-right:none;border-radius:4px 0 0 4px;padding-left:6px;min-width:0;width:auto;height:22px;line-height:22px;font-family:var(--vp-font-family-base);font-size:12px;font-weight:500;transition:color .5s,border-color .5s}.DocSearch-Button .DocSearch-Button-Key+.DocSearch-Button-Key{border-right:1px solid var(--vp-c-divider);border-left:none;border-radius:0 4px 4px 0;padding-left:2px;padding-right:6px}.DocSearch-Button .DocSearch-Button-Key:first-child{font-size:1px;letter-spacing:-12px;color:transparent}.DocSearch-Button .DocSearch-Button-Key:first-child:after{content:var(--vp-meta-key);font-size:12px;letter-spacing:normal;color:var(--docsearch-muted-color)}.DocSearch-Button .DocSearch-Button-Key:first-child>*{display:none}.VPNavBarSearch{display:flex;align-items:center}@media (min-width: 768px){.VPNavBarSearch{flex-grow:1;padding-left:24px}}@media (min-width: 960px){.VPNavBarSearch{padding-left:32px}}.dark .DocSearch-Footer{border-top:1px solid var(--vp-c-divider)}.DocSearch-Form{border:1px solid var(--vp-c-brand);background-color:var(--vp-c-white)}.dark .DocSearch-Form{background-color:var(--vp-c-bg-soft-mute)}.DocSearch-Screen-Icon>svg{margin:auto}.icon[data-v-8f4dc553]{display:inline-block;margin-top:-1px;margin-left:4px;width:11px;height:11px;fill:var(--vp-c-text-3);transition:fill .25s;flex-shrink:0}.VPNavBarMenuLink[data-v-5e623618]{display:flex;align-items:center;padding:0 12px;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.VPNavBarMenuLink.active[data-v-5e623618],.VPNavBarMenuLink[data-v-5e623618]:hover{color:var(--vp-c-brand)}.VPMenuGroup+.VPMenuLink[data-v-2f2cfafc]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.link[data-v-2f2cfafc]{display:block;border-radius:6px;padding:0 12px;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);white-space:nowrap;transition:background-color .25s,color .25s}.link[data-v-2f2cfafc]:hover{color:var(--vp-c-brand);background-color:var(--vp-c-bg-elv-mute)}.link.active[data-v-2f2cfafc]{color:var(--vp-c-brand)}.VPMenuGroup[data-v-69e747b5]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.VPMenuGroup[data-v-69e747b5]:first-child{margin-top:0;border-top:0;padding-top:0}.VPMenuGroup+.VPMenuGroup[data-v-69e747b5]{margin-top:12px;border-top:1px solid var(--vp-c-divider)}.title[data-v-69e747b5]{padding:0 12px;line-height:32px;font-size:14px;font-weight:600;color:var(--vp-c-text-2);white-space:nowrap;transition:color .25s}.VPMenu[data-v-e7ea1737]{border-radius:12px;padding:12px;min-width:128px;border:1px solid var(--vp-c-divider);background-color:var(--vp-c-bg-elv);box-shadow:var(--vp-shadow-3);transition:background-color .5s;max-height:calc(100vh - var(--vp-nav-height));overflow-y:auto}.VPMenu[data-v-e7ea1737] .group{margin:0 -12px;padding:0 12px 12px}.VPMenu[data-v-e7ea1737] .group+.group{border-top:1px solid var(--vp-c-divider);padding:11px 12px 12px}.VPMenu[data-v-e7ea1737] .group:last-child{padding-bottom:0}.VPMenu[data-v-e7ea1737] .group+.item{border-top:1px solid var(--vp-c-divider);padding:11px 16px 0}.VPMenu[data-v-e7ea1737] .item{padding:0 16px;white-space:nowrap}.VPMenu[data-v-e7ea1737] .label{flex-grow:1;line-height:28px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.VPMenu[data-v-e7ea1737] .action{padding-left:24px}.VPFlyout[data-v-764effdf]{position:relative}.VPFlyout[data-v-764effdf]:hover{color:var(--vp-c-brand);transition:color .25s}.VPFlyout:hover .text[data-v-764effdf]{color:var(--vp-c-text-2)}.VPFlyout:hover .icon[data-v-764effdf]{fill:var(--vp-c-text-2)}.VPFlyout.active .text[data-v-764effdf]{color:var(--vp-c-brand)}.VPFlyout.active:hover .text[data-v-764effdf]{color:var(--vp-c-brand-dark)}.VPFlyout:hover .menu[data-v-764effdf],.button[aria-expanded=true]+.menu[data-v-764effdf]{opacity:1;visibility:visible;transform:translateY(0)}.button[data-v-764effdf]{display:flex;align-items:center;padding:0 12px;height:var(--vp-nav-height);color:var(--vp-c-text-1);transition:color .5s}.text[data-v-764effdf]{display:flex;align-items:center;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.option-icon[data-v-764effdf]{margin-right:0;width:16px;height:16px;fill:currentColor}.text-icon[data-v-764effdf]{margin-left:4px;width:14px;height:14px;fill:currentColor}.icon[data-v-764effdf]{width:20px;height:20px;fill:currentColor;transition:fill .25s}.menu[data-v-764effdf]{position:absolute;top:calc(var(--vp-nav-height) / 2 + 20px);right:0;opacity:0;visibility:hidden;transition:opacity .25s,visibility .25s,transform .25s}.VPNavBarMenu[data-v-7f418b0f]{display:none}@media (min-width: 768px){.VPNavBarMenu[data-v-7f418b0f]{display:flex}}.VPNavBarTranslations[data-v-74abcbb9]{display:none}@media (min-width: 1280px){.VPNavBarTranslations[data-v-74abcbb9]{display:flex;align-items:center}}.title[data-v-74abcbb9]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.VPSwitch[data-v-f3c41672]{position:relative;border-radius:11px;display:block;width:40px;height:22px;flex-shrink:0;border:1px solid var(--vp-input-border-color);background-color:var(--vp-input-switch-bg-color);transition:border-color .25s}.VPSwitch[data-v-f3c41672]:hover{border-color:var(--vp-input-hover-border-color)}.check[data-v-f3c41672]{position:absolute;top:1px;left:1px;width:18px;height:18px;border-radius:50%;background-color:var(--vp-c-neutral-inverse);box-shadow:var(--vp-shadow-1);transition:transform .25s}.icon[data-v-f3c41672]{position:relative;display:block;width:18px;height:18px;border-radius:50%;overflow:hidden}.icon[data-v-f3c41672] svg{position:absolute;top:3px;left:3px;width:12px;height:12px;fill:var(--vp-c-text-2)}.dark .icon[data-v-f3c41672] svg{fill:var(--vp-c-text-1);transition:opacity .25s}.sun[data-v-82b282f1]{opacity:1}.moon[data-v-82b282f1],.dark .sun[data-v-82b282f1]{opacity:0}.dark .moon[data-v-82b282f1]{opacity:1}.dark .VPSwitchAppearance[data-v-82b282f1] .check{transform:translate(18px)}.VPNavBarAppearance[data-v-f6a63727]{display:none}@media (min-width: 1280px){.VPNavBarAppearance[data-v-f6a63727]{display:flex;align-items:center}}.VPSocialLink[data-v-36371990]{display:flex;justify-content:center;align-items:center;width:36px;height:36px;color:var(--vp-c-text-2);transition:color .5s}.VPSocialLink[data-v-36371990]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPSocialLink[data-v-36371990]>svg{width:20px;height:20px;fill:currentColor}.VPSocialLinks[data-v-7bc22406]{display:flex;justify-content:center}.VPNavBarSocialLinks[data-v-0394ad82]{display:none}@media (min-width: 1280px){.VPNavBarSocialLinks[data-v-0394ad82]{display:flex;align-items:center}}.VPNavBarExtra[data-v-40855f84]{display:none;margin-right:-12px}@media (min-width: 768px){.VPNavBarExtra[data-v-40855f84]{display:block}}@media (min-width: 1280px){.VPNavBarExtra[data-v-40855f84]{display:none}}.trans-title[data-v-40855f84]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.item.appearance[data-v-40855f84],.item.social-links[data-v-40855f84]{display:flex;align-items:center;padding:0 12px}.item.appearance[data-v-40855f84]{min-width:176px}.appearance-action[data-v-40855f84]{margin-right:-2px}.social-links-list[data-v-40855f84]{margin:-4px -8px}.VPNavBarHamburger[data-v-e5dd9c1c]{display:flex;justify-content:center;align-items:center;width:48px;height:var(--vp-nav-height)}@media (min-width: 768px){.VPNavBarHamburger[data-v-e5dd9c1c]{display:none}}.container[data-v-e5dd9c1c]{position:relative;width:16px;height:14px;overflow:hidden}.VPNavBarHamburger:hover .top[data-v-e5dd9c1c]{top:0;left:0;transform:translate(4px)}.VPNavBarHamburger:hover .middle[data-v-e5dd9c1c]{top:6px;left:0;transform:translate(0)}.VPNavBarHamburger:hover .bottom[data-v-e5dd9c1c]{top:12px;left:0;transform:translate(8px)}.VPNavBarHamburger.active .top[data-v-e5dd9c1c]{top:6px;transform:translate(0) rotate(225deg)}.VPNavBarHamburger.active .middle[data-v-e5dd9c1c]{top:6px;transform:translate(16px)}.VPNavBarHamburger.active .bottom[data-v-e5dd9c1c]{top:6px;transform:translate(0) rotate(135deg)}.VPNavBarHamburger.active:hover .top[data-v-e5dd9c1c],.VPNavBarHamburger.active:hover .middle[data-v-e5dd9c1c],.VPNavBarHamburger.active:hover .bottom[data-v-e5dd9c1c]{background-color:var(--vp-c-text-2);transition:top .25s,background-color .25s,transform .25s}.top[data-v-e5dd9c1c],.middle[data-v-e5dd9c1c],.bottom[data-v-e5dd9c1c]{position:absolute;width:16px;height:2px;background-color:var(--vp-c-text-1);transition:top .25s,background-color .5s,transform .25s}.top[data-v-e5dd9c1c]{top:0;left:0;transform:translate(0)}.middle[data-v-e5dd9c1c]{top:6px;left:0;transform:translate(8px)}.bottom[data-v-e5dd9c1c]{top:12px;left:0;transform:translate(4px)}.VPNavBar[data-v-7683ced7]{position:relative;border-bottom:1px solid transparent;padding:0 8px 0 24px;height:var(--vp-nav-height);pointer-events:none;white-space:nowrap}@media (min-width: 768px){.VPNavBar[data-v-7683ced7]{padding:0 32px}}@media (min-width: 960px){.VPNavBar.has-sidebar[data-v-7683ced7]{padding:0}.VPNavBar.fill[data-v-7683ced7]:not(.has-sidebar){border-bottom-color:var(--vp-c-gutter);background-color:var(--vp-nav-bg-color)}}.container[data-v-7683ced7]{display:flex;justify-content:space-between;margin:0 auto;max-width:calc(var(--vp-layout-max-width) - 64px);height:var(--vp-nav-height);pointer-events:none}.container>.title[data-v-7683ced7],.container>.content[data-v-7683ced7]{pointer-events:none}.container[data-v-7683ced7] *{pointer-events:auto}@media (min-width: 960px){.VPNavBar.has-sidebar .container[data-v-7683ced7]{max-width:100%}}.title[data-v-7683ced7]{flex-shrink:0;height:calc(var(--vp-nav-height) - 1px);transition:background-color .5s}@media (min-width: 960px){.VPNavBar.has-sidebar .title[data-v-7683ced7]{position:absolute;top:0;left:0;z-index:2;padding:0 32px;width:var(--vp-sidebar-width);height:var(--vp-nav-height);background-color:transparent}}@media (min-width: 1440px){.VPNavBar.has-sidebar .title[data-v-7683ced7]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}.content[data-v-7683ced7]{flex-grow:1}@media (min-width: 960px){.VPNavBar.has-sidebar .content[data-v-7683ced7]{position:relative;z-index:1;padding-right:32px;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .content[data-v-7683ced7]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2 + 32px);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.content-body[data-v-7683ced7]{display:flex;justify-content:flex-end;align-items:center;height:calc(var(--vp-nav-height) - 1px);transition:background-color .5s}@media (min-width: 960px){.VPNavBar.has-sidebar .content-body[data-v-7683ced7],.VPNavBar.fill .content-body[data-v-7683ced7]{position:relative;background-color:var(--vp-nav-bg-color)}}@media (max-width: 768px){.content-body[data-v-7683ced7]{column-gap:.5rem}}.menu+.translations[data-v-7683ced7]:before,.menu+.appearance[data-v-7683ced7]:before,.menu+.social-links[data-v-7683ced7]:before,.translations+.appearance[data-v-7683ced7]:before,.appearance+.social-links[data-v-7683ced7]:before{margin-right:8px;margin-left:8px;width:1px;height:24px;background-color:var(--vp-c-divider);content:""}.menu+.appearance[data-v-7683ced7]:before,.translations+.appearance[data-v-7683ced7]:before{margin-right:16px}.appearance+.social-links[data-v-7683ced7]:before{margin-left:16px}.social-links[data-v-7683ced7]{margin-right:-8px}@media (min-width: 960px){.VPNavBar.has-sidebar .curtain[data-v-7683ced7]{position:absolute;right:0;bottom:-31px;width:calc(100% - var(--vp-sidebar-width));height:32px}.VPNavBar.has-sidebar .curtain[data-v-7683ced7]:before{display:block;width:100%;height:32px;background:linear-gradient(var(--vp-c-bg),transparent 70%);content:""}}@media (min-width: 1440px){.VPNavBar.has-sidebar .curtain[data-v-7683ced7]{width:calc(100% - ((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width)))}}.VPNavScreenMenuLink[data-v-30be0acb]{display:block;border-bottom:1px solid var(--vp-c-divider);padding:12px 0 11px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:border-color .25s,color .25s}.VPNavScreenMenuLink[data-v-30be0acb]:hover{color:var(--vp-c-brand)}.VPNavScreenMenuGroupLink[data-v-6656c42a]{display:block;margin-left:12px;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-1);transition:color .25s}.VPNavScreenMenuGroupLink[data-v-6656c42a]:hover{color:var(--vp-c-brand)}.VPNavScreenMenuGroupSection[data-v-8133b170]{display:block}.title[data-v-8133b170]{line-height:32px;font-size:13px;font-weight:700;color:var(--vp-c-text-2);transition:color .25s}.VPNavScreenMenuGroup[data-v-338a1689]{border-bottom:1px solid var(--vp-c-divider);height:48px;overflow:hidden;transition:border-color .5s}.VPNavScreenMenuGroup .items[data-v-338a1689]{visibility:hidden}.VPNavScreenMenuGroup.open .items[data-v-338a1689]{visibility:visible}.VPNavScreenMenuGroup.open[data-v-338a1689]{padding-bottom:10px;height:auto}.VPNavScreenMenuGroup.open .button[data-v-338a1689]{padding-bottom:6px;color:var(--vp-c-brand)}.VPNavScreenMenuGroup.open .button-icon[data-v-338a1689]{transform:rotate(45deg)}.button[data-v-338a1689]{display:flex;justify-content:space-between;align-items:center;padding:12px 4px 11px 0;width:100%;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.button[data-v-338a1689]:hover{color:var(--vp-c-brand)}.button-icon[data-v-338a1689]{width:14px;height:14px;fill:var(--vp-c-text-2);transition:fill .5s,transform .25s}.group[data-v-338a1689]:first-child{padding-top:0}.group+.group[data-v-338a1689],.group+.item[data-v-338a1689]{padding-top:4px}.VPNavScreenAppearance[data-v-add8f686]{display:flex;justify-content:space-between;align-items:center;border-radius:8px;padding:12px 14px 12px 16px;background-color:var(--vp-c-bg-soft)}.text[data-v-add8f686]{line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.VPNavScreenTranslations[data-v-d72aa483]{height:24px;overflow:hidden}.VPNavScreenTranslations.open[data-v-d72aa483]{height:auto}.title[data-v-d72aa483]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-text-1)}.icon[data-v-d72aa483]{width:16px;height:16px;fill:currentColor}.icon.lang[data-v-d72aa483]{margin-right:8px}.icon.chevron[data-v-d72aa483]{margin-left:4px}.list[data-v-d72aa483]{padding:4px 0 0 24px}.link[data-v-d72aa483]{line-height:32px;font-size:13px;color:var(--vp-c-text-1)}.VPNavScreen[data-v-724636ae]{position:fixed;top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 1px);right:0;bottom:0;left:0;padding:0 32px;width:100%;background-color:var(--vp-nav-screen-bg-color);overflow-y:auto;transition:background-color .5s;pointer-events:auto}.VPNavScreen.fade-enter-active[data-v-724636ae],.VPNavScreen.fade-leave-active[data-v-724636ae]{transition:opacity .25s}.VPNavScreen.fade-enter-active .container[data-v-724636ae],.VPNavScreen.fade-leave-active .container[data-v-724636ae]{transition:transform .25s ease}.VPNavScreen.fade-enter-from[data-v-724636ae],.VPNavScreen.fade-leave-to[data-v-724636ae]{opacity:0}.VPNavScreen.fade-enter-from .container[data-v-724636ae],.VPNavScreen.fade-leave-to .container[data-v-724636ae]{transform:translateY(-8px)}@media (min-width: 768px){.VPNavScreen[data-v-724636ae]{display:none}}.container[data-v-724636ae]{margin:0 auto;padding:24px 0 96px;max-width:288px}.menu+.translations[data-v-724636ae],.menu+.appearance[data-v-724636ae],.translations+.appearance[data-v-724636ae]{margin-top:24px}.menu+.social-links[data-v-724636ae]{margin-top:16px}.appearance+.social-links[data-v-724636ae]{margin-top:16px}.VPNav[data-v-7e5bc4a5]{position:relative;top:var(--vp-layout-top-height, 0px);left:0;z-index:var(--vp-z-index-nav);width:100%;pointer-events:none;transition:background-color .5s}@media (min-width: 960px){.VPNav[data-v-7e5bc4a5]{position:fixed}}.root[data-v-9a431c33]{position:relative;z-index:1}.nested[data-v-9a431c33]{padding-left:13px}.outline-link[data-v-9a431c33]{display:block;line-height:28px;color:var(--vp-c-text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .5s;font-weight:500}.outline-link[data-v-9a431c33]:hover,.outline-link.active[data-v-9a431c33]{color:var(--vp-c-text-1);transition:color .25s}.outline-link.nested[data-v-9a431c33]{padding-left:13px}.VPLocalNavOutlineDropdown[data-v-687955bc]{padding:12px 20px 11px}.VPLocalNavOutlineDropdown button[data-v-687955bc]{display:block;font-size:12px;font-weight:500;line-height:24px;color:var(--vp-c-text-2);transition:color .5s;position:relative}.VPLocalNavOutlineDropdown button[data-v-687955bc]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPLocalNavOutlineDropdown button.open[data-v-687955bc]{color:var(--vp-c-text-1)}.icon[data-v-687955bc]{display:inline-block;vertical-align:middle;margin-left:2px;width:14px;height:14px;fill:currentColor}[data-v-687955bc] .outline-link{font-size:14px;padding:2px 0}.open>.icon[data-v-687955bc]{transform:rotate(90deg)}.items[data-v-687955bc]{position:absolute;left:20px;right:20px;top:64px;background-color:var(--vp-local-nav-bg-color);padding:4px 10px 16px;border:1px solid var(--vp-c-divider);border-radius:8px;max-height:calc(var(--vp-vh, 100vh) - 86px);overflow:hidden auto;box-shadow:var(--vp-shadow-3)}.top-link[data-v-687955bc]{display:block;color:var(--vp-c-brand);font-size:13px;font-weight:500;padding:6px 0;margin:0 13px 10px;border-bottom:1px solid var(--vp-c-divider)}.flyout-enter-active[data-v-687955bc]{transition:all .2s ease-out}.flyout-leave-active[data-v-687955bc]{transition:all .15s ease-in}.flyout-enter-from[data-v-687955bc],.flyout-leave-to[data-v-687955bc]{opacity:0;transform:translateY(-16px)}.VPLocalNav[data-v-9074c407]{position:sticky;top:0;left:0;z-index:var(--vp-z-index-local-nav);display:flex;justify-content:space-between;align-items:center;border-top:1px solid var(--vp-c-gutter);border-bottom:1px solid var(--vp-c-gutter);padding-top:var(--vp-layout-top-height, 0px);width:100%;background-color:var(--vp-local-nav-bg-color)}.VPLocalNav.fixed[data-v-9074c407]{position:fixed}.VPLocalNav.reached-top[data-v-9074c407]{border-top-color:transparent}@media (min-width: 960px){.VPLocalNav[data-v-9074c407]{display:none}}.menu[data-v-9074c407]{display:flex;align-items:center;padding:12px 24px 11px;line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.menu[data-v-9074c407]:hover{color:var(--vp-c-text-1);transition:color .25s}@media (min-width: 768px){.menu[data-v-9074c407]{padding:0 32px}}.menu-icon[data-v-9074c407]{margin-right:8px;width:16px;height:16px;fill:currentColor}.VPOutlineDropdown[data-v-9074c407]{padding:12px 24px 11px}@media (min-width: 768px){.VPOutlineDropdown[data-v-9074c407]{padding:12px 32px 11px}}.VPSidebarItem.level-0[data-v-c4656e6d]{padding-bottom:24px}.VPSidebarItem.collapsed.level-0[data-v-c4656e6d]{padding-bottom:10px}.item[data-v-c4656e6d]{position:relative;display:flex;width:100%}.VPSidebarItem.collapsible>.item[data-v-c4656e6d]{cursor:pointer}.indicator[data-v-c4656e6d]{position:absolute;top:6px;bottom:6px;left:-17px;width:1px;transition:background-color .25s}.VPSidebarItem.level-2.is-active>.item>.indicator[data-v-c4656e6d],.VPSidebarItem.level-3.is-active>.item>.indicator[data-v-c4656e6d],.VPSidebarItem.level-4.is-active>.item>.indicator[data-v-c4656e6d],.VPSidebarItem.level-5.is-active>.item>.indicator[data-v-c4656e6d]{background-color:var(--vp-c-brand)}.link[data-v-c4656e6d]{display:flex;align-items:center;flex-grow:1}.text[data-v-c4656e6d]{flex-grow:1;padding:4px 0;line-height:24px;font-size:14px;transition:color .25s}.VPSidebarItem.level-0 .text[data-v-c4656e6d]{font-weight:700;color:var(--vp-c-text-1)}.VPSidebarItem.level-1 .text[data-v-c4656e6d],.VPSidebarItem.level-2 .text[data-v-c4656e6d],.VPSidebarItem.level-3 .text[data-v-c4656e6d],.VPSidebarItem.level-4 .text[data-v-c4656e6d],.VPSidebarItem.level-5 .text[data-v-c4656e6d]{font-weight:500;color:var(--vp-c-text-2)}.VPSidebarItem.level-0.is-link>.item>.link:hover .text[data-v-c4656e6d],.VPSidebarItem.level-1.is-link>.item>.link:hover .text[data-v-c4656e6d],.VPSidebarItem.level-2.is-link>.item>.link:hover .text[data-v-c4656e6d],.VPSidebarItem.level-3.is-link>.item>.link:hover .text[data-v-c4656e6d],.VPSidebarItem.level-4.is-link>.item>.link:hover .text[data-v-c4656e6d],.VPSidebarItem.level-5.is-link>.item>.link:hover .text[data-v-c4656e6d]{color:var(--vp-c-brand)}.VPSidebarItem.level-0.has-active>.item>.link>.text[data-v-c4656e6d],.VPSidebarItem.level-1.has-active>.item>.link>.text[data-v-c4656e6d],.VPSidebarItem.level-2.has-active>.item>.link>.text[data-v-c4656e6d],.VPSidebarItem.level-3.has-active>.item>.link>.text[data-v-c4656e6d],.VPSidebarItem.level-4.has-active>.item>.link>.text[data-v-c4656e6d],.VPSidebarItem.level-5.has-active>.item>.link>.text[data-v-c4656e6d]{color:var(--vp-c-text-1)}.VPSidebarItem.level-0.is-active>.item .link>.text[data-v-c4656e6d],.VPSidebarItem.level-1.is-active>.item .link>.text[data-v-c4656e6d],.VPSidebarItem.level-2.is-active>.item .link>.text[data-v-c4656e6d],.VPSidebarItem.level-3.is-active>.item .link>.text[data-v-c4656e6d],.VPSidebarItem.level-4.is-active>.item .link>.text[data-v-c4656e6d],.VPSidebarItem.level-5.is-active>.item .link>.text[data-v-c4656e6d]{color:var(--vp-c-brand)}.caret[data-v-c4656e6d]{display:flex;justify-content:center;align-items:center;margin-right:-7px;width:32px;height:32px;color:var(--vp-c-text-3);cursor:pointer;transition:color .25s}.item:hover .caret[data-v-c4656e6d]{color:var(--vp-c-text-2)}.item:hover .caret[data-v-c4656e6d]:hover{color:var(--vp-c-text-1)}.caret-icon[data-v-c4656e6d]{width:18px;height:18px;fill:currentColor;transform:rotate(90deg);transition:transform .25s}.VPSidebarItem.collapsed .caret-icon[data-v-c4656e6d]{transform:rotate(0)}.VPSidebarItem.level-1 .items[data-v-c4656e6d],.VPSidebarItem.level-2 .items[data-v-c4656e6d],.VPSidebarItem.level-3 .items[data-v-c4656e6d],.VPSidebarItem.level-4 .items[data-v-c4656e6d],.VPSidebarItem.level-5 .items[data-v-c4656e6d]{border-left:1px solid var(--vp-c-divider);padding-left:16px}.VPSidebarItem.collapsed .items[data-v-c4656e6d]{display:none}.VPSidebar[data-v-af16598e]{position:fixed;top:var(--vp-layout-top-height, 0px);bottom:0;left:0;z-index:var(--vp-z-index-sidebar);padding:32px 32px 96px;width:calc(100vw - 64px);max-width:320px;background-color:var(--vp-sidebar-bg-color);opacity:0;box-shadow:var(--vp-c-shadow-3);overflow-x:hidden;overflow-y:auto;transform:translate(-100%);transition:opacity .5s,transform .25s ease;overscroll-behavior:contain}.VPSidebar.open[data-v-af16598e]{opacity:1;visibility:visible;transform:translate(0);transition:opacity .25s,transform .5s cubic-bezier(.19,1,.22,1)}.dark .VPSidebar[data-v-af16598e]{box-shadow:var(--vp-shadow-1)}@media (min-width: 960px){.VPSidebar[data-v-af16598e]{z-index:1;padding-top:var(--vp-nav-height);padding-bottom:128px;width:var(--vp-sidebar-width);max-width:100%;background-color:var(--vp-sidebar-bg-color);opacity:1;visibility:visible;box-shadow:none;transform:translate(0)}}@media (min-width: 1440px){.VPSidebar[data-v-af16598e]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}@media (min-width: 960px){.curtain[data-v-af16598e]{position:sticky;top:-64px;left:0;z-index:1;margin-top:calc(var(--vp-nav-height) * -1);margin-right:-32px;margin-left:-32px;height:var(--vp-nav-height);background-color:var(--vp-sidebar-bg-color)}}.nav[data-v-af16598e]{outline:0}.group+.group[data-v-af16598e]{border-top:1px solid var(--vp-c-divider);padding-top:10px}@media (min-width: 960px){.group[data-v-af16598e]{padding-top:10px;width:calc(var(--vp-sidebar-width) - 64px)}}.VPButton[data-v-567ba664]{display:inline-block;border:1px solid transparent;text-align:center;font-weight:600;white-space:nowrap;transition:color .25s,border-color .25s,background-color .25s}.VPButton[data-v-567ba664]:active{transition:color .1s,border-color .1s,background-color .1s}.VPButton.medium[data-v-567ba664]{border-radius:20px;padding:0 20px;line-height:38px;font-size:14px}.VPButton.big[data-v-567ba664]{border-radius:24px;padding:0 24px;line-height:46px;font-size:16px}.VPButton.brand[data-v-567ba664]{border-color:var(--vp-button-brand-border);color:var(--vp-button-brand-text);background-color:var(--vp-button-brand-bg)}.VPButton.brand[data-v-567ba664]:hover{border-color:var(--vp-button-brand-hover-border);color:var(--vp-button-brand-hover-text);background-color:var(--vp-button-brand-hover-bg)}.VPButton.brand[data-v-567ba664]:active{border-color:var(--vp-button-brand-active-border);color:var(--vp-button-brand-active-text);background-color:var(--vp-button-brand-active-bg)}.VPButton.alt[data-v-567ba664]{border-color:var(--vp-button-alt-border);color:var(--vp-button-alt-text);background-color:var(--vp-button-alt-bg)}.VPButton.alt[data-v-567ba664]:hover{border-color:var(--vp-button-alt-hover-border);color:var(--vp-button-alt-hover-text);background-color:var(--vp-button-alt-hover-bg)}.VPButton.alt[data-v-567ba664]:active{border-color:var(--vp-button-alt-active-border);color:var(--vp-button-alt-active-text);background-color:var(--vp-button-alt-active-bg)}.VPButton.sponsor[data-v-567ba664]{border-color:var(--vp-button-sponsor-border);color:var(--vp-button-sponsor-text);background-color:var(--vp-button-sponsor-bg)}.VPButton.sponsor[data-v-567ba664]:hover{border-color:var(--vp-button-sponsor-hover-border);color:var(--vp-button-sponsor-hover-text);background-color:var(--vp-button-sponsor-hover-bg)}.VPButton.sponsor[data-v-567ba664]:active{border-color:var(--vp-button-sponsor-active-border);color:var(--vp-button-sponsor-active-text);background-color:var(--vp-button-sponsor-active-bg)}.VPHero[data-v-fd2650d5]{margin-top:calc((var(--vp-nav-height) + var(--vp-layout-top-height, 0px)) * -1);padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px) 24px 48px}@media (min-width: 640px){.VPHero[data-v-fd2650d5]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 48px 64px}}@media (min-width: 960px){.VPHero[data-v-fd2650d5]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 64px 64px}}.container[data-v-fd2650d5]{display:flex;flex-direction:column;margin:0 auto;max-width:1152px}@media (min-width: 960px){.container[data-v-fd2650d5]{flex-direction:row}}.main[data-v-fd2650d5]{position:relative;z-index:10;order:2;flex-grow:1;flex-shrink:0}.VPHero.has-image .container[data-v-fd2650d5]{text-align:center}@media (min-width: 960px){.VPHero.has-image .container[data-v-fd2650d5]{text-align:left}}@media (min-width: 960px){.main[data-v-fd2650d5]{order:1;width:calc((100% / 3) * 2)}.VPHero.has-image .main[data-v-fd2650d5]{max-width:592px}}.name[data-v-fd2650d5],.text[data-v-fd2650d5]{max-width:392px;letter-spacing:-.4px;line-height:40px;font-size:32px;font-weight:700;white-space:pre-wrap}.VPHero.has-image .name[data-v-fd2650d5],.VPHero.has-image .text[data-v-fd2650d5]{margin:0 auto}.name[data-v-fd2650d5]{color:var(--vp-home-hero-name-color)}.clip[data-v-fd2650d5]{background:var(--vp-home-hero-name-background);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:var(--vp-home-hero-name-color)}@media (min-width: 640px){.name[data-v-fd2650d5],.text[data-v-fd2650d5]{max-width:576px;line-height:56px;font-size:48px}}@media (min-width: 960px){.name[data-v-fd2650d5],.text[data-v-fd2650d5]{line-height:64px;font-size:56px}.VPHero.has-image .name[data-v-fd2650d5],.VPHero.has-image .text[data-v-fd2650d5]{margin:0}}.tagline[data-v-fd2650d5]{padding-top:8px;max-width:392px;line-height:28px;font-size:18px;font-weight:500;white-space:pre-wrap;color:var(--vp-c-text-2)}.VPHero.has-image .tagline[data-v-fd2650d5]{margin:0 auto}@media (min-width: 640px){.tagline[data-v-fd2650d5]{padding-top:12px;max-width:576px;line-height:32px;font-size:20px}}@media (min-width: 960px){.tagline[data-v-fd2650d5]{line-height:36px;font-size:24px}.VPHero.has-image .tagline[data-v-fd2650d5]{margin:0}}.actions[data-v-fd2650d5]{display:flex;flex-wrap:wrap;margin:-6px;padding-top:24px}.VPHero.has-image .actions[data-v-fd2650d5]{justify-content:center}@media (min-width: 640px){.actions[data-v-fd2650d5]{padding-top:32px}}@media (min-width: 960px){.VPHero.has-image .actions[data-v-fd2650d5]{justify-content:flex-start}}.action[data-v-fd2650d5]{flex-shrink:0;padding:6px}.image[data-v-fd2650d5]{order:1;margin:-76px -24px -48px}@media (min-width: 640px){.image[data-v-fd2650d5]{margin:-108px -24px -48px}}@media (min-width: 960px){.image[data-v-fd2650d5]{flex-grow:1;order:2;margin:0;min-height:100%}}.image-container[data-v-fd2650d5]{position:relative;margin:0 auto;width:320px;height:320px}@media (min-width: 640px){.image-container[data-v-fd2650d5]{width:392px;height:392px}}@media (min-width: 960px){.image-container[data-v-fd2650d5]{display:flex;justify-content:center;align-items:center;width:100%;height:100%;transform:translate(-32px,-32px)}}.image-bg[data-v-fd2650d5]{position:absolute;top:50%;left:50%;border-radius:50%;width:192px;height:192px;background-image:var(--vp-home-hero-image-background-image);filter:var(--vp-home-hero-image-filter);transform:translate(-50%,-50%)}@media (min-width: 640px){.image-bg[data-v-fd2650d5]{width:256px;height:256px}}@media (min-width: 960px){.image-bg[data-v-fd2650d5]{width:320px;height:320px}}[data-v-fd2650d5] .image-src{position:absolute;top:50%;left:50%;max-width:192px;max-height:192px;transform:translate(-50%,-50%)}@media (min-width: 640px){[data-v-fd2650d5] .image-src{max-width:256px;max-height:256px}}@media (min-width: 960px){[data-v-fd2650d5] .image-src{max-width:320px;max-height:320px}}.VPFeature[data-v-837f6cca]{display:block;border:1px solid var(--vp-c-bg-soft);border-radius:12px;height:100%;background-color:var(--vp-c-bg-soft);transition:border-color .25s,background-color .25s}.VPFeature.link[data-v-837f6cca]:hover{border-color:var(--vp-c-brand);background-color:var(--vp-c-bg-soft-up)}.box[data-v-837f6cca]{display:flex;flex-direction:column;padding:24px;height:100%}.VPFeature[data-v-837f6cca] .VPImage{width:48px;height:48px;margin-bottom:20px}.icon[data-v-837f6cca]{display:flex;justify-content:center;align-items:center;margin-bottom:20px;border-radius:6px;background-color:var(--vp-c-bg-soft-down);width:48px;height:48px;font-size:24px;transition:background-color .25s}.title[data-v-837f6cca]{line-height:24px;font-size:16px;font-weight:600}.details[data-v-837f6cca]{flex-grow:1;padding-top:8px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.link-text[data-v-837f6cca]{padding-top:8px}.link-text-value[data-v-837f6cca]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-brand)}.link-text-icon[data-v-837f6cca]{display:inline-block;margin-left:6px;width:14px;height:14px;fill:currentColor}.VPFeatures[data-v-ba861f23]{position:relative;padding:0 24px}@media (min-width: 640px){.VPFeatures[data-v-ba861f23]{padding:0 48px}}@media (min-width: 960px){.VPFeatures[data-v-ba861f23]{padding:0 64px}}.container[data-v-ba861f23]{margin:0 auto;max-width:1152px}.items[data-v-ba861f23]{display:flex;flex-wrap:wrap;margin:-8px}.item[data-v-ba861f23]{padding:8px;width:100%}@media (min-width: 640px){.item.grid-2[data-v-ba861f23],.item.grid-4[data-v-ba861f23],.item.grid-6[data-v-ba861f23]{width:50%}}@media (min-width: 768px){.item.grid-2[data-v-ba861f23],.item.grid-4[data-v-ba861f23]{width:50%}.item.grid-3[data-v-ba861f23],.item.grid-6[data-v-ba861f23]{width:calc(100% / 3)}}@media (min-width: 960px){.item.grid-4[data-v-ba861f23]{width:25%}}.VPHome[data-v-d82743a8]{padding-bottom:96px}.VPHome[data-v-d82743a8] .VPHomeSponsors{margin-top:112px;margin-bottom:-128px}@media (min-width: 768px){.VPHome[data-v-d82743a8]{padding-bottom:128px}}.VPDocAsideOutline[data-v-ff0f39c8]{display:none}.VPDocAsideOutline.has-outline[data-v-ff0f39c8]{display:block}.content[data-v-ff0f39c8]{position:relative;border-left:1px solid var(--vp-c-divider);padding-left:16px;font-size:13px;font-weight:500}.outline-marker[data-v-ff0f39c8]{position:absolute;top:32px;left:-1px;z-index:0;opacity:0;width:1px;height:18px;background-color:var(--vp-c-brand);transition:top .25s cubic-bezier(0,1,.5,1),background-color .5s,opacity .25s}.outline-title[data-v-ff0f39c8]{letter-spacing:.4px;line-height:28px;font-size:13px;font-weight:600}.VPDocAside[data-v-3f215769]{display:flex;flex-direction:column;flex-grow:1}.spacer[data-v-3f215769]{flex-grow:1}.VPDocAside[data-v-3f215769] .spacer+.VPDocAsideSponsors,.VPDocAside[data-v-3f215769] .spacer+.VPDocAsideCarbonAds{margin-top:24px}.VPDocAside[data-v-3f215769] .VPDocAsideSponsors+.VPDocAsideCarbonAds{margin-top:16px}.VPLastUpdated[data-v-7b3ebfe1]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 640px){.VPLastUpdated[data-v-7b3ebfe1]{line-height:32px;font-size:14px;font-weight:500}}.VPDocFooter[data-v-face870a]{margin-top:64px}.edit-info[data-v-face870a]{padding-bottom:18px}@media (min-width: 640px){.edit-info[data-v-face870a]{display:flex;justify-content:space-between;align-items:center;padding-bottom:14px}}.edit-link-button[data-v-face870a]{display:flex;align-items:center;border:0;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-brand);transition:color .25s}.edit-link-button[data-v-face870a]:hover{color:var(--vp-c-brand-dark)}.edit-link-icon[data-v-face870a]{margin-right:8px;width:14px;height:14px;fill:currentColor}.prev-next[data-v-face870a]{border-top:1px solid var(--vp-c-divider);padding-top:24px}@media (min-width: 640px){.prev-next[data-v-face870a]{display:flex}}.pager.has-prev[data-v-face870a]{padding-top:8px}@media (min-width: 640px){.pager[data-v-face870a]{display:flex;flex-direction:column;flex-shrink:0;width:50%}.pager.has-prev[data-v-face870a]{padding-top:0;padding-left:16px}}.pager-link[data-v-face870a]{display:block;border:1px solid var(--vp-c-divider);border-radius:8px;padding:11px 16px 13px;width:100%;height:100%;transition:border-color .25s}.pager-link[data-v-face870a]:hover{border-color:var(--vp-c-brand)}.pager-link.next[data-v-face870a]{margin-left:auto;text-align:right}.desc[data-v-face870a]{display:block;line-height:20px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.title[data-v-face870a]{display:block;line-height:20px;font-size:14px;font-weight:500;color:var(--vp-c-brand);transition:color .25s}.VPDocOutlineDropdown[data-v-2edece88]{margin-bottom:42px}.VPDocOutlineDropdown button[data-v-2edece88]{display:block;font-size:14px;font-weight:500;line-height:24px;color:var(--vp-c-text-2);transition:color .5s;border:1px solid var(--vp-c-border);padding:4px 12px;border-radius:8px}.VPDocOutlineDropdown button[data-v-2edece88]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPDocOutlineDropdown button.open[data-v-2edece88]{color:var(--vp-c-text-1)}.icon[data-v-2edece88]{display:inline-block;vertical-align:middle;margin-left:2px;width:14px;height:14px;fill:currentColor}[data-v-2edece88] .outline-link{font-size:13px}.open>.icon[data-v-2edece88]{transform:rotate(90deg)}.items[data-v-2edece88]{margin-top:10px;border-left:1px solid var(--vp-c-divider)}.VPDoc[data-v-c4b0d3cf]{padding:32px 24px 96px;width:100%}.VPDoc .VPDocOutlineDropdown[data-v-c4b0d3cf]{display:none}@media (min-width: 960px) and (max-width: 1280px){.VPDoc .VPDocOutlineDropdown[data-v-c4b0d3cf]{display:block}}@media (min-width: 768px){.VPDoc[data-v-c4b0d3cf]{padding:48px 32px 128px}}@media (min-width: 960px){.VPDoc[data-v-c4b0d3cf]{padding:32px 32px 0}.VPDoc:not(.has-sidebar) .container[data-v-c4b0d3cf]{display:flex;justify-content:center;max-width:992px}.VPDoc:not(.has-sidebar) .content[data-v-c4b0d3cf]{max-width:752px}}@media (min-width: 1280px){.VPDoc .container[data-v-c4b0d3cf]{display:flex;justify-content:center}.VPDoc .aside[data-v-c4b0d3cf]{display:block}}@media (min-width: 1440px){.VPDoc:not(.has-sidebar) .content[data-v-c4b0d3cf]{max-width:784px}.VPDoc:not(.has-sidebar) .container[data-v-c4b0d3cf]{max-width:1104px}}.container[data-v-c4b0d3cf]{margin:0 auto;width:100%}.aside[data-v-c4b0d3cf]{position:relative;display:none;order:2;flex-grow:1;padding-left:32px;width:100%;max-width:256px}.left-aside[data-v-c4b0d3cf]{order:1;padding-left:unset;padding-right:32px}.aside-container[data-v-c4b0d3cf]{position:fixed;top:0;padding-top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + var(--vp-doc-top-height, 0px) + 32px);width:224px;height:100vh;overflow-x:hidden;overflow-y:auto;scrollbar-width:none}.aside-container[data-v-c4b0d3cf]::-webkit-scrollbar{display:none}.aside-curtain[data-v-c4b0d3cf]{position:fixed;bottom:0;z-index:10;width:224px;height:32px;background:linear-gradient(transparent,var(--vp-c-bg) 70%)}.aside-content[data-v-c4b0d3cf]{display:flex;flex-direction:column;min-height:calc(100vh - (var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 32px));padding-bottom:32px}.content[data-v-c4b0d3cf]{position:relative;margin:0 auto;width:100%}@media (min-width: 960px){.content[data-v-c4b0d3cf]{padding:0 32px 128px}}@media (min-width: 1280px){.content[data-v-c4b0d3cf]{order:1;margin:0;min-width:640px}}.content-container[data-v-c4b0d3cf]{margin:0 auto}.VPDoc.has-aside .content-container[data-v-c4b0d3cf]{max-width:688px}.NotFound[data-v-c70503b8]{padding:64px 24px 96px;text-align:center}@media (min-width: 768px){.NotFound[data-v-c70503b8]{padding:96px 32px 168px}}.code[data-v-c70503b8]{line-height:64px;font-size:64px;font-weight:600}.title[data-v-c70503b8]{padding-top:12px;letter-spacing:2px;line-height:20px;font-size:20px;font-weight:700}.divider[data-v-c70503b8]{margin:24px auto 18px;width:64px;height:1px;background-color:var(--vp-c-divider)}.quote[data-v-c70503b8]{margin:0 auto;max-width:256px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.action[data-v-c70503b8]{padding-top:20px}.link[data-v-c70503b8]{display:inline-block;border:1px solid var(--vp-c-brand);border-radius:16px;padding:3px 16px;font-size:14px;font-weight:500;color:var(--vp-c-brand);transition:border-color .25s,color .25s}.link[data-v-c70503b8]:hover{border-color:var(--vp-c-brand-dark);color:var(--vp-c-brand-dark)}.VPContent[data-v-a494bd1d]{flex-grow:1;flex-shrink:0;margin:var(--vp-layout-top-height, 0px) auto 0;width:100%}.VPContent.is-home[data-v-a494bd1d]{width:100%;max-width:100%}.VPContent.has-sidebar[data-v-a494bd1d]{margin:0}@media (min-width: 960px){.VPContent[data-v-a494bd1d]{padding-top:var(--vp-nav-height)}.VPContent.has-sidebar[data-v-a494bd1d]{margin:var(--vp-layout-top-height, 0px) 0 0;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPContent.has-sidebar[data-v-a494bd1d]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.VPFooter[data-v-f7fc41f4]{position:relative;z-index:var(--vp-z-index-footer);border-top:1px solid var(--vp-c-gutter);padding:32px 24px;background-color:var(--vp-c-bg)}.VPFooter.has-sidebar[data-v-f7fc41f4]{display:none}@media (min-width: 768px){.VPFooter[data-v-f7fc41f4]{padding:32px}}.container[data-v-f7fc41f4]{margin:0 auto;max-width:var(--vp-layout-max-width);text-align:center}.message[data-v-f7fc41f4],.copyright[data-v-f7fc41f4]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.Layout[data-v-b2cf3e0b]{display:flex;flex-direction:column;min-height:100vh}.VPHomeSponsors[data-v-3c6e61c2]{border-top:1px solid var(--vp-c-gutter);padding:88px 24px 96px;background-color:var(--vp-c-bg)}.container[data-v-3c6e61c2]{margin:0 auto;max-width:1152px}.love[data-v-3c6e61c2]{margin:0 auto;width:28px;height:28px;color:var(--vp-c-text-3)}.icon[data-v-3c6e61c2]{width:28px;height:28px;fill:currentColor}.message[data-v-3c6e61c2]{margin:0 auto;padding-top:10px;max-width:320px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.sponsors[data-v-3c6e61c2]{padding-top:32px}.action[data-v-3c6e61c2]{padding-top:40px;text-align:center}.VPTeamPage[data-v-10b00018]{padding-bottom:96px}@media (min-width: 768px){.VPTeamPage[data-v-10b00018]{padding-bottom:128px}}.VPTeamPageSection+.VPTeamPageSection[data-v-10b00018-s],.VPTeamMembers+.VPTeamPageSection[data-v-10b00018-s]{margin-top:64px}.VPTeamMembers+.VPTeamMembers[data-v-10b00018-s]{margin-top:24px}@media (min-width: 768px){.VPTeamPageTitle+.VPTeamPageSection[data-v-10b00018-s]{margin-top:16px}.VPTeamPageSection+.VPTeamPageSection[data-v-10b00018-s],.VPTeamMembers+.VPTeamPageSection[data-v-10b00018-s]{margin-top:96px}}.VPTeamMembers[data-v-10b00018-s]{padding:0 24px}@media (min-width: 768px){.VPTeamMembers[data-v-10b00018-s]{padding:0 48px}}@media (min-width: 960px){.VPTeamMembers[data-v-10b00018-s]{padding:0 64px}}.VPTeamPageTitle[data-v-bf2cbdac]{padding:48px 32px;text-align:center}@media (min-width: 768px){.VPTeamPageTitle[data-v-bf2cbdac]{padding:64px 48px 48px}}@media (min-width: 960px){.VPTeamPageTitle[data-v-bf2cbdac]{padding:80px 64px 48px}}.title[data-v-bf2cbdac]{letter-spacing:0;line-height:44px;font-size:36px;font-weight:500}@media (min-width: 768px){.title[data-v-bf2cbdac]{letter-spacing:-.5px;line-height:56px;font-size:48px}}.lead[data-v-bf2cbdac]{margin:0 auto;max-width:512px;padding-top:12px;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 768px){.lead[data-v-bf2cbdac]{max-width:592px;letter-spacing:.15px;line-height:28px;font-size:20px}}.VPTeamPageSection[data-v-b1a88750]{padding:0 32px}@media (min-width: 768px){.VPTeamPageSection[data-v-b1a88750]{padding:0 48px}}@media (min-width: 960px){.VPTeamPageSection[data-v-b1a88750]{padding:0 64px}}.title[data-v-b1a88750]{position:relative;margin:0 auto;max-width:1152px;text-align:center;color:var(--vp-c-text-2)}.title-line[data-v-b1a88750]{position:absolute;top:16px;left:0;width:100%;height:1px;background-color:var(--vp-c-divider)}.title-text[data-v-b1a88750]{position:relative;display:inline-block;padding:0 24px;letter-spacing:0;line-height:32px;font-size:20px;font-weight:500;background-color:var(--vp-c-bg)}.lead[data-v-b1a88750]{margin:0 auto;max-width:480px;padding-top:12px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.members[data-v-b1a88750]{padding-top:40px}.VPTeamMembersItem[data-v-a3462077]{display:flex;flex-direction:column;gap:2px;border-radius:12px;width:100%;height:100%;overflow:hidden}.VPTeamMembersItem.small .profile[data-v-a3462077]{padding:32px}.VPTeamMembersItem.small .data[data-v-a3462077]{padding-top:20px}.VPTeamMembersItem.small .avatar[data-v-a3462077]{width:64px;height:64px}.VPTeamMembersItem.small .name[data-v-a3462077]{line-height:24px;font-size:16px}.VPTeamMembersItem.small .affiliation[data-v-a3462077]{padding-top:4px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .desc[data-v-a3462077]{padding-top:12px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .links[data-v-a3462077]{margin:0 -16px -20px;padding:10px 0 0}.VPTeamMembersItem.medium .profile[data-v-a3462077]{padding:48px 32px}.VPTeamMembersItem.medium .data[data-v-a3462077]{padding-top:24px;text-align:center}.VPTeamMembersItem.medium .avatar[data-v-a3462077]{width:96px;height:96px}.VPTeamMembersItem.medium .name[data-v-a3462077]{letter-spacing:.15px;line-height:28px;font-size:20px}.VPTeamMembersItem.medium .affiliation[data-v-a3462077]{padding-top:4px;font-size:16px}.VPTeamMembersItem.medium .desc[data-v-a3462077]{padding-top:16px;max-width:288px;font-size:16px}.VPTeamMembersItem.medium .links[data-v-a3462077]{margin:0 -16px -12px;padding:16px 12px 0}.profile[data-v-a3462077]{flex-grow:1;background-color:var(--vp-c-bg-soft)}.data[data-v-a3462077]{text-align:center}.avatar[data-v-a3462077]{position:relative;flex-shrink:0;margin:0 auto;border-radius:50%;box-shadow:var(--vp-shadow-3)}.avatar-img[data-v-a3462077]{position:absolute;top:0;right:0;bottom:0;left:0;border-radius:50%;object-fit:cover}.name[data-v-a3462077]{margin:0;font-weight:600}.affiliation[data-v-a3462077]{margin:0;font-weight:500;color:var(--vp-c-text-2)}.org.link[data-v-a3462077]{color:var(--vp-c-text-2);transition:color .25s}.org.link[data-v-a3462077]:hover{color:var(--vp-c-brand)}.desc[data-v-a3462077]{margin:0 auto}.desc[data-v-a3462077] a{font-weight:500;color:var(--vp-c-brand);text-decoration-style:dotted;transition:color .25s}.links[data-v-a3462077]{display:flex;justify-content:center;height:56px}.sp-link[data-v-a3462077]{display:flex;justify-content:center;align-items:center;text-align:center;padding:16px;font-size:14px;font-weight:500;color:var(--vp-c-sponsor);background-color:var(--vp-c-bg-soft);transition:color .25s,background-color .25s}.sp .sp-link.link[data-v-a3462077]:hover,.sp .sp-link.link[data-v-a3462077]:focus{outline:none;color:var(--vp-c-white);background-color:var(--vp-c-sponsor)}.sp-icon[data-v-a3462077]{margin-right:8px;width:16px;height:16px;fill:currentColor}.VPTeamMembers.small .container[data-v-04685dce]{grid-template-columns:repeat(auto-fit,minmax(224px,1fr))}.VPTeamMembers.small.count-1 .container[data-v-04685dce]{max-width:276px}.VPTeamMembers.small.count-2 .container[data-v-04685dce]{max-width:576px}.VPTeamMembers.small.count-3 .container[data-v-04685dce]{max-width:876px}.VPTeamMembers.medium .container[data-v-04685dce]{grid-template-columns:repeat(auto-fit,minmax(256px,1fr))}@media (min-width: 375px){.VPTeamMembers.medium .container[data-v-04685dce]{grid-template-columns:repeat(auto-fit,minmax(288px,1fr))}}.VPTeamMembers.medium.count-1 .container[data-v-04685dce]{max-width:368px}.VPTeamMembers.medium.count-2 .container[data-v-04685dce]{max-width:760px}.container[data-v-04685dce]{display:grid;gap:24px;margin:0 auto;max-width:1152px}a[data-v-5030966d]{cursor:pointer}.bots[data-v-b04cb2a5]{display:flex}.title[data-v-b04cb2a5]{color:#b74ec9;font-size:18px;display:flex;flex-direction:column;align-items:center}img[data-v-b04cb2a5]{margin:10px 0}@media screen and (max-width: 768px){.bots[data-v-b04cb2a5]{flex-direction:column}.title[data-v-b04cb2a5]{font-size:14px}}.user[data-v-6c6a5107]{display:flex;align-items:center;margin-bottom:5px}.avatar[data-v-6c6a5107]{width:50px;height:50px;border-radius:50%;border:1px solid #b74ec9;margin-left:5px}.small .avatar[data-v-6c6a5107]{width:40px;height:40px}.user-name[data-v-6c6a5107]{width:calc(100% - 85px);margin:0 20px 0 10px;display:flex;flex-direction:column}.user-name>.name[data-v-6c6a5107]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.desc[data-v-6c6a5107]{font-weight:700;color:#b74ec9}.user-list[data-v-78401fcf]{display:flex;flex-wrap:wrap}.user[data-v-78401fcf]{display:flex;align-items:center;margin-bottom:5px}.user[data-v-78401fcf]:not(.small){width:25%}.avatar[data-v-78401fcf]{width:50px;height:50px;border-radius:50%;border:1px solid #b74ec9;margin-left:5px}.small .avatar[data-v-78401fcf]{width:40px;height:40px}.user-name[data-v-78401fcf]{width:calc(100% - 85px);margin:0 20px 0 10px;display:flex;flex-direction:column}.user-name>.name[data-v-78401fcf]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.amount[data-v-78401fcf]{font-size:12px;font-weight:700;color:#ff9800}@font-face{font-family:Harmony;font-weight:400;font-style:normal;src:url(https://cos.amiyabot.com/resource/Harmony_amiyabot.com.min.woff2)}:root{scroll-behavior:smooth;--vp-font-family-base: "Inter var experimental", "Inter var", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", "Harmony", sans-serif;--vp-c-brand: #ba68c8;--vp-c-brand-dark: #b74ec9;--vp-c-brand-darker: #b74ec9;--vp-c-brand-light: #ce93d8;--vp-c-brand-lighter: #ce93d8;--vp-c-text-light-1: #213547}.vp-doc table{font-size:14px}.vp-doc th,.vp-doc td{padding:5px 10px}.vp-doc blockquote{padding:10px 16px;border-left:3px solid #b74ec9;background:rgb(240 248 255 / 10%)}.vp-doc blockquote>p{color:#b74ec9}code:not(div[class*=language-] code){font-family:var(--vp-font-family-base)}img{border-radius:4px}.beta-tag{color:#fff;background:#f44336;padding:0 5px;font-size:18px;border-radius:4px}i.red{font-style:normal;color:red}.custom-block a{text-decoration:underline!important}.VPLink.link.link>.text{line-height:20px}.main-container{width:1152px;margin:auto;padding:30px 20px 0}@media screen and (max-width: 768px){.main-container{width:calc(100% - 20px)}}.VPLocalSearchBox[data-v-36d7e60a]{position:fixed;z-index:100;top:0;right:0;bottom:0;left:0;display:flex}.backdrop[data-v-36d7e60a]{position:absolute;top:0;right:0;bottom:0;left:0;background:var(--vp-backdrop-bg-color);transition:opacity .5s}.shell[data-v-36d7e60a]{position:relative;padding:12px;margin:64px auto;display:flex;flex-direction:column;gap:16px;background:var(--vp-local-search-bg);width:min(100vw - 60px,900px);height:min-content;max-height:min(100vh - 128px,900px);border-radius:6px}@media (max-width: 768px){.shell[data-v-36d7e60a]{margin:0;width:100vw;height:100vh;max-height:none;border-radius:0}}.search-bar[data-v-36d7e60a]{border:1px solid var(--vp-c-divider);border-radius:4px;display:flex;align-items:center;padding:0 12px;cursor:text}@media (max-width: 768px){.search-bar[data-v-36d7e60a]{padding:0 8px}}.search-bar[data-v-36d7e60a]:focus-within{border-color:var(--vp-c-brand)}.search-icon[data-v-36d7e60a]{margin:8px}@media (max-width: 768px){.search-icon[data-v-36d7e60a]{display:none}}.search-input[data-v-36d7e60a]{padding:6px 12px;font-size:inherit;width:100%}@media (max-width: 768px){.search-input[data-v-36d7e60a]{padding:6px 4px}}.search-actions[data-v-36d7e60a]{display:flex;gap:4px}@media (any-pointer: coarse){.search-actions[data-v-36d7e60a]{gap:8px}}@media (min-width: 769px){.search-actions.before[data-v-36d7e60a]{display:none}}.search-actions button[data-v-36d7e60a]{padding:8px}.search-actions button[data-v-36d7e60a]:not([disabled]):hover,.toggle-layout-button.detailed-list[data-v-36d7e60a]{color:var(--vp-c-brand)}.search-actions button.clear-button[data-v-36d7e60a]:disabled{opacity:.37}.search-keyboard-shortcuts[data-v-36d7e60a]{font-size:.8rem;opacity:75%;display:flex;flex-wrap:wrap;gap:16px;line-height:14px}.search-keyboard-shortcuts span[data-v-36d7e60a]{display:flex;align-items:center;gap:4px}@media (max-width: 768px){.search-keyboard-shortcuts[data-v-36d7e60a]{display:none}}.search-keyboard-shortcuts kbd[data-v-36d7e60a]{background:rgba(128,128,128,.1);border-radius:4px;padding:3px 6px;min-width:24px;display:inline-block;text-align:center;vertical-align:middle;border:1px solid rgba(128,128,128,.15);box-shadow:0 2px 2px #0000001a}.results[data-v-36d7e60a]{display:flex;flex-direction:column;gap:6px;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain}.result[data-v-36d7e60a]{display:flex;align-items:center;gap:8px;border-radius:4px;transition:none;line-height:1rem;border:solid 2px var(--vp-local-search-result-border);outline:none}.result>div[data-v-36d7e60a]{margin:12px;width:100%;overflow:hidden}@media (max-width: 768px){.result>div[data-v-36d7e60a]{margin:8px}}.titles[data-v-36d7e60a]{display:flex;flex-wrap:wrap;gap:4px;position:relative;z-index:1001;padding:2px 0}.title[data-v-36d7e60a]{display:flex;align-items:center;gap:4px}.title.main[data-v-36d7e60a]{font-weight:500}.title-icon[data-v-36d7e60a]{opacity:.5;font-weight:500;color:var(--vp-c-brand)}.title svg[data-v-36d7e60a]{opacity:.5}.result.selected[data-v-36d7e60a]{--vp-local-search-result-bg: var(--vp-local-search-result-selected-bg);border-color:var(--vp-local-search-result-selected-border)}.excerpt-wrapper[data-v-36d7e60a]{position:relative}.excerpt[data-v-36d7e60a]{opacity:75%;pointer-events:none;max-height:140px;overflow:hidden;position:relative;opacity:.5;margin-top:4px}.result.selected .excerpt[data-v-36d7e60a]{opacity:1}.excerpt[data-v-36d7e60a] *{font-size:.8rem!important;line-height:130%!important}.titles[data-v-36d7e60a] mark,.excerpt[data-v-36d7e60a] mark{background-color:var(--vp-local-search-highlight-bg);color:var(--vp-local-search-highlight-text);border-radius:2px;padding:0 2px}.excerpt[data-v-36d7e60a] .vp-code-group .tabs{display:none}.excerpt[data-v-36d7e60a] .vp-code-group div[class*=language-]{border-radius:8px!important}.excerpt-gradient-bottom[data-v-36d7e60a]{position:absolute;bottom:-1px;left:0;width:100%;height:8px;background:linear-gradient(transparent,var(--vp-local-search-result-bg));z-index:1000}.excerpt-gradient-top[data-v-36d7e60a]{position:absolute;top:-1px;left:0;width:100%;height:8px;background:linear-gradient(var(--vp-local-search-result-bg),transparent);z-index:1000}.result.selected .titles[data-v-36d7e60a],.result.selected .title-icon[data-v-36d7e60a]{color:var(--vp-c-brand)!important}.no-results[data-v-36d7e60a]{font-size:.9rem;text-align:center;padding:12px}svg[data-v-36d7e60a]{flex:none} diff --git a/assets/test.6cd83df6.png b/assets/test.6cd83df6.png new file mode 100644 index 00000000..65c0f499 Binary files /dev/null and b/assets/test.6cd83df6.png differ diff --git a/bot/102068219.json b/bot/102068219.json new file mode 100644 index 00000000..ab2afccc --- /dev/null +++ b/bot/102068219.json @@ -0,0 +1 @@ +{"bot_appid":102068219} \ No newline at end of file diff --git a/develop/adapters/comwechat.html b/develop/adapters/comwechat.html new file mode 100644 index 00000000..a92f8163 --- /dev/null +++ b/develop/adapters/comwechat.html @@ -0,0 +1,28 @@ + + + + + + ComWeChatBot Client Beta | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

ComWeChatBot Client Beta

ComWeChatBot Client 是 PC hook 微信的协议端。

需在服务配置开启 正向 websocket

连接 ComWeChatBot

参数名类型释义默认值
hoststr服务的 ip 地址
ws_portint服务的 websocket 端口
http_portint服务的 http 端口
python
from amiyabot.adapters.comwechat import com_wechat
+
+token = '******' # access-token
+
+adapter_service = com_wechat('127.0.0.1', 8080, 8060)
+
+bot = AmiyaBot(appid=appid, token=token, adapter=adapter_service)
+ + + + \ No newline at end of file diff --git a/develop/adapters/gocq.html b/develop/adapters/gocq.html new file mode 100644 index 00000000..24ca7203 --- /dev/null +++ b/develop/adapters/gocq.html @@ -0,0 +1,33 @@ + + + + + + go-cqhttp | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

go-cqhttp

go-cqhttp 以下简称 gocq。它是基于 Mirai 以及 MiraiGo 的 OneBot Golang 原生实现。

注意

go-cq 的配置中,post-format 需更改为 array

yaml
# config.yml
+message:
+    # 上报数据类型
+    # 可选: string, array
+    post-format: array

连接 gocq

参数名类型释义默认值
hoststrgocq 服务的 ip 地址
ws_portintgocq 服务的 websocket 端口
http_portintgocq 服务的 http 端口
python
from amiyabot.adapters.cqhttp import cq_http
+
+qq = '******'    # 机器人的 QQ 号
+token = '******' # gocq 的 access-token
+
+adapter_service = cq_http('127.0.0.1', 8080, 5700)
+
+bot = AmiyaBot(appid=qq, token=token, adapter=adapter_service)
+ + + + \ No newline at end of file diff --git a/develop/adapters/index.html b/develop/adapters/index.html new file mode 100644 index 00000000..b817286e --- /dev/null +++ b/develop/adapters/index.html @@ -0,0 +1,26 @@ + + + + + + 适配器 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

适配器

更改默认适配器可以让你搭建其他平台的机器人,除了 bot.instance.api 有差异外,你几乎可以完全按照文档的开发方式进行。我们尽量为所有适配器的基本逻辑实现了相同的效果,使得在不同平台下 AmiyaBot 的开发差异变得极其之小。

适配器参数 adapter

AmiyaBot 对象拥有一个适配器参数 adapter,接受一个 BotAdapterProtocol 的子类。默认值为 QQ 频道机器人的适配器 QQGuildBotInstance

python
class AmiyaBot(BotHandlerFactory):
+    def __init__(self,
+                 ...
+                 adapter: Type[BotAdapterProtocol] = QQGuildBotInstance):
+        ...

从左侧导航挑选合适的适配器,更改你的实例。

+ + + + \ No newline at end of file diff --git a/develop/adapters/kook.html b/develop/adapters/kook.html new file mode 100644 index 00000000..5866c7cf --- /dev/null +++ b/develop/adapters/kook.html @@ -0,0 +1,26 @@ + + + + + + KOOK 机器人 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

KOOK 机器人

KOOK 是一款免费无广告的语音沟通工具,并提供了强大的官方机器人支持。

KOOK 适配器不需要 appid,只需要传入 应用的 websocket token 参数即可。

python
from amiyabot import KOOKBotInstance
+
+ws_token = '******' # websocket Token
+
+bot = AmiyaBot(token=ws_token, adapter=KOOKBotInstance)
+ + + + \ No newline at end of file diff --git a/develop/adapters/mah.html b/develop/adapters/mah.html new file mode 100644 index 00000000..b83dcac4 --- /dev/null +++ b/develop/adapters/mah.html @@ -0,0 +1,29 @@ + + + + + + mirai-api-http | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

mirai-api-http

mirai-api-http 以下简称 mah。是一个在全平台下运行,提供 QQ Android 协议支持的高效率机器人库。

如要使用此适配器,需要 mah 同时开启了 websocket 和 http 服务。AmiyaBot 将通过 mirai_api_http 方法实例化它的适配器。

连接 mah

参数名类型释义默认值
hoststrmah 服务的 ip 地址
ws_portintmah 服务的 websocket 端口
http_portintmah 服务的 http 端口
python
from amiyabot.adapters.mirai import mirai_api_http
+
+qq = '******'       # 机器人的 QQ 号
+auth_key = '******' # mah 的 verifyKey
+
+adapter_service = mirai_api_http('127.0.0.1', 8060, 8080)
+
+bot = AmiyaBot(appid=qq, token=auth_key, adapter=adapter_service)
+ + + + \ No newline at end of file diff --git a/develop/adapters/onebot11.html b/develop/adapters/onebot11.html new file mode 100644 index 00000000..9ab1f85b --- /dev/null +++ b/develop/adapters/onebot11.html @@ -0,0 +1,29 @@ + + + + + + OneBot v11 Beta | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

OneBot v11 Beta

OneBot 11 以下简称 ob11。该标准是从原 CKYU 平台的 CQHTTP 插件接口修改而来的通用聊天机器人应用接口标准。
使用此适配器,可连接任何 OneBot 11 实现的机器人平台。

连接 onebot11

参数名类型释义默认值
hoststrob11 服务的 ip 地址
ws_portintob11 服务的 websocket 端口
http_portintob11 服务的 http 端口
python
from amiyabot.adapters.onebot.v11 import onebot11
+
+appid = '******'    # 机器人的账号(如需要)
+token = '******' # access-token
+
+adapter_service = onebot11('127.0.0.1', 8080, 8060)
+
+bot = AmiyaBot(appid=appid, token=token, adapter=adapter_service)
+ + + + \ No newline at end of file diff --git a/develop/adapters/onebot12.html b/develop/adapters/onebot12.html new file mode 100644 index 00000000..6b16ee5b --- /dev/null +++ b/develop/adapters/onebot12.html @@ -0,0 +1,29 @@ + + + + + + OneBot v12 Beta | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

OneBot v12 Beta

OneBot 12 以下简称 ob12 。是一个聊天机器人应用接口标准,旨在统一不同聊天平台上的机器人应用开发接口,使开发者只需编写一次业务逻辑代码即可应用到多种机器人平台。
使用此适配器,可连接任何 OneBot 12 实现的机器人平台。

连接 onebot12

参数名类型释义默认值
hoststrob12 服务的 ip 地址
ws_portintob12 服务的 websocket 端口
http_portintob12 服务的 http 端口
python
from amiyabot.adapters.onebot.v12 import onebot12
+
+appid = '******'    # 机器人的账号(如需要)
+token = '******' # access-token
+
+adapter_service = onebot12('127.0.0.1', 8080, 8060)
+
+bot = AmiyaBot(appid=appid, token=token, adapter=adapter_service)
+ + + + \ No newline at end of file diff --git a/develop/adapters/qqChannel.html b/develop/adapters/qqChannel.html new file mode 100644 index 00000000..6164ee34 --- /dev/null +++ b/develop/adapters/qqChannel.html @@ -0,0 +1,31 @@ + + + + + + QQ 频道机器人 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

QQ 频道机器人

按照 基础指南 创建的机器人即为 QQ 频道机器人,无需额外的适配器。

事件分片

考虑到开发者事件接收时可以实现负载均衡,QQ 提供了分片逻辑,事件通知会落在不同的分片上,可参考官方文档 分片连接LoadBalance 了解分片机制。

创建分片连接需要使用分片适配器 qq_guild_shards

python
from amiyabot.adapters.tencent.qqGuild import qq_guild_shards
+
+bot1 = AmiyaBot(appid='...', token='...', adapter=qq_guild_shards(0, 2))
+bot2 = AmiyaBot(appid='...', token='...', adapter=qq_guild_shards(1, 2))

注意

每个分片的启动应当按顺序缓慢进行,切勿同时启动,以免 gateway 返回的信息一致造成连接失败。

python
# 仅作示意,实际上每个分片应当是独立的服务。
+def start():
+    asyncio.create_task(bot1.start())
+    time.sleep(2)
+    asyncio.create_task(bot2.start())

qq_guild_shards 参数

参数名类型释义默认值
shard_indexint分片下标,从 0 开始
shardsint分片总数

沙箱环境

使用 QQGuildSandboxBotInstance 适配器将 API 调用更改为沙箱环境。沙箱环境只会收到测试频道的事件,且调用 openapi 仅能操作测试频道。

python
from amiyabot.adapters.tencent.qqGuild import QQGuildSandboxBotInstance
+
+bot = AmiyaBot(..., adapter=QQGuildSandboxBotInstance)
+ + + + \ No newline at end of file diff --git a/develop/adapters/qqGlobal.html b/develop/adapters/qqGlobal.html new file mode 100644 index 00000000..4f9f1f0c --- /dev/null +++ b/develop/adapters/qqGlobal.html @@ -0,0 +1,26 @@ + + + + + + QQ 全域机器人 Beta | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

QQ 全域机器人 Beta

全域机器人指同时支持群聊、消息记录和频道的机器人

创建全域适配器

全域适配器的参数和用法和QQ 群机器人一致,请参考文档。

创建后机器人能够同时接收到来自群聊、消息记录和频道的消息。

python
from amiyabot.adapters.tencent.qqGlobal import qq_global
+
+client_secret = '******' # 密钥
+
+bot = AmiyaBot(appid='******', token='******', adapter=qq_global(client_secret))
+ + + + \ No newline at end of file diff --git a/develop/adapters/qqGroup.html b/develop/adapters/qqGroup.html new file mode 100644 index 00000000..793974fc --- /dev/null +++ b/develop/adapters/qqGroup.html @@ -0,0 +1,70 @@ + + + + + + QQ 群机器人 Beta | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

QQ 群机器人 Beta

QQ 开放平台 完成企业主体入驻,即可创建可在 QQ 群聊里使用的 QQ 群机器人。

在公网下使用

QQ 群聊适配器需要在本地启动资源服务让腾讯端能够访问媒体资源,默认在公网下使用。如果无法在公网下部署,请参考自定义资源服务

python
from amiyabot.adapters.tencent.qqGroup import qq_group
+
+client_secret = '******' # 密钥
+
+bot = AmiyaBot(appid='******', token='******', adapter=qq_group(client_secret))

qq_group 参数

参数名类型释义默认值
client_secretstr机器人密钥
default_chain_builder默认消息构建器None
default_chain_builder_options默认消息构建器参数QQGroupChainBuilderOptions()
shard_indexint分片下标,从 0 开始0
shardsint分片总数1
  • 在机器人启动时,资源服务也会一同启动。
  • 默认的资源服务是端口单例的,实例化多个 QQ 群聊适配器 AmiyaBot 或使用 多账号 时,同一个端口的资源服务会相互共享。

事件分片

考虑到开发者事件接收时可以实现负载均衡,QQ 提供了分片逻辑,事件通知会落在不同的分片上,可参考官方文档 分片连接LoadBalance 了解分片机制。

python
bot1 = AmiyaBot(appid='...', token='...', adapter=qq_group(client_secret, shard_index=0, shards=2))
+bot2 = AmiyaBot(appid='...', token='...', adapter=qq_group(client_secret, shard_index=1, shards=2))

注意

每个分片的启动应当按顺序缓慢进行,切勿同时启动,以免 gateway 返回的信息一致造成连接失败。

python
# 仅作示意,实际上每个分片应当是独立的服务。
+def start():
+    asyncio.create_task(bot1.start())
+    time.sleep(2)
+    asyncio.create_task(bot2.start())

修改资源服务配置

引入 QQGroupChainBuilderOptions 修改默认的资源服务配置。

参数名类型释义默认值
hoststr资源服务监听地址0.0.0.0
portint资源服务监听端口8086
resource_pathstr临时文件存放目录./resource
http_server_optionsdictHttpServer **kwargs
python
from amiyabot.adapters.tencent.qqGroup import qq_group
+from amiyabot.adapters.tencent.qqGroup.builder import QQGroupChainBuilderOptions
+
+bot = AmiyaBot(
+    appid='******',
+    token='******',
+    adapter=qq_group(
+        client_secret='******',
+        default_chain_builder_options=QQGroupChainBuilderOptions(
+            '0.0.0.0',
+            8086,
+            './resource',
+        ),
+    ),
+)

自定义资源服务

多数情况下我们推荐使用第三方托管服务来搭建资源服务,如 腾讯云COS阿里云OSS 等。

通过自定义默认的 ChainBuilder,来实现上传文件到托管服务以及返回生成的 url。

继承 ChainBuilder 并实现相关方法。

可参考 进阶指南 - 介入媒体消息的构建过程

python
from typing import Union
+from graiax import silkcoder
+from amiyabot import ChainBuilder
+
+class MyBuilder(ChainBuilder):
+    @classmethod
+    async def get_image(cls, image: Union[str, bytes]) -> Union[str, bytes]:
+        # 上传图片到第三方托管服务
+        ...
+        return url # 返回访问资源的 URL
+
+    @classmethod
+    async def get_voice(cls, voice_file: str) -> str:
+        # 上传语音文件到第三方托管服务,语音文件必须是 silk 格式
+        voice: bytes = await silkcoder.async_encode(voice_file, ios_adaptive=True)
+        ...
+        return url # 返回访问资源的 URL
+
+    @classmethod
+    async def get_video(cls, video_file: str) -> str:
+        # 上传视频文件到第三方托管服务
+        ...
+        return url # 返回访问资源的 URL
+
+
+bot = AmiyaBot(..., adapter=qq_group(default_chain_builder=MyBuilder()))
+ + + + \ No newline at end of file diff --git a/develop/advanced/blockingIO.html b/develop/advanced/blockingIO.html new file mode 100644 index 00000000..276a6c64 --- /dev/null +++ b/develop/advanced/blockingIO.html @@ -0,0 +1,28 @@ + + + + + + 处理 IO 阻塞的操作 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

处理 IO 阻塞的操作

AmiyaBot 为异步程序,一般情况下应该遵循异步编程来进行开发。但在使用一些标准或第三方库时,不能保证其方法是异步的,使用 IO 阻塞的方法容易造成线程阻塞,影响业务逻辑。

run_in_thread_pool

AmiyaBot util 库里提供的利用线程池将同步方法转变为异步方法执行的函数。

参数名类型释义默认值
block_funcCallableIO 阻塞的方法
*args原方法参数
**kwargs原方法字典参数
python
from amiyabot.util import run_in_thread_pool
+
+# IO 阻塞的方法
+block_io_method(arg1, arg2, arg3='xxx')
+
+# 转变为异步执行
+await run_in_thread_pool(block_io_method, arg1, arg2, arg3='xxx')
+ + + + \ No newline at end of file diff --git a/develop/advanced/chainBuilder.html b/develop/advanced/chainBuilder.html new file mode 100644 index 00000000..4124f59a --- /dev/null +++ b/develop/advanced/chainBuilder.html @@ -0,0 +1,70 @@ + + + + + + 介入 Chain 构建媒体消息时的操作 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

介入 Chain 构建媒体消息时的操作

Chain 对象在构建消息时,可使用辅助类介入媒体消息或浏览器的构建过程。

创建辅助类

继承 ChainBuilder 类并覆写其方法创建一个自定义的辅助类。在实例化 Chain 时,传入辅助类实例即可介入 Chain 的操作。

python
from typing import Union
+from amiyabot import Chain, ChainBuilder
+from playwright.async_api import Page
+
+class MyBuilder(ChainBuilder):
+    @classmethod
+    async def get_image(cls, image: Union[str, bytes]) -> Union[str, bytes]:
+        ...
+        return image
+
+    @classmethod
+    async def get_voice(cls, voice_file: str) -> str:
+        ...
+        return voice_file
+
+    @classmethod
+    async def get_video(cls, video_file: str) -> str:
+        ...
+        return video_file
+
+    @classmethod
+    async def on_page_rendered(cls, page: Page):
+        ...
+
+
+# 在构造参数里使用辅助类
+chain = Chain(..., chain_builder=MyBuilder())
+
+# 为属性赋值使用辅助类
+chain.builder = MyBuilder()

get_image

该函数会在 chain 构建图片消息时调用,每张图片调用一次。传入一个参数 image ,类型为 str(文件路径或 url) 或 bytes(图片字节数据)。
如果函数有返回值(必须是以上两种类型),chain 会使用返回值构建图片消息。

get_voice

该函数会在 chain 构建语音消息时调用,每个语音文件调用一次。传入文件路径 voice_file
如果函数有返回值,chain 会使用返回值构建语音消息。

get_video

该函数会在 chain 构建视频消息时调用,每个视频文件调用一次。传入文件路径 video_file
如果函数有返回值,chain 会使用返回值构建视频消息。

on_page_rendered

该函数会在 chain 构建浏览器渲染的图片并打开了页面时调用,提供了浏览器的 Page 对象,可在此对 Page 进行操作(如对页面进行 JS 注入等)。

提示

构建浏览器渲染的图片同样也会调用一次 get_image 函数。

使用示例

python
class BaiduSearch(ChainBuilder):
+    @classmethod
+    async def on_page_rendered(cls, page: Page):
+        """
+        可以在截图前先对页面进行操作,比如 ”百度一下“
+        """
+        await page.locator('#kw').fill('AmiyaBot')
+        await page.locator('#su').click()
+        await asyncio.sleep(2)
+
+
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    chain = Chain(data, chain_builder=BaiduSearch())
+
+    return chain.html(
+        'https://www.baidu.com/',
+        is_template=False,
+        render_time=1000,
+    )
+ + + + \ No newline at end of file diff --git a/develop/advanced/databaseSupport.html b/develop/advanced/databaseSupport.html new file mode 100644 index 00000000..d3621f18 --- /dev/null +++ b/develop/advanced/databaseSupport.html @@ -0,0 +1,61 @@ + + + + + + 数据库支持 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

数据库支持

AmiyaBot 提供了 Sqlite 和 MySQL 数据库的 ORM 支持。基于 peewee ,封装了部分表结构管理以及查询转换。日常使用的查询操作详见 peewee文档

温馨提示

AmiyaBot 仅能提供有限的数据库支持,推荐你使用自己的更优的数据库解决方案

Sqlite

对于轻量级机器人应用,Sqlite 足以应对大部分的日常操作,connect_database 方法默认创建 Sqlite 数据库。

python
from amiyabot.database import *  # 引入数据库模块
+
+db = connect_database('database_name')  # 创建或连接一个 Sqlite 数据库文件
+
+
+# 创建数据库基础模型,继承 ModelClass 获得 AmiyaBot 的扩展查询方法
+class BotBaseModel(ModelClass):
+    class Meta:
+        database = db
+
+
+# 创建表模型,使用 table 装饰器进行表结构管理,将会自动创建或更新表结构
+@table
+class TableName(BotBaseModel):
+    field1 = CharField()
+    field2 = IntegerField(null=True)
+
+
+TableName.select()  # ORM 操作详见 peewee 文档

MySQL

connect_database 参数设置 mysql=True 以及 config 即可更改为 MySQL 数据库。

可自动创建数据库。

python
from amiyabot.database import *
+
+db = connect_database('database_name', is_mysql=True, config=MysqlConfig(
+    host='127.0.0.1',
+    port=3306,
+    user='root',
+    password=''
+))

表结构管理

在 table 装饰的表模型内增加或删除字段,启动程序时会自动修改到数据库表结构中。暂不支持更新字段类型。

python
@table
+class TableName(BotBaseModel):
+    field1 = CharField()
+    field2 = IntegerField(null=True)
+    field3 = TextField(null=True)
+    ...

扩展查询

内置了部分扩展查询,方便日常使用。

batch_insert

批量插入

参数名类型释义默认值
rowsList[dict]数据列表
chunk_sizeint分片插入大小200
python
data = [
+    {...},
+    {...},
+    {...}, ...
+]
+
+TableName.batch_insert(data)

insert_or_update

插入或更新(适配Sqlite和MySQL)

参数名类型释义默认值
insertdict如果是插入的数据
updatedict如果是更新的数据None
conflict_targetlist构成约束的列(仅Sqlite需要)None
preservelist一个列的列表,其值应从原始插入中保留None

查询转换工具

convert_model

将查询结果转换为字典

参数名类型释义默认值
modelpeewee 查询结果
select_modelSelectpeewee 查询对象
python
data = convert_model(TableName.get_or_none())

query_to_list

将查询结果转换为字典列表

参数名类型释义默认值
querylistpeewee 查询结果
select_modelSelectpeewee 查询对象
python
data = query_to_list(TableName.select())

select_for_paginate

分页查询工具

参数名类型释义默认值
modelModelSelectpeewee 查询对象
pageint当前页
page_sizeint页行数
python
data = select_for_paginate(TableName.select(), 1, 10)
+
+data['list']  # 查询结果
+data['total'] # 总条数
+ + + + \ No newline at end of file diff --git a/develop/advanced/eventBus.html b/develop/advanced/eventBus.html new file mode 100644 index 00000000..2f1f252f --- /dev/null +++ b/develop/advanced/eventBus.html @@ -0,0 +1,27 @@ + + + + + + 事件总线 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

事件总线

AmiyaBot 提供了简易的全局事件总线的方法

python
from amiyabot import event_bus

发布事件

publish

参数名类型释义默认值
event_namestr事件名
dataAny事件数据None
python
event_bus.publish('myEvent', data=...)

订阅事件

subscribe

参数名类型释义默认值
event_namestr事件名
methodCallable响应方法(可选)None

提示

响应方法同时支持异步同步函数

通过装饰器订阅事件

python
@event_bus.subscribe('myEvent')
+async def event_handler(data):
+    ...

也可以通过传入响应函数订阅事件

python
async def event_handler(data):
+    ...
+
+event_bus.subscribe('myEvent', event_handler)

取消订阅

取消订阅需要传入订阅时的响应方法对象(且需要保证其内存地址是一致的)

unsubscribe

参数名类型释义默认值
event_namestr事件名
methodCallable响应方法None
python
event_bus.unsubscribe('myEvent', event_handler)
+ + + + \ No newline at end of file diff --git a/develop/advanced/httpRequests.html b/develop/advanced/httpRequests.html new file mode 100644 index 00000000..30149b26 --- /dev/null +++ b/develop/advanced/httpRequests.html @@ -0,0 +1,38 @@ + + + + + + 发送 HTTP 请求 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

发送 HTTP 请求

AmiyaBot 内置了异步的 HTTP 请求工具,基于 aiohttp

不推荐使用 requests 库

requests 是著名的 python http 请求工具库。但其请求方法均为同步的。AmiyaBot 为异步程序,使用同步请求将会阻塞主线程运行。

如果是无法干预的同步请求行为,可以使用内置的线程池方法更变为异步。详见 处理阻塞操作

直接引入 http_requests 实例和 download_async 方法即可使用。

python
from amiyabot.network.httpRequests import http_requests
+from amiyabot.network.download import download_async
+
+await http_requests.get()
+await http_requests.post()
+await http_requests.post_form()
+await http_requests.post_upload()
+await http_requests.request()
+await download_async()

返回值

http_requests 的请求均返回字符串的请求结果(如果请求失败会返回空字符串),但有些不一样。这个 “字符串” 可以使用一些额外的属性。

json

调用这个属性会尝试返回 json 格式化的 responseText 内容。

python
res = await http_requests.post('/interface', {...})
+if res:
+    data = res.json['data']

response

调用这个属性可以返回请求结果(aiohttp.ClientResponse 的实例),可以获取请求的状态码和其他信息。

python
res = await http_requests.post('/interface', {...})
+
+status = res.response.status

error

如果请求失败,可以调用这个属性获取异常(Exception 的实例)。

python
res = await http_requests.post('/interface', {...})
+
+error = res.error

GET 请求

python
res: str = await http_requests.get()
参数名类型释义默认值
interfacestr请求地址
**kwargsrequest 参数

POST 请求

post 方法默认在请求头内添加 'Content-Type': 'application/json',请求体仅接受字典或列表类型数据

python
res: str = await http_requests.post()
参数名类型释义默认值
interfacestr请求地址
payloaddict, list请求体
headersdict追加的请求头
**kwargsrequest 参数

FORM 表单请求

post_form 方法类似 post 方法。唯一不同的是请求体仅接受字典类型,发送请求时会被构建为 form data 表单数据。

python
res: str = await http_requests.post_form()
参数名类型释义默认值
interfacestr请求地址
payloaddict请求体
headersdict追加的请求头
**kwargsrequest 参数

文件上传

文件上传 post_upload 方法以 form 表单的方式提交文件。

python
res: str = await http_requests.post_upload()
参数名类型释义默认值
interfacestr请求地址
filebytes文件 bytes
filenamestr文件名file
file_fieldstr表单数据中存放文件的字段名file
payloaddict请求体
headersdict追加的请求头
**kwargsrequest 参数

自定义请求

如果需要发送更多类型的请求,如 PUTPATCHDELETE 等,或需要自定义更多的请求场景,可使用 request 方法。

python
res: str = await http_requests.request()
参数名类型释义默认值
urlstr请求地址
methoddict请求方法post
request_namedict请求过程的 LOG 标识
**kwargsrequest 参数

下载文件

download_async 是提供的异步下载文件的方法。默认返回 bytes 类型的数据。

python
file: bytes = await download_async()
参数名类型释义默认值
urlstr请求地址
headersdict追加的请求头
stringifybool是否返回字符串结果False
**kwargsrequest 参数

同步下载

如某些场景需要使用同步下载,可使用同模块中的 download_async 方法。

python
from amiyabot.network.download import download_sync
+
+file: bytes = download_sync()
参数名类型释义默认值
urlstr请求地址
headersdict追加的请求头
stringifybool是否返回字符串结果False
progressbool是否显示进度条False
**kwargsrequest 参数
+ + + + \ No newline at end of file diff --git a/develop/advanced/httpSupport.html b/develop/advanced/httpSupport.html new file mode 100644 index 00000000..3990c54b --- /dev/null +++ b/develop/advanced/httpSupport.html @@ -0,0 +1,42 @@ + + + + + + HTTP服务器支持 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

HTTP服务器支持

AmiyaBot 内置了基于 FastApi 的HTTP服务构建工具。

创建服务

HttpServer 类

参数名类型释义默认值
hoststr服务监听地址
portint服务监听端口
titlestrswagger 页面标题AmiyaBot
descriptionstrswagger 页面注释https://www.amiyabot.com
auth_keystr请求头密钥
fastapi_optionsdictFastAPI **kwargs
uvicorn_optionsdictuvicorn.Config **kwargs
python
from amiyabot import HttpServer
+
+server = HttpServer(host='0.0.0.0', port=8088)
+
+
+@server.controller
+class Bot:
+    @server.route(method='get')
+    async def get_name(self):
+        return 'AmiyaBot'
+
+    @server.route(method='post')
+    async def say_hello(self):
+        return server.response(message='hello')
+
+
+asyncio.run(server.serve())

运行代码,访问 http://127.0.0.1:8088/docs 即可看到生成了如下两个接口。

/bot/getName
+/bot/sayHello

自定义路由

接口的路由将默认使用控制器类名以及方法名组成,如果需要自定义路由,在方法装饰器 route 传入 router_path 参数即可。

python
@server.route(method='get', router_path='/custom/getBotName')
+async def get_name(self):
+    ...

请求头密钥

在创建 HttpServer 时传入 auth_key 参数,则在调用接口时,需要在请求头(Header)里添加 authKey 字段并匹配参数的值,才允许访问。

python
server = HttpServer(..., auth_key='my_auth_key')

FastApi 扩展

AmiyaBot 仅对 FastApi 的路由注册做了简易的封装。如需要扩展其用法,可获取 app 实例后参考官方文档进一步使用。

python
server = HttpServer()
+app: FastAPI = server.app
+ + + + \ No newline at end of file diff --git a/develop/advanced/index.html b/develop/advanced/index.html new file mode 100644 index 00000000..a50251ca --- /dev/null +++ b/develop/advanced/index.html @@ -0,0 +1,22 @@ + + + + + + 进阶指南 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

进阶指南

本篇章将会深入讲解 AmiyaBot 的一些高级用法。包括如何控制日志、介入生命周期、创建定时任务、加载插件以及额外支持的数据库 ORM 和 HTTP 服务等。这将有助于你构建一个复杂的,更有逻辑性的机器人。

和基础开发指南一样,在本章后续文档中,为了减少篇幅量,将不会再在代码示例中出现 AmiyaBot 类的实例化代码。统一以变量 bot 表示已经实例化的 AmiyaBot 类。

+ + + + \ No newline at end of file diff --git a/develop/advanced/lifeCycle.html b/develop/advanced/lifeCycle.html new file mode 100644 index 00000000..f23085ef --- /dev/null +++ b/develop/advanced/lifeCycle.html @@ -0,0 +1,43 @@ + + + + + + 生命周期 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

生命周期

AmiyaBot 接收的消息和事件,都会历经一个完整的生命周期。你可以介入这些周期来对业务进行进一步的调整。

消息生命周期

在接收消息到回复发送完毕,总共会经过至少五个周期,如下图所示,紫色的节点就是可以介入的周期。

如果消息响应里存在等待事件,那么周期将会延长,再次从消息接收开始,直至等待事件结束后继续向下执行。

通过 AmiyaBot 对象或 PluginInstance 对象注册周期钩子函数。

所有钩子均可以同时存在多个,按加载顺序逐个调用。

message_created

消息创建完毕阶段,可以在此阶段修改 Message 对象并返回。存在多个此钩子时,按加载顺序逐个调用,参数接受的 Message 对象受上一个函数的执行结果影响。

该钩子函数可返回三种结果:

  • None:对后续不产生影响
  • Message:修改 Message 对象,将影响后续所有周期进程的参数
  • False:布尔值仅可返回 False,将结束生命周期(包括此周期后续的钩子函数)
python
@bot.message_created
+async def _(data: Message, instance: BotAdapterProtocol):
+    if ...:
+        data.text = ...
+        return data

message_before_waiter_set

当存在等待事件且消息分配器无返回或等待事件属于强制等待类型时,在进入等待事件前执行此钩子。

python
from amiyabot import Waiter
+
+@bot.message_before_waiter_set
+async def _(data: Message, waiter: Waiter, instance: BotAdapterProtocol):
+    ...

message_before_handle

当消息分配器有返回,在执行消息响应器前执行此钩子。存在多个此钩子时,按加载顺序逐个调用。全部执行完成后当有其中一个返回 False,则不往下继续执行并结束生命周期。

python
@bot.message_before_handle
+async def _(data: Message, factory_name: str, instance: BotAdapterProtocol):
+    if ...:
+        return False
+    return True

message_before_send

当消息响应器执行完毕且存在返回时,在发送其返回前执行此钩子。可以在此阶段修改 Chain 对象并返回。存在多个此钩子时,按加载顺序逐个调用,参数接受的 Chain 对象受上一个函数的执行结果影响。

python
@bot.message_before_send
+async def _(chain: Chain, factory_name: str, instance: BotAdapterProtocol):
+    ...
+    return chain

message_after_send

当消息响应器执行完毕且存在返回时,在发送其返回结束后执行此钩子。

python
@bot.message_after_send
+async def _(chain: Chain, factory_name: str, instance: BotAdapterProtocol):
+    ...

message_after_handle

当消息响应器执行完毕(无论有没有返回)后执行此钩子。

python
@bot.message_after_handle
+async def _(chain: Optional[Chain], factory_name: str, instance: BotAdapterProtocol):
+    ...

事件生命周期

目前事件生命周期只有一个。

python
@bot.event_created
+async def _(event: EventType, instance: BotAdapterProtocol):
+    ...
+ + + + \ No newline at end of file diff --git a/develop/advanced/loadPlugins.html b/develop/advanced/loadPlugins.html new file mode 100644 index 00000000..7f78f9e6 --- /dev/null +++ b/develop/advanced/loadPlugins.html @@ -0,0 +1,69 @@ + + + + + + 加载插件 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

加载插件

本篇将会讲解 AmiyaBot 插件的工作原理以及插件导入和卸载的方法。

前言

插件设计的目的是因为 兔兔-v6 通常会以可执行文件的形式发布,将一些功能模块分散为插件的形式,更有助于用户灵活的管理自己的机器人功能,以及对单独的功能进行热更新。

AmiyaBot 的插件加载得益于 Python 作为脚本语言的一个优点:动态执行代码,配合标准库的 importlibzipimport,就能够很好的完成外部代码的导入与执行,理解这一原理,需要你熟悉 Python 的导入机制。而“动态执行代码”,如果你不是第一次接触脚本语言,想必你对其应有了一定的了解。

开发插件

开发插件可以参考主项目的 插件开发 形式,但本篇并不是作为主项目的引导文档。在主项目里,插件是一个 zip 压缩包,在加载时解压并导入,完成代码的动态执行。

但在本框架的设计里,插件还能有另外几种导入方式。

导入插件实例

插件实例可以直接在你的程序里定义,这是正常的做法,事实上这对你的功能管理(如动态增加或软删除功能时)有很大帮助。

python
from amiyabot import AmiyaBot, PluginInstance
+
+plugin = PluginInstance(
+    name='我的插件',
+    version='1.0',
+    plugin_id='my-plugin',
+    description='我的第一个插件'
+)
+
+@plugin.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')
+
+
+bot = AmiyaBot(...)  # or MultipleAccounts
+bot.install_plugin(plugin)

此时,该 AmiyaBot 实例便拥有了这个插件定义的所有消息响应、事件或定时任务等功能。

导入 Python 文件

这是写有插件注册代码的一个 Python 文件 myPlugin.py

python
from amiyabot import PluginInstance
+
+# bot 变量名是必须的,详见插件开发文档。
+bot = PluginInstance(
+    name='我的插件',
+    version='1.0',
+    plugin_id='my-plugin',
+    description='我的第一个插件'
+)
+
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')

以 Python 文件导入这个插件

python
bot.install_plugin('myPlugin.py') # 相当于执行了代码:import myPlugin

单文件插件是最简单的开发方式,这是在不考虑文件大小、静态资源或变量污染的前提下。

导入 Python Package 目录

如果一个插件的逻辑非常复杂,它可能会是以 Package 目录的形式存在。此时插件的目录应如下所示。

text
myPlugin
+├── __init__.py
+├── a.py
+├── b.py
+│   ...
+...

以目录导入这个插件

python
bot.install_plugin('myPlugin') # 相当于执行了代码:import myPlugin

导入 zip 压缩包

如果一些插件甚至带有静态资源,虽然 Package 目录同样能实现,但为了方便传播,它可能会是一个 zip 压缩文件。

text
myPlugin.zip
+├── assetsFolder
+├── config.yaml
+├── __init__.py
+├── a.py
+├── b.py
+│   ...
+...

以 zip 导入这个插件

python
bot.install_plugin('myPlugin.zip')

这里将会发生另一种情况,在 zip 导入时,并不是像上述两种方式一样相当于执行
import myPlugin 语句。而是通过标准库 zipimport,读取了此压缩包,并执行 __init__.py

这有点抽象,你可以理解为使用了 python 命令执行了 __init__.py

bash
python __init__.py

那么当 __init__.py 在相对导入其目录下的模块时,由于它属于顶级模块,插件将会 加载失败 并抛出如下异常。

python
from .main import bot
text
plugin install error: Traceback (most recent call last):
+  File "F:\Project\Amiya-Bot-core\amiyabot\log\manager.py", line 116, in sync_catch
+    yield
+  File "F:\Project\Amiya-Bot-core\amiyabot\handler\__init__.py", line 287, in install_plugin
+    module = zipimport.zipimporter(plugin).load_module('__init__')
+  File "<frozen zipimport>", line 259, in load_module
+  File "plugins\myPlugin.zip\__init__.py", line 1, in <module>
+    from .main import bot
+ImportError: attempted relative import with no known parent package

install_plugin 里提供了参数解决这一问题。先看看这个方法的参数列表。

参数名类型释义默认值
pluginstr, PluginInstance插件(文件、package 的路径或 PluginInstance 实例)
extract_pluginbool是否解压插件False
extract_plugin_deststr插件解压后的目录名(默认为 zip 文件名)

解决上述问题,我们只需要添加参数 extract_plugin=True,将 zip 导入转换为 Package 目录导入。

python
bot.install_plugin('myPlugin.zip', extract_plugin=True)

注意

每次执行加载时都会解压一次全部文件,但如果路径已存在,将不会覆盖原文件。如果插件有一些原文件修改的更新,应注意这一特性。

卸载插件

插件实例都有一个唯一 ID(属性 plugin_id),通过这个 ID 可以卸载指定的插件。

uninstall_plugin

参数名类型释义默认值
plugin_idstr插件 ID
removebool是否删除插件的原文件False
python
bot.uninstall_plugin('my-plugin')
+ + + + \ No newline at end of file diff --git a/develop/advanced/logger.html b/develop/advanced/logger.html new file mode 100644 index 00000000..c4c83b24 --- /dev/null +++ b/develop/advanced/logger.html @@ -0,0 +1,70 @@ + + + + + + 日志模块 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

日志模块

AmiyaBot 使用 logging 模块构建日志体系。

输出日志

AmiyaBot 的日志同样拥有与 logging 相同的等级输出。输出的日志会储存在 log 文件夹下。

python
from amiyabot import log
+
+log.info(...)
+log.error(...)
+log.debug(...)
+log.warning(...)
+log.critical(...)

日志的固有格式如下所示,分别为时间日志模块名日志等级日志内容。DEBUG 模式下会显示日志的输出文件名和位置。

normal:
+2022-11-02 18:22:40,425 [     Bot][    INFO] initialize completed.
+
+debug mode:
+2022-11-02 18:22:40,425 [     Bot][    INFO][test.py:5] initialize completed.

提示

使用启动参数 --debug 开启 DEBUG 模式。

输出异常日志

log.error() 方法不仅可以传入字符串,也支持传入 Exception 的子类。传入 Exception 子类时,将会输出完整的异常追踪(Traceback)。

python
try:
+    a = 0
+    a += '1'
+except Exception as e:
+    log.error(e, desc='calc error:')

将输出如下日志

2022-11-02 18:44:22,155 [     Bot][   ERROR] calc error: Traceback (most recent call last):
+  File "F:\Project\Amiya-Bot-core\logTest.py", line 5, in <module>
+    a += '1'
+TypeError: unsupported operand type(s) for +=: 'int' and 'str'

如果你并不需要处理异常,仅仅希望异常不会终止你的程序,log 模块提供了上下文管理的方式,来捕获并输出在上下文中产出的异常。

参数名类型释义默认值
descstr异常标题
ignoreList[Type[Exception]]仅捕获但不输出的异常列表None
handlerCallable捕获异常后执行的方法None
python
async def err_handler(err: Exception):
+    print(err)
+
+# 异步方式
+async with log.catch('calc error:', ignore=[TypeError, ...], handler=err_handler):
+    a = 0
+    a += '1'
+
+# 同步方式
+with log.sync_catch(...):
+    a = 0
+    a += '1'

创建日志模块

你可以创建一个独立的日志模块以标记输出。

python
from amiyabot.log import LoggerManager
+
+logger = LoggerManager('MyLogger')
+logger.info('this is a log.')
+
+# 2022-11-02 18:32:05,053 [MyLogger][    INFO] this is a log.

LoggerManager

参数名类型释义默认值
namestrlogger 模块名称
levelint日志等级logging.INFO
formatterstr日志格式%(asctime)s [%(name)8s][%(levelname)8s]%(message)s
save_pathstr日志文件保存目录log
save_filenamestr日志文件名running

自定义全局日志模块

如果你不喜欢默认的日志输出,你也可以全局修改日志模块。但必须注意的事,你自定义的模块,必须包含常规的几个等级输出方法。

python
from amiyabot.log import UserLogger
+
+
+class Mylogger:
+    def info(self, text: str): ...
+
+    def error(self, text: str): ...
+
+    def debug(self, text: str): ...
+
+    def warning(self, text: str): ...
+
+    def critical(self, text: str): ...
+
+
+UserLogger.logger = Mylogger() # 将默认日志处理替换为自定义的类
+ + + + \ No newline at end of file diff --git a/develop/advanced/playwright.html b/develop/advanced/playwright.html new file mode 100644 index 00000000..191dcfd3 --- /dev/null +++ b/develop/advanced/playwright.html @@ -0,0 +1,45 @@ + + + + + + 改变 Playwright 启动 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

改变 Playwright 启动

改变默认的 Playwright 启动行为。

python
from playwright.async_api import Playwright, Browser
+from amiyabot import BrowserLaunchConfig
+
+
+class MyBrowserLauncher(BrowserLaunchConfig):
+    def __init__(self):
+        super().__init__()
+
+        self.browser_type = 'firefox'  # 修改浏览器属性
+
+    # 或改写 launch_browser 方法
+    async def launch_browser(self, playwright: Playwright) -> Browser:
+        ...
+
+        # 返回通过任意方式创建的 Browser 对象
+        # return await playwright.webkit.launch()
+        # return await playwright.chromium.launch()
+        return await playwright.firefox.launch()
+
+
+bot = AmiyaBot()
+asyncio.run(
+    bot.start(launch_browser=MyBrowserLauncher())
+)
+ + + + \ No newline at end of file diff --git a/develop/advanced/startupParameter.html b/develop/advanced/startupParameter.html new file mode 100644 index 00000000..df20f47e --- /dev/null +++ b/develop/advanced/startupParameter.html @@ -0,0 +1,22 @@ + + + + + + 启动参数 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

启动参数

使用启动参数修改一些内置变量

参数是否需要值默认值释义
--debug以 DEBUG 模式启动程序
--browser-width1280浏览器视窗默认宽度(px)
--browser-height720浏览器视窗默认高度(px)
--browser-render-time200浏览器默认渲染时间(ms)
--text-max-length100Chain 对象转换文字图片的文字长度最大值
--browser-page-not-close取消自动关闭 playwright 的网页窗口

在 兔兔-v6 下使用

代码部署

bash
python amiya.py --text-max-length 200 --browser-render-time 1000

可执行文件部署

bash
AmiyaBot-v6.x.x-master.exe --debug --browser-page-not-close
+ + + + \ No newline at end of file diff --git a/develop/advanced/timedTask.html b/develop/advanced/timedTask.html new file mode 100644 index 00000000..e8b795fb --- /dev/null +++ b/develop/advanced/timedTask.html @@ -0,0 +1,63 @@ + + + + + + 定时任务 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

定时任务

AmiyaBot 提供了全局定时任务管理器,基于 apscheduler

⚠️注意⚠️不兼容的更新

在版本 1.6.9 开始,不再支持全局定义定时任务,以及移除了 custom 参数,使用更泛用的 apscheduler trigger 控制任务执行时机。

此方法已不再支持,全局变量 tasks_control 已删除。

python
from amiyabot import AmiyaBot, tasks_control
+
+@tasks_control.timed_task(each=120)
+async def _():
+    ...

bot.timed_task 装饰器的 custom 参数已删除。

参数名类型释义默认值
eachint循环执行间隔时间,单位(秒)
customCallable自定义循环规则
sub_tagstr子标签default_tag

简单使用

python
from amiyabot import AmiyaBot
+from amiyabot.factory import BotHandlerFactory
+
+bot = AmiyaBot(...)  # 或 MultipleAccounts / PluginInstance 对象
+
+# 每 60 秒执行一次任务
+@bot.timed_task(each=60)
+async def _(instance: BotHandlerFactory):
+    ...

插件开发

如果你正在开发插件,并且你不希望在插件的卸载方法里手动取消定时任务,请务必通过 PluginInstance.timed_task 定义任务。

通过 PluginInstance.timed_task 定义的任务可以在插件被卸载时自动取消。

python
from amiyabot import PluginInstance
+from amiyabot.factory import BotHandlerFactory
+
+bot = PluginInstance(...)
+
+@bot.timed_task(each=60)
+async def _(instance: BotHandlerFactory):
+    ...

插件开发详情请查看 插件开发文档

timed_task 装饰器

参数名类型释义默认值
eachint循环执行间隔时间,单位(秒),如果使用其他触发方式,请使用 kwargs 形式的 scheduler.add_job 参数None
sub_tagstr子标签default_tag
run_when_addedbool添加时立即执行一次任务default_tag
**kwargsscheduler.add_job 参数

注意

使用 kwargs 自定义定时任务时,不可使用参数 func 以及 id

自定义执行时机

使用 scheduler.add_job 参数定义任务,可以使任务的执行时机更加灵活。

python
from amiyabot import PluginInstance
+from amiyabot.factory import BotHandlerFactory
+from apscheduler.triggers.cron import CronTrigger
+
+bot = PluginInstance(...)
+
+# 每个小时中的 5 分 30 秒时执行
+@bot.timed_task(trigger='cron', minute=5, second=30)
+async def _(instance: BotHandlerFactory):
+    ...
+
+# 每分钟的第 20 秒和 40 秒时执行
+@bot.timed_task(trigger=CronTrigger('20,40'))
+async def _(instance: BotHandlerFactory):
+    ...

取消定时任务

为需要取消的定时任务传入 sub_tag 参数,可以重复,重复的 sub_tag 会被整合为一组。

bot.remove_timed_task()

按标签名取消定时任务

参数名类型释义默认值
sub_tagstr需要取消的定时任务的子标签名

示例:执行一次后取消任务

python
from amiyabot import PluginInstance
+from amiyabot.factory import BotHandlerFactory
+
+bot = PluginInstance(...)
+
+@bot.timed_task(each=60, sub_tag='test')
+async def _(instance: BotHandlerFactory):
+    ...
+    bot.remove_timed_task('test')
+ + + + \ No newline at end of file diff --git a/develop/basic/api/index.html b/develop/basic/api/index.html new file mode 100644 index 00000000..e52b5d69 --- /dev/null +++ b/develop/basic/api/index.html @@ -0,0 +1,30 @@ + + + + + + API | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

API

API 是实现适配器部分基础逻辑的基础,你也可以调用 API 来进一步完成你的业务逻辑。

api 属性位于 AmiyaBotinstance 属性下。

python
bot = AmiyaBot(...)
+
+await bot.instance.api.get_me()

请注意

不用的适配器下,api 的方法不尽相同,在创作多平台机器人时,请注意可能产生的影响。

引入 API 类以注解变量

我们强烈建议在使用不同的适配器时,引入相应的 API 类注解 api 属性。它们通常在适配器模块的 api 模块下。

python
from amiyabot.adapters.tencent.qqGuild.api import QQGuildAPI
+# from amiyabot.adapters.cqhttp.api import CQHttpAPI
+# from amiyabot.adapters.kook.api import KOOKAPI
+
+
+api: QQGuildAPI = bot.instance.api
+await api.get_me()

共同的方法

api 实际上是调用了不同平台提供的接口。在不同平台下,调用接口的鉴权规则也不一样。所有适配器的 api 都存在以下三个方法,参数也是一样的。方法内部实现了不同平台的鉴权规则,你只需要直接调用接口即可。

get

参数名类型释义默认值
urlstr接口 url
paramsUnion[dict, None]get 参数
**kwargsrequest 参数

post

参数名类型释义默认值
urlstr接口 url
payloadUnion[dict, None]post 参数
is_form_databool是否使用 form 表单提交(仅 QQ 频道拥有此参数)
**kwargsrequest 参数

request

可以使用除 get、post 以外的一些 method 调用接口。

参数名类型释义默认值
urlstr接口 url
methodstr请求 method
payloadUnion[dict, None]请求参数
**kwargsrequest 参数
python
res = await bot.instance.api.post('/interface', {...})

为什么没有 headers 参数

方法内部实现了不同平台的鉴权规则,控制了 headers 的内容,你不需要手动控制。如果你希望自己实现请求,请使用 👉 进阶指南 - HTTP 请求

api 的返回

参考 进阶指南 - HTTP 请求 - 返回值

+ + + + \ No newline at end of file diff --git a/develop/basic/api/qqbot.html b/develop/basic/api/qqbot.html new file mode 100644 index 00000000..a160d7b6 --- /dev/null +++ b/develop/basic/api/qqbot.html @@ -0,0 +1,22 @@ + + + + + + QQ 频道 API | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

QQ 频道 API

🚧 API 文档尚处于建设阶段,缺少 api 说明和参数释义,请酌情阅读。🚧

add_message_reaction

参数名类型释义默认值
channel_idstr
message_idstr
emoji_typeint
emoji_idstr

add_pin

参数名类型释义默认值
channel_idstr
message_idstr

create_announces

参数名类型释义默认值
guild_idstr
message_idUnion[str, None]
channel_idUnion[str, None]
announces_typeUnion[int, None]
recommend_channelsUnion[str, None]

create_channel

参数名类型释义默认值
guild_idstr
channel_namestr
channel_typeint
channel_sub_typeint
positionUnion[int, None]
parent_idUnion[str, None]
private_typeUnion[int, None]
private_user_idsUnion[List[str], None]
speak_permissionUnion[int, None]
application_idUnion[str, None]
参数名类型释义默认值
guild_idstr
channel_idstr
pathstr
methodstr
descstr

create_guild_role

参数名类型释义默认值
guild_idstr
nameUnion[str, None]
colorUnion[int, None]
hoistint

create_schedule

参数名类型释义默认值
channel_idstr
namestr
descriptionstr
start_timestampstr
end_timestampstr
creatorUnion[dict, None]
jump_channel_idUnion[str, None]
remind_typeUnion[str, None]

create_thread

参数名类型释义默认值
channel_idstr
titlestr
contentstr
thread_formatint

delete_announces

参数名类型释义默认值
guild_idstr
message_idUnion[str, None]

delete_channel

参数名类型释义默认值
channel_idstr

delete_guild_member

参数名类型释义默认值
guild_idstr
user_idstr
add_blacklistbool
delete_history_msg_daysint

delete_guild_role

参数名类型释义默认值
guild_idstr
role_idstr

delete_message

参数名类型释义默认值
message_idstr
target_idstr
is_directbool
hidetipbool

delete_message_reaction

参数名类型释义默认值
channel_idstr
message_idstr
emoji_typeint
emoji_idstr

delete_pin

参数名类型释义默认值
channel_idstr
message_idstr

delete_schedule

参数名类型释义默认值
channel_idstr
schedule_idstr

delete_thread

参数名类型释义默认值
channel_idstr
thread_idstr

delete_user_role

参数名类型释义默认值
guild_idstr
user_idstr
role_idstr

gateway

参数名类型释义默认值

gateway_bot

参数名类型释义默认值

get_channel

参数名类型释义默认值
channel_idstr

get_channel_online_nums

参数名类型释义默认值
channel_idstr

get_channels

参数名类型释义默认值
guild_idstr

get_guild

参数名类型释义默认值
guild_idstr

get_guild_api_permission

参数名类型释义默认值
guild_idstr

get_guild_member

参数名类型释义默认值
guild_idstr
user_idstr

get_guild_members

参数名类型释义默认值
guild_idstr
afterstr
limitint

get_guild_roles

参数名类型释义默认值
guild_idstr

get_guild_roles_members

参数名类型释义默认值
guild_idstr
role_idstr
start_indexstr
limitint

get_guilds

参数名类型释义默认值
beforeUnion[str, None]
afterUnion[str, None]
limitint

get_me

参数名类型释义默认值

get_me_dms

参数名类型释义默认值
recipient_idstr
src_guild_idstr

get_message

参数名类型释义默认值
channel_idstr
message_idstr

get_message_reactions

参数名类型释义默认值
channel_idstr
message_idstr
emoji_typeint
emoji_idstr
cookieUnion[str, None]
limitint

get_message_setting

参数名类型释义默认值
guild_idstr

get_pins

参数名类型释义默认值
channel_idstr

get_role_permission

参数名类型释义默认值
channel_idstr
role_idstr

get_schedule

参数名类型释义默认值
channel_idstr
schedule_idstr

get_schedules

参数名类型释义默认值
channel_idstr
sinceint

get_thread

参数名类型释义默认值
channel_idstr
thread_idstr

get_threads

参数名类型释义默认值
channel_idstr

get_user_avatar

参数名类型释义默认值
args_empty
kwargs_empty

get_user_permission

参数名类型释义默认值
channel_idstr
user_idstr

modify_channel

参数名类型释义默认值
channel_idstr
channel_namestr
positionUnion[int, None]
parent_idUnion[str, None]
private_typeUnion[int, None]
speak_permissionUnion[int, None]

modify_guild_role

参数名类型释义默认值
guild_idstr
role_idstr
nameUnion[str, None]
colorUnion[int, None]
hoistint

modify_schedule

参数名类型释义默认值
channel_idstr
schedule_idstr
namestr
descriptionstr
start_timestampstr
end_timestampstr
creatorUnion[dict, None]
jump_channel_idUnion[str, None]
remind_typeUnion[str, None]

mute_all

参数名类型释义默认值
guild_idstr
mute_end_timestampstr
mute_secondsstr

mute_all_lift

参数名类型释义默认值
guild_idstr

mute_user

参数名类型释义默认值
guild_idstr
user_idstr
mute_end_timestampstr
mute_secondsstr

mute_user_lift

参数名类型释义默认值
guild_idstr
user_idstr

mute_users

参数名类型释义默认值
guild_idstr
user_idsList[str]
mute_end_timestampstr
mute_secondsstr

mute_users_lift

参数名类型释义默认值
guild_idstr
user_idsList[str]

post_message

参数名类型释义默认值
guild_idstr
src_guild_idstr
channel_idstr
reqMessageSendRequest

set_role_permission

参数名类型释义默认值
channel_idstr
role_idstr
addUnion[str, None]
removeUnion[str, None]

set_user_permission

参数名类型释义默认值
channel_idstr
user_idstr
addUnion[str, None]
removeUnion[str, None]

set_user_role

参数名类型释义默认值
guild_idstr
user_idstr
role_idstr
channel_idUnion[str, None]
+ + + + \ No newline at end of file diff --git a/develop/basic/chainBuild/ark.html b/develop/basic/chainBuild/ark.html new file mode 100644 index 00000000..830d0307 --- /dev/null +++ b/develop/basic/chainBuild/ark.html @@ -0,0 +1,30 @@ + + + + + + Ark 消息 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

Ark 消息

发送 QQ 频道 ARK 模板消息,详情请查看发送 ark 消息

Chain().ark()

参数名类型释义默认值
template_idstr模版 ID
kvList[dict]模版 key-value 数据
python
kv_data = [
+    {'key': '#PROMPT#', 'value': '通知提醒'},
+    {'key': '#METATITLE#', 'value': '标题'},
+    {'key': '#METASUBTITLE#', 'value': '子标题'},
+    {'key': '#METACOVER#', 'value': 'https://vfiles.gtimg.cn/vupload/20211029/bf0ed01635493790634.jpg'},
+    {'key': '#METAURL#', 'value': 'https://qq.com'},
+]
+
+Chain(data, at=False).ark(37, kv_data)

+ + + + \ No newline at end of file diff --git a/develop/basic/chainBuild/at.html b/develop/basic/chainBuild/at.html new file mode 100644 index 00000000..f0f8c555 --- /dev/null +++ b/develop/basic/chainBuild/at.html @@ -0,0 +1,22 @@ + + + + + + At | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

At

发送 @XXX

Chain().at()

提示

私信回复里无效

参数名类型释义默认值
userint, str@ 的用户ID,默认为 Message 对象的用户
enterbool是否 @ 用户后换行False
python
Chain(data).at(12345678).text('hello, world')

Chain 对象在实例化的时候,默认会在消息体头部添加 @XXX

+ + + + \ No newline at end of file diff --git a/develop/basic/chainBuild/atAll.html b/develop/basic/chainBuild/atAll.html new file mode 100644 index 00000000..597b9d8d --- /dev/null +++ b/develop/basic/chainBuild/atAll.html @@ -0,0 +1,22 @@ + + + + + + At 所有人 | AmiyaBot + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/develop/basic/chainBuild/embed.html b/develop/basic/chainBuild/embed.html new file mode 100644 index 00000000..cb118cf1 --- /dev/null +++ b/develop/basic/chainBuild/embed.html @@ -0,0 +1,27 @@ + + + + + + Embed 消息 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

Embed 消息

发送 QQ 频道卡片消息,详情请查看 embed 消息

Chain().embed()

参数名类型释义默认值
titlestr标题
promptstr消息弹窗内容
thumbnailstr缩略图 url
fieldsList[str]embed 字段数据
python
Chain(data, at=False).embed(
+    '标题',
+    '消息通知',
+    'xxxxxx',
+    ['当前等级:黄金', '之前等级:白银', '😁继续努力'],
+)

+ + + + \ No newline at end of file diff --git a/develop/basic/chainBuild/extend.html b/develop/basic/chainBuild/extend.html new file mode 100644 index 00000000..6b7df4e9 --- /dev/null +++ b/develop/basic/chainBuild/extend.html @@ -0,0 +1,50 @@ + + + + + + 原生模板 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

原生模板

使用原生消息模板扩展 Chain 对象

温馨提示

消息扩展暂仅支持 mirai-api-httpcq-http

除了以上内置的消息类型外,mirai-api-httpcq-http 还提供了多种消息类型用于发送丰富的消息内容。

Chain().extend()

参数名类型释义默认值
dataAny原始消息类型格式数据

示例

使用 mirai-api-http 消息类型 Dice 发送一个点数 6 的骰子魔法表情

python
Chain(data).extend(
+    {
+        'type': 'Dice',
+        'value': 6
+    }
+)

使用 go-cqhttp 消息类型 链接分享 发送一个百度首页链接分享

python
Chain(data).extend(
+    {
+        'type': 'share',
+        'data': {
+            'url': 'https://www.baidu.com',
+            'title': '百度'
+        }
+    }
+)

发送 CQ 码

发送 CQ 码目前仅支持 cq-http 适配器。可通过适配器的 API 对象发送或扩展消息发送。

python
from amiyabot import CQCode, CQHttpBotInstance
+
+instance: CQHttpBotInstance = bot.instance
+
+
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    # 通过 API 发送
+    instance.api.send_cq_code(data.user_id,
+                              data.channel_id,
+                              f'hello, {data.nickname} [CQ:face,id=123]')
+
+    # 通过扩展消息发送
+    return Chain(data).extend(
+        CQCode(f'hello, {data.nickname} [CQ:face,id=123]')
+    )
+ + + + \ No newline at end of file diff --git a/develop/basic/chainBuild/face.html b/develop/basic/chainBuild/face.html new file mode 100644 index 00000000..ad7449bb --- /dev/null +++ b/develop/basic/chainBuild/face.html @@ -0,0 +1,22 @@ + + + + + + emoji 表情 | AmiyaBot + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/develop/basic/chainBuild/forward.html b/develop/basic/chainBuild/forward.html new file mode 100644 index 00000000..36e5bff1 --- /dev/null +++ b/develop/basic/chainBuild/forward.html @@ -0,0 +1,48 @@ + + + + + + 合并转发消息 Beta | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

合并转发消息 Beta

合并转发消息不是 Chain 对象的方法,需要使用适配器提供的工具类构建。

注意

QQ 频道机器人暂时不支持发送合并转发消息,目前仅支持 mirai-api-httpcq-http

python
from amiyabot.adapters.mirai import MiraiForwardMessage
+# from amiyabot.adapters.cqhttp import CQHTTPForwardMessage
+
+...
+
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    forward = MiraiForwardMessage(data)
+    # forward = CQHTTPForwardMessage(data)
+
+    chain = Chain().text(f'hello, {data.nickname}')
+
+    await forward.add_message(chain, user_id=..., nickname='...')
+    await forward.send()

添加自定义消息

add_message

参数名类型释义默认值
chainChain, listChain 对象,可为空 Chain
user_idint用户 ID
nicknamestr用户昵称(可自定义)
timeint发送时间0
  • user_id 为实际 QQ 用户的 QQ 号,可以是任意人,在合并消息内显示其头像。
  • nickname 为自定义的昵称。

如果 chain 参数传入了空 Chain,则 user_idnickname 为必须参数。

python
await forward.add_message(Chain(data).text(...))
+await forward.add_message(Chain().text(...), user_id=..., nickname='...')

添加指定 ID 的消息

add_message_by_id

参数名类型释义默认值
message_idint消息 ID
python
await forward.add_message_by_id(5128)

添加嵌套的合并转发消息

add_messagechain 参数传入 ForwardMessage 类的 node 属性,即可完成合并消息嵌套。

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    forward = MiraiForwardMessage(data)
+
+    await forward.add_message(...)
+    await forward.add_message(...)
+
+    forward2 = MiraiForwardMessage(data)
+
+    await forward2.add_message(forward.node, user_id=..., nickname='...')
+    await forward2.send()

发送 & 撤回

python
callback = await forward.send()  # 发送
+if callback:
+    await callback.recall()  # 撤回
+ + + + \ No newline at end of file diff --git a/develop/basic/chainBuild/html.html b/develop/basic/chainBuild/html.html new file mode 100644 index 00000000..9377dc4c --- /dev/null +++ b/develop/basic/chainBuild/html.html @@ -0,0 +1,39 @@ + + + + + + HTML 生成的图片 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

HTML 生成的图片

发送一张使用 html 页面生成的图片,在同等工作量下,它通常比使用 PIL 合成的图片更加生动,技术难度也比 PIL 要低得多。

操作系统支持

HTML制图需要使用 playwright 模块,所以仅支持以下操作系统:

  • Windows 10、Windows Subsystem for Linux (WSL) 或 Windows Server 2012 及以上系统
  • MacOS 11 (Big Sur) 及以上系统
  • Linux 系统官方支持 Debian 11、Ubuntu 18.04 以及 Ubuntu 20.04

安装 Chromium

命令行执行以下命令安装 Chromium 内核:

bash
# Windows or MacOS
+playwright install chromium
+# Linux
+playwright install --with-deps chromium

启动时打开 Chromium

在 bot(包括多账号实例)启动的 start 方法内设置参数 launch_browser=True

python
bot.start(launch_browser=True)

进阶使用:改变默认的 Playwright 启动行为

Chain().html()

参数名类型释义默认值
pathstr模板文件路径或网站URL
dataAny传入模板文件的数据(数据可被 json 序列化)
widthint浏览器视窗宽度1280
heightint浏览器视窗高度720
is_templatebool是否为模板文件True
render_timeint渲染时间(毫秒)200
python
Chain(data).html('template.html', {...})

创建html模板文件

创建文件 hello.html 并定义全局的 init 方法。

html
<!-- hello.html -->
+<div id="content"></div>
+
+<script>
+    // 必须定义全局的 init 方法,接收一个 data 参数
+    window.init = (data) => {
+        document.querySelector('#content').innerText = data.username
+    }
+</script>

将需要渲染的数据传入模板:

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).html('hello.html', {'username': data.nickname})

示例在触发会话并开始发送消息时,Chain 对象将会调用 Chromium 无头浏览器,渲染 hello.html 并在页面内执行 JavaScript 语句 init({'username': 'vivien8261'})
渲染结束后,无头浏览器截图生成图片,然后执行常规的图片发送方法。

image

发挥你的想象,写出更美观的页面!

兔兔-v6 效果
image

通过网站URL制图

支持直接使用网站URL生成图片。

注意

在页面加载完毕后,默认预留200ms的渲染时间。如果页面有部分元素是异步渲染的,将有可能不显示在图片内。可通过参数 render_time 设置需要的时间。

设置参数 is_template=False

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).html('https://www.baidu.com/',
+                            is_template=False,
+                            render_time=1000)

触发会话时,渲染 https://www.baidu.com/ 页面,并在等待 1000ms 后截图发送图片。

+ + + + \ No newline at end of file diff --git a/develop/basic/chainBuild/image.html b/develop/basic/chainBuild/image.html new file mode 100644 index 00000000..9291b1da --- /dev/null +++ b/develop/basic/chainBuild/image.html @@ -0,0 +1,22 @@ + + + + + + 图片 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

图片

发送一张图片

Chain().image()

参数名类型释义默认值
targetstr, bytes图片文件路径或图片 bytes
urlstr网络图片的URL
python
Chain(data).image(target)

当传入的类型为字符串时,image 方法会认为值为本地图片的路径并尝试读取文件。也可以直接传入 bytes 类型。
如果是网络图片,可以使用 url 参数传入。

python
Chain(data).image(url=target)
+ + + + \ No newline at end of file diff --git a/develop/basic/chainBuild/markdown.html b/develop/basic/chainBuild/markdown.html new file mode 100644 index 00000000..40e8f09b --- /dev/null +++ b/develop/basic/chainBuild/markdown.html @@ -0,0 +1,27 @@ + + + + + + Markdown 生成的图片 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

Markdown 生成的图片

添加一张由 Markdown 文本渲染的图片,直接传入 md 格式的文本,使用 HTML 模式渲染。建议先阅读 发送 html 生成的图片 了解如何启动 Chromium。

注意

这并非 QQ 机器人官方提供的 发送 markdown 消息 ,要发送官方的 Markdown 模版消息请查看 Markdown 模版

Chain().markdown()

参数名类型释义默认值
contentstrmarkdown 文本
render_timeint渲染时间(毫秒)200
is_darkbool是否使用暗黑样式False
python
Chain(data).markdown(text)

提示

文本量大时,渲染将会耗费较长时间,默认预留200ms的渲染时间。可通过参数 render_time 设置需要的时间。

更换渲染 Markdown 的 HTML 文件

更改全局配置可以使用自己的 HTML 文件渲染 Markdown

python
from amiyabot.builtin.messageChain import ChainConfig
+
+ChainConfig.md_template = './myMarkdown.html'
+ChainConfig.md_template_dark = './myDarkMarkdown.html'

HTML 内需要实现以下方法获取到 Markdown 文本

js
window.init = (data) => {
+    const markdownText = data['content']
+}
+ + + + \ No newline at end of file diff --git a/develop/basic/chainBuild/mdTemplate.html b/develop/basic/chainBuild/mdTemplate.html new file mode 100644 index 00000000..e99e9941 --- /dev/null +++ b/develop/basic/chainBuild/mdTemplate.html @@ -0,0 +1,57 @@ + + + + + + Markdown 模版消息 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

Markdown 模版消息

发送 QQ 频道 Markdown 模板消息,详情请查看发送 markdown 消息

Chain().markdown_template()

参数名类型释义默认值
template_idstr模版 ID
paramsList[dict]模版 key-value 数据
keyboardInlineKeyboard按钮消息(自定义)
keyboard_template_idstr按钮消息(模版)
python
params = [
+    {'key': 'para1', 'values': ['段落1']},
+    {'key': 'para2', 'values': ['段落2']},
+    {'key': 'desc', 'values': ['简介']},
+]
+
+Chain(data, at=False).markdown_template('101993071_1658748972', params)

按钮消息

发送含有消息按钮组件的消息

使用按钮模版

python
# 必须跟随 md 模版发送
+Chain(data, at=False).markdown_template(
+    '101993071_1658748972',
+    params,
+    keyboard_template_id='102005657_1703561314',
+)

自定义按钮

自定义按钮通过内置的 InlineKeyboard 类构建。

python
from amiyabot import InlineKeyboard
+
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    keyboard = InlineKeyboard(data.instance.appid)
+
+    # 添加第一行按钮组
+    row = keyboard.add_row()
+    row.add_button('1', '按钮1')
+    row.add_button('2', '按钮2')
+
+    # 添加第二行按钮组
+    row2 = keyboard.add_row()
+    row2.add_button('3', '按钮3')
+    row2.add_button('4', '更多功能...', action_type=0)
+
+    # 必须跟随 md 模版发送
+    chain = Chain(data, at=False).markdown_template(
+        '102005657_1704356453',
+        [{'key': 'content', 'values': ['Markdown 测试']}],
+        keyboard=keyboard,
+    )
+
+    # 通过主动消息发送
+    await bot[data.instance.appid].send_message(chain, channel_id=data.channel_id)
+ + + + \ No newline at end of file diff --git a/develop/basic/chainBuild/tag.html b/develop/basic/chainBuild/tag.html new file mode 100644 index 00000000..e53017ec --- /dev/null +++ b/develop/basic/chainBuild/tag.html @@ -0,0 +1,22 @@ + + + + + + 频道跳转超链接 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

频道跳转超链接

发送频道跳转超链接 #子频道,点击可以跳转至子频道,仅支持当前频道内的子频道

注意

仅支持 QQ 频道

Chain().tag()

参数名类型释义默认值
targetint子频道ID
python
Chain(data).tag(12345678)
+ + + + \ No newline at end of file diff --git a/develop/basic/chainBuild/text.html b/develop/basic/chainBuild/text.html new file mode 100644 index 00000000..0b3e194c --- /dev/null +++ b/develop/basic/chainBuild/text.html @@ -0,0 +1,22 @@ + + + + + + 文字 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

文字

发送一段文字消息

Chain().text()

参数名类型释义默认值
textstr内容文本
auto_convertbool是否超出字数后转换为图片True
python
Chain(data).text('hello, world')

设置 auto_convert=True 可开启自动转换,当文字超过一定长度时(默认配置为 100),会自动将本段落转换为图片发送。

插入表情

在文本内使用 [face:ID] 模板也可以插入 QQ 表情。

python
Chain(data).text('hello, world[face:175]')
+ + + + \ No newline at end of file diff --git a/develop/basic/chainBuild/textImage.html b/develop/basic/chainBuild/textImage.html new file mode 100644 index 00000000..f30c3329 --- /dev/null +++ b/develop/basic/chainBuild/textImage.html @@ -0,0 +1,33 @@ + + + + + + 文字生成的图片 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

文字生成的图片

此方法可以将文字转换为图片发送,使用调色模板可以进行文字调色,亦可插入图片渲染。

Chain().text_image()

参数名类型释义默认值
textstr内容文本
imagesList[ImageElem]插入图片None
widthint图片宽度None
heightint图片高度None
bgcolorstr图片背景色#F5F5F5
python
Chain(data).text_image('hello, world')

调色模板

在文本内使用 [cl 文字内容@#颜色代码 cle] 格式的模板,将指定文字内容改变颜色。

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).text(f'hello [cl {data.nickname}@#ff0000 cle]')
image

text_image 无法插入表情

如果 Chain.text 的文本内使用了调色模板,将会强制转换为图片。同时 [face:ID] 模板也会失效。

渲染图片

在 images 参数内传入一个包含 ImageElem 对象的列表,可在文字图片内渲染图片。

ImageElem

参数名类型释义默认值
pathstr图片路径
sizeint图片大小
pos(int, int)图片渲染位置 (x, y)

简单尝试一下,发送一张 hello, world 的文字图片,并在里面插入一张图片。
需要注意的是,因为 hello, world 文字只有一行,所以需要指定一下图片高度。否则插入的图片可能会显示不全。
你可以一次插入很多张图片,所以任何时候,都请把握好你的文字图片宽高与插入的图片的大小、坐标之间的影响。

python
from amiyabot.builtin.lib.imageCreator import ImageElem
+
+
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    image = ImageElem(path='face.png', size=80, pos=(0, 20))
+
+    return Chain(data).text_image('hello,world', images=[image], height=100)

你可以收到如下的回复

image

更换字体

可以使用自己的 ttf 字体文件更换字体

python
from amiyabot.builtin.lib.imageCreator import FontStyle
+
+FontStyle.file = './font.ttf'
+ + + + \ No newline at end of file diff --git a/develop/basic/chainBuild/video.html b/develop/basic/chainBuild/video.html new file mode 100644 index 00000000..b273e0e3 --- /dev/null +++ b/develop/basic/chainBuild/video.html @@ -0,0 +1,24 @@ + + + + + + 视频 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

视频

发送一段 mp4 格式的视频

注意

QQ 频道机器人暂时不支持发送视频,目前仅支持官方 QQ 群。

Chain().video()

参数名类型释义默认值
filestr视频文件路径
python
Chain(data).video(file)
python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).video('xxxxxx.mp4')
+ + + + \ No newline at end of file diff --git a/develop/basic/chainBuild/voice.html b/develop/basic/chainBuild/voice.html new file mode 100644 index 00000000..c9239125 --- /dev/null +++ b/develop/basic/chainBuild/voice.html @@ -0,0 +1,24 @@ + + + + + + 语音 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

语音

发送一段 wav 格式的音频

注意

QQ 频道机器人暂时不支持发送语音,目前仅支持官方 QQ 群、 mirai-api-httpcq-http

Chain().voice()

参数名类型释义默认值
filestr语音 wav 文件路径
titlestr语音标题voice
python
Chain(data).voice(file)
python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).voice('阿米娅_问候.wav')
+ + + + \ No newline at end of file diff --git a/develop/basic/continuityMessage.html b/develop/basic/continuityMessage.html new file mode 100644 index 00000000..325bbccf --- /dev/null +++ b/develop/basic/continuityMessage.html @@ -0,0 +1,51 @@ + + + + + + 创建连续对话 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

创建连续对话

在一些使用场景里,需要机器人与使用者产生连续的对话。比如询问使用者以获取信息等。

Message 对象内置了连续对话支持。

Message.wait()

参数列表

参数名类型释义默认值
replyChainChain 对象
forcebool使用强制等待False
max_timeint最长等待时间(秒数)30
data_filterCallableMessage 过滤器
levelint优先级0

使用 wait 方法实现一个简单的连续对话

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+
+    reply = await data.wait(Chain(data).text('tell me your name please~'))
+
+    if reply:
+        return Chain(reply).text(f'hello,{reply.text}')
image

force 强制等待

等待通常不会影响消息分配器运作,也就是说 仅在不能触发任何其他功能 的时候,消息才会返回到当前等待处。(也包括本功能的初始触发方式,一般功能的优先级默认为 1,比等待事件的默认优先级高)

如果你不希望如此,使用参数 force=True,可以忽略分配器让消息强制返回到等待处。

data_filter 消息过滤器

如果在等待过程中,希望 wait 接收到符合期望的消息后再返回到等待处,可以使用 data_filter 参数过滤消息。

python
async def my_data_filter(data: Message):
+    if ...:
+        return True # 返回 True 代表此则消息符合期望,将返回到等待处
+
+
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    reply = await data.wait(Chain(data).text('tell me your name please~'), data_filter=my_data_filter)
+
+    if reply:
+        return Chain(reply).text(f'hello,{reply.text}')

关于 wait 方法你需要知道的事

  • 若用户超过最长等待时间未回复,wait 会返回 None

同一个子频道内的同一个用户只能存在一个等待事件,当一个新的等待事件创建后,上一个未使用的等待事件会被注销并引发 WaitEventCancel 异常,进行中的业务将会被终止,这是符合预期的,通常这个异常会被全局异常捕捉器过滤。

  • 在等待时间内使用其他功能,等待也会被注销。

Message.wait_channel()

注意

该方法不可用于支持私信的功能里

参数列表

参数名类型释义默认值
replyChainChain 对象
forcebool使用强制等待False
cleanbool是否清空消息列表True
max_timeint最长等待时间(秒数)30
data_filterCallableMessage 过滤器
levelint优先级0

wait_channel 方法用于等待子频道全体成员的回复

与 wait 方法不同的是,wait_channel 返回的不是 Message 对象,而是 ChannelMessagesItem 对象。内含等待事件的实例,和该次返回的消息。

ChannelMessagesItem

属性

属性类型释义
eventChannelWaitEvent等待事件的实例
messageMessageMessage对象

方法

方法名参数释义异步
close_event关闭等待事件

下面来看一个简单的例子

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    await data.send(Chain(data).text('hello everyone, tell me your name please~'))
+    while True:
+        await asyncio.sleep(0)
+        event = await data.wait_channel()
+        if event:
+            reply = event.message
+
+            if reply.text == 'stop':
+                event.close_event() # 关闭等待事件
+                break
+
+            await data.send(Chain(reply).text(f'hello,{reply.text}'))

close_event()

关闭等待事件

wait_channel 与 wait 的用法是大致相同的,但是 wait_channel 在接收到有效消息并返回后,不会像 wait 那样关闭事件,而是保持接收子频道的消息。在你的业务逻辑正常结束时,你必须使用 close_event 关闭它。

请注意

请务必让你的业务逻辑有机会关闭等待事件,否则等待事件没有被正常关闭时,它可能会持续拦截子频道消息直至超时自动关闭。

不清除消息队列

如果你持续调用 wait_channel(如示例所示),但你不希望在处理业务时错过子频道内的消息,可以设置参数 clean=False 让事件不清除消息队列。让你可以按顺序获取到子频道内的消息。

python
await data.wait_channel(clean=False)
+ + + + \ No newline at end of file diff --git a/develop/basic/handleEvents.html b/develop/basic/handleEvents.html new file mode 100644 index 00000000..4ea97f80 --- /dev/null +++ b/develop/basic/handleEvents.html @@ -0,0 +1,81 @@ + + + + + + 事件监听 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

事件监听

监听频道发生的事件。
一般来说消息(MESSAGE_CREATEAT_MESSAGE_CREATE以及DIRECT_MESSAGE_CREATE)也属于事件,但是在构建阶段,这些消息事件会被归类并产出 Message 对象。剩下的事件类型,则会产出 Event 对象。可以使用 on_event 装饰器去获取事件。

注册事件响应

python
from amiyabot import Event, BotAdapterProtocol
+
+...
+
+@bot.on_event()
+async def _(event: Event, instance: BotAdapterProtocol):
+    ...
+
+@bot.on_event('GUILD_CREATE')
+async def _(event: Event, instance: BotAdapterProtocol):
+    ...
+
+@bot.on_event(['CHANNEL_CREATE', 'CHANNEL_UPDATE'])
+async def _(event: Event, instance: BotAdapterProtocol):
+    ...
  • on_event 接受一个事件名或事件名列表作为参数(无参数则监听全事件)。事件名可参阅对应适配器服务的官方文档。
  • 响应函数是一个协程,接受 Event 对象和 bot 实例两个参数。

Event 对象

属性类型释义
appidstr发生该事件的 Bot AppId
event_namestr事件名
datadict事件的内容字典

频道事件

频道事件 Event.data 的值为 websocket 消息体里的 d 字段内容。

如下为 频道事件 - GUILD_CREATE 官方文档示例的 websocket 消息体。

json
{
+    "op": 0,
+    "s": 6,
+    "t": "GUILD_CREATE",
+    "d": {
+        "description": "频道介绍",
+        "icon": "",
+        "id": "200000000",
+        "joined_at": "2021-10-21T11:20:18+08:00",
+        "max_members": 300,
+        "member_count": 17,
+        "name": "频道名称",
+        "op_user_id": "100000000",
+        "owner_id": "100000000"
+    }
+}

在 on_event 里接收到时

python
@bot.on_event('GUILD_CREATE')
+async def _(event: Event, instance: BotAdapterProtocol):
+
+    print(event.data['name'])        // 频道名称
+    print(event.data['description']) // 频道介绍

频道的事件名和内容可以查看官方文档 事件订阅

mirai-api-http 事件

mirai-api-http 戳一戳事件推送的消息。

json
{
+    "type": "NudgeEvent",
+    "fromId": 123456,
+    "subject": {
+        "id": 123456,
+        "kind": "Group"
+    },
+    "action": "戳了戳",
+    "suffix": "的脸",
+    "target": 123456
+}

监听 type 的值 NudgeEvent 即可。

python
@bot.on_event('NudgeEvent')
+async def _(event: Event, instance: BotAdapterProtocol):
+    ...

go-cqhttp 事件

针对 go-cqhttp 事件的 数据结构,AmiyaBot 对其进行了分类,可以使用以下事件名精确获取。

如:戳一戳事件中 go-cqhttp 对其进行了三级分类。

json
{
+    "post_type": "notice",
+    "notice_type": "notify",
+    "sub_type": "poke"
+}

监听 notice 事件时,无法获得准确的事件。因为在 notice_type 的分类里,还包含了好友添加、消息撤回等一系列子事件。
当然,如果你需要监听这个大类的事件时,仍然可以监听这个事件名。

python
# 监听 post_type 为 notice 的事件
+@bot.on_event('notice')
+async def _(event: Event, instance: BotAdapterProtocol):
+    ...
+
+# 监听 post_type 为 notice 且 notice_type 为 notify 的事件
+@bot.on_event('notice.notify')
+async def _(event: Event, instance: BotAdapterProtocol):
+    ...

通过事件名 notice.notify.poke,即可监听到准确的戳一戳事件。

python
@bot.on_event('notice.notify.poke')
+async def _(event: Event, instance: BotAdapterProtocol):
+    ...

其他类别的事件同理,通过事件数据中的 post_type.xxxxx_type.sub_type 定义事件监听名即可。

+ + + + \ No newline at end of file diff --git a/develop/basic/handleException.html b/develop/basic/handleException.html new file mode 100644 index 00000000..32b6a21f --- /dev/null +++ b/develop/basic/handleException.html @@ -0,0 +1,36 @@ + + + + + + 异常监听 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

异常监听

AmiyaBot 内置了全局的用户层面异常捕获让程序不会轻易崩溃。如果你希望获取这些异常,可以通过注册异常处理器来获得它们。在执行消息响应或在消息响应筛选过程产生异常时,会执行这些注册的异常处理函数。

异常处理函数接受三个参数,分别是 异常类型实例 Exception适配器实例 BotAdapterProtocol产生异常的数据MessageEvent

python
from amiyabot import BotAdapterProtocol
+
+@bot.on_exception()
+async def _(err: Exception,
+            instance: BotAdapterProtocol,
+            data: Union[Message, Event]):
+    ...

指定异常类型

python
@bot.on_exception(KeyError)
+async def _(err: Exception,
+            instance: BotAdapterProtocol,
+            data: Union[Message, Event]):
+    ...

指定多种异常类型

python
@bot.on_exception([OSError, IndexError])
+async def _(err: Exception,
+            instance: BotAdapterProtocol,
+            data: Union[Message, Event]):
+    ...
+ + + + \ No newline at end of file diff --git a/develop/basic/index.html b/develop/basic/index.html new file mode 100644 index 00000000..019aaa02 --- /dev/null +++ b/develop/basic/index.html @@ -0,0 +1,40 @@ + + + + + + 开始使用 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

开始使用

在开始之前,我们希望你知道 AmiyaBot 是一款针对 QQ 频道机器人的框架。如果你想使用第三方机器人服务(如 mirai-api-http 或 go-cqhttp),可通过更改实例的适配器使用。
接下来的文档将围绕 QQ 频道机器人展开。如果需要 更改适配器 请在安装依赖后阅读适配器文档

我们建议你先在 QQ开放平台 了解 QQ 频道机器人的运营规则,这非常重要,因为在本文档里,关于这部分的内容将会非常少。如果你并不了解 QQ 频道机器人,后续的文档可能会对你造成疑惑。

安装依赖

amiyabot

bash
pip install amiyabot

创建你的第一个 Bot

  1. QQ开放平台 申请并创建你的 QQ 机器人。创建沙箱频道,并把你的机器人添加进频道里。(此处不作详细说明)
  2. 使用机器人的 appidtoken 创建一个 AmiyaBot 实例
python
import asyncio
+
+from amiyabot import AmiyaBot, Message, Chain
+
+bot = AmiyaBot(appid='******', token='******')
+
+
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')
+
+
+asyncio.run(bot.start())
  1. 运行代码,在频道里输入 @机器人 hello,你预期会看到如下输出。
image

那么恭喜你,你的 QQ 机器人已经可以正常运作了。

「这是个人迈出的一小步,但却是人类迈出的一大步。」—— 阿姆斯特朗

创建私域机器人

如果你在平台创建的是私域机器人,在 AmiyaBot 的参数里设置 private=True 来开启私域模式,私域机器人支持接收非 @机器人 的消息,你可以使机器人以更灵活的方式触发功能。

python
# 配置 private=True 让实例改为私域
+bot = AmiyaBot(appid='******', token='******', private=True)

使用前缀触发词唤醒机器人

python
bot = AmiyaBot(...)
+
+# 添加前缀触发词
+bot.set_prefix_keywords(['amiya', 'amy'])

此时机器人只能接收指定前缀的对话

image

沙箱环境

使用 QQGuildSandboxBotInstance 适配器将 API 调用更改为沙箱环境。沙箱环境只会收到测试频道的事件,且调用 openapi 仅能操作测试频道。

python
from amiyabot.adapters.tencent.qqGuild import QQGuildSandboxBotInstance
+
+bot = AmiyaBot(..., adapter=QQGuildSandboxBotInstance)
+ + + + \ No newline at end of file diff --git a/develop/basic/messageHandler.html b/develop/basic/messageHandler.html new file mode 100644 index 00000000..10da9224 --- /dev/null +++ b/develop/basic/messageHandler.html @@ -0,0 +1,98 @@ + + + + + + 注册消息响应器 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

注册消息响应器

AmiyaBot 功能开发的关键模块一共有三个,分别是 AmiyaBotMessageChain

  • AmiyaBot 为机器人实例,包含了消息和事件的注册器。
  • Message 为接收的消息主体,内含预解析的消息内容,以及一些相关操作函数。Message 对象在此仅用于参数类型注解,供编辑器智能提示使用,任何时候,你都不需要实例化 Message 对象。
  • Chain 为机器人消息的创建工具。任何需要发送消息的时候,消息都必须由 Chain 类创建。核心会调用 Chain 类的 build 方法生成消息链。

首先需要知道的是,如何注册消息响应

on_message 装饰器

何为机器人的功能?

消息响应我们会在后续的文档称之为功能,因为机器人的主要功能,一般就是通过响应用户的消息实现的。

装饰器 on_message 作用于你的业务逻辑主体函数,以此注册消息响应来实现你的机器人功能。

python
# 当和机器人的对话中包含 'hello' 关键字时,将会触发该函数
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')

参数列表

参数名类型释义默认值
group_idstr功能组ID
keywords触发关键字,支持多种类型,详见本章文档
verifyCallable自定义校验方法,当该参数被赋值时,keywords 将会失效
check_prefixbool是否校验前缀或指定需要校验的前缀True
allow_directbool是否支持通过私信使用该功能False
direct_onlybool是否仅支持私信False
levelint关键字校验成功后函数的候选默认等级0

功能组

参数 group_id 可以为该功能设置功能组。功能组可以批量为功能设置参数。

实例化 GroupConfig 对象创建一个功能组,并将其设置到 bot 实例内。

参数名类型释义默认值
group_idstr功能组ID
check_prefixbool是否校验前缀或指定需要校验的前缀True
allow_directbool是否支持通过私信使用该功能False
direct_onlybool是否仅支持私信False
python
from amiyabot import GroupConfig
+
+fn_group = GroupConfig('test', check_prefix=False)
+bot.set_group_config(fn_group)  # 注册功能组

为消息响应设置 group_id 参数

python
# 传入功能组名称设置组别
+@bot.on_message(group_id='test', keywords='...')
+async def _(data: Message):
+    ...
+
+
+# 传入功能组对象设置组别(效果相同)
+@bot.on_message(group_id=fn_group, keywords='...')
+async def _(data: Message):
+    ...

注意

仅当 on_message 里没有设置该参数时,功能组的参数才会对其生效。否则优先使用 on_message 的参数。

私域模式的前缀校验

AmiyaBot 私域模式建议在对话中包含指定前缀才能进入消息分配器。设置前缀触发词后,在一些特殊的情况下,可以通过 忽略前缀检查校验完全匹配 的方式绕过检查。

接收不包含前缀的消息

添加参数 check_prefix=False 可忽略前缀检查

python
@bot.on_message(keywords='hello', check_prefix=False)
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')

接收指定前缀的消息

check_prefix 参数改为字符串列表可以临时修改前缀检查为指定单词

python
@bot.on_message(keywords='hello', check_prefix=['amiya', '🐰'])
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')

校验符合正则检查的句式

关键字传入 re.compile 对象,可以检查对话文本是否符合正则表达式。

python
import re
+...
+
+@bot.on_message(keywords=re.compile(r'hello,\d+'))
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')

校验完全匹配的句式

完全匹配的句式指对话的文本内容全等于 keyword 关键字(不包括 @ 部分),使用工具类 Equal 即可达到效果。

python
from amiyabot import Equal
+...
+
+@bot.on_message(keywords=Equal('hello, amiya'))
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')

提示

在私域机器人下且不需要 @ 唤起的场合,Equal 会无视前缀检查。

组合多个和多种 keywords

keywords 支持由 字符串、正则、Equal 构成的列表,组合中包含 Equal 时,Equal 依然会无视前缀检查。

python
@bot.on_message(
+    keywords=[
+        'hello',
+        'hey',
+        Equal('hello, amiya'),
+        re.compile(r'hello,(\d+)'),
+    ]
+)
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')

功能优先级

当关键字校验存在冲突时,可以通过指定优先级供消息分配器选择。
分配器的工作原理,是在完成检查之后,将通过校验的候选函数列表按优先级倒序排序,然后选取第一个执行。
所有函数的默认优先级都为 1,如果不指定优先级,分配器会按照加载的先后顺序选择。

python
# 如果不指定优先级,当对话内容为 "helloworld" 时,第一个函数会首先通过校验并输出。
+# 因为在模块加载阶段,第一个函数更早注册完毕。
+
+@bot.on_message(keywords='hello', level=1)
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')
+
+
+@bot.on_message(keywords='helloworld', level=2)
+async def _(data: Message):
+    return Chain(data).text('hello,world')

提示

优先级允许为 0 或负数

自定义检查

当关键字检查无法满足功能的触发方式时,就需要使用自定义检查。
自定义检查是一个协程函数,参数为 Message 对象,返回一个布尔值(必选)优先级(可选)关键值(可选)的元组。

python
async def my_verify(data: Message):
+    if 'hello' in data.text:
+        return True
+
+
+@bot.on_message(verify=my_verify)
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')

当消息响应获得执行权,自定义检查结果(Verify)将储存在 Message.verify 中。

Verify 对象

属性类型释义
resultbool检查结果
weightint优先级
keypointAny关键值信息

动态输出优先级的值

返回元组第二个值,即可以指定动态优先级。

python
async def my_verify(data: Message):
+    if ...:
+        return True, 2
+    elif ...:
+        return True, 1
+    return False

输出关键值

返回元组第三个值,可以向 Message 的检查结果里添加关键值信息。可以是任意类型。

python
async def my_verify(data: Message):
+    if ...:
+        return True, 1, {'name': 'my name'}
+    return False
+
+
+@bot.on_message(verify=my_verify)
+async def _(data: Message):
+    info = data.verify.keypoint # {'name': 'my name'}

使功能在私信里可用

设置参数 allow_direct=True,允许功能在私信里触发。
设置参数 direct_only=True,功能仅私信可触发。

python
@bot.on_message(keywords='hello', allow_direct=True)
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')
+
+
+# 仅私信可触发
+@bot.on_message(keywords='hi', direct_only=True)
+async def _(data: Message):
+    return Chain(data).text(f'hey, {data.nickname}')
+ + + + \ No newline at end of file diff --git a/develop/basic/multipleAccounts.html b/develop/basic/multipleAccounts.html new file mode 100644 index 00000000..5ce9d7a5 --- /dev/null +++ b/develop/basic/multipleAccounts.html @@ -0,0 +1,72 @@ + + + + + + 多账号 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

多账号

AmiyaBot 支持同时启动多个账号,所有账号之间可以共享资源以及功能。

创建多个单独实例

你可以同时创建多个互不相关的实例,只需要实例化多个 AmiyaBot。多实例启动时,一些内置的资源对象不会重复创建多个,而是被它们共享,以节约内存。

python
import asyncio
+
+from amiyabot import AmiyaBot, Message, Chain
+
+bot1 = AmiyaBot(appid='******', token='******', private=True)
+bot2 = AmiyaBot(appid='******', token='******')
+
+
+@bot1.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')
+
+
+@bot2.on_message(keywords='hey')
+async def _(data: Message):
+    return Chain(data).text(f'hey, {data.nickname}')
+
+
+asyncio.run(
+    asyncio.wait([
+        bot1.start(),
+        bot2.start()
+    ])
+)

创建一个多账号实例

MultipleAccounts

MultipleAccounts 可以创建一个多账号实例,参数是多个 AmiyaBot 实例。它拥有与 AmiyaBot 一样的所有方法,所以你可以像 AmiyaBot 一样使用它来注册你的功能。
通过 MultipleAccounts 注册的功能,将被所有包含的 AmiyaBot 共享。而其中的 AmiyaBot 实例,仍能单独注册属于自己的私有功能。

python
import asyncio
+
+from amiyabot import AmiyaBot, MultipleAccounts, Message, Chain
+
+bot1 = AmiyaBot(appid='******', token='******', private=True)
+bot2 = AmiyaBot(appid='******', token='******')
+
+bot = MultipleAccounts(bot1, bot2, AmiyaBot(appid='******', token='******'), ...)
+
+
+# 公共功能
+@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')
+
+
+# bot1 的私有功能
+@bot1.on_message(keywords='hey')
+async def _(data: Message):
+    return Chain(data).text(f'hey, my name is Amiyabot')
+
+
+asyncio.run(bot.start())

多账号热插拔

多账号支持动态创建和删除里面的实例,也允许先创建空多账号实例。随后往里面插入 AmiyaBot 对象。

MultipleAccounts.append()

插入一个实例

参数名类型释义默认值
itemAmiyaBotAmiyaBot 实例
enable_chromiumbool启动时开启 chromiumFalse
start_upbool插入后立即启动True

示例

python
# 创建一个空多账号
+bot = MultipleAccounts()
+# 插入并启动一个实例
+bot.append(AmiyaBot(appid='12345', ...))
+# 删除实例,同时关闭实例的连接
+del bot['12345']
+ + + + \ No newline at end of file diff --git a/develop/basic/recallMessage.html b/develop/basic/recallMessage.html new file mode 100644 index 00000000..408475bb --- /dev/null +++ b/develop/basic/recallMessage.html @@ -0,0 +1,61 @@ + + + + + + 撤回消息 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

撤回消息

撤回一条消息。

在 Message 对象中撤回

使用 Message 对象的 recall 方法,撤回当前消息。

Message.recall()

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    await data.recall()

你可以在任何能获取到 Message 对象的地方使用 recall 方法。比如在连续对话或异常监听里。

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    # 等待事件返回的也是 Message 对象
+    reply = await data.wait(Chain(data).text('...'))
+    if reply:
+        await reply.recall()
python
@bot.on_exception()
+async def _(err: Exception,
+            instance: BotAdapterProtocol,
+            data: Union[Message, Event]):
+    if type(data) is Message:
+        await data.recall()

手动撤回

使用适配器实例的 recall_message 方法

AmiyaBot.instance.recall_message()

参数名类型释义默认值
message_idstr消息ID(通常可以在 Message.message_id 获取到)
dataMessageMessage 对象None
python
await bot.instance.recall_message(message_id='......', target_id='......')

撤回 Bot 发送的消息

如果是通过在消息响应器里面返回 Chain 对象或等待函数 Message.wait() 发送的消息,是无法撤回的,但后者可以通过另外的方法达到撤回效果。

发送消息的方法是否可撤回
Message.send()✅ 可以撤回
Message.wait()❌ 无法撤回
Message.wait_channel()❌ 无法撤回
return Chain()❌ 无法撤回
python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    chain = Chain(data).text(f'hello, {data.nickname}')
+
+    callback = await data.send(chain)  # ✅ 可以撤回
+    if callback:
+        await callback.recall() # 使用回调对象撤回
+
+    wait = await data.wait(chain)  # ❌ 无法撤回
+    event = await data.wait_channel(chain)  # ❌ 无法撤回
+
+    return chain  # ❌ 无法撤回

Message.send() 方法返回一个 MessageCallback 对象或其组成的列表(语音或频道多图消息会产生分开发送的结果)。如果消息没有发送成功则返回 None

调用 MessageCallback.recall() 即可撤回发送的消息。

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+
+    callback = await data.send(...)
+    if callback:
+        await callback.recall()
+        # 或
+        # for item in callback:
+        #     await item.recall()

撤回等待的消息

Message.wait() 没有返回执行 send 时获得的 MessageCallback,因此你无法在使用该方法发送消息的情况下撤回,但你可以配合 send 达到这个效果。

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    callback = await data.send(Chain(data).text('hello, what\'s your name?'))  # 使用 send 方法代替 wait 发送消息
+    wait = await data.wait()  # 只等待,不发送消息
+
+    if callback and not wait:
+        await callback.recall()
+
+    ...

撤回合并转发的消息

撤回合并转发

+ + + + \ No newline at end of file diff --git a/develop/basic/recvMessage.html b/develop/basic/recvMessage.html new file mode 100644 index 00000000..7dc2cfc8 --- /dev/null +++ b/develop/basic/recvMessage.html @@ -0,0 +1,32 @@ + + + + + + 接收消息 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

接收消息

在上一节 注册消息响应 中讲述了如何注册一个接收指定消息的函数,当接收到消息时,函数被执行时,参数 data: Message 就是接收到的消息的内容。

Message 对象是接收到消息之后预处理化的一个消息数据对象。内含这则消息相关的各项属性,以及针对这则消息的一些操作API。
该对象主要应用在功能函数和自定义检查中。建议在开发时引入 Message 对象并注解在对应地方。

python
from amiyabot import Message
+
+
+async def my_verify(data: Message):
+    ...
+
+
+@bot.on_message(verify=my_verify)
+async def _(data: Message):
+    print('recv:', data.text)
+    ...

Message 对象

重要变动

1.9.8 起,如果配置了前缀触发词,Message 对象内的消息文本系列字段将不再包含触发对话的前缀(Commit 99ada6b), 前缀在对话文本中被移除后将赋值到 text_prefix 属性内。

属性

属性类型释义
instanceBotAdapterProtocolbot 实例
messagedict原始消息字典
message_idstr消息 ID
message_typestr消息类型(适用于群聊适配器)
faceList[str]消息内表情 ID 列表
imageList[str]消息内图片 URL 列表
textstr消息文本(不包含触发词、中间件处理)
text_digitsstr消息文本(不包含触发词、中间件处理、中文转数字处理)
text_unsignedstr消息文本(不包含触发词、去字符处理)
text_originalstr消息文本(原始文本)
text_wordsList[str]消息文本分词
text_prefixstr消息触发词
at_targetList[str]消息内 @ 的对象列表
is_atbool是否 @ 机器人
is_adminbool是否为子频道管理员
is_directbool是否是私信消息
user_idstr用户 ID
guild_idstr频道 ID
src_guild_idstr来源频道 ID,私信下有效
channel_idstr子频道 ID
nicknamestr用户昵称
avatarstr用户头像的 URL
joined_atISO8601 timestamp用户加入频道的时间
verifyVerify 对象自定义检查的结果
timeint消息时间

方法

方法名参数释义异步
sendreply发送一条消息
waitreply,force,max_time,data_filter等待用户消息
wait_channelreply,force,clean,max_time,data_filter等待子频道消息
recall撤回消息

接下来,使用 Message 对象提供的属性完成业务逻辑,并发送消息

+ + + + \ No newline at end of file diff --git a/develop/basic/sendActiveMessage.html b/develop/basic/sendActiveMessage.html new file mode 100644 index 00000000..d219bd65 --- /dev/null +++ b/develop/basic/sendActiveMessage.html @@ -0,0 +1,43 @@ + + + + + + 发送主动消息 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

发送主动消息

主动消息限制

主动消息需要频道设置允许机器人推送,发送消息也存在数量限制。
详见官方文档 接入流程-语料配置-消息类型

AmiyaBot.send_message()

send_message 是发送主动消息的方法,它的第一个参数 chain 需要传入一个 Chain 对象。可以通过实例化一个无 Message 的 Chain 得到。

python
message = Chain().text('hello')
参数名类型释义默认值
chainChainChain 对象
user_idstr用户ID
channel_idstr子频道ID
direct_src_guild_idstr来源频道ID

发送一条主动子频道消息

python
bot = AmiyaBot(...)
+message = Chain().text('hello')
+
+await bot.send_message(message, channel_id='******')

发送一条主动私信 Beta

传入参数 user_id(用户ID)和 direct_src_guild_id(来源频道ID),send_message 将会发送主动私信消息。

python
bot = AmiyaBot(...)
+message = Chain().text('hello')
+
+await bot.send_message(message,
+                       user_id='*******',
+                       direct_src_guild_id='*******')

在多账号实例里使用 send_message

python
bot = MultipleAccounts(
+    [
+        AmiyaBot(appid='111111', ...),
+        AmiyaBot(appid='222222', ...),
+    ]
+)
+
+await bot['222222'].send_message(...)

在事件响应里使用 send_message

提示

事件响应的方法通常可以返回触发了该事件的实例。

事件监听

python
@bot.on_event('MESSAGE_DELETE')
+async def _(event: Event, instance: BotAdapterProtocol):
+    await instance.send_message(...)

异常监听

python
@bot.on_exception()
+async def _(err: Exception,
+            instance: BotAdapterProtocol,
+            data: Union[Message, Event]):
+    await instance.send_message(...)
+ + + + \ No newline at end of file diff --git a/develop/basic/sendMessage.html b/develop/basic/sendMessage.html new file mode 100644 index 00000000..587ebd39 --- /dev/null +++ b/develop/basic/sendMessage.html @@ -0,0 +1,26 @@ + + + + + + 发送消息 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

发送消息

在消息响应器内返回 Chain 对象,或使用 Message 对象的 send 方法,均可发送消息。

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    await data.send(Chain(data).text('hello'))
+
+    return Chain(data).text(data.nickname)
image

Chain 对象

参数名类型释义默认值
dataMessageMessage 对象None
atbool是否 @ 用户True
referencebool是否回复用户(引用消息)False
chain_builderChainBuilderChain 辅助构建实例ChainBuilder()

Chain 对象是构建你的消息体的工具类。任何需要发送消息的时候,消息都必须由 Chain 类创建。
Chain 对象提供丰富的消息构建方式,可以让你发送多彩的文字图片,甚至是html模板。

这是最简单的一条文本消息:

python
Chain(data).text('hello, world')

更多类型请查看左侧导航消息构建元素

构建消息的方法

普通消息

Chain 对象支持链式语法,用于构建复杂的消息结构。
只需要按顺序以链式使用上述方法,即可拼接出内容丰富的消息。Chain 在最终构建消息的时候,会优化图片与文字的组成,减少消息的请求数量。

python
Chain(data).text(...).image(...).text(...).html(...)

合并转发消息

合并转发消息需要使用独立的工具类创建

空 Chain

实例化 Chain 对象时,不传入 Message 对象构建的。本文称之为 “空 Chain”。空 Chain 一般用于预构建消息。

python
Chain().text(...).image(...)

使用辅助类扩展构建

Chain 对象在构建消息时,可使用辅助类介入媒体消息或浏览器的构建过程。请移步 进阶指南 - 介入媒体消息的构建过程

+ + + + \ No newline at end of file diff --git a/develop/basic/statement.html b/develop/basic/statement.html new file mode 100644 index 00000000..a98774e4 --- /dev/null +++ b/develop/basic/statement.html @@ -0,0 +1,28 @@ + + + + + + 声明 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

声明

在本章后续文档中,为了减少篇幅量,将不会再在代码示例中出现 AmiyaBotMultipleAccounts 类的实例化代码。统一以变量 bot 表示已经实例化的 AmiyaBotMultipleAccounts 类。

你将会在诸多场景中看到 bot 变量的存在。

python
# 装饰器
+@bot.on_message(...)
+
+# 调用方法
+bot.some_func(...)
+
+...
+ + + + \ No newline at end of file diff --git a/develop/basic/testInstance.html b/develop/basic/testInstance.html new file mode 100644 index 00000000..bebe0230 --- /dev/null +++ b/develop/basic/testInstance.html @@ -0,0 +1,37 @@ + + + + + + 使用测试实例调试 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

使用测试实例调试

使用适配器 test_instance 并配置 host、port 参数即可启动一个测试实例。

python
import asyncio
+
+from amiyabot import AmiyaBot, Message, Chain
+from amiyabot.adapters.test import test_instance
+
+bot = AmiyaBot(appid='123456',
+               token='',
+               adapter=test_instance('127.0.0.1', 32001))
+
+
+@bot.on_message(keywords='hello', check_prefix=False)
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')
+
+
+asyncio.run(bot.start())

运行实例,访问 https://console.amiyabot.com/#/test 并输入配置的地址和 appid 连接测试服务,即可模拟测试对话。

test.png

+ + + + \ No newline at end of file diff --git a/develop/design.html b/develop/design.html new file mode 100644 index 00000000..4ac8c1ff --- /dev/null +++ b/develop/design.html @@ -0,0 +1,22 @@ + + + + + + 设计 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

设计

AmiyaBot 是一款 QQ 机器人框架,基于异步I/O构建,并提供了装饰器模式(Decorator Pattern)以及插件化动态导入(Dynamic import)的编程方式。 内置多种适配器兼容不同的服务来源以及丰富的消息构建类型,旨在帮助你更高效地编写业务逻辑,实现你的创意。

框架结构可分为业务模块通讯模块数据处理模块存储模块运转中心五个组成部分。它们独立运作,并在彼此之间相互提供数据。

业务模块

业务模块由插件(Plugin)账号实例(AmiyaBot)多账号实例(MultipleAccounts) 组成。它们一般会被组织成层层嵌套的树状结构。账号实例和多账号实例是同质的,它们均可以被运转中心(CenterProcessor)直接访问,运转中心无法访问插件。

运转中心在访问这些对象时,顶级对象会组合所有子级对象的属性提供给运转中心。

插件设计

实现上述模式的思路来源于 Vue 的 组件设计 ,所以在代码层面,插件与账号实例都属于“组件”,理论上账号实例之间也能互相嵌套。但在设计时加入了限制,防止这种关系的出现。

业务设计

业务模块通过各种装饰器来定义业务逻辑以及规则。这些装饰器都来源于它们继承的工厂对象(BotHandlerFactory),工厂对象是业务模块与运转中心的桥梁,业务函数会被工厂对象收集并封装,最终提供给运转中心调用。

账号实例图解

通讯与数据处理模块

通讯模块主要形式为适配器(Adapter),用于对接由机器人运营方提供的服务。

适配器

账号实例里面有一个重要参数:adapter,它指定了通讯模块的运行方式(选择适配器)以适配不同运营方的连接协议。

通讯模块负责解决对接收和发送的数据进行解包与封包,所以它与数据处理模块紧密相连。适配器必须为数据处理模块提供统一的接口,在与不同的运营方服务通讯过程中,运转中心获取到的源数据格式都必须是一致的。而接收到运转中心需要发出的数据时,适配器需要把数据封包为运营方协定的格式,完成发送。

账号实例也可以脱离运转中心的调控随时调用适配器与运营方服务通讯,完成一些特殊情况下的操作。

运转中心

运转中心包含事件处理消息处理分配器日志 等各种将所有模块相连的处理单元,是业务层的主要调度模块。在接收到由适配器传入的消息后,运转中心会将消息归类并分发到不同的处理模块。

消息处理

分配到消息处理的数据,将会对数据和业务模块收集的消息响应器(on_message)进行匹配,并将匹配成功的消息响应器按优先级排序,选取最高优先级的执行。

消息响应器的执行结果会经由运转中心返回到适配器,进行封包后发送。

这个过程在运转中心内称为“生命周期”,工厂对象可以介入这些周期影响消息处理的分配与执行结果。

结语

存储模块以及运转中心的日志等模块,在本文将忽略不谈。这些模块依赖第三方库或 Python 的标准库,本框架仅对其做了适度的封装。

+ + + + \ No newline at end of file diff --git a/develop/index.html b/develop/index.html new file mode 100644 index 00000000..164fe69d --- /dev/null +++ b/develop/index.html @@ -0,0 +1,22 @@ + + + + + + 欢迎访问开发文档 | AmiyaBot + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/develop/plugin/addDoc.html b/develop/plugin/addDoc.html new file mode 100644 index 00000000..ae6d6b68 --- /dev/null +++ b/develop/plugin/addDoc.html @@ -0,0 +1,47 @@ + + + + + + 添加插件文档 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

添加插件文档

你应该添加一个文档并详细描述插件的使用方法

添加一个 markdown 文档

text
Amiya-Bot
+├── pluginsDev
+│   ├── myPlugin
+│   │   ├── __init__.py
+│   │   ├── main.py
+│   │   ├── README.md
+│   │   └── HOWTOUSE.md
+│   ...
+...

demo 允许直接使用 markdown 文件路径作为文档,只需要把路径传入到 PluginInstance 对象的 document 参数。

添加使用指引文档

若使用了 AmiyaBotPluginInstance 对象创建插件,可使用参数 instruction,其作用是当 bot 的用户在使用 “查看功能指引” 类的指令时,向其展示 instruction 的内容。document 更偏向于提供给 bot 的部署者查看的文档。在没有配置 instruction 时,“查看功能指引” 将返回 document 的内容。

python
import os
+
+from amiyabot import PluginInstance, AmiyaBotPluginInstance
+
+plugin_dir = os.path.dirname(__file__)
+
+bot = PluginInstance(
+    document=f'{plugin_dir}/README.md'
+)
+# 或
+bot = AmiyaBotPluginInstance(
+    document=f'{plugin_dir}/README.md',
+    instruction=f'{plugin_dir}/HOWTOUSE.md'
+)

直接在参数内编写

提示

我们不推荐这种做法,除非你的插件文档只有少量文本。

python
bot = PluginInstance(
+    document='''
+        ...
+    '''
+)
+ + + + \ No newline at end of file diff --git a/develop/plugin/amiyaBotPluginInstance.html b/develop/plugin/amiyaBotPluginInstance.html new file mode 100644 index 00000000..a777f0ff --- /dev/null +++ b/develop/plugin/amiyaBotPluginInstance.html @@ -0,0 +1,47 @@ + + + + + + AmiyaBotPluginInstance | AmiyaBot + + + + + + + + + + + +
Skip to content
On this page

AmiyaBotPluginInstance

AmiyaBotPluginInstance 是 兔兔-v6 项目中的对插件类 PluginInstance 的扩展实现。使用该类创建插件时,能够获得更多的能力。

在 demo 项目里导入 AmiyaBotPluginInstance 创建插件。

python
from core import AmiyaBotPluginInstance
+
+bot = AmiyaBotPluginInstance(
+    name='我的插件',
+    version='1.0',
+    plugin_id='my-plugin',
+    description='我的第一个插件',
+    channel_config_default=...,
+    channel_config_schema=...,
+    global_config_default=...,
+    global_config_schema=...,
+    deprecated_config_delete_days=...,
+)

AmiyaBotPluginInstance 继承了 PluginInstance,并且拥有以下新参数和方法

参数

参数名类型释义默认值
instructionstr使用指引文档None
requirementsList[Requirement]插件依赖None
channel_config_defaultstr频道级别配置默认值None
channel_config_schemastr频道级别配置表单的 JsonSchemaNone
global_config_defaultstr全局级别配置默认值None
global_config_schemastr全局级别配置表单的 JsonSchemaNone
deprecated_config_delete_daysint旧配置项失效的天数7
  • 默认值和 JsonSchema 传入的值均为字符串,可以是 JSON 字符串或 json 文件路径。(默认值允许使用 yaml 文件路径)
  • 在控制台中点击 重置为默认 时会使用默认值的 JSON 数据覆盖,创建新配置项时使用默认值的 JSON 数据填充。
  • 如果提供了 JsonSchema,将会使用 JsonSchema 创建表单界面,否则使用默认值的 JSON 数据。
  • 如果提供了 JsonSchema,必须同时提供默认值数据。
python
plugin_dir = os.path.dirname(__file__)
+
+bot = AmiyaBotPluginInstance(
+    channel_config_default=f'{plugin_dir}/config.yaml',
+    channel_config_schema=f'{plugin_dir}/jsonSchema.json'
+)

使用 JsonSchema 对接控制台

你可以通过对接控制台使用户能够使用控制台的界面管理你的插件。如下所示。

请阅读 介绍文档 了解如何编辑 jsonSchema.json 文件。

get_config

读取一个指定名称的配置项,如果没有频道级别的配置则返回同名全局配置,如果也没有全局配置,返回 None。传入 channel_id=None 可以直接读取全局配置。

参数名类型释义默认值
config_namestr配置名称
channel_idstr频道IDNone
python
config_value = bot.get_config('name', channel_id='...')

set_config

写入配置,传入 channel_id=None 可以强制指定写入全局配置。

参数名类型释义默认值
config_namestr配置名称
config_valueAny配置值,仅支持可被 JSON 序列化的值类型
channel_idstr频道IDNone
python
bot.set_config('name', 'value', channel_id='...')

说明

插件加载时会进行下面的校验,校验不通过则会报错:

  • 提供了 schema 则必须提供对应的 default,反之则不必。
  • 如果给出了 schema,则会用 schema 对提供的 default 进行校验。

当有下列需求的时候,建议考虑提供 schema 文件:

  • 您想要使用下拉列表框。schema 中指定 enum 元素时,界面会生成下拉列表框。
  • 您想要对用户的配置进行校验,如果不满足条件时输出提示。

提供 channel_config_default 时,界面可以新建频道配置。

插件初次安装初次加载时,会将 global_config_default 作为默认全局配置写入数据库。
该过程发生在构造函数,因此您如果需要对全局配置进行初始化操作,您需要在您的插件实例的构造函数,或者 install 函数中进行。

添加插件依赖

当插件需要在别的插件的基础上运行,可在 requirements 参数内传入 Requirement 类的列表,当插件安装时,会从插件市场服务尝试寻找对应的插件依赖并一同安装。

Requirement

参数名类型释义默认值
plugin_idstr插件ID
versionstr版本号(可选)None
officialbool是否官方插件False
python
from core import AmiyaBotPluginInstance, Requirement
+
+bot = AmiyaBotPluginInstance(
+    requirements=[
+        Requirement('other-plugin'),
+        Requirement('other-plugin2', '2.0'),
+    ]
+)

提示

插件添加依赖后,仅当全部依赖安装成功后,才会进行自身的安装。

+ + + + \ No newline at end of file diff --git a/develop/plugin/build.html b/develop/plugin/build.html new file mode 100644 index 00000000..e5cd26e2 --- /dev/null +++ b/develop/plugin/build.html @@ -0,0 +1,28 @@ + + + + + + 打包插件 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

打包插件

插件推荐发布为 zip 压缩包

直接打包

将整个插件文件夹压缩为 zip 包即可。如果你的插件使用了第三方库,你可能需要将第三方库手动放进插件包内。

示例

如在插件内使用了库 pypyodbc,在本地 python 环境内找到 pypyodbc.py(有时候会是 package 文件夹),并拷贝进 zip 包内。

python
# main.py
+import pypyodbc
+
+...
text
myPlugin.zip
+├── __init__.py
+├── main.py
+└── pypyodbc.py

main.py 内的导入语句 import pypyodbc 被执行时,优先使用插件内的 pypyodbc 包。

注意

若无法通过上述手段将第三方包添加进插件包,你的插件将可能不支持 可执行文件部署 。你可以在你的插件文档内注明,并让代码部署的用户使用 pip install xxx 安装第三方依赖。

使用脚本打包

如果你是在 demo 下开发的插件,运行脚本 run_build.py 即可自动打包。

bash
python run_build.py --type plugins

注意

脚本打包尚处于试验阶段,你仍然需要手动添加第三方包进插件

+ + + + \ No newline at end of file diff --git a/develop/plugin/create.html b/develop/plugin/create.html new file mode 100644 index 00000000..91aea3f8 --- /dev/null +++ b/develop/plugin/create.html @@ -0,0 +1,52 @@ + + + + + + 创建插件 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

创建插件

在 pluginsDev 目录内,创建一个 Python package 形式的模块。为了防止加载插件时的全局环境变量污染。你的业务逻辑必须在另一个入口文件内进行。

创建入口文件 main.py

text
Amiya-Bot
+├── pluginsDev
+│   ├── myPlugin
+│   │   ├── __init__.py
+│   │   └── main.py
+│   ...
+...

编写插件程序

main.py 内编写插件的注册程序

python
from amiyabot import PluginInstance
+
+bot = PluginInstance(
+    name='我的插件',
+    version='1.0',
+    plugin_id='my-plugin',
+    description='我的第一个插件'
+)

PluginInstance 对象继承了工厂类 BotHandlerFactory,这意味着你完全可以按照 开发指南 去编写你的插件功能。

python
@bot.on_message(keywords='hello')
+async def _(data: Message):
+    return Chain(data).text(f'hello, {data.nickname}')
+
+@bot.on_event('GUILD_CREATE')
+async def _(event: Event, instance: BotAdapterProtocol):
+    ...

这些消息响应器都会在插件被加载时注册到主体程序中。

插件内静态资源的使用

如果你的插件包含静态资源,在读取它们时,应该以插件的绝对目录读取。

text
Amiya-Bot
+├── pluginsDev
+│   ├── myPlugin
+│   │   ├── __init__.py
+│   │   ├── main.py
+│   │   └── file.txt
+│   ...
+...
python
# main.py
+import os
+
+plugin_dir = os.path.dirname(__file__)
+file = open(f'{plugin_dir}/file.txt')

导出插件的实例

__init__.py 内导出插件的入口,命名为 bot。这个命名是固定的,即使 main 内部的 PluginInstance 实例变量名不为 bot,在导出时都必须使用 as bot 重命名。

python
from .main import bot

注意

请不要在 __init__.py 内编写多余的代码,我们希望这个文件有且只有上面的一行。插件在加载时,会临时添加插件目录为系统路径,这会使主模块的一些全局一等对象污染主体程序,导致不可预测的后果。

+ + + + \ No newline at end of file diff --git a/develop/plugin/debug.html b/develop/plugin/debug.html new file mode 100644 index 00000000..824b7564 --- /dev/null +++ b/develop/plugin/debug.html @@ -0,0 +1,30 @@ + + + + + + 调试插件 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

调试插件

调试插件的方法有很多种,一般来说,你可以直接打包插件然后放到主项目中加载并使用来观察效果,显然这不够效率。AmiyaBot 提供了 测试实例,在主项目中,有现成的示例脚本。

在测试脚本中调试

在 兔兔-v6 根目录下的 run_test.py 内,修改如下位置的代码。

python
# 显式导入插件开发目录,可以在编辑器 DEBUG 调试。
+from pluginsDev.src.user import bot as plugin
+
+
+async def install_plugin():
+    # 导入插件
+    bot.install_plugin(plugin)
+    # 直接导入插件 zip 包
+    # bot.install_plugin('plugins/amiyabot-arknights-operator-1.5.zip', extract_plugin=True)

运行 python run_test.py,访问测试网址并使用。详见 测试实例

+ + + + \ No newline at end of file diff --git a/develop/plugin/env.html b/develop/plugin/env.html new file mode 100644 index 00000000..63703f1e --- /dev/null +++ b/develop/plugin/env.html @@ -0,0 +1,27 @@ + + + + + + 准备开发环境 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

准备开发环境

插件并不强制要求在 demo 的项目下开发,如果插件不需要使用 demo 的内置模块,那么你可以在自己任意的目录内开发而不需要克隆 demo 项目以及插件仓库的代码。

以下说明默认在 demo 项目内。

克隆仓库

克隆 兔兔-v6

bash
git clone https://github.com/AmiyaBot/Amiya-Bot.git

在 demo 项目内克隆插件开发仓库

bash
cd Amiya-Bot
+git clone https://github.com/AmiyaBot/Amiya-Bot-plugins.git pluginsDev

此时的目录结构应为

Amiya-Bot
+├── pluginsDev
+│   │
+│   ...
+...

建议安装 兔兔-v6 的依赖,如果不需要使用 demo 的内置模块或是你在自己的目录内开发插件。那么只需要安装 amiyabot 即可。

bash
pip install amiyabot
+ + + + \ No newline at end of file diff --git a/develop/plugin/index.html b/develop/plugin/index.html new file mode 100644 index 00000000..a170511c --- /dev/null +++ b/develop/plugin/index.html @@ -0,0 +1,22 @@ + + + + + + 简要说明 | AmiyaBot + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/develop/plugin/jsonSchema.html b/develop/plugin/jsonSchema.html new file mode 100644 index 00000000..ecde2dbc --- /dev/null +++ b/develop/plugin/jsonSchema.html @@ -0,0 +1,144 @@ + + + + + + JsonSchema 解释 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

JsonSchema 解释

本篇介绍如何使用 draft-07 版本的 JsonSchema 规范编辑 插件对接控制台的配置文件

json
{
+    "$schema": "http://json-schema.org/draft-07/schema#",
+    "type": "object",
+    "required": [],
+    "properties": {}
+}
  • required:必填字段(暂未支持前端校验,敬请期待...)
  • properties:字段配置

基本配置

字段定义在 properties 对象里:

  • <config_name>配置名称,是使用 get_config 方法时的参数
  • <config_name>.type:类型
  • <config_name>.title(可选):表单标题,不配置则使用 config_name
  • <config_name>.description(可选):表单tips,鼠标移动到页面的问号图标时显示的内容
  • <config_name>.default(可选):默认值,需按照类型填写。

示例

json
{
+    "properties": {
+        "imagesCachePath": {
+            "title": "图片缓存目录",
+            "description": "图片缓存的目录路径,可以为绝对路径",
+            "type": "string",
+            "default": "./imagesCache"
+        }
+    }
+}

文本输入框

默认值 default 的类型为字符串

json
{
+    "properties": {
+        "<config_name>": {
+            "type": "string",
+            "default": "text"
+        }
+    }
+}

数字输入框

默认值 default 的类型为数字

  • minimum(可选): 可输入的最小值
  • maximum(可选): 可输入的最大值

当 type 为 integer 时,只能输入整数,为 number 时可以输入浮点数。

json
{
+    "properties": {
+        "<config_name>": {
+            "type": "integer",
+            "minimum": -10,
+            "maximum": 20,
+            "default": 0
+        },
+        "<config_name2>": {
+            "type": "number",
+            "default": 0.5
+        }
+    }
+}

切换按钮

默认值 default 的类型为布尔型

json
{
+    "properties": {
+        "<config_name>": {
+            "type": "boolean",
+            "default": false
+        }
+    }
+}

下拉选择框

下拉选择框不需要 type 字段,默认值 default 的类型为内容的值类型

json
{
+    "properties": {
+        "<config_name>": {
+            "enum": [
+                "option1",
+                "option2",
+                "option3"
+            ],
+            "default": "option2"
+        }
+    }
+}

日期时间选择器

type 配置为 string 时,若配置了对应的 format 字段,可更改为日期时间选择器。
默认值 default 的类型为字符串或数值

json
{
+    "properties": {
+        "<config_name>": {
+            "type": "string",
+            "format": "datetime"
+        }
+    }
+}

format 选项

配置相应的 format 以使用不同种类的选择器

  • date:日期 YYYY-MM-DD
  • time:时间 HH:mm:ss
  • datetime:日期时间 YYYY-MM-DD HH:mm:ss
  • date-range:日期范围 [ YYYY-MM-DD, YYYY-MM-DD ]
  • time-range:时间范围 [ HH:mm:ss, HH:mm:ss ]
  • datetime-range:日期时间范围 [ YYYY-MM-DD HH:mm:ss, YYYY-MM-DD HH:mm:ss ]

当使用范围选择器时,数据为数组类型,代表范围,如

json
[
+    "2023-05-20 08:00:00",
+    "2023-05-21 16:00:00"
+]

动态输入-值数组

如果你需要 get_config 方法返回 [value1, value2, value3, ...] 形式的值数值,可以使用动态输入值数组。
默认值 default 的类型为数组

  • type 配置为 array
  • items 为数组配置
    • type:值类型,仅支持 stringintegernumber 以及 object
json
{
+    "properties": {
+        "<config_name>": {
+            "type": "array",
+            "items": {
+                "type": "string"
+            }
+        }
+    }
+}

动态输入-对象数组

如果你需要 get_config 方法返回 [{...}, {...}, {...}, ...] 形式的值数值,可以使用动态输入对象(字典)数组。
默认值 default 的类型为数组

json
{
+    "properties": {
+        "<config_name>": {
+            "type": "array",
+            "items": {
+                "type": "object",
+                "properties": {}
+            }
+        }
+    }
+}

子级对象

有时候有些复杂配置不能用只有一级的对象(字典)存放,使用子级对象组建多层的对象(字典)。

  • type 配置为 object
  • properties 根据上文 基本配置 添加任意输入类型或将 type 配置为 object 继续作为新的子级对象
json
{
+    "properties": {
+        "<config_name>": {
+            "type": "object",
+            "properties": {}
+        }
+    }
+}

示例

json
{
+    "properties": {
+        "user": {
+            "type": "object",
+            "properties": {
+                "name": {
+                    "type": "string"
+                },
+                "age": {
+                    "type": "integer"
+                },
+                "attrs": {
+                    "type": "object",
+                    "properties": {
+                        "atk": {
+                            "type": "number"
+                        },
+                        "def": {
+                            "type": "number"
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

以上配置调用 bot.get_config() 方法将返回以下内容

json
{
+    "user": {
+        "name": ...,
+        "age": ...,
+        "attrs": {
+            "atk": ...,
+            "def": ...
+        }
+    }
+}
+ + + + \ No newline at end of file diff --git a/develop/plugin/life.html b/develop/plugin/life.html new file mode 100644 index 00000000..b6b8538a --- /dev/null +++ b/develop/plugin/life.html @@ -0,0 +1,40 @@ + + + + + + 插件生命周期 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

插件生命周期

你可以在插件被安装或卸载时执行一些操作,只需要继承 PluginInstance 并覆盖其方法。

python
from amiyabot import PluginInstance
+
+
+class MyPlugin(PluginInstance):
+    def install(self):
+        # 插件被安装时执行的操作
+        ...
+
+    def uninstall(self):
+        # 插件被卸载时执行的操作
+        ...
+
+
+bot = MyPlugin(
+    name='我的插件',
+    version='1.0',
+    plugin_id='my-plugin',
+    description='我的第一个插件'
+)
+ + + + \ No newline at end of file diff --git a/develop/plugin/publish.html b/develop/plugin/publish.html new file mode 100644 index 00000000..ad34c746 --- /dev/null +++ b/develop/plugin/publish.html @@ -0,0 +1,22 @@ + + + + + + 发布到插件商店 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

发布到插件商店

访问 控制台-插件商店,点击【上传创意插件】完成流程即可发布到商店。

插件密钥

上传插件时需要输入一个密钥,在你更新或下架你的插件时,需要输入这个密钥校验。请牢记你的密钥。

+ + + + \ No newline at end of file diff --git a/download.html b/download.html new file mode 100644 index 00000000..2cef4b76 --- /dev/null +++ b/download.html @@ -0,0 +1,24 @@ + + + + + + 下载 | AmiyaBot + + + + + + + + + + + + +
Skip to content

下载

amiyabot

bash
pip install amiyabot

兔兔-v6

操作系统下载备注
WindowsAmiyaBot--win32.zip仅支持 Windows 10、Windows Server 2016 及以上系统
+ + + + \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 00000000..929fc34b Binary files /dev/null and b/favicon.ico differ diff --git a/guide/deploy/advanced/index.html b/guide/deploy/advanced/index.html new file mode 100644 index 00000000..4c0758c4 --- /dev/null +++ b/guide/deploy/advanced/index.html @@ -0,0 +1,22 @@ + + + + + + 说明 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

说明

本部分文档可能只是对控制台暂未支持的部分的一种补充,文档中的内容可能不会一直维护,也不会一直有效,在不久的将来可能都会在控制台中实现。届时对应的文档也会从这里删去。当然,这并不是绝对的,部分功能可能无法或者不会在控制台中实现,那么控制台将可能会有指向这些文档的链接。目录名称“高级使用”仅是用来区分可以在控制台内直接实现的操作的,并无其他含义。

请理解:由于本部分的特殊性,我们可能不会高频率的维护这些文档以至于它们可能无法与最新的版本相匹配,甚至可能随时删除或停止维护这些文档。您使用过期文档导致生产事故等的情况我们不负任何责任,也不对其造成的影响负责。

如果您已阅读并理解,同意以上部分,则请您浏览左侧的目录跳转至您需要的部分开始阅读。

+ + + + \ No newline at end of file diff --git a/guide/deploy/advanced/mysql.html b/guide/deploy/advanced/mysql.html new file mode 100644 index 00000000..96c3bc11 --- /dev/null +++ b/guide/deploy/advanced/mysql.html @@ -0,0 +1,27 @@ + + + + + + 使用 Mysql | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

使用 Mysql

config\database.yaml 中可以配置使用的数据库,如需更改数据库类型为 Mysql,请按下面的配置说明进行配置:

yaml
mode: 'mysql'
+config:
+    host: '数据库地址'
+    port: 数据库端口
+    user: '登录用户名'
+    password: '数据库密码'
+ + + + \ No newline at end of file diff --git a/guide/deploy/console/configure.html b/guide/deploy/console/configure.html new file mode 100644 index 00000000..504c6c9e --- /dev/null +++ b/guide/deploy/console/configure.html @@ -0,0 +1,55 @@ + + + + + + 配置实例 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

配置实例

“实例”指的是机器人的账号,兔兔支持登录多个机器人账号同时使用,多个账号之间共享数据。

添加实例

在左侧导航选择“实例管理”,并点击“添加实例”

QQ频道机器人(官方)

QQ 开放平台 查看并在实例配置填写你注册的频道机器人信息,表单字段就是对应内容。

QQ群机器人(官方)

QQ 开放平台 查看并在实例配置填写你注册的群机器人信息,表单字段就是对应内容。

KOOK机器人

KOOK 开发者平台 查看并在实例配置填写你创建的机器人应用的 Token 即可。KOOK 机器人不需要 appid,但你仍然需要在配置里随便填写一个 appid,推荐使用 KOOK 应用的 Client Id

CQ-Http QQ群机器人

APP ID 为登录在 go-cqhttp 的 QQ 号
TOKEN 填写配置的 access-token,没有配置则不需要填写。
CQ-Http 配置 请准确填写你部署 go-cqhttp 时的信息。

需要配置 go-cqhttp 目录下的文件 config.yml 里数据类型为 array,修改完后重启 go-cqhttp 生效。

yaml
message:
+    # 上报数据类型
+    # 可选: string,array
+    post-format: array

access-token 可在 go-cqhttp 目录下的文件 config.yml 找到

yaml
# 默认中间件锚点
+default-middlewares: &default
+    # 访问密钥, 强烈推荐在公网的服务器设置
+    access-token: '*******'
+    # 事件过滤器文件目录
+    filter: ''
+    # API限速设置
+    # 该设置为全局生效
+    # 原 cqhttp 虽然启用了 rate_limit 后缀, 但是基本没插件适配
+    # 目前该限速设置为令牌桶算法, 请参考:
+    # https://baike.baidu.com/item/%E4%BB%A4%E7%89%8C%E6%A1%B6%E7%AE%97%E6%B3%95/6597000?fr=aladdin
+    rate-limit:
+        enabled: false # 是否启用限速
+        frequency: 1  # 令牌回复频率, 单位秒
+        bucket: 1     # 令牌桶大小

Mirai-api-http QQ群机器人

APP ID 为登录在 mirai-api-http 的 QQ 号
TOKEN 为 mirai-api-http 的 AuthKey
Mirai-api-http 配置 请准确填写你部署 mah 时的信息。

AuthKey 可在 mirai-console 目录下的文件 config/net.mamoe.mirai-api-http/setting.yml 找到

yaml
adapters:
+    - http
+    - ws
+debug: false
+enableVerify: true
+verifyKey: ******* # 此处即是 AuthKey
+singleMode: false
+cacheSize: 4096
+adapterSettings:
+    http:
+        host: 0.0.0.0
+        port: 8080
+        cors: [ * ]
+    ws:
+        host: 0.0.0.0
+        port: 8060
+        reservedSyncId: -1

运行实例

点击“保存并启动”运行实例,当实例状态为在线时,即启动成功。

image

温馨提示

实例的连接需要时间,通常只需要几秒钟不到。如果显示离线可以等待几秒再刷新页面。

配置可控实例

配置时打开选项 可控实例,并填写一个群号。可接收到该实例的一些相关通知。

image
+ + + + \ No newline at end of file diff --git a/guide/deploy/console/index.html b/guide/deploy/console/index.html new file mode 100644 index 00000000..470ecbda --- /dev/null +++ b/guide/deploy/console/index.html @@ -0,0 +1,24 @@ + + + + + + 连接控制台 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

连接控制台

兔兔在启动后会开启一个 HTTP 服务,默认端口为 8088。提供给 控制台 调用。你可以根据需要在启动前修改配置config/server.yaml

yaml
host: 127.0.0.1
+port: 8088
+authKey:

authKey 为连接控制台时的密钥,默认不需要。

危险

当您试图将控制台暴露至公网时,请务必设定 authKey!
如果不这么做,您的服务将可能面临极大的安全风险!因此造成的一切后果与项目组无关,由您自行承担!

注意

不推荐您使用纯数字,或是简单的数字、字母组合等弱口令作为 authKey(如 123456, 000000, abcdef 等)。
如果您坚持这么做,您的服务将可能面临较大的安全风险!因此造成的一切后果与项目组无关,由您自行承担!
特别的,当您尝试使用纯数字的 authKey 时,由于 YAML 规范定义其为整数类型,您的 authKey 将可能因类型错误无法识别。如果您坚持使用纯数字的 authKey,请使用单引号 '' 或双引号 "" 将 authKey 括起。

连接

浏览器打开控制台 https://console.amiyabot.com,在主界面填入你的服务地址。
默认为 http://127.0.0.1:8088

点击“测试并连接”,成功进入后即可开始配置。

公网/局域网访问

host 配置为 0.0.0.0 即可让服务通过本机 IP 访问

yaml
host: 0.0.0.0

危险

当您试图从公网连接至控制台时,请务必通过反向代理加密连接!
如果不这么做,您的服务将面临极大的安全风险!因此造成的一切后果与项目组无关,由您自行承担!

我们的团队成员 Initial-heart 为你提供了 一篇通过 Nginx 反向代理加密连接的博客,你可以根据这篇博客对你的连接进行加密。

+ + + + \ No newline at end of file diff --git a/guide/deploy/console/plugin.html b/guide/deploy/console/plugin.html new file mode 100644 index 00000000..38bdab18 --- /dev/null +++ b/guide/deploy/console/plugin.html @@ -0,0 +1,23 @@ + + + + + + 安装插件 | AmiyaBot + + + + + + + + + + + +
Skip to content
On this page

安装插件

选择安装你需要的功能插件

在插件商店安装插件

插件商店可以实时查看有新版本的插件,需要时可通过商店更新。

通过插件包自动安装

插件通常是一个zip压缩包或是 Python Package 的形式,你可以将它放在 plugins 目录下,启动时可以自动安装。

管理插件

安装好的插件可以在插件管理查看,现在,你已经可以使用它们了。

部分插件可能存在需要配置的信息,可在插件配置选项卡查看并编辑(需插件支持)。

🎉 恭喜你,到这里你已经部署完成了!快去体验兔兔吧!🎉

+ + + + \ No newline at end of file diff --git a/guide/deploy/faq/PluginProblem.html b/guide/deploy/faq/PluginProblem.html new file mode 100644 index 00000000..3f62d7b7 --- /dev/null +++ b/guide/deploy/faq/PluginProblem.html @@ -0,0 +1,22 @@ + + + + + + 插件常见问题 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

插件常见问题

本章收录了用户在使用官方插件时向我们提问较多的问题。

公招图片识别没法用

请注意

公招图片识别功能需要申请并配置相应的百度智能云 API

请根据插件文档配置相关信息。

我不知道如何申请百度云 api

  • 请自行百度或联系百度智能云的支持服务。

如何给兔兔添加表情

  • 对应的文件位置在 plugins/amiyabot-user*/face 下,直接将图片文件扔到文件夹内即可。

代码部署后部分插件无法正常产生图片

  • 在安装完依赖后 需要额外安装playwright的chromium及其依赖
    • 对于windows:
    shell
    playwright install chromium
    • 对于linux:
    shell
    playwright install --with-deps chromium

注意

若使用的操作系统不在 官方支持列表 中,您可能无法正确执行该操作,也无法获得官方的任何支持。

有时候公招图/专精材料图显示不完整

偶现该情况是正常现象,这与设备性能等因素有关,通常再请求一次即可正常返回图片。

抽卡时出现了(按游戏卡池发布顺序来说)不可能出现的新干员

请理解为卡池在现在复刻了。复刻的卡池中显然会出现任何非限定或特殊干员。

抽卡时出现了黑色的人物条/出现了限定/赠送/肉鸽干员

  • 可以前往控制台中的干员设置设定干员的限定属性(黑色的条一般是各个预备干员)

可是我的各个限定干员都已经被设置为不可抽取了

  • 有时你可能更新了卡池却没有更新干员数据也会导致这个问题
  • 此时重启兔兔本体或点击按钮【应用干员设置】即可更新干员数据
+ + + + \ No newline at end of file diff --git a/guide/deploy/faq/commonProblem.html b/guide/deploy/faq/commonProblem.html new file mode 100644 index 00000000..7a9762ac --- /dev/null +++ b/guide/deploy/faq/commonProblem.html @@ -0,0 +1,42 @@ + + + + + + 常见问题 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

常见问题

本章收录了用户在部署/使用过程中向我们提问较多的问题。

作者:晓月君
修饰:Chino酱

我看不懂什么是克隆仓库/代码部署的指令会报错

  • 你是否在考虑使用可执行文件部署而不是代码部署?
  • 请注意文档中提供的“使用可执行文件部署”与“使用代码部署”任选其一进行即可,执行完即可进入下一步骤,而不是两者都要进行。

使用可执行文件部署时,兔兔的窗口闪现了一下/出现了一小段时间又消失了(闪退)

git 未正确配置

请使用组合键 win+R 输入 cmd 后回车,在跳出来的黑色框框中输入 git 后回车,如果显示

'git'不是内部或外部命令,也不是可运行的程序或批处理文件。

通常情况下,这是 git 未正确安装导致的,可能是由于你没有认真看文档根本没有安装 git 所导致。请根据文档安装 git

安装完成后,再次重复上述操作,此时应该会显示如下的文本,这就证明你配置好了 git,可以再次尝试打开可执行文件了。

usage: git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]
+           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
+           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
+           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
+           [--super-prefix=<path>] [--config-env=<name>=<envvar>]
+           <command> [<args>]
+
+These are common Git commands used in various situations:
+
+start a working area (see also: git help tutorial)
+   clone     Clone a repository into a new directory
+   init      Create an empty Git repository or reinitialize an existing one
+
+work on the current change (see also: git help everyday)
+   add       Add file contents to the index
+   mv        Move or rename a file, a directory, or a symlink
+   restore   Restore working tree files
+   rm        Remove files from the working tree and from the index
+
+...

我很确定我已经安装了git,但是我在黑框内输入git后还是会显示“不是内部或外部命令”

这个现象大概率是因为设备的环境变量没有配置好导致的,请参考 此文章 尝试将 git 的路径添加入环境变量中再次尝试开头的操作。

资源包没能完成下载

我在窗口最上方看到了一些进度条,可是没能跑完就闪退了

  • 请检查你的网络连接或是否开启了代理软件。
  • 若你有意或无意地导致了 resource/gamedata 文件夹内的内容产生了变动,可能导致无法更新。直接删除整个 resource/gamedata 文件夹重新启动程序即可

启动时弹窗提示“无法定位程序输入点...”

  • 你是否在使用 win7 或较老的 WindowsServer 版本?
  • 就结论而言 win7 或较老的 WindowsServer 版本无法运行兔兔 原因是 node 版本不兼容 推荐升级 win10(若情况允许)或者使用云服务器部署/更换云服务器镜像

无法进入控制台

我尝试进入控制台时出现了 ERR_NETWORK 服务器异常

  • 检查浏览器顶端的地址栏 通常,地址栏中协议(也就是网址最开头的http/https)应该使用http 如果你的网址以https开头,请改为http后再重新尝试访问

  • 部分内核的浏览器可能会拦截公网对私网不安全的访问请求

    • 打开 tab 页面 chrome://flags/#block-insecure-private-network-requests
    • Block insecure private network requests 设置为 Disabled, 然后重启 zukVk6.png
  • 若你访问控制台的设备与运行兔兔的设备不是同一台设备 你需要修改兔兔本体的一些设置

    • 前往兔兔的config/server.yaml
    • host的值修改为0.0.0.0
    • 重新启动兔兔

我不知道服务地址应该填什么

  • 如果你访问控制台的设备与部署兔兔的设备为同一台的话,通常你应该填写的就是http://127.0.0.1:8088,而服务密钥留空
  • 如果你访问控制台的设备与部署兔兔的设备不是同一台,但是在同一个局域网内(通常指在同一个家里)
    • 参照文档host 修改为 0.0.0.0
    • 参考此文章查询你部署兔兔的设备的局域网ip(通常是以 192 开头的一串数字)
    • 控制台中应填写 http://[你查询到的ip]:8088
    • 而服务密钥留空
  • 如果你将兔兔部署在云服务器上,在另一台设备上访问控制台,那么事情将会变得有些棘手,首先你需要参照上面的指示将 host 修改为 0.0.0.0,其次你需要给云服务器运营商的防火墙设置一个入站规则(关于如何做到这一点,请自行百度),通常端口是 8088,协议为tcp,并且操作系统内也需要设置入站规则(也请自行百度)
    • 提示:通过公网访问,可能有设备被攻击的风险,请自行配置服务密钥(在 config/server.yaml 中修改 authKey 的值并填入控制台的服务密钥中)。更进一步,推荐使用Nginx反代服务提供更高的安全性,请参考文档

控制台中实例无法连接

由于作者仅涉足过mirai,本处仅将提供mirai相关问题的解决思路,不过部分解决思路也可用在gocq中

我们先来对配置单的具体内容进行一些解释

  • APP ID:mirai登陆的qq号,也就是你bot的qq号
  • TOKEN:对mirai来说,为mirai/config/net.mamoe.mirai-api-http/settings.ymlverifyKey的值
  • 适配器类型:通常你应该选择CQ-Http或是Mirai-api-http而不是QQ-Bot
  • 可控实例:是否将一些运行信息发送至特定群组 (若是勾选了,控制台群组id应为你希望运行信息出现在的群聊的群聊号中)
  • Host地址:如提示所示,如果是同一台设备的话 填写127.0.0.1
  • HTTP端口:mirai/config/net.mamoe.mirai-api-http/settings.ymlhttpport的值
  • WS端口:mirai/config/net.mamoe.mirai-api-http/settings.ymlwsport的值 (如果你参考的是初心佬的文章,那这两项应该分别为80808060)

以下是兔兔的窗口中可能出现的报错信息以及相应处理方法

指定bot不存在

请检查mirai是否正确登陆了bot的qq

Auth Key错误

rt,检查mirai本体配置中authKey的值与控制台填写的是否一致

Cannot connect to mirai-api-http websocket server

  • 检查mirai是否启动
  • 检查mirai-api-http中host地址与两个端口填写是否有误
  • 常见错误为看错并填写错端口(如8080与8060看混 或者修改了mah的配置却未更改控制台实例配置单)

Got code 401

适配器类型应该是Mirai-api-http或者CQ-Http而不是QQ-Bot

无效参数

实例配置单中的qq号是否填写错误了

mcl无法正常启动

温馨提示:对mcl一切配置文件的更改都应该在mcl不在运行的情况下进行

系统找不到指定的路径

  • mcl处于的路径中不能有任何中文字符(包括汉字与中文标点)
  • 请将mcl-installer转移至一个没有中文字符的路径下重新安装

我很确定我的路径中没有中文字符

  • 你是否人为移动了(有意或无意)mcl所处文件夹或者其子文件夹?
  • 对小白来说,如果你想移动mirai,最好的方法其实是将mcl-installer移动到别处重新安装 并将原来的config以及plugins文件夹移动到新安装的mirai中覆盖

当前qq版本太低

  • 升级mcl本体
  • 将协议换为IPAD 前往config/Console/AutoLogin.ymlprotocol更改为IPAD
  • 删除bots文件夹下所有内容

登录存在安全风险

  • 这个东西吧...挺玄学的,通常是云服务器上部署的mirai才会有这个问题,要通过这个验证,通常需要手机与电脑在同一网络环境下,而如果你使用了云服务器,那么除了使用一些玄学手段(指过两天再试就好了)或者科学手段(这玩意儿可不兴展开来讲啊 哥)外别无他法。

苹果手机无法安装滑块助手

  • 初心佬的文章最下方有手动获取ticket的教程
  • 注意,此时你不需要再点击Open with TxCaptchaHelper按钮了,而是直接将教程中获取到的ticket填入ticket栏中即可

A JNI error has occured.

  • 通常这是由于java版本太低导致的
  • 两个解决方案
    1. 可以手动安装一个java的jdk(建议版本为17或18 安装方法请自行百度)
    2. 使用mcl installer重新安装mcl 在安装时会询问是否安装java jdk 选择安装即可

有大段看不懂/完全没有中文信息的红色报错

  • 通常,这类报错的关键信息都在红色文本的最下方或者最上方
  • 如果最下方没有中文的提示,那么请前往红色文本的最上方查找关键信息

Address already in use

  • 你是否启动了两个mcl? 如果是的话,请关闭一个,并保证同时只有一个mcl在运行
  • mah中所填写的的端口与某个外部应用冲突,可以修改config/net.mamoe.mirai-api-http/setting.yml 中两个端口的值解决,值理论上可以是1024~65535中的任何一个数字

注意

若是在此处修改了端口值,你应该在控制台中填写实例配置单时相对应地修改端口值

代码部署启动时/使用特定命令时会报错

既然你是代码部署的,一些常见的细节我将会省略不解释,希望你能看懂

  • 请更新代码 & 依赖 & 插件
    shell
    git pull
    +pip install --upgrade amiyabot

可执行文件部署启动时会报错

  • 你是否更新了插件? 我通常称这种行为叫旧瓶装新酒
  • 请检查项目官网是否有更新的版本
  • 如果是的话,请更新兔兔版本后再试

部署过程看起来一切都很正常,但兔兔就是不理人

  • 检查是否有安装插件,v6的插件化使得默认部署完的兔兔是没有插件的 也就无法对常见的互动进行回应

我已经安装好插件了

  • 查看mirai窗口,检查是否有消息推送的提示,如果没有,则是mirai启动/配置有问题,导致mirai这一步就收不到消息,请检查mirai的启动情况与配置文件,并配合前文的排错食用
  • 查看兔兔窗口 是否有消息推送 通常 有的话还不回应就见鬼了
    • 检查报错,是否未正确连接到mirai

划重点

windows的cmd存在 单击窗体内黑色部分进入快速选择 这么一个机制 标志是窗口标题最前面出现了选择二字 而进入了快速选择 应用本体的运行将会被冻结 产生应用卡住不动的表象 这种情况下 只要敲击回车就可以推出快速选择 这一点对mirai和兔兔两者都适用

更新兔兔/迁移兔兔时,如何保留原来的数据

  • 将旧兔兔的 database 整个覆盖至新兔兔的根目录下即可
  • 对于可执行文件部署,也可以选择用新的可执行文件覆盖旧的可执行文件,便可以不用迁移数据库文件,但请注意,有时这会导致插件与本体版本不一致的问题,通常使用上一个方案,并重新安装插件即可解决
+ + + + \ No newline at end of file diff --git a/guide/deploy/getStarted.html b/guide/deploy/getStarted.html new file mode 100644 index 00000000..5e1d25d5 --- /dev/null +++ b/guide/deploy/getStarted.html @@ -0,0 +1,59 @@ + + + + + + 开始部署 | AmiyaBot + + + + + + + + + + + + +
Skip to content
On this page

开始部署

操作系统支持

  • Windows 10、Windows Subsystem for Linux (WSL) 或 Windows Server 2012 及以上系统
  • MacOS 11 (Big Sur) 及以上系统
  • Linux 系统官方支持 Debian 11、Ubuntu 18.04 以及 Ubuntu 20.04

安装 Git

部分插件依赖本地的 Git 服务,必须安装 Git 以确保正常使用。点击下载 并安装。或自行到官网下载合适自己系统的版本。

部署

根据你的设备系统或习惯,你可以选择 可执行文件部署 代码部署 两种方式其一

Windows 系统推荐使用可执行文件部署,可执行文件部署是一键部署的模式,部署难度低。

通过可执行文件部署

操作系统下载备注
WindowsAmiyaBot--win32.zip仅支持 Windows 10、Windows Server 2016 及以上系统
LinuxAmiyaBot-v6.4.6-linux.zip不再继续提供支持,请使用代码部署

Windows

下载并解压,运行 AmiyaBot-v6.x.x-win32.exe,如下图成功运行后可以进入下一节

img.png

Linux

不再继续提供支持,请使用代码部署

原内容

不支持 Centos,目前在 Ubuntu 20.04 测试可用。

下载并解压,进入 package/dist 目录,运行 AmiyaBot-v6.x.x-linux

bash
cd package/dist/
+chmod 777 ./AmiyaBot-v6.x.x-linux
+./AmiyaBot-v6.x.x-linux

通过代码部署

请根据操作系统按顺序执行以下命令。

注意

推荐使用 Python 3.8 ~ 3.9 运行本项目代码,并参照可执行文件的系统支持选择部署的操作系统。

  1. 克隆仓库
bash
git clone --depth 1 https://github.com/AmiyaBot/Amiya-Bot.git
+cd Amiya-Bot
  1. 使用 virtualenv 创建虚拟环境(非必须,或根据个人习惯选择虚拟环境)
bash
# Windows
+python -m venv venv
+call venv/Scripts/activate.bat
bash
# Linux or MacOS
+python -m venv venv
+source venv/bin/activate
  1. 安装依赖
bash
pip install -r requirements.txt
  1. 安装浏览器内核

默认为 Chromium

bash
# Windows or MacOS
+playwright install chromium
+# Linux
+playwright install --with-deps chromium

部分系统由于版本过低(如 Windows Server 2012),可能不支持 chromium 内核。推荐修改为火狐(firefox)内核启动。

bash
# Windows or MacOS
+playwright install firefox
+# Linux
+playwright install --with-deps firefox
使用火狐内核需要修改入口程序 amiya.py,点击查看代码
python
import ...
+
+from amiyabot import BrowserLaunchConfig  # 导入浏览器启动配置类
+
+
+# 创建新启动类
+class Launcher(BrowserLaunchConfig):
+    def __init__(self):
+        super().__init__()
+
+        self.browser_type = 'firefox'  # 设定浏览器属性
+
+
+def run_amiya(*tasks: Coroutine):
+    ...
+
+
+if __name__ == '__main__':
+    run_amiya(
+        bot.start(launch_browser=Launcher()),  # 更改为使用新启动类启动浏览器
+        app.serve(),
+        load_plugins()
+    )
  1. 运行代码
bash
python amiya.py

日志显示同可执行文件部署,成功后可以进入下一节。

+ + + + \ No newline at end of file diff --git a/guide/deploy/index.html b/guide/deploy/index.html new file mode 100644 index 00000000..e64839cd --- /dev/null +++ b/guide/deploy/index.html @@ -0,0 +1,23 @@ + + + + + + 简要说明 | AmiyaBot + + + + + + + + + + + +
Skip to content
On this page

简要说明

《明日方舟》机器人 兔兔-v6 为本框架的主体项目。是 Amiya-Bot V5 的迭代版本。本框架原名为 AmiyaBot-core,是围绕着主体项目进行开发的。

本章接下来的文档,是提供给 兔兔-v6 部署用户的指引,如果你的目的是开发一个完全由自己定制的机器人,请阅读开发指南

你也可以从 兔兔-v6 的基础上进行定制。但之中的一部分代码服务于其本身的《明日方舟》功能系列插件,以及控制台项目 Amiya-Bot-console2,如果你不需要这些代码,也许你难以将它们抽离。请谨慎选择此方式。

那么,如何部署属于自己的 兔兔-v6(以下简称“兔兔”),请阅读接下来的文档。

官方版兔兔

现在,你可以直接使用官方版的兔兔啦!🎉🎉🎉

+ + + + \ No newline at end of file diff --git a/guide/deploy/maintain/upgrade.html b/guide/deploy/maintain/upgrade.html new file mode 100644 index 00000000..abbf89ff --- /dev/null +++ b/guide/deploy/maintain/upgrade.html @@ -0,0 +1,22 @@ + + + + + + 如何更新 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

如何更新

游戏资源更新

每次启动时会检查资源仓库并更新新资源。
当游戏有更新的当日,可以通过重启程序来获得更新。

提示

资源的解包需要一定时间,无法获取更新时可稍后再试。

程序更新

从 V6 开始程序将不再自动更新,也不会推送更新消息。请关注 官方频道 获取最新的通知。

当有更新时可到 下载页面 下载更新包。
通常情况下,你只需要解压更新包的 exe 程序到你原来的目录下并启动新的程序就可以了。

插件更新

插件同样也不会自动更新。请关注插件商店和频道的公告。

+ + + + \ No newline at end of file diff --git a/guide/deploy/yourChoose.html b/guide/deploy/yourChoose.html new file mode 100644 index 00000000..e37d592d --- /dev/null +++ b/guide/deploy/yourChoose.html @@ -0,0 +1,26 @@ + + + + + + 选择你的运营方 | AmiyaBot + + + + + + + + + + +
Skip to content
On this page

选择你的运营方

QQ 机器人目前分为两种,一种是由腾讯官方运营的 频道机器人,另一种则是由第三方技术提供支持的QQ群机器人。

频道机器人

如果你选择了频道机器人,并且注册了“公域机器人”,很遗憾地告诉你,你不能继续部署兔兔了。因为兔兔有官方版本,你不能发布一个功能与官方版本相当接近的机器人。你可以加入 官方频道 并找到机器人“AmiyaBot”,点开资料卡添加到自己的频道里。

当然,你可以基于 AmiyaBot 框架开发自己的机器人并发布。请参阅 开发指南

如果是“私域机器人”,你仍然可以继续部署。

KOOK 机器人

请在 KOOK 开发者平台,创建一个机器人应用。

QQ 群机器人

如果你选择了 QQ 群机器人,你可能需要克服一些困难才能顺利部署。你必须部署第三方技术提供的服务才能继续部署兔兔。

第三方技术目前支持:

选择其中一个进行部署即可。

使用 go-cqhttp

请按照 go-cqhttp 官网 的说明进行部署。

修改配置中的 post-format: array

yaml
# config.yml
+message:
+    # 上报数据类型
+    # 可选: string, array
+    post-format: array

使用 mirai-api-http

mirai-api-http 有一定的部署难度,需要你拥有一定的计算机科学基础。但对比其他第三方服务,mirai 在很多方面都占有优势。

我们的团队成员 Initial-heart 为你提供了一篇部署 mirai-api-http 的博客,这篇博文详尽的描述了部署 mirai-api-http 的前期准备、部署、配置等整套部署 mirai-api-http 所需的流程。

https://www.initbili.top/2022/8d92a2feb3e2/#2-部署-mirai

结语

非常重要

请耐心根据教程部署完。部署完第三方服务,你就完成 80% 的工作了!务必部署成功再往下继续,否则后续的操作将毫无意义。

如果一切就绪,那么接着来看开始部署部分。

+ + + + \ No newline at end of file diff --git a/guide/index.html b/guide/index.html new file mode 100644 index 00000000..4ba86231 --- /dev/null +++ b/guide/index.html @@ -0,0 +1,22 @@ + + + + + + AmiyaBot 简介 | AmiyaBot + + + + + + + + + + +
Skip to content

AmiyaBot 简介

介绍

AmiyaBot 是异步 Python QQ 机器人框架。基于 QQ 官方API 。内置了丰富的消息构建方法和适配器,让你轻松实现你的创意。

她的过去...

AmiyaBot 诞生于2019年,是一个《明日方舟》民间 QQ 机器人,至本框架发布时已迭代了 5 个里程碑版本。一直以来,AmiyaBot 都秉着 “为所有人带来快乐” 的初衷,跌跌撞撞到现在,依旧坚持开源、免费为用户提供服务。

2022年5月13日重大变故后,AmiyaBot 决定迁移至 QQ 频道成为正式的机器人。原群聊机器人(Amiya2号)终止服务。
2022年6月11日,剥离出其核心部分成为框架,也就是本文档所指的 AmiyaBot
2022年9月14日,V6 版本 的用户自部署群聊机器人发布,由用户延续原群聊机器人(Amiya2号)的初衷。
2024年6月18日,官方全域机器人正式发布。

现在

AmiyaBot 依旧坚持初心,将快乐带给所有人。加入我们的 官方群官方频道开始使用

+ + + + \ No newline at end of file diff --git a/hashmap.json b/hashmap.json new file mode 100644 index 00000000..80e4918d --- /dev/null +++ b/hashmap.json @@ -0,0 +1 @@ +{"develop_adapters_qqgroup.md":"a8bb1495","develop_adapters_onebot12.md":"8cb31022","develop_adapters_gocq.md":"42ef6fb0","develop_adapters_onebot11.md":"2dcd662d","develop_advanced_loadplugins.md":"05064a96","develop_advanced_httpsupport.md":"82709c73","develop_advanced_playwright.md":"8235080e","develop_advanced_logger.md":"58165055","develop_advanced_lifecycle.md":"05397678","develop_basic_chainbuild_embed.md":"ae4a3957","develop_basic_chainbuild_forward.md":"8fc44648","develop_basic_chainbuild_ark.md":"4bf94265","develop_basic_api_index.md":"c8b00309","develop_advanced_index.md":"5155177e","develop_adapters_index.md":"80074c45","develop_adapters_mah.md":"099962a3","develop_advanced_startupparameter.md":"ca7b0373","develop_basic_chainbuild_atall.md":"b0aa82d9","develop_advanced_timedtask.md":"891d290c","develop_basic_chainbuild_extend.md":"d4c803dd","develop_basic_chainbuild_face.md":"57e44a04","develop_adapters_qqglobal.md":"51606d6f","develop_basic_api_qqbot.md":"068658d1","develop_advanced_blockingio.md":"70c4539f","develop_advanced_eventbus.md":"885a83aa","develop_adapters_kook.md":"17d969b2","develop_adapters_comwechat.md":"1ec4e8a3","develop_basic_chainbuild_at.md":"50524660","develop_advanced_httprequests.md":"d5ec3c2e","develop_adapters_qqchannel.md":"42bbea52","develop_advanced_databasesupport.md":"91220591","develop_advanced_chainbuilder.md":"43e1e2e4","develop_basic_chainbuild_mdtemplate.md":"6ba5c9fa","develop_basic_chainbuild_voice.md":"efe611ec","develop_basic_chainbuild_tag.md":"c0a92925","develop_plugin_env.md":"d6dd6f2b","develop_index.md":"cb06d4cf","develop_basic_recallmessage.md":"35c06f76","develop_design.md":"6a51dd3e","develop_basic_testinstance.md":"9912ed2d","develop_plugin_amiyabotplugininstance.md":"9e3e1e87","develop_basic_statement.md":"9327bd3e","develop_basic_handleexception.md":"501ddbf6","develop_basic_index.md":"52c59217","develop_basic_chainbuild_html.md":"b5f77581","develop_basic_chainbuild_markdown.md":"2f3e8203","develop_basic_chainbuild_video.md":"fb39365f","develop_basic_chainbuild_text.md":"76e8530f","develop_basic_messagehandler.md":"1199dda3","develop_basic_recvmessage.md":"4e302953","develop_basic_handleevents.md":"1fa0bea7","develop_basic_chainbuild_image.md":"3716f519","develop_plugin_debug.md":"495c0873","develop_plugin_adddoc.md":"53e3a292","develop_basic_sendmessage.md":"2be0a78a","download.md":"0155255c","develop_plugin_life.md":"c42d477f","develop_plugin_create.md":"0387968a","develop_plugin_index.md":"44c66f5a","develop_plugin_build.md":"86d0a5fe","guide_index.md":"4a06ec29","develop_basic_continuitymessage.md":"f8d8bfa7","develop_basic_chainbuild_textimage.md":"e1fe255d","develop_basic_multipleaccounts.md":"86504678","guide_deploy_advanced_index.md":"bfe56c56","develop_plugin_jsonschema.md":"6567afac","guide_deploy_console_plugin.md":"6a874539","guide_deploy_faq_pluginproblem.md":"ccf6151b","guide_deploy_faq_commonproblem.md":"66ab12e1","guide_deploy_maintain_upgrade.md":"cf23d537","guide_deploy_console_index.md":"175af869","develop_basic_sendactivemessage.md":"6174eebb","develop_plugin_publish.md":"28cda1dc","index.md":"27207959","guide_deploy_getstarted.md":"86630331","guide_deploy_console_configure.md":"50610948","guide_deploy_advanced_mysql.md":"55d14788","sponsor.md":"b1d18c44","guide_deploy_yourchoose.md":"579635ff","guide_deploy_index.md":"bcece2d5"} diff --git a/index.html b/index.html new file mode 100644 index 00000000..766949ac --- /dev/null +++ b/index.html @@ -0,0 +1,23 @@ + + + + + + AmiyaBot | AmiyaBot + + + + + + + + + + + +
Skip to content

AmiyaBot

Progressive Python QQ Bot Framework

渐进式 QQ 机器人框架,可使用内置适配器对接官方 QQ 群、OneBot v11/12、KOOK 等机器人平台。

AmiyaBot
🚀

简洁高效

采用异步 I/O,摆脱官方 API 繁杂的操作,以更加简洁和可读性更高的代码让你专注于你的业务逻辑。

🎭

多账号 & 热插拔

支持同时创建多个机器人实例,为所有实例注册共享的消息处理方法,以及在多账号实例内动态增删机器人。

🧩

适配器 & 插件支持

通过适配器来更改机器人的服务来源,提供更大的灵活性和可扩展性。支持插件开发方案,将业务和主程序分离,使机器人更加生态化和可定制化。

🎉

丰富的消息类型

内置的 PIL 图像合成模块以及 HTML 转换器,支持合成文字图片或通过渲染 WEB 和 Markdown 合成图片,轻松实现你的绝佳创意。

+ + + + \ No newline at end of file diff --git a/logo.svg b/logo.svg new file mode 100644 index 00000000..3feeda3d --- /dev/null +++ b/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/sponsor.html b/sponsor.html new file mode 100644 index 00000000..765bc609 --- /dev/null +++ b/sponsor.html @@ -0,0 +1,23 @@ + + + + + + 赞助 | AmiyaBot + + + + + + + + + + + +
Skip to content

赞助

AmiyaBot 一路走来离不开大家的默默支持,如果你喜欢并支持我们,可以为我们打赏一瓶快乐水。我相信快乐是可以互相传递的,你的快乐水带给我们快乐的同时,想必 AmiyaBot 也给你带去了快乐吧。

但同时我们希望你量力而为,你对 AmiyaBot 的认可就已经是最大的支持了。如果可以的话,恳请你在 Github 为 AmiyaBot 点上一颗小小的️ ⭐ star。

特别鸣谢

感谢各位对 AmiyaBot 社区做出的贡献,是大家共同塑造了 AmiyaBot 社区的繁荣。期待未来我们能携手创造更多可能!🌹

幕后大佬顶级的存在!支撑兔兔的所有!
Initial heart社区风纪委员、Logo 贡献者
hsyhhssyy插件作者、兔兔 AI 维护人
天基插件作者、插件服务器贡献者
.Tdp插件作者、百度图像识别接口贡献者

充电鸣谢

你们的鼎力支持让我们感到创作 AmiyaBot 项目是值得的。感谢有你,让 AmiyaBot 秉承初衷。❤️

打赏请前往爱发电主页

image
+ + + + \ No newline at end of file