weifuwu 0.72.0 → 0.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -97,7 +97,7 @@ npm install weifuwu # 一个依赖,完整应用栈
97
97
 
98
98
  **async 工厂组件** — `async (ctx) => (initProps, ctx) => (props) => VNode`:工厂层声明数据(`await ctx.data.get`)、mount 初始化状态(`$`)、render 输出视图。异步只在工厂边界,mount/render 保持同步;数据经闭包注入,写数据像写同步代码。三条纪律见[核心概念 · async 组件](#核心概念)。
99
99
 
100
- **SPA/SSR/Hydration 统一透明** — 同一份路由定义(`routes`)一个组件三场景自动适配:后端 `uiSsr({ routes })` 匹配即自动 SSR(完整 HTML + `__DATA__`),客户端 `router({ routes })` + `RouteView` + `mount(..., { hydrate: true })` 按 URL 同源匹配并收养服务端 HTML(不重建、无闪跳)。`ctx.data.get` 一个 API:SSR 预取 / hydration 命中(不重复请求)/ SPA 触发 fetch。服务端直接用 `.tsx`(`weifuwu/dev` Node loader),前后端同一 JSX 运行时。
100
+ **SPA/SSR/Hydration 统一透明** — 同一份路由定义(`UIRouter`)一个组件三场景自动适配:后端 `ssrPage(router, { url })` 匹配即自动 SSR(完整 HTML + `__DATA__`),客户端 `uiServe(router, { root, hydrate: true })` 按 URL 同源匹配并收养服务端 HTML(不重建、无闪跳)。`ctx.data.get` 一个 API:SSR 预取 / hydration 命中(不重复请求)/ SPA 触发 fetch。服务端直接用 `.tsx`(`weifuwu/dev` Node loader),前后端同一 JSX 运行时。
101
101
 
102
102
  **AI 是一等公民** — 自研 OpenAI 兼容协议(`design/ai-contract.md`)+ 零依赖流式客户端 + agent 工具循环 + HITL 人工审批 + embedding 向量化。后端 `ctx.ai` 一个入口:`chat()` / `stream()` / `agent()`(`stream(messages, { emit })` emitter 抽象——事件可接任意通道,`runToResult()` 结构化结果)/ `approve()` / `embed()` / `embedMany()`;前端 `ctx.ui.useChat()`(会话语义)+ `AiChat` 组件(标准对话界面)——流式 token / 工具调用卡 / 审批卡开箱即用,协议对页面完全透明,不用 ai-sdk。
103
103
 
@@ -119,8 +119,8 @@ npm install weifuwu # 一个依赖,完整应用栈
119
119
 
120
120
  | 模式 | 适用场景 | 后端 | 客户端入口 |
121
121
  |------|---------|------|-----------|
122
- | **SPA** | 应用页(Dashboard、工具、后台) | HTML 外壳 | `mount('#root', RouteView)` |
123
- | **SSR + Hydration** | 内容页(博客、营销,需要 SEO/首屏) | `uiSsr` 一行 | `mount('#root', RouteView, { hydrate: true })` |
122
+ | **SPA** | 应用页(Dashboard、工具、后台) | HTML 外壳 | `uiServe(router, { root: '#root' })` |
123
+ | **SSR + Hydration** | 内容页(博客、营销,需要 SEO/首屏) | `ssrPage(router)` 一行 | `uiServe(router, { root: '#root', hydrate: true })` |
124
124
 
125
125
  ### 先写共享部分(两种模式都一样)
126
126
 
@@ -176,7 +176,7 @@ uiServe(app, { root: '#root' }) // 监听 location → 执行路由 → VDOM
176
176
 
177
177
  ### 模式 B:SSR + Hydration(内容页/SEO)
178
178
 
179
- 同一份 `routes`、同一个组件,差异只在**后端加 `uiSsr` 一行、客户端加 `hydrate` 参数**:
179
+ 同一份 `router`、同一个组件,差异只在**后端加 `ssrPage` 一行、客户端加 `hydrate` 参数**:
180
180
 
181
181
  ```ts
182
182
  // server.ts —— 完整版(与模式 A 的差异:ssrPage + 一条样式路由)
@@ -333,7 +333,8 @@ cd apps/agent-platform && npm run seed && npm run dev
333
333
  | `weifuwu` | **postgres** | PostgreSQL 客户端(自研 PG v3 协议)→ `ctx.sql` | Router, DATABASE_URL |
334
334
  | `weifuwu` | **redis** | Redis 客户端(自研 RESP2 协议)→ `ctx.redis` | Router, REDIS_URL |
335
335
  | `weifuwu` | **ui** | SSR 渲染 + esbuild JS/CSS 动态编译 → `ctx.ui` | Router |
336
- | `weifuwu` | **uiSsr** | 路由级 SSR:匹配 routes自动完整 HTML + `__DATA__` + bundle | Router, ui |
336
+ | `weifuwu/ui-dom` | **uiServe** | 渲染运行时:监听 location 执行路由 VDOM 落地(`hydrate: true` 收养 SSR HTML) | UIRouter |
337
+ | `weifuwu/ui-dom` | **ssrPage** | 路由级 SSR:匹配共享 router → 自动完整 HTML + `__DATA__` | Router, ui |
337
338
  | `weifuwu` | **rateLimit** | 限流中间件(fixed/sliding,redis 多实例原子)→ `ctx.limit` | Router, redis |
338
339
  | `weifuwu` | **email** | 邮件发送(Resend/SMTP 自研/自定义适配器)→ `ctx.email` | Router |
339
340
  | `weifuwu` | **userSystem** | 用户系统(scrypt 密码哈希 + 混合会话 + 多租户感知)→ `ctx.user` / `ctx.auth` / `ctx.tenantId` + `/api/auth/*` | Router, postgres |
@@ -388,6 +389,16 @@ cd apps/agent-platform && npm run seed && npm run dev
388
389
 
389
390
  ## 核心概念
390
391
 
392
+ ### 三层形态(路由 / 组件 / 异步工厂)
393
+
394
+ | 层 | 签名 | 异步 | 生命周期 |
395
+ |----|------|------|---------|
396
+ | **UIHandler**(路由) | `async (location, ctx) => VNode` | ✅ 整体 | 每次路由变化执行 |
397
+ | **Component**(组件) | `(initProps, ctx) => (props) => VNode` | ❌ 同步 | mount 一次 + render 每次 |
398
+ | **AsyncFactory**(异步组件) | `async (ctx) => (initProps, ctx) => (props) => VNode` | ✅ 只工厂 | 工厂一次(WeakMap 缓存) |
399
+
400
+ 异步只出现在两个边界——路由 handler(整页)和组件工厂(数据声明);**mount/render 永远同步**(SSR/hydration 两端一致性的根基)。`async (initProps, ctx) => ...` 是混合错形——渲染器不 await 同步组件,Promise 会被当 render 函数调用。
401
+
391
402
  ### 两阶段组件(新手必读:为什么是两层)
392
403
 
393
404
  组件 = `(initProps, ctx) => (props) => VNode`——**外层 = 初始化(只执行一次),内层 = 渲染(每次状态/props 变化时执行)**。类比:外层是对象的构造函数,内层是它的 render 方法。
@@ -414,13 +425,16 @@ const Counter = (_init, ctx) => {
414
425
  app.get('/users', (req, ctx) => { ctx.sql`SELECT *` })
415
426
  // ctx 已注入 ctx.sql
416
427
 
417
- 前端: createApp()
418
- .use(api({ baseURL: '/api' }))
419
- .use(auth())
420
- .mount('#root', App)
428
+ 前端: const router = new UIRouter()
429
+ router.use(api({ baseURL: '/api' }))
430
+ router.use(auth())
431
+ router.get('/users', async (location, ctx) => h(UsersPage, {}))
432
+ uiServe(router, { root: '#root' })
421
433
  // ctx 已注入 ctx.api, ctx.auth
422
434
  ```
423
435
 
436
+ 前端 req = `window.location`(原生对象,不包装),res = `VNode`,`uiServe` = VDOM 落地——与后端 `Request → Response`、`serve(router)` 完全同构。
437
+
424
438
  ### 状态管理
425
439
 
426
440
  | 模式 | 后端 | 前端 |
@@ -467,10 +481,10 @@ const UserProfile = asyncComponent(async (ctx) => {
467
481
  | | SPA | SSR + Hydration |
468
482
  |---|---|---|
469
483
  | 适用 | 应用页(后台、工具、Dashboard) | 内容页(博客、营销,需要 SEO/首屏) |
470
- | 后端 | HTML 外壳 | `uiSsr({ routes })` 一行(自动完整 HTML + `__DATA__`) |
471
- | 客户端 | `mount('#root', RouteView)` | `mount('#root', RouteView, { hydrate: true })` |
484
+ | 后端 | HTML 外壳 | `ssrPage(router, { url })` 一行(自动完整 HTML + `__DATA__`) |
485
+ | 客户端 | `uiServe(router, { root: '#root' })` | `uiServe(router, { root: '#root', hydrate: true })` |
472
486
 
473
- **怎么选**:默认 SPA;需要 SEO 或首屏即内容时用 SSR。两种模式可混合——一个 app 内 `uiSsr` 匹配共享路由,未匹配 `next()` 走普通 handler。
487
+ **怎么选**:默认 SPA;需要 SEO 或首屏即内容时用 SSR。两种模式可混合——一个 app 内 `ssrPage` 匹配共享 router,未匹配 `next()` 走普通 handler。
474
488
 
475
489
  ### Closeable 接口
476
490
 
@@ -498,7 +512,7 @@ README 只保留入门内容(设计理念 / 快速开始 / 核心概念 / 模
498
512
 
499
513
  | 文档 | 内容 |
500
514
  |------|------|
501
- | [docs/frontend.md](docs/frontend.md) | 前端核心:createApp / 组件模型 / 状态管理 / 条件与列表 / ref / 类型 |
515
+ | [docs/frontend.md](docs/frontend.md) | 前端核心:UIRouter / 组件模型 / 状态管理 / 条件与列表 / ref / 类型(历史 client 版见 docs/frontend.md) |
502
516
  | [docs/frontend-ui-dom.md](docs/frontend-ui-dom.md) | **ui-dom**:UIRouter 纯路由 + uiServe 渲染运行时 + ctx 注入链 + components 复用 + SSR/hydration(前端唯一运行时——weifuwu/client 已删除) |
503
517
  | [docs/frontend-middleware.md](docs/frontend-middleware.md) | 前端中间件:router / api / auth / ws / i18n / ErrorBoundary / confirm / toast / ScrollLock / extendCtx |
504
518
  | [docs/components.md](docs/components.md) | 组件库(113 个组件 + 使用示例 + 组件列表) |
@@ -1,18 +1,18 @@
1
- function wn(e){let n=[],t=(e||"/").replace(/:(\w+)/g,(o,i)=>(n.push(i),"([^/]+)")).replace(/\*/g,".*");return{re:new RegExp(`^${t}$`),keys:n}}var Ce=class{_routes=[];_middlewares=[];_injections=[];_injected=!1;_mode;_notFound;constructor(n={}){this._mode=n.mode??"history"}get mode(){return this._mode}use(n,t){if(typeof n=="string"&&t){let o=this,i=n,u=async(r,d,a)=>{let l=d.__routePath??o.getPath(),f=null;return l===i?f="/":(i==="/"?l!=="/"&&l.startsWith("/"):l.startsWith(i+"/"))&&(f=l.slice(i.length)),f===null?a:async(g,w)=>t._handle(f,g,w)};return this._middlewares.push(u),this}return n.length<=1?(this._injections.push(n),this):(this._middlewares.push(n),this)}async _ensureInjected(n){if(!this._injected){this._injected=!0;for(let t of this._injections){let o=await t(n);o&&o!==n&&Object.assign(n,o)}}}get(n,t,o){return this._routes.push({path:n,handler:t,title:o?.title}),this}notFound(n){return this._notFound=n,this}getPath(){return this._getPath(void 0)}_getPath(n){let t=n?.location??(typeof window<"u"?window.location:null);return this._mode==="hash"?(t?.hash??"").replace(/^#/,"")||"/":t?.pathname??"/"}match(n){let t=null;for(let o of this._routes){let{re:i,keys:u}=wn(o.path),r=n.match(i);if(!r)continue;let d={};for(let a=0;a<u.length;a++)d[u[a]]=decodeURIComponent(r[a+1]);t={handler:o.handler,params:d,title:o.title};break}return t||(t={handler:this._notFound??(()=>null),params:{}}),t}async _handle(n,t,o){await this._ensureInjected(o);let i=this.match(n);i.title&&typeof document<"u"&&(document.title=i.title),o.params=i.params;let r=i.handler,d=o.__routePath;o.__routePath=n;try{for(let a=this._middlewares.length-1;a>=0;a--){let l=this._middlewares[a],f=r;r=await l(t,o,f)??f}return await r(t,o)}finally{o.__routePath=d}}async execute(n,t,o){await this._ensureInjected(t);let i=this.match(o);i.title&&typeof document<"u"&&(document.title=i.title),t.params=i.params;let r=i.handler;for(let d=this._middlewares.length-1;d>=0;d--){let a=this._middlewares[d],l=r;r=await a(n,t,l)??l}return await r(n,t)}};function ee(){return{idCounter:0,idRegistry:new Map,unmountHooks:[],asyncFactoryCache:new WeakMap}}function O(e){return e?.__registry??ee()}function ae(e){return`_wf_${e.idCounter++}`}function ue(e,n){return e.unmountHooks.push(n),()=>{let t=e.unmountHooks.indexOf(n);t>=0&&e.unmountHooks.splice(t,1)}}function Te(e,n,t){let o=e.asyncFactoryCache.get(n);if(o)return o;let i={promise:null};return i.promise=Promise.resolve().then(()=>n(t)).then(u=>{if(typeof u!="function")throw new Error(`asyncComponent factory <${n.name||"anonymous"}> must return a Component (initProps, ctx) => (props) => VNode.`);return i.resolved=u,u}),e.asyncFactoryCache.set(n,i),i}async function We(e,n,t){return Te(e,n,t).promise}function De(e,n){return e.asyncFactoryCache.get(n)?.resolved}function xe(e,n,t,o){try{e(n)}catch(i){console.error(`[weifuwu] ref ${t} error in <${o??"anonymous"}>`,i)}}function bn(e,n){let t=e._child;if(t!=null)if(Array.isArray(t))for(let o of t)o&&typeof o=="object"&&U(o,n);else typeof t=="object"&&U(t,n)}function U(e,n){if(e==null||typeof e!="object")return;let t=e;if(t._id){if(t._customId&&n.idRegistry.delete(t._customId),n.idRegistry.delete(t._id),n.unmountHooks.length>0){let o=[...n.unmountHooks];for(let i of o)i(t._id);if(t._customId)for(let i of o)i(t._customId)}t._id=void 0,t._customId=void 0,t._render=void 0,t._parentNode=void 0,t._refNode=void 0}if(t._child!=null){if(Array.isArray(t._child))for(let o of t._child)o&&typeof o=="object"&&U(o,n);else U(t._child,n);t._child=void 0}if(t.props?.children&&typeof t.type=="string"){let o=Array.isArray(t.props.children)?t.props.children:[t.props.children];for(let i of o)i&&typeof i=="object"&&U(i,n)}typeof t.props?.ref=="function"&&xe(t.props.ref,null,"cleanup"),t._remoteEl&&(bn(t,n),t._remoteEl.remove(),t._remoteEl=void 0)}function je(e,n="bottom",t=6,o=!0){switch(n){case"bottom":return{top:e.bottom+t,left:o?e.left+e.width/2:e.left};case"top":return{top:e.top-t,left:o?e.left+e.width/2:e.left};case"left":return{top:o?e.top+e.height/2:e.top,left:e.left-t};case"right":return{top:o?e.top+e.height/2:e.top,left:e.right+t}}}function de(e,n,t=8){if(!n)return e;let o=n.getBoundingClientRect();if(o.width===0&&o.height===0)return e;let i=Number.parseFloat(n.style.top)||o.top,u=Number.parseFloat(n.style.left)||o.left,r=e.top-i,d=e.left-u,a={top:o.top+r,bottom:o.bottom+r,left:o.left+d,right:o.right+d},l=window.innerWidth,f=window.innerHeight,g=e.top,w=e.left;return a.bottom>f-t&&(g=Math.max(t,g-(a.bottom-(f-t)))),a.top<t&&(g=Math.max(t,g+(t-a.top))),a.right>l-t&&(w=Math.max(t,w-(a.right-(l-t)))),a.left<t&&(w=Math.max(t,w+(t-a.left))),{top:g,left:w,width:e.width}}function qe(e){let n=new Map,t=new Map,o=!1,i=0;function u(){i||(i=requestAnimationFrame(()=>{i=0;let f=[];for(let[g,w]of n){if(!w.isOpen())continue;let T=w.getEl();if(!T)continue;let m=T.getBoundingClientRect();if(m.width===0&&m.height===0)continue;let h=w.compute(m);Object.assign(w.pos,de(h,w.panel?.(),w.margin)),f.push(g)}for(let[g,w]of t){let T=w.getScroller(),m=T instanceof Window?document.scrollingElement?.scrollTop??T.scrollY??0:T.scrollTop??0;m!==w.handle.y&&(w.handle.y=m,f.push(g))}f.length>0&&e(f)}))}function r(){o||(o=!0,window.addEventListener("scroll",u,{capture:!0,passive:!0}),window.addEventListener("resize",u))}function d(){o&&(window.removeEventListener("scroll",u,{capture:!0}),window.removeEventListener("resize",u),o=!1)}function a(f){for(let g of[...n.keys()])(g.startsWith(`popup:${f}:`)||g===`popup:${f}`)&&n.delete(g);t.delete(f)}function l(){d(),i&&(cancelAnimationFrame(i),i=0),n.clear(),t.clear()}return{popupTrackers:n,scrollTrackers:t,schedulePopupRecompute:u,ensurePopupListeners:r,destroyPopupListeners:d,cleanupTrackers:a,destroy:l}}var ne=0,$e="",Fe="",Ke="",Be="",ce=0;function Ge(){return typeof window<"u"&&typeof document<"u"}function Ye(){if(ne++,ne>1||!Ge())return;ce=window.scrollY;let e=document.body;$e=e.style.overflow,Fe=e.style.position,Ke=e.style.top,Be=e.style.width,e.style.overflow="hidden",(/iPhone|iPad|iPod/.test(navigator.platform)||/Mac/.test(navigator.platform)&&"ontouchend"in document)&&(e.style.position="fixed",e.style.top=`-${ce}px`,e.style.width="100%")}function ze(){if(ne===0||(ne--,ne>0)||!Ge())return;let e=document.body;e.style.overflow=$e,e.style.position=Fe,e.style.top=Ke,e.style.width=Be,ce>0&&window.scrollTo(0,ce)}var Cn='a[href], button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';function Ee(e){let n=e.querySelectorAll(Cn);if(n.length===0)return()=>{};let t=n[0],o=n[n.length-1],i=r=>{r.key==="Tab"&&(r.shiftKey&&document.activeElement===t?(r.preventDefault(),o.focus()):!r.shiftKey&&document.activeElement===o&&(r.preventDefault(),t.focus()))},u=document.activeElement;return queueMicrotask(()=>{t.focus()}),e.addEventListener("keydown",i),()=>{e.removeEventListener("keydown",i),u?.focus()}}function G(e){let n=new WeakMap,t=new Set,o=u=>{if(u===null||typeof u!="object")return u;if(u instanceof Set||u instanceof Map){if(n.has(u))return n.get(u);let d=u instanceof Set?new Set(["add","delete","clear"]):new Set(["set","delete","clear"]),a=new Proxy(u,{get(l,f){let g=Reflect.get(l,f);return typeof g=="function"?d.has(String(f))?(...w)=>{let T=g.apply(l,w);e();for(let m of t)m();return T}:g.bind(l):g},set(l,f,g){Reflect.set(l,f,g),e();for(let w of t)w();return!0}});return n.set(u,a),a}if(u instanceof Date||u instanceof RegExp)return u;if(n.has(u))return n.get(u);let r=new Proxy(u,{set(d,a,l){if(Reflect.get(d,a)===l)return!0;Reflect.set(d,a,l),e();for(let g of t)g();return!0},get(d,a){let l=Reflect.get(d,a);return typeof l=="object"&&l!==null?o(l):l},deleteProperty(d,a){if(Reflect.has(d,a)){Reflect.deleteProperty(d,a),e();for(let l of t)l()}return!0}});return n.set(u,r),r},i=o({});return Object.defineProperty(i,"__watch",{value:u=>(t.add(u),()=>{t.delete(u)}),writable:!1,enumerable:!1}),i}function Je(e,n,t){let o=new AbortController,i=t?.signal;i&&(i.aborted?o.abort():i.addEventListener("abort",()=>o.abort(),{once:!0}));let u=t?.traceId??_n(),r=t?.record!==!1,d=[],a=(async()=>{let l;try{l=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-Trace-Id":u,Accept:"text/event-stream",...t?.headers},body:JSON.stringify(n),signal:o.signal})}catch(f){if(o.signal.aborted)return;t?.onError?.({code:"provider_error",message:f instanceof Error?f.message:String(f)});return}if(!l.ok){t?.onError?.({code:Pn(l.status),message:`HTTP ${l.status} ${l.statusText}`});return}try{for await(let{name:f,data:g}of xn(l.body)){if(o.signal.aborted)return;En(d,{name:f,data:g},r),Tn(f,g,t??{})}}catch(f){if(o.signal.aborted)return;t?.onError?.({code:"provider_error",message:f instanceof Error?f.message:String(f)})}})();return{abort:()=>o.abort(),done:a,traceId:u,events:d}}function Tn(e,n,t){switch(e){case"wf:token":return t.onToken?.(n.text);case"wf:tool_call":return t.onToolCall?.(n);case"wf:tool_result":return t.onToolResult?.(n);case"wf:tool_progress":return t.onToolProgress?.(n);case"wf:step":return t.onStep?.(n);case"wf:approval_request":return t.onApproval?.(n);case"wf:usage":return t.onUsage?.(n);case"wf:done":return t.onDone?.(n);case"wf:error":return t.onError?.(n);default:return t.onEvent?.(e,n)}}async function*xn(e){let n=e.getReader(),t=new TextDecoder,o="";try{for(;;){let{done:i,value:u}=await n.read();if(i)break;o+=t.decode(u,{stream:!0});let r=o.split(`
1
+ function Pn(e){let n=[],t=(e||"/").replace(/:(\w+)/g,(o,r)=>(n.push(r),"([^/]+)")).replace(/\*/g,".*");return{re:new RegExp(`^${t}$`),keys:n}}var _e=class{_routes=[];_middlewares=[];_injections=[];_injected=!1;_mode;_notFound;constructor(n={}){this._mode=n.mode??"history"}get mode(){return this._mode}use(n,t){if(typeof n=="string"&&t){let o=this,r=n,d=async(s,u,a)=>{let l=u.__routePath??o.getPath(),c=null;return l===r?c="/":(r==="/"?l!=="/"&&l.startsWith("/"):l.startsWith(r+"/"))&&(c=l.slice(r.length)),c===null?a:async(y,v)=>t._handle(c,y,v)};return this._middlewares.push(d),this}return n.length<=1?(this._injections.push(n),this):(this._middlewares.push(n),this)}async _ensureInjected(n){if(!this._injected){this._injected=!0;for(let t of this._injections){let o=await t(n);o&&o!==n&&Object.assign(n,o)}}}get(n,t,o){return this._routes.push({path:n,handler:t,title:o?.title}),this}notFound(n){return this._notFound=n,this}getPath(){return this._getPath(void 0)}_getPath(n){let t=n?.location??(typeof window<"u"?window.location:null);return this._mode==="hash"?(t?.hash??"").replace(/^#/,"")||"/":t?.pathname??"/"}match(n){let t=null;for(let o of this._routes){let{re:r,keys:d}=Pn(o.path),s=n.match(r);if(!s)continue;let u={};for(let a=0;a<d.length;a++)u[d[a]]=decodeURIComponent(s[a+1]);t={handler:o.handler,params:u,title:o.title};break}return t||(t={handler:this._notFound??(()=>null),params:{}}),t}async _handle(n,t,o){await this._ensureInjected(o);let r=this.match(n);r.title&&typeof document<"u"&&(document.title=r.title),o.params=r.params;let s=r.handler,u=o.__routePath;o.__routePath=n;try{for(let a=this._middlewares.length-1;a>=0;a--){let l=this._middlewares[a],c=s;s=await l(t,o,c)??c}return await s(t,o)}finally{o.__routePath=u}}async execute(n,t,o){await this._ensureInjected(t);let r=this.match(o);r.title&&typeof document<"u"&&(document.title=r.title),t.params=r.params;let s=r.handler;for(let u=this._middlewares.length-1;u>=0;u--){let a=this._middlewares[u],l=s;s=await a(n,t,l)??l}return await s(n,t)}};function re(){return{idCounter:0,idRegistry:new Map,unmountHooks:[],asyncFactoryCache:new WeakMap}}function W(e){return e?.__registry??re()}function fe(e){return`_wf_${e.idCounter++}`}function pe(e,n){return e.unmountHooks.push(n),()=>{let t=e.unmountHooks.indexOf(n);t>=0&&e.unmountHooks.splice(t,1)}}function Ne(e,n,t){let o=e.asyncFactoryCache.get(n);if(o)return o;let r={promise:null};return r.promise=Promise.resolve().then(()=>n(t)).then(d=>{if(typeof d!="function")throw new Error(`asyncComponent factory <${n.name||"anonymous"}> must return a Component (initProps, ctx) => (props) => VNode.`);return r.resolved=d,d}),e.asyncFactoryCache.set(n,r),r}async function $e(e,n,t){return Ne(e,n,t).promise}function Be(e,n){return e.asyncFactoryCache.get(n)?.resolved}function ke(e,n,t,o){try{e(n)}catch(r){console.error(`[weifuwu] ref ${t} error in <${o??"anonymous"}>`,r)}}function _n(e,n){let t=e._child;if(t!=null)if(Array.isArray(t))for(let o of t)o&&typeof o=="object"&&O(o,n);else typeof t=="object"&&O(t,n)}function O(e,n){if(e==null||typeof e!="object")return;let t=e;if(t._id){if(t._customId&&n.idRegistry.delete(t._customId),n.idRegistry.delete(t._id),n.unmountHooks.length>0){let o=[...n.unmountHooks];for(let r of o)r(t._id);if(t._customId)for(let r of o)r(t._customId)}t._id=void 0,t._customId=void 0,t._render=void 0,t._parentNode=void 0,t._refNode=void 0}if(t._child!=null){if(Array.isArray(t._child))for(let o of t._child)o&&typeof o=="object"&&O(o,n);else O(t._child,n);t._child=void 0}if(t.props?.children&&typeof t.type=="string"){let o=Array.isArray(t.props.children)?t.props.children:[t.props.children];for(let r of o)r&&typeof r=="object"&&O(r,n)}typeof t.props?.ref=="function"&&ke(t.props.ref,null,"cleanup"),t._remoteEl&&(_n(t,n),t._remoteEl.remove(),t._remoteEl=void 0)}function U(){return{activeElement:()=>typeof document<"u"?document.activeElement:null,byId:e=>typeof document<"u"?document.getElementById(e):null,query:e=>typeof document<"u"?document.querySelector(e):null,queryAll:e=>typeof document<"u"?document.querySelectorAll(e):null,createElement:e=>typeof document<"u"?document.createElement(e):null,createElementNS:(e,n)=>typeof document<"u"?document.createElementNS(e,n):null,createDocumentFragment:()=>typeof document<"u"?document.createDocumentFragment():null,createComment:e=>typeof document<"u"?document.createComment(e):null,createTextNode:e=>typeof document<"u"?document.createTextNode(e):null,addEventListener:(e,n,t)=>{typeof window<"u"&&window.addEventListener(e,n,t)},removeEventListener:(e,n,t)=>{typeof window<"u"&&window.removeEventListener(e,n,t)},scrollTo:e=>{typeof window<"u"&&window.scrollTo(0,e)},matchMedia:e=>typeof window<"u"&&typeof window.matchMedia=="function"?window.matchMedia(e):null,visualViewport:()=>(typeof window<"u"?window:null)?.visualViewport??null,scrollingElement:()=>typeof document<"u"?document.scrollingElement:null,bodyElement:()=>typeof document<"u"?document.body:null,bodyAppend:e=>{typeof document<"u"&&document.body.appendChild(e)},bodyRemove:e=>{typeof document<"u"&&e.parentNode&&document.body.removeChild(e)},clearBody:()=>{typeof document<"u"&&(document.body.innerHTML="")},event:(e,n)=>{let t=typeof window<"u"?window:null,o=n&&(n.key||n.code)?"KeyboardEvent":n&&(n.clientX!==void 0||n.clientY!==void 0||n.pointerId!==void 0)?"PointerEvent":"Event";try{return new t[o](e,n)}catch{return new t.Event(e,n)}},dispatchEvent:(e,n)=>typeof e<"u"?e.dispatchEvent(n):!1,navigate:e=>{typeof window>"u"||(window.history.pushState(null,"",e),window.dispatchEvent(new PopStateEvent("popstate",{state:null})))},copyText:async e=>{let n=typeof window<"u"?window:null;if(n?.navigator?.clipboard?.writeText)try{return await n.navigator.clipboard.writeText(e),!0}catch{}try{if(typeof document>"u")return!1;let t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select();let o=document.execCommand("copy");return document.body.removeChild(t),o}catch{return!1}},execCommand:(e,n)=>typeof document<"u"?document.execCommand(e,!1,n):!1,queryCommandState:e=>typeof document<"u"?document.queryCommandState(e):!1,queryCommandValue:e=>typeof document<"u"?document.queryCommandValue(e):"",selectionText:()=>typeof window<"u"?window.getSelection?.()?.toString()??null:null,getSelection:()=>typeof window<"u"?window.getSelection():null,viewportHeight:()=>typeof window<"u"?window.innerHeight:0,viewportWidth:()=>typeof window<"u"?window.innerWidth:0,pathname:()=>typeof window<"u"?window.location.pathname:"",createTreeWalker:(e,n)=>typeof document<"u"?document.createTreeWalker(e,n??NodeFilter.SHOW_ALL):null,scrollTop:()=>{let e=typeof document<"u"?document:null,n=typeof window<"u"?window:null;return e?.scrollingElement?.scrollTop??n?.scrollY??0},hash:()=>typeof window<"u"?window.location?.hash??"":"",setHash:e=>{typeof window<"u"&&(window.location.hash=e)},timeout:(e,n)=>typeof window<"u"?window.setTimeout(e,n):0,rootElement:()=>typeof document<"u"?document.documentElement:null,storageGet:e=>{try{return typeof window<"u"?window.localStorage?.getItem(e)??null:null}catch{return null}},storageSet:(e,n)=>{try{typeof window<"u"&&window.localStorage?.setItem(e,n)}catch{}}}}var Ke=U();function Ge(e,n="bottom",t=6,o=!0){switch(n){case"bottom":return{top:e.bottom+t,left:o?e.left+e.width/2:e.left};case"top":return{top:e.top-t,left:o?e.left+e.width/2:e.left};case"left":return{top:o?e.top+e.height/2:e.top,left:e.left-t};case"right":return{top:o?e.top+e.height/2:e.top,left:e.right+t}}}function me(e,n,t=8){if(!n)return e;let o=n.getBoundingClientRect();if(o.width===0&&o.height===0)return e;let r=Number.parseFloat(n.style.top)||o.top,d=Number.parseFloat(n.style.left)||o.left,s=e.top-r,u=e.left-d,a={top:o.top+s,bottom:o.bottom+s,left:o.left+u,right:o.right+u},l=Ke.viewportWidth(),c=Ke.viewportHeight(),y=e.top,v=e.left;return a.bottom>c-t&&(y=Math.max(t,y-(a.bottom-(c-t)))),a.top<t&&(y=Math.max(t,y+(t-a.top))),a.right>l-t&&(v=Math.max(t,v-(a.right-(l-t)))),a.left<t&&(v=Math.max(t,v+(t-a.left))),{top:y,left:v,width:e.width}}var ee=U();function Ye(e){let n=new Map,t=new Map,o=!1,r=0;function d(){r||(r=requestAnimationFrame(()=>{r=0;let c=[];for(let[y,v]of n){if(!v.isOpen())continue;let T=v.getEl();if(!T)continue;let h=T.getBoundingClientRect();if(h.width===0&&h.height===0)continue;let p=v.compute(h);Object.assign(v.pos,me(p,v.panel?.(),v.margin)),c.push(y)}for(let[y,v]of t){let T=v.getScroller(),h=T instanceof Window?ee.scrollingElement()?.scrollTop??ee.scrollTop():T.scrollTop??0;h!==v.handle.y&&(v.handle.y=h,c.push(y))}c.length>0&&e(c)}))}function s(){o||(o=!0,ee.addEventListener("scroll",d,{capture:!0,passive:!0}),ee.addEventListener("resize",d))}function u(){o&&(ee.removeEventListener("scroll",d,{capture:!0}),ee.removeEventListener("resize",d),o=!1)}function a(c){for(let y of[...n.keys()])(y.startsWith(`popup:${c}:`)||y===`popup:${c}`)&&n.delete(y);t.delete(c)}function l(){u(),r&&(cancelAnimationFrame(r),r=0),n.clear(),t.clear()}return{popupTrackers:n,scrollTrackers:t,schedulePopupRecompute:d,ensurePopupListeners:s,destroyPopupListeners:u,cleanupTrackers:a,destroy:l}}var ye=U(),se=0,ze="",Xe="",Je="",Qe="",ge=0;function Ze(){return typeof window<"u"&&typeof document<"u"}function en(){if(se++,se>1||!Ze())return;ge=ye.scrollTop();let e=ye.bodyElement();ze=e.style.overflow,Xe=e.style.position,Je=e.style.top,Qe=e.style.width,e.style.overflow="hidden",(/iPhone|iPad|iPod/.test(navigator.platform)||/Mac/.test(navigator.platform)&&"ontouchend"in document)&&(e.style.position="fixed",e.style.top=`-${ge}px`,e.style.width="100%")}function nn(){if(se===0||(se--,se>0)||!Ze())return;let e=ye.bodyElement();e.style.overflow=ze,e.style.position=Xe,e.style.top=Je,e.style.width=Qe,ge>0&&ye.scrollTo(ge)}var Nn='a[href], button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])',Se=U();function Re(e){let n=e.querySelectorAll(Nn);if(n.length===0)return()=>{};let t=n[0],o=n[n.length-1],r=s=>{s.key==="Tab"&&(s.shiftKey&&Se.activeElement()===t?(s.preventDefault(),o.focus()):!s.shiftKey&&Se.activeElement()===o&&(s.preventDefault(),t.focus()))},d=Se.activeElement();return queueMicrotask(()=>{t.focus()}),e.addEventListener("keydown",r),()=>{e.removeEventListener("keydown",r),d?.focus()}}function z(e){let n=new WeakMap,t=new Set,o=d=>{if(d===null||typeof d!="object")return d;if(d instanceof Set||d instanceof Map){if(n.has(d))return n.get(d);let u=d instanceof Set?new Set(["add","delete","clear"]):new Set(["set","delete","clear"]),a=new Proxy(d,{get(l,c){let y=Reflect.get(l,c);return typeof y=="function"?u.has(String(c))?(...v)=>{let T=y.apply(l,v);e();for(let h of t)h();return T}:y.bind(l):y},set(l,c,y){Reflect.set(l,c,y),e();for(let v of t)v();return!0}});return n.set(d,a),a}if(d instanceof Date||d instanceof RegExp)return d;if(n.has(d))return n.get(d);let s=new Proxy(d,{set(u,a,l){if(Reflect.get(u,a)===l)return!0;Reflect.set(u,a,l),e();for(let y of t)y();return!0},get(u,a){let l=Reflect.get(u,a);return typeof l=="object"&&l!==null?o(l):l},deleteProperty(u,a){if(Reflect.has(u,a)){Reflect.deleteProperty(u,a),e();for(let l of t)l()}return!0}});return n.set(d,s),s},r=o({});return Object.defineProperty(r,"__watch",{value:d=>(t.add(d),()=>{t.delete(d)}),writable:!1,enumerable:!1}),r}function tn(e,n,t){let o=new AbortController,r=t?.signal;r&&(r.aborted?o.abort():r.addEventListener("abort",()=>o.abort(),{once:!0}));let d=t?.traceId??An(),s=t?.record!==!1,u=[],a=(async()=>{let l;try{l=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-Trace-Id":d,Accept:"text/event-stream",...t?.headers},body:JSON.stringify(n),signal:o.signal})}catch(c){if(o.signal.aborted)return;t?.onError?.({code:"provider_error",message:c instanceof Error?c.message:String(c)});return}if(!l.ok){t?.onError?.({code:Mn(l.status),message:`HTTP ${l.status} ${l.statusText}`});return}try{for await(let{name:c,data:y}of Sn(l.body)){if(o.signal.aborted)return;Rn(u,{name:c,data:y},s),kn(c,y,t??{})}}catch(c){if(o.signal.aborted)return;t?.onError?.({code:"provider_error",message:c instanceof Error?c.message:String(c)})}})();return{abort:()=>o.abort(),done:a,traceId:d,events:u}}function kn(e,n,t){switch(e){case"wf:token":return t.onToken?.(n.text);case"wf:tool_call":return t.onToolCall?.(n);case"wf:tool_result":return t.onToolResult?.(n);case"wf:tool_progress":return t.onToolProgress?.(n);case"wf:step":return t.onStep?.(n);case"wf:approval_request":return t.onApproval?.(n);case"wf:usage":return t.onUsage?.(n);case"wf:done":return t.onDone?.(n);case"wf:error":return t.onError?.(n);default:return t.onEvent?.(e,n)}}async function*Sn(e){let n=e.getReader(),t=new TextDecoder,o="";try{for(;;){let{done:r,value:d}=await n.read();if(r)break;o+=t.decode(d,{stream:!0});let s=o.split(`
2
2
 
3
- `);o=r.pop()??"";for(let d of r){let a="message",l="";for(let f of d.split(`
4
- `))f.startsWith("event: ")?a=f.slice(7):f.startsWith("data: ")&&(l+=f.slice(6));if(l)try{yield{name:a,data:JSON.parse(l)}}catch{}}}}finally{n.releaseLock()}}function En(e,n,t){t&&(e.length>=1e3&&e.shift(),e.push(n))}function Pn(e){return e===401||e===403?"auth_failed":e===429?"rate_limited":e>=500?"provider_error":"invalid_request"}function _n(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`trace-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function kn(e){return e.map(n=>({role:n.role,content:n.content}))}function Pe(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`msg-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function Xe(e,n,t){t.initialMessages?e.messages=structuredClone(t.initialMessages):e.messages===void 0&&(e.messages=[]),e.input===void 0&&(e.input=""),e.streaming===void 0&&(e.streaming=!1),e.error===void 0&&(e.error=null),e.usage===void 0&&(e.usage=null),e.step===void 0&&(e.step=null);let o=null;function i(){if(!e.streaming)return;let T=e.messages[e.messages.length-1];return T&&T.role==="assistant"&&T.status==="streaming"?T:void 0}function u(T,m,h){let b=i();switch(T){case"wf:token":b&&(b.content+=m.text);break;case"wf:tool_call":{b&&(b.toolCalls||(b.toolCalls=[]),b.toolCalls.push({call:m,status:"running"}));break}case"wf:tool_progress":{let N=m,s=b?.toolCalls?.find(c=>c.call.id===N.toolCallId);s&&(s.progress=N);break}case"wf:tool_result":{let N=m,s=b?.toolCalls?.find(c=>c.call.id===N.id);s&&(s.result=N,s.status=N.ok?"ok":"error");break}case"wf:approval_request":b&&(b.approval=m);break;case"wf:usage":b&&(b.usage=m);break;case"wf:step":e.step=m;break;case"wf:done":b&&(b.status="done",b.approval=void 0),e.streaming=!1,e.step=null;break;case"wf:error":b&&(b.status="error",b.error=m,b.approval=void 0),e.error=m,e.streaming=!1,e.step=null;break;default:h?.(T,m);break}}function r(){let T=t.body?t.body(e.messages):{messages:kn(e.messages)};o=n(t.url,T,{onToken:h=>u("wf:token",{text:h}),onToolCall:h=>u("wf:tool_call",h),onToolProgress:h=>u("wf:tool_progress",h),onToolResult:h=>u("wf:tool_result",h),onApproval:h=>u("wf:approval_request",h),onUsage:h=>u("wf:usage",h),onStep:h=>u("wf:step",h),onDone:h=>u("wf:done",h),onError:h=>u("wf:error",h),onEvent:(h,b)=>u(h,b,t.onEvent)},{signal:t.signal,headers:t.headers}),e.streaming=!0;let m=i();m&&o?.traceId&&(m.id=o.traceId)}function d(){if(e.streaming)return;let T=String(e.input??"").trim();T&&(e.input="",e.error=null,e.usage=null,e.step=null,e.messages.push({id:Pe(),role:"user",content:T,status:"done"},{id:Pe(),role:"assistant",content:"",status:"streaming",toolCalls:[]}),r())}function a(){o?.abort(),e.streaming=!1,e.step=null;let T=e.messages[e.messages.length-1];T&&T.role==="assistant"&&T.status==="streaming"&&(!T.content&&(!T.toolCalls||T.toolCalls.length===0)?e.messages.pop():T.status="done")}function l(){if(e.streaming)return;let T=-1;for(let m=e.messages.length-1;m>=0;m--)if(e.messages[m].role==="user"){T=m;break}T!==-1&&(e.messages.splice(T+1),e.error=null,e.usage=null,e.step=null,e.messages.push({id:Pe(),role:"assistant",content:"",status:"streaming",toolCalls:[]}),r())}function f(){o?.abort(),e.messages=[],e.input="",e.streaming=!1,e.error=null,e.usage=null,e.step=null}async function g(T,m){let h=e.messages[e.messages.length-1],b=h?.role==="assistant"?h.approval:void 0;if(b&&(h.approval=void 0,!!t.approveUrl))try{await fetch(t.approveUrl,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify({id:b.id,decision:T,note:m}),signal:t.signal})}catch(N){if(t.signal?.aborted)return;e.error={code:"provider_error",message:N instanceof Error?N.message:String(N)}}}function w(){o?.abort(),o=null}return{send:d,stop:a,retry:l,clear:f,approve:g,dispose:w}}var Qe="__wfAsyncComponent";function Nn(e){let n=e;return n[Qe]=!0,n}function z(e){return typeof e=="function"&&e?.[Qe]===!0}var $=Symbol("Fragment"),j=Symbol("Portal");function _e(e,n,t){return{type:e,props:Ze(n),key:t??void 0}}var Rn=_e;function Sn(e,n,t){return _e(e,n,t)}function Mn(e,n,...t){let o=Ze(n??{});return t.length>0&&(o.children=t.length===1?t[0]:t),{type:e,props:o,key:n?.key??void 0}}function Ze(e){if(!e)return{};let n={};for(let t of Object.keys(e))t!=="key"&&(n[t]=e[t]);return n}function ke(e,n){return{type:j,props:{children:e,portalKey:n},key:n??void 0,_placement:"remote"}}var fe=new Set,te=new Map,pe=new Map,oe=new Map;function en(e){let{ctx:n,renderByIds:t,getSelfId:o,dirtyBatch:i,dirtySet:u,mediaRegistry:r,popupTrackers:d,scrollTrackers:a,schedulePopupRecompute:l,ensurePopupListeners:f,isRendering:g,isMounting:w,setMounting:T,endMounting:m}=e,h=e.registry??O(n),b=s=>ue(h,s);return{_selfId:"_wf_root",_ctxVersion:0,_dirtySet:u,setMounting:T,endMounting:m,bumpCtxVersion:function(){this._ctxVersion++},render:function(s){if(g()){if(w())return;this._pendingRender||(this._pendingRender=!0,queueMicrotask(()=>{this._pendingRender=!1,this.render(s)}));return}if(!s||s.length===0){let c=o(this);if(c)s=[c];else return}t(s)},dirty:function(s){if(!w()){if(g()){this._pendingDirty||(this._pendingDirty=!0,queueMicrotask(()=>{this._pendingDirty=!1,this.dirty(s)}));return}if(!s||s.length===0){let c=o(this);if(c)s=[c];else return}for(let c of s)c&&(i.add(c),u.add(c));this._dirtyScheduled||(this._dirtyScheduled=!0,queueMicrotask(()=>{this._dirtyScheduled=!1;let c=[...i];i.clear(),c.length>0&&t(c)}))}},$:function(){let s=this;if(!Object.prototype.hasOwnProperty.call(s,"_$cache")){let c=G(()=>{let p=s._selfVNode?._id??o(s);p&&n.ui.dirty([p])});s._$cache=c}return s._$cache},useChat:function(s){let c=this.$(),p=Xe(c,Je,s);Object.assign(c,{send:p.send,stop:p.stop,retry:p.retry,clear:p.clear,approve:p.approve,dispose:p.dispose});let y=o(this);if(y){let v=b(C=>{C===y&&(p.dispose(),v())})}return c},useMedia:function(s,c){let y=`media:${o(this)}:${s}`;if(!r.has(y)){let v=window.matchMedia(s);c(v.matches);let C=P=>c(P.matches);v.addEventListener("change",C),r.set(y,{mql:v,handler:C})}},useBreakpoint:function(s,c){let p=typeof s=="function"?{mobile:"(max-width: 639px)",tablet:"(min-width: 640px) and (max-width: 1023px)",desktop:"(min-width: 1024px)"}:s,y=typeof s=="function"?s:c,C=`bp:${o(this)}`;function P(){for(let[x,M]of Object.entries(p))if(window.matchMedia(M).matches)return x;return Object.keys(p)[0]??""}if(!r.has(C)){y(P());let x=[];for(let M of Object.values(p)){let V=window.matchMedia(M),L=()=>y(P());V.addEventListener("change",L),x.push({mql:V,handler:L})}r.set(C,{mqls:x})}},usePopupPosition:function(s){let c=o(this),p={top:0,left:0,refresh:()=>{}};if(!c)return p;let y={pos:p,getEl:s.el,isOpen:s.isOpen,compute:s.compute,panel:s.panel,margin:s.margin??8};return d.set(c,y),f(),p.refresh=()=>{let v=y.getEl();if(!v)return;let C=v.getBoundingClientRect();if(C.width===0&&C.height===0)return;let P=y.compute(C);Object.assign(p,de(P,y.panel?.(),y.margin))},p},useHoverCapable:function(){return typeof window<"u"&&!!window.matchMedia?.("(hover: hover)").matches},useStableRef:function(s,c){return y=>{y?s(y):c?.()}},useVisualViewport:function(){let s=o(this),c={height:window.innerHeight,offsetTop:0,keyboardOpen:!1},p=()=>{n.ui&&n.ui.dirty(s?[s]:void 0)},y=()=>{let C=window.visualViewport;c.height=C?.height??window.innerHeight,c.offsetTop=C?.offsetTop??0,c.keyboardOpen=c.height<window.innerHeight*.9,p()},v=window.visualViewport;if(v?.addEventListener?(v.addEventListener("resize",y),v.addEventListener("scroll",y)):window.addEventListener("resize",y),s){let C=b(P=>{P===s&&(v?.removeEventListener?(v.removeEventListener("resize",y),v.removeEventListener("scroll",y)):window.removeEventListener("resize",y),C())})}return c},usePopup:function(s){let c=o(this),p=this.useHoverCapable(),y=()=>typeof s.trigger=="function"?s.trigger():s.trigger,v=s.open!==void 0,C=()=>!!s.disabled?.(),P=()=>v?typeof s.open=="function"?!!s.open():!!s.open:s.isOpen(),x=_=>{C()||(v?s.onOpenChange?.(_):s.setOpen(_))},M=()=>{let _=s.placement;return typeof _=="function"?_():_??"bottom"},V=null,L=!1,E=n.ui.usePopupPosition({el:s.el,isOpen:()=>P(),compute:_=>{if(s.position){let A=s.position();return{top:A.y,left:A.x}}return je(_,M(),s.gap??6,s.center!==!1)},panel:()=>V,margin:s.margin??8}),S=_=>{if(s.closeOnOutside===!1||!P())return;let A=_.target;if(!(A instanceof Node))return;let q=s.el();q&&q.contains(A)||V&&V.contains(A)||x(!1)},k=_=>{s.closeOnEscape!==!1&&(_.key!=="Escape"||!P()||x(!1))};if(document.addEventListener("mousedown",S),document.addEventListener("keydown",k),c){let _=b(A=>{A===c&&(document.removeEventListener("mousedown",S),document.removeEventListener("keydown",k),_())})}let R={},I=_=>typeof _=="function"?_():_??0,H=()=>I(s.openDelay),He=()=>I(s.closeDelay),F,K,cn=()=>{clearTimeout(F),clearTimeout(K),F=void 0,K=void 0},fn=_=>{if(C())return;let A=_.currentTarget,q=_.relatedTarget;A.contains(q)||(clearTimeout(K),K=void 0,F=setTimeout(()=>{F=void 0,x(!0)},H()))},pn=_=>{if(C())return;let A=_.currentTarget,q=_.relatedTarget;A.contains(q)||(clearTimeout(F),F=void 0,K=setTimeout(()=>{K=void 0,x(!1)},He()))},mn=()=>{C()||(clearTimeout(K),K=void 0,F=setTimeout(()=>{F=void 0,x(!0)},H()))},yn=()=>{C()||(clearTimeout(F),F=void 0,K=setTimeout(()=>{K=void 0,x(!1)},He()))},Z=()=>y()==="hover";if(R.onMouseOver=_=>{Z()&&fn(_)},R.onMouseOut=_=>{Z()&&pn(_)},R.onClick=()=>{Z()?p||x(!P()):y()==="click"&&x(!0)},R.onFocus=()=>{Z()&&mn()},R.onBlur=()=>{Z()&&yn()},y()==="longpress"){let _,A=0,q=0,B=()=>{clearTimeout(_),_=void 0};R.onPointerDown=W=>{C()||(A=W.clientX??0,q=W.clientY??0,B(),_=setTimeout(()=>{_=void 0,s.onTrigger?.({clientX:A,clientY:q}),x(!0)},s.longPressDuration??500))},R.onPointerUp=B,R.onPointerLeave=B,R.onPointerMove=W=>{let we=Math.abs((W.clientX??0)-A),be=Math.abs((W.clientY??0)-q);(we>10||be>10)&&B()},R.onContextMenu=W=>{W.preventDefault(),s.onTrigger?.({clientX:W.clientX??0,clientY:W.clientY??0}),x(!0)}}if(R.onKeyDown=_=>{_.key==="Escape"&&s.closeOnEscape!==!1&&x(!1)},c){let _=b(A=>{A===c&&(cn(),_())})}let gn=_=>{if(_){V=_;let A=()=>E.refresh();_.addEventListener("animationend",A,{once:!0})}else V=null},he=null,ve=null,hn=_=>{gn(_),ve&&ve(_)};return{get open(){return P()},setOpen:x,wrapProps:R,portal:(_,A="popover")=>{if(C())return null;if(!P())return L=!1,he=null,null;let B=s.el();(!L||B!==he)&&(B?E.refresh():queueMicrotask(()=>{P()&&E.refresh()}),L=!0,he=B);let W=_.props??{};ve=W.ref??null;let we=["wf-popup",W.class].filter(Boolean).join(" "),be={...W.style??{},position:"fixed",top:`${E.top}px`,left:`${E.left}px`,maxWidth:s.width!==void 0?`min(${s.width}px, calc(100vw - 32px))`:"calc(100vw - 32px)"},vn={..._,props:{...W,class:we,style:be,ref:hn}};return ke(vn,A)},refresh:()=>E.refresh()}},useLongPress:function(s){let{onLongPress:c,duration:p=500}=s,y,v=0,C=0,P=null,x=()=>{clearTimeout(y),y=void 0};return{onPointerDown:M=>{v=M.clientX??0,C=M.clientY??0,P=M,x(),y=setTimeout(()=>{y=void 0,P&&c(P)},p)},onPointerUp:x,onPointerLeave:x,onPointerMove:M=>{let V=Math.abs((M.clientX??0)-v),L=Math.abs((M.clientY??0)-C);(V>10||L>10)&&x()},onContextMenu:M=>{M.preventDefault(),c(M)}}},useInView:function(s){let c=o(this),p={isIn:!1,ready:!1,observe:x,refresh:M,disconnect:V},y=null,v=null,C=()=>{n.ui&&n.ui.dirty(c?[c]:void 0)};function P(){if(v?.disconnect(),v=null,!y)return;let L=typeof s.rootMargin=="function"?s.rootMargin():s.rootMargin,E=typeof s.threshold=="function"?s.threshold():s.threshold;v=new IntersectionObserver(S=>{let k=S[S.length-1];if(!k)return;let R=k.isIntersecting,I=R!==p.isIn,H=!p.ready;p.isIn=R,p.ready=!0,s.onChange?.(k,R),(I||H)&&C()},{root:s.root?s.root():null,rootMargin:L??"0px",threshold:E??0}),v.observe(y)}function x(L){y=L,L?P():(v?.disconnect(),v=null,p.isIn=!1)}function M(){P()}function V(){v?.disconnect(),v=null}return p},useScrollPosition:function(s){let c=o(this),p={y:0,refresh(){let v=y.getScroller();p.y=v instanceof Window?document.scrollingElement?.scrollTop??v.scrollY??0:v.scrollTop??0}},y={handle:p,getScroller:s.getScroller??(()=>window)};return c?(a.set(c,y),f(),p.refresh(),p):(p.refresh(),p)},useAsync:function(s){let c=o(this),p=G(()=>{n.ui&&n.ui.dirty(c?[c]:void 0)});p.loading=!0;let y=0,v=()=>{let C=++y;p.loading=!0,p.error=null,Promise.resolve().then(()=>s()).then(P=>{y===C&&(p.data=P,p.loading=!1)}).catch(P=>{y===C&&(p.error=P,p.loading=!1)})};return v(),p.reload=v,p},useControlled:function(s){let c=o(this),p=s.value!==void 0;if(p&&!s.onChange&&s.name&&(fe.has(s.name)||(fe.add(s.name),console.warn(`[weifuwu/${s.name}] \u53D7\u63A7\u6A21\u5F0F\uFF08value \u5DF2\u4F20\uFF09\u4F46\u672A\u63D0\u4F9B onChange\uFF0C\u4EA4\u4E92\u65E0\u6CD5\u751F\u6548\u3002
5
- \u975E\u53D7\u63A7\uFF1A\u53BB\u6389 value\uFF1B\u53D7\u63A7\uFF1A\u4F20\u5165 onChange={(v) => setValue(v)}`))),!p&&c&&!te.has(c)){te.set(c,s.value);let v=b(C=>{C===c&&(te.delete(c),v())})}let y=v=>{if(p){s.onChange?.(v);return}c&&te.set(c,v),n.ui&&(c?n.ui.dirty([c]):n.ui.render())};return{value:p?s.value:c?te.get(c):s.value,setValue:y,controlled:p}},useControlledInput:function(s){let c=o(this),p=this.useControlled({value:s.value,onChange:s.onChange,name:s.name});if(c&&!pe.has(c)){pe.set(c,{keyword:"",selectedLabel:""});let C=b(P=>{P===c&&(pe.delete(c),C())})}let y=c?pe.get(c):{keyword:"",selectedLabel:""},v=()=>{c?n.ui?.dirty([c]):n.ui?.render()};return{...p,get keyword(){return y.keyword},setKeyword(C){y.keyword=C,v()},get selectedLabel(){return y.selectedLabel},setSelectedLabel(C){y.selectedLabel=C,v()}}},useOpen:function(s){let c=o(this);if(c&&!oe.has(c)){oe.set(c,!1);let P=b(x=>{x===c&&(oe.delete(c),P())})}let p=s.open!==void 0;p&&!s.onOpenChange&&s.name&&!fe.has(s.name)&&(fe.add(s.name),console.warn(`[weifuwu/${s.name}] \u53D7\u63A7\u6A21\u5F0F\uFF08open \u5DF2\u4F20\uFF09\u4F46\u672A\u63D0\u4F9B onOpenChange\uFF0C\u4EA4\u4E92\u65E0\u6CD5\u751F\u6548\u3002
6
- \u975E\u53D7\u63A7\uFF1A\u53BB\u6389 open\uFF1B\u53D7\u63A7\uFF1A\u4F20\u5165 onOpenChange={(o) => setOpen(o)}`));let y=()=>p?!!s.open:c?oe.get(c)??!1:!1,v=()=>{c?n.ui?.dirty([c]):n.ui?.render()},C=P=>{if(p){s.onOpenChange?.(P);return}c&&oe.set(c,P),v()};return{get open(){return y()},setOpen:C,triggerProps:{onClick:()=>C(!0),onFocus:()=>{s.openOnFocus&&C(!0)}}}},usePresence:function(s){let c=o(this),p="closed",y,v=()=>{p="closed",n.ui&&(c?n.ui.dirty([c]):n.ui.render())};return{get phase(){return p},ref:P=>{P?y||(y=()=>{p==="exit"&&v()},P.addEventListener("animationend",y)):y=void 0},sync:P=>(P?p="open":p==="open"&&(p="exit"),p)}},useDialog:function(s){let c=o(this),p,y=null,v=this.usePresence(s);return{get phase(){return v.phase},rootRef:x=>{x?(Ye(),y&&(p=Ee(y)),v.ref(x)):(ze(),p?.(),v.ref(null))},panelRef:x=>{y=x,x&&!p&&(p=Ee(x))},sync:x=>v.sync(x)}},useGlobalKey:function(s){let c=o(this);if(typeof window>"u")return()=>{};if(window.addEventListener("keydown",s),c){let p=b(y=>{y===c&&(window.removeEventListener("keydown",s),p())})}return()=>window.removeEventListener("keydown",s)},useDrag:function(s){let c=0,p=0,y=!1,v=x=>{y&&s.onMove(x,{x:x.clientX-c,y:x.clientY-p})},C=x=>{y&&(y=!1,window.removeEventListener("pointermove",v),window.removeEventListener("pointerup",C),s.onEnd?.(x))};return{onPointerDown:x=>{y||(x.preventDefault(),y=!0,c=x.clientX,p=x.clientY,window.addEventListener("pointermove",v),window.addEventListener("pointerup",C),s.onStart?.(x))}}},useDragDrop:function(s){let c={};s.onDrop&&(c.onDrop=y=>{y.preventDefault(),s.onDrop(y)}),s.onDragOver&&(c.onDragOver=y=>{y.preventDefault(),s.onDragOver(y)}),s.onDragLeave&&(c.onDragLeave=y=>s.onDragLeave(y));let p={draggable:!0};if(s.onDragStart){let y=s.onDragStart;p.onDragStart=v=>{typeof document<"u"&&document.body.classList.add("wf-dragging"),y(v)}}if(s.onDragEnd){let y=s.onDragEnd;p.onDragEnd=v=>{typeof document<"u"&&document.body.classList.remove("wf-dragging"),y(v)}}return{dropProps:c,dragProps:p}},useReducedMotion:function(){return typeof window<"u"&&!!window.matchMedia?.("(prefers-reduced-motion: reduce)").matches},useAnimationEnd:function(s,c){let p=null,y=()=>{s(),c?.once&&p&&p.removeEventListener("animationend",y)};return C=>{C?(p=C,C.addEventListener("animationend",y)):p&&(p.removeEventListener("animationend",y),p=null)}},useTween:function(s,c){let p=o(this),y=this.useReducedMotion(),v=c?.duration??400,C=c?.ease==="linear"?E=>E:E=>1-Math.pow(1-E,3),P,x=s,M={value:y?s:0,reset:()=>{}},V=()=>{n.ui&&(p?n.ui.dirty([p]):n.ui.render())},L=E=>{if(x=E,y){M.value=E,V();return}if(E===M.value)return;P&&cancelAnimationFrame(P);let S=M.value,k=performance.now(),R=I=>{let H=Math.min(1,(I-k)/v);M.value=Math.round(S+(E-S)*C(H)),H<1?(P=requestAnimationFrame(R),V()):(P=void 0,V())};P=requestAnimationFrame(R)};return M.reset=E=>{E===x&&P||L(E)},queueMicrotask(()=>L(s)),M},selfId:function(s){if(typeof s!="string"||!s)throw new Error(`[weifuwu] selfId requires a non-empty string, got ${typeof s}`);if(h.idRegistry.has(s))throw new Error(`[weifuwu] Duplicate component ID: "${s}". Each component must have a unique custom ID.`);let c=this._selfVNode;c&&(c._customId=s,h.idRegistry.set(s,c))}}}var nn=new WeakMap;function An(e){let n=nn.get(e)??{count:0,warned:!1};n.count++,n.count>=3&&!n.warned&&(n.warned=!0,console.warn("[weifuwu] ref \u51FD\u6570\u6BCF\u6B21\u6E32\u67D3\u90FD\u53D8\u5316\uFF08\u5185\u8054 ref\uFF09\u2014\u2014ref \u56DE\u8C03\u5728\u6BCF\u6B21\u6E32\u67D3\u540E\u91CD\u65B0\u6267\u884C\uFF08\u6027\u80FD\u635F\u8017\uFF09\u3002\u628A ref \u5B9A\u4E49\u5230 mount \u4F5C\u7528\u57DF\uFF08\u7A33\u5B9A\u5F15\u7528\uFF09\uFF1Aconst listRef = (el) => {...}; return h('div', { ref: listRef })")),nn.set(e,n)}function Y(e,n,t,o,i){if(t==null){if(o==null)return null;let l=D(o,i);return l==null?null:(n&&n.parentNode?n.parentNode.insertBefore(l,n):e.appendChild(l),l)}if(o==null)return n?(U(t,O(i)),n.remove()):U(t,O(i)),null;let u=on(t),r=on(o);if(u!==r){U(t,O(i));let l=D(o,i);return l==null?null:(n?.parentNode&&n.parentNode.replaceChild(l,n),l)}if(r==="text")return n&&n.textContent!==String(o)&&(n.textContent=String(o)),n;let d=o,a=t;if(typeof d.type=="function"){let l=d.type;a._render&&a.type===d.type&&(d._render=a._render,d._id=a._id,d._id&&O(i).idRegistry.set(d._id,d)),d._parentNode=e,d._refNode=n;let f=Object.create(i);f.ui=Object.create(i.ui);let g=f.ui;if(g._selfId=d._id,g._selfVNode=d,d._ctxVersion=a._ctxVersion??g._ctxVersion??0,a._render&&a.type===d.type&&Ln(a.props,d.props)&&!g._dirtySet?.has(a._id)&&d._ctxVersion===g._ctxVersion)return d._child=a._child,n;g._dirtySet?.delete(a._id);let w;try{typeof d._render=="function"?w=d._render(d.props):w=Se(l,d.props,d,f)}catch(h){let b=i.ui?._errorHandler;b?(b(h),w=null):(console.error(`[weifuwu] Component render error in <${l?.name||"anonymous"}> (id: ${a._id??"?"}, phase: update)`,h),w=null)}let T=a._child;d._child=w;let m=Y(e,n,T,w,f);return m||(d._refNode=null),m}if(d.type===$){let l=a._childNodes,f=sn(e,a,d,i,l);return d._childNodes=f,n}if(typeof d.type=="string"){if(n&&n.nodeType===1){let l=a.props?.ref,f=d.props?.ref;l!==f&&(typeof f=="function"&&f(n),typeof l=="function"&&typeof f=="function"&&An(n)),Re(n,a.props,d.props),sn(n,a,d,i)}else if(n){U(t,O(i));let l=D(o,i);return l==null?null:(n.parentNode?.replaceChild(l,n),l)}return n}if(d.type===j)return se(a,d,i),null;if(Array.isArray(o)){let l=Array.isArray(t)?t:[];me(l,o);let f=Array.from(e.childNodes),g=n?f.indexOf(n):-1,w=g>=0?re(f.slice(g),l):re(f,l);return ye(e,l,o,i,w,n),n}return n}var tn=new Map;function In(e){let n=tn.get(e);return n||(n=`fn:${e.name||"anon"}`,tn.set(e,n)),n}function on(e){if(e==null||typeof e=="boolean")return"null";if(typeof e=="string"||typeof e=="number")return"text";if(Array.isArray(e))return"array";let n=e;return typeof n.type=="function"?In(n.type):n.type===$?"fragment":n.type===j?"portal":typeof n.type=="string"?"tag:"+n.type:"unknown"}function Re(e,n,t){let o=n?Object.keys(n).filter(r=>r!=="children"&&r!=="key"&&r!=="innerHTML"):[],i=t?Object.keys(t).filter(r=>r!=="children"&&r!=="key"&&r!=="innerHTML"):[],u=new Set(i);for(let r of o){if(!n)break;if(!u.has(r)){if(r==="ref")continue;r.startsWith("on")&&typeof n[r]=="function"?e.removeEventListener(r.slice(2).toLowerCase(),n[r]):r==="value"&&(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)?e.value="":e.removeAttribute(r==="className"?"class":r)}}for(let r of i){if(r==="ref")continue;let d=n?.[r],a=t?.[r];if(r==="innerHTML")a!==d&&(e.innerHTML=String(a??""));else if(a!==d)if(r==="class"||r==="className")e instanceof SVGElement?e.setAttribute("class",rn(a)):e.className=rn(a);else if(r==="style"&&typeof a=="object"&&a!==null){let l=e.style,f=a;for(let g of Object.keys(f)){let w=f[g];w==null?g.startsWith("--")?l.removeProperty(g):l[g]="":g.startsWith("--")?l.setProperty(g,String(w)):l[g]=typeof w=="number"?w+"px":String(w)}}else if(r.startsWith("on")&&typeof a=="function"){let l=r.slice(2).toLowerCase();typeof d=="function"&&e.removeEventListener(l,d),e.addEventListener(l,a)}else r==="draggable"?e.setAttribute("draggable",a?"true":"false"):r==="value"&&(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)?e.value=String(a??""):a===!0?e.setAttribute(r,""):a!=null&&a!==!1?e.setAttribute(r,String(a)):r==="value"&&(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)?e.value="":e.removeAttribute(r)}}function rn(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(Boolean).join(" "):e&&typeof e=="object"?Object.entries(e).filter(([,n])=>n).map(([n])=>n).join(" "):""}function Ne(e){if(!(e==null||typeof e!="object"))return Array.isArray(e)?void 0:e.key}function me(e,n){if(!n.some(o=>o&&typeof o=="object"&&!Array.isArray(o)&&o.key!==void 0)){for(let o=0;o<n.length;o++){let i=n[o];i&&typeof i=="object"&&!Array.isArray(i)&&(i.key=String(o))}for(let o=0;o<e.length;o++){let i=e[o];i&&typeof i=="object"&&!Array.isArray(i)&&(i.key=String(o))}}}function re(e,n){let t=[],o=0;for(let i of n){if(i==null||typeof i=="boolean"){t.push(null);continue}let u=i;if(u.type===j){t.push(null);continue}if(u.type===$){let r=u._childNodes;Array.isArray(r)&&r.length>0?(t.push(r.slice()),o+=r.length):(t.push(e[o]?[e[o]]:null),o+=1)}else if(typeof u.type=="function")if(u._render){let r=u._childNodes??u._refNode;r==null?t.push(null):Array.isArray(r)?(t.push(r.slice()),o+=r.length):(t.push([r]),o+=1)}else t.push(e[o]?[e[o]]:null),o+=1;else typeof process<"u"&&process.env.DBG&&console.error("[map] idx=",o,"type=",u.type,"sourceLen=",e.length,"hit=",!!e[o]),t.push(e[o]?[e[o]]:null),o+=1}return t}function sn(e,n,t,o,i){let u=ie(n.props?.children),r=ie(t.props?.children);me(u,r);let d=i??Array.from(e.childNodes),a=re(d,u),l=ye(e,u,r,o,a,i?.[0]??null),f=[];for(let g of l)g&&g.length>0&&f.push(...g);return f}function ie(e){if(e==null)return[];if(!Array.isArray(e))return[e];let n=[];for(let t of e)Array.isArray(t)?n.push(...t):n.push(t);return n}function ln(e){return e==null?[]:e instanceof DocumentFragment?Array.from(e.childNodes):[e]}function ye(e,n,t,o,i=[],u=null){if(!t.some(m=>m&&typeof m=="object"&&!Array.isArray(m)&&m.key!==void 0&&m._placement!=="remote")){let m=Math.max(n.length,t.length);for(let h=0;h<m;h++){let b=h<n.length?n[h]:null,N=h<t.length?t[h]:null;if(N==null){if(b!=null){U(b,O(o));for(let s of i[h]??[])s.remove()}}else if(b==null){let s=D(N,o);if(s!=null){let c=null;for(let p=h+1;p<i.length;p++){let y=i[p]?.[0];if(y&&y.parentNode===e){c=y;break}}c?e.insertBefore(s,c):e.appendChild(s)}}else{let s=i[h]?.[0]??null;Y(e,s,b,N,o)}}return[]}for(let m=0;m<n.length;m++){let h=n[m];if(!(h==null||typeof h=="boolean")&&Ne(h)===void 0)for(let b of i[m]??[])b.remove()}let d=new Map,a=0;for(let m=0;m<n.length;m++){let h=Ne(n[m]);h!==void 0&&d.set(h,{vnode:n[m],nodes:i[m]??[],index:a++})}let l=t.map(m=>Ne(m)),f=new Set(l);for(let m of[...d.keys()])if(!f.has(m)){let h=d.get(m);U(h.vnode,O(o));for(let b of h.nodes)b?.remove();d.delete(m)}let g=new Array(t.length).fill(null),w=-1,T=u&&u.parentNode===e?u:e.firstChild;for(let m=0;m<t.length;m++){let h=l[m],b=t[m],N=h!==void 0?d.get(h):void 0,s=b&&typeof b=="object"&&b._placement==="remote";if(N)if(N.nodes.length>0){if(N.index<w)for(let p of N.nodes)e.insertBefore(p,T);w=Math.max(w,N.index),Y(e,N.nodes[0],N.vnode,b,o),g[m]=b._childNodes??N.nodes.filter(p=>p.parentNode===e),T=g[m][g[m].length-1]?.nextSibling??null}else if(s)se(N.vnode,b,o),g[m]=[];else{let c=Y(e,null,N.vnode,b,o);g[m]=ln(c);for(let y of g[m])e.insertBefore(y,T);T=g[m][g[m].length-1]?.nextSibling??null}else if(s)X(b,o),g[m]=[];else{let c=D(b,o);g[m]=ln(c);for(let y of g[m])e.insertBefore(y,T);T=g[m][g[m].length-1]?.nextSibling??null}}return g}function Vn(e,n){if(e===n)return!0;if(Array.isArray(e)&&Array.isArray(n)){if(e.length!==n.length)return!1;for(let t=0;t<e.length;t++)if(e[t]!==n[t])return!1;return!0}return e===n}function Ln(e,n){if(e===n)return!0;if(!e||!n)return!1;let t=new Set([...Object.keys(e),...Object.keys(n)]);for(let o of t)if(o!=="key"){if(o==="children"){if(!Vn(e[o],n[o]))return!1}else if(e[o]!==n[o])return!1}return!0}var Me="http://www.w3.org/2000/svg",Ae=new Set(["svg","path","circle","line","rect","text","g","polyline","polygon","ellipse","defs","use","clipPath","mask","linearGradient","radialGradient","stop","tspan"]);function D(e,n){if(e==null||typeof e=="boolean")return null;if(typeof e=="string"||typeof e=="number")return document.createTextNode(String(e));if(Array.isArray(e))return Hn(e,n);let t=e;if(t.type===j)return X(t,n),null;if(t.type===$){let r=document.createDocumentFragment(),d=t.props?.children==null?[]:Array.isArray(t.props.children)?t.props.children:[t.props.children];for(let a of d){let l=D(a,n);l!=null&&r.appendChild(l)}return t._childNodes=Array.from(r.childNodes),r}if(typeof t.type=="function")return On(t.type,t.props,t,n);let o=t.type,i=Ae.has(o)?document.createElementNS(Me,o):document.createElement(o);t.el=i;let u;for(let[r,d]of Object.entries(t.props??{}))r==="children"||r==="key"||r==="value"||r==="innerHTML"||an(i,r,d);if("value"in(t.props??{})&&i instanceof HTMLSelectElement?u=t.props.value:"value"in(t.props??{})&&an(i,"value",t.props.value),"innerHTML"in(t.props??{}))i.innerHTML=String(t.props.innerHTML??"");else{let r=Ie(t.props?.children);for(let d of r){let a=D(d,n);if(a!=null&&(i.appendChild(a),d&&typeof d=="object"&&typeof d.type=="function")){let l=d;l._parentNode||(l._parentNode=i,l._refNode=a)}}}return u!==void 0&&(i.value=String(u)),typeof t.props?.ref=="function"&&xe(t.props.ref,i,"mount",o),i}function Un(e){let n=e.ui;n&&typeof n.render=="function"&&n.render(["_wf_root"])}function Se(e,n,t,o){let i;if(z(e)){if(i=De(O(o),e),!i)return Te(O(o),e,o).promise.then(()=>Un(o),()=>{}),null}else i=e;o.ui?.setMounting?.(!0);let u;try{u=i(n,o)}finally{o.ui?.endMounting?.()}if(typeof u!="function")throw new Error(`Component ${e.name||"anonymous"} must return a render function. Use (init_props, ctx) => (props) => VNode pattern.`);return t._render=u,u(n)}function On(e,n,t,o){if(!t._id){let a=O(o);t._id=ae(a),a.idRegistry.set(t._id,t)}let i=Object.create(o);i.ui=Object.create(o.ui);let u=i.ui;u._selfId=t._id,u._selfVNode=t,t._ctxVersion=u._ctxVersion??0;let r;try{r=Se(e,n,t,i)}catch(a){let l=o.ui?._errorHandler;l?(l(a),r=null):(console.error(`[weifuwu] Component render error in <${e.name||"anonymous"}> (id: ${t._id??"?"}, phase: mount)`,a),r=null)}if(r==null){if(t._child=null,i.ui?._errorHandler){let l=document.createComment("wf-empty");return t._refNode=l,l}return null}t._child=r;let d=D(r,i);return t._refNode||(t._refNode=d),d}function Hn(e,n){let t=document.createDocumentFragment();for(let o of e){let i=D(o,n);i!=null&&t.appendChild(i)}return t}function Wn(){let e=document.getElementById("__wf_portal");return e||(e=document.createElement("div"),e.id="__wf_portal",e.style.cssText="position:fixed;inset:0;pointer-events:none;z-index:9999",document.body.appendChild(e)),e}function X(e,n){let t=Wn(),o=document.createElement("div");o.style.pointerEvents="auto",t.appendChild(o),e._remoteEl=o;let i=ie(e.props?.children);e._child=i;for(let u of i){let r=D(u,n);r!=null&&o.appendChild(r)}}function se(e,n,t){let o=e?._remoteEl;if(n._remoteEl=o,!o){X(n,t);return}let i=ie(n.props?.children),u=e._child||[];n._child=i,me(u,i);let r=re(Array.from(o.childNodes),u);ye(o,u,i,t,r,r[0]?.[0]??null)}function Ie(e){if(e==null)return[];if(!Array.isArray(e))return[e];let n=[];for(let t of e)Array.isArray(t)?n.push(...t):n.push(t);return n}function an(e,n,t){if(n!=="ref")if(n==="class"||n==="className")e instanceof SVGElement?e.setAttribute("class",String(t??"")):e.className=String(t??"");else if(n==="style"&&typeof t=="object"&&t!==null){let o=e.style;for(let i of Object.keys(t)){let u=t[i];u!=null&&(i.startsWith("--")?o.setProperty(i,String(u)):o[i]=typeof u=="number"?u+"px":String(u))}}else n.startsWith("on")&&typeof t=="function"?e.addEventListener(n.slice(2).toLowerCase(),t):n==="draggable"?e.setAttribute("draggable",t?"true":"false"):n==="value"&&(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)?e.value=String(t??""):t===!0?e.setAttribute(n,""):t!=null&&t!==!1&&e.setAttribute(n,String(t))}function Dn(e,n,t){e.innerHTML="";let o=D(n,t);o instanceof Node&&e.appendChild(o)}function jn(e){U(e,ee())}function Ve(e){e.node=e.node?e.node.nextSibling:null}function qn(e,n){e.node&&e.node.parentNode?e.node.parentNode.insertBefore(n,e.node):e.parent.appendChild(n)}function $n(e,n){e.node&&e.node.parentNode?(e.node.parentNode.replaceChild(n,e.node),Ve(e)):e.parent.appendChild(n)}async function le(e,n,t){if(e==null||typeof e=="boolean")return null;if(typeof e=="string"||typeof e=="number"){let d=String(e);if(t.node&&t.node.nodeType===3)return t.node.textContent!==d&&(t.node.textContent=d),Ve(t),t.node;let a=document.createTextNode(d);return qn(t,a),a}if(Array.isArray(e)){let d=null;for(let a of e){let l=await le(a,n,t);l!=null&&!d&&(d=l)}return d}let o=e;if(o.type===j||o.type===$){let d=o.props?.children,a=d==null?[]:Array.isArray(d)?d:[d],l=null;for(let f of a){let g=await le(f,n,t);g!=null&&!l&&(l=g)}return l}if(typeof o.type=="function")return Fn(o,n,t);let i=o.type,u=o.props??{},r;if(t.node&&t.node.nodeType===1&&t.node.tagName.toLowerCase()===i.toLowerCase()?(r=t.node,Ve(t)):(r=Ae.has(i)?document.createElementNS(Me,i):document.createElement(i),$n(t,r)),o.el=r,Re(r,null,u),!("innerHTML"in u)){let d={parent:r,node:r.firstChild},a=Ie(u.children);for(let l of a){let f=await le(l,n,d);if(f!=null&&f.parentNode!==r&&r.appendChild(f),l&&typeof l=="object"&&typeof l.type=="function"){let g=l;g._parentNode||(g._parentNode=r,g._refNode=f)}}for(;d.node;){let l=d.node;d.node=l.nextSibling,l.parentNode?.removeChild(l)}}return"value"in u&&r instanceof HTMLSelectElement&&(r.value=String(u.value??"")),typeof u.ref=="function"&&u.ref(r),r}async function Fn(e,n,t){if(!e._id){let a=O(n);e._id=ae(a),a.idRegistry.set(e._id,e)}let o=Object.create(n);o.ui=Object.create(n.ui);let i=o.ui;i._selfId=e._id,i._selfVNode=e,e._ctxVersion=i._ctxVersion??0;let u=e.type,r;try{let a;z(u)?a=await We(O(n),u,o):a=u;let l=a(e.props??{},o);if(typeof l!="function")throw new Error(`Component ${u.name||"anonymous"} must return a render function. Use (init_props, ctx) => (props) => VNode pattern.`);e._render=l,r=l(e.props??{})}catch(a){let l=n.ui?._errorHandler;l?(l(a),r=null):(console.error(`[weifuwu] Component hydration error in <${u.name||"anonymous"}> (id: ${e._id??"?"})`,a),r=null)}if(r==null)return e._child=null,null;e._child=r;let d=await le(r,o,t);return e._refNode||(e._refNode=d),d}async function Le(e,n,t){let o={parent:e,node:e.firstChild};for(await le(n,t,o);o.node;){let i=o.node;o.node=i.nextSibling,i.parentNode?.removeChild(i)}}function Ue(){return{activeElement:()=>typeof document<"u"?document.activeElement:null,byId:e=>typeof document<"u"?document.getElementById(e):null,query:e=>typeof document<"u"?document.querySelector(e):null,createElement:e=>typeof document<"u"?document.createElement(e):null,bodyAppend:e=>{typeof document<"u"&&document.body.appendChild(e)},bodyRemove:e=>{typeof document<"u"&&e.parentNode&&document.body.removeChild(e)},copyText:async e=>{let n=typeof window<"u"?window:null;if(n?.navigator?.clipboard?.writeText)try{return await n.navigator.clipboard.writeText(e),!0}catch{}try{if(typeof document>"u")return!1;let t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select();let o=document.execCommand("copy");return document.body.removeChild(t),o}catch{return!1}},execCommand:(e,n)=>typeof document<"u"?document.execCommand(e,!1,n):!1,queryCommandState:e=>typeof document<"u"?document.queryCommandState(e):!1,queryCommandValue:e=>typeof document<"u"?document.queryCommandValue(e):"",selectionText:()=>typeof window<"u"?window.getSelection?.()?.toString()??null:null,getSelection:()=>typeof window<"u"?window.getSelection():null,viewportHeight:()=>typeof window<"u"?window.innerHeight:0,scrollTop:()=>{let e=typeof document<"u"?document:null,n=typeof window<"u"?window:null;return e?.scrollingElement?.scrollTop??n?.scrollY??0},hash:()=>typeof window<"u"?window.location?.hash??"":"",setHash:e=>{typeof window<"u"&&(window.location.hash=e)},timeout:(e,n)=>typeof window<"u"?window.setTimeout(e,n):0,rootElement:()=>typeof document<"u"?document.documentElement:null,storageGet:e=>{try{return typeof window<"u"?window.localStorage?.getItem(e)??null:null}catch{return null}},storageSet:(e,n)=>{try{typeof window<"u"&&window.localStorage?.setItem(e,n)}catch{}}}}function Kn(e,n){let t=typeof n.root=="string"?document.querySelector(n.root):n.root;if(!t)throw new Error(`uiServe: root not found: ${n.root}`);let o=t,i=!!n.hydrate;i||(o.innerHTML="");let u=ee(),r=new Set,d=new Set,a=new Map,l=!1,f=!1,g=[];function w(E){g.push(f),f=E}function T(){f=g.pop()??!1}let m={params:{},query:{}},h=new Map,b=globalThis.__DATA__??window.__DATA__;if(b&&typeof b=="object")for(let[E,S]of Object.entries(b))h.set(E,{value:S});m.data={async get(E,S){let k=h.get(E);if(k&&"value"in k)return k.value;if(k?.promise)return k.promise;if(!S)return;let R=Promise.resolve().then(()=>S()).then(I=>(h.set(E,{value:I}),I));return h.set(E,{promise:R}),R},set(E,S){h.set(E,{value:S})},has(E){return h.has(E)}};let N=!1;function s(){r.size>0&&!N&&(N=!0,queueMicrotask(()=>{N=!1;let E=[...r];r.clear(),E.length>0&&c(E)}))}function c(E){if(!l){l=!0;for(let S of E){let k=u.idRegistry.get(S);if(!k||!k._render)continue;m.ui._dirtySet?.delete(S);let R=k._child,I=k._render(k.props);if(k._child=I,R&&R._placement==="remote"||I&&I._placement==="remote"){R&&I?se(R,I,m):I?X(I,m):R&&U(R,u);continue}if(!k._parentNode&&k._refNode){let H=k._refNode.parentNode;H&&(k._parentNode=H)}if(k._parentNode){let H=Y(k._parentNode,k._refNode??null,R,I,m);H&&H!==k._refNode?k._refNode=H:H||(k._refNode=null)}}l=!1,s()}}let p=null;function y(){return p||(p=qe(E=>m.ui.render(E))),p}m.browser=Ue(),m.__registry=u,m.ui=en({ctx:m,renderByIds:c,getSelfId:E=>E?._selfId??m.ui?._selfId,dirtyBatch:r,dirtySet:d,mediaRegistry:a,popupTrackers:y().popupTrackers,scrollTrackers:y().scrollTrackers,schedulePopupRecompute:y().schedulePopupRecompute,ensurePopupListeners:y().ensurePopupListeners,destroyPopupListeners:y().destroyPopupListeners,isRendering:()=>l,isMounting:()=>f,setMounting:w,endMounting:T,registry:u}),ue(u,E=>{for(let S of[...a.keys()])if(S.startsWith(`media:${E}:`)||S===`bp:${E}`){let k=a.get(S);k?.mql&&k.handler&&k.mql.removeEventListener("change",k.handler),k?.mqls?.forEach(({mql:R,handler:I})=>R.removeEventListener("change",I)),a.delete(S)}y().cleanupTrackers(E)}),m.__rerender=()=>x(),m.app={navigate:E=>{e.mode==="hash"?window.location.hash="#"+E:window.history.pushState({},"",E),x()}};let v=null,C=!1,P=!1;function x(){P||(P=!0,queueMicrotask(()=>{P=!1,M()}))}async function M(){if(!C){C=!0;try{let E=e.getPath();if(m.route={path:E,params:m.params,query:m.query},!m.__state){let k=G(()=>{C||x()});m.__state=k;let R=m.ui.$;m.ui.$=function(){return this&&this._selfVNode?R.call(this):k}}let S=await e.execute(window.location,m,E);if(v==null){if(S){let k=i&&o.firstElementChild?(Le(o,S,m),o.firstChild):D(S,m);k&&k.parentNode!==o&&o.appendChild(k)}}else Y(o,o.firstChild,v,S,m);v=S}catch(E){if(console.error("[ui-dom] render error:",E),v==null){let S=document.createElement("div");S.className="ui-dom-error",S.textContent=`\u6E32\u67D3\u9519\u8BEF: ${E?.message??String(E)}`,o.appendChild(S)}}finally{C=!1}}}let V=()=>x();window.addEventListener("popstate",V);let L=()=>x();return e.mode==="hash"&&window.addEventListener("hashchange",L),x(),{get ctx(){return m},close(){window.removeEventListener("popstate",V),e.mode==="hash"&&window.removeEventListener("hashchange",L),v&&U(v,u),y().destroy(),u.idRegistry.clear(),o.innerHTML="",v=null}}}function Bn(e,n,t=400){let o=!1,i=()=>{o||(o=!0,e.removeEventListener("animationend",i),clearTimeout(u),n())};e.addEventListener("animationend",i);let u=setTimeout(i,t)}function Q(e,n){return Object.assign(Object.create(e),n)}function Gn(e){let n={baseURL:e?.baseURL??"",headers:{"Content-Type":"application/json",...e?.headers}},t=e?.onRequest,o=e?.onResponse,i=e?.timeout??0;async function u(r,d,a,l){let f=n.baseURL+d,g={method:r,headers:{...n.headers,...l?.headers}},w=e?.token?.();w&&!g.headers.Authorization&&(g.headers.Authorization=`Bearer ${w}`);let T=i>0,m=!!l?.signal,h=null,b=null;(T||m)&&(h=new AbortController,g.signal=h.signal,T&&(b=setTimeout(()=>h.abort(new Error("Request timed out")),i)),m&&l.signal.addEventListener("abort",()=>h.abort())),a!==void 0&&r!=="GET"&&r!=="HEAD"&&(g.body=JSON.stringify(a));let N={url:f,init:g};t&&(N=t(N));try{let s=await fetch(N.url,N.init);if(o)return o(s);if(!s.ok){let y=await s.text().catch(()=>"");throw new Oe(s.status,y||s.statusText)}let c=s.headers.get("content-length");if(s.status===204||c==="0")return;let p=(s.headers.get("content-type")||"").toLowerCase();return p.includes("application/json")||p.includes("json")?s.json():s.text()}finally{b&&clearTimeout(b)}}return r=>Q(r,{api:{get:(a,l)=>u("GET",a,void 0,l),post:(a,l,f)=>u("POST",a,l,f),put:(a,l,f)=>u("PUT",a,l,f),patch:(a,l,f)=>u("PATCH",a,l,f),delete:(a,l)=>u("DELETE",a,void 0,l)}})}var Oe=class extends Error{status;body;constructor(n,t){super(`API Error ${n}: ${t}`),this.name="ApiError",this.status=n,this.body=t}};function Yn(e){try{let n=e.split(".");if(n.length!==3)return null;let t=n[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(atob(t))}catch{return null}}function zn(e){let n=Yn(e);return n?.exp?n.exp*1e3-3e4<Date.now():!0}function Jn(e){let n=e?.storage??localStorage,t=e?.tokenKey??"weifuwu_token",o=e?.userKey??"weifuwu_user",i=e?.refreshTokenKey??"weifuwu_refresh",u=e?.refreshEndpoint??"/api/auth/refresh";return r=>{let d=n.getItem(t),a=n.getItem(o),l={token:d,user:a?JSON.parse(a):null,get isLoggedIn(){return this.token!==null},login(f,g,w){l.token=f,l.user=g,n.setItem(t,f),n.setItem(o,JSON.stringify(g)),w&&n.setItem(i,w)},logout(){l.token=null,l.user=null,n.removeItem(t),n.removeItem(o),n.removeItem(i)},setUser(f){l.user=f,n.setItem(o,JSON.stringify(f))},async refresh(){let f=n.getItem(i);if(!f)return!1;try{let g=await fetch(u,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:f})});if(!g.ok)return l.logout(),!1;let w=await g.json();return l.token=w.token,n.setItem(t,w.token),w.refreshToken&&n.setItem(i,w.refreshToken),!0}catch{return!1}}};return d&&zn(d)&&l.refresh().catch(()=>{}),Q(r,{auth:l})}}function Xn(e={}){let n=e.url??"/ws",t=e.reconnectInterval??3e3,o=e.maxReconnect??10,i=e.pingInterval??3e4,u=e.pingTimeout??1e4;return r=>{let d=new Set,a=null,l=0,f=null,g=null,w=null,T=!1,m={isConnected:!1,onMessage:c=>(d.add(c),()=>{d.delete(c)}),send:c=>{a?.readyState===WebSocket.OPEN&&a.send(JSON.stringify(c))},_connect:h,close:()=>{T=!0,s(),a?.close(),a=null,m.isConnected=!1}};async function h(){if(!T)try{a=new WebSocket(n),a.onopen=()=>{m.isConnected=!0,l=0,b()},a.onmessage=c=>{try{let p=JSON.parse(c.data);for(let y of d)y(p)}catch{}N()},a.onclose=()=>{m.isConnected=!1,s(),!T&&l<o&&(l++,f=setTimeout(h,t*Math.min(l,5)))},a.onerror=()=>{a?.close()}}catch{T||(f=setTimeout(h,t))}}function b(){i<=0||(g=setInterval(()=>{a?.readyState===WebSocket.OPEN&&a.send(JSON.stringify({type:"ping"})),w=setTimeout(()=>{a?.close()},u)},i))}function N(){clearTimeout(w)}function s(){clearInterval(g),clearTimeout(w),clearTimeout(f)}return h(),Q(r,{ws:m})}}function ge(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}var Qn=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);function Zn(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(Boolean).join(" "):e&&typeof e=="object"?Object.entries(e).filter(([,n])=>n).map(([n])=>n).join(" "):""}function et(e){return typeof e=="string"?e:e&&typeof e=="object"?Object.entries(e).filter(([,n])=>n!=null).map(([n,t])=>`${n}:${typeof t=="number"?t+"px":String(t)}`).join(";"):""}function un(e,n){let t=new Set,o={$:()=>G(()=>{}),dirty:()=>{},render:()=>{},selfId:r=>{if(t.has(r))throw new Error(`[weifuwu] Duplicate component ID: "${r}"`);t.add(r)},useMedia:()=>{},useBreakpoint:()=>{},usePopupPosition:()=>({top:0,left:0,refresh:()=>{}}),useHoverCapable:()=>!1,useVisualViewport:()=>({height:0,offsetTop:0,keyboardOpen:!1}),useLongPress:()=>({}),useInView:()=>({isIn:!1,ready:!1,observe:()=>{},refresh:()=>{},disconnect:()=>{}}),useScrollPosition:()=>({y:0,refresh:()=>{}}),useStableRef:r=>d=>{d&&r?.(d)},useGlobalKey:()=>()=>{},useReducedMotion:()=>!1,useAnimationEnd:()=>()=>{},useTween:r=>{let d={value:r,reset:a=>{d.value=a}};return d},useDrag:()=>({onPointerDown:()=>{}}),useDragDrop:()=>({dropProps:{},dragProps:{}}),useControlled:r=>({value:r.value,setValue:d=>{r.onChange?.(d)},controlled:r.value!==void 0}),useControlledInput:r=>({value:r.value,setValue:d=>{r.onChange?.(d)},controlled:r.value!==void 0,keyword:"",setKeyword:()=>{},selectedLabel:"",setSelectedLabel:()=>{}}),useOpen:r=>({get open(){return!!r.open},setOpen:d=>{r.onOpenChange?.(d)},triggerProps:{}}),useAsync:()=>({data:void 0,loading:!0,error:void 0,reload:()=>{}}),usePopup:()=>({open:!1,setOpen:()=>{},wrapProps:{},portal:()=>null,refresh:()=>{}}),usePresence:()=>({phase:"closed",ref:()=>{},sync:r=>r?"open":"closed"}),useDialog:()=>({phase:"closed",rootRef:()=>{},panelRef:()=>{},sync:r=>r?"open":"closed"}),useChat:()=>({messages:[],input:"",streaming:!1,error:null,usage:null,step:null,send:()=>{},stop:()=>{},retry:()=>{},clear:()=>{},approve:async()=>{},dispose:()=>{}})},i={activeElement:()=>null,byId:()=>null,query:()=>null,createElement:()=>null,bodyAppend:()=>{},bodyRemove:()=>{},copyText:async()=>!1,execCommand:()=>!1,selectionText:()=>null,getSelection:()=>null,queryCommandState:()=>!1,queryCommandValue:()=>"",viewportHeight:()=>0,scrollTop:()=>0,hash:()=>"",setHash:()=>{},timeout:()=>0,rootElement:()=>null,storageGet:()=>null,storageSet:()=>{}},u=Object.create(e??{});return u.ui=o,u.browser=i,u.data={async get(r,d){if(n.has(r))return n.get(r);if(!d)return;let a=await d();return n.set(r,a),a},set(r,d){n.set(r,d)},has(r){return n.has(r)}},u}async function J(e,n){if(e==null||typeof e=="boolean")return"";if(typeof e=="string"||typeof e=="number")return ge(String(e));if(Array.isArray(e)){let l="";for(let f of e)l+=await J(f,n);return l}let t=e;if(t.type===j||t.type===$)return J(t.props?.children,n);if(typeof t.type=="function"){let l;if(z(t.type)){if(l=await t.type(n),typeof l!="function")throw new Error(`asyncComponent factory <${t.type.name||"anonymous"}> must return a Component (initProps, ctx) => (props) => VNode.`)}else l=t.type;let f=Object.create(n),g=l(t.props??{},f);if(typeof g!="function")throw new Error(`Component ${t.type.name||"anonymous"} must return a render function. Use (init_props, ctx) => (props) => VNode pattern.`);return J(g(t.props??{}),f)}let o=t.type,i=t.props??{},u=[],r;for(let[l,f]of Object.entries(i))if(!(l==="children"||l==="key")&&l!=="ref"&&!(l.startsWith("on")&&typeof f=="function")){if(l==="innerHTML"){r=String(f??"");continue}if(l==="class"||l==="className"){let g=Zn(f);g&&u.push(` class="${ge(g)}"`);continue}if(l==="style"&&f&&typeof f=="object"){u.push(` style="${ge(et(f))}"`);continue}if(f===!0){u.push(` ${l}`);continue}f===!1||f==null||u.push(` ${l}="${ge(String(f))}"`)}let d=u.join("");if(Qn.has(o))return`<${o}${d}>`;if(r!==void 0)return`<${o}${d}>${r}</${o}>`;let a=await J(i.children,n);return`<${o}${d}>${a}</${o}>`}async function nt(e,n,t,o={}){let i=o.data??new Map,u=un(t,i);return await J({type:e,props:n??{},key:void 0},u)}function dn(e){return`<script>window.__DATA__=${JSON.stringify(Object.fromEntries(e)).replace(/</g,"\\u003c")};<\/script>`}async function tt(e,n){let t=new Map,i=un({params:{},query:{}},t),u=n.url.split("?")[0].split("#")[0],r=e.match(u);i.params=r.params,i.query=Object.fromEntries(new URLSearchParams(n.url.split("?")[1]??""));let d=new URL(n.url.startsWith("http")?n.url:`http://localhost${n.url.startsWith("/")?n.url:"/"+n.url}`),a=await e.execute(d,i,u),l=await J(a,i),f=dn(t),g=r.title??n.title??"",w=n.rootId??"root",T=`<!DOCTYPE html>
3
+ `);o=s.pop()??"";for(let u of s){let a="message",l="";for(let c of u.split(`
4
+ `))c.startsWith("event: ")?a=c.slice(7):c.startsWith("data: ")&&(l+=c.slice(6));if(l)try{yield{name:a,data:JSON.parse(l)}}catch{}}}}finally{n.releaseLock()}}function Rn(e,n,t){t&&(e.length>=1e3&&e.shift(),e.push(n))}function Mn(e){return e===401||e===403?"auth_failed":e===429?"rate_limited":e>=500?"provider_error":"invalid_request"}function An(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`trace-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function Ln(e){return e.map(n=>({role:n.role,content:n.content}))}function Me(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`msg-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function on(e,n,t){t.initialMessages?e.messages=structuredClone(t.initialMessages):e.messages===void 0&&(e.messages=[]),e.input===void 0&&(e.input=""),e.streaming===void 0&&(e.streaming=!1),e.error===void 0&&(e.error=null),e.usage===void 0&&(e.usage=null),e.step===void 0&&(e.step=null);let o=null;function r(){if(!e.streaming)return;let T=e.messages[e.messages.length-1];return T&&T.role==="assistant"&&T.status==="streaming"?T:void 0}function d(T,h,p){let b=r();switch(T){case"wf:token":b&&(b.content+=h.text);break;case"wf:tool_call":{b&&(b.toolCalls||(b.toolCalls=[]),b.toolCalls.push({call:h,status:"running"}));break}case"wf:tool_progress":{let N=h,S=b?.toolCalls?.find(i=>i.call.id===N.toolCallId);S&&(S.progress=N);break}case"wf:tool_result":{let N=h,S=b?.toolCalls?.find(i=>i.call.id===N.id);S&&(S.result=N,S.status=N.ok?"ok":"error");break}case"wf:approval_request":b&&(b.approval=h);break;case"wf:usage":b&&(b.usage=h);break;case"wf:step":e.step=h;break;case"wf:done":b&&(b.status="done",b.approval=void 0),e.streaming=!1,e.step=null;break;case"wf:error":b&&(b.status="error",b.error=h,b.approval=void 0),e.error=h,e.streaming=!1,e.step=null;break;default:p?.(T,h);break}}function s(){let T=t.body?t.body(e.messages):{messages:Ln(e.messages)};o=n(t.url,T,{onToken:p=>d("wf:token",{text:p}),onToolCall:p=>d("wf:tool_call",p),onToolProgress:p=>d("wf:tool_progress",p),onToolResult:p=>d("wf:tool_result",p),onApproval:p=>d("wf:approval_request",p),onUsage:p=>d("wf:usage",p),onStep:p=>d("wf:step",p),onDone:p=>d("wf:done",p),onError:p=>d("wf:error",p),onEvent:(p,b)=>d(p,b,t.onEvent)},{signal:t.signal,headers:t.headers}),e.streaming=!0;let h=r();h&&o?.traceId&&(h.id=o.traceId)}function u(){if(e.streaming)return;let T=String(e.input??"").trim();T&&(e.input="",e.error=null,e.usage=null,e.step=null,e.messages.push({id:Me(),role:"user",content:T,status:"done"},{id:Me(),role:"assistant",content:"",status:"streaming",toolCalls:[]}),s())}function a(){o?.abort(),e.streaming=!1,e.step=null;let T=e.messages[e.messages.length-1];T&&T.role==="assistant"&&T.status==="streaming"&&(!T.content&&(!T.toolCalls||T.toolCalls.length===0)?e.messages.pop():T.status="done")}function l(){if(e.streaming)return;let T=-1;for(let h=e.messages.length-1;h>=0;h--)if(e.messages[h].role==="user"){T=h;break}T!==-1&&(e.messages.splice(T+1),e.error=null,e.usage=null,e.step=null,e.messages.push({id:Me(),role:"assistant",content:"",status:"streaming",toolCalls:[]}),s())}function c(){o?.abort(),e.messages=[],e.input="",e.streaming=!1,e.error=null,e.usage=null,e.step=null}async function y(T,h){let p=e.messages[e.messages.length-1],b=p?.role==="assistant"?p.approval:void 0;if(b&&(p.approval=void 0,!!t.approveUrl))try{await fetch(t.approveUrl,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify({id:b.id,decision:T,note:h}),signal:t.signal})}catch(N){if(t.signal?.aborted)return;e.error={code:"provider_error",message:N instanceof Error?N.message:String(N)}}}function v(){o?.abort(),o=null}return{send:u,stop:a,retry:l,clear:c,approve:y,dispose:v}}var rn="__wfAsyncComponent";function In(e){let n=e;return n[rn]=!0,n}function J(e){return typeof e=="function"&&e?.[rn]===!0}var B=Symbol("Fragment"),F=Symbol("Portal");function Ae(e,n,t){return{type:e,props:sn(n),key:t??void 0}}var Vn=Ae;function Hn(e,n,t){return Ae(e,n,t)}function Un(e,n,...t){let o=sn(n??{});return t.length>0&&(o.children=t.length===1?t[0]:t),{type:e,props:o,key:n?.key??void 0}}function sn(e){if(!e)return{};let n={};for(let t of Object.keys(e))t!=="key"&&(n[t]=e[t]);return n}function Le(e,n){return{type:F,props:{children:e,portalKey:n},key:n??void 0,_placement:"remote"}}var he=new Set,ie=new Map,ve=new Map,le=new Map;function ln(e){let{ctx:n,renderByIds:t,getSelfId:o,dirtyBatch:r,dirtySet:d,mediaRegistry:s,popupTrackers:u,scrollTrackers:a,schedulePopupRecompute:l,ensurePopupListeners:c,isRendering:y,isMounting:v,setMounting:T,endMounting:h}=e,p=n.browser??U(),b=e.registry??W(n),N=i=>pe(b,i);return{_selfId:"_wf_root",_ctxVersion:0,_dirtySet:d,setMounting:T,endMounting:h,bumpCtxVersion:function(){this._ctxVersion++},render:function(i){if(y()){if(v())return;this._pendingRender||(this._pendingRender=!0,queueMicrotask(()=>{this._pendingRender=!1,this.render(i)}));return}if(!i||i.length===0){let f=o(this);if(f)i=[f];else return}t(i)},dirty:function(i){if(!v()){if(y()){this._pendingDirty||(this._pendingDirty=!0,queueMicrotask(()=>{this._pendingDirty=!1,this.dirty(i)}));return}if(!i||i.length===0){let f=o(this);if(f)i=[f];else return}for(let f of i)f&&(r.add(f),d.add(f));this._dirtyScheduled||(this._dirtyScheduled=!0,queueMicrotask(()=>{this._dirtyScheduled=!1;let f=[...r];r.clear(),f.length>0&&t(f)}))}},$:function(){let i=this;if(!Object.prototype.hasOwnProperty.call(i,"_$cache")){let f=z(()=>{let m=i._selfVNode?._id??o(i);m&&n.ui.dirty([m])});i._$cache=f}return i._$cache},useChat:function(i){let f=this.$(),m=on(f,tn,i);Object.assign(f,{send:m.send,stop:m.stop,retry:m.retry,clear:m.clear,approve:m.approve,dispose:m.dispose});let g=o(this);if(g){let w=N(C=>{C===g&&(m.dispose(),w())})}return f},useMedia:function(i,f){let g=`media:${o(this)}:${i}`;if(!s.has(g)){let w=p.matchMedia(i);f(w.matches);let C=P=>f(P.matches);w.addEventListener("change",C),s.set(g,{mql:w,handler:C})}},useBreakpoint:function(i,f){let m=typeof i=="function"?{mobile:"(max-width: 639px)",tablet:"(min-width: 640px) and (max-width: 1023px)",desktop:"(min-width: 1024px)"}:i,g=typeof i=="function"?i:f,C=`bp:${o(this)}`;function P(){for(let[E,A]of Object.entries(m))if(p.matchMedia(A).matches)return E;return Object.keys(m)[0]??""}if(!s.has(C)){g(P());let E=[];for(let A of Object.values(m)){let V=p.matchMedia(A),H=()=>g(P());V.addEventListener("change",H),E.push({mql:V,handler:H})}s.set(C,{mqls:E})}},usePopupPosition:function(i){let f=o(this),m={top:0,left:0,refresh:()=>{}};if(!f)return m;let g={pos:m,getEl:i.el,isOpen:i.isOpen,compute:i.compute,panel:i.panel,margin:i.margin??8};return u.set(f,g),c(),m.refresh=()=>{let w=g.getEl();if(!w)return;let C=w.getBoundingClientRect();if(C.width===0&&C.height===0)return;let P=g.compute(C);Object.assign(m,me(P,g.panel?.(),g.margin))},m},useHoverCapable:function(){return typeof window<"u"&&!!window.matchMedia?.("(hover: hover)").matches},useStableRef:function(i,f){return g=>{g?i(g):f?.()}},useVisualViewport:function(){let i=o(this),f={height:p.viewportHeight(),offsetTop:0,keyboardOpen:!1},m=()=>{n.ui&&n.ui.dirty(i?[i]:void 0)},g=()=>{let C=p.visualViewport();f.height=C?.height??p.viewportHeight(),f.offsetTop=C?.offsetTop??0,f.keyboardOpen=f.height<p.viewportHeight()*.9,m()},w=p.visualViewport();if(w?.addEventListener?(w.addEventListener("resize",g),w.addEventListener("scroll",g)):p.addEventListener("resize",g),i){let C=N(P=>{P===i&&(w?.removeEventListener?(w.removeEventListener("resize",g),w.removeEventListener("scroll",g)):p.removeEventListener("resize",g),C())})}return f},usePopup:function(i){let f=o(this),m=this.useHoverCapable(),g=()=>typeof i.trigger=="function"?i.trigger():i.trigger,w=i.open!==void 0,C=()=>!!i.disabled?.(),P=()=>w?typeof i.open=="function"?!!i.open():!!i.open:i.isOpen(),E=_=>{C()||(w?i.onOpenChange?.(_):i.setOpen(_))},A=()=>{let _=i.placement;return typeof _=="function"?_():_??"bottom"},V=null,H=!1,x=n.ui.usePopupPosition({el:i.el,isOpen:()=>P(),compute:_=>{if(i.position){let L=i.position();return{top:L.y,left:L.x}}return Ge(_,A(),i.gap??6,i.center!==!1)},panel:()=>V,margin:i.margin??8}),M=_=>{if(i.closeOnOutside===!1||!P())return;let L=_.target;if(!(L instanceof Node))return;let $=i.el();$&&$.contains(L)||V&&V.contains(L)||E(!1)},k=_=>{i.closeOnEscape!==!1&&(_.key!=="Escape"||!P()||E(!1))};if(p.addEventListener("mousedown",M),p.addEventListener("keydown",k),f){let _=N(L=>{L===f&&(p.removeEventListener("mousedown",M),p.removeEventListener("keydown",k),_())})}let R={},I=_=>typeof _=="function"?_():_??0,D=()=>I(i.openDelay),Fe=()=>I(i.closeDelay),K,G,hn=()=>{clearTimeout(K),clearTimeout(G),K=void 0,G=void 0},vn=_=>{if(C())return;let L=_.currentTarget,$=_.relatedTarget;L.contains($)||(clearTimeout(G),G=void 0,K=setTimeout(()=>{K=void 0,E(!0)},D()))},wn=_=>{if(C())return;let L=_.currentTarget,$=_.relatedTarget;L.contains($)||(clearTimeout(K),K=void 0,G=setTimeout(()=>{G=void 0,E(!1)},Fe()))},bn=()=>{C()||(clearTimeout(G),G=void 0,K=setTimeout(()=>{K=void 0,E(!0)},D()))},Cn=()=>{C()||(clearTimeout(K),K=void 0,G=setTimeout(()=>{G=void 0,E(!1)},Fe()))},oe=()=>g()==="hover";if(R.onMouseOver=_=>{oe()&&vn(_)},R.onMouseOut=_=>{oe()&&wn(_)},R.onClick=()=>{oe()?m||E(!P()):g()==="click"&&E(!0)},R.onFocus=()=>{oe()&&bn()},R.onBlur=()=>{oe()&&Cn()},g()==="longpress"){let _,L=0,$=0,Y=()=>{clearTimeout(_),_=void 0};R.onPointerDown=j=>{C()||(L=j.clientX??0,$=j.clientY??0,Y(),_=setTimeout(()=>{_=void 0,i.onTrigger?.({clientX:L,clientY:$}),E(!0)},i.longPressDuration??500))},R.onPointerUp=Y,R.onPointerLeave=Y,R.onPointerMove=j=>{let xe=Math.abs((j.clientX??0)-L),Pe=Math.abs((j.clientY??0)-$);(xe>10||Pe>10)&&Y()},R.onContextMenu=j=>{j.preventDefault(),i.onTrigger?.({clientX:j.clientX??0,clientY:j.clientY??0}),E(!0)}}if(R.onKeyDown=_=>{_.key==="Escape"&&i.closeOnEscape!==!1&&E(!1)},f){let _=N(L=>{L===f&&(hn(),_())})}let Tn=_=>{if(_){V=_;let L=()=>x.refresh();_.addEventListener("animationend",L,{once:!0})}else V=null},Te=null,Ee=null,En=_=>{Tn(_),Ee&&Ee(_)};return{get open(){return P()},setOpen:E,wrapProps:R,portal:(_,L="popover")=>{if(C())return null;if(!P())return H=!1,Te=null,null;let Y=i.el();(!H||Y!==Te)&&(Y?x.refresh():queueMicrotask(()=>{P()&&x.refresh()}),H=!0,Te=Y);let j=_.props??{};Ee=j.ref??null;let xe=["wf-popup",j.class].filter(Boolean).join(" "),Pe={...j.style??{},position:"fixed",top:`${x.top}px`,left:`${x.left}px`,maxWidth:i.width!==void 0?`min(${i.width}px, calc(100vw - 32px))`:"calc(100vw - 32px)"},xn={..._,props:{...j,class:xe,style:Pe,ref:En}};return Le(xn,L)},refresh:()=>x.refresh()}},useLongPress:function(i){let{onLongPress:f,duration:m=500}=i,g,w=0,C=0,P=null,E=()=>{clearTimeout(g),g=void 0};return{onPointerDown:A=>{w=A.clientX??0,C=A.clientY??0,P=A,E(),g=setTimeout(()=>{g=void 0,P&&f(P)},m)},onPointerUp:E,onPointerLeave:E,onPointerMove:A=>{let V=Math.abs((A.clientX??0)-w),H=Math.abs((A.clientY??0)-C);(V>10||H>10)&&E()},onContextMenu:A=>{A.preventDefault(),f(A)}}},useInView:function(i){let f=o(this),m={isIn:!1,ready:!1,observe:E,refresh:A,disconnect:V},g=null,w=null,C=()=>{n.ui&&n.ui.dirty(f?[f]:void 0)};function P(){if(w?.disconnect(),w=null,!g)return;let H=typeof i.rootMargin=="function"?i.rootMargin():i.rootMargin,x=typeof i.threshold=="function"?i.threshold():i.threshold;w=new IntersectionObserver(M=>{let k=M[M.length-1];if(!k)return;let R=k.isIntersecting,I=R!==m.isIn,D=!m.ready;m.isIn=R,m.ready=!0,i.onChange?.(k,R),(I||D)&&C()},{root:i.root?i.root():null,rootMargin:H??"0px",threshold:x??0}),w.observe(g)}function E(H){g=H,H?P():(w?.disconnect(),w=null,m.isIn=!1)}function A(){P()}function V(){w?.disconnect(),w=null}return m},useScrollPosition:function(i){let f=o(this),m={y:0,refresh(){let w=g.getScroller();m.y=w instanceof Window?p.scrollingElement()?.scrollTop??p.scrollTop():w.scrollTop??0}},g={handle:m,getScroller:i.getScroller??(()=>window)};return f?(a.set(f,g),c(),m.refresh(),m):(m.refresh(),m)},useAsync:function(i){let f=o(this),m=z(()=>{n.ui&&n.ui.dirty(f?[f]:void 0)});m.loading=!0;let g=0,w=()=>{let C=++g;m.loading=!0,m.error=null,Promise.resolve().then(()=>i()).then(P=>{g===C&&(m.data=P,m.loading=!1)}).catch(P=>{g===C&&(m.error=P,m.loading=!1)})};return w(),m.reload=w,m},useControlled:function(i){let f=o(this),m=i.value!==void 0;if(m&&!i.onChange&&i.name&&(he.has(i.name)||(he.add(i.name),console.warn(`[weifuwu/${i.name}] \u53D7\u63A7\u6A21\u5F0F\uFF08value \u5DF2\u4F20\uFF09\u4F46\u672A\u63D0\u4F9B onChange\uFF0C\u4EA4\u4E92\u65E0\u6CD5\u751F\u6548\u3002
5
+ \u975E\u53D7\u63A7\uFF1A\u53BB\u6389 value\uFF1B\u53D7\u63A7\uFF1A\u4F20\u5165 onChange={(v) => setValue(v)}`))),!m&&f&&!ie.has(f)){ie.set(f,i.value);let w=N(C=>{C===f&&(ie.delete(f),w())})}let g=w=>{if(m){i.onChange?.(w);return}f&&ie.set(f,w),n.ui&&(f?n.ui.dirty([f]):n.ui.render())};return{value:m?i.value:f?ie.get(f):i.value,setValue:g,controlled:m}},useControlledInput:function(i){let f=o(this),m=this.useControlled({value:i.value,onChange:i.onChange,name:i.name});if(f&&!ve.has(f)){ve.set(f,{keyword:"",selectedLabel:""});let C=N(P=>{P===f&&(ve.delete(f),C())})}let g=f?ve.get(f):{keyword:"",selectedLabel:""},w=()=>{f?n.ui?.dirty([f]):n.ui?.render()};return{...m,get keyword(){return g.keyword},setKeyword(C){g.keyword=C,w()},get selectedLabel(){return g.selectedLabel},setSelectedLabel(C){g.selectedLabel=C,w()}}},useOpen:function(i){let f=o(this);if(f&&!le.has(f)){le.set(f,!1);let P=N(E=>{E===f&&(le.delete(f),P())})}let m=i.open!==void 0;m&&!i.onOpenChange&&i.name&&!he.has(i.name)&&(he.add(i.name),console.warn(`[weifuwu/${i.name}] \u53D7\u63A7\u6A21\u5F0F\uFF08open \u5DF2\u4F20\uFF09\u4F46\u672A\u63D0\u4F9B onOpenChange\uFF0C\u4EA4\u4E92\u65E0\u6CD5\u751F\u6548\u3002
6
+ \u975E\u53D7\u63A7\uFF1A\u53BB\u6389 open\uFF1B\u53D7\u63A7\uFF1A\u4F20\u5165 onOpenChange={(o) => setOpen(o)}`));let g=()=>m?!!i.open:f?le.get(f)??!1:!1,w=()=>{f?n.ui?.dirty([f]):n.ui?.render()},C=P=>{if(m){i.onOpenChange?.(P);return}f&&le.set(f,P),w()};return{get open(){return g()},setOpen:C,triggerProps:{onClick:()=>C(!0),onFocus:()=>{i.openOnFocus&&C(!0)}}}},usePresence:function(i){let f=o(this),m="closed",g,w=()=>{m="closed",n.ui&&(f?n.ui.dirty([f]):n.ui.render())};return{get phase(){return m},ref:P=>{P?g||(g=()=>{m==="exit"&&w()},P.addEventListener("animationend",g)):g=void 0},sync:P=>(P?m="open":m==="open"&&(m="exit"),m)}},useDialog:function(i){let f=o(this),m,g=null,w=this.usePresence(i);return{get phase(){return w.phase},rootRef:E=>{E?(en(),g&&(m=Re(g)),w.ref(E)):(nn(),m?.(),w.ref(null))},panelRef:E=>{g=E,E&&!m&&(m=Re(E))},sync:E=>w.sync(E)}},useGlobalKey:function(i){let f=o(this);if(typeof window>"u")return()=>{};if(p.addEventListener("keydown",i),f){let m=N(g=>{g===f&&(p.removeEventListener("keydown",i),m())})}return()=>p.removeEventListener("keydown",i)},useDrag:function(i){let f=0,m=0,g=!1,w=E=>{g&&i.onMove(E,{x:E.clientX-f,y:E.clientY-m})},C=E=>{g&&(g=!1,p.removeEventListener("pointermove",w),p.removeEventListener("pointerup",C),i.onEnd?.(E))};return{onPointerDown:E=>{g||(E.preventDefault(),g=!0,f=E.clientX,m=E.clientY,p.addEventListener("pointermove",w),p.addEventListener("pointerup",C),i.onStart?.(E))}}},useDragDrop:function(i){let f={};i.onDrop&&(f.onDrop=g=>{g.preventDefault(),i.onDrop(g)}),i.onDragOver&&(f.onDragOver=g=>{g.preventDefault(),i.onDragOver(g)}),i.onDragLeave&&(f.onDragLeave=g=>i.onDragLeave(g));let m={draggable:!0};if(i.onDragStart){let g=i.onDragStart;m.onDragStart=w=>{typeof document<"u"&&document.body.classList.add("wf-dragging"),g(w)}}if(i.onDragEnd){let g=i.onDragEnd;m.onDragEnd=w=>{typeof document<"u"&&document.body.classList.remove("wf-dragging"),g(w)}}return{dropProps:f,dragProps:m}},useReducedMotion:function(){return typeof window<"u"&&!!window.matchMedia?.("(prefers-reduced-motion: reduce)").matches},useAnimationEnd:function(i,f){let m=null,g=()=>{i(),f?.once&&m&&m.removeEventListener("animationend",g)};return C=>{C?(m=C,C.addEventListener("animationend",g)):m&&(m.removeEventListener("animationend",g),m=null)}},useTween:function(i,f){let m=o(this),g=this.useReducedMotion(),w=f?.duration??400,C=f?.ease==="linear"?x=>x:x=>1-Math.pow(1-x,3),P,E=i,A={value:g?i:0,reset:()=>{}},V=()=>{n.ui&&(m?n.ui.dirty([m]):n.ui.render())},H=x=>{if(E=x,g){A.value=x,V();return}if(x===A.value)return;P&&cancelAnimationFrame(P);let M=A.value,k=performance.now(),R=I=>{let D=Math.min(1,(I-k)/w);A.value=Math.round(M+(x-M)*C(D)),D<1?(P=requestAnimationFrame(R),V()):(P=void 0,V())};P=requestAnimationFrame(R)};return A.reset=x=>{x===E&&P||H(x)},queueMicrotask(()=>H(i)),A},selfId:function(i){if(typeof i!="string"||!i)throw new Error(`[weifuwu] selfId requires a non-empty string, got ${typeof i}`);if(b.idRegistry.has(i))throw new Error(`[weifuwu] Duplicate component ID: "${i}". Each component must have a unique custom ID.`);let f=this._selfVNode;f&&(f._customId=i,b.idRegistry.set(i,f))}}}var an=new WeakMap;function On(e){let n=an.get(e)??{count:0,warned:!1};n.count++,n.count>=3&&!n.warned&&(n.warned=!0,console.warn("[weifuwu] ref \u51FD\u6570\u6BCF\u6B21\u6E32\u67D3\u90FD\u53D8\u5316\uFF08\u5185\u8054 ref\uFF09\u2014\u2014ref \u56DE\u8C03\u5728\u6BCF\u6B21\u6E32\u67D3\u540E\u91CD\u65B0\u6267\u884C\uFF08\u6027\u80FD\u635F\u8017\uFF09\u3002\u628A ref \u5B9A\u4E49\u5230 mount \u4F5C\u7528\u57DF\uFF08\u7A33\u5B9A\u5F15\u7528\uFF09\uFF1Aconst listRef = (el) => {...}; return h('div', { ref: listRef })")),an.set(e,n)}function X(e,n,t,o,r){if(t==null){if(o==null)return null;let l=q(o,r);return l==null?null:(n&&n.parentNode?n.parentNode.insertBefore(l,n):e.appendChild(l),l)}if(o==null)return n?(O(t,W(r)),n.remove()):O(t,W(r)),null;let d=dn(t),s=dn(o);if(d!==s){O(t,W(r));let l=q(o,r);return l==null?null:(n?.parentNode&&n.parentNode.replaceChild(l,n),l)}if(s==="text")return n&&n.textContent!==String(o)&&(n.textContent=String(o)),n;let u=o,a=t;if(typeof u.type=="function"){let l=u.type;a._render&&a.type===u.type&&(u._render=a._render,u._id=a._id,u._id&&W(r).idRegistry.set(u._id,u)),u._parentNode=e,u._refNode=n;let c=Object.create(r);c.ui=Object.create(r.ui);let y=c.ui;if(y._selfId=u._id,y._selfVNode=u,u._ctxVersion=a._ctxVersion??y._ctxVersion??0,a._render&&a.type===u.type&&jn(a.props,u.props)&&!y._dirtySet?.has(a._id)&&u._ctxVersion===y._ctxVersion)return u._child=a._child,n;y._dirtySet?.delete(a._id);let v;try{typeof u._render=="function"?v=u._render(u.props):v=He(l,u.props,u,c)}catch(p){let b=r.ui?._errorHandler;b?(b(p),v=null):(console.error(`[weifuwu] Component render error in <${l?.name||"anonymous"}> (id: ${a._id??"?"}, phase: update)`,p),v=null)}let T=a._child;u._child=v;let h=X(e,n,T,v,c);return h||(u._refNode=null),h}if(u.type===B){let l=a._childNodes,c=fn(e,a,u,r,l);return u._childNodes=c,n}if(typeof u.type=="string"){if(n&&n.nodeType===1){let l=a.props?.ref,c=u.props?.ref;l!==c&&(typeof c=="function"&&c(n),typeof l=="function"&&typeof c=="function"&&On(n)),Ve(n,a.props,u.props),fn(n,a,u,r)}else if(n){O(t,W(r));let l=q(o,r);return l==null?null:(n.parentNode?.replaceChild(l,n),l)}return n}if(u.type===F)return de(a,u,r),null;if(Array.isArray(o)){let l=Array.isArray(t)?t:[];we(l,o);let c=Array.from(e.childNodes),y=n?c.indexOf(n):-1,v=y>=0?ae(c.slice(y),l):ae(c,l);return be(e,l,o,r,v,n),n}return n}var un=new Map;function Wn(e){let n=un.get(e);return n||(n=`fn:${e.name||"anon"}`,un.set(e,n)),n}function dn(e){if(e==null||typeof e=="boolean")return"null";if(typeof e=="string"||typeof e=="number")return"text";if(Array.isArray(e))return"array";let n=e;return typeof n.type=="function"?Wn(n.type):n.type===B?"fragment":n.type===F?"portal":typeof n.type=="string"?"tag:"+n.type:"unknown"}function Ve(e,n,t){let o=n?Object.keys(n).filter(s=>s!=="children"&&s!=="key"&&s!=="innerHTML"):[],r=t?Object.keys(t).filter(s=>s!=="children"&&s!=="key"&&s!=="innerHTML"):[],d=new Set(r);for(let s of o){if(!n)break;if(!d.has(s)){if(s==="ref")continue;s.startsWith("on")&&typeof n[s]=="function"?e.removeEventListener(s.slice(2).toLowerCase(),n[s]):s==="value"&&(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)?e.value="":e.removeAttribute(s==="className"?"class":s)}}for(let s of r){if(s==="ref")continue;let u=n?.[s],a=t?.[s];if(s==="innerHTML")a!==u&&(e.innerHTML=String(a??""));else if(a!==u)if(s==="class"||s==="className")e instanceof SVGElement?e.setAttribute("class",cn(a)):e.className=cn(a);else if(s==="style"&&typeof a=="object"&&a!==null){let l=e.style,c=a;for(let y of Object.keys(c)){let v=c[y];v==null?y.startsWith("--")?l.removeProperty(y):l[y]="":y.startsWith("--")?l.setProperty(y,String(v)):l[y]=typeof v=="number"?v+"px":String(v)}}else if(s.startsWith("on")&&typeof a=="function"){let l=s.slice(2).toLowerCase();typeof u=="function"&&e.removeEventListener(l,u),e.addEventListener(l,a)}else s==="draggable"?e.setAttribute("draggable",a?"true":"false"):s==="value"&&(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)?e.value=String(a??""):a===!0?e.setAttribute(s,""):a!=null&&a!==!1?e.setAttribute(s,String(a)):s==="value"&&(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)?e.value="":e.removeAttribute(s)}}function cn(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(Boolean).join(" "):e&&typeof e=="object"?Object.entries(e).filter(([,n])=>n).map(([n])=>n).join(" "):""}function Ie(e){if(!(e==null||typeof e!="object"))return Array.isArray(e)?void 0:e.key}function we(e,n){if(!n.some(o=>o&&typeof o=="object"&&!Array.isArray(o)&&o.key!==void 0)){for(let o=0;o<n.length;o++){let r=n[o];r&&typeof r=="object"&&!Array.isArray(r)&&(r.key=String(o))}for(let o=0;o<e.length;o++){let r=e[o];r&&typeof r=="object"&&!Array.isArray(r)&&(r.key=String(o))}}}function ae(e,n){let t=[],o=0;for(let r of n){if(r==null||typeof r=="boolean"){t.push(null);continue}let d=r;if(d.type===F){t.push(null);continue}if(d.type===B){let s=d._childNodes;Array.isArray(s)&&s.length>0?(t.push(s.slice()),o+=s.length):(t.push(e[o]?[e[o]]:null),o+=1)}else if(typeof d.type=="function")if(d._render){let s=d._childNodes??d._refNode;s==null?t.push(null):Array.isArray(s)?(t.push(s.slice()),o+=s.length):(t.push([s]),o+=1)}else t.push(e[o]?[e[o]]:null),o+=1;else typeof process<"u"&&process.env.DBG&&console.error("[map] idx=",o,"type=",d.type,"sourceLen=",e.length,"hit=",!!e[o]),t.push(e[o]?[e[o]]:null),o+=1}return t}function fn(e,n,t,o,r){let d=ue(n.props?.children),s=ue(t.props?.children);we(d,s);let u=r??Array.from(e.childNodes),a=ae(u,d),l=be(e,d,s,o,a,r?.[0]??null),c=[];for(let y of l)y&&y.length>0&&c.push(...y);return c}function ue(e){if(e==null)return[];if(!Array.isArray(e))return[e];let n=[];for(let t of e)Array.isArray(t)?n.push(...t):n.push(t);return n}function pn(e){return e==null?[]:e instanceof DocumentFragment?Array.from(e.childNodes):[e]}function be(e,n,t,o,r=[],d=null){if(!t.some(h=>h&&typeof h=="object"&&!Array.isArray(h)&&h.key!==void 0&&h._placement!=="remote")){let h=Math.max(n.length,t.length);for(let p=0;p<h;p++){let b=p<n.length?n[p]:null,N=p<t.length?t[p]:null;if(N==null){if(b!=null){O(b,W(o));for(let S of r[p]??[])S.remove()}}else if(b==null){let S=q(N,o);if(S!=null){let i=null;for(let f=p+1;f<r.length;f++){let m=r[f]?.[0];if(m&&m.parentNode===e){i=m;break}}i?e.insertBefore(S,i):e.appendChild(S)}}else{let S=r[p]?.[0]??null;X(e,S,b,N,o)}}return[]}for(let h=0;h<n.length;h++){let p=n[h];if(!(p==null||typeof p=="boolean")&&Ie(p)===void 0)for(let b of r[h]??[])b.remove()}let u=new Map,a=0;for(let h=0;h<n.length;h++){let p=Ie(n[h]);p!==void 0&&u.set(p,{vnode:n[h],nodes:r[h]??[],index:a++})}let l=t.map(h=>Ie(h)),c=new Set(l);for(let h of[...u.keys()])if(!c.has(h)){let p=u.get(h);O(p.vnode,W(o));for(let b of p.nodes)b?.remove();u.delete(h)}let y=new Array(t.length).fill(null),v=-1,T=d&&d.parentNode===e?d:e.firstChild;for(let h=0;h<t.length;h++){let p=l[h],b=t[h],N=p!==void 0?u.get(p):void 0,S=b&&typeof b=="object"&&b._placement==="remote";if(N)if(N.nodes.length>0){if(N.index<v)for(let f of N.nodes)e.insertBefore(f,T);v=Math.max(v,N.index),X(e,N.nodes[0],N.vnode,b,o),y[h]=b._childNodes??N.nodes.filter(f=>f.parentNode===e),T=y[h][y[h].length-1]?.nextSibling??null}else if(S)de(N.vnode,b,o),y[h]=[];else{let i=X(e,null,N.vnode,b,o);y[h]=pn(i);for(let m of y[h])e.insertBefore(m,T);T=y[h][y[h].length-1]?.nextSibling??null}else if(S)ne(b,o),y[h]=[];else{let i=q(b,o);y[h]=pn(i);for(let m of y[h])e.insertBefore(m,T);T=y[h][y[h].length-1]?.nextSibling??null}}return y}function Dn(e,n){if(e===n)return!0;if(Array.isArray(e)&&Array.isArray(n)){if(e.length!==n.length)return!1;for(let t=0;t<e.length;t++)if(e[t]!==n[t])return!1;return!0}return e===n}function jn(e,n){if(e===n)return!0;if(!e||!n)return!1;let t=new Set([...Object.keys(e),...Object.keys(n)]);for(let o of t)if(o!=="key"){if(o==="children"){if(!Dn(e[o],n[o]))return!1}else if(e[o]!==n[o])return!1}return!0}var Q=U(),Ue="http://www.w3.org/2000/svg",Oe=new Set(["svg","path","circle","line","rect","text","g","polyline","polygon","ellipse","defs","use","clipPath","mask","linearGradient","radialGradient","stop","tspan"]);function q(e,n){let t=n.browser??Q;if(e==null||typeof e=="boolean")return null;if(typeof e=="string"||typeof e=="number")return t.createTextNode(String(e));if(Array.isArray(e))return $n(e,n);let o=e;if(o.type===F)return ne(o,n),null;if(o.type===B){let u=t.createDocumentFragment(),a=o.props?.children==null?[]:Array.isArray(o.props.children)?o.props.children:[o.props.children];for(let l of a){let c=q(l,n);c!=null&&u.appendChild(c)}return o._childNodes=Array.from(u.childNodes),u}if(typeof o.type=="function")return Fn(o.type,o.props,o,n);let r=o.type,d=Oe.has(r)?t.createElementNS(Ue,r):t.createElement(r);if(!d)return null;o.el=d;let s;for(let[u,a]of Object.entries(o.props??{}))u==="children"||u==="key"||u==="value"||u==="innerHTML"||mn(d,u,a);if("value"in(o.props??{})&&d instanceof HTMLSelectElement?s=o.props.value:"value"in(o.props??{})&&mn(d,"value",o.props.value),"innerHTML"in(o.props??{}))d.innerHTML=String(o.props.innerHTML??"");else{let u=We(o.props?.children);for(let a of u){let l=q(a,n);if(l!=null&&(d.appendChild(l),a&&typeof a=="object"&&typeof a.type=="function")){let c=a;c._parentNode||(c._parentNode=d,c._refNode=l)}}}return s!==void 0&&(d.value=String(s)),typeof o.props?.ref=="function"&&ke(o.props.ref,d,"mount",r),d}function qn(e){let n=e.ui;n&&typeof n.render=="function"&&n.render(["_wf_root"])}function He(e,n,t,o){let r=o.browser??Q,d;if(J(e)){if(d=Be(W(o),e),!d)return Ne(W(o),e,o).promise.then(()=>qn(o),()=>{}),null}else d=e;o.ui?.setMounting?.(!0);let s;try{s=d(n,o)}finally{o.ui?.endMounting?.()}if(typeof s!="function")throw new Error(`Component ${e.name||"anonymous"} must return a render function. Use (init_props, ctx) => (props) => VNode pattern.`);return t._render=s,s(n)}function Fn(e,n,t,o){let r=o.browser??Q;if(!t._id){let l=W(o);t._id=fe(l),l.idRegistry.set(t._id,t)}let d=Object.create(o);d.ui=Object.create(o.ui);let s=d.ui;s._selfId=t._id,s._selfVNode=t,t._ctxVersion=s._ctxVersion??0;let u;try{u=He(e,n,t,d)}catch(l){let c=o.ui?._errorHandler;c?(c(l),u=null):(console.error(`[weifuwu] Component render error in <${e.name||"anonymous"}> (id: ${t._id??"?"}, phase: mount)`,l),u=null)}if(u==null){if(t._child=null,d.ui?._errorHandler){let c=r.createComment("wf-empty");return t._refNode=c,c}return null}t._child=u;let a=q(u,d);return t._refNode||(t._refNode=a),a}function $n(e,n){let o=(n.browser??Q).createDocumentFragment();for(let r of e){let d=q(r,n);d!=null&&o.appendChild(d)}return o}function Bn(){let e=Q,n=e.byId("__wf_portal");if(!n){if(n=e.createElement("div"),!n)throw new Error("[ui-dom] portal container creation failed");n.id="__wf_portal",n.style.cssText="position:fixed;inset:0;pointer-events:none;z-index:9999",e.bodyAppend(n)}return n}function ne(e,n){let t=n.browser??Q,o=Bn(),r=t.createElement("div");r.style.pointerEvents="auto",o.appendChild(r),e._remoteEl=r;let d=ue(e.props?.children);e._child=d;for(let s of d){let u=q(s,n);u!=null&&r.appendChild(u)}}function de(e,n,t){let o=t.browser??Q,r=e?._remoteEl;if(n._remoteEl=r,!r){ne(n,t);return}let d=ue(n.props?.children),s=e._child||[];n._child=d,we(s,d);let u=ae(Array.from(r.childNodes),s);be(r,s,d,t,u,u[0]?.[0]??null)}function We(e){if(e==null)return[];if(!Array.isArray(e))return[e];let n=[];for(let t of e)Array.isArray(t)?n.push(...t):n.push(t);return n}function mn(e,n,t){if(n!=="ref")if(n==="class"||n==="className")e instanceof SVGElement?e.setAttribute("class",String(t??"")):e.className=String(t??"");else if(n==="style"&&typeof t=="object"&&t!==null){let o=e.style;for(let r of Object.keys(t)){let d=t[r];d!=null&&(r.startsWith("--")?o.setProperty(r,String(d)):o[r]=typeof d=="number"?d+"px":String(d))}}else n.startsWith("on")&&typeof t=="function"?e.addEventListener(n.slice(2).toLowerCase(),t):n==="draggable"?e.setAttribute("draggable",t?"true":"false"):n==="value"&&(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)?e.value=String(t??""):t===!0?e.setAttribute(n,""):t!=null&&t!==!1&&e.setAttribute(n,String(t))}function Kn(e,n,t){e.innerHTML="";let o=q(n,t);o instanceof Node&&e.appendChild(o)}function Gn(e){O(e,re())}function De(e){e.node=e.node?e.node.nextSibling:null}function Yn(e,n){e.node&&e.node.parentNode?e.node.parentNode.insertBefore(n,e.node):e.parent.appendChild(n)}function zn(e,n){e.node&&e.node.parentNode?(e.node.parentNode.replaceChild(n,e.node),De(e)):e.parent.appendChild(n)}async function ce(e,n,t){let o=n.browser??U();if(e==null||typeof e=="boolean")return null;if(typeof e=="string"||typeof e=="number"){let a=String(e);if(t.node&&t.node.nodeType===3)return t.node.textContent!==a&&(t.node.textContent=a),De(t),t.node;let l=o.createTextNode(a);return Yn(t,l),l}if(Array.isArray(e)){let a=null;for(let l of e){let c=await ce(l,n,t);c!=null&&!a&&(a=c)}return a}let r=e;if(r.type===F||r.type===B){let a=r.props?.children,l=a==null?[]:Array.isArray(a)?a:[a],c=null;for(let y of l){let v=await ce(y,n,t);v!=null&&!c&&(c=v)}return c}if(typeof r.type=="function")return Xn(r,n,t);let d=r.type,s=r.props??{},u;if(t.node&&t.node.nodeType===1&&t.node.tagName.toLowerCase()===d.toLowerCase()?(u=t.node,De(t)):(u=Oe.has(d)?o.createElementNS(Ue,d):o.createElement(d),zn(t,u)),r.el=u,Ve(u,null,s),!("innerHTML"in s)){let a={parent:u,node:u.firstChild},l=We(s.children);for(let c of l){let y=await ce(c,n,a);if(y!=null&&y.parentNode!==u&&u.appendChild(y),c&&typeof c=="object"&&typeof c.type=="function"){let v=c;v._parentNode||(v._parentNode=u,v._refNode=y)}}for(;a.node;){let c=a.node;a.node=c.nextSibling,c.parentNode?.removeChild(c)}}return"value"in s&&u instanceof HTMLSelectElement&&(u.value=String(s.value??"")),typeof s.ref=="function"&&s.ref(u),u}async function Xn(e,n,t){if(!e._id){let a=W(n);e._id=fe(a),a.idRegistry.set(e._id,e)}let o=Object.create(n);o.ui=Object.create(n.ui);let r=o.ui;r._selfId=e._id,r._selfVNode=e,e._ctxVersion=r._ctxVersion??0;let d=e.type,s;try{let a;J(d)?a=await $e(W(n),d,o):a=d;let l=a(e.props??{},o);if(typeof l!="function")throw new Error(`Component ${d.name||"anonymous"} must return a render function. Use (init_props, ctx) => (props) => VNode pattern.`);e._render=l,s=l(e.props??{})}catch(a){let l=n.ui?._errorHandler;l?(l(a),s=null):(console.error(`[weifuwu] Component hydration error in <${d.name||"anonymous"}> (id: ${e._id??"?"})`,a),s=null)}if(s==null)return e._child=null,null;e._child=s;let u=await ce(s,o,t);return e._refNode||(e._refNode=u),u}async function je(e,n,t){let o={parent:e,node:e.firstChild};for(await ce(n,t,o);o.node;){let r=o.node;o.node=r.nextSibling,r.parentNode?.removeChild(r)}}function Jn(e,n){let t=U(),o=typeof n.root=="string"?t.query(n.root):n.root;if(!o)throw new Error(`uiServe: root not found: ${n.root}`);let r=o,d=!!n.hydrate;d||(r.innerHTML="");let s=re(),u=new Set,a=new Set,l=new Map,c=!1,y=!1,v=[];function T(x){v.push(y),y=x}function h(){y=v.pop()??!1}let p={params:{},query:{}},b=new Map,N=globalThis.__DATA__??window.__DATA__;if(N&&typeof N=="object")for(let[x,M]of Object.entries(N))b.set(x,{value:M});p.data={async get(x,M){let k=b.get(x);if(k&&"value"in k)return k.value;if(k?.promise)return k.promise;if(!M)return;let R=Promise.resolve().then(()=>M()).then(I=>(b.set(x,{value:I}),I));return b.set(x,{promise:R}),R},set(x,M){b.set(x,{value:M})},has(x){return b.has(x)}};let S=!1;function i(){u.size>0&&!S&&(S=!0,queueMicrotask(()=>{S=!1;let x=[...u];u.clear(),x.length>0&&f(x)}))}function f(x){if(!c){c=!0;for(let M of x){let k=s.idRegistry.get(M);if(!k||!k._render)continue;p.ui._dirtySet?.delete(M);let R=k._child,I=k._render(k.props);if(k._child=I,R&&R._placement==="remote"||I&&I._placement==="remote"){R&&I?de(R,I,p):I?ne(I,p):R&&O(R,s);continue}if(!k._parentNode&&k._refNode){let D=k._refNode.parentNode;D&&(k._parentNode=D)}if(k._parentNode){let D=X(k._parentNode,k._refNode??null,R,I,p);D&&D!==k._refNode?k._refNode=D:D||(k._refNode=null)}}c=!1,i()}}let m=null;function g(){return m||(m=Ye(x=>p.ui.render(x))),m}p.browser=U(),p.__registry=s,p.ui=ln({ctx:p,renderByIds:f,getSelfId:x=>x?._selfId??p.ui?._selfId,dirtyBatch:u,dirtySet:a,mediaRegistry:l,popupTrackers:g().popupTrackers,scrollTrackers:g().scrollTrackers,schedulePopupRecompute:g().schedulePopupRecompute,ensurePopupListeners:g().ensurePopupListeners,destroyPopupListeners:g().destroyPopupListeners,isRendering:()=>c,isMounting:()=>y,setMounting:T,endMounting:h,registry:s}),pe(s,x=>{for(let M of[...l.keys()])if(M.startsWith(`media:${x}:`)||M===`bp:${x}`){let k=l.get(M);k?.mql&&k.handler&&k.mql.removeEventListener("change",k.handler),k?.mqls?.forEach(({mql:R,handler:I})=>R.removeEventListener("change",I)),l.delete(M)}g().cleanupTrackers(x)}),p.__rerender=()=>E(),p.app={navigate:x=>{e.mode==="hash"?t.setHash("#"+x):t.navigate(x),E()}};let w=null,C=!1,P=!1;function E(){P||(P=!0,queueMicrotask(()=>{P=!1,A()}))}async function A(){if(!C){C=!0;try{let x=e.getPath();if(p.route={path:x,params:p.params,query:p.query},!p.__state){let k=z(()=>{C||E()});p.__state=k;let R=p.ui.$;p.ui.$=function(){return this&&this._selfVNode?R.call(this):k}}let M=await e.execute(window.location,p,x);if(w==null){if(M){let k=d&&r.firstElementChild?(je(r,M,p),r.firstChild):q(M,p);k&&k.parentNode!==r&&r.appendChild(k)}}else X(r,r.firstChild,w,M,p);w=M}catch(x){if(console.error("[ui-dom] render error:",x),w==null){let M=t.createElement("div");M.className="ui-dom-error",M.textContent=`\u6E32\u67D3\u9519\u8BEF: ${x?.message??String(x)}`,r.appendChild(M)}}finally{C=!1}}}let V=()=>E();t.addEventListener("popstate",V);let H=()=>E();return e.mode==="hash"&&t.addEventListener("hashchange",H),E(),{get ctx(){return p},close(){t.removeEventListener("popstate",V),e.mode==="hash"&&t.removeEventListener("hashchange",H),w&&O(w,s),g().destroy(),s.idRegistry.clear(),r.innerHTML="",w=null}}}function Qn(e,n,t=400){let o=!1,r=()=>{o||(o=!0,e.removeEventListener("animationend",r),clearTimeout(d),n())};e.addEventListener("animationend",r);let d=setTimeout(r,t)}function te(e,n){return Object.assign(Object.create(e),n)}function Zn(e){let n={baseURL:e?.baseURL??"",headers:{"Content-Type":"application/json",...e?.headers}},t=e?.onRequest,o=e?.onResponse,r=e?.timeout??0;async function d(s,u,a,l){let c=n.baseURL+u,y={method:s,headers:{...n.headers,...l?.headers}},v=e?.token?.();v&&!y.headers.Authorization&&(y.headers.Authorization=`Bearer ${v}`);let T=r>0,h=!!l?.signal,p=null,b=null;(T||h)&&(p=new AbortController,y.signal=p.signal,T&&(b=setTimeout(()=>p.abort(new Error("Request timed out")),r)),h&&l.signal.addEventListener("abort",()=>p.abort())),a!==void 0&&s!=="GET"&&s!=="HEAD"&&(y.body=JSON.stringify(a));let N={url:c,init:y};t&&(N=t(N));try{let S=await fetch(N.url,N.init);if(o)return o(S);if(!S.ok){let m=await S.text().catch(()=>"");throw new qe(S.status,m||S.statusText)}let i=S.headers.get("content-length");if(S.status===204||i==="0")return;let f=(S.headers.get("content-type")||"").toLowerCase();return f.includes("application/json")||f.includes("json")?S.json():S.text()}finally{b&&clearTimeout(b)}}return s=>te(s,{api:{get:(a,l)=>d("GET",a,void 0,l),post:(a,l,c)=>d("POST",a,l,c),put:(a,l,c)=>d("PUT",a,l,c),patch:(a,l,c)=>d("PATCH",a,l,c),delete:(a,l)=>d("DELETE",a,void 0,l)}})}var qe=class extends Error{status;body;constructor(n,t){super(`API Error ${n}: ${t}`),this.name="ApiError",this.status=n,this.body=t}};function et(e){try{let n=e.split(".");if(n.length!==3)return null;let t=n[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(atob(t))}catch{return null}}function nt(e){let n=et(e);return n?.exp?n.exp*1e3-3e4<Date.now():!0}function tt(e){let n=e?.storage??localStorage,t=e?.tokenKey??"weifuwu_token",o=e?.userKey??"weifuwu_user",r=e?.refreshTokenKey??"weifuwu_refresh",d=e?.refreshEndpoint??"/api/auth/refresh";return s=>{let u=n.getItem(t),a=n.getItem(o),l={token:u,user:a?JSON.parse(a):null,get isLoggedIn(){return this.token!==null},login(c,y,v){l.token=c,l.user=y,n.setItem(t,c),n.setItem(o,JSON.stringify(y)),v&&n.setItem(r,v)},logout(){l.token=null,l.user=null,n.removeItem(t),n.removeItem(o),n.removeItem(r)},setUser(c){l.user=c,n.setItem(o,JSON.stringify(c))},async refresh(){let c=n.getItem(r);if(!c)return!1;try{let y=await fetch(d,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:c})});if(!y.ok)return l.logout(),!1;let v=await y.json();return l.token=v.token,n.setItem(t,v.token),v.refreshToken&&n.setItem(r,v.refreshToken),!0}catch{return!1}}};return u&&nt(u)&&l.refresh().catch(()=>{}),te(s,{auth:l})}}function ot(e={}){let n=e.url??"/ws",t=e.reconnectInterval??3e3,o=e.maxReconnect??10,r=e.pingInterval??3e4,d=e.pingTimeout??1e4;return s=>{let u=new Set,a=null,l=0,c=null,y=null,v=null,T=!1,h={isConnected:!1,onMessage:i=>(u.add(i),()=>{u.delete(i)}),send:i=>{a?.readyState===WebSocket.OPEN&&a.send(JSON.stringify(i))},_connect:p,close:()=>{T=!0,S(),a?.close(),a=null,h.isConnected=!1}};async function p(){if(!T)try{a=new WebSocket(n),a.onopen=()=>{h.isConnected=!0,l=0,b()},a.onmessage=i=>{try{let f=JSON.parse(i.data);for(let m of u)m(f)}catch{}N()},a.onclose=()=>{h.isConnected=!1,S(),!T&&l<o&&(l++,c=setTimeout(p,t*Math.min(l,5)))},a.onerror=()=>{a?.close()}}catch{T||(c=setTimeout(p,t))}}function b(){r<=0||(y=setInterval(()=>{a?.readyState===WebSocket.OPEN&&a.send(JSON.stringify({type:"ping"})),v=setTimeout(()=>{a?.close()},d)},r))}function N(){clearTimeout(v)}function S(){clearInterval(y),clearTimeout(v),clearTimeout(c)}return p(),te(s,{ws:h})}}function Ce(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}var rt=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);function st(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(Boolean).join(" "):e&&typeof e=="object"?Object.entries(e).filter(([,n])=>n).map(([n])=>n).join(" "):""}function it(e){return typeof e=="string"?e:e&&typeof e=="object"?Object.entries(e).filter(([,n])=>n!=null).map(([n,t])=>`${n}:${typeof t=="number"?t+"px":String(t)}`).join(";"):""}function yn(e,n){let t=new Set,o={$:()=>z(()=>{}),dirty:()=>{},render:()=>{},selfId:s=>{if(t.has(s))throw new Error(`[weifuwu] Duplicate component ID: "${s}"`);t.add(s)},useMedia:()=>{},useBreakpoint:()=>{},usePopupPosition:()=>({top:0,left:0,refresh:()=>{}}),useHoverCapable:()=>!1,useVisualViewport:()=>({height:0,offsetTop:0,keyboardOpen:!1}),useLongPress:()=>({}),useInView:()=>({isIn:!1,ready:!1,observe:()=>{},refresh:()=>{},disconnect:()=>{}}),useScrollPosition:()=>({y:0,refresh:()=>{}}),useStableRef:s=>u=>{u&&s?.(u)},useGlobalKey:()=>()=>{},useReducedMotion:()=>!1,useAnimationEnd:()=>()=>{},useTween:s=>{let u={value:s,reset:a=>{u.value=a}};return u},useDrag:()=>({onPointerDown:()=>{}}),useDragDrop:()=>({dropProps:{},dragProps:{}}),useControlled:s=>({value:s.value,setValue:u=>{s.onChange?.(u)},controlled:s.value!==void 0}),useControlledInput:s=>({value:s.value,setValue:u=>{s.onChange?.(u)},controlled:s.value!==void 0,keyword:"",setKeyword:()=>{},selectedLabel:"",setSelectedLabel:()=>{}}),useOpen:s=>({get open(){return!!s.open},setOpen:u=>{s.onOpenChange?.(u)},triggerProps:{}}),useAsync:()=>({data:void 0,loading:!0,error:void 0,reload:()=>{}}),usePopup:()=>({open:!1,setOpen:()=>{},wrapProps:{},portal:()=>null,refresh:()=>{}}),usePresence:()=>({phase:"closed",ref:()=>{},sync:s=>s?"open":"closed"}),useDialog:()=>({phase:"closed",rootRef:()=>{},panelRef:()=>{},sync:s=>s?"open":"closed"}),useChat:()=>({messages:[],input:"",streaming:!1,error:null,usage:null,step:null,send:()=>{},stop:()=>{},retry:()=>{},clear:()=>{},approve:async()=>{},dispose:()=>{}})},r={activeElement:()=>null,byId:()=>null,query:()=>null,queryAll:()=>null,createElement:()=>null,createElementNS:()=>null,createDocumentFragment:()=>null,createComment:()=>null,createTextNode:()=>null,addEventListener:()=>{},removeEventListener:()=>{},scrollTo:()=>{},matchMedia:()=>null,visualViewport:()=>null,scrollingElement:()=>null,bodyElement:()=>null,bodyAppend:()=>{},bodyRemove:()=>{},clearBody:()=>{},event:()=>new Event("wf-ssr"),dispatchEvent:()=>!1,navigate:()=>{},createTreeWalker:()=>null,copyText:async()=>!1,execCommand:()=>!1,selectionText:()=>null,getSelection:()=>null,queryCommandState:()=>!1,queryCommandValue:()=>"",viewportHeight:()=>0,viewportWidth:()=>0,pathname:()=>"",scrollTop:()=>0,hash:()=>"",setHash:()=>{},timeout:()=>0,rootElement:()=>null,storageGet:()=>null,storageSet:()=>{}},d=Object.create(e??{});return d.ui=o,d.browser=r,d.data={async get(s,u){if(n.has(s))return n.get(s);if(!u)return;let a=await u();return n.set(s,a),a},set(s,u){n.set(s,u)},has(s){return n.has(s)}},d}async function Z(e,n){if(e==null||typeof e=="boolean")return"";if(typeof e=="string"||typeof e=="number")return Ce(String(e));if(Array.isArray(e)){let l="";for(let c of e)l+=await Z(c,n);return l}let t=e;if(t.type===F||t.type===B)return Z(t.props?.children,n);if(typeof t.type=="function"){let l;if(J(t.type)){if(l=await t.type(n),typeof l!="function")throw new Error(`asyncComponent factory <${t.type.name||"anonymous"}> must return a Component (initProps, ctx) => (props) => VNode.`)}else l=t.type;let c=Object.create(n),y=l(t.props??{},c);if(typeof y!="function")throw new Error(`Component ${t.type.name||"anonymous"} must return a render function. Use (init_props, ctx) => (props) => VNode pattern.`);return Z(y(t.props??{}),c)}let o=t.type,r=t.props??{},d=[],s;for(let[l,c]of Object.entries(r))if(!(l==="children"||l==="key")&&l!=="ref"&&!(l.startsWith("on")&&typeof c=="function")){if(l==="innerHTML"){s=String(c??"");continue}if(l==="class"||l==="className"){let y=st(c);y&&d.push(` class="${Ce(y)}"`);continue}if(l==="style"&&c&&typeof c=="object"){d.push(` style="${Ce(it(c))}"`);continue}if(c===!0){d.push(` ${l}`);continue}c===!1||c==null||d.push(` ${l}="${Ce(String(c))}"`)}let u=d.join("");if(rt.has(o))return`<${o}${u}>`;if(s!==void 0)return`<${o}${u}>${s}</${o}>`;let a=await Z(r.children,n);return`<${o}${u}>${a}</${o}>`}async function lt(e,n,t,o={}){let r=o.data??new Map,d=yn(t,r);return await Z({type:e,props:n??{},key:void 0},d)}function gn(e){return`<script>window.__DATA__=${JSON.stringify(Object.fromEntries(e)).replace(/</g,"\\u003c")};<\/script>`}async function at(e,n){let t=new Map,r=yn({params:{},query:{}},t),d=n.url.split("?")[0].split("#")[0],s=e.match(d);r.params=s.params,r.query=Object.fromEntries(new URLSearchParams(n.url.split("?")[1]??""));let u=new URL(n.url.startsWith("http")?n.url:`http://localhost${n.url.startsWith("/")?n.url:"/"+n.url}`),a=await e.execute(u,r,d),l=await Z(a,r),c=gn(t),y=s.title??n.title??"",v=n.rootId??"root",T=`<!DOCTYPE html>
7
7
  <html lang="${n.lang??"zh-CN"}">
8
8
  <head>
9
9
  <meta charset="UTF-8">
10
10
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
11
- ${g?`<title>${g}</title>`:""}
11
+ ${y?`<title>${y}</title>`:""}
12
12
  </head>
13
13
  <body>
14
- <div id="${w}">${l}</div>
15
- ${f}
14
+ <div id="${v}">${l}</div>
15
+ ${c}
16
16
  <script src="/app.js"><\/script>
17
17
  </body>
18
- </html>`;return{html:l,dataScript:f,page:T}}export{$ as Fragment,j as Portal,Ce as UIRouter,Bn as animateOut,Gn as api,Nn as asyncComponent,Jn as auth,jn as callRefCleanup,Ue as createClientBrowser,ke as createPortal,G as createReactiveState,Mn as h,Le as hydrateVNode,z as isAsyncComponent,_e as jsx,Sn as jsxDEV,Rn as jsxs,Dn as mountVNode,Y as patchValue,dn as serializeData,tt as ssrPage,nt as ssrToString,Kn as uiServe,Xn as ws};
18
+ </html>`;return{html:l,dataScript:c,page:T}}export{B as Fragment,F as Portal,_e as UIRouter,Qn as animateOut,Zn as api,In as asyncComponent,tt as auth,Gn as callRefCleanup,U as createClientBrowser,Le as createPortal,z as createReactiveState,Un as h,je as hydrateVNode,J as isAsyncComponent,Ae as jsx,Hn as jsxDEV,Vn as jsxs,Kn as mountVNode,X as patchValue,gn as serializeData,at as ssrPage,lt as ssrToString,Jn as uiServe,ot as ws};
@@ -9,17 +9,6 @@ export interface FixedPos {
9
9
  left: number;
10
10
  }
11
11
  export type Placement = 'top' | 'bottom' | 'left' | 'right';
12
- /**
13
- * 根据触发元素 rect 和方向计算弹出层的 fixed 坐标(视口坐标)
14
- *
15
- * 与 computeFixedPos 等价,但直接接收 rect,方便在 scroll/resize
16
- * 监听中复用(配合 ctx.ui.usePopupPosition)。
17
- *
18
- * @param rect 触发元素的 getBoundingClientRect()
19
- * @param placement 弹出方向
20
- * @param gap 间距(px),默认 6
21
- * @param center 是否居中于触发元素,默认 true
22
- */
23
12
  export declare function computeFixedPosRect(rect: DOMRect, placement?: Placement, gap?: number, center?: boolean): FixedPos;
24
13
  /**
25
14
  * 根据触发元素和方向计算弹出层的 fixed 坐标
@@ -178,11 +178,45 @@ export interface BrowserEnv {
178
178
  byId(id: string): HTMLElement | null;
179
179
  /** CSS 选择器查询元素 */
180
180
  query(sel: string): HTMLElement | null;
181
+ /** CSS 选择器批量查询 */
182
+ queryAll(sel: string): NodeListOf<Element> | null;
181
183
  /** 创建元素 */
182
184
  createElement<K extends keyof HTMLElementTagNameMap>(tag: K): HTMLElementTagNameMap[K] | null;
185
+ /** 创建 SVG/命名空间元素 */
186
+ createElementNS(ns: string, tag: string): Element | null;
187
+ /** 创建文档片段 */
188
+ createDocumentFragment(): DocumentFragment | null;
189
+ /** 创建注释节点 */
190
+ createComment(text: string): Comment | null;
191
+ /** 创建文本节点 */
192
+ createTextNode(text: string): Text | null;
193
+ /** 全局事件监听(scroll/resize/popstate 等) */
194
+ addEventListener(type: string, fn: (e: any) => void, options?: any): void;
195
+ /** 全局事件移除 */
196
+ removeEventListener(type: string, fn: (e: any) => void, options?: any): void;
197
+ /** 滚动到指定 y(window.scrollTo) */
198
+ scrollTo(y: number): void;
199
+ /** 媒体查询(组件 useMedia 入口) */
200
+ matchMedia(query: string): MediaQueryList | null;
201
+ /** 视觉视口(键盘弹起感知——完整对象,含 addEventListener 监听) */
202
+ visualViewport(): VisualViewport | null;
203
+ /** scrollingElement(滚动量读取优先源) */
204
+ scrollingElement(): Element | null;
205
+ /** body 引用(容器/断言) */
206
+ bodyElement(): HTMLElement | null;
183
207
  /** body 追加/移除 */
184
208
  bodyAppend(el: Node): void;
185
209
  bodyRemove(el: Node): void;
210
+ /** 清空 body(测试清理 / 命令式重置) */
211
+ clearBody(): void;
212
+ /** 创建浏览器事件(Event/KeyboardEvent/PointerEvent——按 init 推断构造器) */
213
+ event(type: string, init?: any): Event;
214
+ /** 派发事件到目标(测试/命令式触发) */
215
+ dispatchEvent(target: EventTarget, evt: Event): boolean;
216
+ /** 编程式导航(history.pushState + popstate——路由驱动) */
217
+ navigate(url: string): void;
218
+ /** 文本遍历(TreeWalker) */
219
+ createTreeWalker(root: Node, whatToShow?: number): TreeWalker | null;
186
220
  /** 复制文本(clipboard API + execCommand 降级,统一组件重复实现) */
187
221
  copyText(text: string): Promise<boolean>;
188
222
  /** execCommand(富文本编辑器) */
@@ -197,6 +231,10 @@ export interface BrowserEnv {
197
231
  queryCommandValue(cmd: string): string;
198
232
  /** 视口高度 */
199
233
  viewportHeight(): number;
234
+ /** 视口宽度 */
235
+ viewportWidth(): number;
236
+ /** 当前位置路径(location.pathname) */
237
+ pathname(): string;
200
238
  /** 滚动量(scrollingElement 优先) */
201
239
  scrollTop(): number;
202
240
  /** location.hash */
@@ -1,13 +1,68 @@
1
- # ui-dom — 前端路由(UIRouter + uiServe,试验性)
1
+ # ui-dom — 前端运行时(UIRouter + uiServe + SSR/hydration)
2
2
 
3
- > **试验性**:`src/ui-dom/` 是定稿架构(`design/ui-architecture.md`)的落地——
4
- > **UIRouter(纯路由)+ uiServe(渲染运行时)**,复用 `weifuwu/components`
5
- > VNode 契约共享,组件零修改)。渲染算法复制自 client(局部 registry 隔离,
6
- > 不与 createApp 交叉)。当前未随 npm 包发布,源码直用。
3
+ > **weifuwu 前端唯一运行时**(`weifuwu/ui-dom`,随 npm 包发布):
4
+ > **UIRouter(纯路由 + ctx 注入链)+ uiServe(渲染运行时)+ ssrPage/hydration**,
5
+ > 复用 `weifuwu/components`(VNode 契约唯一来源,组件零修改)。
6
+ > 已取代 `weifuwu/client`(createApp/router 已删除)。
7
7
  >
8
8
  > 概念对齐:**req = window.location**,**res = VNode**(数据结构),
9
9
  > **uiServe = VDOM**(落地机制),**params/query 在 ctx**(对齐后端 `ctx.params`)。
10
10
 
11
+ ## 为什么是 ui-dom(开发者价值)
12
+
13
+ ### 心智模型统一:一套 API 贯穿两端,无需「两套前端」
14
+
15
+ ```
16
+ 后端: Request → [Middleware → ctx.field] → Handler → Response
17
+ 前端: window.location → [UIMiddleware → ctx.field] → Handler → VNode
18
+ ```
19
+
20
+ - **req/res 契约同构**:`UIRequest = window.location`(原生对象,不包装)对齐后端 `Request`;`UIResponse = VNode` 对齐 `Response`。后端开发者迁移到前端,中间件思维直接复用(`app.use(mw)` 与 `router.use(mw)` 累积类型同构)。
21
+ - **SSR 不是另一套代码**:同一份 `router.ts`(两端共享),`ssrPage(router, { url })` 服务端直接跑,`uiServe(router, { root, hydrate: true })` 客户端收养。`ctx.data.get(key)` 一个 API 三场景自动适配(SSR 真 fetch → 序列化进 `__DATA__` → hydration 种子命中 → SPA 未命中触发 fetcher)——**开发者不需要理解「首屏/水合/客户端渲染」的区别**。
22
+
23
+ ### 两阶段组件模型:从 hooks 心智负担中解脱
24
+
25
+ ```tsx
26
+ const Counter = (initProps, ctx) => {
27
+ const $ = ctx.ui.$()
28
+ $.count = initProps.initial ?? 0 // mount:只执行一次
29
+ return (props) =>
30
+ h('button', { onClick: () => $.count += props.step }, $.count) // render
31
+ }
32
+ ```
33
+
34
+ - **没有 hooks 规则、没有依赖数组、没有闭包陷阱**。外层 = 初始化(一次),内层 = 渲染(每次变化)。`$` Proxy 赋值自动触发组件级重渲染——**状态更新就是赋值**,不需要思考 `useState`/`useEffect`/`useMemo` 三件套的触发时机。
35
+ - **状态驱动渲染**:`$.x = val` → dirty → 局部 patch。组件库手动优先(行为可预测、测试简单),业务层自动优先(省样板、不易遗漏)——按场景选模式而非被迫统一。
36
+
37
+ ### 框架即纪律:浏览器环境抽象把常见坑变成编译期/审计期错误
38
+
39
+ - **`ctx.browser` 唯一入口**:复制/查询/滚动/存储/主题/定时器/媒体查询/事件监听全部经 BrowserEnv(组件侧 46 处迁移清零 + 测试侧 ~300 处对齐,SSR shim 三态同构)。开发者不需要记「SSR 里 `window.innerWidth` 会崩」这类环境知识——**框架替他们承担**。
40
+ - **诚实裁剪**:不支持的能力明确抛 `ProtocolError('unsupported')`——确定性失败,绝不静默降级。
41
+
42
+ ### 零依赖 + 确定性:可审计、可测试、可读的运行时
43
+
44
+ - **零 npm 运行时依赖**(对比 React + react-dom + react-router + 状态库 + SSR 工具 5+ 依赖)。
45
+ - **自研 VDOM/diff**(keyed children、style diff、CSS 变量、Portal、hydration 游标收养)——每个算法都有对应测试与纪律条目(真实事故沉淀)。**读源码即可完全理解框架行为**。
46
+ - **零构建步骤**:`weifuwu/dev` loader + `ctx.ui.js/css` 动态编译,服务端直接跑 `.tsx`,改组件刷新即生效。
47
+
48
+ ### 弹层/浮层体系:最难的 UI 类别变成复用的原语
49
+
50
+ `ctx.ui.usePopup()` 一个组合器覆盖:portal 渲染、fixed 定位 + 视口夹紧、锚点变化自动重算、外部点击/Escape 关闭、el-null 微任务重试、ref 稳定化。**开发者不需要再写任何弹层脚手架**——这是传统前端最常重复造轮子的地方。弹窗纪律(portal 必须、z-index token、exit 动画成对)由审计测试强制。
51
+
52
+ ### 对贡献者的价值:纪律 = 事故沉淀
53
+
54
+ AGENTS.md 每条纪律对应真实事故(JSONViewer selfId 错位、AutoComplete 焦点丢失、TreeSelect 0 rect、Kanban draggable 空字符串解析 false)——新贡献者站在「踩过坑」的肩膀上。分层清晰(UIRouter 纯路由 → uiServe 装配点 → ctx.browser 环境边界 → components 消费层),改动边界由架构约束,协议层改动 TDD 先行 + 真实库验证(CS-04/CS-05)。
55
+
56
+ | 维度 | 价值 |
57
+ |------|------|
58
+ | **上手** | 两阶段组件 + 赋值即渲染——无 hooks/依赖数组心智负担 |
59
+ | **后端互迁** | req/res/中间件契约同构,SSR 透明,一份 router 两端共享 |
60
+ | **可靠性** | 确定性失败、诚实裁剪、环境边界、测试侧同构 |
61
+ | **效率** | 弹层/数据管道/事件原语全覆盖——不重复造轮子 |
62
+ | **可维护** | 零依赖可审计、纪律沉淀事故教训、构建可选 |
63
+
64
+ > 一句话:ui-dom 不是「又一个 React」——它是把 weifuwu 后端中间件生态的确定性、可测试性和纪律性,原样移植到了前端。开发者得到的是一个行为可预测、失败可预期、源码可读懂的运行时。
65
+
11
66
  ## 快速开始
12
67
 
13
68
  ```tsx
@@ -62,12 +117,12 @@ handler 只产 VNode,落地由 serve 决定——SSR 与 SPA 是两种落地
62
117
 
63
118
  ### components 复用(零修改)
64
119
 
65
- VNode 契约与 client 共享(Fragment/Portal symbol 同一份)——components 产的 VNode
66
- 直接被 ui-dom 渲染器识别。渲染算法(render/diff/createUi 19 原语)复制到 ui-dom
67
- **registry/popup-tracker/dirty 集合局部实例**(不与 createApp 交叉)。
120
+ VNode 契约以 ui-dom 为唯一来源(Fragment/Portal symbol 由 ui-dom 自持)——components 产的 VNode
121
+ 直接被 ui-dom 渲染器识别。渲染算法(render/diff/createUi 原语)在 ui-dom 内自主实现,
122
+ **registry/popup-tracker/dirty 集合局部实例**(serve 每实例隔离)。
68
123
 
69
- 命令式工厂(toast/confirm/notification)复制到 ui-dom(`src/ui-dom/Toast.ts` 等):
70
- components import client 的 mountVNode(模块级 registry)会注册错——ui-dom 版用局部。
124
+ 命令式工厂(toast/confirm/notification)位于 ui-dom(`src/ui-dom/Toast.ts` 等):
125
+ components 消费端 import `weifuwu/ui-dom`(构建外部化,共享同一模块实例)。
71
126
 
72
127
  ### $ 响应式(两层)
73
128
 
@@ -100,7 +155,7 @@ uiServe(app, { root: '#root', hydrate: true })
100
155
  | `ctx.params` / `ctx.query` | 路由参数 / URL query(顶层,对齐后端) |
101
156
  | `ctx.data.get/set/has` | 数据管道(缓存 + in-flight 合并 + `__DATA__` 种子) |
102
157
  | `ctx.ui.*` | 19 原语(`$`/`dirty`/`render`/`usePopup`/`useChat`/`useInView`…) |
103
- | `ctx.browser.*` | 环境抽象(复制自 client) |
158
+ | `ctx.browser.*` | 环境抽象(window/document 唯一入口,SSR shim 同构) |
104
159
  | `ctx.toast` / `ctx.confirm` / `ctx.notification` | 命令式注入(`app.use(toast())` 等) |
105
160
 
106
161
  ## demo
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "weifuwu",
3
3
  "type": "module",
4
- "version": "0.72.0",
4
+ "version": "0.73.0",
5
5
  "description": "AI SaaS framework — (req, ctx) => Response",
6
6
  "exports": {
7
7
  ".": {