reasonix 0.50.0 → 0.51.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/dashboard/dist/app.css +1 -1
- package/dashboard/dist/app.js +24 -22
- package/dashboard/dist/app.js.map +1 -1
- package/dist/cli/{acp-6B25WIFF.js → acp-XEUHGG7X.js} +34 -31
- package/dist/cli/acp-XEUHGG7X.js.map +1 -0
- package/dist/cli/chat-NJ2Q5KHG.js +50 -0
- package/dist/cli/{chunk-OPGWCKKU.js → chunk-2HVTBFCI.js} +3 -3
- package/dist/cli/{chunk-AJIZ5KFK.js → chunk-2WUEAI2I.js} +3 -3
- package/dist/cli/{chunk-I4Q3QT4W.js → chunk-36BM7INR.js} +2 -2
- package/dist/cli/{chunk-3RNFYDDM.js → chunk-3BTK5BHI.js} +11 -7
- package/dist/cli/chunk-3BTK5BHI.js.map +1 -0
- package/dist/cli/{chunk-GMSAB2TC.js → chunk-3YRTIWFX.js} +2 -2
- package/dist/cli/{chunk-NLRC3DWQ.js → chunk-544J4PXD.js} +5 -5
- package/dist/cli/{chunk-7WITYWKN.js → chunk-5AIDYVH2.js} +2 -2
- package/dist/cli/{chunk-ALCOQP6R.js → chunk-5BBC6YMV.js} +5 -5
- package/dist/cli/{chunk-S4XVGLRW.js → chunk-6UNHNVJR.js} +72 -5
- package/dist/cli/chunk-6UNHNVJR.js.map +1 -0
- package/dist/cli/{chunk-IK6WWRIX.js → chunk-6XWXIVQ3.js} +38 -22
- package/dist/cli/chunk-6XWXIVQ3.js.map +1 -0
- package/dist/cli/{chunk-AAHB2PFX.js → chunk-7YB26OQO.js} +4 -4
- package/dist/cli/chunk-7YB26OQO.js.map +1 -0
- package/dist/cli/{chunk-MXWPAPZW.js → chunk-A5PBEIJ7.js} +53 -10
- package/dist/cli/chunk-A5PBEIJ7.js.map +1 -0
- package/dist/cli/{chunk-FQSQFCBI.js → chunk-BA5R6BAE.js} +2 -2
- package/dist/cli/{chunk-XWPZHWC2.js → chunk-BM6BBFAV.js} +2 -2
- package/dist/cli/{chunk-CAGKEGNE.js → chunk-BOWSNGQC.js} +52 -140
- package/dist/cli/chunk-BOWSNGQC.js.map +1 -0
- package/dist/cli/{chunk-EZ57UEZQ.js → chunk-C2MRSJTV.js} +2 -2
- package/dist/cli/{chunk-PYIZZAVQ.js → chunk-DVD67FXQ.js} +1716 -4
- package/dist/cli/chunk-DVD67FXQ.js.map +1 -0
- package/dist/cli/{chunk-ZAXMJANP.js → chunk-EAMXOWUW.js} +3 -3
- package/dist/cli/{chunk-TX652NBA.js → chunk-EWVFGYT6.js} +2 -2
- package/dist/cli/{chunk-IBRTU5WO.js → chunk-FP7IOWBQ.js} +18 -1182
- package/dist/cli/chunk-FP7IOWBQ.js.map +1 -0
- package/dist/cli/{chunk-I6FBSTTR.js → chunk-HGK57NBN.js} +9 -353
- package/dist/cli/chunk-HGK57NBN.js.map +1 -0
- package/dist/cli/chunk-JHWQDJZA.js +80 -0
- package/dist/cli/chunk-JHWQDJZA.js.map +1 -0
- package/dist/cli/{chunk-X2BQZQEE.js → chunk-K3QJ3GKI.js} +3 -3
- package/dist/cli/{chunk-GPUH2BNM.js → chunk-K4YQFULP.js} +612 -254
- package/dist/cli/chunk-K4YQFULP.js.map +1 -0
- package/dist/cli/chunk-L3VPEESB.js +31 -0
- package/dist/cli/chunk-L3VPEESB.js.map +1 -0
- package/dist/cli/{chunk-ENFBF6HI.js → chunk-N4SEBLU4.js} +383 -5
- package/dist/cli/chunk-N4SEBLU4.js.map +1 -0
- package/dist/cli/chunk-NRROJXXT.js +879 -0
- package/dist/cli/chunk-NRROJXXT.js.map +1 -0
- package/dist/cli/{chunk-3KRRTLC5.js → chunk-R6KIHEF3.js} +1619 -1036
- package/dist/cli/chunk-R6KIHEF3.js.map +1 -0
- package/dist/cli/{chunk-VVMY4M7J.js → chunk-SBHF5NWD.js} +27 -4
- package/dist/cli/chunk-SBHF5NWD.js.map +1 -0
- package/dist/cli/{chunk-OWA42BKS.js → chunk-SXSAWOB7.js} +14 -14
- package/dist/cli/{chunk-6IUMTRFP.js → chunk-UMZ6KHTS.js} +2 -2
- package/dist/cli/{chunk-7X4JJOO7.js → chunk-UO6E7FN3.js} +69 -5
- package/dist/cli/{chunk-7X4JJOO7.js.map → chunk-UO6E7FN3.js.map} +1 -1
- package/dist/cli/{chunk-3ZZXQ3CZ.js → chunk-UPW544V3.js} +2 -2
- package/dist/cli/{chunk-XJZWMU5P.js → chunk-WPOKBW5E.js} +2 -2
- package/dist/cli/{chunk-WSBFVOCO.js → chunk-Z3MKG7MQ.js} +2 -2
- package/dist/cli/{code-TBK2TASK.js → code-BMXLBC7D.js} +37 -36
- package/dist/cli/{code-TBK2TASK.js.map → code-BMXLBC7D.js.map} +1 -1
- package/dist/cli/{commands-NXTKSQTN.js → commands-E4RZXMF6.js} +5 -5
- package/dist/cli/{commit-IR5SPP7A.js → commit-KSRQ64IL.js} +3 -3
- package/dist/cli/{config-XK5WQGTS.js → config-QNDONOTU.js} +4 -2
- package/dist/cli/{desktop-5NTQBADL.js → desktop-H3ZHIMDA.js} +83 -37
- package/dist/cli/desktop-H3ZHIMDA.js.map +1 -0
- package/dist/cli/{diff-JNYX5BSZ.js → diff-I4PYI43W.js} +9 -9
- package/dist/cli/{doctor-IKYLUFXX.js → doctor-Y2E4MY2F.js} +12 -12
- package/dist/cli/{events-HSC57ONU.js → events-47HOT7ZA.js} +5 -5
- package/dist/cli/find-in-code-YLEIK5FK.js +145 -0
- package/dist/cli/find-in-code-YLEIK5FK.js.map +1 -0
- package/dist/cli/index.js +95 -44
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{mcp-BDJJWOCD.js → mcp-76DK63ZB.js} +3 -3
- package/dist/cli/{mcp-browse-NJRZDI6V.js → mcp-browse-SDNUGO74.js} +3 -3
- package/dist/cli/{mcp-inspect-Y62NWZQL.js → mcp-inspect-BL5DEO5M.js} +3 -3
- package/dist/cli/{prompt-UTOIFUQC.js → prompt-JLATI3P7.js} +5 -5
- package/dist/cli/{prune-sessions-UCUD4XAP.js → prune-sessions-WHZDFUKD.js} +4 -4
- package/dist/cli/{replay-VVIN64MN.js → replay-MHXS7C7Z.js} +10 -10
- package/dist/cli/{run-76OBDZFB.js → run-SXNCPRJE.js} +22 -22
- package/dist/cli/{server-SZZDKTH2.js → server-GEHOE6CO.js} +61 -35
- package/dist/cli/server-GEHOE6CO.js.map +1 -0
- package/dist/cli/{sessions-FZTGRCM5.js → sessions-EPBFYISL.js} +18 -18
- package/dist/cli/{setup-4UNENGOE.js → setup-IW2XR5XI.js} +8 -7
- package/dist/cli/setup-IW2XR5XI.js.map +1 -0
- package/dist/cli/{stats-F4NDOD7D.js → stats-4WB4XHBP.js} +6 -6
- package/dist/cli/symbols-UQ274IOB.js +167 -0
- package/dist/cli/symbols-UQ274IOB.js.map +1 -0
- package/dist/cli/version-4SP3DLLH.js +33 -0
- package/dist/index.d.ts +25 -6
- package/dist/index.js +2700 -578
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
- package/scripts/postinstall.mjs +10 -0
- package/dist/cli/acp-6B25WIFF.js.map +0 -1
- package/dist/cli/chat-7WASPB4O.js +0 -50
- package/dist/cli/chunk-3KRRTLC5.js.map +0 -1
- package/dist/cli/chunk-3RNFYDDM.js.map +0 -1
- package/dist/cli/chunk-AAHB2PFX.js.map +0 -1
- package/dist/cli/chunk-CAGKEGNE.js.map +0 -1
- package/dist/cli/chunk-ENFBF6HI.js.map +0 -1
- package/dist/cli/chunk-GPUH2BNM.js.map +0 -1
- package/dist/cli/chunk-I6FBSTTR.js.map +0 -1
- package/dist/cli/chunk-IBRTU5WO.js.map +0 -1
- package/dist/cli/chunk-IK6WWRIX.js.map +0 -1
- package/dist/cli/chunk-MXWPAPZW.js.map +0 -1
- package/dist/cli/chunk-PYIZZAVQ.js.map +0 -1
- package/dist/cli/chunk-S4XVGLRW.js.map +0 -1
- package/dist/cli/chunk-VVMY4M7J.js.map +0 -1
- package/dist/cli/desktop-5NTQBADL.js.map +0 -1
- package/dist/cli/server-SZZDKTH2.js.map +0 -1
- package/dist/cli/setup-4UNENGOE.js.map +0 -1
- package/dist/cli/version-LUVTWHLL.js +0 -33
- /package/dist/cli/{chat-7WASPB4O.js.map → chat-NJ2Q5KHG.js.map} +0 -0
- /package/dist/cli/{chunk-OPGWCKKU.js.map → chunk-2HVTBFCI.js.map} +0 -0
- /package/dist/cli/{chunk-AJIZ5KFK.js.map → chunk-2WUEAI2I.js.map} +0 -0
- /package/dist/cli/{chunk-I4Q3QT4W.js.map → chunk-36BM7INR.js.map} +0 -0
- /package/dist/cli/{chunk-GMSAB2TC.js.map → chunk-3YRTIWFX.js.map} +0 -0
- /package/dist/cli/{chunk-NLRC3DWQ.js.map → chunk-544J4PXD.js.map} +0 -0
- /package/dist/cli/{chunk-7WITYWKN.js.map → chunk-5AIDYVH2.js.map} +0 -0
- /package/dist/cli/{chunk-ALCOQP6R.js.map → chunk-5BBC6YMV.js.map} +0 -0
- /package/dist/cli/{chunk-FQSQFCBI.js.map → chunk-BA5R6BAE.js.map} +0 -0
- /package/dist/cli/{chunk-XWPZHWC2.js.map → chunk-BM6BBFAV.js.map} +0 -0
- /package/dist/cli/{chunk-EZ57UEZQ.js.map → chunk-C2MRSJTV.js.map} +0 -0
- /package/dist/cli/{chunk-ZAXMJANP.js.map → chunk-EAMXOWUW.js.map} +0 -0
- /package/dist/cli/{chunk-TX652NBA.js.map → chunk-EWVFGYT6.js.map} +0 -0
- /package/dist/cli/{chunk-X2BQZQEE.js.map → chunk-K3QJ3GKI.js.map} +0 -0
- /package/dist/cli/{chunk-OWA42BKS.js.map → chunk-SXSAWOB7.js.map} +0 -0
- /package/dist/cli/{chunk-6IUMTRFP.js.map → chunk-UMZ6KHTS.js.map} +0 -0
- /package/dist/cli/{chunk-3ZZXQ3CZ.js.map → chunk-UPW544V3.js.map} +0 -0
- /package/dist/cli/{chunk-XJZWMU5P.js.map → chunk-WPOKBW5E.js.map} +0 -0
- /package/dist/cli/{chunk-WSBFVOCO.js.map → chunk-Z3MKG7MQ.js.map} +0 -0
- /package/dist/cli/{commands-NXTKSQTN.js.map → commands-E4RZXMF6.js.map} +0 -0
- /package/dist/cli/{commit-IR5SPP7A.js.map → commit-KSRQ64IL.js.map} +0 -0
- /package/dist/cli/{config-XK5WQGTS.js.map → config-QNDONOTU.js.map} +0 -0
- /package/dist/cli/{diff-JNYX5BSZ.js.map → diff-I4PYI43W.js.map} +0 -0
- /package/dist/cli/{doctor-IKYLUFXX.js.map → doctor-Y2E4MY2F.js.map} +0 -0
- /package/dist/cli/{events-HSC57ONU.js.map → events-47HOT7ZA.js.map} +0 -0
- /package/dist/cli/{mcp-BDJJWOCD.js.map → mcp-76DK63ZB.js.map} +0 -0
- /package/dist/cli/{mcp-browse-NJRZDI6V.js.map → mcp-browse-SDNUGO74.js.map} +0 -0
- /package/dist/cli/{mcp-inspect-Y62NWZQL.js.map → mcp-inspect-BL5DEO5M.js.map} +0 -0
- /package/dist/cli/{prompt-UTOIFUQC.js.map → prompt-JLATI3P7.js.map} +0 -0
- /package/dist/cli/{prune-sessions-UCUD4XAP.js.map → prune-sessions-WHZDFUKD.js.map} +0 -0
- /package/dist/cli/{replay-VVIN64MN.js.map → replay-MHXS7C7Z.js.map} +0 -0
- /package/dist/cli/{run-76OBDZFB.js.map → run-SXNCPRJE.js.map} +0 -0
- /package/dist/cli/{sessions-FZTGRCM5.js.map → sessions-EPBFYISL.js.map} +0 -0
- /package/dist/cli/{stats-F4NDOD7D.js.map → stats-4WB4XHBP.js.map} +0 -0
- /package/dist/cli/{version-LUVTWHLL.js.map → version-4SP3DLLH.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"mappings":"gzCAOMA,OAAgB,IACtB,IAAIC,GAAiB,EACjBC,GAAc,EAGlB,MAAMC,GAAW,SAAS,cAAc,4BAA4B,EAC9DC,GAAUD,IAAU,aAAa,SAAS,GAAK,GAC/CE,GAAeD,KAAY,IAAMA,KAAY,oBAC7CE,GAAOD,GAAe,SAAW,OAG1BE,GAAeF,GAE5B,QAAQ,IAAI,uBAAuBC,EAAI,GAAGD,GAAe,UAAUD,EAAO,IAAM,EAAE,EAAE,EAGpF,SAASI,GAAUC,EAAmBC,EAAc,CAClD,MAAMC,EAAYX,GAAU,IAAIS,CAAS,EACzC,GAAIE,EACF,UAAWC,KAAMD,EACfC,EAAG,CAAE,QAAAF,EAAS,MAAOD,CAAA,CAAW,CAGtC,CAEA,SAASI,EAAUC,EAA4B,CAC7CN,GAAU,YAAa,CAAE,KAAM,KAAK,UAAUM,CAAK,EAAG,CACxD,CAGA,IAAIC,GAA0B,KAC1BC,GAAiB,GACjBC,GAAuB,EAC3B,MAAMC,GAA6B,GAC7BC,GAA2B,IAEjC,IAAIC,GAAkB,GAEtB,SAASC,GAAgBC,EAAoB,CACvCF,KAAoBE,IACtBF,GAAkB,CAACE,EAIjBT,EAHGS,EAGO,CAAE,KAAM,SAAU,KAAM,QAAS,MAAO,SAFxC,CAAE,KAAM,SAAU,KAAM,QAAS,MAAO,QAES,EAGjE,CAGA,SAASC,GAAcC,EAAgC,CACrD,MAAMC,EAAiC,GAEvC,OAAQD,EAAG,MACT,IAAK,kBAAmB,CACjBR,KACHA,GAAiB,GACjBd,KACAuB,EAAQ,KAAK,CACX,KAAM,qBACN,MAAO,QACP,GAAID,EAAG,GACP,KAAMtB,GACN,MAAO,oBACR,GAECsB,EAAG,cACLC,EAAQ,KAAK,CACX,KAAM,cACN,MAAO,QACP,QAAS,UACT,KAAMD,EAAG,aACT,KAAMtB,EAAA,CACP,EAECsB,EAAG,gBACLC,EAAQ,KAAK,CACX,KAAM,cACN,MAAO,QACP,QAAS,YACT,KAAMD,EAAG,eACT,KAAMtB,EAAA,CACP,EAEH,KACF,CACA,IAAK,kBAAmB,CAItBuB,EAAQ,KAAK,CACX,KAAM,cACN,MAAO,QACP,KAAMvB,GACN,QAASsB,EAAG,MAAQ,GACpB,iBAAkBA,EAAG,WAAa,GAClC,MAAOA,EAAG,OAAS,OACnB,QAASA,EAAG,SAAW,OACxB,EACD,KACF,CACA,IAAK,aAAc,CACjBC,EAAQ,KAAK,CACX,KAAM,iBACN,MAAO,QACP,KAAMvB,GACN,OAAQsB,EAAG,GACX,KAAMA,EAAG,SACV,EACDC,EAAQ,KAAK,CACX,KAAM,cACN,MAAO,QACP,KAAMvB,GACN,OAAQsB,EAAG,GACX,KAAMA,EAAG,SACT,KAAMA,EAAG,MAAQ,GAClB,EACD,KACF,CACA,IAAK,OAAQ,CACXC,EAAQ,KAAK,CACX,KAAM,cACN,MAAO,QACP,KAAMvB,GACN,OAAQsB,EAAG,GACX,KAAMA,EAAG,SACT,OAAQA,EAAG,QACX,GAAI,GACL,EACD,KACF,CACA,IAAK,OAAQ,CACXC,EAAQ,KAAK,CACX,KAAM,eACN,MAAO,QACP,GAAID,EAAG,GACP,KAAMtB,GACN,KAAMsB,EAAG,KACV,EACD,KACF,CACA,IAAK,cAAe,CACd,CAACA,EAAG,MAAQR,KACdS,EAAQ,KAAK,CAAE,KAAM,iBAAkB,MAAO,QAAS,EACvDT,GAAiB,IAEnB,KACF,CACA,IAAK,WAAY,CACf,MAAMU,EAAIF,EAAG,MACTE,GAAG,OAAS,QACdD,EAAQ,KAAK,CACX,KAAM,oBACN,MAAO,QACP,GAAIC,EAAE,IAAM,EAAEzB,GACd,KAAM,cACN,QAASyB,EAAE,QACZ,EACQA,GAAG,OAAS,SACrBD,EAAQ,KAAK,CACX,KAAM,mBACN,MAAO,QACP,GAAIC,EAAE,IAAM,EAAEzB,GACd,SAAUyB,EAAE,SACZ,QAASA,EAAE,SAAW,GACtB,YAAaA,EAAE,aAAe,GAC/B,EACQA,GAAG,OAAS,OACrBD,EAAQ,KAAK,CACX,KAAM,iBACN,MAAO,QACP,GAAIC,EAAE,IAAM,EAAEzB,GACd,KAAMyB,EAAE,MAAQ,GAChB,QAASA,EAAE,QACX,MAAOA,EAAE,MACV,EACQA,GAAG,OAAS,cACrBD,EAAQ,KAAK,CACX,KAAM,uBACN,MAAO,QACP,GAAIC,EAAE,IAAM,EAAEzB,GACd,OAAQyB,EAAE,OACV,MAAOA,EAAE,MACT,OAAQA,EAAE,OACV,MAAOA,EAAE,MACT,UAAWA,EAAE,UACb,MAAOA,EAAE,MACV,EAEH,KACF,CACA,IAAK,aAEH,MAEF,IAAK,UACL,IAAK,QAAS,CACZD,EAAQ,KAAK,CACX,KAAM,SACN,MAAO,QACP,QAASD,EAAG,KACb,EACD,KACF,CACA,IAAK,SAAU,CACbC,EAAQ,KAAK,CACX,KAAM,SACN,MAAO,QACP,KAAMD,EAAG,KACV,EACD,KACF,CACA,IAAK,OACH,MACF,QACE,QAAQ,KAAK,2CAA4CA,EAAG,IAAI,EAEpE,OAAOC,CACT,CAEA,SAASE,IAAmB,CACtBZ,OAAS,QACb,MAAMa,EAAQ,SAAS,cAAc,6BAA6B,GAAG,aAAa,SAAS,GAAK,GAC1FC,EAASD,GAASA,IAAU,qBAC9B,qBAAqB,mBAAmBA,CAAK,CAAC,GAC9C,cACJb,GAAM,IAAI,YAAYc,CAAM,EAC5Bd,GAAI,UAAae,GAAsB,CACrC,GAAI,CACF,MAAMC,EAAiB,KAAK,MAAMD,EAAI,IAAI,EAE1C,GAAIC,EAAe,OAAS,SAAWA,EAAe,MAAM,SAAS,OAAO,EAAG,CAC7ElB,EAAU,CACR,KAAM,SACN,MAAO,QACP,QAAS,oBACV,EACD,MACF,CACA,MAAMmB,EAAST,GAAcQ,CAAc,EAC3C,UAAWE,KAAOD,EAAQnB,EAAUoB,CAAG,EAEvChB,GAAuB,EACvBI,GAAgB,EAAI,CACtB,OAASa,EAAK,CACZ,QAAQ,KAAK,gCAAiCA,CAAG,CACnD,CACF,EACAnB,GAAI,QAAU,IAAM,CAOlB,GANA,QAAQ,KAAK,+CAA+C,EAC5DA,IAAK,QACLA,GAAM,KACNM,GAAgB,EAAK,EAErBJ,KACIA,GAAuBC,GAA4B,CACrDL,EAAU,CACR,KAAM,SACN,MAAO,QACP,QAAS,gBACV,EACD,MACF,CAEA,MAAMsB,EAAQhB,GAA2B,KAAK,IAAI,EAAGF,GAAuB,CAAC,EAC7E,WAAWU,GAAY,KAAK,IAAIQ,EAAO,GAAK,CAAC,CAC/C,EAGAC,GAAA,CACF,CAGA,IAAIC,GAAwD,KAE5D,SAASD,IAA0B,CAC7BC,kBAA8BA,EAAc,EAEhDA,GAAiB,YAAY,SAAY,CACvC,GAAI,CACF,MAAMC,EAAW,MAAMC,EAAS,UAAU,EAC1C,GAAID,GAAU,MAAO,CACnB,MAAME,EAAQF,EAAS,MAEvB,GAAIE,EAAM,QAAS,CACjB,MAAMC,EAAeD,EAAM,QAAQ,CAAC,EAChCC,GACF5B,EAAU,CACR,KAAM,WACN,MAAO,QACP,SAAU4B,EAAa,SACvB,MAAO,WAAWA,EAAa,aAAa,GAAK,EACjD,YAAa,GACd,CAEL,CAEA,MAAMC,EAAc,KAAK,MACvBF,EAAM,aAAe,EAAKA,EAAM,cAAgB,IAAS,EAI7D,CACF,MAAQ,CAER,CACF,EAAG,GAAI,CACT,CAGA,eAAeD,EAASI,EAAkBC,EAAqC,CAC7E,MAAMhB,EAAQ,SAAS,cAAc,6BAA6B,GAAG,aAAa,SAAS,EACrFiB,EAAkC,CACtC,GAAID,GAAS,SAAqC,EAAC,EAEjDhB,GAASA,IAAU,uBACrBiB,EAAQ,kBAAkB,EAAIjB,GAE5BgB,GAAS,MAAQ,CAACC,EAAQ,cAAc,IAC1CA,EAAQ,cAAc,EAAI,oBAE5B,MAAMC,EAAM,MAAM,MAAM,QAAQH,CAAQ,GAAI,CAAE,GAAGC,EAAS,QAAAC,EAAS,EACnE,GAAIC,EAAI,SAAW,IAAK,OAAO,KAC/B,MAAMC,EAAO,MAAMD,EAAI,OACvB,GAAI,CAAE,OAAO,KAAK,MAAMC,CAAI,CAAG,MAAQ,CAAE,OAAOA,CAAM,CACxD,CAEA,SAASC,GAAmBC,EAAeX,EAAsB,CAC/DzB,EAAU,CACR,KAAM,YACN,MAAO,QACP,gBAAiBoC,GAAU,iBAAmBX,GAAU,iBAAmB,OAC3E,SAAUW,GAAU,UAAYX,GAAU,UAAY,SACtD,UAAWW,GAAU,WAAaX,GAAU,WAAa,KACzD,aAAcA,GAAU,KAAO,GAC/B,iBAAkB,GAClB,MAAOA,GAAU,OAASW,GAAU,OAAS,oBAC7C,OAAQ,OACR,gBAAiBA,GAAU,iBAAmB,OAC9C,eAAgBA,GAAU,gBAAkB,GAC5C,QAASX,GAAU,SAAW,GAC9B,QAASW,GAAU,SAAW,GAC9B,aAAcA,GAAU,QAAU,GACnC,CACH,CAGA,eAAeC,IAA4B,CACzC,SAAS,gBAAgB,QAAQ,IAAM,OAGvC,IAAIC,EAAQ,GACZ,GAAI,CACF,KAAM,CAACF,EAAUG,EAAcd,CAAQ,EAAI,MAAM,QAAQ,IAAI,CAC3DC,EAAS,UAAU,EACnBA,EAAS,UAAU,EACnBA,EAAS,UAAU,EACpB,EAGD,GAFAY,EAAQb,GAAU,KAAO,GACrBW,GAAUD,GAAmBC,EAAUX,CAAQ,EAC/Cc,GAAc,SAAU,CAC1B,MAAMC,EAAQD,EAAa,SAAS,IAAKE,IAAY,CACnD,KAAMA,EAAE,KACR,aAAcA,EAAE,aAChB,MAAO,IAAI,KAAKA,EAAE,KAAK,EAAE,cACzB,QAASA,EAAE,SACX,EACFzC,EAAU,CACR,KAAM,YACN,MAAO,QACP,MAAAwC,CAAA,CACD,CACH,CAEA,MAAMb,EAAQF,GAAU,MACxB,GAAIE,GAAO,QAAS,CAClB,MAAMC,EAAeD,EAAM,QAAQ,CAAC,EAChCC,GACF5B,EAAU,CACR,KAAM,WACN,MAAO,QACP,SAAU4B,EAAa,SACvB,MAAO,WAAWA,EAAa,aAAa,GAAK,EACjD,YAAa,GACd,CAEL,CACF,OAASP,EAAK,CACZ,QAAQ,KAAK,qCAAsCA,CAAG,CACxD,CAEArB,EAAU,CAAE,KAAM,SAAU,MAAO,QAAS,EAC5CA,EAAU,CACR,KAAM,cACN,MAAO,QACP,aAAcsC,EACd,OAAQ,GACT,EAGDxB,GAAA,CACF,CAGA,eAAe4B,GAAU7C,EAA6C,CACpE,MAAM8C,EAAM9C,EAAQ,IAEpB,OAAQ8C,EAAA,CACN,IAAK,aAAc,CACjB,MAAMC,EAAS,MAAMlB,EAAS,SAAU,CACtC,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,OAAQ7B,EAAQ,KAAM,EAC9C,EAAE,MAAOwB,IACR,QAAQ,KAAK,gCAAiCA,CAAG,EAC1C,KACR,EAEIuB,GAAQ,UACX5C,EAAU,CACR,KAAM,SACN,MAAO,QACP,QAAS4C,GAAQ,QAAU,WAC5B,EAEH,KACF,CACA,IAAK,QAAS,CACZ,MAAMlB,EAAS,QAAS,CAAE,OAAQ,OAAQ,EAAE,MAAM,IAAM,CAAC,CAAC,EAC1D,KACF,CACA,IAAK,eAAgB,CACnB,GAAI,CACF,MAAMmB,EAAO,MAAMnB,EAAS,UAAU,EACtC,GAAImB,GAAM,SAAU,CAClB,MAAML,EAAQK,EAAK,SAAS,IAAKJ,IAAY,CAC3C,KAAMA,EAAE,KACR,aAAcA,EAAE,aAChB,MAAO,IAAI,KAAKA,EAAE,KAAK,EAAE,cACzB,QAASA,EAAE,SACX,EACFzC,EAAU,CAAE,KAAM,YAAa,MAAO,QAAS,MAAAwC,EAAO,CACxD,CACF,MAAQ,CAAe,CACvB,KACF,CACA,IAAK,eAAgB,CACnB,GAAI,CACF,MAAMM,EAAa,MAAMpB,EAAS,YAAY,mBAAmB7B,EAAQ,IAAI,CAAC,UAAW,CAAE,OAAQ,OAAQ,EAC3G,GAAI,CAACiD,GAAY,GAAI,CACnB,QAAQ,KAAK,wCAAyCjD,EAAQ,KAAMiD,CAAU,EAC9E,KACF,CACA,MAAMD,EAAO,MAAMnB,EAAS,YAAY,mBAAmB7B,EAAQ,IAAI,CAAC,EAAE,EAC1E,GAAI,CAAC,MAAM,QAAQgD,GAAM,QAAQ,EAAG,CAClC,QAAQ,KAAK,6DAA8DA,CAAI,EAC/E,KACF,CACA,MAAME,EAAMF,EAAK,SAIXG,MAAkB,IACxB,UAAWnC,KAAKkC,EACVlC,GAAG,OAAS,QAAU,OAAOA,EAAE,YAAe,UAChDmC,EAAY,IAAInC,EAAE,WAAY,CAC5B,QAAS,OAAOA,EAAE,SAAY,SAAWA,EAAE,QAAU,GACrD,KAAM,OAAOA,EAAE,UAAa,SAAWA,EAAE,SAAW,OACrD,EAGL,MAAMoC,EAAkB,GACxB,UAAWpC,KAAKkC,EAAK,CACnB,GAAIlC,GAAG,OAAS,OAAQ,CACtBoC,EAAS,KAAK,CAAE,KAAM,OAAiB,KAAMpC,EAAE,SAAW,GAAI,EAC9D,QACF,CACA,GAAIA,GAAG,OAAS,YAAa,CAC3B,MAAMqC,EAAkB,GAOxB,GANI,OAAOrC,EAAE,WAAc,UAAYA,EAAE,UAAU,OAAS,GAC1DqC,EAAS,KAAK,CAAE,KAAM,YAAsB,KAAMrC,EAAE,UAAW,EAE7D,OAAOA,EAAE,SAAY,UAAYA,EAAE,QAAQ,OAAS,GACtDqC,EAAS,KAAK,CAAE,KAAM,OAAiB,KAAMrC,EAAE,QAAS,EAEtD,MAAM,QAAQA,EAAE,SAAS,EAC3B,UAAWsC,KAAMtC,EAAE,UAAW,CAC5B,MAAM+B,EAASI,EAAY,IAAIG,EAAG,EAAE,EACpCD,EAAS,KAAK,CACZ,KAAM,OACN,OAAQC,EAAG,GACX,KAAMA,EAAG,MAAQP,GAAQ,MAAQ,OACjC,KAAMO,EAAG,WAAa,GACtB,UAAW,EACX,OAAQP,GAAQ,QAChB,GAAIA,GAAU,KACd,WAAY,EACb,CACH,CAEFK,EAAS,KAAK,CACZ,KAAM,YACN,KAAMpC,EAAE,MAAQ,EAChB,SAAAqC,EACA,QAAS,GACV,CACH,CAEF,CACAlD,EAAU,CACR,KAAM,kBACN,MAAO,QACP,KAAMH,EAAQ,KACd,SAAAoD,EACA,UAAW,CAAE,aAAc,EAAG,eAAgB,EAAG,gBAAiB,EAAE,CACrE,CACH,OAAS5B,EAAK,CACZ,QAAQ,KAAK,sCAAuCA,CAAG,CACzD,CACA,KACF,CACA,IAAK,iBAAkB,CACrB,GAAI,CACF,MAAMK,EAAS,YAAY,mBAAmB7B,EAAQ,IAAI,CAAC,GAAI,CAAE,OAAQ,SAAU,EAEnF,MAAMgD,EAAO,MAAMnB,EAAS,UAAU,EACtC,GAAImB,GAAM,SAAU,CAClB,MAAML,EAAQK,EAAK,SAAS,IAAKJ,IAAY,CAC3C,KAAMA,EAAE,KACR,aAAcA,EAAE,aAChB,MAAO,IAAI,KAAKA,EAAE,KAAK,EAAE,cACzB,QAASA,EAAE,SACX,EACFzC,EAAU,CAAE,KAAM,YAAa,MAAO,QAAS,MAAAwC,EAAO,CACxD,CACF,MAAQ,CAAe,CACvB,KACF,CACA,IAAK,WAAY,CACf,GAAI,CACF,MAAMK,EAAO,MAAMnB,EAAS,eAAgB,CAAE,OAAQ,OAAQ,EAC9D,GAAImB,GAAM,GAAI,CACZ,MAAMO,EAAU,OAAOP,EAAK,MAAS,SAAWA,EAAK,KAAO,UAI5D7C,EAAU,CACR,KAAM,kBACN,MAAO,QACP,KAAMoD,EACN,SAAU,GACV,UAAW,CAAE,aAAc,EAAG,eAAgB,EAAG,gBAAiB,EAAE,CACrE,EACD,MAAMC,EAAW,MAAM3B,EAAS,UAAU,EAC1C,GAAI2B,GAAU,SAAU,CACtB,MAAMb,EAAQa,EAAS,SAAS,IAAKZ,IAAY,CAC/C,KAAMA,EAAE,KACR,aAAcA,EAAE,aAChB,MAAO,IAAI,KAAKA,EAAE,KAAK,EAAE,cACzB,QAASA,EAAE,SACX,EACFzC,EAAU,CAAE,KAAM,YAAa,MAAO,QAAS,MAAAwC,EAAO,CACxD,CACF,CACF,MAAQ,CAAiB,CACzB,KACF,CACA,IAAK,eAAgB,CACnB,GAAI,CACF,KAAM,CAACJ,EAAUX,CAAQ,EAAI,MAAM,QAAQ,IAAI,CAACC,EAAS,UAAU,EAAGA,EAAS,UAAU,CAAC,CAAC,EACvFU,GAAUD,GAAmBC,EAAUX,CAAQ,CACrD,MAAQ,CAAe,CACvB,KACF,CACA,IAAK,gBAAiB,CACpB,GAAI,CACF,MAAMC,EAAS,WAAY,CACzB,OAAQ,OACR,KAAM,KAAK,UAAU7B,CAAO,EAC7B,EAED,KAAM,CAACuC,EAAUX,CAAQ,EAAI,MAAM,QAAQ,IAAI,CAACC,EAAS,UAAU,EAAGA,EAAS,UAAU,CAAC,CAAC,EACvFU,GAAUD,GAAmBC,EAAUX,CAAQ,CACrD,MAAQ,CAAe,CACvB,KACF,CACA,IAAK,iBAAkB,CACrB,MAAMC,EAAS,WAAY,CACzB,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,OAAQ7B,EAAQ,IAAK,EAC7C,EAAE,MAAM,IAAM,CAAC,CAAC,EACjB,KACF,CACA,IAAK,mBAAoB,CACvB,MAAM6B,EAAS,QAAS,CACtB,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,GAAI7B,EAAQ,GAAI,SAAUA,EAAQ,SAAU,EACpE,EAAE,MAAM,IAAM,CAAC,CAAC,EACjB,KACF,CACA,IAAK,kBAAmB,CACtB,MAAM6B,EAAS,QAAS,CACtB,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,GAAI7B,EAAQ,GAAI,SAAUA,EAAQ,SAAU,EACpE,EAAE,MAAM,IAAM,CAAC,CAAC,EACjB,KACF,CACA,IAAK,gBAAiB,CACpB,MAAM6B,EAAS,QAAS,CACtB,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,GAAI7B,EAAQ,GAAI,SAAUA,EAAQ,SAAU,EACpE,EAAE,MAAM,IAAM,CAAC,CAAC,EACjB,KACF,CACA,IAAK,sBAAuB,CAC1B,MAAM6B,EAAS,QAAS,CACtB,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,GAAI7B,EAAQ,GAAI,SAAUA,EAAQ,SAAU,EACpE,EAAE,MAAM,IAAM,CAAC,CAAC,EACjB,KACF,CACA,IAAK,oBAAqB,CACxB,MAAM6B,EAAS,QAAS,CACtB,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,GAAI7B,EAAQ,GAAI,SAAUA,EAAQ,SAAU,EACpE,EAAE,MAAM,IAAM,CAAC,CAAC,EACjB,KACF,CACA,IAAK,YAAa,CAChB,GAAI,CACF,MAAMgD,EAAO,MAAMnB,EAAS,OAAO,EAC/BmB,GAAM,MACR7C,EAAU,CAAE,KAAM,QAAS,MAAO,QAAS,MAAO6C,EAAK,KAAM,CAEjE,MAAQ,CAAe,CACvB,KACF,CACA,IAAK,gBAAiB,CACpB,GAAI,CACF,MAAMA,EAAO,MAAMnB,EAAS,kBAAkB,mBAAmB7B,EAAQ,KAAK,CAAC,UAAUA,EAAQ,KAAK,EAAE,EACpGgD,GACF7C,EAAU,CACR,KAAM,mBACN,MAAO,QACP,MAAOH,EAAQ,MACf,MAAOA,EAAQ,MACf,QAASgD,EAAK,SAAW,EAAC,CAC3B,CAEL,MAAQ,CAAe,CACvB,KACF,CACA,IAAK,kBAAmB,CACtB,GAAI,CACF,MAAMA,EAAO,MAAMnB,EAAS,kBAAkB,mBAAmB7B,EAAQ,IAAI,CAAC,UAAUA,EAAQ,KAAK,EAAE,EACnGgD,GACF7C,EAAU,CACR,KAAM,mBACN,MAAO,QACP,MAAOH,EAAQ,MACf,KAAMA,EAAQ,KACd,KAAMgD,EAAK,MAAQ,GACnB,WAAYA,EAAK,YAAc,EAChC,CAEL,MAAQ,CAAe,CACvB,KACF,CAEA,IAAK,gBACL,IAAK,aACL,IAAK,gBACL,IAAK,iBACL,IAAK,eACL,IAAK,WACL,IAAK,YACL,IAAK,iBACL,IAAK,MAEH,MAEF,IAAK,YAAa,CAChB,GAAI,CAAE,MAAMnB,EAAS,QAAQ7B,EAAQ,KAAK,QAAS,CAAE,OAAQ,OAAQ,CAAG,MAAQ,CAAC,CACjF,KACF,CACA,IAAK,gBAAiB,CACpB,GAAI,CAAE,MAAM6B,EAAS,gBAAiB,CAAE,OAAQ,OAAQ,CAAG,MAAQ,CAAC,CACpE,KACF,CACA,IAAK,kBAAmB,CACtB,GAAI,CAAE,MAAMA,EAAS,mBAAoB,CAAE,OAAQ,OAAQ,CAAG,MAAQ,CAAC,CACvE,KACF,CACA,IAAK,QAAS,CACZ,GAAI,CAAE,MAAMA,EAAS,SAAU,CAAE,OAAQ,OAAQ,KAAM,KAAK,UAAU,CAAE,MAAO,GAAM,EAAG,CAAG,MAAQ,CAAC,CACpG,KACF,CACA,IAAK,YAAa,CAChB,MAAM4B,EAA4B,CAAE,KAAMzD,EAAQ,MAC9CA,EAAQ,OAAMyD,EAAK,KAAOzD,EAAQ,MACtC,GAAI,CAAE,MAAM6B,EAAS,aAAc,CAAE,OAAQ,OAAQ,KAAM,KAAK,UAAU4B,CAAI,EAAG,CAAG,MAAQ,CAAC,CAC7F,KACF,CACA,IAAK,gBACL,IAAK,mBAAoB,CAEvB,GAAI,CACF,MAAM5B,EAAS,MAAO,CACpB,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,OAAQiB,IAAQ,gBAAkB,MAAQ,SAAU,KAAM9C,EAAQ,KAAM,EAChG,CACH,MAAQ,CAAC,CACT,KACF,CACA,QACE,QAAQ,KAAK,oCAAqC8C,CAAG,EAE3D,CAIA,eAAsBY,GAAOZ,EAAaa,EAA0B,CAGlE,GAFA,QAAQ,IAAI,iCAAiCb,CAAG,GAAGa,EAAO,IAAM,KAAK,UAAUA,CAAI,EAAI,EAAE,EAAE,EAEvF/D,KAAS,SAAU,CACrB,GAAIkD,IAAQ,YACV,OAAAN,KAAa,MAAM,QAAQ,IAAI,EACxB,QAAQ,UAEjB,GAAIM,IAAQ,WAAY,CACtB,MAAM9C,EAAU,KAAK,MAAM2D,EAAK,IAAI,EACpC,OAAA3D,EAAQ,MAAQA,EAAQ,OAAS,QACjC6C,GAAU7C,CAAO,EAAE,MAAM,QAAQ,IAAI,EAC9B,QAAQ,SACjB,CACA,OAAI8C,IAAQ,kBACV,QAAQ,IAAI,iCAAkCa,CAAI,EAC3C,QAAQ,SAGnB,CAGA,GAAIb,IAAQ,YACV,OAAAc,GAAA,EACO,QAAQ,UAGjB,GAAId,IAAQ,WAAY,CACtB,MAAM9C,EAAU,KAAK,MAAM2D,EAAK,IAAI,EACpC,OAAI3D,EAAQ,MAAQ,cAClBG,EAAU,CACR,KAAM,eAAgB,MAAO,QAC7B,GAAI,KAAK,MAAO,GAAI,IAAI,OAAO,cAAe,KAAM,EAAG,KAAMH,EAAQ,KACtE,EACD6D,GAAkB7D,EAAQ,IAAI,GACrBA,EAAQ,MAAQ,eACzBG,EAAU,CAAE,KAAM,YAAa,MAAO,QAAS,MAAO2D,GAAc,EAC3D9D,EAAQ,MAAQ,eACzBG,EAAU,CACR,KAAM,kBAAmB,MAAO,QAAS,KAAMH,EAAQ,KACvD,SAAU+D,GACV,UAAW,CAAE,aAAc,KAAO,eAAgB,KAAM,gBAAiB,KAAK,CAC/E,EACQ/D,EAAQ,MAAQ,WACzBG,EAAU,CAAE,KAAM,iBAAkB,MAAO,QAAS,KAAM,sBAAuB,UAAW,EAAG,EACtFH,EAAQ,MAAQ,gBACzBG,EAAU,CAAE,KAAM,YAAa,MAAO,QAAS,GAAG6D,GAAc,EAE3D,QAAQ,SACjB,CAEA,OAAIlB,IAAQ,kBACV,QAAQ,IAAI,4CAA6Ca,CAAI,EACtD,QAAQ,SAInB,CAGA,eAAsBM,GACpBlE,EACAmE,EACqB,CACrB,IAAIC,EAAS7E,GAAU,IAAIS,CAAS,EACpC,OAAKoE,IACHA,MAAa,IACb7E,GAAU,IAAIS,EAAWoE,CAAM,GAEjCA,EAAO,IAAID,CAAQ,EACZ,IAAM,CACX,MAAME,EAAI9E,GAAU,IAAIS,CAAS,EAC7BqE,GAAGA,EAAE,OAAOF,CAAQ,CAC1B,CACF,CAGO,SAASG,IAAyB,CACvC,MAAO,CACL,gBAAiB,MAAOC,IACtB,QAAQ,IAAI,+CAA+C,EACpD,IAAM,CAAC,EAChB,CAEJ,CAGO,SAASC,IAAwB,CACtC,MAAO,CACL,YAAa,SAAY,GACzB,SAAU,SAAY,CAAE,QAAQ,IAAI,iCAAiC,CAAG,EACxE,MAAO,SAAY,CAAE,QAAQ,IAAI,8BAA8B,CAAG,EAClE,eAAgB,SAAY,CAAE,QAAQ,IAAI,uCAAuC,CAAG,EACpF,OAAQ,MAAOC,EAAgBF,IAAwC,IAAM,CAAC,EAC9E,MAAO,OAEX,CAGA,eAAsBG,GAAKvC,EAA6B,CACtD,eAAQ,IAAI,8BAA+BA,CAAO,EAC3C,QAAQ,QAAQ,EAAE,CAC3B,CAEA,eAAsBwC,GAAKxC,EAA6B,CACtD,eAAQ,IAAI,8BAA+BA,CAAO,EAC3C,QAAQ,QAAQ,EAAE,CAC3B,CAGA,eAAsByC,GAAQC,EAA4B,CACxD,eAAQ,IAAI,8BAA8BA,CAAG,EAAE,EAC/C,OAAO,KAAKA,EAAK,QAAQ,EAClB,QAAQ,SACjB,CAEA,eAAsBC,GAASC,EAA6B,CAC1D,eAAQ,IAAI,+BAA+BA,CAAI,EAAE,EAC1C,QAAQ,SACjB,CAGA,eAAsBC,IAA0B,CAC9C,eAAQ,IAAI,+CAA+C,EAC3D,OAAO,SAAS,SACT,QAAQ,SACjB,CAIA,MAAMjB,GAAe,CACnB,CAAE,KAAM,qBAAsB,aAAc,EAAG,MAAO,IAAI,OAAO,cAAe,QAAS,sBACzF,CAAE,KAAM,qBAAsB,aAAc,GAAI,MAAO,IAAI,KAAK,KAAK,MAAQ,KAAQ,EAAE,cAAe,QAAS,gCAC/G,CAAE,KAAM,qBAAsB,aAAc,EAAG,MAAO,IAAI,KAAK,KAAK,MAAQ,MAAS,EAAE,cAAe,QAAS,oCACjH,EAEME,GAAe,CACnB,gBAAiB,OAAQ,SAAU,SAAU,UAAW,KACxD,aAAc,GAAI,iBAAkB,GACpC,MAAO,oBAAqB,QAAS,QACvC,EAEMD,GAAsB,CAC1B,CAAE,KAAM,OAAQ,KAAM,uCACtB,CACE,KAAM,YACN,KAAM,EACN,SAAU,CACR,CAAE,KAAM,YAAa,KAAM,oBAC3B,CAAE,KAAM,OAAQ,KAAM,qDAAqD,EAE7E,QAAS,GAEb,EAEA,SAASF,GAAkBmB,EAAqB,CAC9C7E,EAAU,CAAE,KAAM,SAAU,KAAM,qBAAsB,MAAO,QAAS,EACxE,WAAW,IAAM,CACfA,EAAU,CACR,KAAM,qBAAsB,MAAO,QAAS,GAAI,KAAK,MACrD,KAAM,EAAG,MAAO,oBAAqB,gBAAiB,OACvD,CACH,EAAG,GAAG,EAEN,MAAM8E,EAAQ,CAAC;AAAA,EAAgB;AAAA,CAAyB,EACxD,IAAIxD,EAAQ,KACZwD,EAAM,QAASC,GAAS,CACtB,WAAW,IAAM,CACf/E,EAAU,CAAE,KAAM,cAAe,MAAO,QAAS,QAAS,YAAa,KAAM+E,EAAM,KAAM,EAAG,CAC9F,EAAGzD,CAAK,EACRA,GAAS,GACX,CAAC,EAED,WAAW,IAAM,CACftB,EAAU,CAAE,KAAM,iBAAkB,MAAO,QAAS,KAAM,WAAY,OAAQ,aAAc,CAC9F,EAAGsB,CAAK,EACRA,GAAS,IACT,WAAW,IAAM,CACftB,EAAU,CACR,KAAM,cAAe,MAAO,QAAS,KAAM,WAC3C,KAAM,KAAK,UAAU,CAAE,cAAe,4BAA6B,EAAG,OAAQ,aAC/E,CACH,EAAGsB,CAAK,EACRA,GAAS,IACT,WAAW,IAAM,CACftB,EAAU,CACR,KAAM,cAAe,MAAO,QAAS,KAAM,WAAY,GAAI,GAC3D,OAAQ,KAAK,UAAU,CAAC,CAAE,KAAM,eAAgB,UAAW,KAAO,CAAE,KAAM,MAAO,MAAO,GAAM,CAAC,EAC/F,OAAQ,aACT,CACH,EAAGsB,CAAK,EACRA,GAAS,IAET,MAAM0D,EAAS,CACb;AAAA,EACA,sCACA;AAAA,EACA,4BAEFA,EAAO,QAASC,GAAU,CACxB,WAAW,IAAM,CACfjF,EAAU,CAAE,KAAM,cAAe,MAAO,QAAS,QAAS,UAAW,KAAMiF,EAAO,KAAM,EAAG,CAC7F,EAAG3D,CAAK,EACRA,GAAS,GACX,CAAC,EACD,WAAW,IAAM,CACftB,EAAU,CAAE,KAAM,cAAe,MAAO,QAAS,KAAM,EAAG,QAASgF,EAAO,KAAK,EAAE,EAAG,iBAAkBF,EAAM,KAAK,EAAE,EAAG,QAAS,KAAO,EACtI9E,EAAU,CAAE,KAAM,iBAAkB,MAAO,QAAS,CACtD,EAAGsB,EAAQ,GAAG,CAChB,CAEA,SAASmC,IAAoB,CAC3B,SAAS,gBAAgB,QAAQ,IAAM,OACvC,WAAW,IAAMzD,EAAU,CAAE,KAAM,SAAU,MAAO,QAAS,EAAG,GAAG,EACnE,WAAW,IAAM,CACfA,EAAU,CAAE,KAAM,cAAe,MAAO,QAAS,aAAc,oBAAqB,OAAQ,GAAM,CACpG,EAAG,GAAG,EACN,WAAW,IAAMA,EAAU,CAAE,KAAM,YAAa,MAAO,QAAS,GAAG6D,GAAc,EAAG,GAAG,EACvF,WAAW,IAAM7D,EAAU,CAAE,KAAM,YAAa,MAAO,QAAS,MAAO2D,EAAA,CAAc,EAAG,GAAG,CAC7F,qOCl7BauB,GAAK,CAChB,IAAK,CACH,iBAAkB,YAClB,eAAgB,UAChB,iBAAkB,YAClB,QAAS,OACT,SAAU,QACV,YAAa,WACb,YAAa,WACb,SAAU,QACV,UAAW,SACX,YAAa,WACb,SAAU,QACV,eAAgB,cAChB,OAAQ,MACR,UAAW,SACX,UAAW,SACX,SAAU,QACV,YAAa,WACb,eAAgB,UAChB,WAAY,UACZ,OAAQ,+BACR,YAAa,eACb,WAAY,QACZ,UAAW,OACX,MAAO,CACL,MAAO,CACL,QAAS,WACT,OAAQ,SACR,QAAS,WAEX,MAAO,CACL,SAAU,WACV,OAAQ,UAEV,QAAS,SAEX,uBAAwB,oBACxB,gBAAiB,aACjB,gBAAiB,gBACjB,MAAO,CACL,iBAAkB,oBAClB,gBAAiB,oCACjB,YAAa,2BACb,YAAa,gBACb,YAAa,gBACb,YAAa,kBACb,QAAS,uBAEX,WAAY,QACZ,WAAY,cACZ,QAAS,CACP,OAAQ,UACR,IAAK,eAEP,MAAO,CACL,OAAQ,qBACR,YAAa,sCACb,YAAa,wBACb,aAAc,eACd,QAAS,UACT,UAAW,aAEb,IAAK,CACH,OAAQ,YACR,YAAa,kBAEf,SAAU,CACR,UAAW,aACX,MAAO,QACP,eAAgB,kBAChB,aAAc,gBACd,OAAQ,mBACR,SAAU,qBACV,SAAU,WACV,SAAU,WACV,KAAM,OACN,QAAS,UACT,SAAU,WACV,QAAS,UACT,eAAgB,mBAElB,MAAO,CACL,QAAS,eACT,OAAQ,sBACR,SAAU,qBACV,aAAc,wBACd,kBAAmB,cACnB,WAAY,uBACZ,aAAc,gBACd,aAAc,oBACd,cAAe,kBACf,eAAgB,oBAChB,aAAc,gBACd,WAAY,uBAEd,KAAM,CACJ,MAAO,qBAET,IAAK,CACH,MAAO,QACP,IAAK,MACL,UAAW,aACX,QAAS,UACT,SAAU,YACV,SAAU,qBACV,SAAU,WACV,KAAM,OACN,WAAY,cACZ,MAAO,QACP,YAAa,eACb,eAAgB,kBAChB,WAAY,kBACZ,YAAa,gBAEf,OAAQ,CACN,MAAO,QACP,cAAe,kBACf,KAAM,OACN,OAAQ,mBACR,OAAQ,SACR,SAAU,qBACV,QAAS,WACT,YAAa,eACb,QAAS,YAEX,aAAc,iBACd,OAAQ,UACR,OAAQ,KACR,eAAgB,+BAElB,QAAS,CACP,gBAAiB,yBACjB,YAAa,oDACb,SAAU,OACV,kBAAmB,wBACnB,UAAW,UACX,SAAU,YACV,gBAAiB,MACjB,kBAAmB,QACnB,SAAU,mCACV,WAAY,mCACZ,eAAgB,2DAChB,WAAY,8CACZ,SAAU,mBACV,WAAY,qBACZ,UAAW,uBACX,YAAa,yBACb,YAAa,OACb,cAAe,QACf,gBAAiB,cACjB,eAAgB,OAChB,aAAc,yBACd,OAAQ,SACR,SAAU,YACV,QAAS,UACT,aAAc,qBACd,mBAAoB,iBACpB,cAAe,SACf,cAAe,UACf,YAAa,OACb,YAAa,OACb,cAAe,SACf,cAAe,cACf,kBAAmB,mBACnB,qBAAsB,aACtB,gBAAiB,wCACjB,WAAY,UACZ,eAAgB,uDAChB,UAAW,SACX,cAAe,8EACf,UAAW,WACX,kBAAmB,qBACnB,WAAY,eACZ,YAAa,sBACb,iBAAkB,UAClB,eAAgB,QAChB,UAAW,aACX,YAAa,eACb,aAAc,gBACd,cAAe,iBACf,aAAc,iBAEhB,OAAQ,CACN,QAAS,WACT,cAAe,yBACf,KAAM,SACN,KAAM,OACN,OAAQ,SACR,OAAQ,SACR,OAAQ,SACR,IAAK,MACL,QAAS,UACT,OAAQ,iBACR,IAAK,MACL,IAAK,MACL,GAAI,KACJ,GAAI,KACJ,IAAK,MACL,QAAS,UACT,SAAU,YAEZ,SAAU,CACR,MAAO,WACP,QAAS,oBACT,MAAO,kBACP,WAAY,eACZ,OAAQ,UACR,aAAc,UACd,WAAY,WACZ,UAAW,MACX,WAAY,oBACZ,OAAQ,YACR,QAAS,UACT,SAAU,2BACV,QAAS,WACT,QAAS,WACT,mBAAoB,qCACpB,YAAa,4BACb,gBAAiB,WACjB,cAAe,mBACf,YAAa,kBACb,gBAAiB,6EACjB,kBAAmB,4CACnB,gBAAiB,oBACjB,OAAQ,SACR,UAAW,6DACX,WAAY,gDACZ,aAAc,SACd,UAAW,gBACX,UAAW,aACX,cAAe,+BACf,gBAAiB,gBACjB,oBAAqB,8CACrB,uBAAwB,6DACxB,sBAAuB,6DACvB,sBAAuB,6CACvB,0BAA2B,kDAC3B,mBAAoB,iDACpB,oBAAqB,sCACrB,cAAe,SACf,OAAQ,SACR,WAAY,sBACZ,kBAAmB,sBACnB,SAAU,KACV,aAAc,YACd,aAAc,SACd,eAAgB,6BAChB,YAAa,YACb,eAAgB,mCAChB,eAAgB,+CAChB,eAAgB,4DAChB,YAAa,OACb,aAAc,8CACd,aAAc,4CACd,aAAc,WACd,WAAY,SACZ,eAAgB,+BAChB,WAAY,SACZ,sBAAuB,qDACvB,UAAW,aACX,SAAU,OACV,YAAa,UACb,SAAU,cACV,YAAa,uBACb,cAAe,SACf,WAAY,cACZ,sBAAuB,uCACvB,eAAgB,6CAChB,YAAa,mBACb,aAAc,gBACd,mBAAoB,QACpB,iBAAkB,MAClB,kBAAmB,0DACnB,eAAgB,UAChB,YAAa,eACb,MAAO,QACP,eAAgB,uBAChB,aAAc,mBACd,iBAAkB,qDAClB,SAAU,YACV,aAAc,kCACd,aAAc,sBACd,iBAAkB,gBAClB,qBAAsB,uEACtB,MAAO,QACP,OAAQ,SACR,gBAAiB,WACjB,SAAU,WACV,aAAc,kBACd,OAAQ,UACR,SAAU,OACV,QAAS,WACT,kBAAmB,aACnB,gBAAiB,WACjB,qBAAsB,gCACtB,wBAAyB,sBACzB,MAAO,QACP,UAAW,OACX,UAAW,uCACX,WAAY,QACZ,WAAY,cACZ,eAAgB,qBAChB,mBAAoB,WACpB,uBAAwB,+CACxB,oBAAqB,YACrB,wBAAyB,2CACzB,oBAAqB,YACrB,wBAAyB,mCACzB,mBAAoB,WACpB,uBAAwB,oCACxB,iBAAkB,UAClB,gBAAiB,wCACjB,gBAAiB,SACjB,eAAgB,sCAChB,aAAc,cACd,YAAa,iCACb,gBAAiB,SACjB,eAAgB,+CAChB,gBAAiB,SACjB,eAAgB,4CAChB,eAAgB,QAChB,cAAe,+CACf,iBAAkB,UAClB,gBAAiB,2CACjB,mBAAoB,YACpB,kBAAmB,gCACnB,WAAY,cACZ,eAAgB,qBAChB,eAAgB,aAChB,gBAAiB,QACjB,iBAAkB,SAClB,UAAW,aACX,cAAe,mBACf,eAAgB,QAChB,gBAAiB,SACjB,eAAgB,QAChB,iBAAkB,oBAClB,oBAAqB,gBACrB,OAAQ,SACR,WAAY,+BACZ,UAAW,aACX,gBAAiB,mBACjB,oBAAqB,yBACrB,YAAa,eACb,iBAAkB,YAClB,aAAc,UACd,WAAY,cACZ,aAAc,iBACd,UAAW,iBACX,YAAa,eACb,WAAY,cACZ,gBAAiB,SACjB,iBAAkB,YAClB,OAAQ,MACR,cAAe,iBACf,WAAY,UACZ,cAAe,aACf,SAAU,iBACV,cAAe,cACf,UAAW,SACX,cAAe,cACf,aAAc,cACd,WAAY,4BACZ,cAAe,SACf,cAAe,QACf,iBAAkB,YAClB,uBAAwB,kBACxB,sBAAuB,iBACvB,gBAAiB,WACjB,eAAgB,UAChB,iBAAkB,WAClB,kBAAmB,aACnB,kBAAmB,YACnB,aAAc,OACd,cAAe,QACf,2BAA4B,oBAC5B,gBAAiB,UACjB,QAAS,SACT,cAAe,QACf,aAAc,QACd,YAAa,aACb,OAAQ,OACR,YAAa,YACb,gBAAiB,wBACjB,iBAAkB,mBAClB,YAAa,YACb,aAAc,cACd,eAAgB,eAChB,cAAe,cACf,SAAU,SACV,aAAc,aACd,UAAW,UACX,OAAQ,OACR,iBAAkB,iBAClB,UAAW,iBACX,eAAgB,SAChB,gBAAiB,UACjB,iBAAkB,iBAClB,QAAS,UAEX,KAAM,CACJ,WAAY,aACZ,SAAU,eACV,YAAa,2EACb,gBAAiB,uCACjB,qBAAsB,+DACtB,UAAW,yDACX,KAAM,OACN,IAAK,MACL,MAAO,QACP,SAAU,2DACV,WAAY,uDACZ,eAAgB,qDAChB,eAAgB,2DAChB,WAAY,8CACZ,SAAU,mBACV,WAAY,qBACZ,UAAW,uBACX,YAAa,yBACb,iBAAkB,2CAClB,eAAgB,kDAChB,mBACE,sIACF,kBAAmB,aACnB,sBAAuB,6BACvB,cAAe,iBACf,aAAc,gBACd,YAAa,uCACb,eAAgB,2BAChB,gBAAiB,gDACjB,kBAAmB,SACnB,eAAgB,gBAChB,cAAe,sCACf,gBAAiB,0DACjB,cAAe,4CACf,cAAe,sDACf,YAAa,UACb,UAAW,QACX,cAAe,aACf,SAAU,OACV,aAAc,YACd,eAAgB,cAChB,UAAW,QACX,eAAgB,cAChB,aAAc,WACd,YAAa,QACb,UAAW,MACX,YAAa,QACb,WAAY,OACZ,cAAe,UACf,cAAe,UACf,YAAa,kBACb,aAAc,gCACd,cAAe,UACf,gBAAiB,UACjB,iBAAkB,WAClB,kBAAmB,YACnB,gBAAiB,UACjB,kBAAmB,uBACnB,YAAa,iBACb,SAAU,cACV,WAAY,YACZ,UAAW,aACX,aAAc,iBACd,YAAa,oBAEf,SAAU,CACR,QAAS,oBACT,OAAQ,2BACR,gBAAiB,kBACjB,eACE,0GACF,QAAS,UACT,QAAS,UACT,SAAU,cACV,SAAU,YACV,aAAc,mBACd,OAAQ,SACR,eAAgB,kBAChB,UAAW,oEACX,UAAW,aACX,cAAe,iBACf,KAAM,OACN,UAAW,gBACX,WAAY,eACZ,OAAQ,WACR,YAAa,eACb,QAAS,8CACT,aAAc,gBACd,YAAa,qBACb,YAAa,eACb,WAAY,cACZ,SAAU,YACV,QAAS,WACT,WAAY,oBACZ,YAAa,eACb,YAAa,gBACb,OAAQ,WACR,QAAS,0BACT,OAAQ,SACR,MAAO,SACP,YAAa,uBACb,SAAU,WACV,OAAQ,UAEV,MAAO,CACL,QAAS,iBACT,OAAQ,wBACR,QAAS,kBACT,WAAY,cACZ,UAAW,6BACX,OAAQ,4EACR,QAAS,kBACT,UAAW,SACX,SAAU,QACV,YAAa,YACb,QAAS,aACT,cAAe,cACf,YAAa,YACb,SAAU,QACV,SAAU,OACV,QAAS,MACT,UAAW,QACX,WAAY,OACZ,iBAAkB,cAClB,YAAa,QACb,SAAU,mBACV,SAAU,SAEZ,SAAU,CACR,QAAS,oBACT,OAAQ,2BACR,WAAY,yBACZ,kBAAmB,kBACnB,KAAM,OACN,SAAU,qDACV,YAAa,gBACb,WACE,kHACF,kBAAmB,sBACnB,gBAAiB,oBACjB,SAAU,qBACV,OAAQ,cACR,QAAS,yDACT,UAAW,yBACX,UAAW,SACX,cAAe,kFACf,iBAAkB,0DAClB,eACE,kIACF,WAAY,SACZ,WAAY,UAEd,MAAO,CACL,QAAS,iBACT,OAAQ,wBACR,QAAS,uBACT,SAAU,2BACV,QAAS,OACT,SAAU,QACV,QAAS,cACT,SAAU,YACV,MAAO,QACP,KAAM,OACN,KAAM,CACJ,WACE,gLACF,UACE,sIACF,YACE,qKACF,eACE,yKACF,WACE,6HACF,aACE,sHACF,SACE,6GACF,UACE,2GACF,SACE,kKACF,OACE,mIACF,cACE,qFACF,UACE,yIACF,eACE,sGACF,eACE,mHACF,aACE,uHACF,eACE,4IACF,KAAM,6HACN,cAAe,8EACf,WACE,+FACF,UACE,4GACF,WACE,6GACF,iBAAkB,uEAClB,UAAW,6DACX,YACE,gGACF,iBACE,+GACF,UACE,iGACF,YACE,iIACF,mBACE,2FACF,YACE,6FACF,UACE,wHACF,eACE,4HACF,WACE,qHACF,WACE,8GACF,aACE,qGACF,eACE,8HACJ,EAEF,YAAa,CACX,QAAS,uBACT,OAAQ,8BACR,UAAW,YACX,SACE,+FACF,QAAS,UACT,QAAS,UACT,UAAW,eACX,eAAgB,sCAChB,SAAU,YACV,UAAW,2BACX,MAAO,kBACP,QAAS,oBACT,QAAS,0BACT,cAAe,mDACf,aAAc,sEACd,iBAAkB,8BAClB,cAAe,uCACf,OAAQ,IACR,UAAW,SACX,aAAc,gCACd,kBACE,0JAEJ,IAAK,CACH,QAAS,eACT,QAAS,gCACT,IAAK,MACL,KAAM,OACN,UAAW,YACX,gBAAiB,kDACjB,MAAO,QACP,aAAc,sDACd,QAAS,4CACT,cAAe;AAAA;AAAA,QACf,UAAW,kCACX,MAAO,QACP,SAAU,yBACV,eAAgB,wBAChB,UAAW,SACX,KAAM,OACN,aAAc,iBACd,iBACE,gLACF,iBAAkB,mEAClB,aAAc,gBACd,kBAAmB,4BACnB,iBACE,gMACF,SAAU,yEACV,WAAY,kBACZ,eAAgB,sBAChB,aAAc,oBACd,QAAS,OACT,QAAS,cACT,OAAQ,MACR,YAAa,cACb,kBAAmB,uBACnB,mBAAoB,oBACpB,gBAAiB,oBACjB,qBAAsB,6CACtB,oBAAqB,uCACrB,0BAA2B,sCAC3B,qBAAsB,mBACtB,yBAA0B,mDAC1B,iBAAkB,+DAClB,wBAAyB,YACzB,qBAAsB,sDACtB,mBAAoB,UACpB,oBAAqB,2CACrB,qBAAsB,qBACtB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","names":["listeners","eventIdCounter","currentTurn","modeMeta","rawMode","isServerMode","MODE","isWebRuntime","broadcast","eventName","payload","callbacks","cb","emitEvent","event","sse","sseTurnStarted","sseReconnectAttempts","SSE_MAX_RECONNECT_ATTEMPTS","SSE_RECONNECT_BASE_DELAY","cliDisconnected","notifyCliStatus","connected","sseToIncoming","ev","results","m","connectSSE","token","sseUrl","msg","dashboardEvent","events","evt","err","delay","startStatsPolling","statsPollTimer","overview","apiFetch","stats","firstBalance","totalTokens","endpoint","options","headers","res","text","emitServerSettings","settings","serverInit","wsDir","sessionsData","items","s","serverRpc","cmd","result","data","switchData","raw","toolResults","messages","segments","tc","newName","listData","body","invoke","args","mockSetupAndReady","mockAssistantTurn","mockSessions","mockMessages","mockSettings","listen","callback","bucket","b","getCurrentWebview","_callback","getCurrentWindow","_event","open","save","openUrl","url","openPath","path","relaunch","_promptText","lines","line","chunks","chunk","en","zhCN","SUPPORTED","STORAGE_KEY","detectDefault","stored","currentLang","syncHtmlLang","lang","getLang","setLang","useLang","setTick","useState","useEffect","idx","dicts","resolve","dict","key","parts","cursor","p","t","params","_","k","isMacPlatform","keyLabel","mac","shortcutText","keys","localizeShortcutText","Shortcut","className","jsx","index","useCommandPalette","active","setOpen","onKey","e","v","buildCommands","handlers","list","FilePlus","Plus","SquareX","FocusIcon","StopCircle","ClipboardCopy","Download","Trash2","FolderOpen","Settings","Info","GROUP_ORDER","groupLabel","g","CommandPalette","onClose","commands","query","setQuery","setActive","inputRef","useRef","listRef","filtered","useMemo","q","c","a","grouped","byGroup","arr","run","jsxs","Search","section","i","Toast","message","DARK_THEME","LIGHT_THEME","usePrismTheme","theme","setTheme","prevRef","el","mo","CodeView","startLine","showLineNumbers","Highlight","tokens","getLineProps","getTokenProps","openWithEditor","editor","abs","WorkspaceContext","createContext","WorkspaceProvider","resolveAgainstWorkspace","rel","ws","sep","KNOWN_EXTS","FILE_PATH_RE","FilePill","ctx","useContext","done","setDone","display","openInEditor","lineNum","copyOnly","FileText","Check","splitFilePaths","out","last","prefix","pillStart","withFilePills","children","Children","child","isValidElement","props","cloneElement","Markdown","memo","source","ReactMarkdown","remarkGfm","remarkBreaks","remarkMath","rehypeKatex","rawText","flattenChildText","CodeBlock","extractFencedLang","href","SafeLink","isExternal","onClick","stripped","ExternalLink","kid","cls","node","copied","setCopied","onCopy","Copy","Ic","size","rest","I","THEME","isTheme","value","THEME_STYLE","DEFAULT_THEME_STYLE","THEME_STYLE_THEME","THEME_STYLES","isThemeStyle","themeForStyle","style","defaultStyleForTheme","FONT_SCALE","isFontScale","FONT_SCALE_ZOOM","FONT_FAMILY","isFontFamily","FONT_FAMILY_STACK","SESSION_PARAM","readSessionFromUrl","trimmed","writeSessionToUrl","name","fmtElapsed","ms","useElapsed","startAt","setMs","start","id","EFFORTS","MODE_INFO","ModeSwitch","mode","onChange","slashIcon","parentOfAtQuery","normalized","trailingSlash","lastSlash","dirContext","parentIdx","atIcon","Composer","draft","setDraft","onSend","onAbort","disabled","busy","busyLabel","busyElapsedMs","modelLabel","reasoningEffort","onModelChange","onEffortChange","editMode","onEditModeChange","textareaRef","slashCommands","onMentionQuery","onMentionPreview","onMentionPicked","mentionResults","workspaceDir","queuedSends","onQueueWhileBusy","onDequeueSend","chips","setChips","popup","setPopup","activeIdx","setActiveIdx","modelMenuOpen","setModelMenuOpen","nonceRef","modelWrapRef","composingRef","compositionEndedAtRef","prevDraftRef","prev","onDown","attachFile","filter","picked","openFileDialog","slashItems","atItems","base","parent","handleChange","trail","sigil","nonce","dismiss","pickItem","it","next","mention","handleKeyDown","dirPath","Fragment","cs","j","ModelEffortMenu","Popup","item","kind","onPick","onHover","KNOWN_MODELS","currentEffort","onPickModel","onPickEffort","PanelErrorBoundary","Component","error","info","CONTEXT_MAX_TOKENS","ContextPanel","usage","mcpSpecs","mcpBridged","sessionFiles","memory","tab","setTab","reserved","cached","used","reservedPct","usedPct","cachedPct","free","CtxFiles","CtxTools","CtxMemory","CtxRules","buildSessionTree","files","sorted","seenDirs","f","seg","leaf","tree","specs","bridged","readyCount","dot","suffix","entries","r","JobsPop","jobs","onStop","onStopAll","tick","n","running","exited","JobRow","formatElapsed","job","exp","setExp","elapsedMs","liveMs","REPO_URL","AboutModal","openGitHub","maskQQAppId","appId","getQQConnectIntent","qq","getQQStatusLabel","describeQQAccessLabel","access","owner","openId","count","allowlist","runtime","describeQQRowSummary","PAGE_META","SettingsModal","balance","currency","themeStyle","onSetTheme","onSetThemeStyle","fontScale","onSetFontScale","fontFamily","onSetFontFamily","initialPage","skills","onSave","onSaveApiKey","onLoadQQ","onConnectQQ","onDisconnectQQ","onSaveQQConfig","onOpenQQApplyLink","onPickWorkspace","onAddMcpSpec","onRemoveMcpSpec","page","setPage","qqConfigureOpen","setQQConfigureOpen","currentMeta","PageGeneral","PageModels","PageMCP","PageSkills","PageMemory","PageRules","PageBilling","PageShortcuts","ApiKeySection","QQChannelSection","patch","configureOpen","onOpenConfigure","onCloseConfigure","onConnect","onDisconnect","onSaveConfig","onSaveAndConnect","onOpenApplyLink","current","setAppId","appSecret","setAppSecret","sandbox","setSandbox","savePatch","editorDraft","setEditorDraft","baseUrl","apiKeyPrefix","setKey","urlDraft","setUrlDraft","EFFORT_VALUES","isKnown","onAdd","onRemove","submit","subagentModels","setSubagentModel","symbol","sessionCost","hitPct","rows","SectionRow","nm","prettyName","month","day","hh","mm","relative","min","hr","d","Sidebar","sessions","activeName","loadingName","onNewChat","onLoadSession","onDeleteSession","onOpenSettings","onOpenRules","onOpenCommands","onOpenAbout","pendingDelete","setPendingDelete","onMouseDown","loading","mtime","updated","rect","SessionDeletePopover","target","onCancel","onConfirm","ref","cancelRef","pos","setPos","useLayoutEffect","pad","vw","vh","left","top","SPLASH_FLAG","shouldShowSplash","markSplashShown","Splash","onDone","leaving","setLeaving","onDoneRef","t1","t2","skip","skipClick","USD_TO_CNY","formatMoney","amountUsd","amount","tokenLabel","StatusBar","ready","jobsOpen","onToggleJobs","onToggleCurrency","onOpenWorkdir","cacheHitPct","runningJobs","spent","balanceLabel","connState","themeOpen","setThemeOpen","themePopRef","themeButtonRef","onPointerDown","COMPACTION_SUMMARY_MARKER","isCompactionSummary","stripCompactionMarker","derivePrefix","command","first","Card","tone","icon","meta","defaultOpen","compact","headRight","StatusIcon","state","label","ReasoningCard","streaming","elapsed","model","para","ShellCard","output","durationMs","onApprove","onReject","onAlwaysAllow","ln","CompactionCard","summary","charCount","ToolCard","ok","AssistantText","ApprovalCard","title","sub","preview","primaryLabel","secondaryLabel","tertiaryLabel","onPrimary","onSecondary","onTertiary","TaskCard","subtitle","steps","x","pct","st","TurnDivider","UserMsg","time","skill","AssistantMsg","pending","onApproveConfirm","onRejectConfirm","onAlwaysAllowConfirm","pendingConfirms","content","pendingConfirm","extractCommand","PlanBanner","plan","onDismiss","total","PlanApprovalCard","onRefine","stepCount","CheckpointApprovalCard","onContinue","onRevise","RevisionApprovalCard","onAccept","ConfirmApprovalCard","onAllow","onDeny","isBackground","PathAccessApprovalCard","isWrite","ChoiceApprovalCard","o","activePlanToTaskSteps","ActivePlanTaskCard","WorkdirPop","recent","anchor","onBrowse","positionStyle","isCurrent","fetchBrowse","WorkdirInputModal","initialPath","typed","setTyped","browse","setBrowse","setError","setLoading","seededRef","navigate","useCallback","trimmedTyped","canConfirm","sameAsCurrent","handleConfirm","handleTypedKey","PIN_THRESHOLD","useAutoScroll","containerRef","contentRef","getRestoreScrollTop","showJumpButton","setShowJumpButton","isPinnedRef","wasBusyRef","rafIdRef","isAtBottom","refreshJumpButton","scrollToBottom","smooth","pendingFrame","onUserGesture","ro","restore","TEXT_INPUT_SELECTOR","getTextAssistAttrs","applyTextAssistAttrs","element","attrs","applyWithin","root","useDisableTextAssist","handleFocusIn","observer","mutations","mutation","fallbackSkillDesc","scope","runAs","nextMessageTurn","max","reduce","action","argsLine","applyIncoming","collapsed","relevant","appendTextSegment","zeroUsage","removed","activePlan","pendingSteps","doneIds","keptDone","READING_TOOLS","MODIFYING_TOOLS","extractToolFiles","parsed","seen","mergeSessionFiles","existing","adds","indexByPath","changed","add","stepIds","prevWs","wsChanged","sessionName","loaded","sizeNote","u","callHit","callMiss","hasCall","segs","mutated","formatConversationMarkdown","userLabel","arg","sanitizeFilename","defaultExportFilename","session","TabRuntime","tabId","registerDispatch","onNewTab","onCloseTab","canCloseTab","onToggleTheme","sideCollapsed","ctxCollapsed","onToggleSide","onToggleCtx","tabsList","activeTabId","setActiveTabId","mobileSideOpen","onToggleMobileSide","dispatch","useReducer","toast","setToast","splashOn","setSplashOn","wdOpen","setWdOpen","wdAnchor","setWdAnchor","composerRef","threadRef","threadInnerRef","settingsOpen","setSettingsOpen","settingsPage","setSettingsPage","setJobsOpen","aboutOpen","setAboutOpen","loadingSession","setLoadingSession","workdirModalOpen","setWorkdirModalOpen","openSettingsAt","palette","sendRpc","queryMentions","previewMention","markMentionPicked","saveSettings","loadQQSettings","connectQQ","disconnectQQ","saveQQConfig","saveApiKey","addMcpSpec","spec","removeMcpSpec","newChat","pickWorkspace","openDialog","flashToast","opts","dropActiveRef","unlisten","cancelled","handle","__vitePreload","tauriBridge","paths","mentions","norm","wsNorm","send","override","btwMatch","question","skillMatch","clientId","trimmedArgs","abort","resolveConfirm","response","resolvePathAccess","resolveChoice","resolvePlan","resolveCheckpoint","resolveRevision","currentSessionRef","restoreScrollTop","timer","onScroll","initialUrlSession","urlSessionDispatched","mod","tag","conversationCopy","exportConversation","langName","workspaceLabel","firstUser","cleaned","md","filename","saveDialog","TitleBar","TabBar","NeedsSetupView","MainHead","EmptyState","match","dividerLabel","needsDivider","optionId","jobId","WinMinimize","WinMaximize","WinRestore","WinClose","sideOn","ctxOn","onExport","onClear","hasMessages","menuOpen","setMenuOpen","isMaximized","setIsMaximized","moreWrapRef","isMac","isWeb","win","fn","tabs","activeId","onNew","singleTab","wsLabel","suggestions","onSubmit","App","setTabs","dispatchersRef","pendingEventsRef","pendingDeltasRef","rafScheduledRef","tabsRef","setCurrency","setThemeStyle","storedTheme","setFontScale","setFontFamily","setSideCollapsed","setCtxCollapsed","onCur","detail","deliverToTab","buf","cleanups","flushDeltas","scheduleFlush","flushTabDeltas","subs","openTab","closeTab","nextTheme","nextStyle","setMobileSideOpen","storedStyle","platform","host","createRoot"],"ignoreList":[],"sources":["../src/lib/tauri-bridge.ts","../src/i18n/en.ts","../src/i18n/zh-CN.ts","../src/i18n/index.ts","../src/ui/shortcut.tsx","../src/CommandPalette.tsx","../src/CodeView.tsx","../src/Markdown.tsx","../src/icons.tsx","../src/theme.ts","../src/lib/session-url.ts","../src/ui/live.tsx","../src/ui/composer.tsx","../src/ui/error-boundary.tsx","../src/ui/context-panel.tsx","../src/ui/jobs-pop.tsx","../src/ui/about.tsx","../src/qq-settings.ts","../src/ui/settings.tsx","../src/ui/sidebar.tsx","../src/ui/splash.tsx","../src/ui/statusbar.tsx","../../packages/core-utils/src/compaction.ts","../../packages/core-utils/src/derive-prefix.ts","../src/ui/cards.tsx","../src/ui/extra-cards.tsx","../src/ui/thread.tsx","../src/ui/workdir-pop.tsx","../src/ui/workdir-input-modal.tsx","../src/ui/useAutoScroll.ts","../src/ui/useDisableTextAssist.ts","../src/App.tsx","../src/main.tsx"],"sourcesContent":["// Tauri API 兼容别名桥接器 (Tauri Bridge for Web/Mobile)\n// 双模式:Mock 模式(Vite 开发) + Server 模式(真实 CLI 后端)\n\ntype UnlistenFn = () => void;\ntype EventCallback<T = any> = (event: { payload: T; event: string }) => void;\n\n// 事件监听中心\nconst listeners = new Map<string, Set<EventCallback>>();\nlet eventIdCounter = 0;\nlet currentTurn = 1;\n\n// 模式检测\nconst modeMeta = document.querySelector('meta[name=\"reasonix-mode\"]');\nconst rawMode = modeMeta?.getAttribute(\"content\") ?? \"\";\nconst isServerMode = rawMode !== \"\" && rawMode !== \"__REASONIX_MODE__\";\nconst MODE = isServerMode ? \"server\" : \"mock\";\n\n/** Web vs. native dispatcher hint — `true` whenever the dashboard is served by the CLI server, false in the Tauri desktop wrapper where native dialogs work. */\nexport const isWebRuntime = isServerMode;\n\nconsole.log(`[tauri-bridge] mode=${MODE}${isServerMode ? ` mode=\"${rawMode}\"` : \"\"}`);\n\n// 事件广播\nfunction broadcast(eventName: string, payload: any) {\n const callbacks = listeners.get(eventName);\n if (callbacks) {\n for (const cb of callbacks) {\n cb({ payload, event: eventName });\n }\n }\n}\n\nfunction emitEvent(event: Record<string, any>) {\n broadcast(\"rpc:event\", { data: JSON.stringify(event) });\n}\n\n// SSE 连接(Server 模式)\nlet sse: EventSource | null = null;\nlet sseTurnStarted = false;\nlet sseReconnectAttempts = 0;\nconst SSE_MAX_RECONNECT_ATTEMPTS = 10;\nconst SSE_RECONNECT_BASE_DELAY = 1000;\n\nlet cliDisconnected = false;\n\nfunction notifyCliStatus(connected: boolean) {\n if (cliDisconnected !== connected) {\n cliDisconnected = !connected;\n if (!connected) {\n emitEvent({ type: \"status\", text: \"正在重连…\", tabId: \"tab-1\" });\n } else {\n emitEvent({ type: \"status\", text: \"连接已恢复\", tabId: \"tab-1\" });\n }\n }\n}\n\n// SSE DashboardEvent → IncomingEvent 转换\nfunction sseToIncoming(ev: any): Record<string, any>[] {\n const results: Record<string, any>[] = [];\n\n switch (ev.kind) {\n case \"assistant_delta\": {\n if (!sseTurnStarted) {\n sseTurnStarted = true;\n currentTurn++;\n results.push({\n type: \"model.turn.started\",\n tabId: \"tab-1\",\n id: ev.id,\n turn: currentTurn,\n model: \"deepseek-reasoner\",\n });\n }\n if (ev.contentDelta) {\n results.push({\n type: \"model.delta\",\n tabId: \"tab-1\",\n channel: \"content\",\n text: ev.contentDelta,\n turn: currentTurn,\n });\n }\n if (ev.reasoningDelta) {\n results.push({\n type: \"model.delta\",\n tabId: \"tab-1\",\n channel: \"reasoning\",\n text: ev.reasoningDelta,\n turn: currentTurn,\n });\n }\n break;\n }\n case \"assistant_final\": {\n // Loop's `assistant_final` fires per model iteration (mid-turn it\n // precedes tool dispatch); the real turn end is signaled by\n // `busy-change` (busy=false), handled below.\n results.push({\n type: \"model.final\",\n tabId: \"tab-1\",\n turn: currentTurn,\n content: ev.text ?? \"\",\n reasoningContent: ev.reasoning ?? \"\",\n usage: ev.usage ?? undefined,\n costUsd: ev.costUsd ?? undefined,\n });\n break;\n }\n case \"tool_start\": {\n results.push({\n type: \"tool.preparing\",\n tabId: \"tab-1\",\n turn: currentTurn,\n callId: ev.id,\n name: ev.toolName,\n });\n results.push({\n type: \"tool.intent\",\n tabId: \"tab-1\",\n turn: currentTurn,\n callId: ev.id,\n name: ev.toolName,\n args: ev.args ?? \"\",\n });\n break;\n }\n case \"tool\": {\n results.push({\n type: \"tool.result\",\n tabId: \"tab-1\",\n turn: currentTurn,\n callId: ev.id,\n name: ev.toolName,\n output: ev.content,\n ok: true,\n });\n break;\n }\n case \"user\": {\n results.push({\n type: \"user.message\",\n tabId: \"tab-1\",\n id: ev.id,\n turn: currentTurn,\n text: ev.text,\n });\n break;\n }\n case \"busy-change\": {\n if (!ev.busy && sseTurnStarted) {\n results.push({ type: \"$turn_complete\", tabId: \"tab-1\" });\n sseTurnStarted = false;\n }\n break;\n }\n case \"modal-up\": {\n const m = ev.modal;\n if (m?.kind === \"shell\") {\n results.push({\n type: \"$confirm_required\",\n tabId: \"tab-1\",\n id: m.id ?? ++eventIdCounter,\n kind: \"run_command\",\n command: m.command,\n });\n } else if (m?.kind === \"choice\") {\n results.push({\n type: \"$choice_required\",\n tabId: \"tab-1\",\n id: m.id ?? ++eventIdCounter,\n question: m.question,\n options: m.options ?? [],\n allowCustom: m.allowCustom ?? false,\n });\n } else if (m?.kind === \"plan\") {\n results.push({\n type: \"$plan_required\",\n tabId: \"tab-1\",\n id: m.id ?? ++eventIdCounter,\n plan: m.plan ?? \"\",\n summary: m.summary,\n steps: m.steps,\n });\n } else if (m?.kind === \"checkpoint\") {\n results.push({\n type: \"$checkpoint_required\",\n tabId: \"tab-1\",\n id: m.id ?? ++eventIdCounter,\n stepId: m.stepId,\n title: m.title,\n result: m.result,\n notes: m.notes,\n completed: m.completed,\n total: m.total,\n });\n }\n break;\n }\n case \"modal-down\": {\n // Modal closed — normally handled by user action response\n break;\n }\n case \"warning\":\n case \"error\": {\n results.push({\n type: \"$error\",\n tabId: \"tab-1\",\n message: ev.text,\n });\n break;\n }\n case \"status\": {\n results.push({\n type: \"status\",\n tabId: \"tab-1\",\n text: ev.text,\n });\n break;\n }\n case \"ping\":\n break; // keep-alive, no action needed\n default:\n console.warn(\"[tauri-bridge] unhandled SSE event kind:\", ev.kind);\n }\n return results;\n}\n\nfunction connectSSE(): void {\n if (sse) sse.close();\n const token = document.querySelector('meta[name=\"reasonix-token\"]')?.getAttribute(\"content\") ?? \"\";\n const sseUrl = token && token !== \"__REASONIX_TOKEN__\"\n ? `/api/events?token=${encodeURIComponent(token)}`\n : \"/api/events\";\n sse = new EventSource(sseUrl);\n sse.onmessage = (msg: MessageEvent) => {\n try {\n const dashboardEvent = JSON.parse(msg.data);\n // Token 无效时显示过期提示\n if (dashboardEvent.kind === \"error\" && dashboardEvent.text?.includes(\"token\")) {\n emitEvent({\n type: \"$error\",\n tabId: \"tab-1\",\n message: \"链接已过期,请重新从 CLI 打开\",\n });\n return;\n }\n const events = sseToIncoming(dashboardEvent);\n for (const evt of events) emitEvent(evt);\n // 成功收到事件,重置重连计数\n sseReconnectAttempts = 0;\n notifyCliStatus(true);\n } catch (err) {\n console.warn(\"[tauri-bridge] bad SSE event:\", err);\n }\n };\n sse.onerror = () => {\n console.warn(\"[tauri-bridge] SSE connection lost, retrying…\");\n sse?.close();\n sse = null;\n notifyCliStatus(false);\n\n sseReconnectAttempts++;\n if (sseReconnectAttempts > SSE_MAX_RECONNECT_ATTEMPTS) {\n emitEvent({\n type: \"$error\",\n tabId: \"tab-1\",\n message: \"CLI 已停止,请重新启动\",\n });\n return;\n }\n\n const delay = SSE_RECONNECT_BASE_DELAY * Math.pow(2, sseReconnectAttempts - 1);\n setTimeout(connectSSE, Math.min(delay, 30000));\n };\n\n // SSE 连接成功后,开始定期轮询 overview 更新 balance/stats\n startStatsPolling();\n}\n\n// 定期轮询 stats/balance\nlet statsPollTimer: ReturnType<typeof setInterval> | null = null;\n\nfunction startStatsPolling(): void {\n if (statsPollTimer) clearInterval(statsPollTimer);\n // 每 5 秒轮询一次 overview 获取最新 stats/balance\n statsPollTimer = setInterval(async () => {\n try {\n const overview = await apiFetch(\"overview\");\n if (overview?.stats) {\n const stats = overview.stats;\n // 更新 balance\n if (stats.balance) {\n const firstBalance = stats.balance[0];\n if (firstBalance) {\n emitEvent({\n type: \"$balance\",\n tabId: \"tab-1\",\n currency: firstBalance.currency,\n total: parseFloat(firstBalance.total_balance) || 0,\n isAvailable: true,\n });\n }\n }\n // 更新 usage stats(缓存命中率、tokens、金额)\n const totalTokens = Math.round(\n stats.totalCostUsd > 0 ? (stats.cacheHitRatio * 10000) : 0\n );\n // 通过 $settings 事件附带更新 usage 相关信息\n // 注意:usage 主要由 model.final 事件更新,这里只更新 balance\n }\n } catch {\n // 静默失败,等待下次轮询\n }\n }, 5000);\n}\n\n// REST API 辅助\nasync function apiFetch(endpoint: string, options?: RequestInit): Promise<any> {\n const token = document.querySelector('meta[name=\"reasonix-token\"]')?.getAttribute(\"content\");\n const headers: Record<string, string> = {\n ...(options?.headers as Record<string, string> ?? {}),\n };\n if (token && token !== \"__REASONIX_TOKEN__\") {\n headers[\"x-reasonix-token\"] = token;\n }\n if (options?.body && !headers[\"content-type\"]) {\n headers[\"content-type\"] = \"application/json\";\n }\n const res = await fetch(`/api/${endpoint}`, { ...options, headers });\n if (res.status === 204) return null;\n const text = await res.text();\n try { return JSON.parse(text); } catch { return text; }\n}\n\nfunction emitServerSettings(settings: any, overview?: any): void {\n emitEvent({\n type: \"$settings\",\n tabId: \"tab-1\",\n reasoningEffort: settings?.reasoningEffort ?? overview?.reasoningEffort ?? \"high\",\n editMode: settings?.editMode ?? overview?.editMode ?? \"review\",\n budgetUsd: settings?.budgetUsd ?? overview?.budgetUsd ?? null,\n workspaceDir: overview?.cwd ?? \"\",\n recentWorkspaces: [],\n model: overview?.model ?? settings?.model ?? \"deepseek-v4-flash\",\n editor: \"code\",\n webSearchEngine: settings?.webSearchEngine ?? \"bing\",\n subagentModels: settings?.subagentModels ?? {},\n version: overview?.version ?? \"\",\n baseUrl: settings?.baseUrl ?? \"\",\n apiKeyPrefix: settings?.apiKey ?? \"\",\n });\n}\n\n// 初始化 Server 状态\nasync function serverInit(): Promise<void> {\n document.documentElement.dataset.web = \"true\";\n\n // 加载初始设置和会话;overview 提供 workspace 等信息\n let wsDir = \"\";\n try {\n const [settings, sessionsData, overview] = await Promise.all([\n apiFetch(\"settings\"),\n apiFetch(\"sessions\"),\n apiFetch(\"overview\"),\n ]);\n wsDir = overview?.cwd ?? \"\";\n if (settings) emitServerSettings(settings, overview);\n if (sessionsData?.sessions) {\n const items = sessionsData.sessions.map((s: any) => ({\n name: s.name,\n messageCount: s.messageCount,\n mtime: new Date(s.mtime).toISOString(),\n summary: s.summary,\n }));\n emitEvent({\n type: \"$sessions\",\n tabId: \"tab-1\",\n items,\n });\n }\n // 从 overview 中提取 balance 和 stats\n const stats = overview?.stats;\n if (stats?.balance) {\n const firstBalance = stats.balance[0];\n if (firstBalance) {\n emitEvent({\n type: \"$balance\",\n tabId: \"tab-1\",\n currency: firstBalance.currency,\n total: parseFloat(firstBalance.total_balance) || 0,\n isAvailable: true,\n });\n }\n }\n } catch (err) {\n console.warn(\"[tauri-bridge] server init failed:\", err);\n }\n\n emitEvent({ type: \"$ready\", tabId: \"tab-1\" });\n emitEvent({\n type: \"$tab_opened\",\n tabId: \"tab-1\",\n workspaceDir: wsDir,\n active: true,\n });\n\n // 连接 SSE\n connectSSE();\n}\n\n// RPC 命令 → REST API 映射\nasync function serverRpc(payload: Record<string, any>): Promise<void> {\n const cmd = payload.cmd;\n\n switch (cmd) {\n case \"user_input\": {\n const result = await apiFetch(\"submit\", {\n method: \"POST\",\n body: JSON.stringify({ prompt: payload.text }),\n }).catch((err) => {\n console.warn(\"[tauri-bridge] submit failed:\", err);\n return null;\n });\n // 提交失败时通知前端保留草稿\n if (!result?.accepted) {\n emitEvent({\n type: \"$error\",\n tabId: \"tab-1\",\n message: result?.reason ?? \"提交失败,请重试\",\n });\n }\n break;\n }\n case \"abort\": {\n await apiFetch(\"abort\", { method: \"POST\" }).catch(() => {});\n break;\n }\n case \"session_list\": {\n try {\n const data = await apiFetch(\"sessions\");\n if (data?.sessions) {\n const items = data.sessions.map((s: any) => ({\n name: s.name,\n messageCount: s.messageCount,\n mtime: new Date(s.mtime).toISOString(),\n summary: s.summary,\n }));\n emitEvent({ type: \"$sessions\", tabId: \"tab-1\", items });\n }\n } catch { /* ignore */ }\n break;\n }\n case \"session_load\": {\n try {\n const switchData = await apiFetch(`sessions/${encodeURIComponent(payload.name)}/switch`, { method: \"POST\" });\n if (!switchData?.ok) {\n console.warn(\"[tauri-bridge] session switch failed:\", payload.name, switchData);\n break;\n }\n const data = await apiFetch(`sessions/${encodeURIComponent(payload.name)}`);\n if (!Array.isArray(data?.messages)) {\n console.warn(\"[tauri-bridge] session_load: GET response missing messages\", data);\n break;\n }\n const raw = data.messages as any[];\n // Pre-pass: map tool-result rows by their call id so we can stitch\n // them into the assistant message that issued the call. Without\n // this, every tool segment in the replay shows \"(no result)\".\n const toolResults = new Map<string, { content: string; name?: string }>();\n for (const m of raw) {\n if (m?.role === \"tool\" && typeof m.toolCallId === \"string\") {\n toolResults.set(m.toolCallId, {\n content: typeof m.content === \"string\" ? m.content : \"\",\n name: typeof m.toolName === \"string\" ? m.toolName : undefined,\n });\n }\n }\n const messages: any[] = [];\n for (const m of raw) {\n if (m?.role === \"user\") {\n messages.push({ kind: \"user\" as const, text: m.content ?? \"\" });\n continue;\n }\n if (m?.role === \"assistant\") {\n const segments: any[] = [];\n if (typeof m.reasoning === \"string\" && m.reasoning.length > 0) {\n segments.push({ kind: \"reasoning\" as const, text: m.reasoning });\n }\n if (typeof m.content === \"string\" && m.content.length > 0) {\n segments.push({ kind: \"text\" as const, text: m.content });\n }\n if (Array.isArray(m.toolCalls)) {\n for (const tc of m.toolCalls) {\n const result = toolResults.get(tc.id);\n segments.push({\n kind: \"tool\" as const,\n callId: tc.id,\n name: tc.name || result?.name || \"tool\",\n args: tc.arguments ?? \"\",\n startedAt: 0,\n result: result?.content,\n ok: result != null,\n durationMs: 0,\n });\n }\n }\n messages.push({\n kind: \"assistant\" as const,\n turn: m.turn ?? 0,\n segments,\n pending: false,\n });\n }\n // tool-role messages are absorbed into their matching assistant segment above.\n }\n emitEvent({\n type: \"$session_loaded\",\n tabId: \"tab-1\",\n name: payload.name,\n messages,\n carryover: { totalCostUsd: 0, cacheHitTokens: 0, cacheMissTokens: 0 },\n });\n } catch (err) {\n console.warn(\"[tauri-bridge] session load failed:\", err);\n }\n break;\n }\n case \"session_delete\": {\n try {\n await apiFetch(`sessions/${encodeURIComponent(payload.name)}`, { method: \"DELETE\" });\n // 删除后刷新列表\n const data = await apiFetch(\"sessions\");\n if (data?.sessions) {\n const items = data.sessions.map((s: any) => ({\n name: s.name,\n messageCount: s.messageCount,\n mtime: new Date(s.mtime).toISOString(),\n summary: s.summary,\n }));\n emitEvent({ type: \"$sessions\", tabId: \"tab-1\", items });\n }\n } catch { /* ignore */ }\n break;\n }\n case \"new_chat\": {\n try {\n const data = await apiFetch(\"sessions/new\", { method: \"POST\" });\n if (data?.ok) {\n const newName = typeof data.name === \"string\" ? data.name : \"default\";\n // Treat a fresh session like a loaded-empty session so the reducer\n // resets state.currentSession + messages. `$session_empty` is for\n // \"file exists but unparseable\" and would render a scary error.\n emitEvent({\n type: \"$session_loaded\",\n tabId: \"tab-1\",\n name: newName,\n messages: [],\n carryover: { totalCostUsd: 0, cacheHitTokens: 0, cacheMissTokens: 0 },\n });\n const listData = await apiFetch(\"sessions\");\n if (listData?.sessions) {\n const items = listData.sessions.map((s: any) => ({\n name: s.name,\n messageCount: s.messageCount,\n mtime: new Date(s.mtime).toISOString(),\n summary: s.summary,\n }));\n emitEvent({ type: \"$sessions\", tabId: \"tab-1\", items });\n }\n }\n } catch { /* fallback */ }\n break;\n }\n case \"settings_get\": {\n try {\n const [settings, overview] = await Promise.all([apiFetch(\"settings\"), apiFetch(\"overview\")]);\n if (settings) emitServerSettings(settings, overview);\n } catch { /* ignore */ }\n break;\n }\n case \"settings_save\": {\n try {\n await apiFetch(\"settings\", {\n method: \"POST\",\n body: JSON.stringify(payload),\n });\n // 保存后主动拉取最新设置以同步 UI\n const [settings, overview] = await Promise.all([apiFetch(\"settings\"), apiFetch(\"overview\")]);\n if (settings) emitServerSettings(settings, overview);\n } catch { /* ignore */ }\n break;\n }\n case \"setup_save_key\": {\n await apiFetch(\"settings\", {\n method: \"POST\",\n body: JSON.stringify({ apiKey: payload.key }),\n }).catch(() => {});\n break;\n }\n case \"confirm_response\": {\n await apiFetch(\"modal\", {\n method: \"POST\",\n body: JSON.stringify({ id: payload.id, response: payload.response }),\n }).catch(() => {});\n break;\n }\n case \"choice_response\": {\n await apiFetch(\"modal\", {\n method: \"POST\",\n body: JSON.stringify({ id: payload.id, response: payload.response }),\n }).catch(() => {});\n break;\n }\n case \"plan_response\": {\n await apiFetch(\"modal\", {\n method: \"POST\",\n body: JSON.stringify({ id: payload.id, response: payload.response }),\n }).catch(() => {});\n break;\n }\n case \"checkpoint_response\": {\n await apiFetch(\"modal\", {\n method: \"POST\",\n body: JSON.stringify({ id: payload.id, response: payload.response }),\n }).catch(() => {});\n break;\n }\n case \"revision_response\": {\n await apiFetch(\"modal\", {\n method: \"POST\",\n body: JSON.stringify({ id: payload.id, response: payload.response }),\n }).catch(() => {});\n break;\n }\n case \"jobs_list\": {\n try {\n const data = await apiFetch(\"usage\");\n if (data?.jobs) {\n emitEvent({ type: \"$jobs\", tabId: \"tab-1\", items: data.jobs });\n }\n } catch { /* ignore */ }\n break;\n }\n case \"mention_query\": {\n try {\n const data = await apiFetch(`files/search?q=${encodeURIComponent(payload.query)}&nonce=${payload.nonce}`);\n if (data) {\n emitEvent({\n type: \"$mention_results\",\n tabId: \"tab-1\",\n nonce: payload.nonce,\n query: payload.query,\n results: data.results ?? [],\n });\n }\n } catch { /* ignore */ }\n break;\n }\n case \"mention_preview\": {\n try {\n const data = await apiFetch(`file-read?path=${encodeURIComponent(payload.path)}&nonce=${payload.nonce}`);\n if (data) {\n emitEvent({\n type: \"$mention_preview\",\n tabId: \"tab-1\",\n nonce: payload.nonce,\n path: payload.path,\n head: data.head ?? \"\",\n totalLines: data.totalLines ?? 0,\n });\n }\n } catch { /* ignore */ }\n break;\n }\n // ── 桌面端特有操作(Web 版无操作或静默忽略) ──\n case \"qq_status_get\":\n case \"qq_connect\":\n case \"qq_disconnect\":\n case \"qq_config_save\":\n case \"tab_activate\":\n case \"tab_open\":\n case \"tab_close\":\n case \"mention_picked\":\n case \"btw\": {\n // 这些命令在 Web Server 模式下无对应 REST API,静默忽略\n break;\n }\n case \"jobs_stop\": {\n try { await apiFetch(`jobs/${payload.jobId}/stop`, { method: \"POST\" }); } catch {}\n break;\n }\n case \"jobs_stop_all\": {\n try { await apiFetch(\"jobs/stop-all\", { method: \"POST\" }); } catch {}\n break;\n }\n case \"compact_history\": {\n try { await apiFetch(\"messages/compact\", { method: \"POST\" }); } catch {}\n break;\n }\n case \"retry\": {\n try { await apiFetch(\"submit\", { method: \"POST\", body: JSON.stringify({ retry: true }) }); } catch {}\n break;\n }\n case \"skill_run\": {\n const body: Record<string, any> = { name: payload.name };\n if (payload.args) body.args = payload.args;\n try { await apiFetch(\"skills/run\", { method: \"POST\", body: JSON.stringify(body) }); } catch {}\n break;\n }\n case \"mcp_specs_add\":\n case \"mcp_specs_remove\": {\n // MCP 操作通过 REST API 管理\n try {\n await apiFetch(\"mcp\", {\n method: \"POST\",\n body: JSON.stringify({ action: cmd === \"mcp_specs_add\" ? \"add\" : \"remove\", spec: payload.spec }),\n });\n } catch {}\n break;\n }\n default:\n console.warn(\"[tauri-bridge] unhandled RPC cmd:\", cmd);\n }\n}\n\n// // ═══ 导出接口(Mock + Server 双模式)\n// Tauri core API\nexport async function invoke(cmd: string, args?: any): Promise<any> {\n console.log(`[tauri-bridge] invoke -> cmd: ${cmd}${args ? \" \" + JSON.stringify(args) : \"\"}`);\n\n if (MODE === \"server\") {\n if (cmd === \"rpc_spawn\") {\n serverInit().catch(console.warn);\n return Promise.resolve();\n }\n if (cmd === \"rpc_send\") {\n const payload = JSON.parse(args.line);\n payload.tabId = payload.tabId ?? \"tab-1\";\n serverRpc(payload).catch(console.warn);\n return Promise.resolve();\n }\n if (cmd === \"open_in_editor\") {\n console.log(\"[tauri-bridge] open in editor:\", args);\n return Promise.resolve();\n }\n return Promise.resolve();\n }\n\n // Mock mode\n if (cmd === \"rpc_spawn\") {\n mockSetupAndReady();\n return Promise.resolve();\n }\n\n if (cmd === \"rpc_send\") {\n const payload = JSON.parse(args.line);\n if (payload.cmd === \"user_input\") {\n emitEvent({\n type: \"user.message\", tabId: \"tab-1\",\n id: Date.now(), ts: new Date().toISOString(), turn: 2, text: payload.text,\n });\n mockAssistantTurn(payload.text);\n } else if (payload.cmd === \"session_list\") {\n emitEvent({ type: \"$sessions\", tabId: \"tab-1\", items: mockSessions });\n } else if (payload.cmd === \"session_load\") {\n emitEvent({\n type: \"$session_loaded\", tabId: \"tab-1\", name: payload.name,\n messages: mockMessages,\n carryover: { totalCostUsd: 0.045, cacheHitTokens: 2500, cacheMissTokens: 1400 },\n });\n } else if (payload.cmd === \"new_chat\") {\n emitEvent({ type: \"$session_empty\", tabId: \"tab-1\", name: \"desktop-new-session\", sizeBytes: 0 });\n } else if (payload.cmd === \"settings_get\") {\n emitEvent({ type: \"$settings\", tabId: \"tab-1\", ...mockSettings });\n }\n return Promise.resolve();\n }\n\n if (cmd === \"open_in_editor\") {\n console.log(\"[tauri-bridge] open in editor simulation:\", args);\n return Promise.resolve();\n }\n\n return Promise.resolve();\n}\n\n// 2. @tauri-apps/api/event\nexport async function listen<T = any>(\n eventName: string,\n callback: EventCallback<T>\n): Promise<UnlistenFn> {\n let bucket = listeners.get(eventName);\n if (!bucket) {\n bucket = new Set();\n listeners.set(eventName, bucket);\n }\n bucket.add(callback);\n return () => {\n const b = listeners.get(eventName);\n if (b) b.delete(callback);\n };\n}\n\n// 3a. @tauri-apps/api/webview\nexport function getCurrentWebview(): any {\n return {\n onDragDropEvent: async (_callback: any): Promise<() => void> => {\n console.log(\"[tauri-bridge] onDragDropEvent (no-op in web)\");\n return () => {};\n },\n };\n}\n\n// 3b. @tauri-apps/api/window\nexport function getCurrentWindow(): any {\n return {\n isMaximized: async () => false,\n minimize: async () => { console.log(\"[tauri-bridge] minimize (no-op)\"); },\n close: async () => { console.log(\"[tauri-bridge] close (no-op)\"); },\n toggleMaximize: async () => { console.log(\"[tauri-bridge] toggleMaximize (no-op)\"); },\n listen: async (_event: string, _callback: any): Promise<() => void> => () => {},\n label: \"main\",\n };\n}\n\n// 4. @tauri-apps/plugin-dialog\nexport async function open(options?: any): Promise<any> {\n console.log(\"[tauri-bridge] dialog open:\", options);\n return Promise.resolve(\"\");\n}\n\nexport async function save(options?: any): Promise<any> {\n console.log(\"[tauri-bridge] dialog save:\", options);\n return Promise.resolve(\"\");\n}\n\n// 5. @tauri-apps/plugin-opener\nexport async function openUrl(url: string): Promise<void> {\n console.log(`[tauri-bridge] open url -> ${url}`);\n window.open(url, \"_blank\");\n return Promise.resolve();\n}\n\nexport async function openPath(path: string): Promise<void> {\n console.log(`[tauri-bridge] open path -> ${path}`);\n return Promise.resolve();\n}\n\n// 6. @tauri-apps/plugin-process\nexport async function relaunch(): Promise<void> {\n console.log(\"[tauri-bridge] process relaunch (reload page)\");\n window.location.reload();\n return Promise.resolve();\n}\n\n// // ═══ Mock 数据(仅 Vite 开发模式使用)\n// \nconst mockSessions = [\n { name: \"desktop-20260520-1\", messageCount: 8, mtime: new Date().toISOString(), summary: \"项目工程模块重构及自适应 UI 设计\" },\n { name: \"desktop-20260519-2\", messageCount: 14, mtime: new Date(Date.now() - 86400000).toISOString(), summary: \"编写 WebSocket 桥接与 RPC 行协议对接逻辑\" },\n { name: \"desktop-20260518-3\", messageCount: 4, mtime: new Date(Date.now() - 172800000).toISOString(), summary: \"测试移动端 TextArea 与 Dynamic Viewport\" },\n];\n\nconst mockSettings = {\n reasoningEffort: \"high\", editMode: \"review\", budgetUsd: null,\n workspaceDir: \"\", recentWorkspaces: [],\n model: \"deepseek-v4-flash\", version: \"0.47.2\",\n};\n\nconst mockMessages: any[] = [\n { kind: \"user\", text: \"你好 Reasonix,帮我列出这个项目的主要技术栈以及前端架构体系。\" },\n {\n kind: \"assistant\",\n turn: 1,\n segments: [\n { kind: \"reasoning\", text: \"用户询问项目的技术栈和前端架构。\" },\n { kind: \"text\", text: \"你好!**DeepSeek-Reasonix** 是一个以 DeepSeek 为内核的智能代码助手…\" },\n ],\n pending: false,\n },\n];\n\nfunction mockAssistantTurn(_promptText: string) {\n emitEvent({ type: \"status\", text: \"DeepSeek R1 思考中...\", tabId: \"tab-1\" });\n setTimeout(() => {\n emitEvent({\n type: \"model.turn.started\", tabId: \"tab-1\", id: Date.now(),\n turn: 2, model: \"deepseek-reasoner\", reasoningEffort: \"high\",\n });\n }, 600);\n // reasoning deltas\n const lines = [\"分析用户的输入内容。\\n\", \"用户要求提供自适应 UI 重构的验证指令。\\n\"];\n let delay = 1200;\n lines.forEach((line) => {\n setTimeout(() => {\n emitEvent({ type: \"model.delta\", tabId: \"tab-1\", channel: \"reasoning\", text: line, turn: 2 });\n }, delay);\n delay += 800;\n });\n // tool call\n setTimeout(() => {\n emitEvent({ type: \"tool.preparing\", tabId: \"tab-1\", name: \"list_dir\", callId: \"call_12345\" });\n }, delay);\n delay += 500;\n setTimeout(() => {\n emitEvent({\n type: \"tool.intent\", tabId: \"tab-1\", name: \"list_dir\",\n args: JSON.stringify({ DirectoryPath: \"d:/AI/workspace/dashboard\" }), callId: \"call_12345\",\n });\n }, delay);\n delay += 1000;\n setTimeout(() => {\n emitEvent({\n type: \"tool.result\", tabId: \"tab-1\", name: \"list_dir\", ok: true,\n output: JSON.stringify([{ name: \"package.json\", sizeBytes: 864 }, { name: \"src\", isDir: true }]),\n callId: \"call_12345\",\n });\n }, delay);\n delay += 800;\n // text response\n const chunks = [\n \"您的 dashboard 目录结构已确认。在**独立 Mock 开发预览阶段**,\\n\",\n \"您可以使用 `npm run dev` 启动 Vite 开发服务,\\n\",\n \"配合 Chrome 设备模拟器或真实手机进行移动端自适应效果验证。\\n\",\n \"手机端支持侧滑拉出会话抽屉,输入框紧贴虚拟键盘。\",\n ];\n chunks.forEach((chunk) => {\n setTimeout(() => {\n emitEvent({ type: \"model.delta\", tabId: \"tab-1\", channel: \"content\", text: chunk, turn: 2 });\n }, delay);\n delay += 500;\n });\n setTimeout(() => {\n emitEvent({ type: \"model.final\", tabId: \"tab-1\", turn: 2, content: chunks.join(\"\"), reasoningContent: lines.join(\"\"), costUsd: 0.002 });\n emitEvent({ type: \"$turn_complete\", tabId: \"tab-1\" });\n }, delay + 400);\n}\n\nfunction mockSetupAndReady() {\n document.documentElement.dataset.web = \"true\";\n setTimeout(() => emitEvent({ type: \"$ready\", tabId: \"tab-1\" }), 100);\n setTimeout(() => {\n emitEvent({ type: \"$tab_opened\", tabId: \"tab-1\", workspaceDir: \"d:\\\\AI\\\\workspace\", active: true });\n }, 150);\n setTimeout(() => emitEvent({ type: \"$settings\", tabId: \"tab-1\", ...mockSettings }), 200);\n setTimeout(() => emitEvent({ type: \"$sessions\", tabId: \"tab-1\", items: mockSessions }), 350);\n}\n","export const en = {\n app: {\n sectionWorkspace: \"workspace\",\n sectionObserve: \"observe\",\n sectionConfigure: \"configure\",\n tabChat: \"Chat\",\n tabPlans: \"Plans\",\n tabSessions: \"Sessions\",\n tabOverview: \"Overview\",\n tabUsage: \"Usage\",\n tabSystem: \"System\",\n tabSemantic: \"Semantic\",\n tabTools: \"Tools\",\n tabPermissions: \"Permissions\",\n tabMcp: \"MCP\",\n tabSkills: \"Skills\",\n tabMemory: \"Memory\",\n tabHooks: \"Hooks\",\n tabSettings: \"Settings\",\n sectionChanges: \"Changes\",\n tabChanges: \"Changes\",\n footer: \"127.0.0.1 only · token-gated\",\n themeToggle: \"Toggle theme\",\n themeLight: \"Light\",\n themeDark: \"Dark\",\n skill: {\n scope: {\n builtin: \"Built-in\",\n global: \"Global\",\n project: \"Project\",\n },\n runAs: {\n subagent: \"Subagent\",\n inline: \"Inline\",\n },\n generic: \"Skill\",\n },\n exportReasoningSummary: \"Reasoning Summary\",\n exportToolLabel: \"Tool Calls\",\n exportUserLabel: \"User Messages\",\n empty: {\n currentWorkspace: \"Current workspace\",\n selectWorkspace: \"Select a workspace to get started\",\n suggestion0: \"Start a new conversation\",\n suggestion1: \"Open settings\",\n suggestion2: \"View overview\",\n suggestion3: \"Browse sessions\",\n welcome: \"Welcome to Reasonix\",\n },\n errorLabel: \"Error\",\n connecting: \"Connecting…\",\n session: {\n format: \"Session\",\n new: \"New Session\",\n },\n setup: {\n choose: \"Choose a workspace\",\n description: \"Select a workspace to start working\",\n notSelected: \"No workspace selected\",\n saveAndStart: \"Save & Start\",\n welcome: \"Welcome\",\n workspace: \"Workspace\",\n },\n tab: {\n newTab: \"+ New Tab\",\n newTabTitle: \"Open a new tab\",\n },\n titlebar: {\n clearChat: \"Clear Chat\",\n close: \"Close\",\n commandPalette: \"Command Palette\",\n contextPanel: \"Context Panel\",\n copyMd: \"Copy as Markdown\",\n exportMd: \"Export as Markdown\",\n maximize: \"Maximize\",\n minimize: \"Minimize\",\n more: \"More\",\n restore: \"Restore\",\n settings: \"Settings\",\n sidebar: \"Sidebar\",\n windowControls: \"Window Controls\",\n },\n toast: {\n cleared: \"Chat cleared\",\n copied: \"Copied to clipboard\",\n copiedMd: \"Copied as Markdown\",\n emptySession: \"No messages to export\",\n exportDialogTitle: \"Export Chat\",\n exportedMd: \"Exported as Markdown\",\n exportFailed: \"Export failed\",\n langSwitched: \"Language switched\",\n modelSwitched: \"Model → {model}\",\n effortSwitched: \"Effort → {effort}\",\n modeSwitched: \"Mode switched\",\n newSession: \"New session created\",\n },\n yolo: {\n toast: \"YOLO mode enabled\",\n },\n cmd: {\n abort: \"Abort\",\n btw: \"BTW\",\n clearChat: \"Clear Chat\",\n compact: \"Compact\",\n copyLast: \"Copy Last\",\n exportMd: \"Export as Markdown\",\n feedback: \"Feedback\",\n help: \"Help\",\n newSession: \"New Session\",\n retry: \"Retry\",\n switchModel: \"Switch Model\",\n toggleCurrency: \"Toggle Currency\",\n toggleLang: \"Toggle Language\",\n toggleTheme: \"Toggle Theme\",\n },\n header: {\n abort: \"Abort\",\n clickToSelect: \"Click to select\",\n copy: \"Copy\",\n copyMd: \"Copy as Markdown\",\n export: \"Export\",\n exportMd: \"Export as Markdown\",\n newChat: \"New Chat\",\n noWorkspace: \"No workspace\",\n running: \"Running…\",\n },\n jumpToBottom: \"Jump to bottom\",\n langEN: \"English\",\n langZH: \"中文\",\n splashSubtitle: \"AI-powered coding assistant\",\n },\n changes: {\n chatPlaceholder: \"Ask about your code...\",\n chatWelcome: \"Changes — ask questions about your project files.\",\n chatSend: \"Send\",\n viewerPlaceholder: \"Select a file to view\",\n treeEmpty: \"(empty)\",\n tabClose: \"Close tab\",\n newConversation: \"New\",\n clearConversation: \"Clear\",\n newTitle: \"/new — wipe conversation context\",\n clearTitle: \"/clear — wipe visible scrollback\",\n newConfirmBusy: \"A turn is in flight. Abort and start a new conversation?\",\n newConfirm: \"Clear current conversation and start fresh?\",\n newToast: \"new conversation\",\n clearToast: \"scrollback cleared\",\n newFailed: \"/new failed: {error}\",\n clearFailed: \"/clear failed: {error}\",\n chatSendBtn: \"Send\",\n fileTreeTitle: \"Files\",\n codeViewerTitle: \"Code Viewer\",\n chatPanelTitle: \"Chat\",\n loadingFiles: \"Loading project files…\",\n review: \"Review\",\n allFiles: \"All Files\",\n changes: \"changes\",\n commentLabel: \"Commenting on line\",\n commentPlaceholder: \"Add a comment…\",\n commentCancel: \"Cancel\",\n commentSubmit: \"Comment\",\n commentLine: \"Line\",\n commentEdit: \"Edit\",\n commentDelete: \"Delete\",\n diffSourceGit: \"Git changes\",\n diffSourceSession: \"Previous session\",\n diffSourceCheckpoint: \"Checkpoint\",\n checkpointEmpty: \"No checkpoints in this workspace yet.\",\n restoreBtn: \"Restore\",\n restoreConfirm: 'Restore \"{name}\"? This will overwrite current files.',\n deleteBtn: \"Delete\",\n deleteConfirm: 'Delete checkpoint \"{name}\"? Snapshot will be removed, files stay unchanged.',\n createBtn: \"Snapshot\",\n createPlaceholder: \"name for snapshot…\",\n backToList: \"back to list\",\n reviewEmpty: \"No pending reviews.\",\n diffStyleUnified: \"Unified\",\n diffStyleSplit: \"Split\",\n expandAll: \"Expand all\",\n collapseAll: \"Collapse all\",\n createFailed: \"create failed\",\n restoreFailed: \"restore failed\",\n deleteFailed: \"delete failed\",\n },\n common: {\n loading: \"loading…\",\n loadingFailed: \"{name} failed: {error}\",\n back: \"← back\",\n save: \"Save\",\n remove: \"remove\",\n cancel: \"Cancel\",\n delete: \"Delete\",\n add: \"Add\",\n confirm: \"Confirm\",\n noData: \"No {name} yet.\",\n all: \"all\",\n yes: \"yes\",\n no: \"no\",\n on: \"ON\",\n off: \"off\",\n enabled: \"enabled\",\n disabled: \"disabled\",\n },\n settings: {\n title: \"Settings\",\n loading: \"loading settings…\",\n saved: \"saved: {fields}\",\n sectionApi: \"DeepSeek API\",\n apiKey: \"API key\",\n apiKeyNotSet: \"Not set\",\n apiKeySave: \"Save key\",\n apiKeySet: \"Set\",\n apiSection: \"API Configuration\",\n notSet: \"(not set)\",\n replace: \"replace\",\n pasteKey: \"paste a fresh sk-… token\",\n saveKey: \"Save key\",\n baseUrl: \"base url\",\n baseUrlPlaceholder: \"https://api.deepseek.com (default)\",\n baseUrlHint: \"Base URL for API requests\",\n sectionDefaults: \"Defaults\",\n effortSection: \"Reasoning effort\",\n modelCustom: \"Custom model id\",\n modelCustomHint: \"Any OpenAI-compatible id your endpoint serves (vLLM, Ollama, Together, …).\",\n modelCustomActive: \"Currently running on a custom id: {model}\",\n appliesNextTurn: \"applies next turn\",\n effort: \"effort\",\n effortMax: \"max (DeepSeek extension — rejected by stock OpenAI / vLLM)\",\n effortHigh: \"high (safe default — vLLM / Azure compatible)\",\n effortMedium: \"medium\",\n effortLow: \"low (fastest)\",\n webSearch: \"web search\",\n webSearchNote: \"web_fetch + web_search tools\",\n webSearchEngine: \"search engine\",\n webSearchEngineBing: \"bing — default, works from CN without proxy\",\n webSearchEngineSearxng: \"searxng — self-hosted (set endpoint via /se searxng <url>)\",\n webSearchEngineMetaso: \"metaso — 100/day free (CN-friendly, free key at metaso.cn)\",\n webSearchEngineTavily: \"tavily — 1000/mo free (set TAVILY_API_KEY)\",\n webSearchEnginePerplexity: \"perplexity — AI-native (set PERPLEXITY_API_KEY)\",\n webSearchEngineExa: \"exa — AI-native 1000/mo free (set EXA_API_KEY)\",\n webSearchEngineNote: \"applies to the next web_search call\",\n sectionBudget: \"Budget\",\n budget: \"Budget\",\n budgetHint: \"Set spending limits\",\n budgetPlaceholder: \"Enter budget amount\",\n budgetOf: \"of\",\n budgetSetCap: \"set a cap\",\n budgetCustom: \"custom\",\n budgetBumpHint: \"bump the cap to keep going\",\n budgetClear: \"Clear cap\",\n budgetIdleLine: \"warns at 80% · refuses past 100%\",\n budgetWarnLine: \"approaching cap — loop will refuse past 100%\",\n budgetRefusing: \"cap exhausted — next turn refused until bumped or cleared\",\n sectionLoop: \"Loop\",\n loopIdleHint: \"Auto-resubmit a prompt on a fixed interval.\",\n loopCostHint: \"Each iteration costs ~{cost} (last turn).\",\n loopInterval: \"interval\",\n loopCustom: \"custom\",\n loopRangeError: \"interval must fall in 5s..6h\",\n loopPrompt: \"prompt\",\n loopPromptPlaceholder: \"e.g. check the deploy status and report any errors\",\n loopStart: \"Start loop\",\n loopStop: \"Stop\",\n loopRunning: \"running\",\n loopIter: \"iter {iter}\",\n loopFiresIn: \"fires in {remaining}\",\n sectionSkills: \"Skills\",\n skillPaths: \"skill paths\",\n skillPathsPlaceholder: \"/path/to/skills-a, /path/to/skills-b\",\n skillPathsNote: \"comma-separated · next /new or new session\",\n skillsEmpty: \"No skills loaded\",\n skillsLoaded: \"Skills loaded\",\n subagentModelFlash: \"flash\",\n subagentModelPro: \"pro\",\n subagentModelHint: \"Model used when this skill spawns its isolated subagent\",\n sectionRuntime: \"Runtime\",\n activeModel: \"active model\",\n model: \"Model\",\n modelFlashDesc: \"Flash — always flash\",\n modelProDesc: \"Pro — always pro\",\n modelPricingLine: \"${hit} hit · ${miss} miss · ${out} out per 1M tok\",\n editMode: \"edit mode\",\n editModeNote: \"switch from the Chat tab header\",\n editModeHint: \"Configure edit mode\",\n showSystemEvents: \"system events\",\n showSystemEventsHint: \"Show quiet inline notices for context compaction, abort, rate-limit.\",\n shown: \"shown\",\n hidden: \"hidden\",\n sectionLanguage: \"Language\",\n language: \"language\",\n languageHint: \"Switch language\",\n langEn: \"English\",\n langZhCn: \"简体中文\",\n appMode: \"App mode\",\n appearanceSection: \"Appearance\",\n behaviorSection: \"Behavior\",\n ruleAutoApprovalHint: \"Configure auto-approval rules\",\n ruleAutoApprovalSection: \"Auto-approval Rules\",\n theme: \"Theme\",\n themeDark: \"Dark\",\n themeHint: \"Switch between light and dark themes\",\n themeLight: \"Light\",\n themeStyle: \"Theme style\",\n themeStyleHint: \"Choose theme style\",\n themeStyleGraphite: \"Graphite\",\n themeStyleGraphiteDesc: \"Cool dark neutrals — best for long sessions.\",\n themeStyleSandstone: \"Sandstone\",\n themeStyleSandstoneDesc: \"Warm light tones — easy on bright rooms.\",\n themeStylePorcelain: \"Porcelain\",\n themeStylePorcelainDesc: \"Clean light with extra contrast.\",\n themeStyleMidnight: \"Midnight\",\n themeStyleMidnightDesc: \"Deep dark with cooler highlights.\",\n pageGeneralLabel: \"General\",\n pageGeneralDesc: \"Theme, fonts, language and workspace.\",\n pageModelsLabel: \"Models\",\n pageModelsDesc: \"Default model and reasoning effort.\",\n pageMcpLabel: \"MCP servers\",\n pageMcpDesc: \"Connect external tool servers.\",\n pageSkillsLabel: \"Skills\",\n pageSkillsDesc: \"User-defined skills you can run with /skill.\",\n pageMemoryLabel: \"Memory\",\n pageMemoryDesc: \"Long-lived notes carried across sessions.\",\n pageRulesLabel: \"Rules\",\n pageRulesDesc: \"Auto-approval rules for shell + path access.\",\n pageBillingLabel: \"Billing\",\n pageBillingDesc: \"API key, balance and per-session budget.\",\n pageShortcutsLabel: \"Shortcuts\",\n pageShortcutsDesc: \"Keyboard shortcuts reference.\",\n fontFamily: \"Font family\",\n fontFamilyHint: \"Choose font family\",\n fontFamilySans: \"Sans-serif\",\n fontFamilySerif: \"Serif\",\n fontFamilySystem: \"System\",\n fontScale: \"Font scale\",\n fontScaleHint: \"Adjust font size\",\n fontScaleLarge: \"Large\",\n fontScaleMedium: \"Medium\",\n fontScaleSmall: \"Small\",\n currentWorkspace: \"Current workspace\",\n defaultModelCurrent: \"Current model\",\n editor: \"Editor\",\n editorHint: \"Configure editor preferences\",\n maxOutput: \"Max output\",\n reasoningEffort: \"Reasoning effort\",\n reasoningEffortHint: \"Adjust reasoning depth\",\n sessionCost: \"Session cost\",\n balanceAvailable: \"Available\",\n balanceLabel: \"Balance\",\n balanceLow: \"Low balance\",\n cacheHitRate: \"Cache hit rate\",\n ctxWindow: \"Context window\",\n notSelected: \"Not selected\",\n parseError: \"Parse error\",\n workspaceChange: \"Change\",\n workspaceSection: \"Workspace\",\n mcpAdd: \"Add\",\n mcpAddSection: \"Add MCP Server\",\n mcpBridged: \"Bridged\",\n mcpConfigured: \"Configured\",\n mcpEmpty: \"No MCP servers\",\n mcpNotBridged: \"Not bridged\",\n mcpRemove: \"Remove\",\n mcpSpecFormat: \"JSON format\",\n mcpSpecLabel: \"Server spec\",\n memoryDesc: \"Configure memory settings\",\n memorySection: \"Memory\",\n shortcutAbort: \"Abort\",\n shortcutCloseTab: \"Close Tab\",\n shortcutCommandPalette: \"Command Palette\",\n shortcutFocusComposer: \"Focus Composer\",\n shortcutNewChat: \"New Chat\",\n shortcutNewTab: \"New Tab\",\n shortcutSettings: \"Settings\",\n shortcutSwitchTab: \"Switch Tab\",\n qqAccessAllowlist: \"Allowlist\",\n qqAccessOpen: \"Open\",\n qqAccessOwner: \"Owner\",\n qqAccessOwnerWithAllowlist: \"Owner + Allowlist\",\n qqAccessRuntime: \"Runtime\",\n qqAppId: \"App ID\",\n qqApplyAction: \"Apply\",\n qqApplyLabel: \"Apply\",\n qqAppSecret: \"App Secret\",\n qqBack: \"Back\",\n qqConfigure: \"Configure\",\n qqConfigureHint: \"Set up QQ integration\",\n qqConfigureTitle: \"QQ Configuration\",\n qqConnected: \"Connected\",\n qqConnecting: \"Connecting…\",\n qqDisconnected: \"Disconnected\",\n qqEnvironment: \"Environment\",\n qqFailed: \"Failed\",\n qqProduction: \"Production\",\n qqSandbox: \"Sandbox\",\n qqSave: \"Save\",\n qqSaveAndConnect: \"Save & Connect\",\n qqSection: \"QQ Integration\",\n qqSummaryAppId: \"App ID\",\n qqSummaryDetail: \"Details\",\n qqSummaryMissing: \"Not configured\",\n qqTitle: \"QQ Bot\",\n },\n chat: {\n modeMirror: \"TUI mirror\",\n modeView: \"session view\",\n placeholder: \"Type a prompt — Enter sends, Shift+Enter for a newline · / @ for pickers\",\n placeholderBusy: \"wait for the current turn to finish…\",\n placeholderSteerBusy: \"type to steer — commands and pickers are disabled while busy\",\n steerHint: \"message steers the current turn (added as instruction)\",\n send: \"Send\",\n new: \"New\",\n clear: \"Clear\",\n newTitle: \"/new — wipe conversation context (loop log + scrollback)\",\n clearTitle: \"/clear — wipe just visible scrollback (context kept)\",\n noConversation: \"No conversation yet. Send a prompt below to begin.\",\n newConfirmBusy: \"A turn is in flight. Abort and start a new conversation?\",\n newConfirm: \"Clear current conversation and start fresh?\",\n newToast: \"new conversation\",\n clearToast: \"scrollback cleared\",\n newFailed: \"/new failed: {error}\",\n clearFailed: \"/clear failed: {error}\",\n eventStreamError: \"event stream interrupted — reconnecting…\",\n semanticBanner: \"Semantic search isn't enabled for this project.\",\n semanticBannerDesc:\n 'Build the index once and the model can find code by meaning (\"where do we handle auth failures?\") instead of grep on exact strings.',\n semanticBannerBtn: \"Build it →\",\n semanticBannerDismiss: \"dismiss (don't show again)\",\n slashCommands: \"slash commands\",\n projectFiles: \"project files\",\n effortTitle: \"reasoning_effort — applies next turn\",\n effortMaxTitle: \"max (DeepSeek extension)\",\n effortHighTitle: \"high (safe default — vLLM / Azure compatible)\",\n effortMediumTitle: \"medium\",\n effortLowTitle: \"low (fastest)\",\n editGateTitle: \"edit gate — Shift+Tab cycles in TUI\",\n editReviewTitle: \"review — both edits and non-allowlisted shell ask first\",\n editAutoTitle: \"auto — edits auto-apply, shell still asks\",\n editYoloTitle: \"yolo — edits AND shell auto-run, allowlist bypassed\",\n railSession: \"Session\",\n railTurns: \"turns\",\n railPromptTok: \"prompt tok\",\n railCost: \"cost\",\n railCacheHit: \"cache hit\",\n railToolBudget: \"Tool budget\",\n railSpend: \"spend\",\n railActivePlan: \"Active plan\",\n railProgress: \"progress\",\n statusModel: \"model\",\n statusCtx: \"ctx\",\n statusCache: \"cache\",\n statusTurn: \"turn\",\n statusSession: \"session\",\n statusBalance: \"balance\",\n statusTurns: \"{count} turn{s}\",\n waitingStats: \"· · · waiting for live stats\",\n inflightPhase: \"{phase}\",\n inflightRunning: \"running\",\n inflightThinking: \"thinking\",\n inflightStreaming: \"streaming\",\n inflightWaiting: \"waiting\",\n inflightReasoning: \"reasoning {count} ch\",\n inflightOut: \"out {count} ch\",\n abortBtn: \"Abort (Esc)\",\n confirmBtn: \"Apply (y)\",\n rejectBtn: \"Reject (n)\",\n applyRestBtn: \"Apply rest (a)\",\n flipAutoBtn: \"Flip to AUTO (A)\",\n },\n overview: {\n loading: \"loading overview…\",\n failed: \"overview failed: {error}\",\n standaloneTitle: \"Standalone mode\",\n standaloneDesc:\n \"Read-only disk view. Start /dashboard from inside reasonix code for live session state, MCP, and tools.\",\n cockpit: \"Cockpit\",\n balance: \"balance\",\n tokens7d: \"tokens · 7d\",\n cacheHit: \"cache hit\",\n toolCalls24h: \"tool calls · 24h\",\n budget: \"budget\",\n currentSession: \"current session\",\n noSession: \"No live session — /dashboard from inside reasonix code to attach.\",\n promptTok: \"prompt tok\",\n completionTok: \"completion tok\",\n cost: \"cost\",\n costTrend: \"cost · 14 day\",\n noUsageYet: \"no usage yet\",\n dayAvg: \"/day avg\",\n recentPlans: \"recent plans\",\n noPlans: \"No plans yet — submit one with submit_plan.\",\n toolActivity: \"tool activity\",\n noToolCalls: \"No tool calls yet.\",\n toolsLoaded: \"tools loaded\",\n mcpServers: \"mcp servers\",\n editMode: \"edit mode\",\n version: \"Reasonix\",\n workingDir: \"Working directory\",\n projectRoot: \"project root\",\n noPriorData: \"no prior data\",\n stable: \"— stable\",\n vsPrior: \"{arrow} {pct}% vs prior\",\n active: \"active\",\n allUp: \"all up\",\n yoloWarning: \"all prompts bypassed\",\n checking: \"checking\",\n latest: \"latest\",\n },\n usage: {\n loading: \"loading usage…\",\n failed: \"usage failed: {error}\",\n records: \"{count} records\",\n dailyUsage: \"Daily usage\",\n dailyMeta: \"cost · cache saved · turns\",\n noData: \"No usage data yet — run a turn in reasonix chat / code / run and refresh.\",\n windows: \"Rolling windows\",\n colWindow: \"window\",\n colTurns: \"turns\",\n colCacheHit: \"cache hit\",\n colCost: \"cost (USD)\",\n colCacheSaved: \"cache saved\",\n colVsClaude: \"vs Claude\",\n colSaved: \"saved\",\n axisTime: \"time\",\n axisUsd: \"USD\",\n axisTurns: \"turns\",\n seriesCost: \"cost\",\n seriesCacheSaved: \"cache saved\",\n seriesTurns: \"turns\",\n mostUsed: \"Most used models\",\n colModel: \"model\",\n },\n sessions: {\n loading: \"loading sessions…\",\n failed: \"sessions failed: {error}\",\n noSessions: \"No saved sessions yet.\",\n filterPlaceholder: \"filter sessions\",\n msgs: \"msgs\",\n pickHint: \"Pick a session on the left to read its transcript.\",\n resumeTitle: \"Resume in TUI\",\n resumeDesc:\n \"Mid-session swap requires a restart so the message log can rewind cleanly. Quit your current session, then run:\",\n loadingTranscript: \"loading transcript…\",\n emptyTranscript: \"empty transcript.\",\n messages: \"{count} message{s}\",\n newBtn: \"New session\",\n newHint: \"Archive the current conversation and start a fresh one\",\n switchBtn: \"Switch to this session\",\n deleteBtn: \"Delete\",\n deleteConfirm: \"Delete session \\\"{name}\\\"? This removes the transcript file and cannot be undone.\",\n cantDeleteActive: \"Switch to a different session before deleting this one.\",\n attachRequired:\n \"Live session operations need an attached CLI session. Launch via reasonix chat or open the dashboard from inside a TUI session.\",\n activeChip: \"active\",\n activePill: \"active\",\n },\n tools: {\n loading: \"loading tools…\",\n failed: \"tools failed: {error}\",\n noTools: \"No tools registered.\",\n planMode: \"plan mode — writes gated\",\n colTool: \"tool\",\n colFlags: \"flags\",\n colDesc: \"description\",\n readOnly: \"read-only\",\n write: \"write\",\n flat: \"flat\",\n desc: {\n web_search:\n \"Search the public web. Returns ranked results with title, url, and snippet. Call this when the answer depends on current state — events, prices, releases, real-world status.\",\n web_fetch:\n \"Download a URL and return its visible text content (scripts/styles/nav stripped). Use after web_search when a snippet isn't enough.\",\n run_command:\n \"Run a shell command in the project root; returns combined stdout+stderr. Allowlisted read-only commands run immediately; mutations are gated by user confirmation.\",\n run_background:\n \"Spawn a long-running process and detach. Returns a job id for tailing logs, waiting for completion, or killing. Use for dev servers, watchers, and one-shot long jobs.\",\n job_output:\n \"Read the latest output of a background job. Returns the tail of the buffer and tells you whether the job is still running.\",\n wait_for_job:\n \"Block server-side until a background job finishes, bounded by timeout. Use instead of polling job_output in a loop.\",\n stop_job:\n \"Stop a background job. SIGTERM first, SIGKILL after a grace period. Safe to call on an already-exited job.\",\n list_jobs:\n \"List every background job started this session — running and exited — with id, command, pid, and status.\",\n remember:\n \"Save a memory for future sessions. Use when the user states a preference, corrects your approach, shares a non-obvious fact, or asks you to remember something.\",\n forget:\n \"Delete a memory file and remove it from MEMORY.md. Use when the user asks to forget something or a remembered fact is now wrong.\",\n recall_memory:\n \"Read the full body of a memory file when its one-line summary isn't enough detail.\",\n read_file:\n \"Read a file under the sandbox root. Supports head/tail/range scoping to save context. Auto-returns a preview for files over 200 lines.\",\n list_directory:\n \"List entries in a directory. Returns one line per entry, marking directories with a trailing slash.\",\n directory_tree:\n \"Recursively list entries in a directory as an indented tree. Budget-aware with auto-collapse for large subtrees.\",\n search_files:\n \"Find files whose NAME matches a substring or regex. Case-insensitive. Skips dependency/build directories by default.\",\n search_content:\n \"Recursively grep file CONTENTS for a substring or regex. Returns matches in path:line:text format. The right tool for finding references.\",\n glob: \"List files matching a glob pattern, sorted by mtime. Default limit 200, max 1000. Skips node_modules/.git/dist by default.\",\n get_file_info: \"Stat a path under the sandbox root. Returns type, size in bytes, and mtime.\",\n write_file:\n \"Create or overwrite a file with the given content. Parent directories are created as needed.\",\n edit_file:\n \"Apply a SEARCH/REPLACE edit to an existing file. The search must match exactly and be unique in the file.\",\n multi_edit:\n \"Apply N SEARCH/REPLACE edits across one or more files atomically. If any edit fails, no files are written.\",\n create_directory: \"Create a directory (and any missing parents) under the sandbox root.\",\n move_file: \"Rename or move a file or directory under the sandbox root.\",\n delete_file:\n \"Delete one file under the sandbox root. Refuses directories — use delete_directory for those.\",\n delete_directory:\n \"Recursively delete a directory under the sandbox root. Pass recursive:false to refuse non-empty directories.\",\n copy_file:\n \"Copy a file or directory under the sandbox root. Refuses to overwrite an existing destination.\",\n submit_plan:\n \"Submit one concrete plan for a review gate. Use for multi-file refactors, architecture changes, or anything expensive to undo.\",\n mark_step_complete:\n \"Mark one step of the approved plan as done. Call exactly once after finishing each step.\",\n revise_plan:\n \"Surgically replace the remaining steps of an in-flight plan. Done steps are never touched.\",\n run_skill:\n \"Invoke a playbook from the Skills index. Pass the bare skill name. Subagent-tagged skills spawn an isolated subagent.\",\n spawn_subagent:\n \"Spawn an isolated subagent for a self-contained subtask. Use for parallel fan-out or when the work needs many file reads.\",\n todo_write:\n \"In-session task tracker for multi-step work. Replaces the entire list every call. No approval gate or file writes.\",\n ask_choice:\n \"Present 2-6 alternatives to the user. Use when the user asks for options or you need a preference decision.\",\n create_skill:\n \"Scaffold a new skill the user can invoke later via /skill. Supports inline and subagent run modes.\",\n add_mcp_server:\n \"Register a new MCP server in the user's config. Takes effect on the next session. Supports stdio, SSE, and streamable-http.\",\n },\n },\n permissions: {\n loading: \"loading permissions…\",\n failed: \"permissions failed: {error}\",\n yoloTitle: \"YOLO mode\",\n yoloDesc:\n \"Every shell command auto-runs, allowlist bypassed. Switch back with /mode review in the TUI.\",\n project: \"project\",\n builtin: \"builtin\",\n addPrefix: \"add a prefix\",\n addPlaceholder: 'e.g. \"npm run build\" or \"deploy.sh\"',\n clearAll: \"Clear all\",\n alreadyIn: \"{prefix} already in list\",\n added: \"added: {prefix}\",\n removed: \"removed: {prefix}\",\n cleared: \"cleared {count} entr{y}\",\n removeConfirm: 'Remove \"{prefix}\" from this project\\'s allowlist?',\n clearConfirm: \"Wipe every project allowlist entry? Builtin entries are unaffected.\",\n projectAllowlist: \"Project allowlist · {count}\",\n nothingStored: \"Nothing stored yet for this project.\",\n colNum: \"#\",\n colPrefix: \"prefix\",\n builtinTitle: \"Builtin · {count} · read-only\",\n standaloneWarning:\n \"Mutations require /dashboard from inside an active reasonix code session — standalone reasonix dashboard can't tell which project's allowlist to edit.\",\n },\n mcp: {\n loading: \"loading MCP…\",\n servers: \"MCP servers · {count} bridged\",\n all: \"all\",\n live: \"live\",\n unbridged: \"unbridged\",\n specPlaceholder: \"spec — e.g. fs=npx -y @modelcontextprotocol/...\",\n saved: \"saved\",\n savedRestart: \"saved — restart reasonix code to bridge this server\",\n removed: \"removed — restart to drop the live bridge\",\n removeConfirm: \"Remove MCP spec from config?\\n\\n{spec}\",\n noServers: \"No MCP servers in this session.\",\n tools: \"tools\",\n inConfig: \"in config · not loaded\",\n unbridgedTitle: \"unbridged · in config\",\n removeBtn: \"Remove\",\n spec: \"spec\",\n whyUnbridged: \"Why unbridged?\",\n whyUnbridgedDesc:\n \"This spec lives in your config.json but isn't bridged into the live session. MCP servers attach when reasonix code starts; the dashboard alone can't spawn the child process.\",\n whyUnbridgedHint: \"To activate: restart reasonix code, then refresh this dashboard.\",\n bridgeFailed: \"Bridge failed\",\n bridgeFailedTitle: \"bridge failed · in config\",\n bridgeFailedHint:\n \"Reasonix tried to bridge this server and the attempt errored. Common causes: wrong URL, missing auth header, upstream 404/5xx, missing local command. Fix and restart reasonix code to retry.\",\n pickHint: \"Pick an MCP server on the left to inspect tools / resources / prompts.\",\n toolsTitle: \"Tools · {count}\",\n resourcesTitle: \"Resources · {count}\",\n promptsTitle: \"Prompts · {count}\",\n colName: \"name\",\n colDesc: \"description\",\n colUri: \"uri\",\n marketplace: \"marketplace\",\n marketplaceSearch: \"search the registry…\",\n marketplaceLoading: \"loading registry…\",\n marketplaceMore: \"load 5 more pages\",\n marketplaceMoreLabel: \"load 50 more · showing {shown} / {total}\",\n marketplaceMoreHint: \"fetches more pages from the registry\",\n marketplaceMoreCachedHint: \"more entries already cached locally\",\n marketplaceExhausted: \"all pages loaded\",\n marketplaceExhaustedFull: \"showing all {total} entries — registry exhausted\",\n marketplaceCount: \"{loaded} loaded · {matched} match · source: {source}{cached}\",\n marketplaceCachedSuffix: \" · cached\",\n marketplaceNoMatches: \"No matches. Try different terms or load more pages.\",\n marketplaceInstall: \"Install\",\n marketplacePickHint: \"Pick a server on the left, then Install.\",\n marketplaceInstalled: \"installed → {spec}\",\n marketplaceInstalledBridged: \"installed + bridged → {spec}\",\n marketplaceAlready: \"already installed\",\n marketplaceNeedsEnv: \"needs env: {names}\",\n marketplaceSourceTag: \"[{source}]\",\n marketplaceNoInstall:\n \"smithery listing — install metadata not exposed; use `npx -y @smithery/cli install {name}` directly\",\n marketplaceFetchOnInstall:\n \"Smithery listing — install detail fetched on Install. http servers map to streamable-http remotes; stdio servers run via @smithery/cli.\",\n marketplaceInstalledBadge: \"installed\",\n marketplaceUninstall: \"Uninstall\",\n marketplaceEnvTitle: \"Required environment variables\",\n marketplaceEnvHint:\n \"Set these in your shell before next `reasonix code` so the bridged server can authenticate.\",\n marketplaceRestartHint:\n \"Spec written to ~/.reasonix/config.json. Restart `reasonix code` to bridge the server (live hot-reload is on the roadmap).\",\n },\n memory: {\n loading: \"loading memory…\",\n files: \"memory · {count} files\",\n exists: \"exists\",\n create: \"create\",\n noFiles: \"No memory files yet.\",\n pickHint: \"Pick a memory file on the left.\",\n pickDesc: \"Project REASONIX.md is committable; global notes live in ~/.reasonix/memory/.\",\n chars: \"{count} chars\",\n saved: \"saved {scope}\",\n reloadHint: \"re-applied on next /new or session restart\",\n },\n hooks: {\n loading: \"loading hooks…\",\n resolved: \"resolved\",\n eventMatrix: \"Event matrix\",\n matrixSub: \"{scripts} script{s} × {events} event{s}\",\n noHooks: \"No hooks configured. Edit the JSON below to add some.\",\n colScript: \"script\",\n noProject: \"No active project — open /dashboard from reasonix code to edit project hooks.\",\n saveReload: \"Save + Reload\",\n discard: \"Discard changes\",\n savedReloaded: \"saved + reloaded {scope}\",\n recentRuns: \"Recent runs\",\n noRuns: \"No hook runs in the recent session log.\",\n colWhen: \"when\",\n colPhase: \"phase\",\n colHook: \"hook\",\n colOutcome: \"outcome\",\n },\n skills: {\n loading: \"loading skills…\",\n filterPlaceholder: \"filter skills\",\n project: \"project\",\n custom: \"custom\",\n global: \"global\",\n builtin: \"builtin\",\n newSkill: \"new skill\",\n noDescription: \"(no description)\",\n runs7d: \"runs · 7d\",\n pickHint: \"Pick a skill on the left, or create a new one above.\",\n readOnlyBuiltin: \"read-only · builtin\",\n readOnlyCustom: \"read-only · custom path\",\n builtinDesc:\n \"Built-in skills ship with Reasonix; the model picks them up automatically. To customize, create a project- or global-scoped skill with the same name.\",\n saved: \"saved {scope}/{name}\",\n deleteConfirm: \"Delete skill {scope}/{name}?\",\n reloadHint: \"re-loaded on next /new or session restart\",\n },\n system: {\n loading: \"loading health…\",\n failed: \"health failed: {error}\",\n healthChecks: \"Health checks\",\n version: \"version\",\n checking: \"checking\",\n latest: \"● latest\",\n outOfDate: \"● out of date\",\n versionPending: \"version check pending\",\n upToDate: \"up to date\",\n latestVer: \"latest: {version}\",\n sessions: \"sessions\",\n ok: \"● ok\",\n memory: \"memory\",\n semanticIndex: \"semantic index\",\n built: \"● built\",\n none: \"— none\",\n runIndex: \"run reasonix index to build\",\n usageLog: \"usage log\",\n backgroundJobs: \"background jobs\",\n noSession: \"— no session\",\n running: \"{count} running\",\n attachHint: \"attach a session to see jobs\",\n shellSpawn: \"shell + spawn\",\n paths: \"paths\",\n home: \"home\",\n sessionsPath: \"sessions\",\n memoryPath: \"memory\",\n semanticPath: \"semantic\",\n usagePath: \"usage\",\n },\n plans: {\n loading: \"loading plans…\",\n failed: \"plans failed: {error}\",\n noPlans: \"No archived plans yet — run a turn that calls submit_plan and mark_step_complete.\",\n filterPlaceholder: \"filter plans\",\n active: \"active\",\n done: \"done\",\n idle: \"idle\",\n steps: \"steps\",\n pickHint: \"Pick a plan on the left.\",\n noTitle: \"(no title)\",\n stepTimeline: \"Step timeline · {done} / {total}\",\n step: \"step {n}\",\n },\n semantic: {\n codeRequired: \"Semantic — code-mode required\",\n indexBuilt: \"index built\",\n noIndex: \"no index yet\",\n ready: \"ready\",\n setupNeeded: \"setup needed\",\n installOllama: \"Install Ollama\",\n installOllamaDesc:\n \"Reasonix doesn't run package managers for you. Install Ollama first, then come back:\",\n macWindows: \"macOS / Windows:\",\n download: \"download from ollama.com/download\",\n linux: \"Linux:\",\n refreshHint:\n \"Refresh after install — this panel will offer to start the daemon and pull {model}.\",\n daemon: \"Daemon\",\n daemonDesc: \"ollama is on your PATH but the HTTP daemon isn't reachable.\",\n startDaemon: \"Start daemon\",\n runsOllama: \"runs ollama serve detached\",\n model: \"Model\",\n modelMissing: \"{model} isn't installed yet.\",\n modelSize: \"~270 MB on first pull.\",\n pulling: \"pulling…\",\n pullModel: \"Pull {model}\",\n indexStatus: \"index status\",\n builtStatus: \"● built\",\n incompatibleStatus: \"● incompatible\",\n chunks: \"chunks\",\n files: \"files\",\n dim: \"dim\",\n size: \"size\",\n lastBuild: \"last build\",\n builtWith: \"built with\",\n currentTarget: \"current target\",\n incompatibleHint:\n \"This on-disk index was built for a different provider or model. Run Rebuild to replace it.\",\n runIndexHint: \"Run an index to enable semantic_search.\",\n reIndex: \"Re-index\",\n build: \"Build\",\n rebuild: \"Rebuild\",\n stop: \"Stop\",\n provider: \"provider\",\n providerType: \"service type\",\n openaiCompat: \"openai-compatible\",\n apiUrl: \"API URL\",\n apiKey: \"API key\",\n apiKeyStoredNote: \"API key is stored in ~/.reasonix/config.json — do not share that file.\",\n customRequestBody: \"custom request body\",\n invalidCustomRequestBody: \"Custom request body must be valid JSON: {error}\",\n customRequestBodyMustBeObject: \"Custom request body must be a JSON object.\",\n saveBeforeIndex: \"Save semantic settings before starting an index.\",\n extraBody: \"extra body\",\n batchSize: \"batch size\",\n keepExistingKey: \"leave blank to keep existing key\",\n remoteProvider: \"Remote embedding provider\",\n remoteProviderDesc:\n \"Configure the full OpenAI-compatible embeddings URL here. Reasonix will send requests exactly to the URL you provide.\",\n ollama: \"ollama\",\n binary: \"binary\",\n found: \"found\",\n missing: \"missing\",\n daemonStatus: \"daemon\",\n up: \"up\",\n down: \"down\",\n pulled: \"pulled\",\n indexConfig: \"index config\",\n reset: \"reset\",\n excludeDirs: \"exclude dirs\",\n excludeFiles: \"exclude files\",\n excludeExts: \"exclude exts\",\n excludePatterns: \"exclude patterns\",\n glob: \"glob\",\n respectGitignore: \"respect .gitignore\",\n maxFileBytes: \"max file bytes\",\n skipLarger: \"skip files larger than ~{size} MiB\",\n preview: \"Preview\",\n searchPlaceholder: \"describe what to find — 'where do we handle abort signals'\",\n searching: \"searching…\",\n results: \"{count} result{s} · {ms}ms · {model}\",\n noMatches: \"No matches above the score threshold.\",\n previewSummary: \"Preview — would index {included} file(s), skip {skipped}\",\n nothingSkipped: \"nothing skipped — all walked files would be indexed.\",\n firstIncluded: \"first {count} included file(s)\",\n job: \"Job\",\n phaseSetup: \"preparing\",\n phaseScan: \"scanning files\",\n phaseEmbed: \"embedding chunks\",\n phaseWrite: \"writing index\",\n phaseDone: \"done\",\n phaseError: \"error\",\n phaseCancelled: \"cancelled\",\n setupFailed: \"setup failed\",\n stopping: \"stopping\",\n scanned: \"scanned {count}\",\n changed: \"changed {count}\",\n skipped: \"skipped {count}\",\n chunksProgress: \"{done} / {total} ({pct}%)\",\n result: \"result\",\n added: \"added {count}\",\n removed: \"removed {count}\",\n failed: \"failed {count}\",\n skippedFiles: \"{total} files ({details})\",\n rebuildStarted: \"rebuild started\",\n incrementalStarted: \"incremental index started\",\n stopRequested: \"stopping requested — current chunk batch will finish first\",\n startingDaemon: \"starting ollama daemon (15s timeout)…\",\n daemonUp: \"daemon is up\",\n daemonTimeout: \"daemon didn't come up in time — check ollama serve manually\",\n pullingModel: \"pulling {model} — this may take a few minutes on first install\",\n savedConfig: \"saved · {count} fields updated · re-run index to apply\",\n runningPreview: \"running dry walk against project root…\",\n exclude: \"exclude\",\n },\n modal: {\n shellTitle: \"shell command\",\n shellBgTitle: \"background process\",\n shellSubtitle: \"model wants to run a shell command\",\n shellBgSubtitle: \"long-running — keeps running after approval\",\n pathTitle: \"file outside sandbox\",\n pathSubtitle: \"{intent} via {tool}\",\n pathRead: \"read\",\n pathWrite: \"write\",\n pathSandboxLabel: \"sandbox\",\n pathAllowPrefixLabel: \"allow prefix\",\n runOnce: \"Run once\",\n alwaysAllow: 'Always allow \"{prefix}\"',\n deny: \"Deny\",\n choiceTitle: \"model wants you to pick\",\n typeOwn: \"Type my own answer\",\n typeOwnSummary: \"None of the above fits — write a free-form reply.\",\n typePlaceholder: \"Type a free-form answer…\",\n send: \"Send\",\n cancel: \"Cancel\",\n cancelSummary: \"Drop the question. Model will ask what you actually want.\",\n planTitle: \"plan submitted\",\n planSubtitle: \"model proposed a plan; review then pick\",\n approveInstructions:\n \"Optional last instructions / answers to open questions (Enter to send blank)\",\n refinePlaceholder: \"What needs to change? Be specific.\",\n approve: \"Approve\",\n refine: \"Refine\",\n sendRefinement: \"Send refinement\",\n editTitle: \"edit pending review\",\n editSubtitle: \"{path} · {remaining} of {total} blocks remaining\",\n before: \"before\",\n after: \"after\",\n workspaceTitle: \"model wants to switch workspace\",\n workspaceSubtitle: \"every subsequent file / shell / memory tool resolves against the new root\",\n switchBtn: \"Switch (Enter)\",\n denyBtn: \"Deny (Esc)\",\n stepComplete: \"step complete{counter}\",\n continueBtn: \"Continue\",\n reviseBtn: \"Revise…\",\n stopBtn: \"Stop\",\n revisionTitle: \"model proposed a plan revision\",\n sendRevision: \"Send revision\",\n accept: \"Accept\",\n reject: \"Reject\",\n arguments: \"arguments\",\n revisePlaceholder: \"What needs to change before the next step? Leave blank to just continue.\",\n pickerFilter: \"Filter…\",\n pickerEmpty: \"Nothing to show.\",\n pickerLoadMore: \"Load more\",\n pickerPick: \"Open\",\n pickerInstall: \"Install\",\n pickerUninstall: \"Uninstall\",\n pickerRename: \"Rename…\",\n pickerNew: \"New…\",\n pickerNewPlaceholder: \"Name (leave blank for default)\",\n viewerClose: \"Close\",\n },\n error: {\n title: \"Something broke in the dashboard\",\n body: \"The TUI is unaffected — only this browser tab tripped. You can dismiss and keep working, or report it so we can fix the underlying cause.\",\n copyDetails: \"Copy details\",\n copied: \"Copied ✓\",\n reportOnGithub: \"Report on GitHub\",\n dismiss: \"Dismiss (Esc)\",\n crashing: \"this panel keeps crashing — {name}\",\n retry: \"Try again\",\n recovering: \"recovering…\",\n },\n fmt: {\n justNow: \"just now\",\n minutesAgo: \"{n}m ago\",\n hoursAgo: \"{n}h ago\",\n daysAgo: \"{n}d ago\",\n },\n cards: {\n applied: \"Applied\",\n cacheHit: \"Cache hit\",\n checkpointRewind: \"Checkpoint Rewind\",\n cost: \"Cost\",\n diffApply: \"Apply\",\n diffApplyChanges: \"Apply Changes\",\n diffAwaiting: \"Awaiting review\",\n diffDiscard: \"Discard\",\n done: \"Done\",\n elapsed: \"Elapsed\",\n error: \"Error\",\n errorName: \"Error\",\n failed: \"Failed\",\n hits: \"Hits\",\n memoryCountSuffix: \"memories\",\n memoryName: \"Memory\",\n output: \"Output\",\n planDefaultTitle: \"Plan\",\n prompt: \"Prompt\",\n compactionMeta: \"{chars} chars\",\n compactionName: \"Compacted history\",\n reasoningComplete: \"Reasoning complete\",\n reasoningName: \"Reasoning\",\n result: \"Result\",\n running: \"Running\",\n searchName: \"Search\",\n shellAlwaysAllow: \"Always Allow\",\n shellAwaiting: \"Awaiting approval\",\n shellExecuteHint: \"Execute this command?\",\n shellReject: \"Reject\",\n shellRun: \"Run\",\n shellRunning: \"Running\",\n streaming: \"Streaming\",\n subagentDone: \"Subagent done\",\n subagentDoneProgress: \"Subagent done ({pct}%)\",\n subagentFailed: \"Subagent failed\",\n subagentRunning: \"Subagent running\",\n },\n planBadge: {\n blocked: \"Blocked\",\n done: \"Done\",\n failed: \"Failed\",\n pending: \"Pending\",\n running: \"Running\",\n },\n composer: {\n atHeader: \"Mention files\",\n close: \"Close\",\n commandPalette: \"Command Palette\",\n commands: \"Commands\",\n commandsLabel: \"Commands\",\n confirm: \"Confirm\",\n imageFilterName: \"Images\",\n insertFile: \"Insert File\",\n insertImage: \"Insert Image\",\n interrupt: \"Interrupt\",\n mentionFiles: \"Mention Files\",\n mentionLabel: \"Mention\",\n newline: \"New Line\",\n noMatches: \"No matches\",\n placeholder: \"Type a prompt…\",\n queue: \"Queue\",\n queueCount: \"{count} queued\",\n select: \"Select\",\n send: \"Send\",\n slashHeader: \"Slash Commands\",\n switchModel: \"Switch Model\",\n switchEffort: \"Switch Reasoning Effort\",\n workspaceRoot: \"Workspace Root\",\n },\n contextPanel: {\n allow: \"Allow\",\n ask: \"Ask\",\n autoApproveTitle: \"Auto-approve\",\n cacheKey: \"Cache\",\n contextTokens: \"Context tokens\",\n fileInContext: \"In context\",\n fileModified: \"Modified\",\n filesCount: \"{count} files\",\n filesTab: \"Files\",\n filesTitle: \"Files\",\n freeKey: \"Free\",\n itemCount: \"{count} items\",\n mcpConfigured: \"Configured\",\n mcpConnecting: \"Connecting…\",\n mcpDisabled: \"Disabled\",\n mcpEmpty: \"No MCP servers\",\n mcpFailed: \"Failed\",\n mcpReady: \"Ready\",\n mcpReadyAll: \"All ready\",\n mcpReadySome: \"Some ready\",\n mcpTitle: \"MCP\",\n mcpTools: \"Tools\",\n memoryTab: \"Memory\",\n memoryTitle: \"Memory\",\n noFilesMsg: \"No files in context\",\n noMemoriesMsg: \"No memories\",\n reservedKey: \"Reserved\",\n ruleReadOnly: \"Read-only\",\n ruleReview: \"Review\",\n ruleShellAllowlist: \"Shell allowlist\",\n rulesTab: \"Rules\",\n ruleWritesAsk: \"Writes ask\",\n ruleYolo: \"YOLO\",\n scopeGlobal: \"Global\",\n scopeProject: \"Project\",\n toolsTab: \"Tools\",\n usedKey: \"Used\",\n },\n dragDrop: {\n overlay: \"Drop files here\",\n },\n extraCards: {\n approve: \"Approve\",\n balance: \"Balance\",\n cache: \"Cache\",\n cacheHit: \"Cache hit\",\n contextWindow: \"Context window\",\n doctorTitle: \"Diagnostics\",\n output: \"Output\",\n prompt: \"Prompt\",\n reasoning: \"Reasoning\",\n reject: \"Reject\",\n sessionCost: \"Session cost\",\n sessionUsage: \"Session usage\",\n topToolsUsage: \"Top tools\",\n unknownKind: \"Unknown\",\n memoryUser: \"User\",\n memoryFeedback: \"Feedback\",\n memoryProject: \"Project\",\n memoryReference: \"Reference\",\n },\n jobs: {\n empty: \"No background jobs\",\n exited: \"Exited\",\n kbClose: \"Close\",\n kbToggle: \"Toggle\",\n running: \"Running\",\n stop: \"Stop\",\n stopAll: \"Stop All\",\n stopAllTip: \"Stop all jobs\",\n stopOne: \"Stop\",\n title: \"Background Jobs\",\n },\n live: {\n deliveredWaiting: \"Waiting for next message\",\n reasoning: \"Reasoning\",\n running: \"Running\",\n secondsAgo: \"{n}s ago\",\n you: \"You\",\n },\n markdown: {\n copied: \"Copied!\",\n copy: \"Copy\",\n externalLinkTitle: \"Open in new tab\",\n filePillTitle: \"Open file\",\n localLinkTitle: \"Open link\",\n },\n palette: {\n abort: \"Abort\",\n abortHint: \"Abort current request\",\n about: \"About\",\n clearChat: \"Clear Chat\",\n clearChatHint: \"Clear conversation\",\n closeTab: \"Close Tab\",\n closeTabHint: \"Close current tab\",\n copyConv: \"Copy Conversation\",\n copyConvHint: \"Copy conversation as Markdown\",\n copyLast: \"Copy Last Response\",\n copyLastHint: \"Copy last assistant message\",\n countSuffix: \"items\",\n empty: \"No matching commands\",\n exportMd: \"Export as Markdown\",\n exportMdHint: \"Export chat as Markdown file\",\n focusComposer: \"Focus Composer\",\n footClose: \"Close\",\n footMove: \"Move\",\n footRun: \"Run\",\n groupAction: \"Actions\",\n groupNav: \"Navigation\",\n groupSettings: \"Settings\",\n groupWorkspace: \"Workspace\",\n newChat: \"New Chat\",\n newChatHint: \"Start a new conversation\",\n newTab: \"New Tab\",\n newTabHint: \"Open a new tab\",\n pickWorkspace: \"Switch Workspace\",\n pickWorkspaceHint: \"Change workspace\",\n searchPlaceholder: \"Search commands…\",\n settings: \"Settings\",\n settingsHint: \"Open settings\",\n },\n panel: {\n renderError: \"Panel crashed\",\n },\n sidebarPanel: {\n approvalRules: \"Approval Rules\",\n cancel: \"Cancel\",\n commandPalette: \"Command Palette\",\n daysAgo: \"{n}d ago\",\n delete: \"Delete\",\n deleteSession: \"Delete Session\",\n hoursAgo: \"{n}h ago\",\n justNow: \"Just now\",\n loading: \"Loading…\",\n messageCount: \"{count} messages\",\n minutesAgo: \"{n}m ago\",\n newChat: \"New Chat\",\n noMatches: \"No matches\",\n noSessions: \"No sessions\",\n recent: \"Recent\",\n searchSessions: \"Search sessions…\",\n sessionTitle: \"Sessions\",\n settings: \"Settings\",\n weeksAgo: \"{n}w ago\",\n },\n statusbar: {\n balance: \"Balance\",\n busy: \"Busy\",\n cache: \"Cache\",\n cacheHit: \"Cache hit\",\n jobs: \"Jobs\",\n jobsTip: \"Background jobs\",\n offline: \"Offline\",\n online: \"Online\",\n switchCurrency: \"Switch currency\",\n switchTheme: \"Switch theme\",\n switchWorkspace: \"Switch workspace\",\n themeDark: \"Dark\",\n themeLight: \"Light\",\n themeStyleGraphite: \"Graphite\",\n themeStyleSandstone: \"Sandstone\",\n themeStylePorcelain: \"Porcelain\",\n themeStyleMidnight: \"Midnight\",\n thisTurn: \"This turn\",\n tokens: \"Tokens\",\n },\n thread: {\n activePlan: \"Active plan\",\n allowRead: \"Allow read\",\n allowWrite: \"Allow write\",\n alwaysAllow: \"Always allow\",\n alwaysAllowPrefix: \"Always allow {prefix}\",\n approve: \"Approve\",\n approveRewrite: \"Approve rewrite\",\n cancel: \"Cancel\",\n checkpointKind: \"Checkpoint\",\n checkpointSub: \"Save current state\",\n checkpointTitle: \"Create checkpoint\",\n collapse: \"Collapse\",\n continue: \"Continue\",\n copyMessage: \"Copy message\",\n copyResponse: \"Copy response\",\n execute: \"Execute\",\n keepOriginal: \"Keep original\",\n keepSteps: \"Keep steps\",\n optionCount: \"{count} options\",\n pathAccessKind: \"Path access\",\n planConfirmationKind: \"Plan approval\",\n planRevisionKind: \"Plan revision\",\n planRunning: \"Plan in progress\",\n planStepCount: \"Step {done}/{total}\",\n readPathOutsideSandbox: \"Read path outside sandbox\",\n refine: \"Refine\",\n reject: \"Reject\",\n revise: \"Revise\",\n revisionMeta: \"Revision\",\n rewritePlan: \"Rewrite plan\",\n risk: \"Risk assessment\",\n riskMedium: \"Medium risk\",\n runBackgroundCommand: \"Run in background\",\n runCommand: \"Run command\",\n shellConfirmationKind: \"Shell confirmation\",\n startPlan: \"Start plan\",\n stop: \"Stop\",\n subagent: \"Subagent\",\n userChoiceKind: \"User choice\",\n writePathOutsideSandbox: \"Write path outside sandbox\",\n you: \"You\",\n },\n workdir: {\n browse: \"Browse…\",\n cancel: \"Cancel\",\n empty: \"No workspaces\",\n emptyDir: \"No subdirectories.\",\n go: \"Go\",\n goTip: \"Navigate to this path\",\n loading: \"Loading…\",\n openHere: \"Open this folder\",\n pathPlaceholder: \"Absolute path…\",\n promptWeb: \"Enter the absolute path of the workspace to open:\",\n searchPlaceholder: \"Search workspaces…\",\n title: \"Workspace\",\n },\n about: {\n close: \"Close\",\n repo: \"Repository\",\n sidebarLabel: \"About\",\n tagline: \"AI-powered coding assistant\",\n version: \"Version\",\n },\n effort: {\n lowDesc: \"fastest — minimal reasoning\",\n mediumDesc: \"balanced\",\n highDesc: \"default — safe for vLLM / Azure\",\n maxDesc: \"DeepSeek extension; rejected by stock OpenAI / vLLM\",\n },\n editMode: {\n review: \"Review\",\n reviewHint: \"both edits and non-allowlisted shell ask first\",\n auto: \"Auto\",\n autoHint: \"edits auto-apply, shell still asks\",\n yolo: \"YOLO\",\n yoloHint: \"edits AND shell auto-run, allowlist bypassed\",\n },\n};\n","export const zhCN = {\n app: {\n sectionWorkspace: \"工作区\",\n sectionObserve: \"监控\",\n sectionConfigure: \"配置\",\n tabChat: \"对话\",\n tabPlans: \"计划\",\n tabSessions: \"会话\",\n tabOverview: \"概览\",\n tabUsage: \"用量\",\n tabSystem: \"系统\",\n tabSemantic: \"语义\",\n tabTools: \"工具\",\n tabPermissions: \"权限\",\n tabMcp: \"MCP\",\n tabSkills: \"技能\",\n tabMemory: \"记忆\",\n tabHooks: \"钩子\",\n tabSettings: \"设置\",\n sectionChanges: \"变更\",\n tabChanges: \"变更\",\n footer: \"仅 127.0.0.1 · Token 保护\",\n themeToggle: \"切换主题\",\n themeLight: \"浅色\",\n themeDark: \"深色\",\n skill: {\n scope: {\n builtin: \"内置\",\n global: \"全局\",\n project: \"项目\",\n },\n runAs: {\n subagent: \"子代理\",\n inline: \"内联\",\n },\n generic: \"技能\",\n },\n exportReasoningSummary: \"推理摘要\",\n exportToolLabel: \"工具调用\",\n exportUserLabel: \"用户消息\",\n empty: {\n currentWorkspace: \"当前工作区\",\n selectWorkspace: \"选择一个工作区开始\",\n suggestion0: \"开始新对话\",\n suggestion1: \"打开设置\",\n suggestion2: \"查看概览\",\n suggestion3: \"浏览会话\",\n welcome: \"欢迎使用 Reasonix\",\n },\n errorLabel: \"错误\",\n connecting: \"连接中…\",\n session: {\n format: \"会话\",\n new: \"新建会话\",\n },\n setup: {\n choose: \"选择工作区\",\n description: \"选择一个工作区开始工作\",\n notSelected: \"未选择工作区\",\n saveAndStart: \"保存并开始\",\n welcome: \"欢迎\",\n workspace: \"工作区\",\n },\n tab: {\n newTab: \"+ 新建标签\",\n newTabTitle: \"打开新标签\",\n },\n titlebar: {\n clearChat: \"清除对话\",\n close: \"关闭\",\n commandPalette: \"命令面板\",\n contextPanel: \"上下文面板\",\n copyMd: \"复制为 Markdown\",\n exportMd: \"导出为 Markdown\",\n maximize: \"最大化\",\n minimize: \"最小化\",\n more: \"更多\",\n restore: \"还原\",\n settings: \"设置\",\n sidebar: \"侧边栏\",\n windowControls: \"窗口控制\",\n },\n toast: {\n cleared: \"对话已清除\",\n copied: \"已复制到剪贴板\",\n copiedMd: \"已复制为 Markdown\",\n emptySession: \"无消息可导出\",\n exportDialogTitle: \"导出对话\",\n exportedMd: \"已导出为 Markdown\",\n exportFailed: \"导出失败\",\n langSwitched: \"语言已切换\",\n modelSwitched: \"模型 → {model}\",\n effortSwitched: \"强度 → {effort}\",\n modeSwitched: \"模式已切换\",\n newSession: \"新会话已创建\",\n },\n yolo: {\n toast: \"YOLO 模式已启用\",\n },\n cmd: {\n abort: \"中止\",\n btw: \"顺便说一下\",\n clearChat: \"清除对话\",\n compact: \"紧凑\",\n copyLast: \"复制上条\",\n exportMd: \"导出为 Markdown\",\n feedback: \"反馈\",\n help: \"帮助\",\n newSession: \"新建会话\",\n retry: \"重试\",\n switchModel: \"切换模型\",\n toggleCurrency: \"切换货币\",\n toggleLang: \"切换语言\",\n toggleTheme: \"切换主题\",\n },\n header: {\n abort: \"中止\",\n clickToSelect: \"点击选择\",\n copy: \"复制\",\n copyMd: \"复制为 Markdown\",\n export: \"导出\",\n exportMd: \"导出为 Markdown\",\n newChat: \"新建对话\",\n noWorkspace: \"无工作区\",\n running: \"运行中…\",\n },\n jumpToBottom: \"跳到底部\",\n langEN: \"English\",\n langZH: \"中文\",\n splashSubtitle: \"AI 驱动的编程助手\",\n },\n changes: {\n chatPlaceholder: \"询问代码问题…\",\n chatWelcome: \"变更 — 询问项目文件相关问题。\",\n chatSend: \"发送\",\n viewerPlaceholder: \"选择一个文件查看\",\n treeEmpty: \"(空)\",\n tabClose: \"关闭标签\",\n newConversation: \"新建\",\n clearConversation: \"清除\",\n newTitle: \"/new — 清除对话上下文\",\n clearTitle: \"/clear — 仅清除可见的滚动回放\",\n newConfirmBusy: \"有轮次正在执行。中止并开始新对话?\",\n newConfirm: \"清除当前对话并重新开始?\",\n newToast: \"新对话\",\n clearToast: \"滚动回放已清除\",\n newFailed: \"/new 失败:{error}\",\n clearFailed: \"/clear 失败:{error}\",\n chatSendBtn: \"发送\",\n fileTreeTitle: \"文件\",\n codeViewerTitle: \"代码查看器\",\n chatPanelTitle: \"对话\",\n loadingFiles: \"正在加载项目文件…\",\n review: \"审查\",\n allFiles: \"所有文件\",\n changes: \"更改\",\n commentLabel: \"正在评论 第\",\n commentPlaceholder: \"添加评论…\",\n commentCancel: \"取消\",\n commentSubmit: \"评论\",\n commentLine: \"第\",\n commentEdit: \"编辑\",\n commentDelete: \"删除\",\n diffSourceGit: \"Git 变更\",\n diffSourceSession: \"上一轮变更\",\n diffSourceCheckpoint: \"检查点\",\n checkpointEmpty: \"暂无检查点\",\n restoreBtn: \"恢复\",\n restoreConfirm: '确定要恢复检查点\"{name}\"吗?当前更改将被覆盖。',\n deleteBtn: \"删除\",\n deleteConfirm: '确定要删除检查点\"{name}\"吗?',\n createBtn: \"创建\",\n createPlaceholder: \"检查点名称…\",\n backToList: \"返回列表\",\n reviewEmpty: \"暂无可审查的更改\",\n diffStyleUnified: \"统一视图\",\n diffStyleSplit: \"分栏视图\",\n expandAll: \"全部展开\",\n collapseAll: \"全部折叠\",\n createFailed: \"创建失败\",\n restoreFailed: \"恢复失败\",\n deleteFailed: \"删除失败\",\n },\n common: {\n loading: \"加载中…\",\n loadingFailed: \"{name}失败:{error}\",\n back: \"← 返回\",\n save: \"保存\",\n remove: \"移除\",\n cancel: \"取消\",\n delete: \"删除\",\n add: \"添加\",\n confirm: \"确认\",\n noData: \"暂无{name}。\",\n all: \"全部\",\n yes: \"是\",\n no: \"否\",\n on: \"开启\",\n off: \"关闭\",\n enabled: \"已启用\",\n disabled: \"已禁用\",\n },\n settings: {\n title: \"设置\",\n loading: \"加载设置…\",\n saved: \"已保存:{fields}\",\n sectionApi: \"DeepSeek API\",\n apiKey: \"API 密钥\",\n apiKeyNotSet: \"未设置\",\n apiKeySave: \"保存密钥\",\n apiKeySet: \"已设置\",\n apiSection: \"API 配置\",\n notSet: \"(未设置)\",\n replace: \"替换\",\n pasteKey: \"粘贴新的 sk-… 令牌\",\n saveKey: \"保存密钥\",\n baseUrl: \"基础 URL\",\n baseUrlPlaceholder: \"https://api.deepseek.com(默认)\",\n baseUrlHint: \"API 请求的基础 URL\",\n sectionDefaults: \"默认设置\",\n effortSection: \"推理强度\",\n modelCustom: \"自定义模型 ID\",\n modelCustomHint: \"任何 OpenAI 兼容的 ID(vLLM、Ollama、Together …)。\",\n modelCustomActive: \"当前运行自定义 ID:{model}\",\n appliesNextTurn: \"下一轮生效\",\n effort: \"推理强度\",\n effortMax: \"max(DeepSeek 扩展 — 标准 OpenAI / vLLM 会拒绝)\",\n effortHigh: \"high(安全默认 — vLLM / Azure 兼容)\",\n effortMedium: \"medium\",\n effortLow: \"low(最快)\",\n webSearch: \"网页搜索\",\n webSearchNote: \"web_fetch + web_search 工具\",\n webSearchEngine: \"搜索引擎\",\n webSearchEngineBing: \"bing — 默认,国内裸 IP 直连,无需代理\",\n webSearchEngineSearxng: \"searxng — 自托管(端点用 /se searxng <url> 配置)\",\n webSearchEngineMetaso: \"metaso — 每日 100 次免费(国内友好,metaso.cn 可领免费 key)\",\n webSearchEngineTavily: \"tavily — 每月 1000 次免费(设置 TAVILY_API_KEY)\",\n webSearchEnginePerplexity: \"perplexity — AI 直接回答(设置 PERPLEXITY_API_KEY)\",\n webSearchEngineExa: \"exa — AI 直接回答,每月 1000 次免费(设置 EXA_API_KEY)\",\n webSearchEngineNote: \"下一次 web_search 调用生效\",\n sectionBudget: \"预算\",\n budget: \"预算\",\n budgetHint: \"设置支出限额\",\n budgetPlaceholder: \"输入预算金额\",\n budgetOf: \"/\",\n budgetSetCap: \"设置上限\",\n budgetCustom: \"自定义\",\n budgetBumpHint: \"提高上限以继续\",\n budgetClear: \"清除上限\",\n budgetIdleLine: \"80% 时提醒 · 100% 后拒绝执行\",\n budgetWarnLine: \"接近上限 — 超过 100% 将拒绝执行\",\n budgetRefusing: \"已超出上限 — 提高或清除后才会继续\",\n sectionLoop: \"循环\",\n loopIdleHint: \"按固定间隔自动重新提交一段提示词。\",\n loopCostHint: \"每次迭代约 {cost}(上一轮成本)。\",\n loopInterval: \"间隔\",\n loopCustom: \"自定义\",\n loopRangeError: \"间隔需在 5s..6h 之间\",\n loopPrompt: \"提示词\",\n loopPromptPlaceholder: \"例如:检查部署状态并汇报任何错误\",\n loopStart: \"启动循环\",\n loopStop: \"停止\",\n loopRunning: \"运行中\",\n loopIter: \"第 {iter} 次\",\n loopFiresIn: \"{remaining} 后触发\",\n sectionSkills: \"技能\",\n skillPaths: \"技能路径\",\n skillPathsPlaceholder: \"/path/to/skills-a, /path/to/skills-b\",\n skillPathsNote: \"英文逗号分隔 · 下次 /new 或新会话生效\",\n skillsEmpty: \"无已加载技能\",\n skillsLoaded: \"技能已加载\",\n subagentModelFlash: \"flash\",\n subagentModelPro: \"pro\",\n subagentModelHint: \"技能派生独立 subagent 时使用的模型\",\n sectionRuntime: \"运行时\",\n activeModel: \"当前模型\",\n model: \"模型\",\n modelFlashDesc: \"Flash — 始终 flash\",\n modelProDesc: \"Pro — 始终 pro\",\n modelPricingLine: \"${hit} 命中 · ${miss} 未命中 · ${out} 输出 / 100 万 tok\",\n editMode: \"编辑模式\",\n editModeNote: \"在对话标签页头部切换\",\n editModeHint: \"配置编辑模式\",\n showSystemEvents: \"系统事件\",\n showSystemEventsHint: \"在对话流中以细线显示压缩 / 中断 / 限速等系统事件\",\n shown: \"显示\",\n hidden: \"隐藏\",\n appMode: \"应用模式\",\n sectionLanguage: \"语言\",\n language: \"语言\",\n languageHint: \"切换语言\",\n langEn: \"English\",\n langZhCn: \"简体中文\",\n appearanceSection: \"外观\",\n behaviorSection: \"行为\",\n ruleAutoApprovalHint: \"配置自动审批规则\",\n ruleAutoApprovalSection: \"自动审批规则\",\n theme: \"主题\",\n themeDark: \"深色\",\n themeHint: \"在浅色和深色主题之间切换\",\n themeLight: \"浅色\",\n themeStyle: \"主题风格\",\n themeStyleHint: \"选择主题风格\",\n themeStyleGraphite: \"石墨\",\n themeStyleGraphiteDesc: \"冷色深色调,适合长时间使用。\",\n themeStyleSandstone: \"砂岩\",\n themeStyleSandstoneDesc: \"暖色浅色调,明亮环境更舒适。\",\n themeStylePorcelain: \"瓷白\",\n themeStylePorcelainDesc: \"高对比度浅色,简洁清爽。\",\n themeStyleMidnight: \"午夜\",\n themeStyleMidnightDesc: \"深色配冷色高光,更深邃。\",\n pageGeneralLabel: \"通用\",\n pageGeneralDesc: \"主题、字体、语言与工作目录。\",\n pageModelsLabel: \"模型\",\n pageModelsDesc: \"默认模型与推理强度。\",\n pageMcpLabel: \"MCP 服务器\",\n pageMcpDesc: \"接入外部工具服务器。\",\n pageSkillsLabel: \"技能\",\n pageSkillsDesc: \"可通过 /skill 调用的自定义技能。\",\n pageMemoryLabel: \"记忆\",\n pageMemoryDesc: \"跨会话保留的长期笔记。\",\n pageRulesLabel: \"规则\",\n pageRulesDesc: \"Shell 与路径访问的自动审批规则。\",\n pageBillingLabel: \"账单\",\n pageBillingDesc: \"API key、余额与会话预算。\",\n pageShortcutsLabel: \"快捷键\",\n pageShortcutsDesc: \"键盘快捷键参考。\",\n fontFamily: \"字体\",\n fontFamilyHint: \"选择字体\",\n fontFamilySans: \"无衬线\",\n fontFamilySerif: \"衬线\",\n fontFamilySystem: \"系统\",\n fontScale: \"字体大小\",\n fontScaleHint: \"调整字体大小\",\n fontScaleLarge: \"大\",\n fontScaleMedium: \"中\",\n fontScaleSmall: \"小\",\n currentWorkspace: \"当前工作区\",\n defaultModelCurrent: \"当前模型\",\n editor: \"编辑器\",\n editorHint: \"配置编辑器偏好\",\n maxOutput: \"最大输出\",\n reasoningEffort: \"推理强度\",\n reasoningEffortHint: \"调整推理深度\",\n sessionCost: \"会话成本\",\n balanceAvailable: \"可用\",\n balanceLabel: \"余额\",\n balanceLow: \"余额不足\",\n cacheHitRate: \"缓存命中率\",\n ctxWindow: \"上下文窗口\",\n notSelected: \"未选择\",\n parseError: \"解析错误\",\n workspaceChange: \"更改\",\n workspaceSection: \"工作区\",\n mcpAdd: \"添加\",\n mcpAddSection: \"添加 MCP 服务器\",\n mcpBridged: \"已桥接\",\n mcpConfigured: \"已配置\",\n mcpEmpty: \"无 MCP 服务器\",\n mcpNotBridged: \"未桥接\",\n mcpRemove: \"移除\",\n mcpSpecFormat: \"JSON 格式\",\n mcpSpecLabel: \"服务器规格\",\n memoryDesc: \"配置记忆设置\",\n memorySection: \"记忆\",\n shortcutAbort: \"中止\",\n shortcutCloseTab: \"关闭标签\",\n shortcutCommandPalette: \"命令面板\",\n shortcutFocusComposer: \"聚焦编辑器\",\n shortcutNewChat: \"新建对话\",\n shortcutNewTab: \"新建标签\",\n shortcutSettings: \"设置\",\n shortcutSwitchTab: \"切换标签\",\n qqAccessAllowlist: \"允许列表\",\n qqAccessOpen: \"开放\",\n qqAccessOwner: \"所有者\",\n qqAccessOwnerWithAllowlist: \"所有者 + 允许列表\",\n qqAccessRuntime: \"运行时\",\n qqAppId: \"App ID\",\n qqApplyAction: \"应用\",\n qqApplyLabel: \"应用\",\n qqAppSecret: \"App Secret\",\n qqBack: \"返回\",\n qqConfigure: \"配置\",\n qqConfigureHint: \"设置 QQ 集成\",\n qqConfigureTitle: \"QQ 配置\",\n qqConnected: \"已连接\",\n qqConnecting: \"连接中…\",\n qqDisconnected: \"已断开\",\n qqEnvironment: \"环境\",\n qqFailed: \"失败\",\n qqProduction: \"生产环境\",\n qqSandbox: \"沙箱环境\",\n qqSave: \"保存\",\n qqSaveAndConnect: \"保存并连接\",\n qqSection: \"QQ 集成\",\n qqSummaryAppId: \"App ID\",\n qqSummaryDetail: \"详情\",\n qqSummaryMissing: \"未配置\",\n qqTitle: \"QQ 机器人\",\n },\n chat: {\n modeMirror: \"TUI 镜像\",\n modeView: \"会话视图\",\n placeholder: \"输入提示词 — Enter 发送,Shift+Enter 换行 · / @ 打开选择器\",\n placeholderBusy: \"请等待当前轮次完成…\",\n placeholderSteerBusy: \"输入消息以引导当前任务 — 忙碌时不支持命令和选择器\",\n steerHint: \"消息将作为附加指示引导当前轮次\",\n send: \"发送\",\n new: \"新建\",\n clear: \"清除\",\n newTitle: \"/new — 清除对话上下文(循环日志 + 滚动回放)\",\n clearTitle: \"/clear — 仅清除可见的滚动回放(上下文保留)\",\n noConversation: \"暂无对话。在下方发送提示词开始。\",\n newConfirmBusy: \"有轮次正在执行。中止并开始新对话?\",\n newConfirm: \"清除当前对话并重新开始?\",\n newToast: \"新对话\",\n clearToast: \"滚动回放已清除\",\n newFailed: \"/new 失败:{error}\",\n clearFailed: \"/clear 失败:{error}\",\n eventStreamError: \"事件流中断 — 正在重连…\",\n semanticBanner: \"此项目未启用语义搜索。\",\n semanticBannerDesc:\n \"构建一次索引,模型即可按含义查找代码(\\u201C哪里处理认证失败?\\u201D),而不仅依赖精确字符串的 grep。\",\n semanticBannerBtn: \"构建 →\",\n semanticBannerDismiss: \"关闭(不再显示)\",\n slashCommands: \"斜杠命令\",\n projectFiles: \"项目文件\",\n effortTitle: \"reasoning_effort — 下一轮生效\",\n effortMaxTitle: \"max(DeepSeek 扩展)\",\n effortHighTitle: \"high(安全默认 — vLLM / Azure 兼容)\",\n effortMediumTitle: \"medium\",\n effortLowTitle: \"low(最快)\",\n editGateTitle: \"编辑门控 — Shift+Tab 在 TUI 中循环\",\n editReviewTitle: \"review — 编辑和非允许列表的 shell 命令都会先询问\",\n editAutoTitle: \"auto — 编辑自动应用,shell 仍会询问\",\n editYoloTitle: \"yolo — 编辑和 shell 都自动运行,绕过允许列表\",\n railSession: \"会话\",\n railTurns: \"轮次\",\n railPromptTok: \"提示 tokens\",\n railCost: \"费用\",\n railCacheHit: \"缓存命中\",\n railToolBudget: \"工具预算\",\n railSpend: \"已用\",\n railActivePlan: \"活跃计划\",\n railProgress: \"进度\",\n statusModel: \"模型\",\n statusCtx: \"上下文\",\n statusCache: \"缓存\",\n statusTurn: \"轮次\",\n statusSession: \"会话\",\n statusBalance: \"余额\",\n statusTurns: \"{count} 轮\",\n waitingStats: \"· · · 等待实时统计\",\n inflightPhase: \"{phase}\",\n inflightRunning: \"运行中\",\n inflightThinking: \"思考中\",\n inflightStreaming: \"输出中\",\n inflightWaiting: \"等待中\",\n inflightReasoning: \"推理 {count} 字符\",\n inflightOut: \"输出 {count} 字符\",\n abortBtn: \"中止 (Esc)\",\n confirmBtn: \"应用 (y)\",\n rejectBtn: \"拒绝 (n)\",\n applyRestBtn: \"应用剩余 (a)\",\n flipAutoBtn: \"切换为 AUTO (A)\",\n },\n overview: {\n loading: \"加载概览…\",\n failed: \"概览失败:{error}\",\n standaloneTitle: \"独立模式\",\n standaloneDesc:\n \"只读磁盘视图。在 reasonix code 内启动 /dashboard 以获取实时会话状态、MCP 和工具。\",\n cockpit: \"驾驶舱\",\n balance: \"余额\",\n tokens7d: \"tokens · 7 天\",\n cacheHit: \"缓存命中\",\n toolCalls24h: \"工具调用 · 24 小时\",\n budget: \"预算\",\n currentSession: \"当前会话\",\n noSession: \"无活跃会话 — 在 reasonix code 内执行 /dashboard 进行连接。\",\n promptTok: \"提示 tokens\",\n completionTok: \"补全 tokens\",\n cost: \"费用\",\n costTrend: \"费用 · 14 天\",\n noUsageYet: \"暂无用量\",\n dayAvg: \"/天 均值\",\n recentPlans: \"近期计划\",\n noPlans: \"暂无计划 — 使用 submit_plan 提交一个。\",\n toolActivity: \"工具活动\",\n noToolCalls: \"暂无工具调用。\",\n toolsLoaded: \"已加载工具\",\n mcpServers: \"MCP 服务器\",\n editMode: \"编辑模式\",\n version: \"Reasonix\",\n workingDir: \"工作目录\",\n projectRoot: \"项目根目录\",\n noPriorData: \"无历史数据\",\n stable: \"— 稳定\",\n vsPrior: \"{arrow} {pct}% 较上期\",\n active: \"活跃\",\n allUp: \"全部在线\",\n yoloWarning: \"所有提示被绕过\",\n checking: \"检查中\",\n latest: \"最新\",\n },\n usage: {\n loading: \"加载用量…\",\n failed: \"用量失败:{error}\",\n records: \"{count} 条记录\",\n dailyUsage: \"每日用量\",\n dailyMeta: \"费用 · 缓存节省 · 轮次\",\n noData: \"暂无用量数据 — 在 reasonix chat / code / run 中执行一轮,然后刷新。\",\n windows: \"滚动窗口\",\n colWindow: \"时间范围\",\n colTurns: \"轮次\",\n colCacheHit: \"缓存命中\",\n colCost: \"费用 (USD)\",\n colCacheSaved: \"缓存节省\",\n colVsClaude: \"对比 Claude\",\n colSaved: \"节省\",\n axisTime: \"时间\",\n axisUsd: \"美元\",\n axisTurns: \"轮次\",\n seriesCost: \"费用\",\n seriesCacheSaved: \"缓存节省\",\n seriesTurns: \"轮次\",\n mostUsed: \"最常用模型\",\n colModel: \"模型\",\n },\n sessions: {\n loading: \"加载会话…\",\n failed: \"会话失败:{error}\",\n noSessions: \"暂无已保存的会话。\",\n filterPlaceholder: \"筛选会话\",\n msgs: \"条消息\",\n pickHint: \"选择左侧的会话以查看其转录稿。\",\n resumeTitle: \"在 TUI 中恢复\",\n resumeDesc: \"会话中途切换需要重启,以便消息日志可以干净地回退。请退出当前会话,然后运行:\",\n loadingTranscript: \"加载转录稿…\",\n emptyTranscript: \"空的转录稿。\",\n messages: \"{count} 条消息\",\n newBtn: \"新建会话\",\n newHint: \"归档当前会话并开启新会话\",\n switchBtn: \"切换到此会话\",\n deleteBtn: \"删除\",\n deleteConfirm: \"确定删除会话「{name}」?转录文件将被移除,无法撤销。\",\n cantDeleteActive: \"请先切换到其他会话,再删除当前会话。\",\n attachRequired:\n \"实时会话操作需要已连接的 CLI 会话。请通过 reasonix chat 启动,或在 TUI 会话中打开仪表盘。\",\n activeChip: \"当前\",\n activePill: \"当前\",\n },\n tools: {\n loading: \"加载工具…\",\n failed: \"工具失败:{error}\",\n noTools: \"未注册任何工具。\",\n planMode: \"计划模式 — 写入受限\",\n colTool: \"工具\",\n colFlags: \"标志\",\n colDesc: \"描述\",\n readOnly: \"只读\",\n write: \"写入\",\n flat: \"扁平\",\n desc: {\n web_search:\n \"搜索公共网络。返回带标题、URL 和摘要的排序结果。当答案的正确性依赖于当前状态时调用——事件、价格、发布、现实世界的状态。\",\n web_fetch:\n \"下载 URL 并返回其可见文本内容(已剥离脚本/样式/导航)。在 web_search 摘要不够时使用。\",\n run_command:\n \"在项目根目录执行 shell 命令,返回合并的标准输出和标准错误。白名单中的只读命令立即执行;可能修改状态的操作需用户确认。\",\n run_background:\n \"启动一个长时间运行的进程并分离。返回任务 ID 用于查看日志、等待完成或终止。用于开发服务器、文件监听器和一次性长时间任务。\",\n job_output: \"读取后台任务的最新输出。返回缓冲区末尾内容并告知任务是否仍在运行。\",\n wait_for_job: \"在服务端阻塞直到后台任务完成(有超时限制)。用于替代轮询 job_output。\",\n stop_job: \"停止后台任务。先发送 SIGTERM,宽限期后发送 SIGKILL。可安全调用已退出的任务。\",\n list_jobs: \"列出本次会话启动的所有后台任务——运行中和已退出的——包含 ID、命令、PID 和状态。\",\n remember:\n \"保存一条记忆供未来会话使用。当用户陈述偏好、纠正你的方法、分享非显而易见的事实或要求你记住某事时使用。\",\n forget:\n \"删除记忆文件并从 MEMORY.md 中移除。当用户要求忘记某事或之前记住的事实已不再正确时使用。\",\n recall_memory: \"当记忆文件的一行摘要不够详细时,读取其完整内容。\",\n read_file:\n \"读取沙箱根目录下的文件。支持 head/tail/range 范围读取以节省上下文。超过 200 行的文件自动返回预览。\",\n list_directory: \"列出目录中的条目。每行一个条目,目录以斜杠标记。\",\n directory_tree: \"递归列出目录中的条目,以缩进树形结构显示。对大子目录自动折叠以节省预算。\",\n search_files: \"根据名称匹配子串或正则表达式查找文件。不区分大小写。默认跳过依赖/构建目录。\",\n search_content:\n \"递归搜索文件内容中的子串或正则表达式。以 path:line:text 格式返回匹配结果。查找引用的正确工具。\",\n glob: \"按 glob 模式列出文件,按修改时间排序。默认限制 200,最大 1000。默认跳过 node_modules/.git/dist。\",\n get_file_info: \"获取沙箱根目录下路径的状态信息。返回类型、字节大小和修改时间。\",\n write_file: \"创建或覆盖文件,内容由参数指定。按需创建父目录。\",\n edit_file: \"对现有文件应用 SEARCH/REPLACE 编辑。搜索必须完全匹配且在文件中唯一。\",\n multi_edit:\n \"跨一个或多个文件原子性地应用 N 个 SEARCH/REPLACE 编辑。如果任何编辑失败,不写入任何文件。\",\n create_directory: \"在沙箱根目录下创建目录(以及任何缺失的父目录)。\",\n move_file: \"重命名或移动沙箱根目录下的文件或目录。\",\n delete_file: \"删除沙箱根目录下的一个文件。拒绝目录——请使用 delete_directory 删除目录。\",\n delete_directory: \"递归删除沙箱根目录下的目录。传入 recursive:false 可拒绝非空目录。\",\n copy_file: \"复制沙箱根目录下的文件或目录。拒绝覆盖已存在的目标。\",\n submit_plan:\n \"提交一个具体的计划以供审查审批。用于多文件重构、架构变更或任何撤销代价高昂的操作。\",\n mark_step_complete: \"将已批准计划的一个步骤标记为完成。完成每个步骤后恰好调用一次。\",\n revise_plan: \"外科手术式替换进行中计划的剩余步骤。已完成的步骤永远不会被触及。\",\n run_skill:\n \"从技能索引中调用一个 playbook。传入裸技能名称。标记为子代理的技能将启动独立的子代理。\",\n spawn_subagent: \"为一个独立子任务启动隔离的子代理。用于并行分发或需要大量文件读取的工作。\",\n todo_write: \"多步工作的会话内任务跟踪器。每次调用替换整个列表。无审批关卡,不写入文件。\",\n ask_choice: \"向用户展示 2-6 个选项。当用户要求选择或需要偏好决策时使用。\",\n create_skill: \"创建一个新技能,用户可通过 /skill 命令调用。支持内联和子代理两种运行模式。\",\n add_mcp_server:\n \"在用户配置中注册新的 MCP 服务器。下次会话生效。支持 stdio、SSE 和 streamable-http。\",\n },\n },\n permissions: {\n loading: \"加载权限…\",\n failed: \"权限失败:{error}\",\n yoloTitle: \"YOLO 模式\",\n yoloDesc: \"所有 shell 命令自动运行,允许列表被绕过。在 TUI 中使用 /mode review 切换回来。\",\n project: \"项目\",\n builtin: \"内置\",\n addPrefix: \"添加前缀\",\n addPlaceholder: '例如 \"npm run build\" 或 \"deploy.sh\"',\n clearAll: \"清除全部\",\n alreadyIn: \"{prefix} 已在列表中\",\n added: \"已添加:{prefix}\",\n removed: \"已移除:{prefix}\",\n cleared: \"已清除 {count} 条\",\n removeConfirm: '从此项目的允许列表中移除 \"{prefix}\"?',\n clearConfirm: \"清除所有项目允许列表条目?内置条目不受影响。\",\n projectAllowlist: \"项目允许列表 · {count}\",\n nothingStored: \"此项目暂无存储的条目。\",\n colNum: \"#\",\n colPrefix: \"前缀\",\n builtinTitle: \"内置 · {count} · 只读\",\n standaloneWarning:\n \"修改操作需要在活跃的 reasonix code 会话内执行 /dashboard — 独立模式的 reasonix dashboard 无法确定要编辑哪个项目的允许列表。\",\n },\n mcp: {\n loading: \"加载 MCP…\",\n servers: \"MCP 服务器 · {count} 个已桥接\",\n all: \"全部\",\n live: \"在线\",\n unbridged: \"未桥接\",\n specPlaceholder: \"规格 — 例如 fs=npx -y @modelcontextprotocol/...\",\n saved: \"已保存\",\n savedRestart: \"已保存 — 重启 reasonix code 以桥接此服务器\",\n removed: \"已移除 — 重启以断开实时桥接\",\n removeConfirm: \"从配置中移除 MCP 规格?\\n\\n{spec}\",\n noServers: \"此会话中无 MCP 服务器。\",\n tools: \"个工具\",\n inConfig: \"在配置中 · 未加载\",\n unbridgedTitle: \"未桥接 · 在配置中\",\n removeBtn: \"移除\",\n spec: \"规格\",\n whyUnbridged: \"为什么未桥接?\",\n whyUnbridgedDesc:\n \"此规格存在于您的 config.json 中,但未桥接到实时会话。MCP 服务器在 reasonix code 启动时连接;仪表盘本身无法生成子进程。\",\n whyUnbridgedHint: \"激活方法:重启 reasonix code,然后刷新此仪表盘。\",\n bridgeFailed: \"桥接失败\",\n bridgeFailedTitle: \"桥接失败 · 在配置中\",\n bridgeFailedHint:\n \"已尝试桥接但失败。常见原因:URL 错误、需要鉴权、上游 404 / 5xx、本地命令缺失。修复后重启 reasonix code 重试。\",\n pickHint: \"选择左侧的 MCP 服务器以检查工具 / 资源 / 提示。\",\n toolsTitle: \"工具 · {count}\",\n resourcesTitle: \"资源 · {count}\",\n promptsTitle: \"提示 · {count}\",\n colName: \"名称\",\n colDesc: \"描述\",\n colUri: \"URI\",\n marketplace: \"市场\",\n marketplaceSearch: \"搜索注册表…\",\n marketplaceLoading: \"加载注册表…\",\n marketplaceMore: \"再加载 5 页\",\n marketplaceMoreLabel: \"再加载 50 条 · 当前 {shown} / {total}\",\n marketplaceMoreHint: \"需要从远端注册表再拉几页\",\n marketplaceMoreCachedHint: \"本地缓存已有更多条目\",\n marketplaceExhausted: \"已加载全部页\",\n marketplaceExhaustedFull: \"已展示全部 {total} 条 — 注册表耗尽\",\n marketplaceCount: \"已载入 {loaded} · 匹配 {matched} · 来源:{source}{cached}\",\n marketplaceCachedSuffix: \" · 缓存中\",\n marketplaceNoMatches: \"无匹配结果。换关键词或加载更多页。\",\n marketplaceInstall: \"安装\",\n marketplacePickHint: \"在左侧选择服务器,然后点安装。\",\n marketplaceInstalled: \"已安装 → {spec}\",\n marketplaceInstalledBridged: \"已安装并桥接 → {spec}\",\n marketplaceAlready: \"已安装过\",\n marketplaceNeedsEnv: \"需设置环境变量:{names}\",\n marketplaceSourceTag: \"[{source}]\",\n marketplaceNoInstall:\n \"Smithery 列表项 — 不暴露安装元数据;请直接 `npx -y @smithery/cli install {name}`\",\n marketplaceFetchOnInstall:\n \"Smithery 列表 — 安装时再拉详情。HTTP 服务映射为 streamable-http 远端;stdio 服务通过 @smithery/cli 运行。\",\n marketplaceInstalledBadge: \"已安装\",\n marketplaceUninstall: \"卸载\",\n marketplaceEnvTitle: \"必需的环境变量\",\n marketplaceEnvHint: \"下次启动 `reasonix code` 之前在 shell 里设好,桥接的服务器才能正常鉴权。\",\n marketplaceRestartHint:\n \"已写入 ~/.reasonix/config.json。重启 `reasonix code` 后服务器才会真正桥接(热重载在路线图上)。\",\n },\n memory: {\n loading: \"加载记忆…\",\n files: \"记忆 · {count} 个文件\",\n exists: \"已存在\",\n create: \"创建\",\n noFiles: \"暂无记忆文件。\",\n pickHint: \"选择左侧的记忆文件。\",\n pickDesc: \"项目 REASONIX.md 可提交;全局笔记存储在 ~/.reasonix/memory/。\",\n chars: \"{count} 个字符\",\n saved: \"已保存 {scope}\",\n reloadHint: \"在下次 /new 或会话重启时重新加载\",\n },\n hooks: {\n loading: \"加载钩子…\",\n resolved: \"已解析\",\n eventMatrix: \"事件矩阵\",\n matrixSub: \"{scripts} 个脚本 × {events} 个事件\",\n noHooks: \"未配置钩子。编辑下方的 JSON 以添加。\",\n colScript: \"脚本\",\n noProject: \"无活跃项目 — 在 reasonix code 中打开 /dashboard 以编辑项目钩子。\",\n saveReload: \"保存并重载\",\n discard: \"放弃更改\",\n savedReloaded: \"已保存并重载 {scope}\",\n recentRuns: \"近期运行\",\n noRuns: \"近期会话日志中无钩子运行记录。\",\n colWhen: \"时间\",\n colPhase: \"阶段\",\n colHook: \"钩子\",\n colOutcome: \"结果\",\n },\n skills: {\n loading: \"加载技能…\",\n filterPlaceholder: \"筛选技能\",\n project: \"项目\",\n custom: \"自定义\",\n global: \"全局\",\n builtin: \"内置\",\n newSkill: \"新技能\",\n noDescription: \"(无描述)\",\n runs7d: \"次运行 · 7 天\",\n pickHint: \"选择左侧的技能,或在上方创建新技能。\",\n readOnlyBuiltin: \"只读 · 内置\",\n readOnlyCustom: \"只读 · 自定义路径\",\n builtinDesc:\n \"内置技能随 Reasonix 一起发布;模型会自动识别。如需自定义,请创建同名的项目或全局技能。\",\n saved: \"已保存 {scope}/{name}\",\n deleteConfirm: \"删除技能 {scope}/{name}?\",\n reloadHint: \"在下次 /new 或会话重启时重新加载\",\n },\n system: {\n loading: \"加载健康状态…\",\n failed: \"健康检查失败:{error}\",\n healthChecks: \"健康检查\",\n version: \"版本\",\n checking: \"检查中\",\n latest: \"● 最新\",\n outOfDate: \"● 需要更新\",\n versionPending: \"版本检查中\",\n upToDate: \"已是最新\",\n latestVer: \"最新:{version}\",\n sessions: \"会话\",\n ok: \"● 正常\",\n memory: \"记忆\",\n semanticIndex: \"语义索引\",\n built: \"● 已构建\",\n none: \"— 无\",\n runIndex: \"运行 reasonix index 以构建\",\n usageLog: \"用量日志\",\n backgroundJobs: \"后台任务\",\n noSession: \"— 无会话\",\n running: \"{count} 个运行中\",\n attachHint: \"连接会话以查看任务\",\n shellSpawn: \"Shell + 生成\",\n paths: \"路径\",\n home: \"主目录\",\n sessionsPath: \"会话\",\n memoryPath: \"记忆\",\n semanticPath: \"语义\",\n usagePath: \"用量\",\n },\n plans: {\n loading: \"加载计划…\",\n failed: \"计划失败:{error}\",\n noPlans: \"暂无归档计划 — 运行调用 submit_plan 和 mark_step_complete 的轮次。\",\n filterPlaceholder: \"筛选计划\",\n active: \"进行中\",\n done: \"已完成\",\n idle: \"未开始\",\n steps: \"步骤\",\n pickHint: \"选择左侧的计划。\",\n noTitle: \"(无标题)\",\n stepTimeline: \"步骤时间线 · {done} / {total}\",\n step: \"步骤 {n}\",\n },\n semantic: {\n codeRequired: \"语义 — 需要代码模式\",\n indexBuilt: \"索引已构建\",\n noIndex: \"尚无索引\",\n ready: \"就绪\",\n setupNeeded: \"需要设置\",\n installOllama: \"安装 Ollama\",\n installOllamaDesc: \"Reasonix 不会为您运行包管理器。请先安装 Ollama,然后返回:\",\n macWindows: \"macOS / Windows:\",\n download: \"从 ollama.com/download 下载\",\n linux: \"Linux:\",\n refreshHint: \"安装后刷新 — 此面板将提供启动守护进程和拉取 {model} 的选项。\",\n daemon: \"守护进程\",\n daemonDesc: \"ollama 在您的 PATH 中,但 HTTP 守护进程不可达。\",\n startDaemon: \"启动守护进程\",\n runsOllama: \"以分离模式运行 ollama serve\",\n model: \"模型\",\n modelMissing: \"{model} 尚未安装。\",\n modelSize: \"首次拉取约 270 MB。\",\n pulling: \"拉取中…\",\n pullModel: \"拉取 {model}\",\n indexStatus: \"索引状态\",\n builtStatus: \"● 已构建\",\n incompatibleStatus: \"● 不兼容\",\n chunks: \"分块\",\n files: \"文件\",\n dim: \"维度\",\n size: \"大小\",\n lastBuild: \"上次构建\",\n builtWith: \"构建来源\",\n currentTarget: \"当前目标\",\n incompatibleHint:\n \"磁盘上的这个索引是为不同的 provider 或 model 构建的。运行\\u201C完全重建\\u201D即可替换。\",\n runIndexHint: \"运行索引以启用 semantic_search。\",\n reIndex: \"重建索引\",\n build: \"构建\",\n rebuild: \"完全重建\",\n stop: \"停止\",\n provider: \"提供方\",\n providerType: \"服务类型\",\n openaiCompat: \"OpenAI-Compatible\",\n apiUrl: \"API URL\",\n apiKey: \"API Key\",\n apiKeyStoredNote: \"API Key 仅保存在本地,不会发送到第三方。\",\n customRequestBody: \"自定义请求体\",\n invalidCustomRequestBody: \"自定义请求体必须是合法 JSON:{error}\",\n customRequestBodyMustBeObject: \"自定义请求体必须是 JSON 对象。\",\n saveBeforeIndex: \"请先保存语义设置,再启动索引。\",\n extraBody: \"扩展请求体\",\n batchSize: \"批次大小\",\n keepExistingKey: \"留空则保留现有 Key\",\n remoteProvider: \"远程向量服务\",\n remoteProviderDesc:\n \"在这里配置 OpenAI-Compatible embeddings 的完整 URL。Reasonix 会严格使用你提供的 URL 发起请求。\",\n ollama: \"Ollama\",\n binary: \"二进制\",\n found: \"已找到\",\n missing: \"缺失\",\n daemonStatus: \"守护进程\",\n up: \"运行中\",\n down: \"已停止\",\n pulled: \"已拉取\",\n indexConfig: \"索引配置\",\n reset: \"重置\",\n excludeDirs: \"排除目录\",\n excludeFiles: \"排除文件\",\n excludeExts: \"排除扩展名\",\n excludePatterns: \"排除模式\",\n glob: \"glob\",\n respectGitignore: \"遵循 .gitignore\",\n maxFileBytes: \"最大文件字节数\",\n skipLarger: \"跳过大于 ~{size} MiB 的文件\",\n preview: \"预览\",\n searchPlaceholder: \"描述要查找的内容 — '哪里处理中止信号'\",\n searching: \"搜索中…\",\n results: \"{count} 个结果 · {ms}ms · {model}\",\n noMatches: \"没有超过分数阈值的匹配。\",\n previewSummary: \"预览 — 将索引 {included} 个文件,跳过 {skipped} 个\",\n nothingSkipped: \"无跳过 — 所有遍历的文件都将被索引。\",\n firstIncluded: \"前 {count} 个包含的文件\",\n job: \"任务\",\n phaseSetup: \"初始化中\",\n phaseScan: \"扫描文件\",\n phaseEmbed: \"嵌入分块\",\n phaseWrite: \"写入索引\",\n phaseDone: \"完成\",\n phaseError: \"错误\",\n phaseCancelled: \"已停止\",\n setupFailed: \"初始化失败\",\n stopping: \"停止中\",\n scanned: \"已扫描 {count}\",\n changed: \"已变更 {count}\",\n skipped: \"已跳过 {count}\",\n chunksProgress: \"{done} / {total}({pct}%)\",\n result: \"结果\",\n added: \"已添加 {count}\",\n removed: \"已移除 {count}\",\n failed: \"失败 {count}\",\n skippedFiles: \"{total} 个文件({details})\",\n rebuildStarted: \"已启动完全重建\",\n incrementalStarted: \"已启动增量索引\",\n stopRequested: \"已请求停止 — 当前分块批次将首先完成\",\n startingDaemon: \"正在启动 ollama 守护进程(15 秒超时)…\",\n daemonUp: \"守护进程已启动\",\n daemonTimeout: \"守护进程未在规定时间内启动 — 请手动检查 ollama serve\",\n pullingModel: \"正在拉取 {model} — 首次安装可能需要几分钟\",\n savedConfig: \"已保存 · {count} 个字段已更新 · 重新运行索引以应用\",\n runningPreview: \"正在对项目根目录执行干运行…\",\n exclude: \"排除\",\n },\n modal: {\n shellTitle: \"Shell 命令\",\n shellBgTitle: \"后台进程\",\n shellSubtitle: \"模型想要运行一条 Shell 命令\",\n shellBgSubtitle: \"长时间运行 — 批准后继续运行\",\n pathTitle: \"沙箱外文件访问\",\n pathSubtitle: \"{intent} · 通过 {tool}\",\n pathRead: \"读取\",\n pathWrite: \"写入\",\n pathSandboxLabel: \"沙箱\",\n pathAllowPrefixLabel: \"允许前缀\",\n runOnce: \"运行一次\",\n alwaysAllow: '始终允许 \"{prefix}\"',\n deny: \"拒绝\",\n choiceTitle: \"模型需要您选择\",\n typeOwn: \"输入自定义回答\",\n typeOwnSummary: \"以上选项都不合适 — 写一个自由格式的回复。\",\n typePlaceholder: \"输入自由格式的回答…\",\n send: \"发送\",\n cancel: \"取消\",\n cancelSummary: \"放弃此问题。模型将询问您实际想要什么。\",\n planTitle: \"计划已提交\",\n planSubtitle: \"模型提出了一项计划;请审阅后选择\",\n approveInstructions: \"可选的最后指示 / 对开放问题的回答(Enter 发送空白)\",\n refinePlaceholder: \"需要更改什么?请具体说明。\",\n approve: \"批准\",\n refine: \"优化\",\n sendRefinement: \"发送优化\",\n editTitle: \"编辑待审阅\",\n editSubtitle: \"{path} · {remaining} / {total} 个块剩余\",\n before: \"修改前\",\n after: \"修改后\",\n workspaceTitle: \"模型想要切换工作区\",\n workspaceSubtitle: \"后续所有文件 / Shell / 记忆工具将针对新根目录解析\",\n switchBtn: \"切换 (Enter)\",\n denyBtn: \"拒绝 (Esc)\",\n stepComplete: \"步骤完成{counter}\",\n continueBtn: \"继续\",\n reviseBtn: \"修订…\",\n stopBtn: \"停止\",\n revisionTitle: \"模型提出了计划修订\",\n sendRevision: \"发送修订\",\n accept: \"接受\",\n reject: \"拒绝\",\n arguments: \"参数\",\n revisePlaceholder: \"下一步之前需要更改什么?留空则直接继续。\",\n pickerFilter: \"过滤…\",\n pickerEmpty: \"暂无内容。\",\n pickerLoadMore: \"加载更多\",\n pickerPick: \"打开\",\n pickerInstall: \"安装\",\n pickerUninstall: \"卸载\",\n pickerRename: \"重命名…\",\n pickerNew: \"新建…\",\n pickerNewPlaceholder: \"名称(留空使用默认)\",\n viewerClose: \"关闭\",\n },\n error: {\n title: \"仪表盘出错了\",\n body: \"TUI 不受影响——只有这个浏览器标签出了问题。通常可以直接关闭并继续使用,不会打断智能体。\",\n copyDetails: \"复制详情\",\n copied: \"已复制 ✓\",\n reportOnGithub: \"在 GitHub 上报告\",\n dismiss: \"关闭 (Esc)\",\n crashing: \"此面板持续崩溃 — {name}\",\n retry: \"重试\",\n recovering: \"恢复中…\",\n },\n fmt: {\n justNow: \"刚刚\",\n minutesAgo: \"{n} 分钟前\",\n hoursAgo: \"{n} 小时前\",\n daysAgo: \"{n} 天前\",\n },\n cards: {\n applied: \"已应用\",\n cacheHit: \"缓存命中\",\n checkpointRewind: \"检查点回退\",\n cost: \"费用\",\n diffApply: \"应用\",\n diffApplyChanges: \"应用更改\",\n diffAwaiting: \"待审阅\",\n diffDiscard: \"丢弃\",\n done: \"完成\",\n elapsed: \"耗时\",\n error: \"错误\",\n errorName: \"错误\",\n failed: \"失败\",\n hits: \"命中\",\n memoryCountSuffix: \"条记忆\",\n memoryName: \"记忆\",\n output: \"输出\",\n planDefaultTitle: \"计划\",\n prompt: \"提示词\",\n compactionMeta: \"{chars} 字符\",\n compactionName: \"已压缩历史\",\n reasoningComplete: \"推理完成\",\n reasoningName: \"推理\",\n result: \"结果\",\n running: \"运行中\",\n searchName: \"搜索\",\n shellAlwaysAllow: \"始终允许\",\n shellAwaiting: \"待审批\",\n shellExecuteHint: \"执行此命令?\",\n shellReject: \"拒绝\",\n shellRun: \"运行\",\n shellRunning: \"运行中\",\n streaming: \"输出中\",\n subagentDone: \"子代理完成\",\n subagentDoneProgress: \"子代理完成 ({pct}%)\",\n subagentFailed: \"子代理失败\",\n subagentRunning: \"子代理运行中\",\n },\n planBadge: {\n blocked: \"已阻塞\",\n done: \"完成\",\n failed: \"失败\",\n pending: \"待处理\",\n running: \"运行中\",\n },\n composer: {\n atHeader: \"提及文件\",\n close: \"关闭\",\n commandPalette: \"命令面板\",\n commands: \"命令\",\n commandsLabel: \"命令\",\n confirm: \"确认\",\n imageFilterName: \"图片\",\n insertFile: \"插入文件\",\n insertImage: \"插入图片\",\n interrupt: \"中断\",\n mentionFiles: \"提及文件\",\n mentionLabel: \"提及\",\n newline: \"换行\",\n noMatches: \"无匹配\",\n placeholder: \"输入提示词…\",\n queue: \"队列\",\n queueCount: \"{count} 个排队\",\n select: \"选择\",\n send: \"发送\",\n slashHeader: \"斜杠命令\",\n switchModel: \"切换模型\",\n switchEffort: \"切换推理强度\",\n workspaceRoot: \"工作区根目录\",\n },\n contextPanel: {\n allow: \"允许\",\n ask: \"询问\",\n autoApproveTitle: \"自动审批\",\n cacheKey: \"缓存\",\n contextTokens: \"上下文 tokens\",\n fileInContext: \"在上下文中\",\n fileModified: \"已修改\",\n filesCount: \"{count} 个文件\",\n filesTab: \"文件\",\n filesTitle: \"文件\",\n freeKey: \"空闲\",\n itemCount: \"{count} 个项目\",\n mcpConfigured: \"已配置\",\n mcpConnecting: \"连接中…\",\n mcpDisabled: \"已禁用\",\n mcpEmpty: \"无 MCP 服务器\",\n mcpFailed: \"失败\",\n mcpReady: \"就绪\",\n mcpReadyAll: \"全部就绪\",\n mcpReadySome: \"部分就绪\",\n mcpTitle: \"MCP\",\n mcpTools: \"工具\",\n memoryTab: \"记忆\",\n memoryTitle: \"记忆\",\n noFilesMsg: \"上下文中无文件\",\n noMemoriesMsg: \"无记忆\",\n reservedKey: \"保留\",\n ruleReadOnly: \"只读\",\n ruleReview: \"审阅\",\n ruleShellAllowlist: \"Shell 允许列表\",\n rulesTab: \"规则\",\n ruleWritesAsk: \"写入需询问\",\n ruleYolo: \"YOLO\",\n scopeGlobal: \"全局\",\n scopeProject: \"项目\",\n toolsTab: \"工具\",\n usedKey: \"已用\",\n },\n dragDrop: {\n overlay: \"拖放文件到此处\",\n },\n extraCards: {\n approve: \"批准\",\n balance: \"余额\",\n cache: \"缓存\",\n cacheHit: \"缓存命中\",\n contextWindow: \"上下文窗口\",\n doctorTitle: \"诊断\",\n output: \"输出\",\n prompt: \"提示词\",\n reasoning: \"推理\",\n reject: \"拒绝\",\n sessionCost: \"会话成本\",\n sessionUsage: \"会话用量\",\n topToolsUsage: \"热门工具\",\n unknownKind: \"未知\",\n memoryUser: \"用户\",\n memoryFeedback: \"反馈\",\n memoryProject: \"项目\",\n memoryReference: \"参考\",\n },\n jobs: {\n empty: \"无后台任务\",\n exited: \"已退出\",\n kbClose: \"关闭\",\n kbToggle: \"切换\",\n running: \"运行中\",\n stop: \"停止\",\n stopAll: \"全部停止\",\n stopAllTip: \"停止所有任务\",\n stopOne: \"停止\",\n title: \"后台任务\",\n },\n live: {\n deliveredWaiting: \"等待下一条消息\",\n reasoning: \"推理\",\n running: \"运行中\",\n secondsAgo: \"{n} 秒前\",\n you: \"你\",\n },\n markdown: {\n copied: \"已复制!\",\n copy: \"复制\",\n externalLinkTitle: \"在新标签中打开\",\n filePillTitle: \"打开文件\",\n localLinkTitle: \"打开链接\",\n },\n palette: {\n abort: \"中止\",\n abortHint: \"中止当前请求\",\n about: \"关于\",\n clearChat: \"清除对话\",\n clearChatHint: \"清除对话\",\n closeTab: \"关闭标签\",\n closeTabHint: \"关闭当前标签\",\n copyConv: \"复制对话\",\n copyConvHint: \"复制对话为 Markdown\",\n copyLast: \"复制上条回复\",\n copyLastHint: \"复制上条助手消息\",\n countSuffix: \"个项目\",\n empty: \"无匹配命令\",\n exportMd: \"导出为 Markdown\",\n exportMdHint: \"导出对话为 Markdown 文件\",\n focusComposer: \"聚焦编辑器\",\n footClose: \"关闭\",\n footMove: \"移动\",\n footRun: \"运行\",\n groupAction: \"操作\",\n groupNav: \"导航\",\n groupSettings: \"设置\",\n groupWorkspace: \"工作区\",\n newChat: \"新建对话\",\n newChatHint: \"开始新对话\",\n newTab: \"新建标签\",\n newTabHint: \"打开新标签\",\n pickWorkspace: \"切换工作区\",\n pickWorkspaceHint: \"更改工作区\",\n searchPlaceholder: \"搜索命令…\",\n settings: \"设置\",\n settingsHint: \"打开设置\",\n },\n panel: {\n renderError: \"面板崩溃\",\n },\n sidebarPanel: {\n approvalRules: \"审批规则\",\n cancel: \"取消\",\n commandPalette: \"命令面板\",\n daysAgo: \"{n} 天前\",\n delete: \"删除\",\n deleteSession: \"删除会话\",\n hoursAgo: \"{n} 小时前\",\n justNow: \"刚刚\",\n loading: \"加载中…\",\n messageCount: \"{count} 条消息\",\n minutesAgo: \"{n} 分钟前\",\n newChat: \"新建对话\",\n noMatches: \"无匹配\",\n noSessions: \"无会话\",\n recent: \"最近\",\n searchSessions: \"搜索会话…\",\n sessionTitle: \"会话\",\n settings: \"设置\",\n weeksAgo: \"{n} 周前\",\n },\n statusbar: {\n balance: \"余额\",\n busy: \"忙碌\",\n cache: \"缓存\",\n cacheHit: \"缓存命中\",\n jobs: \"任务\",\n jobsTip: \"后台任务\",\n offline: \"离线\",\n online: \"在线\",\n switchCurrency: \"切换货币\",\n switchTheme: \"切换主题\",\n switchWorkspace: \"切换工作区\",\n themeDark: \"深色\",\n themeLight: \"浅色\",\n themeStyleGraphite: \"石墨\",\n themeStyleSandstone: \"砂岩\",\n themeStylePorcelain: \"瓷白\",\n themeStyleMidnight: \"午夜\",\n thisTurn: \"本轮\",\n tokens: \"Tokens\",\n },\n thread: {\n activePlan: \"活跃计划\",\n allowRead: \"允许读取\",\n allowWrite: \"允许写入\",\n alwaysAllow: \"始终允许\",\n alwaysAllowPrefix: \"始终允许 {prefix}\",\n approve: \"批准\",\n approveRewrite: \"批准重写\",\n cancel: \"取消\",\n checkpointKind: \"检查点\",\n checkpointSub: \"保存当前状态\",\n checkpointTitle: \"创建检查点\",\n collapse: \"折叠\",\n continue: \"继续\",\n copyMessage: \"复制消息\",\n copyResponse: \"复制回复\",\n execute: \"执行\",\n keepOriginal: \"保留原始\",\n keepSteps: \"保留步骤\",\n optionCount: \"{count} 个选项\",\n pathAccessKind: \"路径访问\",\n planConfirmationKind: \"计划审批\",\n planRevisionKind: \"计划修订\",\n planRunning: \"计划进行中\",\n planStepCount: \"步骤 {done}/{total}\",\n readPathOutsideSandbox: \"沙箱外读取路径\",\n refine: \"优化\",\n reject: \"拒绝\",\n revise: \"修订\",\n revisionMeta: \"修订\",\n rewritePlan: \"重写计划\",\n risk: \"风险评估\",\n riskMedium: \"中等风险\",\n runBackgroundCommand: \"后台运行\",\n runCommand: \"运行命令\",\n shellConfirmationKind: \"Shell 确认\",\n startPlan: \"启动计划\",\n stop: \"停止\",\n subagent: \"子代理\",\n userChoiceKind: \"用户选择\",\n writePathOutsideSandbox: \"沙箱外写入路径\",\n you: \"你\",\n },\n workdir: {\n browse: \"浏览…\",\n cancel: \"取消\",\n empty: \"无工作区\",\n emptyDir: \"无子目录。\",\n go: \"前往\",\n goTip: \"跳转到该路径\",\n loading: \"加载中…\",\n openHere: \"打开此目录\",\n pathPlaceholder: \"绝对路径…\",\n promptWeb: \"输入要打开的工作区绝对路径:\",\n searchPlaceholder: \"搜索工作区…\",\n title: \"工作区\",\n },\n about: {\n close: \"关闭\",\n repo: \"仓库\",\n sidebarLabel: \"关于\",\n tagline: \"AI 驱动的编程助手\",\n version: \"版本\",\n },\n effort: {\n lowDesc: \"最快 — 极少推理\",\n mediumDesc: \"平衡\",\n highDesc: \"默认 — vLLM / Azure 安全\",\n maxDesc: \"DeepSeek 扩展;标准 OpenAI / vLLM 会拒绝\",\n },\n editMode: {\n review: \"审阅\",\n reviewHint: \"编辑和非允许列表的 shell 命令都会先询问\",\n auto: \"自动\",\n autoHint: \"编辑自动应用,shell 仍会询问\",\n yolo: \"YOLO\",\n yoloHint: \"编辑和 shell 都自动运行,绕过允许列表\",\n },\n};\n","import { useEffect, useState } from \"react\";\nimport { en } from \"./en\";\nimport { zhCN } from \"./zh-CN\";\n\nexport type Lang = \"en\" | \"zh-CN\";\n\nconst SUPPORTED: ReadonlySet<Lang> = new Set<Lang>([\"en\", \"zh-CN\"]);\nconst STORAGE_KEY = \"reasonix.lang\";\n\ntype Listener = () => void;\nconst listeners: Listener[] = [];\n\nfunction detectDefault(): Lang {\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored && SUPPORTED.has(stored as Lang)) return stored as Lang;\n } catch {\n /* private mode */\n }\n const nav = typeof navigator !== \"undefined\" ? navigator.language : \"\";\n return nav.toLowerCase().startsWith(\"zh\") ? \"zh-CN\" : \"en\";\n}\n\nlet currentLang: Lang = detectDefault();\n\nfunction syncHtmlLang(lang: Lang): void {\n if (typeof document === \"undefined\") return;\n try {\n document.documentElement.lang = lang;\n } catch {\n /* document not ready */\n }\n}\n\nsyncHtmlLang(currentLang);\n\nexport function getLang(): Lang {\n return currentLang;\n}\n\nexport function setLang(lang: Lang): void {\n if (!SUPPORTED.has(lang) || lang === currentLang) return;\n currentLang = lang;\n try {\n localStorage.setItem(STORAGE_KEY, lang);\n } catch {\n /* ignore */\n }\n syncHtmlLang(lang);\n for (const cb of listeners) cb();\n}\n\nexport function useLang(): Lang {\n const [, setTick] = useState(0);\n useEffect(() => {\n const cb = () => setTick((n) => n + 1);\n listeners.push(cb);\n return () => {\n const idx = listeners.indexOf(cb);\n if (idx >= 0) listeners.splice(idx, 1);\n };\n }, []);\n return currentLang;\n}\n\nconst dicts = { en, \"zh-CN\": zhCN } as const;\n\ntype Dict = typeof en;\ntype Path<T, K extends keyof T = keyof T> = K extends string\n ? T[K] extends Record<string, unknown>\n ? `${K}.${Path<T[K]>}`\n : K\n : never;\nexport type TKey = Path<Dict>;\n\nfunction resolve(dict: Dict, key: string): string {\n const parts = key.split(\".\");\n let cursor: unknown = dict;\n for (const p of parts) {\n if (cursor && typeof cursor === \"object\" && p in (cursor as Record<string, unknown>)) {\n cursor = (cursor as Record<string, unknown>)[p];\n } else {\n return key;\n }\n }\n return typeof cursor === \"string\" ? cursor : key;\n}\n\nexport function t(key: TKey, params?: Record<string, string | number>): string {\n const raw = resolve(dicts[currentLang], key);\n if (!params) return raw;\n return raw.replace(/\\{(\\w+)\\}/g, (_, k) => (k in params ? String(params[k]) : `{${k}}`));\n}\n","import type { ReactNode } from \"react\";\n\nexport type ShortcutKey = \"mod\" | \"shift\" | \"enter\" | \"tab\" | \"esc\" | \"updown\" | string;\n\nfunction isMacPlatform(): boolean {\n if (typeof document === \"undefined\") return false;\n return document.documentElement.dataset.platform === \"macos\";\n}\n\nfunction keyLabel(key: ShortcutKey, mac: boolean): string {\n switch (key) {\n case \"mod\":\n case \"⌘\":\n return mac ? \"⌘\" : \"Ctrl\";\n case \"shift\":\n case \"⇧\":\n return mac ? \"⇧\" : \"Shift\";\n case \"enter\":\n case \"⏎\":\n return \"Enter\";\n case \"tab\":\n case \"⇥\":\n return \"Tab\";\n case \"esc\":\n return \"Esc\";\n case \"updown\":\n case \"↑↓\":\n return \"↑↓\";\n default:\n return key;\n }\n}\n\nexport function shortcutText(keys: readonly ShortcutKey[]): string {\n const mac = isMacPlatform();\n return keys.map((key) => keyLabel(key, mac)).join(mac ? \"\" : \"+\");\n}\n\nexport function localizeShortcutText(text: string): string {\n return text.replace(/⌘/g, keyLabel(\"mod\", isMacPlatform()));\n}\n\nexport function Shortcut({\n keys,\n className,\n}: {\n keys: readonly ShortcutKey[];\n className?: string;\n}): ReactNode {\n const mac = isMacPlatform();\n return (\n <span className={[\"shortcut\", className].filter(Boolean).join(\" \")}>\n {keys.map((key, index) => (\n <kbd key={`${key}-${index}`} data-key={key}>\n {keyLabel(key, mac)}\n </kbd>\n ))}\n </span>\n );\n}\n","import {\n ClipboardCopy,\n Download,\n FilePlus,\n FocusIcon,\n FolderOpen,\n Info,\n Plus,\n Search,\n Settings,\n SquareX,\n StopCircle,\n Trash2,\n} from \"lucide-react\";\nimport { type ReactNode, useEffect, useMemo, useRef, useState } from \"react\";\nimport { t, useLang } from \"./i18n\";\nimport { Shortcut, type ShortcutKey } from \"./ui/shortcut\";\n\nexport type CommandGroup = \"nav\" | \"action\" | \"workspace\" | \"settings\";\n\nexport type Command = {\n id: string;\n label: string;\n hint?: string;\n icon: ReactNode;\n shortcut?: ShortcutKey[];\n group: CommandGroup;\n run: () => void;\n};\n\nexport function useCommandPalette(active: boolean = true) {\n const [open, setOpen] = useState(false);\n useEffect(() => {\n // Skip in background tabs — each TabRuntime calls this hook, so without the gate Cmd+K toggles every tab's palette at once.\n if (!active) return;\n const onKey = (e: KeyboardEvent) => {\n const mod = e.ctrlKey || e.metaKey;\n if (mod && (e.key === \"k\" || e.key === \"K\")) {\n e.preventDefault();\n setOpen((v) => !v);\n } else if (e.key === \"Escape\") {\n setOpen(false);\n }\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [active]);\n return { open, setOpen };\n}\n\nexport type CommandHandlers = {\n newChat: () => void;\n clearChat: () => void;\n focusComposer: () => void;\n openSettings: () => void;\n about: () => void;\n abort: () => void;\n copyLast: () => void;\n conversationCopy: () => void;\n exportMarkdown: () => void;\n pickWorkspace: () => void;\n newTab: () => void;\n closeTab: () => void;\n busy: boolean;\n canCloseTab: boolean;\n hasMessages: boolean;\n};\n\nexport function buildCommands(handlers: CommandHandlers): Command[] {\n const list: Command[] = [\n {\n id: \"new-chat\",\n group: \"nav\",\n label: t(\"palette.newChat\"),\n hint: t(\"palette.newChatHint\"),\n icon: <FilePlus size={13} />,\n shortcut: [\"mod\", \"N\"],\n run: handlers.newChat,\n },\n {\n id: \"new-tab\",\n group: \"nav\",\n label: t(\"palette.newTab\"),\n hint: t(\"palette.newTabHint\"),\n icon: <Plus size={13} />,\n shortcut: [\"mod\", \"T\"],\n run: handlers.newTab,\n },\n ];\n if (handlers.canCloseTab) {\n list.push({\n id: \"close-tab\",\n group: \"nav\",\n label: t(\"palette.closeTab\"),\n hint: t(\"palette.closeTabHint\"),\n icon: <SquareX size={13} />,\n shortcut: [\"mod\", \"W\"],\n run: handlers.closeTab,\n });\n }\n list.push({\n id: \"focus-composer\",\n group: \"nav\",\n label: t(\"palette.focusComposer\"),\n icon: <FocusIcon size={13} />,\n shortcut: [\"mod\", \"L\"],\n run: handlers.focusComposer,\n });\n if (handlers.busy) {\n list.push({\n id: \"abort\",\n group: \"action\",\n label: t(\"palette.abort\"),\n hint: t(\"palette.abortHint\"),\n icon: <StopCircle size={13} />,\n shortcut: [\"esc\"],\n run: handlers.abort,\n });\n }\n if (handlers.hasMessages) {\n list.push({\n id: \"copy-last\",\n group: \"action\",\n label: t(\"palette.copyLast\"),\n hint: t(\"palette.copyLastHint\"),\n icon: <ClipboardCopy size={13} />,\n run: handlers.copyLast,\n });\n list.push({\n id: \"copy-conv\",\n group: \"action\",\n label: t(\"palette.copyConv\"),\n hint: t(\"palette.copyConvHint\"),\n icon: <ClipboardCopy size={13} />,\n run: handlers.conversationCopy,\n });\n list.push({\n id: \"export-md\",\n group: \"action\",\n label: t(\"palette.exportMd\"),\n hint: t(\"palette.exportMdHint\"),\n icon: <Download size={13} />,\n run: handlers.exportMarkdown,\n });\n list.push({\n id: \"clear-chat\",\n group: \"action\",\n label: t(\"palette.clearChat\"),\n hint: t(\"palette.clearChatHint\"),\n icon: <Trash2 size={13} />,\n run: handlers.clearChat,\n });\n }\n list.push({\n id: \"pick-workspace\",\n group: \"workspace\",\n label: t(\"palette.pickWorkspace\"),\n hint: t(\"palette.pickWorkspaceHint\"),\n icon: <FolderOpen size={13} />,\n run: handlers.pickWorkspace,\n });\n list.push({\n id: \"settings\",\n group: \"settings\",\n label: t(\"palette.settings\"),\n hint: t(\"palette.settingsHint\"),\n icon: <Settings size={13} />,\n run: handlers.openSettings,\n });\n list.push({\n id: \"about\",\n group: \"settings\",\n label: t(\"palette.about\"),\n icon: <Info size={13} />,\n run: handlers.about,\n });\n return list;\n}\n\nconst GROUP_ORDER: CommandGroup[] = [\"nav\", \"action\", \"workspace\", \"settings\"];\n\nfunction groupLabel(g: CommandGroup): string {\n switch (g) {\n case \"nav\": return t(\"palette.groupNav\");\n case \"action\": return t(\"palette.groupAction\");\n case \"workspace\": return t(\"palette.groupWorkspace\");\n case \"settings\": return t(\"palette.groupSettings\");\n }\n}\n\nexport function CommandPalette({\n open,\n onClose,\n commands,\n}: {\n open: boolean;\n onClose: () => void;\n commands: Command[];\n}) {\n useLang();\n const [query, setQuery] = useState(\"\");\n const [active, setActive] = useState(0);\n const inputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n\n const filtered = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return commands;\n return commands.filter((c) =>\n [c.label, c.hint].filter(Boolean).join(\" \").toLowerCase().includes(q),\n );\n }, [query, commands]);\n\n useEffect(() => {\n if (open) {\n setQuery(\"\");\n setActive(0);\n requestAnimationFrame(() => inputRef.current?.focus());\n }\n }, [open]);\n\n useEffect(() => {\n setActive((a) => Math.min(a, Math.max(0, filtered.length - 1)));\n }, [filtered.length]);\n\n useEffect(() => {\n const el = listRef.current?.querySelector<HTMLElement>(`[data-idx=\"${active}\"]`);\n el?.scrollIntoView({ block: \"nearest\" });\n }, [active]);\n\n const grouped = useMemo(() => {\n const byGroup = new Map<CommandGroup, Command[]>();\n for (const c of filtered) {\n const arr = byGroup.get(c.group) ?? [];\n arr.push(c);\n byGroup.set(c.group, arr);\n }\n return GROUP_ORDER\n .map((g) => ({ group: g, items: byGroup.get(g) ?? [] }))\n .filter((s) => s.items.length > 0);\n }, [filtered]);\n\n if (!open) return null;\n\n const run = (cmd: Command) => {\n cmd.run();\n onClose();\n };\n\n return (\n <div className=\"cmdk-mask\" onMouseDown={onClose}>\n <div className=\"cmdk\" onMouseDown={(e) => e.stopPropagation()}>\n <div className=\"cmdk-head\">\n <Search size={14} />\n <input\n ref={inputRef}\n placeholder={t(\"palette.searchPlaceholder\")}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setActive((a) => Math.min(a + 1, filtered.length - 1));\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setActive((a) => Math.max(a - 1, 0));\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n const cmd = filtered[active];\n if (cmd) run(cmd);\n }\n }}\n />\n <span className=\"hint\">\n <Shortcut keys={[\"esc\"]} />\n </span>\n </div>\n <div className=\"cmdk-body\" ref={listRef}>\n {filtered.length === 0 ? (\n <div className=\"cmdk-empty\">{t(\"palette.empty\")}</div>\n ) : null}\n {grouped.map((section) => (\n <div className=\"cmdk-group\" key={section.group}>\n <div className=\"cmdk-gh\">{groupLabel(section.group)}</div>\n {section.items.map((c) => {\n const i = filtered.indexOf(c);\n return (\n <div\n key={c.id}\n data-idx={i}\n className=\"cmdk-row\"\n data-active={i === active}\n onMouseEnter={() => setActive(i)}\n onClick={() => run(c)}\n >\n <span className=\"ic\">{c.icon}</span>\n <span className=\"l\">{c.label}</span>\n <span className=\"g\">{groupLabel(c.group)}</span>\n {c.shortcut ? (\n <span className=\"kb\">\n <Shortcut keys={c.shortcut} />\n </span>\n ) : (\n <span className=\"kb-empty\" />\n )}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n <div className=\"cmdk-foot\">\n <span>\n <Shortcut keys={[\"updown\"]} />\n {t(\"palette.footMove\")}\n </span>\n <span>\n <Shortcut keys={[\"enter\"]} />\n {t(\"palette.footRun\")}\n </span>\n <span>\n <Shortcut keys={[\"esc\"]} />\n {t(\"palette.footClose\")}\n </span>\n <span style={{ marginLeft: \"auto\", color: \"var(--muted)\" }}>\n {filtered.length} {t(\"palette.countSuffix\")}\n </span>\n </div>\n </div>\n </div>\n );\n}\n\nexport function Toast({ message }: { message: { msg: string; yolo?: boolean } | null }) {\n if (!message) return null;\n if (message.yolo) {\n return (\n <div className=\"toast toast-yolo\">\n <span className=\"toast-yolo-badge\">YOLO</span>\n {message.msg}\n </div>\n );\n }\n return <div className=\"toast\">{message.msg}</div>;\n}\n","import { Highlight, type PrismTheme } from \"prism-react-renderer\";\nimport { useEffect, useRef, useState } from \"react\";\n\nconst DARK_THEME: PrismTheme = {\n plain: { color: \"#dde1ea\", backgroundColor: \"transparent\" },\n styles: [\n { types: [\"comment\", \"prolog\", \"doctype\", \"cdata\"], style: { color: \"#6d6e80\", fontStyle: \"italic\" } },\n { types: [\"punctuation\"], style: { color: \"#a8a9b8\" } },\n { types: [\"property\", \"tag\", \"boolean\", \"number\", \"constant\", \"symbol\", \"deleted\"], style: { color: \"#fbbf24\" } },\n { types: [\"selector\", \"attr-name\", \"string\", \"char\", \"builtin\", \"inserted\"], style: { color: \"#86dcb1\" } },\n { types: [\"operator\", \"entity\", \"url\"], style: { color: \"#84b9e8\" } },\n { types: [\"atrule\", \"attr-value\", \"keyword\"], style: { color: \"#b4a8f0\" } },\n { types: [\"function\", \"class-name\", \"maybe-class-name\"], style: { color: \"#84b9e8\", fontWeight: \"500\" } },\n { types: [\"regex\", \"important\", \"variable\"], style: { color: \"#f0c062\" } },\n { types: [\"important\", \"bold\"], style: { fontWeight: \"bold\" } },\n { types: [\"italic\"], style: { fontStyle: \"italic\" } },\n ],\n};\n\nconst LIGHT_THEME: PrismTheme = {\n plain: { color: \"#24292e\", backgroundColor: \"transparent\" },\n styles: [\n { types: [\"comment\", \"prolog\", \"doctype\", \"cdata\"], style: { color: \"#6a737d\", fontStyle: \"italic\" } },\n { types: [\"punctuation\"], style: { color: \"#24292e\" } },\n { types: [\"property\", \"tag\", \"boolean\", \"number\", \"constant\", \"symbol\", \"deleted\"], style: { color: \"#d73a49\" } },\n { types: [\"selector\", \"attr-name\", \"string\", \"char\", \"builtin\", \"inserted\"], style: { color: \"#032f62\" } },\n { types: [\"operator\", \"entity\", \"url\"], style: { color: \"#d73a49\" } },\n { types: [\"atrule\", \"attr-value\", \"keyword\"], style: { color: \"#d73a49\" } },\n { types: [\"function\", \"class-name\", \"maybe-class-name\"], style: { color: \"#6f42c1\", fontWeight: \"500\" } },\n { types: [\"regex\", \"important\", \"variable\"], style: { color: \"#e36209\" } },\n { types: [\"important\", \"bold\"], style: { fontWeight: \"bold\" } },\n { types: [\"italic\"], style: { fontStyle: \"italic\" } },\n ],\n};\n\nfunction usePrismTheme(): PrismTheme {\n const [theme, setTheme] = useState<\"dark\" | \"light\">(() =>\n document.documentElement.dataset.theme === \"light\" ? \"light\" : \"dark\",\n );\n const prevRef = useRef(theme);\n useEffect(() => {\n const el = document.documentElement;\n const cb = () => {\n const t = el.dataset.theme === \"light\" ? \"light\" : \"dark\";\n if (t !== prevRef.current) {\n prevRef.current = t;\n setTheme(t);\n }\n };\n const mo = new MutationObserver(cb);\n mo.observe(el, { attributes: true, attributeFilter: [\"data-theme\"] });\n return () => mo.disconnect();\n }, []);\n return theme === \"dark\" ? DARK_THEME : LIGHT_THEME;\n}\n\nexport const PRISM_THEME = DARK_THEME;\n\nconst EXTS: Record<string, string> = {\n ts: \"typescript\", tsx: \"tsx\", mts: \"typescript\", cts: \"typescript\",\n js: \"javascript\", jsx: \"jsx\", mjs: \"javascript\", cjs: \"javascript\",\n py: \"python\", pyi: \"python\",\n rs: \"rust\",\n go: \"go\",\n json: \"json\", jsonc: \"json\",\n md: \"markdown\", mdx: \"markdown\",\n css: \"css\", scss: \"scss\", less: \"less\",\n html: \"markup\", htm: \"markup\", xml: \"markup\", svg: \"markup\",\n yaml: \"yaml\", yml: \"yaml\",\n toml: \"toml\",\n sh: \"bash\", bash: \"bash\", zsh: \"bash\", fish: \"bash\",\n sql: \"sql\",\n rb: \"ruby\",\n java: \"java\", kt: \"kotlin\",\n swift: \"swift\",\n c: \"c\", h: \"c\",\n cpp: \"cpp\", cc: \"cpp\", cxx: \"cpp\", hpp: \"cpp\", hxx: \"cpp\",\n cs: \"csharp\",\n php: \"php\",\n lua: \"lua\",\n dart: \"dart\",\n ex: \"elixir\", exs: \"elixir\",\n erl: \"erlang\",\n hs: \"haskell\",\n clj: \"clojure\", cljs: \"clojure\",\n zig: \"zig\",\n vue: \"markup\",\n svelte: \"markup\",\n graphql: \"graphql\", gql: \"graphql\",\n proto: \"protobuf\",\n dockerfile: \"docker\",\n};\n\nexport function langFromPath(path: string | null | undefined): string | null {\n if (!path) return null;\n const base = path.split(/[\\\\/]/).pop() ?? \"\";\n if (base.toLowerCase() === \"dockerfile\") return \"docker\";\n if (base.toLowerCase() === \"makefile\") return \"makefile\";\n const m = /\\.([a-z0-9]+)$/i.exec(base);\n if (!m) return null;\n return EXTS[m[1].toLowerCase()] ?? null;\n}\n\nexport function CodeView({\n text,\n lang,\n startLine = 1,\n showLineNumbers = true,\n}: {\n text: string;\n lang: string;\n startLine?: number;\n showLineNumbers?: boolean;\n}) {\n const theme = usePrismTheme();\n return (\n <Highlight theme={theme} code={text} language={lang}>\n {({ className, tokens, getLineProps, getTokenProps }) => (\n <pre className={`codeview ${className}`}>\n {tokens.map((line, i) => (\n <div key={i} {...getLineProps({ line })} className=\"codeview-line\">\n {showLineNumbers && (\n <span className=\"codeview-line-num\">{i + startLine}</span>\n )}\n <span className=\"codeview-line-content\">\n {line.map((token, k) => (\n <span key={k} {...getTokenProps({ token })} />\n ))}\n </span>\n </div>\n ))}\n </pre>\n )}\n </Highlight>\n );\n}\n\nexport function CollapsibleCode({\n text,\n lang,\n startLine = 1,\n maxLines = 20,\n}: {\n text: string;\n lang: string;\n startLine?: number;\n maxLines?: number;\n}) {\n const [open, setOpen] = useState(false);\n const lines = text.split(\"\\n\");\n const tooLong = lines.length > maxLines;\n const shown = open || !tooLong ? text : lines.slice(0, maxLines).join(\"\\n\");\n return (\n <>\n <CodeView text={shown} lang={lang} startLine={startLine} />\n {tooLong && (\n <button type=\"button\" className=\"tool-more\" onClick={() => setOpen((v) => !v)}>\n {open ? \"less\" : `+ ${lines.length - maxLines} more lines`}\n </button>\n )}\n </>\n );\n}\n","import { invoke } from \"@tauri-apps/api/core\";\nimport { openPath, openUrl } from \"@tauri-apps/plugin-opener\";\nimport { Check, Copy, ExternalLink, FileText } from \"lucide-react\";\nimport {\n Children,\n cloneElement,\n createContext,\n isValidElement,\n memo,\n type ReactNode,\n useContext,\n useState,\n} from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport rehypeKatex from \"rehype-katex\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport { CodeView } from \"./CodeView\";\nimport { t, useLang } from \"./i18n\";\n\nasync function openWithEditor(\n editor: string | undefined,\n abs: string,\n line?: number,\n): Promise<void> {\n if (editor && editor.trim()) {\n await invoke(\"open_in_editor\", { command: editor, path: abs, line: line ?? null });\n return;\n }\n await openPath(abs);\n}\n\ntype WorkspaceCtx = { dir?: string; editor?: string };\nconst WorkspaceContext = createContext<WorkspaceCtx>({});\nexport const WorkspaceProvider = WorkspaceContext.Provider;\n\nfunction resolveAgainstWorkspace(rel: string, ws: string | undefined): string {\n if (!ws) return rel;\n if (/^[a-zA-Z]:[\\\\/]/.test(rel) || rel.startsWith(\"/\")) return rel;\n const sep = ws.includes(\"\\\\\") ? \"\\\\\" : \"/\";\n const trimmed = ws.replace(/[\\\\/]$/, \"\");\n return `${trimmed}${sep}${rel.replace(/^\\.[\\\\/]/, \"\")}`;\n}\n\nconst KNOWN_EXTS =\n \"ts|tsx|mts|cts|js|jsx|mjs|cjs|py|pyi|rs|go|json|jsonc|md|mdx|css|scss|less|html|htm|xml|svg|yaml|yml|toml|sh|bash|zsh|fish|sql|rb|java|kt|swift|c|cpp|cc|cxx|h|hpp|hxx|cs|php|lua|dart|ex|exs|erl|hs|clj|cljs|zig|vue|svelte|graphql|gql|proto\";\n// No lookbehind here — Tauri's WKWebView on macOS Monterey (Safari < 16.4)\n// can't parse `(?<=...)` and the whole bundle fails to load with an\n// \"invalid group specifier name\" error. Capture the leading char as\n// group 1 instead and let splitFilePaths skip past it. Issue #1209.\nconst FILE_PATH_RE = new RegExp(\n `(^|[\\\\s\\`'\"(\\\\[])((?:[\\\\w.-]+\\\\/)+[\\\\w.-]+\\\\.(?:${KNOWN_EXTS}))(?::(\\\\d+(?:-\\\\d+)?))?(?=[\\\\s.,;!?\\\\]\\\\)'\"\\`]|$)`,\n \"g\",\n);\n\nfunction FilePill({ path, line }: { path: string; line?: string }) {\n useLang();\n const ctx = useContext(WorkspaceContext);\n const [done, setDone] = useState<\"open\" | \"copy\" | null>(null);\n const display = line ? `${path}:${line}` : path;\n const openInEditor = async () => {\n try {\n const abs = resolveAgainstWorkspace(path, ctx.dir);\n const lineNum = line ? Number.parseInt(line.split(\"-\")[0] ?? line, 10) : undefined;\n await openWithEditor(ctx.editor, abs, Number.isFinite(lineNum) ? lineNum : undefined);\n setDone(\"open\");\n setTimeout(() => setDone(null), 1200);\n } catch {\n try {\n await navigator.clipboard.writeText(display);\n setDone(\"copy\");\n setTimeout(() => setDone(null), 1200);\n } catch {\n /* ignore */\n }\n }\n };\n const copyOnly = async (e: React.MouseEvent) => {\n e.stopPropagation();\n try {\n await navigator.clipboard.writeText(display);\n setDone(\"copy\");\n setTimeout(() => setDone(null), 1200);\n } catch {\n /* ignore */\n }\n };\n return (\n <span\n className={`file-pill ${done ? \"done\" : \"\"}`}\n role=\"button\"\n tabIndex={0}\n onClick={openInEditor}\n onContextMenu={(e) => {\n e.preventDefault();\n void copyOnly(e);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n void openInEditor();\n }\n }}\n title={t(\"markdown.filePillTitle\")}\n >\n <FileText size={10} className=\"file-pill-icon\" />\n <span className=\"file-pill-path\">{path}</span>\n {line && <span className=\"file-pill-line\">:{line}</span>}\n {done && <Check size={10} className=\"file-pill-check\" />}\n </span>\n );\n}\n\nfunction splitFilePaths(text: string): ReactNode[] | string {\n FILE_PATH_RE.lastIndex = 0;\n const out: ReactNode[] = [];\n let last = 0;\n let m: RegExpExecArray | null = FILE_PATH_RE.exec(text);\n while (m !== null) {\n const prefix = m[1] ?? \"\";\n const path = m[2]!;\n const line = m[3];\n const pillStart = m.index + prefix.length;\n if (pillStart > last) out.push(text.slice(last, pillStart));\n out.push(<FilePill key={`fp-${pillStart}`} path={path} line={line} />);\n last = pillStart + path.length + (line ? line.length + 1 : 0);\n m = FILE_PATH_RE.exec(text);\n }\n if (out.length === 0) return text;\n if (last < text.length) out.push(text.slice(last));\n return out;\n}\n\ntype AnyProps = { children?: ReactNode } & Record<string, unknown>;\n\nfunction withFilePills(children: ReactNode): ReactNode {\n return Children.map(children, (child) => {\n if (typeof child === \"string\") return splitFilePaths(child);\n if (isValidElement(child)) {\n const props = child.props as AnyProps;\n if (props.children !== undefined) {\n return cloneElement(child, undefined, withFilePills(props.children));\n }\n }\n return child;\n });\n}\n\nexport const Markdown = memo(function Markdown({ source }: { source: string }) {\n return (\n <div className=\"markdown\">\n <ReactMarkdown\n remarkPlugins={[remarkGfm, remarkBreaks, remarkMath]}\n rehypePlugins={[[rehypeKatex, { throwOnError: false }]]}\n components={{\n pre: ({ children }) => {\n // react-markdown v9 nests children unpredictably — flatten all text.\n const rawText = flattenChildText(children).trimEnd();\n return <CodeBlock lang={extractFencedLang(children)} text={rawText} />;\n },\n code: ({ className, children }) => <code className={className}>{children}</code>,\n a: ({ href, children }) => <SafeLink href={href}>{children}</SafeLink>,\n p: ({ children }) => <p>{withFilePills(children)}</p>,\n li: ({ children }) => <li>{withFilePills(children)}</li>,\n td: ({ children }) => <td>{withFilePills(children)}</td>,\n }}\n >\n {source}\n </ReactMarkdown>\n </div>\n );\n});\n\nfunction SafeLink({ href, children }: { href?: string; children: ReactNode }) {\n useLang();\n const ctx = useContext(WorkspaceContext);\n const [done, setDone] = useState(false);\n const isExternal = !!href && /^https?:\\/\\//i.test(href);\n const onClick = async (e: React.MouseEvent) => {\n e.preventDefault();\n if (!href) return;\n if (isExternal) {\n try {\n await openUrl(href);\n } catch {\n window.open(href, \"_blank\", \"noopener,noreferrer\");\n }\n return;\n }\n try {\n const stripped = href.replace(/^file:\\/\\//, \"\");\n const abs = resolveAgainstWorkspace(stripped, ctx.dir);\n await openWithEditor(ctx.editor, abs);\n } catch {\n try {\n await navigator.clipboard.writeText(href);\n setDone(true);\n setTimeout(() => setDone(false), 1200);\n } catch {\n /* ignore */\n }\n }\n };\n return (\n <a\n href={href ?? \"#\"}\n onClick={onClick}\n className={`md-link ${isExternal ? \"external\" : \"local\"} ${done ? \"done\" : \"\"}`}\n title={\n isExternal\n ? t(\"markdown.externalLinkTitle\", { href: href ?? \"\" })\n : t(\"markdown.localLinkTitle\", { href: href ?? \"\" })\n }\n >\n {children}\n {isExternal ? (\n <ExternalLink size={10} className=\"md-link-icon\" />\n ) : done ? (\n <Check size={10} className=\"md-link-icon\" />\n ) : null}\n </a>\n );\n}\n\nexport function extractFencedLang(children: ReactNode): string {\n for (const kid of Children.toArray(children)) {\n if (isValidElement(kid)) {\n const cls = (kid.props as Record<string, unknown>).className;\n if (typeof cls === \"string\") {\n const m = cls.match(/language-([\\w-]+)/);\n if (m) return m[1]!;\n }\n }\n }\n return \"text\";\n}\n\nfunction flattenChildText(node: ReactNode): string {\n if (typeof node === \"string\" || typeof node === \"number\") return String(node);\n if (Array.isArray(node)) return node.map(flattenChildText).join(\"\");\n if (isValidElement(node))\n return flattenChildText((node.props as { children?: ReactNode }).children);\n return \"\";\n}\n\nfunction CodeBlock({ lang, text }: { lang: string; text: string }): ReactNode {\n useLang();\n const [copied, setCopied] = useState(false);\n const onCopy = async () => {\n try {\n await navigator.clipboard.writeText(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 1400);\n } catch {\n /* ignore */\n }\n };\n return (\n <div className=\"codeblock\">\n <div className=\"codeblock-head\">\n <span className=\"codeblock-lang\">{lang}</span>\n <button type=\"button\" className={`copy-btn ${copied ? \"done\" : \"\"}`} onClick={onCopy}>\n {copied ? <Check size={11} /> : <Copy size={11} />}\n {copied ? t(\"markdown.copied\") : t(\"markdown.copy\")}\n </button>\n </div>\n <CodeView text={text} lang={lang} />\n </div>\n );\n}\n","import type { SVGProps } from \"react\";\n\ntype IconProps = SVGProps<SVGSVGElement> & { size?: number };\n\nfunction Ic({ size = 14, children, ...rest }: IconProps & { children: React.ReactNode }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...rest}\n >\n {children}\n </svg>\n );\n}\n\nexport const I = {\n plus: (p: IconProps) => (<Ic {...p}><path d=\"M12 5v14M5 12h14\" /></Ic>),\n search: (p: IconProps) => (<Ic {...p}><circle cx=\"11\" cy=\"11\" r=\"7\" /><path d=\"m20 20-3.5-3.5\" /></Ic>),\n send: (p: IconProps) => (<Ic {...p}><path d=\"M4 12 20 4l-6 16-3-7-7-1Z\" /></Ic>),\n chev: (p: IconProps) => (<Ic {...p}><path d=\"m6 9 6 6 6-6\" /></Ic>),\n chevR: (p: IconProps) => (<Ic {...p}><path d=\"m9 6 6 6-6 6\" /></Ic>),\n check: (p: IconProps) => (<Ic {...p}><path d=\"m5 12 5 5L20 7\" /></Ic>),\n x: (p: IconProps) => (<Ic {...p}><path d=\"M6 6l12 12M18 6 6 18\" /></Ic>),\n terminal: (p: IconProps) => (<Ic {...p}><rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" /><path d=\"m7 9 3 3-3 3M13 15h4\" /></Ic>),\n brain: (p: IconProps) => (\n <Ic {...p}>\n <path d=\"M9 4a3 3 0 0 0-3 3v0a3 3 0 0 0-2 5 3 3 0 0 0 2 5 3 3 0 0 0 3 3h0a3 3 0 0 0 3-3V4\" />\n <path d=\"M15 4a3 3 0 0 1 3 3 3 3 0 0 1 2 5 3 3 0 0 1-2 5 3 3 0 0 1-3 3\" />\n </Ic>\n ),\n list: (p: IconProps) => (<Ic {...p}><path d=\"M4 6h2M4 12h2M4 18h2M9 6h11M9 12h11M9 18h11\" /></Ic>),\n diff: (p: IconProps) => (<Ic {...p}><path d=\"M7 4v11a3 3 0 0 0 3 3h2M17 20V9a3 3 0 0 0-3-3h-2\" /><circle cx=\"7\" cy=\"20\" r=\"2\" /><circle cx=\"17\" cy=\"4\" r=\"2\" /></Ic>),\n globe: (p: IconProps) => (<Ic {...p}><circle cx=\"12\" cy=\"12\" r=\"9\" /><path d=\"M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18\" /></Ic>),\n link: (p: IconProps) => (<Ic {...p}><path d=\"M10 14a4 4 0 0 1 0-6l3-3a4 4 0 0 1 6 6l-2 2\" /><path d=\"M14 10a4 4 0 0 1 0 6l-3 3a4 4 0 0 1-6-6l2-2\" /></Ic>),\n wrench: (p: IconProps) => (<Ic {...p}><path d=\"M14 7a4 4 0 1 0 4 4l3 3-3 3-3-3a4 4 0 0 1-4-4l-3-3-3 3 3 3a4 4 0 0 0 6 0\" /></Ic>),\n bot: (p: IconProps) => (<Ic {...p}><rect x=\"4\" y=\"7\" width=\"16\" height=\"12\" rx=\"3\" /><path d=\"M12 3v4M8 12h.01M16 12h.01M9 16h6\" /></Ic>),\n archive: (p: IconProps) => (<Ic {...p}><rect x=\"3\" y=\"3\" width=\"18\" height=\"5\" rx=\"1\" /><path d=\"M5 8v11a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V8M10 12h4\" /></Ic>),\n bookmark: (p: IconProps) => (<Ic {...p}><path d=\"M6 3h12v18l-6-4-6 4Z\" /></Ic>),\n warning: (p: IconProps) => (<Ic {...p}><path d=\"M12 3 2 21h20Z\" /><path d=\"M12 10v5M12 18h.01\" /></Ic>),\n zap: (p: IconProps) => (<Ic {...p}><path d=\"M13 3 4 14h7l-1 7 9-11h-7Z\" /></Ic>),\n database: (p: IconProps) => (<Ic {...p}><ellipse cx=\"12\" cy=\"5\" rx=\"8\" ry=\"3\" /><path d=\"M4 5v6c0 1.7 3.6 3 8 3s8-1.3 8-3V5M4 11v6c0 1.7 3.6 3 8 3s8-1.3 8-3v-6\" /></Ic>),\n cpu: (p: IconProps) => (<Ic {...p}><rect x=\"5\" y=\"5\" width=\"14\" height=\"14\" rx=\"2\" /><rect x=\"9\" y=\"9\" width=\"6\" height=\"6\" /><path d=\"M9 2v3M15 2v3M9 19v3M15 19v3M2 9h3M2 15h3M19 9h3M19 15h3\" /></Ic>),\n coin: (p: IconProps) => (<Ic {...p}><circle cx=\"12\" cy=\"12\" r=\"9\" /><path d=\"M12 7v10M9 10h4a2 2 0 0 1 0 4H9\" /></Ic>),\n file: (p: IconProps) => (<Ic {...p}><path d=\"M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9Z\" /><path d=\"M14 3v6h6\" /></Ic>),\n folder: (p: IconProps) => (<Ic {...p}><path d=\"M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z\" /></Ic>),\n image: (p: IconProps) => (<Ic {...p}><rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" /><circle cx=\"9\" cy=\"10\" r=\"2\" /><path d=\"m3 18 5-5 4 4 3-3 6 6\" /></Ic>),\n paperclip: (p: IconProps) => (<Ic {...p}><path d=\"M21 12 12 21a5 5 0 0 1-7-7L14 5a3 3 0 0 1 4 4l-9 9a1 1 0 0 1-2-2l8-8\" /></Ic>),\n mic: (p: IconProps) => (<Ic {...p}><rect x=\"9\" y=\"3\" width=\"6\" height=\"12\" rx=\"3\" /><path d=\"M5 11a7 7 0 0 0 14 0M12 18v3M9 21h6\" /></Ic>),\n sun: (p: IconProps) => (<Ic {...p}><circle cx=\"12\" cy=\"12\" r=\"4\" /><path d=\"M12 2v2M12 20v2M2 12h2M20 12h2M5 5l1.5 1.5M17.5 17.5 19 19M5 19l1.5-1.5M17.5 6.5 19 5\" /></Ic>),\n moon: (p: IconProps) => (<Ic {...p}><path d=\"M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8Z\" /></Ic>),\n panel_l: (p: IconProps) => (<Ic {...p}><rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" /><path d=\"M9 4v16\" /></Ic>),\n panel_r: (p: IconProps) => (<Ic {...p}><rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" /><path d=\"M15 4v16\" /></Ic>),\n cog: (p: IconProps) => (<Ic {...p}><path d=\"M12 3.6 19.2 7.8v8.4L12 20.4 4.8 16.2V7.8Z\" /><circle cx=\"12\" cy=\"12\" r=\"3.7\" /></Ic>),\n stop: (p: IconProps) => (<Ic {...p}><rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\" /></Ic>),\n play: (p: IconProps) => (<Ic {...p}><path d=\"M7 5v14l12-7Z\" /></Ic>),\n more: (p: IconProps) => (<Ic {...p}><circle cx=\"6\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" /><circle cx=\"12\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" /><circle cx=\"18\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" /></Ic>),\n pin: (p: IconProps) => (<Ic {...p}><path d=\"M15 3 9 9l-4 1 9 9 1-4 6-6ZM4 20l5-5\" /></Ic>),\n rotate: (p: IconProps) => (<Ic {...p}><path d=\"M3 12a9 9 0 1 0 3-6.7L3 8\" /><path d=\"M3 3v5h5\" /></Ic>),\n branch: (p: IconProps) => (<Ic {...p}><circle cx=\"6\" cy=\"4\" r=\"2\" /><circle cx=\"6\" cy=\"20\" r=\"2\" /><circle cx=\"18\" cy=\"8\" r=\"2\" /><path d=\"M6 6v12M6 14a6 6 0 0 0 6-6h4\" /></Ic>),\n at: (p: IconProps) => (<Ic {...p}><circle cx=\"12\" cy=\"12\" r=\"4\" /><path d=\"M16 8v6a3 3 0 0 0 5-2 9 9 0 1 0-4 7\" /></Ic>),\n slash: (p: IconProps) => (<Ic {...p}><path d=\"M16 4 8 20\" /></Ic>),\n layers: (p: IconProps) => (<Ic {...p}><path d=\"m12 3 9 5-9 5-9-5Z\" /><path d=\"m3 13 9 5 9-5M3 18l9 5 9-5\" /></Ic>),\n download: (p: IconProps) => (<Ic {...p}><path d=\"M12 4v12M6 12l6 6 6-6M4 20h16\" /></Ic>),\n upload: (p: IconProps) => (<Ic {...p}><path d=\"M12 20V8M6 12l6-6 6 6M4 4h16\" /></Ic>),\n history: (p: IconProps) => (<Ic {...p}><path d=\"M3 12a9 9 0 1 0 3-6.7L3 8M12 7v5l3 2\" /></Ic>),\n shield: (p: IconProps) => (<Ic {...p}><path d=\"M12 3 4 6v6c0 5 3.5 8 8 9 4.5-1 8-4 8-9V6Z\" /><path d=\"m9 12 2 2 4-4\" /></Ic>),\n warn: (p: IconProps) => (<Ic {...p}><path d=\"M12 3 2 21h20Z\" /><path d=\"M12 10v5M12 18h.01\" /></Ic>),\n help: (p: IconProps) => (<Ic {...p}><circle cx=\"12\" cy=\"12\" r=\"9\" /><path d=\"M9.5 9a2.5 2.5 0 0 1 5 0c0 1.5-2.5 2-2.5 4M12 17h.01\" /></Ic>),\n refresh: (p: IconProps) => (<Ic {...p}><path d=\"M3 12a9 9 0 0 1 15-6.7L21 8M21 4v4h-4M21 12a9 9 0 0 1-15 6.7L3 16M3 20v-4h4\" /></Ic>),\n copy: (p: IconProps) => (<Ic {...p}><rect x=\"8\" y=\"8\" width=\"12\" height=\"12\" rx=\"2\" /><path d=\"M4 16V6a2 2 0 0 1 2-2h10\" /></Ic>),\n};\n\nexport type IconKey = keyof typeof I;\n","export const THEME = {\n DARK: \"dark\",\n LIGHT: \"light\",\n} as const;\n\nexport type Theme = (typeof THEME)[keyof typeof THEME];\n\nexport function isTheme(value: unknown): value is Theme {\n return value === THEME.DARK || value === THEME.LIGHT;\n}\n\nexport const THEME_STYLE = {\n GRAPHITE: \"graphite\",\n SANDSTONE: \"sandstone\",\n PORCELAIN: \"porcelain\",\n MIDNIGHT: \"midnight\",\n} as const;\n\nexport type ThemeStyle = (typeof THEME_STYLE)[keyof typeof THEME_STYLE];\n\nexport const DEFAULT_THEME_STYLE: Record<Theme, ThemeStyle> = {\n dark: THEME_STYLE.GRAPHITE,\n light: THEME_STYLE.SANDSTONE,\n};\n\nexport const THEME_STYLE_THEME: Record<ThemeStyle, Theme> = {\n graphite: THEME.DARK,\n sandstone: THEME.LIGHT,\n porcelain: THEME.LIGHT,\n midnight: THEME.DARK,\n};\n\nexport const THEME_STYLES = [\n THEME_STYLE.GRAPHITE,\n THEME_STYLE.SANDSTONE,\n THEME_STYLE.PORCELAIN,\n THEME_STYLE.MIDNIGHT,\n] as const;\n\nexport function isThemeStyle(value: unknown): value is ThemeStyle {\n return (\n value === THEME_STYLE.GRAPHITE ||\n value === THEME_STYLE.SANDSTONE ||\n value === THEME_STYLE.PORCELAIN ||\n value === THEME_STYLE.MIDNIGHT\n );\n}\n\nexport function themeForStyle(style: ThemeStyle): Theme {\n return THEME_STYLE_THEME[style];\n}\n\nexport function defaultStyleForTheme(theme: Theme): ThemeStyle {\n return DEFAULT_THEME_STYLE[theme];\n}\n\nexport const FONT_SCALE = {\n SMALL: \"small\",\n MEDIUM: \"medium\",\n LARGE: \"large\",\n} as const;\n\nexport type FontScale = (typeof FONT_SCALE)[keyof typeof FONT_SCALE];\n\nexport function isFontScale(value: unknown): value is FontScale {\n return value === FONT_SCALE.SMALL || value === FONT_SCALE.MEDIUM || value === FONT_SCALE.LARGE;\n}\n\nexport const FONT_SCALE_ZOOM: Record<FontScale, number> = {\n small: 0.875,\n medium: 1.0,\n large: 1.125,\n};\n\nexport const FONT_FAMILY = {\n SANS: \"sans\",\n SYSTEM: \"system\",\n SERIF: \"serif\",\n} as const;\n\nexport type FontFamily = (typeof FONT_FAMILY)[keyof typeof FONT_FAMILY];\n\nexport function isFontFamily(value: unknown): value is FontFamily {\n return value === FONT_FAMILY.SANS || value === FONT_FAMILY.SYSTEM || value === FONT_FAMILY.SERIF;\n}\n\nexport const FONT_FAMILY_STACK: Record<FontFamily, string> = {\n sans: '\"Geist\", system-ui, sans-serif',\n system: '-apple-system, system-ui, \"Segoe UI\", Roboto, sans-serif',\n serif: 'Georgia, \"Times New Roman\", serif',\n};\n","const SESSION_PARAM = \"session\";\n\nexport function readSessionFromUrl(): string | null {\n if (typeof window === \"undefined\") return null;\n const raw = new URLSearchParams(window.location.search).get(SESSION_PARAM);\n if (!raw) return null;\n const trimmed = raw.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nexport function writeSessionToUrl(name: string | null): void {\n if (typeof window === \"undefined\") return;\n const url = new URL(window.location.href);\n if (name && name.trim().length > 0) {\n url.searchParams.set(SESSION_PARAM, name);\n } else {\n url.searchParams.delete(SESSION_PARAM);\n }\n if (url.href === window.location.href) return;\n window.history.replaceState(null, \"\", url.href);\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { I } from \"../icons\";\nimport { t, useLang } from \"../i18n\";\n\nexport function fmtElapsed(ms: number): string {\n const s = ms / 1000;\n return s < 10 ? `${s.toFixed(1)}s` : `${Math.floor(s)}s`;\n}\n\nexport function useElapsed(active: boolean, startAt?: number): number {\n const [ms, setMs] = useState(0);\n const start = useRef<number | null>(null);\n useEffect(() => {\n if (!active) {\n setMs(0);\n start.current = null;\n return;\n }\n start.current = startAt ?? performance.now();\n const id = setInterval(() => {\n if (start.current !== null) setMs(performance.now() - start.current);\n }, 80);\n return () => clearInterval(id);\n }, [active, startAt]);\n return ms;\n}\n\nexport function ThinkingPill({\n phase = \"thinking\",\n label,\n elapsedMs,\n}: {\n phase?: \"queued\" | \"thinking\" | \"tool\";\n label: string;\n elapsedMs: number;\n}) {\n const color =\n phase === \"queued\"\n ? \"var(--muted)\"\n : phase === \"tool\"\n ? \"var(--warning)\"\n : \"var(--accent)\";\n return (\n <div className=\"thinking\">\n <span className=\"dots\" style={{ color }}>\n <span style={{ background: color }} />\n <span style={{ background: color }} />\n <span style={{ background: color }} />\n </span>\n <span className=\"label\">\n <span className=\"sh\">{label}</span>\n </span>\n <span className=\"timer\">{fmtElapsed(elapsedMs)}</span>\n </div>\n );\n}\n\nexport function LiveReasoning({ lines }: { lines: string[] }) {\n useLang();\n return (\n <div className=\"live-reason\">\n <div className=\"head\">\n <span className=\"dot\" /> {t(\"live.reasoning\")}\n </div>\n {lines.map((line, i) => (\n <div key={i}>\n {line}\n {i === lines.length - 1 ? <span className=\"stream-caret\" /> : null}\n </div>\n ))}\n </div>\n );\n}\n\nexport function ToolRunningCard({\n kind = \"tool\",\n name,\n elapsedMs,\n logLines,\n}: {\n kind?: \"shell\" | \"fetch\" | \"search\" | \"tool\";\n name: string;\n elapsedMs: number;\n logLines?: { text: string; tone?: \"ok\" | \"dim\" }[];\n}) {\n useLang();\n const ic =\n kind === \"shell\" ? <I.terminal size={12} /> : kind === \"fetch\" ? <I.globe size={12} /> : kind === \"search\" ? <I.search size={12} /> : <I.wrench size={12} />;\n return (\n <div className=\"skel-card\">\n <div className=\"h\">\n <span className=\"ico\">{ic}</span>\n <span className=\"kind\">{kind}</span>\n <span style={{ color: \"var(--fg)\", fontWeight: 500 }}>{name}</span>\n <span className=\"grow\" />\n <span className=\"spin-meta\" role=\"img\" aria-label={t(\"live.running\")} title={t(\"live.running\")} />\n <span className=\"timer\">{fmtElapsed(elapsedMs)}</span>\n </div>\n {logLines && logLines.length > 0 ? (\n <div className=\"live-log\">\n {logLines.map((ln, i) => (\n <div\n key={i}\n className={`line ${ln.tone ?? \"\"}`}\n style={{ animationDelay: `${i * 0.25}s` }}\n >\n {ln.text}\n </div>\n ))}\n </div>\n ) : (\n <div className=\"body\">\n <div className=\"skel-line w-90\" />\n <div className=\"skel-line w-70\" />\n <div className=\"skel-line w-60\" />\n </div>\n )}\n </div>\n );\n}\n\nexport function PendingUserMsg({ text, elapsedMs }: { text: string; elapsedMs: number }) {\n useLang();\n return (\n <div className=\"msg user\">\n <div className=\"avatar\">YOU</div>\n <div className=\"body\">\n <div className=\"who\">\n <span className=\"name\">{t(\"live.you\")}</span>\n <span className=\"time\">\n {t(\"live.secondsAgo\", { seconds: (elapsedMs / 1000).toFixed(1) })}\n </span>\n </div>\n <div className=\"msg-text user-pending\">{text}</div>\n <div className=\"user-status\">\n <span className=\"spin\" />\n <span>{t(\"live.deliveredWaiting\")}</span>\n </div>\n </div>\n </div>\n );\n}\n","import {\n type ChangeEvent,\n type KeyboardEvent,\n type RefObject,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type React from \"react\";\nimport { open as openFileDialog } from \"@tauri-apps/plugin-dialog\";\nimport { t, type TKey } from \"../i18n\";\nimport { I } from \"../icons\";\nimport { fmtElapsed } from \"./live\";\nimport { Shortcut } from \"./shortcut\";\n\nexport type ReasoningEffort = \"low\" | \"medium\" | \"high\" | \"max\";\nexport type EditMode = \"review\" | \"auto\" | \"yolo\";\n\ntype ModeEntry = { k: EditMode; label: TKey; icon: React.ReactNode; hint: TKey };\n\nconst EFFORTS: readonly ReasoningEffort[] = [\"low\", \"medium\", \"high\", \"max\"];\n\nconst MODE_INFO: ModeEntry[] = [\n { k: \"review\", label: \"editMode.review\", icon: <I.shield size={11} />, hint: \"editMode.reviewHint\" },\n { k: \"auto\", label: \"editMode.auto\", icon: <I.zap size={11} />, hint: \"editMode.autoHint\" },\n { k: \"yolo\", label: \"editMode.yolo\", icon: <I.warn size={11} />, hint: \"editMode.yoloHint\" },\n];\n\nexport function ModeSwitch({\n mode,\n onChange,\n}: {\n mode: EditMode;\n onChange: (m: EditMode) => void;\n}) {\n return (\n <div className=\"mode-switch\" data-mode={mode}>\n {MODE_INFO.map((m) => (\n <button\n key={m.k}\n type=\"button\"\n className=\"ms-seg\"\n data-on={mode === m.k}\n data-k={m.k}\n onClick={() => onChange(m.k)}\n title={t(m.hint)}\n >\n {m.icon}\n <span>{t(m.label)}</span>\n </button>\n ))}\n </div>\n );\n}\n\nexport type SlashCmd = {\n cmd: string;\n desc: string;\n run: () => void;\n kb?: string;\n insertOnly?: boolean;\n};\nexport type MentionItem = {\n name: string;\n kind: \"file\" | \"dir\" | \"url\" | \"agent\" | \"clip\";\n desc?: string;\n};\n\nexport type Chip =\n | { kind: \"at\"; label: string }\n | { kind: \"slash\"; label: string };\n\ntype Popup =\n | { kind: \"slash\"; query: string }\n | { kind: \"at\"; query: string; nonce: number }\n | null;\n\nfunction slashIcon(cmd: string) {\n const m: Record<string, React.ReactNode> = {\n \"/clear\": <I.x size={12} />,\n \"/new\": <I.plus size={12} />,\n \"/abort\": <I.stop size={12} />,\n \"/copy\": <I.layers size={12} />,\n \"/export\": <I.download size={12} />,\n \"/model\": <I.cpu size={12} />,\n \"/theme\": <I.sun size={12} />,\n \"/lang\": <I.globe size={12} />,\n };\n return m[cmd] || <I.slash size={12} />;\n}\n\n/** Parent dir of the current @ query, with trailing slash. `null` = no parent to show (at workspace root). */\nfunction parentOfAtQuery(query: string): string | null {\n const normalized = query.replace(/\\\\/g, \"/\");\n const trailingSlash = normalized.endsWith(\"/\");\n const lastSlash = normalized.lastIndexOf(\"/\");\n if (lastSlash < 0) return null;\n const dirContext = trailingSlash ? normalized.slice(0, -1) : normalized.slice(0, lastSlash);\n if (!dirContext) return null;\n const parentIdx = dirContext.lastIndexOf(\"/\");\n return parentIdx >= 0 ? `${dirContext.slice(0, parentIdx)}/` : \"\";\n}\n\nfunction atIcon(k: MentionItem[\"kind\"]) {\n if (k === \"file\") return <I.file size={12} />;\n if (k === \"dir\") return <I.folder size={12} />;\n if (k === \"url\") return <I.globe size={12} />;\n if (k === \"agent\") return <I.bot size={12} />;\n if (k === \"clip\") return <I.layers size={12} />;\n return <I.at size={12} />;\n}\n\nexport function Composer({\n draft,\n setDraft,\n onSend,\n onAbort,\n disabled,\n busy,\n busyLabel,\n busyElapsedMs,\n modelLabel,\n reasoningEffort,\n onModelChange,\n onEffortChange,\n editMode,\n onEditModeChange,\n textareaRef,\n slashCommands,\n onMentionQuery,\n onMentionPreview,\n onMentionPicked,\n mentionResults,\n workspaceDir,\n queuedSends,\n onQueueWhileBusy,\n onDequeueSend,\n}: {\n draft: string;\n setDraft: (s: string) => void;\n onSend: () => void;\n onAbort: () => void;\n disabled?: boolean;\n busy?: boolean;\n /** Replaces the hint-row left side while the agent is running — typically \"Reasoning\" or \"Skill · <name>\". */\n busyLabel?: string;\n busyElapsedMs?: number;\n modelLabel: string;\n reasoningEffort: ReasoningEffort;\n onModelChange: (model: string) => void;\n onEffortChange: (effort: ReasoningEffort) => void;\n editMode: EditMode;\n onEditModeChange: (mode: EditMode) => void;\n textareaRef: RefObject<HTMLTextAreaElement | null>;\n slashCommands: SlashCmd[];\n onMentionQuery?: (q: string, nonce: number) => void;\n onMentionPreview?: (path: string, nonce: number) => void;\n onMentionPicked?: (path: string) => void;\n mentionResults?: { nonce: number; query: string; results: string[] } | null;\n workspaceDir?: string;\n /** Messages typed while busy=true; rendered as removable chips above the textarea and auto-drained FIFO on turn-complete. */\n queuedSends?: string[];\n /** Called when the user presses Enter while busy with a non-empty draft. Owns clearing the draft. */\n onQueueWhileBusy?: (text: string) => void;\n onDequeueSend?: (index: number) => void;\n}) {\n const [chips, setChips] = useState<Chip[]>([]);\n const [popup, setPopup] = useState<Popup>(null);\n const [activeIdx, setActiveIdx] = useState(0);\n const [modelMenuOpen, setModelMenuOpen] = useState(false);\n const nonceRef = useRef(0);\n const modelWrapRef = useRef<HTMLDivElement>(null);\n // macOS Chinese IME fires compositionend before the confirm keydown.\n const composingRef = useRef(false);\n const compositionEndedAtRef = useRef(0);\n\n // Programmatic draft transitions to \"/\" (e.g. /help suggestion in EmptyState, #929) must open the slash popup, since handleChange only fires on actual user input.\n const prevDraftRef = useRef(draft);\n useEffect(() => {\n const prev = prevDraftRef.current;\n prevDraftRef.current = draft;\n if (draft === \"/\" && prev !== \"/\") {\n setPopup({ kind: \"slash\", query: \"\" });\n }\n }, [draft]);\n\n useEffect(() => {\n if (!modelMenuOpen) return;\n const onDown = (e: MouseEvent) => {\n if (\n modelWrapRef.current &&\n !modelWrapRef.current.contains(e.target as Node)\n ) {\n setModelMenuOpen(false);\n }\n };\n window.addEventListener(\"mousedown\", onDown);\n return () => window.removeEventListener(\"mousedown\", onDown);\n }, [modelMenuOpen]);\n\n const attachFile = async (filter?: \"image\") => {\n try {\n const picked = await openFileDialog({\n multiple: false,\n directory: false,\n defaultPath: workspaceDir,\n filters:\n filter === \"image\"\n ? [\n {\n name: t(\"composer.imageFilterName\"),\n extensions: [\"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"svg\"],\n },\n ]\n : undefined,\n });\n if (typeof picked !== \"string\" || !picked) return;\n const rel =\n workspaceDir && picked.startsWith(workspaceDir)\n ? picked.slice(workspaceDir.length).replace(/^[\\\\/]+/, \"\")\n : picked;\n setDraft(draft ? `${draft.replace(/\\s+$/, \"\")} @${rel} ` : `@${rel} `);\n setChips((c) => [...c, { kind: \"at\", label: rel }]);\n onMentionPicked?.(rel);\n textareaRef.current?.focus();\n } catch (err) {\n console.error(\"attach failed\", err);\n }\n };\n\n const slashItems = useMemo(() => {\n if (!popup || popup.kind !== \"slash\") return [];\n const q = popup.query.toLowerCase();\n if (!q) return slashCommands;\n return slashCommands.filter((c) => c.cmd.toLowerCase().includes(q));\n }, [popup, slashCommands]);\n\n const atItems = useMemo<MentionItem[]>(() => {\n if (!popup || popup.kind !== \"at\") return [];\n if (!mentionResults || mentionResults.nonce !== popup.nonce) return [];\n const base: MentionItem[] = mentionResults.results.map((path) => ({\n name: path,\n kind: path.endsWith(\"/\") || path.endsWith(\"\\\\\") ? \"dir\" : \"file\",\n desc: path,\n }));\n // \"../\" entry (#1019): one level up whenever the @ query is inside a subdir.\n const parent = parentOfAtQuery(popup.query);\n if (parent !== null) {\n base.unshift({\n name: \"..\",\n kind: \"dir\",\n desc: parent ? `↑ ${parent}` : `↑ ${t(\"composer.workspaceRoot\")}`,\n });\n }\n return base;\n }, [popup, mentionResults]);\n\n const items =\n popup?.kind === \"slash\" ? slashItems : popup?.kind === \"at\" ? atItems : [];\n\n useEffect(() => {\n setActiveIdx(0);\n }, [items.length, popup?.kind]);\n\n useEffect(() => {\n if (!popup || popup.kind !== \"at\" || !onMentionQuery) return;\n onMentionQuery(popup.query, popup.nonce);\n }, [popup, onMentionQuery]);\n\n const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {\n const v = e.target.value;\n setDraft(v);\n const trail = v.match(/(^|\\s)([/@])([^\\s]*)$/);\n if (trail) {\n const sigil = trail[2];\n const query = trail[3] ?? \"\";\n if (sigil === \"/\") {\n setPopup({ kind: \"slash\", query });\n } else {\n const nonce = ++nonceRef.current;\n setPopup({ kind: \"at\", query, nonce });\n }\n } else if (popup) {\n setPopup(null);\n }\n };\n\n const dismiss = () => setPopup(null);\n\n const pickItem = (idx: number) => {\n const it = items[idx];\n if (!it || !popup) return;\n if (popup.kind === \"slash\") {\n const cmd = (it as SlashCmd).cmd;\n const insertOnly = (it as SlashCmd).insertOnly === true;\n if (insertOnly) {\n const next = draft.replace(/[/@][^\\s]*$/, \"\").trimEnd();\n setDraft(next ? `${next} ${cmd} ` : `${cmd} `);\n setChips((c) => [...c, { kind: \"slash\", label: cmd.replace(/^\\//, \"\") }]);\n } else {\n const next = draft.replace(/[/@][^\\s]*$/, \"\").trimEnd();\n setDraft(next);\n setChips((c) => [...c, { kind: \"slash\", label: cmd.replace(/^\\//, \"\") }]);\n (it as SlashCmd).run();\n }\n } else {\n const mention = it as MentionItem;\n if (mention.name === \"..\") {\n const parent = parentOfAtQuery(popup.query) ?? \"\";\n const next = draft.replace(/[@][^\\s]*$/, `@${parent}`);\n setDraft(next);\n const nonce = ++nonceRef.current;\n setPopup({ kind: \"at\", query: parent, nonce });\n textareaRef.current?.focus();\n return;\n }\n const next = draft.replace(/[/@][^\\s]*$/, \"\").trimEnd();\n setDraft(next ? `${next} @${mention.name} ` : `@${mention.name} `);\n setChips((c) => [...c, { kind: \"at\", label: mention.name }]);\n onMentionPicked?.(mention.name);\n }\n setPopup(null);\n textareaRef.current?.focus();\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (popup) {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setActiveIdx((i) => (items.length ? (i + 1) % items.length : 0));\n return;\n }\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setActiveIdx((i) =>\n items.length ? (i - 1 + items.length) % items.length : 0,\n );\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n dismiss();\n return;\n }\n if (e.key === \"Tab\" && popup.kind === \"at\" && items.length > 0) {\n // Tab on a directory enters it — replaces `@src` with `@src/`\n // and re-queries so the popup shows that directory's children.\n // `..` is the synthetic parent-dir entry (#1019); same shape\n // but rewrites to the parent path.\n const it = items[activeIdx];\n if (it && (it as MentionItem).kind === \"dir\") {\n e.preventDefault();\n const mention = it as MentionItem;\n if (mention.name === \"..\") {\n const parent = parentOfAtQuery(popup.query) ?? \"\";\n const next = draft.replace(/[@][^\\s]*$/, `@${parent}`);\n setDraft(next);\n const nonce = ++nonceRef.current;\n setPopup({ kind: \"at\", query: parent, nonce });\n return;\n }\n const dirPath = mention.name.replace(/\\/+$/, \"\");\n const next = draft.replace(/[@][^\\s]*$/, `@${dirPath}/`);\n setDraft(next);\n const nonce = ++nonceRef.current;\n setPopup({ kind: \"at\", query: `${dirPath}/`, nonce });\n return;\n }\n }\n if (e.key === \"Enter\") {\n if (items.length > 0) {\n e.preventDefault();\n pickItem(activeIdx);\n return;\n }\n dismiss();\n }\n }\n if (composingRef.current || Date.now() - compositionEndedAtRef.current < 50) return;\n if (e.key === \"Enter\" && !e.shiftKey && !popup) {\n e.preventDefault();\n if (busy) {\n const text = draft.trim();\n if (text && onQueueWhileBusy) {\n onQueueWhileBusy(text);\n setChips([]);\n }\n } else if (!disabled && draft.trim()) {\n onSend();\n setChips([]);\n }\n }\n };\n\n return (\n <div className=\"composer-wrap\">\n <div className=\"composer-inner\">\n {queuedSends && queuedSends.length > 0 ? (\n <div className=\"composer-queued\">\n <span className=\"composer-queued-label\">\n {t(\"composer.queueCount\", { count: queuedSends.length })}\n </span>\n {queuedSends.map((text, i) => (\n <span key={i} className=\"composer-queue-chip\" title={text}>\n <span className=\"text\">{text}</span>\n {onDequeueSend ? (\n <span className=\"x\" onClick={() => onDequeueSend(i)}>\n <I.x size={10} />\n </span>\n ) : null}\n </span>\n ))}\n </div>\n ) : null}\n\n <div className=\"hint-row\">\n {busy && busyLabel ? (\n <>\n <span className=\"composer-busy-status\">\n <span className=\"composer-busy-pip\" />\n <span className=\"composer-busy-label\">{busyLabel}</span>\n <span className=\"composer-busy-time\">\n {fmtElapsed(busyElapsedMs ?? 0)}\n </span>\n </span>\n <span className=\"grow\" />\n <ModeSwitch mode={editMode} onChange={onEditModeChange} />\n <span className=\"hint-sep\" />\n <span>\n <Shortcut keys={[\"enter\"]} /> {t(\"composer.queue\")} · {\" \"}\n <Shortcut keys={[\"esc\"]} /> {t(\"composer.interrupt\")}\n </span>\n </>\n ) : (\n <>\n <span>\n <Shortcut keys={[\"/\"]} /> {t(\"composer.commands\")} · {\" \"}\n <Shortcut keys={[\"@\"]} /> {t(\"composer.mentionFiles\")}\n · <Shortcut keys={[\"mod\", \"K\"]} /> {t(\"composer.commandPalette\")}\n </span>\n <span className=\"grow\" />\n <ModeSwitch mode={editMode} onChange={onEditModeChange} />\n <span className=\"hint-sep\" />\n <span>\n <Shortcut keys={[\"enter\"]} /> {t(\"composer.send\")} {\" \"}\n <Shortcut keys={[\"shift\", \"enter\"]} /> {t(\"composer.newline\")}\n </span>\n </>\n )}\n </div>\n\n <div className=\"composer\">\n {chips.length > 0 ? (\n <div className=\"composer-tags\">\n {chips.map((c, i) => (\n <span key={i} className={`chip ${c.kind}`}>\n {c.kind === \"slash\" ? (\n <I.slash size={11} />\n ) : (\n <I.at size={11} />\n )}\n <span>{c.label}</span>\n <span\n className=\"x\"\n onClick={() =>\n setChips((cs) => cs.filter((_, j) => j !== i))\n }\n >\n <I.x size={10} />\n </span>\n </span>\n ))}\n </div>\n ) : null}\n\n <textarea\n ref={textareaRef}\n value={draft}\n placeholder={t(\"composer.placeholder\")}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onCompositionStart={() => {\n composingRef.current = true;\n }}\n onCompositionEnd={() => {\n composingRef.current = false;\n compositionEndedAtRef.current = Date.now();\n }}\n rows={2}\n disabled={disabled}\n />\n\n <div className=\"composer-foot\">\n <button\n type=\"button\"\n className=\"cf-btn\"\n title={t(\"composer.insertFile\")}\n onClick={() => void attachFile()}\n >\n <span className=\"ico\">\n <I.paperclip size={14} />\n </span>\n </button>\n <button\n type=\"button\"\n className=\"cf-btn\"\n title={t(\"composer.insertImage\")}\n onClick={() => void attachFile(\"image\")}\n >\n <span className=\"ico\">\n <I.image size={14} />\n </span>\n </button>\n <button\n type=\"button\"\n className=\"cf-btn\"\n onClick={() => setPopup({ kind: \"slash\", query: \"\" })}\n >\n <span className=\"ico\">\n <I.slash size={14} />\n </span>\n <span className=\"label\">{t(\"composer.commandsLabel\")}</span>\n </button>\n <button\n type=\"button\"\n className=\"cf-btn\"\n onClick={() => {\n const nonce = ++nonceRef.current;\n setPopup({ kind: \"at\", query: \"\", nonce });\n }}\n >\n <span className=\"ico\">\n <I.at size={14} />\n </span>\n <span className=\"label\">{t(\"composer.mentionLabel\")}</span>\n </button>\n\n <span className=\"grow\" />\n\n <div ref={modelWrapRef} style={{ position: \"relative\" }}>\n <button\n type=\"button\"\n className=\"model-pill\"\n onClick={() => setModelMenuOpen((v) => !v)}\n title={t(\"composer.switchModel\")}\n >\n <I.brain size={12} />\n <span>{modelLabel}</span>\n <span className=\"badge\">{reasoningEffort}</span>\n <I.chev size={10} />\n </button>\n {modelMenuOpen ? (\n <ModelEffortMenu\n modelLabel={modelLabel}\n currentEffort={reasoningEffort}\n onPickModel={(m) => {\n onModelChange(m);\n setModelMenuOpen(false);\n }}\n onPickEffort={(e) => {\n onEffortChange(e);\n setModelMenuOpen(false);\n }}\n />\n ) : null}\n </div>\n {busy ? (\n <button\n type=\"button\"\n className=\"send-btn\"\n style={{ background: \"var(--danger)\" }}\n onClick={onAbort}\n title={t(\"composer.interrupt\")}\n >\n <I.stop size={14} />\n </button>\n ) : (\n <button\n type=\"button\"\n className=\"send-btn\"\n disabled={disabled || !draft.trim()}\n onClick={() => {\n if (!disabled && draft.trim()) {\n onSend();\n setChips([]);\n }\n }}\n >\n <I.send size={14} />\n </button>\n )}\n </div>\n\n {popup ? (\n <Popup\n kind={popup.kind}\n items={items}\n activeIdx={activeIdx}\n onPick={(i) => pickItem(i)}\n onClose={dismiss}\n onHover={(i, item) => {\n setActiveIdx(i);\n if (popup.kind === \"at\" && onMentionPreview) {\n const path = (item as MentionItem).name;\n onMentionPreview(path, popup.nonce);\n }\n }}\n />\n ) : null}\n </div>\n </div>\n </div>\n );\n}\n\nfunction Popup({\n kind,\n items,\n activeIdx,\n onPick,\n onClose,\n onHover,\n}: {\n kind: \"slash\" | \"at\";\n items: (SlashCmd | MentionItem)[];\n activeIdx: number;\n onPick: (i: number) => void;\n onClose: () => void;\n onHover: (i: number, item: SlashCmd | MentionItem) => void;\n}) {\n const listRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n requestAnimationFrame(() => {\n const el = listRef.current?.querySelector<HTMLElement>(`[data-active=\"true\"]`);\n el?.scrollIntoView({ block: \"nearest\" });\n });\n }, [activeIdx]);\n\n return (\n <div className=\"popup\" onMouseDown={(e) => e.preventDefault()}>\n <div className=\"ph\">\n <span className=\"tok\">{kind === \"slash\" ? \"/\" : \"@\"}</span>\n <span>\n {kind === \"slash\"\n ? t(\"composer.slashHeader\")\n : t(\"composer.atHeader\")}\n </span>\n <span className=\"grow\" />\n <span style={{ cursor: \"pointer\" }} onClick={onClose}>\n <I.x size={11} />\n </span>\n </div>\n <div className=\"popup-list\" ref={listRef}>\n {items.length === 0 ? (\n <div\n style={{\n padding: \"12px 8px\",\n fontSize: 11.5,\n color: \"var(--muted-2)\",\n fontFamily: \"Geist Mono, monospace\",\n }}\n >\n {t(\"composer.noMatches\")}\n </div>\n ) : null}\n {items.map((it, i) => (\n <div\n key={i}\n className=\"popup-item\"\n data-active={i === activeIdx}\n onClick={() => onPick(i)}\n onMouseEnter={() => onHover(i, it)}\n >\n <span className=\"ico\">\n {kind === \"slash\"\n ? slashIcon((it as SlashCmd).cmd)\n : atIcon((it as MentionItem).kind)}\n </span>\n <div className=\"nm\">\n {kind === \"slash\" ? (\n <>\n <span className=\"cmd\">{(it as SlashCmd).cmd}</span>\n <span className=\"desc\">{(it as SlashCmd).desc}</span>\n </>\n ) : (\n <>\n <span>{(it as MentionItem).name}</span>\n {(it as MentionItem).desc ? (\n <div className=\"desc\">{(it as MentionItem).desc}</div>\n ) : null}\n </>\n )}\n </div>\n <span className=\"kb\">\n {kind === \"slash\" ? ((it as SlashCmd).kb ?? \"\") : \"\"}\n </span>\n </div>\n ))}\n </div>\n <div className=\"popup-foot\">\n <span>\n <Shortcut keys={[\"updown\"]} /> {t(\"composer.select\")}\n </span>\n <span>\n <Shortcut keys={[\"enter\"]} /> {t(\"composer.confirm\")}\n </span>\n <span>\n <Shortcut keys={[\"esc\"]} /> {t(\"composer.close\")}\n </span>\n </div>\n </div>\n );\n}\n\nconst KNOWN_MODELS: readonly string[] = [\"deepseek-v4-flash\", \"deepseek-v4-pro\"];\n\nfunction ModelEffortMenu({\n modelLabel,\n currentEffort,\n onPickModel,\n onPickEffort,\n}: {\n modelLabel: string;\n currentEffort: ReasoningEffort;\n onPickModel: (model: string) => void;\n onPickEffort: (effort: ReasoningEffort) => void;\n}) {\n const [draft, setDraft] = useState(modelLabel);\n return (\n <div\n className=\"popup\"\n style={{\n bottom: \"calc(100% + 6px)\",\n left: \"auto\",\n right: 0,\n width: 280,\n position: \"absolute\",\n }}\n >\n <div className=\"ph\">\n <span className=\"tok\">M</span>\n <span>{t(\"composer.switchModel\")}</span>\n </div>\n <div className=\"popup-list\">\n {KNOWN_MODELS.map((m) => (\n <div\n key={m}\n className=\"popup-item\"\n data-active={m === modelLabel}\n onClick={() => onPickModel(m)}\n >\n <span className=\"ico\">\n <I.brain size={12} />\n </span>\n <div className=\"nm\">\n <span className=\"cmd\">{m}</span>\n </div>\n </div>\n ))}\n <div style={{ padding: \"6px 8px\", display: \"flex\", gap: 6 }}>\n <input\n className=\"field mono\"\n style={{ flex: 1 }}\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n placeholder=\"custom model id\"\n />\n <button\n type=\"button\"\n className=\"btn\"\n disabled={!draft.trim() || draft.trim() === modelLabel}\n onClick={() => onPickModel(draft.trim())}\n >\n {t(\"composer.confirm\")}\n </button>\n </div>\n </div>\n <div className=\"ph\" style={{ marginTop: 4 }}>\n <span className=\"tok\">E</span>\n <span>{t(\"composer.switchEffort\")}</span>\n </div>\n <div className=\"popup-list\">\n {EFFORTS.map((e) => (\n <div\n key={e}\n className=\"popup-item\"\n data-active={e === currentEffort}\n onClick={() => onPickEffort(e)}\n >\n <span className=\"ico\">\n <I.cpu size={12} />\n </span>\n <div className=\"nm\">\n <span className=\"cmd\">{e}</span>\n <div className=\"desc\">{t(`effort.${e}Desc` as TKey)}</div>\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n","import { Component, type ReactNode } from \"react\";\nimport { t } from \"../i18n\";\n\ntype Props = { label: string; children: ReactNode };\ntype State = { error: Error | null };\n\nexport class PanelErrorBoundary extends Component<Props, State> {\n state: State = { error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { error };\n }\n\n componentDidCatch(error: Error, info: { componentStack?: string | null }): void {\n console.error(`[panel:${this.props.label}] render error`, error, info);\n }\n\n render(): ReactNode {\n if (!this.state.error) return this.props.children;\n return (\n <div\n className=\"ctx-empty\"\n style={{\n color: \"var(--danger, #e25555)\",\n padding: 12,\n fontSize: 12,\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n >\n {t(\"panel.renderError\", { panel: this.props.label })}\n {\": \"}\n {this.state.error.message}\n </div>\n );\n }\n}\n","import { useMemo, useState } from \"react\";\nimport type { SessionFile, Settings, UsageStats } from \"../App\";\nimport { t, useLang } from \"../i18n\";\nimport { I } from \"../icons\";\nimport type { McpSpecInfo, MemoryEntryInfo } from \"../protocol\";\nimport { PanelErrorBoundary } from \"./error-boundary\";\n\ntype Tab = \"files\" | \"tools\" | \"memory\" | \"rules\";\n\nconst CONTEXT_MAX_TOKENS = 1_000_000;\n\nexport function ContextPanel({\n settings,\n usage,\n mcpSpecs,\n mcpBridged,\n sessionFiles,\n memory,\n}: {\n settings: Settings | null;\n usage: UsageStats;\n mcpSpecs: McpSpecInfo[];\n mcpBridged: boolean;\n sessionFiles: SessionFile[];\n memory: MemoryEntryInfo[];\n}) {\n useLang();\n const [tab, setTab] = useState<Tab>(\"files\");\n const reserved = usage.reservedTokens;\n // After a warm cache turn the API counts the reserved prefix inside cacheHit;\n // subtract to keep the bar segments visually disjoint. Cold cache shows the\n // reserved portion in cacheMiss instead, so do the same for `used`.\n const cached = Math.max(0, usage.cacheHitTokens - reserved);\n const used = Math.max(0, usage.cacheMissTokens - Math.max(0, reserved - usage.cacheHitTokens));\n const reservedPct = Math.min(100, (reserved / CONTEXT_MAX_TOKENS) * 100);\n const usedPct = Math.min(100, (used / CONTEXT_MAX_TOKENS) * 100);\n const cachedPct = Math.min(100, (cached / CONTEXT_MAX_TOKENS) * 100);\n const free = Math.max(0, CONTEXT_MAX_TOKENS - reserved - used - cached);\n return (\n <aside className=\"ctx\">\n <div className=\"ctx-tabs\">\n <div className=\"ctx-tab\" data-active={tab === \"files\"} onClick={() => setTab(\"files\")}>\n {t(\"contextPanel.filesTab\")}\n </div>\n <div className=\"ctx-tab\" data-active={tab === \"tools\"} onClick={() => setTab(\"tools\")}>\n {t(\"contextPanel.toolsTab\")}\n </div>\n <div className=\"ctx-tab\" data-active={tab === \"memory\"} onClick={() => setTab(\"memory\")}>\n {t(\"contextPanel.memoryTab\")}\n </div>\n <div className=\"ctx-tab\" data-active={tab === \"rules\"} onClick={() => setTab(\"rules\")}>\n {t(\"contextPanel.rulesTab\")}\n </div>\n </div>\n\n <div className=\"ctx-body\">\n <div className=\"ctx-block\">\n <div className=\"h\">\n <span>{t(\"contextPanel.contextTokens\")}</span>\n <span className=\"right\">\n {(reserved + used + cached).toLocaleString()} /{\" \"}\n {CONTEXT_MAX_TOKENS.toLocaleString()}\n </span>\n </div>\n <div className=\"meter\">\n <span className=\"rsvd\" style={{ width: `${reservedPct}%` }} />\n <span className=\"cached\" style={{ width: `${cachedPct}%` }} />\n <span className=\"used\" style={{ width: `${usedPct}%` }} />\n </div>\n <div className=\"legend\">\n <span className=\"l\">\n <span className=\"sw r\" />\n {t(\"contextPanel.reservedKey\")} <span className=\"v\">{reserved.toLocaleString()}</span>\n </span>\n <span className=\"l\">\n <span className=\"sw c\" />\n {t(\"contextPanel.cacheKey\")} <span className=\"v\">{cached.toLocaleString()}</span>\n </span>\n <span className=\"l\">\n <span className=\"sw u\" />\n {t(\"contextPanel.usedKey\")} <span className=\"v\">{used.toLocaleString()}</span>\n </span>\n <span className=\"l\">\n {t(\"contextPanel.freeKey\")} <span className=\"v\">{free.toLocaleString()}</span>\n </span>\n </div>\n </div>\n\n <PanelErrorBoundary key={tab} label={tab}>\n {tab === \"files\" && <CtxFiles files={sessionFiles} />}\n {tab === \"tools\" && <CtxTools specs={mcpSpecs} bridged={mcpBridged} />}\n {tab === \"memory\" && <CtxMemory entries={memory} />}\n {tab === \"rules\" && <CtxRules settings={settings} />}\n </PanelErrorBoundary>\n </div>\n </aside>\n );\n}\n\ntype TreeNode =\n | { kind: \"dir\"; depth: number; name: string; key: string }\n | { kind: \"file\"; depth: number; name: string; key: string; status: \"c\" | \"m\" };\n\nfunction buildSessionTree(files: SessionFile[]): TreeNode[] {\n const sorted = [...files].sort((a, b) =>\n a.path.replace(/\\\\/g, \"/\").localeCompare(b.path.replace(/\\\\/g, \"/\")),\n );\n const out: TreeNode[] = [];\n const seenDirs = new Set<string>();\n for (const f of sorted) {\n const parts = f.path.replace(/\\\\/g, \"/\").split(\"/\").filter(Boolean);\n if (parts.length === 0) continue;\n let prefix = \"\";\n for (let i = 0; i < parts.length - 1; i++) {\n const seg = parts[i] ?? \"\";\n prefix = prefix ? `${prefix}/${seg}` : seg;\n if (!seenDirs.has(prefix)) {\n seenDirs.add(prefix);\n out.push({ kind: \"dir\", depth: i, name: seg, key: `d:${prefix}` });\n }\n }\n const leaf = parts[parts.length - 1] ?? \"\";\n out.push({\n kind: \"file\",\n depth: parts.length - 1,\n name: leaf,\n key: `f:${f.path}`,\n status: f.status,\n });\n }\n return out;\n}\n\nfunction CtxFiles({ files }: { files: SessionFile[] }) {\n const tree = useMemo(() => buildSessionTree(files), [files]);\n return (\n <div className=\"ctx-block\">\n <div className=\"h\">\n <span>{t(\"contextPanel.filesTitle\")}</span>\n <span className=\"right\">\n {files.length === 0 ? \"—\" : t(\"contextPanel.filesCount\", { count: files.length })}\n </span>\n </div>\n <div className=\"tree\">\n {files.length === 0 ? (\n <div className=\"ctx-empty\">{t(\"contextPanel.noFilesMsg\")}</div>\n ) : (\n tree.map((n) =>\n n.kind === \"dir\" ? (\n <div className=\"node\" key={n.key} data-d={n.depth} data-kind=\"dir\">\n <span className=\"ico\">\n <I.folder size={12} />\n </span>\n <span className=\"nm\">{n.name}/</span>\n </div>\n ) : (\n <div\n className=\"node\"\n key={n.key}\n data-d={n.depth}\n data-kind=\"file\"\n title={n.name}\n >\n <span className=\"ico\">\n <I.file size={12} />\n </span>\n <span className=\"nm\">{n.name}</span>\n <span\n className=\"dot\"\n data-s={n.status}\n title={n.status === \"m\" ? t(\"contextPanel.fileModified\") : t(\"contextPanel.fileInContext\")}\n />\n </div>\n ),\n )\n )}\n </div>\n </div>\n );\n}\n\nfunction CtxTools({ specs, bridged }: { specs: McpSpecInfo[]; bridged: boolean }) {\n const readyCount = specs.filter((s) => s.status === \"connected\").length;\n return (\n <div className=\"ctx-block\">\n <div className=\"h\">\n <span>{t(\"contextPanel.mcpTitle\")}</span>\n <span className=\"right\">\n {specs.length === 0\n ? \"—\"\n : bridged\n ? t(\"contextPanel.mcpReadyAll\", { count: specs.length })\n : t(\"contextPanel.mcpReadySome\", { ready: readyCount, count: specs.length })}\n </span>\n </div>\n {specs.length === 0 ? (\n <div className=\"ctx-empty\">{t(\"contextPanel.mcpEmpty\")}</div>\n ) : (\n specs.map((s) => {\n const dot =\n s.status === \"connected\"\n ? \"ok\"\n : s.status === \"failed\" || s.parseError\n ? \"off\"\n : \"pending\";\n const suffix = s.statusReason\n ? ` · ${s.statusReason}`\n : s.status === \"connected\"\n ? typeof s.toolCount === \"number\"\n ? ` · ${t(\"contextPanel.mcpTools\", { count: s.toolCount })}`\n : ` · ${t(\"contextPanel.mcpReady\")}`\n : s.status === \"handshake\"\n ? ` · ${t(\"contextPanel.mcpConnecting\")}`\n : s.status === \"disabled\"\n ? ` · ${t(\"contextPanel.mcpDisabled\")}`\n : s.status === \"failed\"\n ? ` · ${t(\"contextPanel.mcpFailed\")}`\n : ` · ${t(\"contextPanel.mcpConfigured\")}`;\n return (\n <div className=\"mcp-row\" key={s.raw}>\n <span className=\"ico\">\n <I.wrench size={12} />\n </span>\n <div className=\"body\">\n <div className=\"n\">{s.name ?? s.summary}</div>\n <div className=\"m\">\n {s.transport}\n {suffix}\n </div>\n </div>\n <span className=\"status\" data-s={dot} />\n </div>\n );\n })\n )}\n </div>\n );\n}\n\nfunction CtxMemory({ entries }: { entries: MemoryEntryInfo[] }) {\n return (\n <div className=\"ctx-block\">\n <div className=\"h\">\n <span>{t(\"contextPanel.memoryTitle\")}</span>\n <span className=\"right\">\n {entries.length === 0 ? \"—\" : t(\"contextPanel.itemCount\", { count: entries.length })}\n </span>\n </div>\n {entries.length === 0 ? (\n <div className=\"ctx-empty\">{t(\"contextPanel.noMemoriesMsg\")}</div>\n ) : (\n <div className=\"mem\">\n {entries.map((m) => (\n <div className=\"mem-row\" key={`${m.scope}/${m.name}`}>\n <span className=\"scope\" data-s={m.scope}>\n {m.scope === \"project\" ? t(\"contextPanel.scopeProject\") : t(\"contextPanel.scopeGlobal\")}\n </span>\n <span className=\"txt\">{m.description || m.name}</span>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction CtxRules({ settings }: { settings: Settings | null }) {\n const editMode = settings?.editMode ?? \"review\";\n const items: { p: string; allow: boolean; desc: string }[] =\n editMode === \"yolo\"\n ? [{ p: \"*\", allow: true, desc: t(\"contextPanel.ruleYolo\") }]\n : editMode === \"auto\"\n ? [\n { p: \"read_file, list_directory, search_files, *\", allow: true, desc: t(\"contextPanel.ruleReadOnly\") },\n { p: \"run_command (allowlist)\", allow: true, desc: t(\"contextPanel.ruleShellAllowlist\") },\n { p: \"edit_file, write_file, run_command (other)\", allow: false, desc: t(\"contextPanel.ruleWritesAsk\") },\n ]\n : [\n { p: \"*\", allow: false, desc: t(\"contextPanel.ruleReview\") },\n ];\n return (\n <div className=\"ctx-block\">\n <div className=\"h\">\n <span>{t(\"contextPanel.autoApproveTitle\")}</span>\n <span className=\"right\">{editMode}</span>\n </div>\n {items.map((r) => (\n <div className=\"rule\" key={r.p}>\n <div className=\"top\">\n <span className={`pat ${r.allow ? \"\" : \"deny\"}`}>{r.p}</span>\n <span className={`sw ${r.allow ? \"\" : \"deny\"}`}>\n {r.allow ? t(\"contextPanel.allow\") : t(\"contextPanel.ask\")}\n </span>\n </div>\n <div className=\"desc\">{r.desc}</div>\n </div>\n ))}\n </div>\n );\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { I } from \"../icons\";\nimport { t, useLang } from \"../i18n\";\nimport type { JobInfo } from \"../protocol\";\nimport { Shortcut } from \"./shortcut\";\n\nexport function JobsPop({\n open,\n onClose,\n jobs,\n onStop,\n onStopAll,\n}: {\n open: boolean;\n onClose: () => void;\n jobs: JobInfo[];\n onStop: (jobId: number) => void;\n onStopAll: () => void;\n}) {\n useLang();\n const [tick, setTick] = useState(0);\n useEffect(() => {\n if (!open) return;\n const id = window.setInterval(() => setTick((n) => n + 1), 600);\n return () => window.clearInterval(id);\n }, [open]);\n useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onClose();\n }\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [open, onClose]);\n\n const running = useMemo(() => jobs.filter((j) => j.running), [jobs]);\n const exited = useMemo(() => jobs.filter((j) => !j.running), [jobs]);\n\n if (!open) return null;\n\n return (\n <div className=\"jobs-mask\" onClick={onClose}>\n <div className=\"jobs-pop\" onClick={(e) => e.stopPropagation()}>\n <div className=\"jobs-head\">\n <span className=\"ico\">\n <I.cpu size={13} />\n </span>\n <div>\n <div className=\"tt\">{t(\"jobs.title\")}</div>\n <div className=\"ss\">\n <span className=\"b ok\">{running.length}</span> {t(\"jobs.running\")} ·{\" \"}\n <span className=\"b mut\">{exited.length}</span> {t(\"jobs.exited\")}\n </div>\n </div>\n <span className=\"grow\" />\n {running.length > 0 ? (\n <button\n type=\"button\"\n className=\"btn danger sm\"\n onClick={onStopAll}\n title={t(\"jobs.stopAllTip\")}\n >\n <I.stop size={10} /> {t(\"jobs.stopAll\")}\n </button>\n ) : null}\n </div>\n\n <div className=\"jobs-body\">\n {jobs.length === 0 ? (\n <div className=\"jobs-empty\">{t(\"jobs.empty\")}</div>\n ) : (\n <>\n {running.length > 0 ? <div className=\"jobs-grp\">{t(\"jobs.running\")}</div> : null}\n {running.map((j) => (\n <JobRow key={j.id} job={j} tick={tick} onStop={onStop} />\n ))}\n {exited.length > 0 ? <div className=\"jobs-grp\">{t(\"jobs.exited\")}</div> : null}\n {exited.map((j) => (\n <JobRow key={j.id} job={j} tick={tick} onStop={onStop} />\n ))}\n </>\n )}\n </div>\n\n <div className=\"jobs-foot\">\n <div className=\"row\">\n <I.zap size={11} />\n <span>\n {t(\"jobs.running\")} <span className=\"v\">{running.length}</span>\n </span>\n <span>·</span>\n <span>\n {t(\"jobs.exited\")} <span className=\"v\">{exited.length}</span>\n </span>\n <span className=\"grow\" />\n <span>\n <Shortcut keys={[\"mod\", \"J\"]} /> {t(\"jobs.kbToggle\")} ·{\" \"}\n <Shortcut keys={[\"esc\"]} /> {t(\"jobs.kbClose\")}\n </span>\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction formatElapsed(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n const s = ms / 1000;\n if (s < 60) return `${s.toFixed(1)}s`;\n const m = Math.floor(s / 60);\n const r = Math.floor(s % 60);\n return `${m}m${r}s`;\n}\n\nfunction JobRow({\n job,\n tick,\n onStop,\n}: {\n job: JobInfo;\n tick: number;\n onStop: (jobId: number) => void;\n}) {\n const [exp, setExp] = useState(false);\n const elapsedMs = (job.running ? Date.now() : job.startedAt + 0) - job.startedAt;\n const liveMs = job.running ? Date.now() - job.startedAt : elapsedMs;\n // tick is referenced so the row re-renders for the running clock\n void tick;\n return (\n <div className=\"job-row\" data-status={job.running ? \"running\" : \"exited\"}>\n <div className=\"jr-main\" onClick={() => setExp((v) => !v)}>\n <span className=\"jr-state\">\n {job.running ? (\n <span className=\"spin\" />\n ) : (\n <I.history size={11} style={{ color: \"var(--muted-2)\" }} />\n )}\n </span>\n <span className=\"jr-kind\">\n <I.terminal size={11} />\n <span>shell</span>\n </span>\n <div className=\"jr-body\">\n <div className=\"nm\" title={job.command}>\n {job.command}\n </div>\n <div className=\"sub\">\n <span className=\"ses\">{job.sessionLabel}</span>\n {job.spawnError ? <span className=\"rk\">· {job.spawnError}</span> : null}\n {!job.running && job.exitCode !== null && job.exitCode !== 0 ? (\n <span className=\"rk\">· exit {job.exitCode}</span>\n ) : null}\n </div>\n </div>\n <div className=\"jr-time\">{formatElapsed(liveMs)}</div>\n <div className=\"jr-act\">\n {job.running ? (\n <button\n type=\"button\"\n className=\"btn danger sm\"\n title={t(\"jobs.stopOne\")}\n onClick={(e) => {\n e.stopPropagation();\n onStop(job.id);\n }}\n >\n <I.stop size={10} /> {t(\"jobs.stop\")}\n </button>\n ) : (\n <span className=\"jr-exit\" title={`exit ${job.exitCode ?? \"—\"}`}>\n {job.exitCode === 0 ? \"ok\" : `exit ${job.exitCode ?? \"?\"}`}\n </span>\n )}\n </div>\n </div>\n {exp ? (\n <div className=\"jr-detail\">\n <div className=\"kv-grid\">\n <div>\n <span className=\"k\">job_id</span>\n <span className=\"v\">{job.id}</span>\n </div>\n <div>\n <span className=\"k\">pid</span>\n <span className=\"v\">{job.pid ?? \"—\"}</span>\n </div>\n <div>\n <span className=\"k\">elapsed</span>\n <span className=\"v\">{formatElapsed(liveMs)}</span>\n </div>\n </div>\n {job.outputTail ? <pre className=\"jr-log\">{job.outputTail}</pre> : null}\n </div>\n ) : null}\n </div>\n );\n}\n","import { openUrl } from \"@tauri-apps/plugin-opener\";\nimport { t } from \"../i18n\";\nimport { I } from \"../icons\";\n\nconst REPO_URL = \"https://github.com/esengine/DeepSeek-Reasonix\";\n\nexport function AboutModal({ onClose }: { onClose: () => void }) {\n const openGitHub = () => {\n void openUrl(REPO_URL).catch(() => undefined);\n };\n\n return (\n <div className=\"about-mask\" onClick={onClose}>\n <div className=\"about-modal\" onClick={(e) => e.stopPropagation()}>\n <button type=\"button\" className=\"about-close\" onClick={onClose} aria-label={t(\"about.close\")}>\n <I.x size={14} />\n </button>\n <div className=\"about-brand\">\n <div className=\"about-name\">Reasonix</div>\n <div className=\"about-tagline\">{t(\"about.tagline\")}</div>\n </div>\n <div className=\"about-meta\">\n <div className=\"about-row\">\n <span className=\"about-label\">{t(\"about.version\")}</span>\n <code className=\"about-value\">{__APP_VERSION__}</code>\n </div>\n <div className=\"about-row\">\n <span className=\"about-label\">{t(\"about.repo\")}</span>\n <button type=\"button\" className=\"about-link\" onClick={openGitHub}>\n <I.link size={12} />\n <span>esengine/DeepSeek-Reasonix</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import { t } from \"./i18n\";\n\nexport interface QQDesktopSettingsState {\n appId?: string;\n appSecret?: string;\n sandbox: boolean;\n enabled: boolean;\n configured: boolean;\n runtimeState: \"disconnected\" | \"connecting\" | \"connected\" | \"failed\";\n lastError?: string;\n appIdPreview?: string;\n access: string;\n}\n\nexport function maskQQAppId(appId: string | undefined): string | undefined {\n if (!appId) return undefined;\n return appId.length > 6 ? `${appId.slice(0, 6)}...` : appId;\n}\n\nexport function getQQConnectIntent(qq: QQDesktopSettingsState): \"configure\" | \"connect\" {\n return qq.configured ? \"connect\" : \"configure\";\n}\n\nexport function getQQStatusLabel(qq: QQDesktopSettingsState): string {\n switch (qq.runtimeState) {\n case \"connected\":\n return t(\"settings.qqConnected\");\n case \"connecting\":\n return t(\"settings.qqConnecting\");\n case \"failed\":\n return t(\"settings.qqFailed\");\n default:\n return t(\"settings.qqDisconnected\");\n }\n}\n\nexport function describeQQAccessLabel(access: string): string {\n const owner = /^owner (.+?)(?:, allowlist (\\d+))?$/.exec(access);\n if (owner) {\n const openId = owner[1] ?? \"unknown\";\n const count = owner[2];\n if (count) return t(\"settings.qqAccessOwnerWithAllowlist\", { openId, count });\n return t(\"settings.qqAccessOwner\", { openId });\n }\n\n const allowlist = /^allowlist (\\d+)$/.exec(access);\n if (allowlist) return t(\"settings.qqAccessAllowlist\", { count: allowlist[1] ?? \"0\" });\n\n const runtime = /^first-sender \\(runtime only, (.+)\\)$/.exec(access);\n if (runtime) return t(\"settings.qqAccessRuntime\", { openId: runtime[1] ?? \"unknown\" });\n\n return t(\"settings.qqAccessOpen\");\n}\n\nexport function describeQQRowSummary(qq: QQDesktopSettingsState): string {\n if (!qq.configured) return t(\"settings.qqSummaryMissing\");\n const appId = qq.appIdPreview ?? maskQQAppId(qq.appId) ?? \"unknown\";\n return t(\"settings.qqSummaryDetail\", {\n appId: t(\"settings.qqSummaryAppId\", { appId }),\n environment: qq.sandbox ? t(\"settings.qqSandbox\") : t(\"settings.qqProduction\"),\n access: describeQQAccessLabel(qq.access),\n });\n}\n","import { type ReactNode, useEffect, useState } from \"react\";\nimport type { Balance, Settings as SettingsType, UsageStats } from \"../App\";\nimport { setLang, t, useLang } from \"../i18n\";\nimport { I } from \"../icons\";\nimport type { McpSpecInfo, SettingsPatch, SkillInfo } from \"../protocol\";\nimport {\n describeQQRowSummary,\n getQQConnectIntent,\n getQQStatusLabel,\n type QQDesktopSettingsState,\n} from \"../qq-settings\";\nimport {\n FONT_FAMILY,\n FONT_SCALE,\n type FontFamily,\n type FontScale,\n THEME,\n THEME_STYLES,\n type Theme,\n type ThemeStyle,\n themeForStyle,\n} from \"../theme\";\nimport { Shortcut, type ShortcutKey } from \"./shortcut\";\n\nexport type PageId =\n | \"general\"\n | \"models\"\n | \"mcp\"\n | \"skills\"\n | \"memory\"\n | \"rules\"\n | \"billing\"\n | \"shortcuts\";\n\nconst PAGE_META: ReadonlyArray<{ id: PageId; icon: keyof typeof I }> = [\n { id: \"general\", icon: \"cog\" },\n { id: \"models\", icon: \"brain\" },\n { id: \"mcp\", icon: \"wrench\" },\n { id: \"skills\", icon: \"zap\" },\n { id: \"memory\", icon: \"bookmark\" },\n { id: \"rules\", icon: \"shield\" },\n { id: \"billing\", icon: \"coin\" },\n { id: \"shortcuts\", icon: \"cpu\" },\n];\n\nexport function SettingsModal({\n settings,\n balance,\n usage,\n currency,\n theme,\n themeStyle,\n onSetTheme,\n onSetThemeStyle,\n fontScale,\n onSetFontScale,\n fontFamily,\n onSetFontFamily,\n initialPage,\n mcpSpecs,\n mcpBridged,\n skills,\n qq,\n onClose,\n onSave,\n onSaveApiKey,\n onLoadQQ,\n onConnectQQ,\n onDisconnectQQ,\n onSaveQQConfig,\n onOpenQQApplyLink,\n onPickWorkspace,\n onAddMcpSpec,\n onRemoveMcpSpec,\n}: {\n settings: SettingsType;\n balance: Balance | null;\n usage: UsageStats;\n currency: \"CNY\" | \"USD\";\n theme: Theme;\n themeStyle: ThemeStyle;\n onSetTheme: (theme: Theme) => void;\n onSetThemeStyle: (style: ThemeStyle) => void;\n fontScale: FontScale;\n onSetFontScale: (scale: FontScale) => void;\n fontFamily: FontFamily;\n onSetFontFamily: (family: FontFamily) => void;\n initialPage?: PageId;\n mcpSpecs: McpSpecInfo[];\n mcpBridged: boolean;\n skills: SkillInfo[];\n qq: QQDesktopSettingsState | null;\n onClose: () => void;\n onSave: (patch: SettingsPatch) => void;\n onSaveApiKey: (key: string) => void;\n onLoadQQ: () => void;\n onConnectQQ: () => void;\n onDisconnectQQ: () => void;\n onSaveQQConfig: (patch: { appId?: string; appSecret?: string; sandbox: boolean }) => void;\n onOpenQQApplyLink: () => void;\n onPickWorkspace: () => void;\n onAddMcpSpec: (spec: string) => void;\n onRemoveMcpSpec: (spec: string) => void;\n}) {\n const [page, setPage] = useState<PageId>(initialPage ?? \"general\");\n const [qqConfigureOpen, setQQConfigureOpen] = useState(false);\n const currentMeta = PAGE_META.find((p) => p.id === page) ?? PAGE_META[0]!;\n return (\n <div className=\"settings-mask\" onClick={onClose}>\n <div className=\"settings\" onClick={(e) => e.stopPropagation()}>\n <nav className=\"settings-side\">\n <div className=\"sg\">{t(\"settings.title\")}</div>\n {PAGE_META.map((p) => (\n <div\n key={p.id}\n className=\"row\"\n data-active={page === p.id}\n onClick={() => setPage(p.id)}\n >\n <span className=\"ico\">{I[p.icon]({ size: 13 })}</span>\n <span>{t(`settings.page${p.id[0]!.toUpperCase()}${p.id.slice(1)}Label` as any)}</span>\n </div>\n ))}\n </nav>\n <div className=\"settings-main\">\n <div className=\"settings-head\">\n <div>\n <h2>\n {t(\n `settings.page${currentMeta.id[0]!.toUpperCase()}${currentMeta.id.slice(1)}Label` as any,\n )}\n </h2>\n <div className=\"desc\">\n {t(\n `settings.page${currentMeta.id[0]!.toUpperCase()}${currentMeta.id.slice(1)}Desc` as any,\n )}\n </div>\n </div>\n <span className=\"grow\" />\n <button type=\"button\" className=\"close-btn\" onClick={onClose}>\n <I.x size={14} />\n </button>\n </div>\n <div className=\"settings-body\">\n {page === \"general\" && (\n <PageGeneral\n settings={settings}\n theme={theme}\n themeStyle={themeStyle}\n onSetTheme={onSetTheme}\n onSetThemeStyle={onSetThemeStyle}\n fontScale={fontScale}\n onSetFontScale={onSetFontScale}\n fontFamily={fontFamily}\n onSetFontFamily={onSetFontFamily}\n onSave={onSave}\n onPickWorkspace={onPickWorkspace}\n />\n )}\n {page === \"models\" && <PageModels settings={settings} onSave={onSave} />}\n {page === \"mcp\" && (\n <PageMCP\n specs={mcpSpecs}\n bridged={mcpBridged}\n onAdd={onAddMcpSpec}\n onRemove={onRemoveMcpSpec}\n />\n )}\n {page === \"skills\" && (\n <PageSkills\n skills={skills}\n subagentModels={settings.subagentModels ?? {}}\n onSave={onSave}\n />\n )}\n {page === \"memory\" && <PageMemory />}\n {page === \"rules\" && <PageRules settings={settings} onSave={onSave} />}\n {page === \"billing\" && (\n <PageBilling balance={balance} usage={usage} currency={currency} />\n )}\n {page === \"shortcuts\" && <PageShortcuts />}\n {page === \"general\" ? (\n <>\n <ApiKeySection\n baseUrl={settings.baseUrl}\n apiKeyPrefix={settings.apiKeyPrefix}\n onSave={onSave}\n onSaveApiKey={onSaveApiKey}\n />\n <QQChannelSection\n qq={qq}\n configureOpen={qqConfigureOpen}\n onOpenConfigure={() => {\n onLoadQQ();\n setQQConfigureOpen(true);\n }}\n onCloseConfigure={() => setQQConfigureOpen(false)}\n onConnect={onConnectQQ}\n onDisconnect={onDisconnectQQ}\n onSaveConfig={onSaveQQConfig}\n onSaveAndConnect={(patch) => {\n onSaveQQConfig(patch);\n onConnectQQ();\n }}\n onOpenApplyLink={onOpenQQApplyLink}\n />\n </>\n ) : null}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nexport function QQChannelSection({\n qq,\n configureOpen,\n onOpenConfigure,\n onCloseConfigure,\n onConnect,\n onDisconnect,\n onSaveConfig,\n onSaveAndConnect,\n onOpenApplyLink,\n}: {\n qq: QQDesktopSettingsState | null;\n configureOpen: boolean;\n onOpenConfigure: () => void;\n onCloseConfigure: () => void;\n onConnect: () => void;\n onDisconnect: () => void;\n onSaveConfig: (patch: { appId?: string; appSecret?: string; sandbox: boolean }) => void;\n onSaveAndConnect: (patch: { appId?: string; appSecret?: string; sandbox: boolean }) => void;\n onOpenApplyLink: () => void;\n}) {\n const current = qq ?? {\n appId: undefined,\n appSecret: undefined,\n sandbox: true,\n enabled: false,\n configured: false,\n runtimeState: \"disconnected\",\n access: \"open (unbound)\",\n };\n const [appId, setAppId] = useState(current.appId ?? \"\");\n const [appSecret, setAppSecret] = useState(current.appSecret ?? \"\");\n const [sandbox, setSandbox] = useState(current.sandbox ?? true);\n\n useEffect(() => {\n setAppId(current.appId ?? \"\");\n setAppSecret(current.appSecret ?? \"\");\n setSandbox(current.sandbox ?? true);\n }, [current.appId, current.appSecret, current.sandbox, configureOpen]);\n\n const savePatch = { appId, appSecret, sandbox };\n\n return (\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.qqSection\")}</div>\n {!configureOpen ? (\n <div className=\"setting-row qq-setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.qqTitle\")}</div>\n <div className=\"h\">{describeQQRowSummary(current)}</div>\n </div>\n <div className=\"qq-row-actions\">\n <button\n type=\"button\"\n className={`btn qq-status-btn qq-status-${\n current.runtimeState === \"connected\"\n ? \"on\"\n : current.runtimeState === \"connecting\"\n ? \"connecting\"\n : current.runtimeState === \"failed\"\n ? \"failed\"\n : \"off\"\n }`}\n onClick={() => {\n if (getQQConnectIntent(current) === \"configure\") {\n onOpenConfigure();\n return;\n }\n if (current.runtimeState === \"connected\") {\n onDisconnect();\n return;\n }\n onConnect();\n }}\n >\n {getQQStatusLabel(current)}\n </button>\n <button type=\"button\" className=\"btn\" onClick={onOpenConfigure}>\n {t(\"settings.qqConfigure\")}\n </button>\n </div>\n </div>\n ) : (\n <div className=\"qq-config-card\">\n <div className=\"qq-config-head\">\n <div>\n <div className=\"n\">{t(\"settings.qqConfigureTitle\")}</div>\n <div className=\"h\">{t(\"settings.qqConfigureHint\")}</div>\n </div>\n <button type=\"button\" className=\"btn\" onClick={onCloseConfigure}>\n {t(\"settings.qqBack\")}\n </button>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.qqAppId\")}</div>\n </div>\n <input\n className=\"field mono\"\n value={appId}\n onChange={(e) => setAppId(e.target.value)}\n placeholder=\"QQ Open Platform App ID\"\n />\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.qqAppSecret\")}</div>\n </div>\n <input\n className=\"field mono\"\n type=\"password\"\n value={appSecret}\n onChange={(e) => setAppSecret(e.target.value)}\n placeholder=\"QQ Open Platform App Secret\"\n />\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.qqEnvironment\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n <button type=\"button\" data-on={sandbox} onClick={() => setSandbox(true)}>\n {t(\"settings.qqSandbox\")}\n </button>\n <button type=\"button\" data-on={!sandbox} onClick={() => setSandbox(false)}>\n {t(\"settings.qqProduction\")}\n </button>\n </div>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.qqApplyLabel\")}</div>\n </div>\n <button type=\"button\" className=\"btn\" onClick={onOpenApplyLink}>\n {t(\"settings.qqApplyAction\")}\n </button>\n </div>\n <div className=\"qq-config-actions\">\n <button\n type=\"button\"\n className=\"btn\"\n onClick={() => {\n onSaveConfig(savePatch);\n onCloseConfigure();\n }}\n >\n {t(\"settings.qqSave\")}\n </button>\n <button\n type=\"button\"\n className=\"btn primary\"\n onClick={() => {\n onSaveAndConnect(savePatch);\n onCloseConfigure();\n }}\n >\n {t(\"settings.qqSaveAndConnect\")}\n </button>\n </div>\n </div>\n )}\n </section>\n );\n}\n\nfunction PageGeneral({\n settings,\n theme,\n themeStyle,\n onSetTheme,\n onSetThemeStyle,\n fontScale,\n onSetFontScale,\n fontFamily,\n onSetFontFamily,\n onSave,\n onPickWorkspace,\n}: {\n settings: SettingsType;\n theme: Theme;\n themeStyle: ThemeStyle;\n onSetTheme: (theme: Theme) => void;\n onSetThemeStyle: (style: ThemeStyle) => void;\n fontScale: FontScale;\n onSetFontScale: (scale: FontScale) => void;\n fontFamily: FontFamily;\n onSetFontFamily: (family: FontFamily) => void;\n onSave: (patch: SettingsPatch) => void;\n onPickWorkspace: () => void;\n}) {\n const [editorDraft, setEditorDraft] = useState(settings.editor ?? \"\");\n const lang = useLang();\n return (\n <>\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.appearanceSection\")}</div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.theme\")}</div>\n <div className=\"h\">{t(\"settings.themeHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n <button\n type=\"button\"\n data-on={theme === THEME.DARK}\n onClick={() => onSetTheme(THEME.DARK)}\n >\n {t(\"settings.themeDark\")}\n </button>\n <button\n type=\"button\"\n data-on={theme === THEME.LIGHT}\n onClick={() => onSetTheme(THEME.LIGHT)}\n >\n {t(\"settings.themeLight\")}\n </button>\n </div>\n </div>\n <div className=\"setting-row theme-style-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.themeStyle\")}</div>\n <div className=\"h\">{t(\"settings.themeStyleHint\")}</div>\n </div>\n <div className=\"style-grid\">\n {THEME_STYLES.map((style) => (\n <button\n key={style}\n type=\"button\"\n className=\"style-card\"\n data-on={themeStyle === style}\n data-style={style}\n onClick={() => onSetThemeStyle(style)}\n >\n <span className=\"style-card-head\">\n <span className=\"style-name\">\n {t(`settings.themeStyle${style[0]!.toUpperCase()}${style.slice(1)}` as any)}\n </span>\n <span className=\"style-mode\">\n {themeForStyle(style) === THEME.DARK\n ? t(\"settings.themeDark\")\n : t(\"settings.themeLight\")}\n </span>\n </span>\n <span className=\"style-swatches\" aria-hidden=\"true\">\n <span />\n <span />\n <span />\n </span>\n <span className=\"style-desc\">\n {t(`settings.themeStyle${style[0]!.toUpperCase()}${style.slice(1)}Desc` as any)}\n </span>\n </button>\n ))}\n </div>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.fontScale\")}</div>\n <div className=\"h\">{t(\"settings.fontScaleHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n <button\n type=\"button\"\n data-on={fontScale === FONT_SCALE.SMALL}\n onClick={() => onSetFontScale(FONT_SCALE.SMALL)}\n >\n {t(\"settings.fontScaleSmall\")}\n </button>\n <button\n type=\"button\"\n data-on={fontScale === FONT_SCALE.MEDIUM}\n onClick={() => onSetFontScale(FONT_SCALE.MEDIUM)}\n >\n {t(\"settings.fontScaleMedium\")}\n </button>\n <button\n type=\"button\"\n data-on={fontScale === FONT_SCALE.LARGE}\n onClick={() => onSetFontScale(FONT_SCALE.LARGE)}\n >\n {t(\"settings.fontScaleLarge\")}\n </button>\n </div>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.fontFamily\")}</div>\n <div className=\"h\">{t(\"settings.fontFamilyHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n <button\n type=\"button\"\n data-on={fontFamily === FONT_FAMILY.SANS}\n onClick={() => onSetFontFamily(FONT_FAMILY.SANS)}\n >\n {t(\"settings.fontFamilySans\")}\n </button>\n <button\n type=\"button\"\n data-on={fontFamily === FONT_FAMILY.SYSTEM}\n onClick={() => onSetFontFamily(FONT_FAMILY.SYSTEM)}\n >\n {t(\"settings.fontFamilySystem\")}\n </button>\n <button\n type=\"button\"\n data-on={fontFamily === FONT_FAMILY.SERIF}\n onClick={() => onSetFontFamily(FONT_FAMILY.SERIF)}\n >\n {t(\"settings.fontFamilySerif\")}\n </button>\n </div>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.language\")}</div>\n <div className=\"h\">{t(\"settings.languageHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n <button\n type=\"button\"\n data-on={lang === \"zh-CN\"}\n onClick={() => setLang(\"zh-CN\")}\n >\n {t(\"settings.langZhCn\")}\n </button>\n <button type=\"button\" data-on={lang === \"en\"} onClick={() => setLang(\"en\")}>\n {t(\"settings.langEn\")}\n </button>\n </div>\n </div>\n </section>\n\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.workspaceSection\")}</div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.currentWorkspace\")}</div>\n <div className=\"h\">{settings.workspaceDir || t(\"settings.notSelected\")}</div>\n </div>\n <button type=\"button\" className=\"btn\" onClick={onPickWorkspace}>\n {t(\"settings.workspaceChange\")}\n </button>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.editor\")}</div>\n <div className=\"h\">{t(\"settings.editorHint\")}</div>\n </div>\n <input\n className=\"field mono\"\n value={editorDraft}\n placeholder=\"cursor --goto\"\n onChange={(e) => setEditorDraft(e.target.value)}\n onBlur={() => onSave({ editor: editorDraft || undefined })}\n />\n </div>\n </section>\n\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.behaviorSection\")}</div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.reasoningEffort\")}</div>\n <div className=\"h\">{t(\"settings.reasoningEffortHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n {([\"low\", \"medium\", \"high\", \"max\"] as const).map((e) => (\n <button\n type=\"button\"\n key={e}\n data-on={settings.reasoningEffort === e}\n onClick={() => onSave({ reasoningEffort: e })}\n >\n {e}\n </button>\n ))}\n </div>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.editMode\")}</div>\n <div className=\"h\">{t(\"settings.editModeHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n {([\"review\", \"auto\", \"yolo\"] as const).map((m) => (\n <button\n type=\"button\"\n key={m}\n data-on={settings.editMode === m}\n onClick={() => onSave({ editMode: m })}\n >\n {m}\n </button>\n ))}\n </div>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.showSystemEvents\")}</div>\n <div className=\"h\">{t(\"settings.showSystemEventsHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n <button\n type=\"button\"\n data-on={settings.showSystemEvents !== false}\n onClick={() => onSave({ showSystemEvents: true })}\n >\n {t(\"settings.shown\")}\n </button>\n <button\n type=\"button\"\n data-on={settings.showSystemEvents === false}\n onClick={() => onSave({ showSystemEvents: false })}\n >\n {t(\"settings.hidden\")}\n </button>\n </div>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.budget\")}</div>\n <div className=\"h\">{t(\"settings.budgetHint\")}</div>\n </div>\n <input\n className=\"field\"\n type=\"number\"\n defaultValue={settings.budgetUsd ?? \"\"}\n placeholder={t(\"settings.budgetPlaceholder\")}\n onBlur={(e) => {\n const v = e.target.value.trim();\n onSave({ budgetUsd: v === \"\" ? null : Number(v) });\n }}\n />\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.webSearchEngine\")}</div>\n <div className=\"h\">{t(\"settings.webSearchEngineNote\")}</div>\n </div>\n <select\n className=\"field\"\n value={settings.webSearchEngine ?? \"bing\"}\n onChange={(e) =>\n onSave({\n webSearchEngine: e.target.value as\n | \"bing\"\n | \"searxng\"\n | \"metaso\"\n | \"tavily\"\n | \"perplexity\"\n | \"exa\",\n })\n }\n >\n <option value=\"bing\">{t(\"settings.webSearchEngineBing\")}</option>\n <option value=\"searxng\">{t(\"settings.webSearchEngineSearxng\")}</option>\n <option value=\"metaso\">{t(\"settings.webSearchEngineMetaso\")}</option>\n <option value=\"tavily\">{t(\"settings.webSearchEngineTavily\")}</option>\n <option value=\"perplexity\">{t(\"settings.webSearchEnginePerplexity\")}</option>\n <option value=\"exa\">{t(\"settings.webSearchEngineExa\")}</option>\n </select>\n </div>\n </section>\n </>\n );\n}\n\nfunction ApiKeySection({\n baseUrl,\n apiKeyPrefix,\n onSave,\n onSaveApiKey,\n}: {\n baseUrl?: string;\n apiKeyPrefix?: string;\n onSave: (patch: SettingsPatch) => void;\n onSaveApiKey: (key: string) => void;\n}) {\n const [key, setKey] = useState(\"\");\n const [urlDraft, setUrlDraft] = useState(baseUrl ?? \"\");\n return (\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.apiSection\")}</div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.apiKey\")}</div>\n <div className=\"h\">\n {apiKeyPrefix\n ? t(\"settings.apiKeySet\", { prefix: apiKeyPrefix })\n : t(\"settings.apiKeyNotSet\")}\n </div>\n </div>\n <div style={{ display: \"flex\", gap: 6 }}>\n <input\n className=\"field mono\"\n type=\"password\"\n value={key}\n onChange={(e) => setKey(e.target.value)}\n placeholder=\"sk-…\"\n />\n <button\n type=\"button\"\n className=\"btn primary\"\n disabled={!key}\n onClick={() => {\n if (!key) return;\n onSaveApiKey(key);\n setKey(\"\");\n }}\n >\n {t(\"settings.apiKeySave\")}\n </button>\n </div>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.baseUrl\")}</div>\n <div className=\"h\">{t(\"settings.baseUrlHint\")}</div>\n </div>\n <input\n className=\"field mono\"\n value={urlDraft}\n onChange={(e) => setUrlDraft(e.target.value)}\n onBlur={() => onSave({ baseUrl: urlDraft.trim() || undefined })}\n />\n </div>\n </section>\n );\n}\n\nconst KNOWN_MODELS = [\"deepseek-v4-flash\", \"deepseek-v4-pro\"] as const;\n\nconst EFFORT_VALUES = [\"low\", \"medium\", \"high\", \"max\"] as const;\ntype EffortValue = (typeof EFFORT_VALUES)[number];\n\nfunction PageModels({\n settings,\n onSave,\n}: {\n settings: SettingsType;\n onSave: (patch: SettingsPatch) => void;\n}) {\n const [draft, setDraft] = useState(settings.model);\n useEffect(() => setDraft(settings.model), [settings.model]);\n const isKnown = (KNOWN_MODELS as readonly string[]).includes(settings.model);\n return (\n <>\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.defaultModelCurrent\", { model: settings.model })}</div>\n <div className=\"model-grid\">\n {KNOWN_MODELS.map((id) => (\n <div\n key={id}\n className=\"mcard\"\n data-on={settings.model === id}\n onClick={() => onSave({ model: id })}\n >\n <div className=\"nm\">{id}</div>\n </div>\n ))}\n </div>\n <div className=\"setting-row\" style={{ marginTop: 12 }}>\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.modelCustom\")}</div>\n <div className=\"h\">{t(\"settings.modelCustomHint\")}</div>\n </div>\n <div style={{ display: \"flex\", gap: 6 }}>\n <input\n className=\"field mono\"\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n placeholder=\"deepseek-v4-flash\"\n />\n <button\n type=\"button\"\n className=\"btn primary\"\n disabled={!draft.trim() || draft.trim() === settings.model}\n onClick={() => onSave({ model: draft.trim() })}\n >\n {t(\"settings.apiKeySave\")}\n </button>\n </div>\n </div>\n {!isKnown ? (\n <div className=\"h\" style={{ marginTop: 6 }}>\n {t(\"settings.modelCustomActive\", { model: settings.model })}\n </div>\n ) : null}\n </section>\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.effortSection\")}</div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.reasoningEffort\")}</div>\n <div className=\"h\">{t(\"settings.reasoningEffortHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n {EFFORT_VALUES.map((e) => (\n <button\n type=\"button\"\n key={e}\n data-on={settings.reasoningEffort === e}\n onClick={() => onSave({ reasoningEffort: e as EffortValue })}\n >\n {e}\n </button>\n ))}\n </div>\n </div>\n </section>\n </>\n );\n}\n\nfunction PageMCP({\n specs,\n bridged,\n onAdd,\n onRemove,\n}: {\n specs: McpSpecInfo[];\n bridged: boolean;\n onAdd: (spec: string) => void;\n onRemove: (spec: string) => void;\n}) {\n const [draft, setDraft] = useState(\"\");\n const submit = () => {\n const v = draft.trim();\n if (!v) return;\n onAdd(v);\n setDraft(\"\");\n };\n return (\n <>\n <section className=\"section\">\n <div className=\"stitle\">\n {t(\"settings.mcpConfigured\", { count: specs.length })}\n {bridged ? (\n <span style={{ color: \"var(--accent)\", marginLeft: 8, fontSize: 11 }}>\n {t(\"settings.mcpBridged\")}\n </span>\n ) : (\n <span style={{ color: \"var(--muted)\", marginLeft: 8, fontSize: 11 }}>\n {t(\"settings.mcpNotBridged\")}\n </span>\n )}\n </div>\n {specs.length === 0 ? (\n <div\n style={{\n padding: 16,\n background: \"var(--card)\",\n border: \"1px solid var(--border)\",\n borderRadius: 10,\n fontSize: 12,\n color: \"var(--muted)\",\n }}\n >\n {t(\"settings.mcpEmpty\")}\n </div>\n ) : (\n specs.map((s) => (\n <div className=\"scard\" key={s.raw}>\n <div className=\"top\">\n <span className=\"ico\">\n <I.wrench size={14} />\n </span>\n <div>\n <div className=\"nm\">{s.name ?? \"(anonymous)\"}</div>\n <div className=\"sub\">{s.summary}</div>\n </div>\n <span className=\"grow\" />\n <button\n type=\"button\"\n className=\"btn ghost\"\n style={{ color: \"var(--danger)\" }}\n onClick={() => onRemove(s.raw)}\n >\n {t(\"settings.mcpRemove\")}\n </button>\n </div>\n {s.parseError ? (\n <div className=\"desc\" style={{ color: \"var(--danger)\" }}>\n {t(\"settings.parseError\", { error: s.parseError })}\n </div>\n ) : null}\n </div>\n ))\n )}\n </section>\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.mcpAddSection\")}</div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.mcpSpecLabel\")}</div>\n <div className=\"h\" dangerouslySetInnerHTML={{ __html: t(\"settings.mcpSpecFormat\") }} />\n </div>\n <div style={{ display: \"flex\", gap: 6 }}>\n <input\n className=\"field mono\"\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n placeholder=\"github=npx -y @smithery/cli ...\"\n onKeyDown={(e) => {\n if (e.key === \"Enter\") submit();\n }}\n />\n <button type=\"button\" className=\"btn primary\" disabled={!draft.trim()} onClick={submit}>\n {t(\"settings.mcpAdd\")}\n </button>\n </div>\n </div>\n </section>\n </>\n );\n}\n\nfunction PageSkills({\n skills,\n subagentModels,\n onSave,\n}: {\n skills: SkillInfo[];\n subagentModels: Record<string, \"flash\" | \"pro\">;\n onSave: (patch: SettingsPatch) => void;\n}) {\n const setSubagentModel = (name: string, value: \"flash\" | \"pro\") => {\n onSave({ subagentModels: { ...subagentModels, [name]: value } });\n };\n return (\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.skillsLoaded\", { count: skills.length })}</div>\n {skills.length === 0 ? (\n <div\n style={{\n padding: 16,\n background: \"var(--card)\",\n border: \"1px solid var(--border)\",\n borderRadius: 10,\n fontSize: 12,\n color: \"var(--muted)\",\n }}\n >\n {t(\"settings.skillsEmpty\")}\n </div>\n ) : (\n skills.map((s) => (\n <div className=\"scard\" key={`${s.scope}:${s.name}`}>\n <div className=\"top\">\n <span className=\"ico\">\n <I.zap size={14} />\n </span>\n <div>\n <div className=\"nm\">\n <span\n style={{\n fontFamily: \"Geist Mono, monospace\",\n color: \"var(--accent)\",\n }}\n >\n /{s.name}\n </span>\n </div>\n <div className=\"sub\">\n {s.scope} · {s.runAs}\n {s.model ? ` · ${s.model}` : \"\"}\n </div>\n </div>\n {s.runAs === \"subagent\" ? (\n <select\n className=\"field\"\n style={{ marginLeft: \"auto\", minWidth: 96 }}\n value={subagentModels[s.name] ?? \"flash\"}\n onChange={(e) =>\n setSubagentModel(s.name, e.target.value as \"flash\" | \"pro\")\n }\n title={t(\"settings.subagentModelHint\")}\n >\n <option value=\"flash\">{t(\"settings.subagentModelFlash\")}</option>\n <option value=\"pro\">{t(\"settings.subagentModelPro\")}</option>\n </select>\n ) : null}\n </div>\n <div className=\"desc\">{s.description}</div>\n <div\n style={{\n fontFamily: \"Geist Mono, monospace\",\n fontSize: 10.5,\n color: \"var(--muted-2)\",\n marginTop: 4,\n }}\n >\n {s.path}\n </div>\n </div>\n ))\n )}\n </section>\n );\n}\n\nfunction PageMemory() {\n return (\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.memorySection\")}</div>\n <div\n style={{\n padding: 16,\n background: \"var(--card)\",\n border: \"1px solid var(--border)\",\n borderRadius: 10,\n fontSize: 12,\n color: \"var(--muted)\",\n }}\n >\n {t(\"settings.memoryDesc\")}\n </div>\n </section>\n );\n}\n\nfunction PageRules({\n settings,\n onSave,\n}: {\n settings: SettingsType;\n onSave: (patch: SettingsPatch) => void;\n}) {\n return (\n <>\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.editMode\")}</div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.appMode\")}</div>\n <div className=\"h\">{t(\"settings.editModeHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n {([\"review\", \"auto\", \"yolo\"] as const).map((m) => (\n <button\n type=\"button\"\n key={m}\n data-on={settings.editMode === m}\n onClick={() => onSave({ editMode: m })}\n >\n {m}\n </button>\n ))}\n </div>\n </div>\n </section>\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.ruleAutoApprovalSection\")}</div>\n <div\n style={{\n padding: 12,\n background: \"var(--card)\",\n border: \"1px solid var(--border)\",\n borderRadius: 10,\n fontSize: 12,\n color: \"var(--muted)\",\n }}\n >\n {t(\"settings.ruleAutoApprovalHint\")}\n </div>\n </section>\n </>\n );\n}\n\nfunction PageBilling({\n balance,\n usage,\n currency,\n}: {\n balance: Balance | null;\n usage: UsageStats;\n currency: \"CNY\" | \"USD\";\n}) {\n const symbol = currency === \"CNY\" ? \"¥\" : \"$\";\n const sessionCost = currency === \"CNY\" ? usage.totalCostUsd * 7.2 : usage.totalCostUsd;\n const totalTokens = usage.cacheHitTokens + usage.cacheMissTokens;\n const hitPct = totalTokens > 0 ? Math.round((usage.cacheHitTokens / totalTokens) * 100) : 0;\n return (\n <>\n <div className=\"bill-grid\">\n <div className=\"bill-card\">\n <div className=\"l\">{t(\"settings.balanceLabel\")}</div>\n <div className=\"v ok\">\n {balance\n ? `${balance.currency === \"USD\" ? \"$\" : \"¥\"} ${balance.total.toFixed(2)}`\n : \"—\"}\n </div>\n <div className=\"sub\">\n {balance && !balance.isAvailable\n ? t(\"settings.balanceLow\")\n : t(\"settings.balanceAvailable\")}\n </div>\n </div>\n <div className=\"bill-card\">\n <div className=\"l\">{t(\"settings.sessionCost\")}</div>\n <div className=\"v\">\n {symbol} {sessionCost.toFixed(4)}\n </div>\n <div className=\"sub\">prompt {usage.totalPromptTokens.toLocaleString()} t</div>\n </div>\n <div className=\"bill-card\">\n <div className=\"l\">{t(\"settings.cacheHitRate\")}</div>\n <div className=\"v acc\">{hitPct}%</div>\n <div className=\"sub\">\n hit {usage.cacheHitTokens.toLocaleString()} / miss{\" \"}\n {usage.cacheMissTokens.toLocaleString()}\n </div>\n </div>\n </div>\n </>\n );\n}\n\nfunction PageShortcuts() {\n const rows: { nm: string; keys: ShortcutKey[] }[] = [\n { nm: t(\"settings.shortcutNewChat\"), keys: [\"mod\", \"N\"] },\n { nm: t(\"settings.shortcutNewTab\"), keys: [\"mod\", \"T\"] },\n { nm: t(\"settings.shortcutCloseTab\"), keys: [\"mod\", \"W\"] },\n { nm: t(\"settings.shortcutCommandPalette\"), keys: [\"mod\", \"K\"] },\n { nm: t(\"settings.shortcutFocusComposer\"), keys: [\"mod\", \"L\"] },\n { nm: t(\"settings.shortcutSwitchTab\"), keys: [\"mod\", \"tab\"] },\n { nm: t(\"settings.shortcutAbort\"), keys: [\"esc\"] },\n { nm: t(\"settings.shortcutSettings\"), keys: [\"mod\", \",\"] },\n ];\n return (\n <section className=\"section\">\n <div className=\"kbd-grid\">\n {rows.map((s, i) => (\n <SectionRow key={i} nm={s.nm} keys={s.keys} />\n ))}\n </div>\n </section>\n );\n}\n\nfunction SectionRow({ nm, keys }: { nm: string; keys: ShortcutKey[] }): ReactNode {\n return (\n <>\n <div className=\"nm\">{nm}</div>\n <div className=\"keys\">\n <Shortcut keys={keys} />\n </div>\n </>\n );\n}\n","import { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport type { SessionInfo } from \"../App\";\nimport { t, useLang } from \"../i18n\";\nimport { I } from \"../icons\";\nimport { Shortcut } from \"./shortcut\";\n\ntype PendingDelete = {\n name: string;\n pretty: string;\n x: number;\n y: number;\n};\n\nfunction prettyName(s: SessionInfo): string {\n if (s.summary && s.summary.trim()) return s.summary.trim();\n const m = s.name.match(/^desktop-(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(?:-(\\d+))?$/);\n if (m) {\n const [, , month, day, hh, mm, tab] = m;\n return `${t(\"sidebarPanel.sessionTitle\", {\n month,\n day,\n hour: hh,\n minute: mm,\n })}${tab && tab !== \"1\" ? ` · #${tab}` : \"\"}`;\n }\n return s.name.replace(/^desktop-/, \"\").replace(/[-_]+/g, \" \");\n}\n\nfunction relative(ms: number): string {\n const min = ms / 60_000;\n if (min < 1) return t(\"sidebarPanel.justNow\");\n if (min < 60) return t(\"sidebarPanel.minutesAgo\", { n: Math.floor(min) });\n const hr = min / 60;\n if (hr < 24) return t(\"sidebarPanel.hoursAgo\", { n: Math.floor(hr) });\n const d = hr / 24;\n if (d < 7) return t(\"sidebarPanel.daysAgo\", { n: Math.floor(d) });\n return t(\"sidebarPanel.weeksAgo\", { n: Math.floor(d / 7) });\n}\n\nexport function Sidebar({\n sessions,\n activeName,\n loadingName,\n onNewChat,\n onLoadSession,\n onDeleteSession,\n onOpenSettings,\n onOpenRules,\n onOpenCommands,\n onOpenAbout,\n}: {\n sessions: SessionInfo[];\n activeName?: string;\n /** Name of the session currently being loaded — drives the per-row spinner. */\n loadingName?: string | null;\n onNewChat: () => void;\n onLoadSession: (name: string) => void;\n onDeleteSession: (name: string) => void;\n onOpenSettings: () => void;\n onOpenRules: () => void;\n onOpenCommands: () => void;\n onOpenAbout: () => void;\n}) {\n useLang();\n const [query, setQuery] = useState(\"\");\n const [pendingDelete, setPendingDelete] = useState<PendingDelete | null>(null);\n const filtered = query\n ? sessions.filter((s) => {\n const q = query.toLowerCase();\n return (\n prettyName(s).toLowerCase().includes(q) || s.name.toLowerCase().includes(q)\n );\n })\n : sessions;\n\n useEffect(() => {\n if (!pendingDelete) return;\n const onMouseDown = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null;\n if (!target?.closest(\".session-delete-popover\")) setPendingDelete(null);\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setPendingDelete(null);\n };\n window.addEventListener(\"mousedown\", onMouseDown);\n window.addEventListener(\"keydown\", onKey);\n return () => {\n window.removeEventListener(\"mousedown\", onMouseDown);\n window.removeEventListener(\"keydown\", onKey);\n };\n }, [pendingDelete]);\n\n return (\n <aside className=\"sidebar\">\n <div className=\"side-head\">\n <button type=\"button\" className=\"new-btn\" onClick={onNewChat}>\n <I.plus size={14} />\n <span>{t(\"sidebarPanel.newChat\")}</span>\n <Shortcut keys={[\"mod\", \"N\"]} />\n </button>\n <button\n type=\"button\"\n className=\"icon-btn\"\n title={t(\"sidebarPanel.commandPalette\")}\n onClick={onOpenCommands}\n >\n <I.history size={14} />\n </button>\n </div>\n\n <div className=\"search-row\">\n <div className=\"input\">\n <I.search size={13} />\n <input\n placeholder={t(\"sidebarPanel.searchSessions\")}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n />\n <Shortcut keys={[\"mod\", \"K\"]} />\n </div>\n </div>\n\n <div className=\"session-list\">\n <div className=\"side-section\">\n <div className=\"label\">\n <span>{t(\"sidebarPanel.recent\")}</span>\n <span className=\"count\">{filtered.length}</span>\n </div>\n {sessions.length === 0 ? (\n <div\n style={{\n padding: \"12px 8px\",\n fontSize: 11,\n color: \"var(--muted-2)\",\n fontFamily: \"Geist Mono, monospace\",\n }}\n >\n {t(\"sidebarPanel.noSessions\")}\n </div>\n ) : filtered.length === 0 ? (\n <div\n style={{\n padding: \"12px 8px\",\n fontSize: 11,\n color: \"var(--muted-2)\",\n fontFamily: \"Geist Mono, monospace\",\n }}\n >\n {t(\"sidebarPanel.noMatches\")}\n </div>\n ) : null}\n {filtered.map((s) => {\n const active = s.name === activeName;\n const loading = s.name === loadingName;\n const mtime = Date.parse(s.mtime);\n const updated = Number.isFinite(mtime) ? relative(Date.now() - mtime) : s.mtime;\n return (\n <div\n key={s.name}\n className=\"session-item\"\n data-active={active}\n data-loading={loading || undefined}\n style={loadingName && !loading ? { opacity: 0.5, pointerEvents: \"none\" } : undefined}\n onClick={() => onLoadSession(s.name)}\n role=\"button\"\n tabIndex={0}\n title={s.name}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") onLoadSession(s.name);\n }}\n >\n <span\n className=\"state\"\n style={{\n background: loading\n ? \"var(--accent)\"\n : active\n ? \"var(--accent)\"\n : \"var(--border-strong)\",\n animation: loading ? \"session-pulse 0.9s ease-in-out infinite\" : undefined,\n }}\n />\n <div className=\"body\">\n <span className=\"title\">{prettyName(s)}</span>\n <span className=\"meta\">\n {loading ? (\n <span>{t(\"sidebarPanel.loading\")}</span>\n ) : (\n <>\n <span>{t(\"sidebarPanel.messageCount\", { count: s.messageCount })}</span>\n <span className=\"sep\">·</span>\n <span>{updated}</span>\n </>\n )}\n </span>\n </div>\n <button\n type=\"button\"\n className=\"delete-btn\"\n title={t(\"sidebarPanel.deleteSession\")}\n aria-label={t(\"sidebarPanel.deleteSession\")}\n onClick={(e) => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n setPendingDelete({\n name: s.name,\n pretty: prettyName(s),\n x: rect.right,\n y: rect.bottom,\n });\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") e.stopPropagation();\n }}\n >\n <I.x size={12} />\n </button>\n </div>\n );\n })}\n </div>\n </div>\n\n <div className=\"side-foot\">\n <div className=\"row\" onClick={onOpenRules}>\n <span className=\"ico\">\n <I.shield size={13} />\n </span>\n <span>{t(\"sidebarPanel.approvalRules\")}</span>\n </div>\n <div className=\"row\" onClick={onOpenAbout}>\n <span className=\"ico\">\n <I.help size={13} />\n </span>\n <span>{t(\"about.sidebarLabel\")}</span>\n </div>\n <div className=\"row\" onClick={onOpenSettings}>\n <span className=\"ico\">\n <I.cog size={13} />\n </span>\n <span>{t(\"sidebarPanel.settings\")}</span>\n <span className=\"right\">\n <Shortcut keys={[\"mod\", \",\"]} />\n </span>\n </div>\n </div>\n\n {pendingDelete ? (\n <SessionDeletePopover\n target={pendingDelete}\n onCancel={() => setPendingDelete(null)}\n onConfirm={() => {\n onDeleteSession(pendingDelete.name);\n setPendingDelete(null);\n }}\n />\n ) : null}\n </aside>\n );\n}\n\nfunction SessionDeletePopover({\n target,\n onCancel,\n onConfirm,\n}: {\n target: PendingDelete;\n onCancel: () => void;\n onConfirm: () => void;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const cancelRef = useRef<HTMLButtonElement>(null);\n const [pos, setPos] = useState<{ left: number; top: number }>({\n left: target.x,\n top: target.y,\n });\n\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n const pad = 8;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n let left = target.x;\n let top = target.y;\n if (left + rect.width + pad > vw) left = Math.max(pad, vw - rect.width - pad);\n if (top + rect.height + pad > vh) top = Math.max(pad, vh - rect.height - pad);\n if (left !== pos.left || top !== pos.top) setPos({ left, top });\n cancelRef.current?.focus();\n }, [target.x, target.y, pos.left, pos.top]);\n\n return (\n <div\n ref={ref}\n className=\"session-delete-popover\"\n role=\"dialog\"\n aria-modal=\"true\"\n style={{ left: pos.left, top: pos.top }}\n >\n <div className=\"msg\">\n {t(\"sidebarPanel.deleteSession\")}\n <span className=\"name\">{target.pretty}</span>\n </div>\n <div className=\"actions\">\n <button ref={cancelRef} type=\"button\" className=\"cancel\" onClick={onCancel}>\n {t(\"sidebarPanel.cancel\")}\n </button>\n <button type=\"button\" className=\"confirm\" onClick={onConfirm}>\n <I.x size={11} />\n {t(\"sidebarPanel.delete\")}\n </button>\n </div>\n </div>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { t } from \"../i18n\";\n\nconst SPLASH_FLAG = \"reasonix.splash.shown\";\n\nexport function shouldShowSplash(): boolean {\n try {\n return sessionStorage.getItem(SPLASH_FLAG) !== \"1\";\n } catch {\n return true;\n }\n}\n\nfunction markSplashShown() {\n try {\n sessionStorage.setItem(SPLASH_FLAG, \"1\");\n } catch {\n /* sessionStorage unavailable */\n }\n}\n\nexport function Splash({ onDone }: { onDone: () => void }) {\n const [leaving, setLeaving] = useState(false);\n const onDoneRef = useRef(onDone);\n onDoneRef.current = onDone;\n\n useEffect(() => {\n const t1 = window.setTimeout(() => setLeaving(true), 1350);\n const t2 = window.setTimeout(() => {\n markSplashShown();\n onDoneRef.current();\n }, 1800);\n return () => {\n window.clearTimeout(t1);\n window.clearTimeout(t2);\n };\n }, []);\n\n useEffect(() => {\n const skip = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\" && e.key !== \"Enter\" && e.key !== \" \") return;\n markSplashShown();\n onDoneRef.current();\n };\n window.addEventListener(\"keydown\", skip);\n return () => window.removeEventListener(\"keydown\", skip);\n }, []);\n\n const skipClick = () => {\n markSplashShown();\n onDone();\n };\n\n return (\n <div className=\"splash\" data-leaving={leaving} onClick={skipClick}>\n <div className=\"splash-card\">\n <div className=\"splash-mark\" />\n <div className=\"splash-name\">Reasonix</div>\n <div className=\"splash-sub\">{t(\"app.splashSubtitle\")}</div>\n <div className=\"splash-dots\">\n <span />\n <span />\n <span />\n </div>\n </div>\n </div>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { I } from \"../icons\";\nimport { t } from \"../i18n\";\nimport type { Balance, Settings, UsageStats } from \"../App\";\nimport type { JobInfo } from \"../protocol\";\nimport { THEME, THEME_STYLES, type Theme, type ThemeStyle, themeForStyle } from \"../theme\";\nimport { localizeShortcutText } from \"./shortcut\";\n\nconst USD_TO_CNY = 7.2;\n\nfunction formatMoney(amountUsd: number, currency: \"CNY\" | \"USD\"): string {\n const symbol = currency === \"CNY\" ? \"¥\" : \"$\";\n const amount = currency === \"CNY\" ? amountUsd * USD_TO_CNY : amountUsd;\n return `${symbol} ${amount.toFixed(4)}`;\n}\n\nfunction tokenLabel(n: number): string {\n if (n >= 1000) return `${(n / 1000).toFixed(1)}k`;\n return `${n}`;\n}\n\nexport function StatusBar({\n settings,\n balance,\n usage,\n busy,\n ready,\n currency,\n theme,\n themeStyle,\n jobs,\n jobsOpen,\n onToggleJobs,\n onSetThemeStyle,\n onToggleCurrency,\n onOpenSettings,\n onOpenWorkdir,\n}: {\n settings: Settings | null;\n balance: Balance | null;\n usage: UsageStats;\n busy: boolean;\n ready: boolean;\n currency: \"CNY\" | \"USD\";\n theme: Theme;\n themeStyle: ThemeStyle;\n jobs: JobInfo[];\n jobsOpen: boolean;\n onToggleJobs: () => void;\n onSetThemeStyle: (style: ThemeStyle) => void;\n onToggleCurrency: () => void;\n onOpenSettings: () => void;\n onOpenWorkdir?: (anchor: { bottom: number; left: number }) => void;\n}) {\n const totalTokens = usage.cacheHitTokens + usage.cacheMissTokens;\n const cacheHitPct = totalTokens > 0 ? Math.round((usage.cacheHitTokens / totalTokens) * 100) : 0;\n const runningJobs = jobs.filter((j) => j.running).length;\n const spent = formatMoney(usage.totalCostUsd, currency);\n const balanceLabel = balance\n ? `${balance.currency === \"USD\" ? \"$\" : \"¥\"} ${balance.total.toFixed(2)}`\n : \"—\";\n const connState = !ready ? \"off\" : busy ? \"running\" : \"online\";\n const [themeOpen, setThemeOpen] = useState(false);\n const themePopRef = useRef<HTMLDivElement | null>(null);\n const themeButtonRef = useRef<HTMLSpanElement | null>(null);\n\n useEffect(() => {\n if (!themeOpen) return;\n const onPointerDown = (event: PointerEvent) => {\n const target = event.target as Node;\n if (themePopRef.current?.contains(target) || themeButtonRef.current?.contains(target)) return;\n setThemeOpen(false);\n };\n window.addEventListener(\"pointerdown\", onPointerDown);\n return () => window.removeEventListener(\"pointerdown\", onPointerDown);\n }, [themeOpen]);\n\n return (\n <footer className=\"statusbar\">\n <span className=\"seg\" title={`API · ${settings?.baseUrl ?? \"api.deepseek.com\"}`}>\n <span\n className={connState === \"off\" ? \"sw warn\" : \"sw\"}\n style={connState === \"off\" ? { background: \"var(--danger)\" } : undefined}\n />\n <span>{settings?.baseUrl?.replace(/^https?:\\/\\//, \"\") ?? \"api.deepseek.com\"}</span>\n <span className=\"v\">{!ready ? t(\"statusbar.offline\") : busy ? t(\"statusbar.busy\") : t(\"statusbar.online\")}</span>\n </span>\n <span className=\"seg\" title={t(\"statusbar.cacheHit\")}>\n <I.zap size={11} style={{ color: \"var(--accent)\" }} />\n <span>{t(\"statusbar.cache\")}</span>\n <span className=\"v acc\">{cacheHitPct}%</span>\n </span>\n <span className=\"seg\">\n <I.cpu size={11} />\n <span>{t(\"statusbar.tokens\")}</span>\n <span className=\"v\">{tokenLabel(totalTokens)}</span>\n </span>\n <span className=\"seg\">\n <I.coin size={11} />\n <span>{t(\"statusbar.thisTurn\")}</span>\n <span className=\"v ok\">{spent}</span>\n </span>\n\n <span className=\"grow\" />\n\n <span\n className={`seg jobs ${jobsOpen ? \"active\" : \"\"}`}\n onClick={onToggleJobs}\n title={localizeShortcutText(t(\"statusbar.jobsTip\"))}\n >\n <I.cpu size={11} />\n <span>{t(\"statusbar.jobs\")}</span>\n <span className={runningJobs > 0 ? \"v acc\" : \"v\"}>{runningJobs}</span>\n </span>\n\n {settings?.workspaceDir ? (\n <span\n className=\"seg\"\n title={t(\"statusbar.switchWorkspace\", { workspace: settings.workspaceDir })}\n style={onOpenWorkdir ? { cursor: \"pointer\" } : undefined}\n onClick={(e) => {\n if (!onOpenWorkdir) return;\n const r = (e.currentTarget as HTMLElement).getBoundingClientRect();\n onOpenWorkdir({ bottom: window.innerHeight - r.top + 6, left: r.left });\n }}\n >\n <I.folder size={11} />\n <span className=\"v\">{settings.workspaceDir.split(/[\\\\/]/).pop() || \"ws\"}</span>\n </span>\n ) : null}\n <span\n className=\"seg\"\n title={`model · effort ${settings?.reasoningEffort ?? \"high\"}`}\n onClick={onOpenSettings}\n >\n <I.brain size={11} style={{ color: \"var(--violet)\" }} />\n <span className=\"v vio\">{settings?.model ?? \"—\"}</span>\n <span className=\"v\">{settings?.reasoningEffort ?? \"high\"}</span>\n </span>\n <span className=\"seg\" title={t(\"statusbar.switchCurrency\")} onClick={onToggleCurrency}>\n <I.coin size={11} />\n <span>{t(\"statusbar.balance\")}</span>\n <span className=\"v ok\">{balanceLabel}</span>\n </span>\n <span\n ref={themeButtonRef}\n className={`seg theme-trigger ${themeOpen ? \"active\" : \"\"}`}\n title={t(\"statusbar.switchTheme\")}\n onClick={() => setThemeOpen((open) => !open)}\n >\n {theme === THEME.DARK ? <I.moon size={11} /> : <I.sun size={11} />}\n <span className=\"v\">\n {t(`statusbar.themeStyle${themeStyle[0]!.toUpperCase()}${themeStyle.slice(1)}` as any)}\n </span>\n </span>\n {themeOpen ? (\n <div ref={themePopRef} className=\"theme-pop\" role=\"menu\" aria-label={t(\"settings.themeStyle\")}>\n <div className=\"theme-pop-head\">\n <div className=\"tt\">{t(\"settings.themeStyle\")}</div>\n <div className=\"ss\">{t(\"statusbar.switchTheme\")}</div>\n </div>\n <div className=\"theme-pop-list\">\n {THEME_STYLES.map((style) => (\n <button\n key={style}\n type=\"button\"\n className=\"theme-pop-item\"\n data-on={themeStyle === style}\n data-style={style}\n onClick={() => {\n onSetThemeStyle(style);\n setThemeOpen(false);\n }}\n >\n <span className=\"style-swatches\" aria-hidden=\"true\">\n <span />\n <span />\n <span />\n </span>\n <span className=\"txt\">\n <span className=\"nm\">\n {t(`statusbar.themeStyle${style[0]!.toUpperCase()}${style.slice(1)}` as any)}\n </span>\n <span className=\"md\">\n {themeForStyle(style) === THEME.DARK\n ? t(\"statusbar.themeDark\")\n : t(\"statusbar.themeLight\")}\n </span>\n </span>\n {themeStyle === style ? <I.check size={13} /> : null}\n </button>\n ))}\n </div>\n </div>\n ) : null}\n </footer>\n );\n}\n","/** Prefix the context-manager prepends when fold replaces older turns with a synthesized recap.\n * Single-sourced here so the agent producer (src/context-manager) and the three UI surfaces\n * (TUI, Desktop, Dashboard) all agree on the wire string. */\nexport const COMPACTION_SUMMARY_MARKER =\n \"[CONVERSATION HISTORY SUMMARY — earlier turns folded for context efficiency]\\n\\n\";\n\nexport function isCompactionSummary(text: string | null | undefined): boolean {\n return typeof text === \"string\" && text.startsWith(COMPACTION_SUMMARY_MARKER);\n}\n\nexport function stripCompactionMarker(text: string): string {\n return text.startsWith(COMPACTION_SUMMARY_MARKER)\n ? text.slice(COMPACTION_SUMMARY_MARKER.length)\n : text;\n}\n","/** First two tokens for known wrappers (`npm install`, `git commit`, …); else first token only.\n * Used by the \"always allow\" permission gate so that `npm test` and `npm run build`\n * share one prefix, while `cargo` and `ls` stay single-token.\n *\n * This function is duplicated in ≥2 build targets (CLI + Desktop), so it lives\n * in `@reasonix/core-utils` to prevent drift like issue #1180. */\nexport function derivePrefix(command: string): string {\n const tokens = command.trim().split(/\\s+/).filter(Boolean);\n if (tokens.length === 0) return \"\";\n if (tokens.length === 1) return tokens[0]!;\n const first = tokens[0]!;\n const TWO_TOKEN_WRAPPERS = new Set([\n \"npm\",\n \"npx\",\n \"pnpm\",\n \"yarn\",\n \"bun\",\n \"git\",\n \"cargo\",\n \"go\",\n \"docker\",\n \"kubectl\",\n \"python\",\n \"python3\",\n \"deno\",\n \"pip\",\n \"pip3\",\n \"make\",\n \"rake\",\n \"bundle\",\n \"gem\",\n ]);\n return TWO_TOKEN_WRAPPERS.has(first) ? `${first} ${tokens[1]}` : first;\n}\n","import { memo, useState, type ReactNode } from \"react\";\nimport { I } from \"../icons\";\nimport { Markdown } from \"../Markdown\";\nimport { t, useLang } from \"../i18n\";\nimport { Shortcut } from \"./shortcut\";\n\ntype Tone = \"default\" | \"success\" | \"warning\" | \"danger\" | \"accent\" | \"violet\";\n\nexport function Card({\n tone = \"default\",\n icon,\n kind,\n name,\n meta,\n defaultOpen = true,\n compact = false,\n children,\n headRight,\n}: {\n tone?: Tone;\n icon: ReactNode;\n kind: string;\n name?: ReactNode;\n meta?: ReactNode;\n defaultOpen?: boolean;\n /** Slimmer header — used for thinking / tool-call process cards so they\n * read as background detail rather than primary content. */\n compact?: boolean;\n children: ReactNode;\n headRight?: ReactNode;\n}) {\n const [open, setOpen] = useState(defaultOpen);\n return (\n <div className={compact ? \"card is-compact\" : \"card\"} data-tone={tone} data-open={open}>\n <button\n type=\"button\"\n className=\"card-head\"\n onClick={() => setOpen((v) => !v)}\n style={{\n width: \"100%\",\n background: \"none\",\n border: \"none\",\n textAlign: \"left\",\n font: \"inherit\",\n color: \"inherit\",\n }}\n >\n <span className=\"ico\">{icon}</span>\n <span className=\"kind\">{kind}</span>\n {name ? <span className=\"name\">{name}</span> : null}\n <span className=\"grow\" />\n {meta ? <span className=\"meta\">{meta}</span> : null}\n {headRight}\n <span className=\"chev\">\n <I.chev size={12} />\n </span>\n </button>\n {open ? <div className=\"card-body\">{children}</div> : null}\n </div>\n );\n}\n\n// ---- Plan ----\n\nexport type PlanItem = {\n id: string | number;\n status: \"todo\" | \"active\" | \"done\" | \"failed\" | \"blocked\" | \"skipped\";\n text: string;\n tool?: string;\n note?: string;\n};\n\nfunction derivePlanBadge(items: PlanItem[]): { state: \"running\" | \"done\" | \"failed\" | \"waiting\" | \"blocked\"; label: string } {\n if (items.some((x) => x.status === \"failed\")) return { state: \"failed\", label: t(\"planBadge.failed\") };\n if (items.some((x) => x.status === \"blocked\")) return { state: \"blocked\", label: t(\"planBadge.blocked\") };\n if (items.some((x) => x.status === \"active\")) return { state: \"running\", label: t(\"planBadge.running\") };\n if (items.length > 0 && items.every((x) => x.status === \"done\")) return { state: \"done\", label: t(\"planBadge.done\") };\n return { state: \"waiting\", label: t(\"planBadge.pending\") };\n}\n\nfunction StatusIcon({ state, label }: { state: \"running\" | \"done\" | \"failed\" | \"waiting\" | \"blocked\"; label: string }) {\n switch (state) {\n case \"running\":\n return <span className=\"spin-meta\" role=\"img\" aria-label={label} title={label} />;\n case \"done\":\n return <I.check size={10} style={{ color: \"var(--success)\" }} aria-label={label} />;\n case \"failed\":\n return <I.x size={10} style={{ color: \"var(--danger)\" }} aria-label={label} />;\n case \"waiting\":\n return <span className=\"status-dot warn\" role=\"img\" aria-label={label} title={label} />;\n case \"blocked\":\n return <I.slash size={10} style={{ color: \"var(--warning)\" }} aria-label={label} />;\n }\n}\n\nexport function PlanCardView({ items, title }: { items: PlanItem[]; title?: string }) {\n useLang();\n const resolvedTitle = title ?? t(\"cards.planDefaultTitle\");\n const done = items.filter((x) => x.status === \"done\").length;\n const badge = derivePlanBadge(items);\n return (\n <Card\n tone=\"accent\"\n icon={<I.list size={12} />}\n kind=\"plan\"\n name={resolvedTitle}\n meta={\n <>\n <span>\n {done}/{items.length}\n </span>\n <StatusIcon state={badge.state} label={badge.label} />\n <span className=\"meta-label\">{badge.label}</span>\n </>\n }\n >\n <ul className=\"plan-list\" style={{ listStyle: \"none\", margin: 0, padding: \"8px 12px 12px\" }}>\n {items.map((it) => (\n <li key={it.id} className=\"plan-item\" data-status={it.status}>\n <span className=\"ck\">{it.status === \"done\" ? <I.check size={12} /> : null}</span>\n <div>\n <div className=\"text\">{it.text}</div>\n {it.tool || it.note ? (\n <div className=\"sub\">\n {it.tool ? <span className=\"tool\">{it.tool}</span> : null}\n {it.note ? <span>{it.note}</span> : null}\n </div>\n ) : null}\n </div>\n <span className=\"stat\">{it.status === \"active\" ? <span className=\"spin\" /> : null}</span>\n </li>\n ))}\n </ul>\n </Card>\n );\n}\n\n// ---- Reasoning ----\n\nexport function ReasoningCard({\n text,\n streaming,\n tokens,\n elapsed,\n model,\n}: {\n text: string;\n streaming: boolean;\n tokens?: number;\n elapsed?: string;\n model?: string;\n}) {\n useLang();\n return (\n <Card\n tone=\"violet\"\n icon={<I.brain size={12} />}\n kind=\"reasoning\"\n name={t(\"cards.reasoningName\")}\n meta={\n <>\n {elapsed || tokens ? (\n <span>\n {elapsed ?? \"\"}\n {elapsed && tokens ? \" · \" : \"\"}\n {tokens ? `${tokens.toLocaleString()} t` : \"\"}\n </span>\n ) : null}\n {streaming ? (\n <StatusIcon state=\"running\" label={t(\"cards.streaming\")} />\n ) : (\n <StatusIcon state=\"done\" label={t(\"cards.reasoningComplete\")} />\n )}\n </>\n }\n defaultOpen={streaming}\n compact\n >\n <div className=\"reason\">\n <div className=\"stream\">\n {text.split(/\\n\\n+/).map((para, i) => (\n <p\n key={i}\n dangerouslySetInnerHTML={{\n __html: para\n .replace(/`([^`]+)`/g, '<span class=\"hl\">$1</span>')\n .replace(/\\*\\*([^*]+)\\*\\*/g, \"<strong>$1</strong>\"),\n }}\n />\n ))}\n </div>\n {model || tokens !== undefined ? (\n <div className=\"meta\">\n {model ? (\n <span>\n <span className=\"k\">{t(\"settings.model\")}</span> {model}\n </span>\n ) : null}\n {tokens !== undefined ? (\n <span>\n <span className=\"k\">{t(\"statusbar.tokens\")}</span> {tokens.toLocaleString()}\n </span>\n ) : null}\n </div>\n ) : null}\n </div>\n </Card>\n );\n}\n\n// ---- Shell ----\n\nexport function ShellCard({\n command,\n output,\n state,\n durationMs,\n onApprove,\n onReject,\n onAlwaysAllow,\n}: {\n command: string;\n output?: string;\n state: \"await\" | \"running\" | \"done\" | \"failed\";\n durationMs?: number;\n onApprove?: () => void;\n onReject?: () => void;\n onAlwaysAllow?: () => void;\n}) {\n useLang();\n const tone: Tone = state === \"failed\" ? \"danger\" : state === \"done\" ? \"success\" : \"warning\";\n return (\n <Card\n tone={tone}\n icon={<I.terminal size={12} />}\n kind=\"shell\"\n name=\"shell\"\n compact\n meta={\n <>\n {state === \"await\" ? (\n <StatusIcon state=\"waiting\" label={t(\"cards.shellAwaiting\")} />\n ) : state === \"running\" ? (\n <StatusIcon state=\"running\" label={t(\"cards.shellRunning\")} />\n ) : state === \"failed\" ? (\n <StatusIcon state=\"failed\" label={t(\"cards.failed\")} />\n ) : (\n <StatusIcon state=\"done\" label={t(\"cards.done\")} />\n )}\n {(state === \"done\" || state === \"failed\") && durationMs ? (\n <span className=\"meta-dur\">{(durationMs / 1000).toFixed(2)}s</span>\n ) : null}\n </>\n }\n >\n <div className=\"shell\">\n <div className=\"cmd\">\n <span className=\"prompt\">$</span>\n <span className=\"text\">{command}</span>\n </div>\n {output ? (\n <pre className=\"out\">\n {output.split(\"\\n\").map((ln, i) => {\n if (ln.startsWith(\" ✓\") || ln.startsWith(\"✓\"))\n return (\n <div key={i}>\n <span className=\"ok\">{ln}</span>\n </div>\n );\n if (ln.startsWith(\" ✗\") || ln.startsWith(\"✗\") || /error/i.test(ln))\n return (\n <div key={i}>\n <span className=\"err\">{ln}</span>\n </div>\n );\n return <div key={i}>{ln}</div>;\n })}\n </pre>\n ) : null}\n {state === \"await\" && onApprove ? (\n <div className=\"approve-row\">\n <div className=\"why\">\n <b>{t(\"cards.shellAwaiting\")}</b> — {t(\"cards.shellExecuteHint\")}\n </div>\n <div className=\"actions\">\n {onAlwaysAllow ? (\n <button type=\"button\" className=\"btn ghost\" onClick={onAlwaysAllow}>\n {t(\"cards.shellAlwaysAllow\")}\n </button>\n ) : null}\n {onReject ? (\n <button type=\"button\" className=\"btn\" onClick={onReject}>\n {t(\"cards.shellReject\")} <Shortcut keys={[\"mod\", \".\"]} />\n </button>\n ) : null}\n <button type=\"button\" className=\"btn primary\" onClick={onApprove}>\n {t(\"cards.shellRun\")} <Shortcut keys={[\"mod\", \"enter\"]} />\n </button>\n </div>\n </div>\n ) : null}\n </div>\n </Card>\n );\n}\n\n// ---- Compaction ----\n\nexport function CompactionCard({ summary }: { summary: string }) {\n useLang();\n const charCount = summary.length;\n return (\n <Card\n tone=\"default\"\n icon={<I.archive size={12} />}\n kind=\"compaction\"\n name={t(\"cards.compactionName\")}\n meta={<span>{t(\"cards.compactionMeta\", { chars: charCount.toLocaleString() })}</span>}\n defaultOpen={false}\n compact\n >\n <div className=\"compaction-body\">\n <Markdown source={summary} />\n </div>\n </Card>\n );\n}\n\n// ---- Generic Tool ----\n\nexport function ToolCard({\n name,\n args,\n result,\n ok,\n durationMs,\n}: {\n name: string;\n args?: string;\n result?: string;\n ok?: boolean;\n durationMs?: number;\n}) {\n useLang();\n const running = result === undefined;\n const tone: Tone = running ? \"default\" : ok === false ? \"danger\" : \"success\";\n return (\n <Card\n tone={tone}\n icon={<I.wrench size={12} />}\n kind=\"tool\"\n name={name}\n defaultOpen={false}\n compact\n meta={\n <>\n {running ? (\n <StatusIcon state=\"running\" label={t(\"cards.running\")} />\n ) : ok === false ? (\n <StatusIcon state=\"failed\" label={t(\"cards.error\")} />\n ) : (\n <StatusIcon state=\"done\" label={t(\"cards.done\")} />\n )}\n {!running && durationMs !== undefined ? (\n <span className=\"meta-dur\">{durationMs} ms</span>\n ) : null}\n </>\n }\n >\n <div className=\"tool-call\">\n {args ? (\n <div className=\"row\">\n <span className=\"k\">args</span>\n <span className=\"v\">\n <span className=\"str\">{args.length > 600 ? `${args.slice(0, 600)}…` : args}</span>\n </span>\n </div>\n ) : null}\n {result !== undefined ? (\n <div className=\"row\">\n <span className=\"k\">{ok === false ? t(\"cards.error\") : t(\"cards.result\")}</span>\n <span className=\"v\">\n <span className={ok === false ? \"num\" : \"str\"}>\n {result.length > 1200 ? `${result.slice(0, 1200)}…` : result}\n </span>\n </span>\n </div>\n ) : null}\n </div>\n </Card>\n );\n}\n\n// ---- Diff ----\n\nexport type DiffLine =\n | { t: \"hunk\"; s: string }\n | { t: \"ctx\"; l?: number; r?: number; s: string }\n | { t: \"add\"; r: number; s: string }\n | { t: \"rm\"; l: number; s: string };\n\nexport function DiffCard({\n filename,\n lines,\n applied,\n onApply,\n onDiscard,\n}: {\n filename: string;\n lines: DiffLine[];\n applied?: boolean;\n onApply?: () => void;\n onDiscard?: () => void;\n}) {\n useLang();\n const adds = lines.filter((x) => x.t === \"add\").length;\n const rms = lines.filter((x) => x.t === \"rm\").length;\n return (\n <Card\n tone={applied ? \"success\" : \"accent\"}\n icon={<I.diff size={12} />}\n kind=\"edit\"\n name={filename}\n meta={\n <>\n <span style={{ color: \"var(--success)\" }}>+{adds}</span>\n <span style={{ color: \"var(--danger)\" }}>−{rms}</span>\n {applied ? (\n <StatusIcon state=\"done\" label={t(\"cards.applied\")} />\n ) : (\n <StatusIcon state=\"waiting\" label={t(\"cards.diffAwaiting\")} />\n )}\n </>\n }\n >\n <div className=\"diff\">\n <div className=\"lines\">\n {lines.map((ln, i) => {\n if (ln.t === \"hunk\")\n return (\n <div key={i} className=\"ln hunk\">\n <span className=\"code\">{ln.s}</span>\n </div>\n );\n const cls = ln.t === \"add\" ? \"add\" : ln.t === \"rm\" ? \"rm\" : \"\";\n const l = ln.t === \"ctx\" ? ln.l : ln.t === \"rm\" ? ln.l : undefined;\n const r = ln.t === \"ctx\" ? ln.r : ln.t === \"add\" ? ln.r : undefined;\n return (\n <div key={i} className={`ln ${cls}`}>\n <span className=\"num\">{l ?? \"\"}</span>\n <span className=\"num\">{r ?? \"\"}</span>\n <span className=\"code\">\n {ln.t === \"add\" ? \"+ \" : ln.t === \"rm\" ? \"− \" : \" \"}\n {ln.s}\n </span>\n </div>\n );\n })}\n </div>\n {!applied && (onApply || onDiscard) ? (\n <div className=\"approve-row\">\n <div className=\"why\">\n <b>{t(\"cards.diffApplyChanges\")}</b> · +{adds} / −{rms}\n </div>\n <div className=\"actions\">\n {onDiscard ? (\n <button type=\"button\" className=\"btn\" onClick={onDiscard}>\n {t(\"cards.diffDiscard\")}\n </button>\n ) : null}\n {onApply ? (\n <button type=\"button\" className=\"btn primary\" onClick={onApply}>\n {t(\"cards.diffApply\")} <Shortcut keys={[\"mod\", \"enter\"]} />\n </button>\n ) : null}\n </div>\n </div>\n ) : null}\n </div>\n </Card>\n );\n}\n\n// ---- Error ----\n\nexport function ErrorCard({ message, hint, code }: { message: string; hint?: ReactNode; code?: string }) {\n useLang();\n return (\n <Card\n tone=\"danger\"\n icon={<I.warning size={12} />}\n kind=\"error\"\n name={t(\"cards.errorName\")}\n meta={code ? <span className=\"pill-tag err\">{code}</span> : null}\n >\n <div className=\"error-body\">\n <div className=\"msg-err\">{message}</div>\n {hint ? <div className=\"hint\">{hint}</div> : null}\n </div>\n </Card>\n );\n}\n\n// ---- Search results ----\n\nexport type SearchHit = { url: string; title: string; snippet: string };\n\nexport function WebSearchCard({ query, results }: { query: string; results: SearchHit[] }) {\n useLang();\n return (\n <Card\n tone=\"default\"\n icon={<I.globe size={12} />}\n kind=\"web_search\"\n name={t(\"cards.searchName\")}\n meta={\n <>\n <span>\"{query}\"</span>\n <span className=\"pill-tag ok\">{results.length} {t(\"cards.hits\")}</span>\n </>\n }\n >\n <div className=\"search-results\">\n {results.map((r, i) => (\n <div className=\"search-result\" key={i}>\n <div className=\"url\">\n <span className=\"favicon\" />\n <span>{r.url}</span>\n </div>\n <div className=\"title\">{r.title}</div>\n <div className=\"snippet\">{r.snippet}</div>\n </div>\n ))}\n </div>\n </Card>\n );\n}\n\n// ---- Subagent ----\n\nexport type SubAgentChild = {\n avatar: string;\n what: string;\n role: string;\n status: \"done\" | \"running\" | \"queued\";\n};\n\nexport function SubagentCard({\n name,\n children,\n status,\n}: {\n name: string;\n children: SubAgentChild[];\n status: \"running\" | \"done\" | \"failed\";\n}) {\n useLang();\n const done = children.filter((c) => c.status === \"done\").length;\n return (\n <Card\n tone=\"violet\"\n icon={<I.bot size={12} />}\n kind=\"subagent\"\n name={name}\n meta={\n <>\n <span>\n {done} / {children.length} {t(\"cards.subagentDoneProgress\")}\n </span>\n {status === \"done\" ? (\n <StatusIcon state=\"done\" label={t(\"cards.subagentDone\")} />\n ) : status === \"failed\" ? (\n <StatusIcon state=\"failed\" label={t(\"cards.subagentFailed\")} />\n ) : (\n <StatusIcon state=\"running\" label={t(\"cards.subagentRunning\")} />\n )}\n </>\n }\n >\n <div className=\"sub-card\">\n {children.map((c, i) => (\n <div className=\"sub-row\" key={i}>\n <span className=\"av\">{c.avatar}</span>\n <div className=\"what\">\n <div>{c.what}</div>\n <div className=\"role\">{c.role}</div>\n </div>\n <span className=\"prog\">\n {c.status === \"done\" ? (\n <I.check size={12} style={{ color: \"var(--success)\" }} />\n ) : c.status === \"running\" ? (\n <span className=\"spin\" />\n ) : null}\n </span>\n </div>\n ))}\n </div>\n </Card>\n );\n}\n\n// ---- Memory rows ----\n\nexport type MemRow = { scope: string; txt: string };\n\nexport function MemoryCard({ rows }: { rows: MemRow[] }) {\n useLang();\n return (\n <Card\n tone=\"violet\"\n icon={<I.bookmark size={12} />}\n kind=\"memory\"\n name={t(\"cards.memoryName\")}\n meta={<span>+ {rows.length} {t(\"cards.memoryCountSuffix\")}</span>}\n >\n <div className=\"mem\">\n {rows.map((m, i) => (\n <div className=\"mem-row\" key={i}>\n <span className=\"scope\">{m.scope}</span>\n <span className=\"txt\">{m.txt}</span>\n </div>\n ))}\n </div>\n </Card>\n );\n}\n\n// ---- Image attachment ----\n\nexport function AttachCard({\n filename,\n meta,\n preview,\n}: {\n filename: string;\n meta: string;\n preview?: string;\n}) {\n useLang();\n return (\n <Card\n tone=\"default\"\n icon={<I.image size={12} />}\n kind=\"image\"\n name={filename}\n meta={<span>{meta}</span>}\n >\n <div className=\"attach-card\">\n <div className=\"ph\">{preview ?? \"PNG\"}</div>\n <div className=\"info\">\n <div className=\"n\">{filename}</div>\n <div className=\"m\">{meta}</div>\n </div>\n <button type=\"button\" className=\"btn ghost\">\n <I.download size={12} />\n </button>\n </div>\n </Card>\n );\n}\n\n// ---- Metric strip (inline) ----\n\nexport function MetricStrip({\n cacheHit,\n promptTokens,\n outputTokens,\n costLabel,\n elapsed,\n}: {\n cacheHit?: number;\n promptTokens?: number;\n outputTokens?: number;\n costLabel?: string;\n elapsed?: string;\n}) {\n return (\n <div className=\"metric-strip\">\n {cacheHit !== undefined ? (\n <span className=\"item\">\n <I.zap size={11} style={{ color: \"var(--accent)\" }} />\n <span>{t(\"cards.cacheHit\")}</span>\n <span className=\"v acc\">{cacheHit}%</span>\n </span>\n ) : null}\n {promptTokens !== undefined ? (\n <span className=\"item\">\n <span>{t(\"cards.prompt\")}</span>\n <span className=\"v\">{promptTokens.toLocaleString()} t</span>\n </span>\n ) : null}\n {outputTokens !== undefined ? (\n <span className=\"item\">\n <span>{t(\"cards.output\")}</span>\n <span className=\"v\">{outputTokens.toLocaleString()} t</span>\n </span>\n ) : null}\n {costLabel ? (\n <span className=\"item\">\n <I.coin size={11} />\n <span>{t(\"cards.cost\")}</span>\n <span className=\"v ok\">{costLabel}</span>\n </span>\n ) : null}\n {elapsed ? (\n <span className=\"item\">\n <span>{t(\"cards.elapsed\")}</span>\n <span className=\"v\">{elapsed}</span>\n </span>\n ) : null}\n </div>\n );\n}\n\n// ---- Checkpoint marker (inline) ----\n\nexport function Checkpoint({\n hash,\n label,\n onRewind,\n}: {\n hash: string;\n label: string;\n onRewind?: () => void;\n}) {\n useLang();\n return (\n <div className=\"checkpoint\">\n <I.history size={12} />\n <span className=\"hash\">{hash}</span>\n <span>·</span>\n <span>{label}</span>\n {onRewind ? (\n <button type=\"button\" onClick={onRewind}>\n {t(\"cards.checkpointRewind\")}\n </button>\n ) : null}\n </div>\n );\n}\n\n// ---- Plain text block (assistant content via markdown) ----\n\nexport const AssistantText = memo(function AssistantText({ text }: { text: string }) {\n return (\n <div className=\"msg-text\">\n <Markdown source={text} />\n </div>\n );\n});\n","import type { ReactNode } from \"react\";\nimport { I } from \"../icons\";\nimport { t, useLang } from \"../i18n\";\n\nexport type ApprovalTone = \"ok\" | \"warn\" | \"danger\" | \"info\" | \"brand\" | \"ghost\";\n\nexport function ApprovalCard({\n kind,\n tone = \"info\",\n title,\n sub,\n body,\n preview,\n meta,\n primaryLabel,\n secondaryLabel,\n tertiaryLabel,\n onPrimary,\n onSecondary,\n onTertiary,\n}: {\n kind: string;\n tone?: ApprovalTone;\n title: string;\n sub?: string;\n body?: ReactNode;\n preview?: ReactNode;\n meta?: ReactNode;\n primaryLabel?: string;\n secondaryLabel?: string;\n tertiaryLabel?: string;\n onPrimary?: () => void;\n onSecondary?: () => void;\n onTertiary?: () => void;\n}) {\n useLang();\n return (\n <div className=\"approval\" data-tone={tone}>\n <div className=\"ap-head\">\n <span className=\"ap-ico\">\n <I.shield size={13} />\n </span>\n <div>\n <div className=\"ap-kind\">{kind}</div>\n <div className=\"ap-title\">{title}</div>\n {sub ? <div className=\"ap-sub\">{sub}</div> : null}\n </div>\n </div>\n {body ? <div className=\"ap-body\">{body}</div> : null}\n {preview ? <div className=\"ap-preview\">{preview}</div> : null}\n <div className=\"ap-foot\">\n {onPrimary ? (\n <button type=\"button\" className=\"btn primary\" onClick={onPrimary}>\n {primaryLabel ?? t(\"extraCards.approve\")}\n </button>\n ) : null}\n {onSecondary ? (\n <button type=\"button\" className=\"btn ghost\" onClick={onSecondary}>\n {secondaryLabel ?? t(\"extraCards.reject\")}\n </button>\n ) : null}\n {onTertiary && tertiaryLabel ? (\n <button type=\"button\" className=\"btn ghost\" onClick={onTertiary}>\n {tertiaryLabel}\n </button>\n ) : null}\n <span className=\"grow\" />\n {meta ? <span className=\"meta\">{meta}</span> : null}\n </div>\n </div>\n );\n}\n\n// ---- Task Card (multi-step execution from active plan) ----\n\nexport type TaskStepView = {\n n: string;\n state: \"queued\" | \"running\" | \"done\" | \"failed\" | \"blocked\" | \"skipped\";\n label: string;\n hint?: string;\n durationLabel?: string;\n};\n\nexport function TaskCard({\n title,\n subtitle,\n steps,\n}: {\n title: string;\n subtitle?: string;\n steps: TaskStepView[];\n}) {\n useLang();\n const done = steps.filter((x) => x.state === \"done\").length;\n const pct = steps.length ? (done / steps.length) * 100 : 0;\n return (\n <div className=\"task-card\">\n <div className=\"th\">\n <span className=\"ico\">\n <I.list size={13} />\n </span>\n <div>\n <div className=\"tt\">{title}</div>\n {subtitle ? <div className=\"ss\">{subtitle}</div> : null}\n </div>\n <span className=\"grow\" />\n <span className=\"ss\">\n {done}/{steps.length}\n </span>\n <div className=\"meter\">\n <span style={{ width: `${pct}%` }} />\n </div>\n </div>\n <div className=\"tb\">\n {steps.map((st) => (\n <div className=\"task-step\" key={st.n} data-state={st.state}>\n <span className=\"nx\">step.{st.n}</span>\n <span className=\"st\" />\n <div className=\"l\">\n {st.label}\n {st.hint ? <div className=\"h\">{st.hint}</div> : null}\n </div>\n <span className=\"t\">{st.durationLabel ?? \"—\"}</span>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\n// ---- Warn / Tip / Doctor ----\n\nexport function WarnCard({ title, body }: { title: string; body: ReactNode }) {\n return (\n <div className=\"warn-card\">\n <span className=\"ico\">\n <I.warn size={16} />\n </span>\n <div>\n <div className=\"tt\">{title}</div>\n <div className=\"ds\">{body}</div>\n </div>\n </div>\n );\n}\n\nexport type TipSection = { title: string; rows: ReactNode[] };\n\nexport function TipCard({\n topic,\n command,\n sections,\n footer,\n}: {\n topic: string;\n command?: string;\n sections: TipSection[];\n footer?: ReactNode;\n}) {\n return (\n <div className=\"tip-card\">\n <div className=\"head\">\n <span className=\"ico\">\n <I.help size={12} />\n </span>\n <span className=\"topic\">{topic}</span>\n <span className=\"grow\" />\n {command ? <span className=\"pill\">{command}</span> : null}\n </div>\n {sections.map((sec, i) => (\n <div className=\"sec\" key={i}>\n <div className=\"stt\">{sec.title}</div>\n {sec.rows.map((r, j) => (\n <div className=\"row\" key={j}>\n {r}\n </div>\n ))}\n </div>\n ))}\n {footer ? <div className=\"foot\">{footer}</div> : null}\n </div>\n );\n}\n\nexport type DoctorRow = { s: \"ok\" | \"warn\" | \"fail\"; nm: string; sub: string; v: string };\n\nexport function DoctorCard({ rows, headerSubtitle }: { rows: DoctorRow[]; headerSubtitle?: string }) {\n useLang();\n const c = { ok: 0, warn: 0, fail: 0 };\n for (const r of rows) c[r.s]++;\n return (\n <div className=\"doctor-card\">\n <div className=\"dh\">\n <span className=\"ico\">\n <I.shield size={13} />\n </span>\n <div>\n <div className=\"tt\">{t(\"extraCards.doctorTitle\")}</div>\n {headerSubtitle ? (\n <div\n className=\"ss\"\n style={{\n fontFamily: \"Geist Mono, monospace\",\n fontSize: 10.5,\n color: \"var(--muted)\",\n }}\n >\n {headerSubtitle}\n </div>\n ) : null}\n </div>\n <span className=\"grow\" />\n <div className=\"summary\">\n <span>\n <span className=\"b ok\">{c.ok}</span> ok\n </span>\n <span>\n <span className=\"b warn\">{c.warn}</span> warn\n </span>\n <span>\n <span className=\"b err\">{c.fail}</span> fail\n </span>\n </div>\n </div>\n {rows.map((r, i) => (\n <div className=\"doctor-row\" key={i} data-s={r.s}>\n <span className=\"ic\" data-mark={r.s === \"ok\" ? \"✓\" : r.s === \"warn\" ? \"!\" : \"✕\"} />\n <div className=\"body\">\n <div className=\"nm\">{r.nm}</div>\n <div className=\"sub\">{r.sub}</div>\n </div>\n <span className=\"v\">{r.v}</span>\n </div>\n ))}\n </div>\n );\n}\n\n// ---- Usage (full) ----\n\nexport function UsageFull({\n promptTokens,\n reasoningTokens,\n outputTokens,\n cacheHitTokens,\n costLabel,\n balanceLabel,\n range,\n}: {\n promptTokens: number;\n reasoningTokens: number;\n outputTokens: number;\n cacheHitTokens: number;\n costLabel: string;\n balanceLabel?: string;\n range?: string;\n}) {\n useLang();\n const fmt = (n: number) => (n >= 1000 ? `${(n / 1000).toFixed(1)}k` : `${n}`);\n const total = promptTokens + reasoningTokens + outputTokens + cacheHitTokens || 1;\n const pct = (n: number) => Math.round((n / total) * 100);\n return (\n <div className=\"usage-full\">\n <div className=\"uh\">\n <div>\n <div className=\"tt\">{t(\"extraCards.sessionUsage\")}</div>\n {range ? <div className=\"ss\">{range}</div> : null}\n </div>\n <span className=\"grow\" />\n </div>\n <div className=\"ub\">\n <div className=\"ucol\">\n <div className=\"l\">{t(\"extraCards.prompt\")}</div>\n <div className=\"v acc\">{fmt(promptTokens)}</div>\n <div className=\"pct\">{pct(promptTokens)}%</div>\n </div>\n <div className=\"ucol\">\n <div className=\"l\">{t(\"extraCards.reasoning\")}</div>\n <div className=\"v vio\">{fmt(reasoningTokens)}</div>\n <div className=\"pct\">{pct(reasoningTokens)}%</div>\n </div>\n <div className=\"ucol\">\n <div className=\"l\">{t(\"extraCards.output\")}</div>\n <div className=\"v ok\">{fmt(outputTokens)}</div>\n <div className=\"pct\">{pct(outputTokens)}%</div>\n </div>\n <div className=\"ucol\">\n <div className=\"l\">{t(\"extraCards.cacheHit\")}</div>\n <div className=\"v\">{fmt(cacheHitTokens)}</div>\n <div className=\"pct\">{pct(cacheHitTokens)}%</div>\n </div>\n </div>\n <div className=\"stack\">\n <span className=\"s1\" style={{ width: `${pct(promptTokens)}%` }} />\n <span className=\"s2\" style={{ width: `${pct(reasoningTokens)}%` }} />\n <span className=\"s3\" style={{ width: `${pct(outputTokens)}%` }} />\n <span className=\"s4\" style={{ width: `${pct(cacheHitTokens)}%` }} />\n </div>\n <div className=\"uf\">\n <span className=\"x\">\n <span className=\"sw\" style={{ background: \"var(--accent)\" }} />\n {t(\"extraCards.prompt\")}\n </span>\n <span className=\"x\">\n <span className=\"sw\" style={{ background: \"var(--violet)\" }} />\n {t(\"extraCards.reasoning\")}\n </span>\n <span className=\"x\">\n <span className=\"sw\" style={{ background: \"var(--tone-ok)\" }} />\n {t(\"extraCards.output\")}\n </span>\n <span className=\"x\">\n <span className=\"sw\" style={{ background: \"var(--border-strong)\" }} />\n {t(\"extraCards.cache\")}\n </span>\n <span style={{ marginLeft: \"auto\" }}>\n {t(\"extraCards.sessionCost\", { costLabel })}\n {balanceLabel ? ` · ${t(\"extraCards.balance\", { balanceLabel })}` : \"\"}\n </span>\n </div>\n </div>\n );\n}\n\n// ---- Context window breakdown ----\n\nexport type CtxPart = { k: \"system\" | \"tools\" | \"log\" | \"input\"; label: string; value: string; widthPct: number };\nexport type CtxTopRow = { name: string; widthPct: number; value: string };\n\nexport function CtxCard({\n totalLabel,\n parts,\n topTools,\n}: {\n totalLabel: string;\n parts: CtxPart[];\n topTools: CtxTopRow[];\n}) {\n useLang();\n return (\n <div className=\"ctx-card\">\n <div className=\"h\">\n <span className=\"tt\">{t(\"extraCards.contextWindow\")}</span>\n <span className=\"grow\" />\n <span className=\"v\">{totalLabel}</span>\n </div>\n <div className=\"bar\">\n {parts.map((p) => (\n <span key={p.k} className={p.k} style={{ width: `${p.widthPct}%` }} />\n ))}\n </div>\n <div className=\"legend\">\n {parts.map((p) => {\n const color =\n p.k === \"system\"\n ? \"var(--accent)\"\n : p.k === \"tools\"\n ? \"var(--violet)\"\n : p.k === \"log\"\n ? \"var(--tone-ok)\"\n : \"var(--tone-warn)\";\n return (\n <div key={p.k}>\n <span className=\"sw\" style={{ background: color }} />\n <span className=\"l\">{p.label}</span>\n <span className=\"v\">{p.value}</span>\n </div>\n );\n })}\n </div>\n {topTools.length > 0 ? (\n <div className=\"ttop\">\n <div className=\"stt\">{t(\"extraCards.topToolsUsage\")}</div>\n {topTools.map((t, i) => (\n <div className=\"row\" key={i}>\n <span className=\"n\">{t.name}</span>\n <div className=\"bbar\">\n <span style={{ width: `${t.widthPct}%` }} />\n </div>\n <span className=\"v\">{t.value}</span>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n );\n}\n\n// ---- Memory groups ----\n\nexport type MemGroupKey = \"user\" | \"feedback\" | \"project\" | \"reference\";\nexport type MemEntry = { text: string; meta?: string };\nexport type MemGroups = Partial<Record<MemGroupKey, MemEntry[]>>;\n\nconst GROUP_LABELS: Record<MemGroupKey, Parameters<typeof t>[0]> = {\n user: \"extraCards.memoryUser\",\n feedback: \"extraCards.memoryFeedback\",\n project: \"extraCards.memoryProject\",\n reference: \"extraCards.memoryReference\",\n};\n\nexport function MemoryGroups({ data }: { data: MemGroups }) {\n useLang();\n const keys: MemGroupKey[] = [\"user\", \"feedback\", \"project\", \"reference\"];\n return (\n <div className=\"mem-groups\">\n {keys.map((g) => {\n const rows = data[g] ?? [];\n if (rows.length === 0) return null;\n return (\n <div key={g}>\n <div className=\"gh\" data-g={g}>\n <span className=\"sw\" />\n <span>{t(GROUP_LABELS[g])}</span>\n <span className=\"grow\" />\n <span className=\"cnt\">{rows.length}</span>\n </div>\n {rows.map((r, i) => (\n <div className=\"mrow\" key={i}>\n <span className=\"b\">·</span>\n <div className=\"t\">{r.text}</div>\n {r.meta ? <span className=\"meta\">{r.meta}</span> : null}\n </div>\n ))}\n </div>\n );\n })}\n </div>\n );\n}\n\n// ---- Fallback ----\n\nexport function FallbackCard({ kindLabel, payload }: { kindLabel: string; payload: Record<string, string> }) {\n useLang();\n return (\n <div className=\"fallback-card\">\n <div className=\"hd\">{t(\"extraCards.unknownKind\")}</div>\n <div className=\"kv\">\n <span className=\"k\">kind</span>\n <span className=\"v\">\"{kindLabel}\"</span>\n {Object.entries(payload).map(([k, v]) => (\n <span key={k} style={{ display: \"contents\" }}>\n <span className=\"k\">{k}</span>\n <span className=\"v\">{v}</span>\n </span>\n ))}\n </div>\n </div>\n );\n}\n\n// ---- LiveCard (pill variants) ----\n\nexport type LiveVariant =\n | \"thinking\"\n | \"undo\"\n | \"ctxPressure\"\n | \"aborted\"\n | \"retry\"\n | \"checkpoint\"\n | \"stepProgress\"\n | \"mcpEvent\"\n | \"sessionOp\";\n\nexport function LiveCard({\n variant,\n icon,\n body,\n action,\n onAction,\n}: {\n variant: LiveVariant;\n icon: ReactNode;\n body: ReactNode;\n action?: string;\n onAction?: () => void;\n}) {\n return (\n <span className={`live-card ${variant === \"stepProgress\" ? \"step\" : \"\"}`} data-v={variant}>\n <span className=\"lc-ico\">{icon}</span>\n <span className=\"lc-body\">{body}</span>\n {action ? (\n <button type=\"button\" className=\"lc-act\" onClick={onAction}>\n {action}\n </button>\n ) : null}\n </span>\n );\n}\n","import { isCompactionSummary, stripCompactionMarker } from \"@reasonix/core-utils/compaction\";\nimport { derivePrefix } from \"@reasonix/core-utils/derive-prefix\";\nimport { memo, useState, type ReactNode } from \"react\";\nimport { Copy } from \"lucide-react\";\nimport { I } from \"../icons\";\nimport { t, useLang } from \"../i18n\";\nimport type { AssistantSegment, ActivePlan, PendingPlan, PendingCheckpoint, PendingRevision, PendingConfirm, PendingChoice, SkillOrigin } from \"../App\";\nimport { AssistantText, CompactionCard, PlanCardView, ReasoningCard, ShellCard, ToolCard, type PlanItem } from \"./cards\";\nimport { ApprovalCard, TaskCard, type TaskStepView } from \"./extra-cards\";\n\nexport function TurnDivider({ label }: { label: string }) {\n return (\n <div className=\"turn-divider\">\n <span>{label}</span>\n <span className=\"line\" />\n </div>\n );\n}\n\nexport const UserMsg = memo(function UserMsg({\n text,\n time,\n skill,\n}: {\n text: string;\n time?: string;\n skill?: SkillOrigin;\n}) {\n useLang();\n const [copied, setCopied] = useState(false);\n const onCopy = async () => {\n try {\n await navigator.clipboard.writeText(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n } catch {\n /* ignore */\n }\n };\n return (\n <div className=\"msg user\">\n <div className=\"avatar\">YOU</div>\n <div className=\"body\">\n <div className=\"who\">\n <span className=\"name\">{t(\"thread.you\")}</span>\n {skill ? (\n <span className=\"skill-chip\" title={`skill · ${skill.runAs}`}>\n <I.zap size={10} /> /{skill.name}\n {skill.runAs === \"subagent\" ? <span className=\"sub\">{t(\"thread.subagent\")}</span> : null}\n </span>\n ) : null}\n {time ? <span className=\"time\">{time}</span> : null}\n </div>\n <div className=\"msg-text\">{text}</div>\n <div className=\"msg-actions\">\n <button\n type=\"button\"\n className={`copy-btn ${copied ? \"done\" : \"\"}`}\n onClick={onCopy}\n title={t(\"thread.copyMessage\")}\n >\n <Copy size={11} />\n {copied ? t(\"markdown.copied\") : null}\n </button>\n </div>\n </div>\n </div>\n );\n});\n\nexport const AssistantMsg = memo(function AssistantMsg({\n segments,\n pending,\n model,\n time,\n onApproveConfirm,\n onRejectConfirm,\n onAlwaysAllowConfirm,\n pendingConfirms,\n}: {\n segments: AssistantSegment[];\n pending: boolean;\n model?: string;\n time?: string;\n onApproveConfirm: (id: number) => void;\n onRejectConfirm: (id: number) => void;\n onAlwaysAllowConfirm: (id: number, prefix: string) => void;\n pendingConfirms: PendingConfirm[];\n}) {\n const [copied, setCopied] = useState(false);\n const content = segments\n .filter((s): s is AssistantSegment & { kind: \"text\" } => s.kind === \"text\")\n .map((s) => s.text)\n .join(\"\\n\\n\");\n const onCopy = async () => {\n try {\n await navigator.clipboard.writeText(content);\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n } catch {\n /* ignore */\n }\n };\n return (\n <div className=\"msg assistant\">\n <div className=\"avatar\">DS</div>\n <div className=\"body\">\n <div className=\"who\">\n <span className=\"name\">Reasonix</span>\n {model ? <span className=\"model\">{model}</span> : null}\n {time ? <span className=\"time\">{time}</span> : null}\n </div>\n {segments.map((s, i) => {\n if (s.kind === \"text\") {\n if (!s.text.trim()) return null;\n if (isCompactionSummary(s.text)) {\n return <CompactionCard key={i} summary={stripCompactionMarker(s.text)} />;\n }\n return <AssistantText key={i} text={s.text} />;\n }\n if (s.kind === \"reasoning\") {\n return (\n <ReasoningCard\n key={i}\n text={s.text}\n streaming={pending && i === segments.length - 1}\n />\n );\n }\n // tool segment\n const pendingConfirm =\n (s.name === \"run_command\" || s.name === \"run_background\") && s.result === undefined\n ? pendingConfirms.find((c) => c.command === extractCommand(s.args))\n : undefined;\n if (s.name === \"run_command\" || s.name === \"run_background\") {\n const cmd = extractCommand(s.args) ?? s.args;\n const state: \"await\" | \"running\" | \"done\" | \"failed\" =\n s.result === undefined\n ? pendingConfirm\n ? \"await\"\n : \"running\"\n : s.ok === false\n ? \"failed\"\n : \"done\";\n return (\n <ShellCard\n key={i}\n command={cmd}\n output={s.result}\n state={state}\n durationMs={s.durationMs}\n onApprove={pendingConfirm ? () => onApproveConfirm(pendingConfirm.id) : undefined}\n onReject={pendingConfirm ? () => onRejectConfirm(pendingConfirm.id) : undefined}\n onAlwaysAllow={\n pendingConfirm\n ? () => {\n onAlwaysAllowConfirm(pendingConfirm.id, derivePrefix(cmd));\n }\n : undefined\n }\n />\n );\n }\n return (\n <ToolCard\n key={i}\n name={s.name}\n args={s.args}\n result={s.result}\n ok={s.ok}\n durationMs={s.durationMs}\n />\n );\n })}\n {content ? (\n <div className=\"msg-actions\">\n <button\n type=\"button\"\n className={`copy-btn ${copied ? \"done\" : \"\"}`}\n onClick={onCopy}\n title={t(\"thread.copyResponse\")}\n >\n <Copy size={11} />\n {copied ? t(\"markdown.copied\") : null}\n </button>\n </div>\n ) : null}\n </div>\n </div>\n );\n});\n\nfunction extractCommand(args: string): string | undefined {\n if (!args) return undefined;\n try {\n const v = JSON.parse(args);\n if (v && typeof v === \"object\" && typeof v.command === \"string\") return v.command;\n } catch {\n // ignore\n }\n return undefined;\n}\n\nexport function PlanBanner({\n plan,\n onDismiss,\n}: {\n plan: ActivePlan;\n onDismiss?: () => void;\n}) {\n useLang();\n const total = plan.steps.length || 1;\n const done = plan.completedStepIds.length;\n const pct = (done / total) * 100;\n const current = plan.steps.find((s) => !plan.completedStepIds.includes(s.id));\n return (\n <div className=\"plan-banner\">\n <span className=\"ico\">\n <I.list size={14} />\n </span>\n <div className=\"body\">\n <div className=\"t\">\n {t(\"thread.planRunning\", { step: Math.min(done + 1, total), total })}\n {current ? ` — ${current.title}` : \"\"}\n </div>\n <div className=\"s\">{plan.plan}</div>\n </div>\n <div className=\"prog\">\n <div className=\"meter-mini\">\n <span style={{ width: `${pct}%` }} />\n </div>\n {onDismiss ? (\n <button type=\"button\" onClick={onDismiss}>\n {t(\"thread.collapse\")}\n </button>\n ) : null}\n </div>\n </div>\n );\n}\n\nexport function ActivePlanCard({ plan }: { plan: ActivePlan }) {\n useLang();\n const done = new Set(plan.completedStepIds);\n const items: PlanItem[] = plan.steps.map((s) => {\n let status: PlanItem[\"status\"];\n if (done.has(s.id)) status = \"done\";\n else if (s === plan.steps.find((x) => !done.has(x.id))) status = \"active\";\n else status = \"todo\";\n return {\n id: s.id,\n status,\n text: s.title,\n tool: s.action,\n note: s.risk ? `${t(\"thread.risk\")}: ${s.risk}` : undefined,\n };\n });\n return <PlanCardView items={items} title={t(\"thread.activePlan\")} />;\n}\n\n// ---- Approval bindings ----\n\nexport function PlanApprovalCard({\n p,\n onApprove,\n onRefine,\n onCancel,\n}: {\n p: PendingPlan;\n onApprove: () => void;\n onRefine: () => void;\n onCancel: () => void;\n}) {\n useLang();\n const stepCount = p.steps?.length ?? 0;\n const sub = stepCount > 0 ? t(\"thread.planStepCount\", { count: stepCount }) : undefined;\n return (\n <ApprovalCard\n kind={t(\"thread.planConfirmationKind\")}\n tone=\"info\"\n title={t(\"thread.startPlan\")}\n sub={sub}\n body={\n <>\n {p.summary ? <div style={{ marginBottom: 6 }}>{p.summary}</div> : null}\n <div style={{ whiteSpace: \"pre-wrap\" }}>{p.plan}</div>\n </>\n }\n meta={`plan/#${p.id}`}\n primaryLabel={t(\"thread.approve\")}\n secondaryLabel={t(\"thread.cancel\")}\n tertiaryLabel={t(\"thread.refine\")}\n onPrimary={onApprove}\n onSecondary={onCancel}\n onTertiary={onRefine}\n />\n );\n}\n\nexport function CheckpointApprovalCard({\n c,\n onContinue,\n onRevise,\n onStop,\n}: {\n c: PendingCheckpoint;\n onContinue: () => void;\n onRevise: () => void;\n onStop: () => void;\n}) {\n useLang();\n return (\n <ApprovalCard\n kind={t(\"thread.checkpointKind\")}\n tone=\"brand\"\n title={c.title ?? t(\"thread.checkpointTitle\", { completed: c.completed, total: c.total })}\n sub={t(\"thread.checkpointSub\", { completed: c.completed, total: c.total })}\n body={\n <>\n <div style={{ whiteSpace: \"pre-wrap\" }}>{c.result}</div>\n {c.notes ? (\n <div style={{ marginTop: 8, fontSize: 11.5, color: \"var(--muted)\" }}>{c.notes}</div>\n ) : null}\n </>\n }\n meta={`checkpoint · ${c.stepId}`}\n primaryLabel={t(\"thread.continue\")}\n secondaryLabel={t(\"thread.stop\")}\n tertiaryLabel={t(\"thread.revise\")}\n onPrimary={onContinue}\n onSecondary={onStop}\n onTertiary={onRevise}\n />\n );\n}\n\nexport function RevisionApprovalCard({\n r,\n onAccept,\n onReject,\n}: {\n r: PendingRevision;\n onAccept: () => void;\n onReject: () => void;\n}) {\n useLang();\n return (\n <ApprovalCard\n kind={t(\"thread.planRevisionKind\")}\n tone=\"warn\"\n title={t(\"thread.rewritePlan\")}\n sub={t(\"thread.keepSteps\", { n: r.remainingSteps.length })}\n body={\n <>\n <div style={{ marginBottom: 8 }}>{r.reason}</div>\n {r.summary ? (\n <div style={{ fontSize: 11.5, color: \"var(--muted)\", marginBottom: 8 }}>{r.summary}</div>\n ) : null}\n <ul style={{ margin: 0, paddingLeft: 18 }}>\n {r.remainingSteps.map((s) => (\n <li key={s.id} style={{ fontSize: 12, marginBottom: 2 }}>\n {s.title}\n {s.risk ? (\n <span\n style={{\n marginLeft: 6,\n fontSize: 10,\n color:\n s.risk === \"high\"\n ? \"var(--tone-err)\"\n : s.risk === \"med\"\n ? \"var(--tone-warn)\"\n : \"var(--muted)\",\n }}\n >\n [{s.risk}]\n </span>\n ) : null}\n </li>\n ))}\n </ul>\n </>\n }\n meta={t(\"thread.revisionMeta\")}\n primaryLabel={t(\"thread.approveRewrite\")}\n secondaryLabel={t(\"thread.keepOriginal\")}\n onPrimary={onAccept}\n onSecondary={onReject}\n />\n );\n}\n\nexport function ConfirmApprovalCard({\n c,\n onAllow,\n onAlwaysAllow,\n onDeny,\n}: {\n c: PendingConfirm;\n onAllow: () => void;\n onAlwaysAllow: (prefix: string) => void;\n onDeny: () => void;\n}) {\n useLang();\n const isBackground = c.kind === \"run_background\";\n const prefix = derivePrefix(c.command);\n return (\n <ApprovalCard\n kind={t(\"thread.shellConfirmationKind\")}\n tone=\"warn\"\n title={isBackground ? t(\"thread.runBackgroundCommand\") : t(\"thread.runCommand\")}\n sub={c.command.length > 80 ? `${c.command.slice(0, 80)}…` : c.command}\n preview={\n <>\n <span style={{ color: \"var(--accent)\" }}>$</span> {c.command}\n </>\n }\n meta={t(\"thread.riskMedium\", { kind: c.kind })}\n primaryLabel={t(\"thread.execute\")}\n secondaryLabel={t(\"thread.reject\")}\n tertiaryLabel={t(\"thread.alwaysAllow\", { prefix })}\n onPrimary={onAllow}\n onSecondary={onDeny}\n onTertiary={() => onAlwaysAllow(prefix)}\n />\n );\n}\n\nexport function PathAccessApprovalCard({\n p,\n onAllow,\n onAlwaysAllow,\n onDeny,\n}: {\n p: {\n id: number;\n path: string;\n intent: \"read\" | \"write\";\n toolName: string;\n sandboxRoot: string;\n allowPrefix: string;\n };\n onAllow: () => void;\n onAlwaysAllow: (prefix: string) => void;\n onDeny: () => void;\n}) {\n useLang();\n const isWrite = p.intent === \"write\";\n return (\n <ApprovalCard\n kind={t(\"thread.pathAccessKind\")}\n tone=\"warn\"\n title={isWrite ? t(\"thread.writePathOutsideSandbox\") : t(\"thread.readPathOutsideSandbox\")}\n sub={p.path}\n preview={\n <>\n <div>{p.toolName} → {p.path}</div>\n <div style={{ color: \"var(--muted)\", marginTop: 4 }}>\n workspace: {p.sandboxRoot}\n </div>\n </>\n }\n meta={t(\"thread.riskMedium\", { kind: p.intent })}\n primaryLabel={isWrite ? t(\"thread.allowWrite\") : t(\"thread.allowRead\")}\n secondaryLabel={t(\"thread.reject\")}\n tertiaryLabel={t(\"thread.alwaysAllowPrefix\", { prefix: p.allowPrefix })}\n onPrimary={onAllow}\n onSecondary={onDeny}\n onTertiary={() => onAlwaysAllow(p.allowPrefix)}\n />\n );\n}\n\nexport function ChoiceApprovalCard({\n c,\n onPick,\n onCancel,\n}: {\n c: PendingChoice;\n onPick: (optionId: string) => void;\n onCancel: () => void;\n}) {\n useLang();\n return (\n <ApprovalCard\n kind={t(\"thread.userChoiceKind\")}\n tone=\"info\"\n title={c.question}\n sub={t(\"thread.optionCount\", { count: c.options.length })}\n body={\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n {c.options.map((o) => (\n <button\n key={o.id}\n type=\"button\"\n className=\"btn\"\n style={{ justifyContent: \"flex-start\", textAlign: \"left\" }}\n onClick={() => onPick(o.id)}\n >\n <div>\n <div style={{ fontWeight: 600 }}>{o.title}</div>\n {o.summary ? (\n <div style={{ fontSize: 11, color: \"var(--muted)\", marginTop: 2 }}>\n {o.summary}\n </div>\n ) : null}\n </div>\n </button>\n ))}\n </div>\n }\n primaryLabel={t(\"thread.cancel\")}\n onPrimary={onCancel}\n />\n );\n}\n\nexport function activePlanToTaskSteps(plan: ActivePlan): TaskStepView[] {\n const done = new Set(plan.completedStepIds);\n return plan.steps.map((s, i) => ({\n n: String(i + 1),\n state: done.has(s.id) ? \"done\" : i === plan.completedStepIds.length ? \"running\" : \"queued\",\n label: s.title,\n hint: s.action,\n durationLabel: undefined,\n }));\n}\n\nexport function ActivePlanTaskCard({ plan }: { plan: ActivePlan }) {\n useLang();\n return (\n <TaskCard\n title={t(\"thread.activePlan\")}\n subtitle={plan.summary}\n steps={activePlanToTaskSteps(plan)}\n />\n );\n}\n\nexport function HeaderHint({ children }: { children: ReactNode }) {\n return <div className=\"msg-text\">{children}</div>;\n}\n","import { useEffect, useMemo, useRef, useState } from \"react\";\nimport { I } from \"../icons\";\nimport { t, useLang } from \"../i18n\";\nimport { Shortcut } from \"./shortcut\";\n\ntype Anchor = { top?: number; bottom?: number; left: number };\n\nexport function WorkdirPop({\n open,\n onClose,\n recent,\n current,\n anchor,\n onPick,\n onBrowse,\n}: {\n open: boolean;\n onClose: () => void;\n recent: string[];\n current?: string;\n anchor?: Anchor;\n onPick: (path: string) => void;\n onBrowse: () => void;\n}) {\n useLang();\n const [query, setQuery] = useState(\"\");\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (!open) return;\n setQuery(\"\");\n const id = window.setTimeout(() => inputRef.current?.focus(), 40);\n return () => window.clearTimeout(id);\n }, [open]);\n\n const items = useMemo(() => {\n const list = recent.length > 0 ? recent : current ? [current] : [];\n const q = query.trim().toLowerCase();\n if (!q) return list;\n return list.filter((p) => p.toLowerCase().includes(q));\n }, [recent, current, query]);\n\n if (!open) return null;\n\n const left = anchor?.left ?? 240;\n const positionStyle =\n anchor?.bottom !== undefined\n ? { bottom: anchor.bottom, left }\n : { top: anchor?.top ?? 56, left };\n\n return (\n <div className=\"wd-mask\" onMouseDown={onClose}>\n <div className=\"wd-pop\" style={positionStyle} onMouseDown={(e) => e.stopPropagation()}>\n <div className=\"wd-head\">\n <I.folder size={12} />\n <span>{t(\"workdir.title\")}</span>\n <span\n style={{\n marginLeft: \"auto\",\n fontFamily: \"Geist Mono, monospace\",\n fontSize: 10,\n color: \"var(--muted)\",\n }}\n >\n <Shortcut keys={[\"mod\", \"O\"]} />\n </span>\n </div>\n <input\n ref={inputRef}\n className=\"wd-search\"\n placeholder={t(\"workdir.searchPlaceholder\")}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onClose();\n } else if (e.key === \"Enter\" && items[0]) {\n e.preventDefault();\n onPick(items[0]);\n onClose();\n }\n }}\n />\n <div className=\"wd-list\">\n {items.length === 0 ? (\n <div\n style={{\n padding: \"16px 12px\",\n fontSize: 11.5,\n color: \"var(--muted)\",\n fontFamily: \"Geist Mono, monospace\",\n }}\n >\n {t(\"workdir.empty\")}\n </div>\n ) : null}\n {items.map((p) => {\n const isCurrent = p === current;\n const name = p.split(/[\\\\/]/).filter(Boolean).pop() ?? p;\n return (\n <div\n key={p}\n className=\"wd-row\"\n onClick={() => {\n if (!isCurrent) onPick(p);\n onClose();\n }}\n title={p}\n >\n <span className=\"ic\">\n <I.folder size={12} />\n </span>\n <div className=\"b\">\n <div className=\"p\">{name}</div>\n <div className=\"br\">{p}</div>\n </div>\n {isCurrent ? (\n <span className=\"pin\">\n <I.check size={11} />\n </span>\n ) : null}\n </div>\n );\n })}\n </div>\n <div className=\"wd-foot\">\n <button\n type=\"button\"\n className=\"btn ghost\"\n onClick={() => {\n onBrowse();\n onClose();\n }}\n >\n <I.plus size={11} /> {t(\"workdir.browse\")}\n </button>\n </div>\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { I } from \"../icons\";\nimport { t, useLang } from \"../i18n\";\n\ninterface BrowseEntry {\n name: string;\n full: string;\n}\n\ninterface BrowseResult {\n path: string;\n parent: string | null;\n entries: BrowseEntry[];\n}\n\nasync function fetchBrowse(path: string): Promise<BrowseResult> {\n const token = document\n .querySelector('meta[name=\"reasonix-token\"]')\n ?.getAttribute(\"content\") ?? \"\";\n const params = new URLSearchParams();\n if (path) params.set(\"path\", path);\n if (token && token !== \"__REASONIX_TOKEN__\") params.set(\"token\", token);\n const res = await fetch(`/api/browse?${params.toString()}`);\n if (!res.ok) {\n const text = await res.text();\n throw new Error(text || `browse failed (${res.status})`);\n }\n return (await res.json()) as BrowseResult;\n}\n\nexport function WorkdirInputModal({\n open,\n initialPath,\n onCancel,\n onConfirm,\n}: {\n open: boolean;\n initialPath?: string;\n onCancel: () => void;\n onConfirm: (path: string) => void;\n}) {\n useLang();\n const [typed, setTyped] = useState<string>(initialPath ?? \"\");\n const [browse, setBrowse] = useState<BrowseResult | null>(null);\n const [error, setError] = useState<string>(\"\");\n const [loading, setLoading] = useState(false);\n const seededRef = useRef(false);\n\n const navigate = useCallback(async (path: string) => {\n setLoading(true);\n setError(\"\");\n try {\n const result = await fetchBrowse(path);\n setBrowse(result);\n setTyped(result.path);\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n if (!open) {\n seededRef.current = false;\n return;\n }\n if (seededRef.current) return;\n seededRef.current = true;\n void navigate(initialPath ?? \"\");\n }, [open, initialPath, navigate]);\n\n if (!open) return null;\n\n const trimmedTyped = typed.trim();\n const canConfirm = trimmedTyped.length > 0 && !loading;\n const sameAsCurrent = browse !== null && trimmedTyped === browse.path;\n\n const handleConfirm = () => {\n if (!canConfirm) return;\n onConfirm(trimmedTyped);\n };\n\n const handleTypedKey = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onCancel();\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n if (sameAsCurrent) {\n handleConfirm();\n } else {\n void navigate(trimmedTyped);\n }\n }\n };\n\n return (\n <div className=\"settings-mask\" onMouseDown={onCancel}>\n <div\n className=\"workdir-input\"\n onMouseDown={(e) => e.stopPropagation()}\n >\n <div className=\"workdir-input-head\">\n <I.folder size={14} />\n <span>{t(\"workdir.title\")}</span>\n <button\n type=\"button\"\n className=\"close-btn\"\n onClick={onCancel}\n title={t(\"workdir.cancel\")}\n >\n <I.x size={13} />\n </button>\n </div>\n <div className=\"workdir-input-pathrow\">\n <input\n autoFocus\n className=\"workdir-input-path\"\n value={typed}\n placeholder={t(\"workdir.pathPlaceholder\")}\n onChange={(e) => setTyped(e.target.value)}\n onKeyDown={handleTypedKey}\n spellCheck={false}\n />\n <button\n type=\"button\"\n className=\"btn ghost\"\n onClick={() => void navigate(trimmedTyped)}\n disabled={loading || trimmedTyped.length === 0}\n title={t(\"workdir.goTip\")}\n >\n {t(\"workdir.go\")}\n </button>\n </div>\n {error ? <div className=\"workdir-input-error\">{error}</div> : null}\n <div className=\"workdir-input-list\">\n {browse?.parent ? (\n <div\n className=\"workdir-input-row up\"\n onClick={() => void navigate(browse.parent!)}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") void navigate(browse.parent!);\n }}\n >\n <span className=\"ic\">↑</span>\n <span>..</span>\n </div>\n ) : null}\n {browse?.entries.length === 0 && !loading ? (\n <div className=\"workdir-input-empty\">{t(\"workdir.emptyDir\")}</div>\n ) : null}\n {browse?.entries.map((e) => (\n <div\n key={e.full}\n className=\"workdir-input-row\"\n onClick={() => void navigate(e.full)}\n onDoubleClick={() => onConfirm(e.full)}\n role=\"button\"\n tabIndex={0}\n title={e.full}\n onKeyDown={(ev) => {\n if (ev.key === \"Enter\") void navigate(e.full);\n }}\n >\n <span className=\"ic\"><I.folder size={12} /></span>\n <span className=\"n\">{e.name}</span>\n </div>\n ))}\n {loading ? <div className=\"workdir-input-empty\">{t(\"workdir.loading\")}</div> : null}\n </div>\n <div className=\"workdir-input-foot\">\n <button type=\"button\" className=\"btn ghost\" onClick={onCancel}>\n {t(\"workdir.cancel\")}\n </button>\n <button\n type=\"button\"\n className=\"btn primary\"\n onClick={handleConfirm}\n disabled={!canConfirm}\n >\n {t(\"workdir.openHere\")}\n </button>\n </div>\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\n\nconst PIN_THRESHOLD = 80; // px from bottom to consider \"pinned\"\n\n// Auto-scrolls while content grows; un-pins only on real user gestures.\n// Scroll events are avoided because smooth scrollTo can fire them mid-flight.\nexport function useAutoScroll(\n containerRef: React.RefObject<HTMLDivElement | null>,\n contentRef: React.RefObject<HTMLDivElement | null>,\n busy: boolean,\n /** Optional boot-time restore: the offset the transcript should open at. */\n getRestoreScrollTop?: () => number | null,\n) {\n const [showJumpButton, setShowJumpButton] = useState(false);\n const isPinnedRef = useRef(true);\n const wasBusyRef = useRef(busy);\n const rafIdRef = useRef<number>(0);\n\n const isAtBottom = useCallback(() => {\n const el = containerRef.current;\n if (!el) return true;\n return el.scrollTop + el.clientHeight >= el.scrollHeight - PIN_THRESHOLD;\n }, [containerRef]);\n\n const refreshJumpButton = useCallback(() => {\n const el = containerRef.current;\n if (!el) return;\n setShowJumpButton(\n !isPinnedRef.current && el.scrollHeight > el.clientHeight + PIN_THRESHOLD,\n );\n }, [containerRef]);\n\n const scrollToBottom = useCallback(\n (smooth = true) => {\n const el = containerRef.current;\n if (!el) return;\n isPinnedRef.current = true;\n setShowJumpButton(false);\n el.scrollTo({\n top: el.scrollHeight,\n behavior: smooth ? \"smooth\" : \"instant\",\n });\n },\n [containerRef],\n );\n\n // User-intent detection: only these gestures un-pin. Scroll events are\n // intentionally NOT listened to — they can't tell user gestures from our\n // own scrollTo.\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n\n // rAF lets the gesture's scroll delta land before we measure.\n let pendingFrame = 0;\n const onUserGesture = () => {\n if (pendingFrame) cancelAnimationFrame(pendingFrame);\n pendingFrame = requestAnimationFrame(() => {\n pendingFrame = 0;\n isPinnedRef.current = isAtBottom();\n refreshJumpButton();\n });\n };\n\n el.addEventListener(\"wheel\", onUserGesture, { passive: true });\n el.addEventListener(\"touchmove\", onUserGesture, { passive: true });\n el.addEventListener(\"keydown\", onUserGesture);\n // pointerdown on the scrollbar gutter starts a drag-scroll. The\n // drag itself fires no wheel/touch, but pointerdown's followup\n // scroll arrives within a frame; one rAF measure catches it.\n el.addEventListener(\"pointerdown\", onUserGesture);\n\n return () => {\n if (pendingFrame) cancelAnimationFrame(pendingFrame);\n el.removeEventListener(\"wheel\", onUserGesture);\n el.removeEventListener(\"touchmove\", onUserGesture);\n el.removeEventListener(\"keydown\", onUserGesture);\n el.removeEventListener(\"pointerdown\", onUserGesture);\n };\n }, [containerRef, isAtBottom, refreshJumpButton]);\n\n // Both busy edges re-pin: turn start = user just sent and expects to\n // see the reply; turn end = settle on the final answer (issue #1182).\n useEffect(() => {\n if (wasBusyRef.current !== busy) {\n scrollToBottom(true);\n }\n wasBusyRef.current = busy;\n }, [busy, scrollToBottom]);\n\n // Watch content size changes (streaming text, tool results, new\n // messages) and follow the bottom while pinned.\n useEffect(() => {\n const content = contentRef.current;\n if (!content) return;\n\n const ro = new ResizeObserver(() => {\n if (rafIdRef.current) cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = requestAnimationFrame(() => {\n rafIdRef.current = 0;\n const el = containerRef.current;\n if (!el) return;\n if (isPinnedRef.current) {\n el.scrollTo({ top: el.scrollHeight, behavior: \"instant\" });\n } else {\n refreshJumpButton();\n }\n });\n });\n\n ro.observe(content);\n return () => {\n ro.disconnect();\n if (rafIdRef.current) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = 0;\n }\n };\n }, [containerRef, contentRef, refreshJumpButton]);\n\n // Initial scroll when the hook mounts (e.g. session loaded). Restores the\n // saved offset if there is one (#1244), otherwise pins to the bottom.\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n const id = setTimeout(() => {\n const restore = getRestoreScrollTop?.() ?? null;\n if (restore != null && restore > PIN_THRESHOLD) {\n // Mid-transcript restore: stay un-pinned so content growth and the\n // ResizeObserver don't yank the view back to the bottom.\n isPinnedRef.current = false;\n el.scrollTop = restore;\n refreshJumpButton();\n } else {\n isPinnedRef.current = true;\n setShowJumpButton(false);\n el.scrollTo({ top: el.scrollHeight, behavior: \"instant\" });\n }\n }, 60);\n return () => clearTimeout(id);\n }, [containerRef, getRestoreScrollTop, refreshJumpButton]);\n\n return { showJumpButton, scrollToBottom };\n}\n","import { useEffect } from \"react\";\n\nconst TEXT_INPUT_SELECTOR =\n 'input, textarea, [contenteditable=\"\"], [contenteditable=\"true\"], [contenteditable=\"plaintext-only\"]';\n\nfunction getTextAssistAttrs() {\n return {\n autoCorrect: \"off\" as const,\n autoCapitalize: \"off\" as const,\n spellCheck: false as const,\n };\n}\n\nfunction isMacPlatform() {\n if (typeof document === \"undefined\") return false;\n return document.documentElement.dataset.platform === \"macos\";\n}\n\nfunction applyTextAssistAttrs(element: Element) {\n if (!(element instanceof HTMLElement)) return;\n if (\n !(element instanceof HTMLInputElement) &&\n !(element instanceof HTMLTextAreaElement) &&\n !element.isContentEditable\n ) {\n return;\n }\n\n const attrs = getTextAssistAttrs();\n element.setAttribute(\"autocorrect\", attrs.autoCorrect);\n element.setAttribute(\"autocapitalize\", attrs.autoCapitalize);\n element.setAttribute(\"spellcheck\", String(attrs.spellCheck));\n element.spellcheck = attrs.spellCheck;\n}\n\nfunction applyWithin(root: ParentNode) {\n if (root instanceof Element) {\n applyTextAssistAttrs(root);\n }\n root.querySelectorAll(TEXT_INPUT_SELECTOR).forEach(applyTextAssistAttrs);\n}\n\nexport function useDisableTextAssist() {\n useEffect(() => {\n if (typeof document === \"undefined\" || !isMacPlatform()) return;\n\n const root = document.body;\n if (!root) return;\n\n applyWithin(root);\n\n const handleFocusIn = (event: FocusEvent) => {\n if (event.target instanceof Element) {\n applyTextAssistAttrs(event.target);\n }\n };\n\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n mutation.addedNodes.forEach((node) => {\n if (node instanceof Element) {\n applyWithin(node);\n }\n });\n }\n });\n\n document.addEventListener(\"focusin\", handleFocusIn, true);\n observer.observe(root, { childList: true, subtree: true });\n\n return () => {\n document.removeEventListener(\"focusin\", handleFocusIn, true);\n observer.disconnect();\n };\n }, []);\n}\n","import { invoke } from \"@tauri-apps/api/core\";\nimport { listen } from \"@tauri-apps/api/event\";\nimport { getCurrentWindow } from \"@tauri-apps/api/window\";\nimport { open as openDialog, save as saveDialog } from \"@tauri-apps/plugin-dialog\";\nimport { isWebRuntime } from \"./lib/tauri-bridge\";\nimport { useCallback, useEffect, useReducer, useRef, useState } from \"react\";\nimport { CommandPalette, Toast, buildCommands, useCommandPalette } from \"./CommandPalette\";\nimport { WorkspaceProvider } from \"./Markdown\";\nimport { getLang, setLang, t, useLang } from \"./i18n\";\nimport { I } from \"./icons\";\nimport {\n FONT_FAMILY,\n FONT_FAMILY_STACK,\n FONT_SCALE,\n FONT_SCALE_ZOOM,\n type FontFamily,\n type FontScale,\n THEME,\n type Theme,\n type ThemeStyle,\n defaultStyleForTheme,\n isFontFamily,\n isFontScale,\n isTheme,\n isThemeStyle,\n themeForStyle,\n} from \"./theme\";\nimport type {\n CheckpointVerdict,\n ChoiceVerdict,\n ConfirmationChoice,\n IncomingEvent,\n JobInfo,\n McpSpecInfo,\n MemoryEntryInfo,\n OutgoingCommand,\n PlanVerdict,\n RevisionVerdict,\n SettingsPatch,\n SkillInfo,\n} from \"./protocol\";\nimport { readSessionFromUrl, writeSessionToUrl } from \"./lib/session-url\";\nimport { type QQDesktopSettingsState } from \"./qq-settings\";\nimport { Composer, type SlashCmd } from \"./ui/composer\";\nimport { ContextPanel } from \"./ui/context-panel\";\nimport { JobsPop } from \"./ui/jobs-pop\";\nimport { useElapsed } from \"./ui/live\";\nimport { AboutModal } from \"./ui/about\";\nimport { SettingsModal, type PageId as SettingsPageId } from \"./ui/settings\";\nimport { Sidebar } from \"./ui/sidebar\";\nimport { Shortcut, localizeShortcutText, shortcutText } from \"./ui/shortcut\";\nimport { Splash, shouldShowSplash } from \"./ui/splash\";\nimport { StatusBar } from \"./ui/statusbar\";\nimport {\n ActivePlanTaskCard,\n AssistantMsg,\n CheckpointApprovalCard,\n ChoiceApprovalCard,\n ConfirmApprovalCard,\n PathAccessApprovalCard,\n PlanApprovalCard,\n PlanBanner,\n RevisionApprovalCard,\n TurnDivider,\n UserMsg,\n} from \"./ui/thread\";\nimport { WorkdirPop } from \"./ui/workdir-pop\";\nimport { WorkdirInputModal } from \"./ui/workdir-input-modal\";\nimport { useAutoScroll } from \"./ui/useAutoScroll\";\nimport { useDisableTextAssist } from \"./ui/useDisableTextAssist\";\nimport { openUrl } from \"@tauri-apps/plugin-opener\";\n\nexport type AssistantSegment =\n | { kind: \"text\"; text: string }\n | { kind: \"reasoning\"; text: string }\n | {\n kind: \"tool\";\n callId: string;\n name: string;\n args: string;\n startedAt: number;\n result?: string;\n ok?: boolean;\n durationMs?: number;\n };\n\nexport type SkillOrigin = {\n name: string;\n runAs: \"inline\" | \"subagent\";\n};\n\nexport type ChatMessage =\n | { kind: \"user\"; text: string; clientId: string; turn: number; skill?: SkillOrigin }\n | {\n kind: \"assistant\";\n turn: number;\n segments: AssistantSegment[];\n pending: boolean;\n }\n | { kind: \"status\"; text: string }\n | { kind: \"warning\"; id: string; text: string; severity: \"low\" | \"high\" }\n | { kind: \"error\"; message: string };\n\nexport type PendingConfirm = {\n id: number;\n kind: \"run_command\" | \"run_background\";\n command: string;\n};\n\nexport type PendingPathAccess = {\n id: number;\n path: string;\n intent: \"read\" | \"write\";\n toolName: string;\n sandboxRoot: string;\n allowPrefix: string;\n};\n\nexport type PendingChoice = {\n id: number;\n question: string;\n options: { id: string; title: string; summary?: string }[];\n allowCustom: boolean;\n};\n\nexport type PendingPlan = {\n id: number;\n plan: string;\n summary?: string;\n steps?: PlanStep[];\n};\n\nexport type PlanStep = {\n id: string;\n title: string;\n action: string;\n risk?: \"low\" | \"med\" | \"high\";\n};\n\nexport type ActivePlan = {\n plan: string;\n summary?: string;\n steps: PlanStep[];\n completedStepIds: string[];\n stepResults: Record<string, string>;\n};\n\nexport type PendingCheckpoint = {\n id: number;\n stepId: string;\n title?: string;\n result: string;\n notes?: string;\n completed: number;\n total: number;\n};\n\nexport type PendingRevision = {\n id: number;\n reason: string;\n remainingSteps: PlanStep[];\n summary?: string;\n};\n\nexport type UsageStats = {\n totalCostUsd: number;\n totalPromptTokens: number;\n totalCompletionTokens: number;\n cacheHitTokens: number;\n cacheMissTokens: number;\n lastCallCacheHit: number | null;\n lastCallCacheMiss: number | null;\n /** System prompt + tool specs — constant for the session, sent on tab open. */\n reservedTokens: number;\n};\n\nexport type SessionInfo = {\n name: string;\n messageCount: number;\n mtime: string;\n summary?: string;\n};\n\nexport type Settings = {\n reasoningEffort: \"low\" | \"medium\" | \"high\" | \"max\";\n editMode: \"review\" | \"auto\" | \"yolo\";\n budgetUsd: number | null;\n baseUrl?: string;\n apiKeyPrefix?: string;\n workspaceDir: string;\n recentWorkspaces: string[];\n model: string;\n editor?: string;\n webSearchEngine?: \"bing\" | \"searxng\" | \"metaso\" | \"tavily\" | \"perplexity\" | \"exa\";\n subagentModels?: Record<string, \"flash\" | \"pro\">;\n showSystemEvents?: boolean;\n version: string;\n};\n\nexport type Balance = {\n currency: string;\n total: number;\n isAvailable: boolean;\n};\n\ntype MentionResults = { nonce: number; query: string; results: string[] };\ntype MentionPreviewState = {\n nonce: number;\n path: string;\n head: string;\n totalLines: number;\n};\n\ntype State = {\n ready: boolean;\n needsSetup: boolean;\n busy: boolean;\n model?: string;\n currentSession?: string;\n messages: ChatMessage[];\n pendingConfirms: PendingConfirm[];\n pendingPathAccess: PendingPathAccess[];\n pendingChoices: PendingChoice[];\n pendingPlans: PendingPlan[];\n pendingCheckpoints: PendingCheckpoint[];\n pendingRevisions: PendingRevision[];\n activePlan: ActivePlan | null;\n usage: UsageStats;\n sessions: SessionInfo[];\n settings: Settings | null;\n qq: QQDesktopSettingsState | null;\n balance: Balance | null;\n mentionResults: MentionResults | null;\n mentionPreview: MentionPreviewState | null;\n mcpSpecs: McpSpecInfo[];\n mcpBridged: boolean;\n skills: SkillInfo[];\n /** Files the agent has read or modified this session — paths as the tool args provided them. */\n sessionFiles: SessionFile[];\n memory: MemoryEntryInfo[];\n jobs: JobInfo[];\n /** Live \"skill running\" indicator — set when a `skill_run` RPC dispatches, cleared on `$turn_complete`. */\n activeSkill: SkillOrigin | null;\n /** Messages typed while busy=true — auto-sent FIFO once the current turn completes. Cleared on `clear`, `rpc_exit`, `session_loaded`. */\n queuedSends: string[];\n /** Populated by $retry_result — component useEffect reads and sets composer draft. */\n retryText?: string;\n retryNonce: number;\n};\n\nexport type SessionFile = {\n path: string;\n /** \"c\": pulled into context (read_file). \"m\": modified by the agent (edit_file / write_file / multi_edit). */\n status: \"c\" | \"m\";\n};\n\ntype DeltaBatchItem = {\n turn: number;\n channel: \"content\" | \"reasoning\";\n text: string;\n};\n\ntype Action =\n | { t: \"send_user\"; text: string; clientId: string }\n | { t: \"start_skill\"; skill: SkillOrigin; args?: string; clientId: string }\n | { t: \"incoming\"; event: IncomingEvent }\n | { t: \"batch_delta\"; items: DeltaBatchItem[] }\n | { t: \"rpc_exit\"; code: number | null }\n | { t: \"clear\" }\n | { t: \"resolve_confirm\"; id: number }\n | { t: \"resolve_path_access\"; id: number }\n | { t: \"resolve_choice\"; id: number }\n | { t: \"resolve_plan\"; id: number; verdict: PlanVerdict }\n | { t: \"resolve_checkpoint\"; id: number; verdict: CheckpointVerdict }\n | { t: \"resolve_revision\"; id: number; verdict: RevisionVerdict }\n | { t: \"dismiss_plan\" }\n | { t: \"mention_results\"; results: MentionResults }\n | { t: \"mention_preview\"; preview: MentionPreviewState }\n | { t: \"enqueue_send\"; text: string }\n | { t: \"dequeue_send\"; index: number }\n | { t: \"shift_queued_send\" };\n\nfunction fallbackSkillDesc(skill: SkillInfo): string {\n const scope =\n skill.scope === \"builtin\"\n ? t(\"app.skill.scope.builtin\")\n : skill.scope === \"global\"\n ? t(\"app.skill.scope.global\")\n : t(\"app.skill.scope.project\");\n const runAs =\n skill.runAs === \"subagent\"\n ? t(\"app.skill.runAs.subagent\")\n : t(\"app.skill.runAs.inline\");\n return t(\"app.skill.generic\", { scope, runAs });\n}\n\nfunction nextMessageTurn(messages: ChatMessage[]): number {\n const lastTurn = messages.reduce((max, m) => {\n if (m.kind === \"user\" || m.kind === \"assistant\") return Math.max(max, m.turn);\n return max;\n }, 0);\n return lastTurn + 1;\n}\n\nfunction reduce(state: State, action: Action): State {\n switch (action.t) {\n case \"send_user\": {\n return {\n ...state,\n busy: true,\n messages: [\n ...state.messages,\n { kind: \"user\", text: action.text, clientId: action.clientId, turn: nextMessageTurn(state.messages) },\n ],\n };\n }\n case \"start_skill\": {\n const argsLine = action.args ? ` ${action.args}` : \"\";\n return {\n ...state,\n busy: true,\n activeSkill: action.skill,\n messages: [\n ...state.messages,\n {\n kind: \"user\",\n text: `/${action.skill.name}${argsLine}`,\n clientId: action.clientId,\n turn: nextMessageTurn(state.messages),\n skill: action.skill,\n },\n ],\n };\n }\n case \"rpc_exit\":\n return {\n ...state,\n ready: false,\n busy: false,\n activeSkill: null,\n queuedSends: [],\n messages: [\n ...state.messages,\n { kind: \"error\", message: `reasonix exited (code ${action.code ?? \"?\"})` },\n ],\n };\n case \"incoming\":\n return applyIncoming(state, action.event);\n case \"batch_delta\": {\n const collapsed: DeltaBatchItem[] = [];\n for (const item of action.items) {\n const last = collapsed[collapsed.length - 1];\n if (last && last.turn === item.turn && last.channel === item.channel) {\n last.text += item.text;\n } else {\n collapsed.push({ ...item });\n }\n }\n return {\n ...state,\n messages: state.messages.map((m) => {\n if (m.kind !== \"assistant\") return m;\n const relevant = collapsed.filter((it) => it.turn === m.turn);\n if (relevant.length === 0) return m;\n let segments = m.segments;\n for (const it of relevant) {\n segments = appendTextSegment(\n segments,\n it.channel === \"content\" ? \"text\" : \"reasoning\",\n it.text,\n );\n }\n return { ...m, segments };\n }),\n };\n }\n case \"clear\":\n return {\n ...state,\n busy: false,\n currentSession: undefined,\n messages: [],\n pendingConfirms: [],\n pendingPathAccess: [],\n pendingChoices: [],\n pendingPlans: [],\n pendingCheckpoints: [],\n pendingRevisions: [],\n activePlan: null,\n usage: zeroUsage(),\n sessionFiles: [],\n activeSkill: null,\n queuedSends: [],\n retryNonce: 0,\n };\n case \"resolve_confirm\":\n return {\n ...state,\n pendingConfirms: state.pendingConfirms.filter((c) => c.id !== action.id),\n };\n case \"resolve_path_access\":\n return {\n ...state,\n pendingPathAccess: state.pendingPathAccess.filter((p) => p.id !== action.id),\n };\n case \"resolve_choice\":\n return {\n ...state,\n pendingChoices: state.pendingChoices.filter((c) => c.id !== action.id),\n };\n case \"resolve_plan\": {\n const removed = state.pendingPlans.find((p) => p.id === action.id);\n let activePlan = state.activePlan;\n if (removed && action.verdict.type === \"approve\") {\n const pendingSteps = (removed as PendingPlan & { steps?: PlanStep[] }).steps;\n activePlan = {\n plan: removed.plan,\n summary: removed.summary,\n steps: pendingSteps ?? [],\n completedStepIds: [],\n stepResults: {},\n };\n }\n return {\n ...state,\n pendingPlans: state.pendingPlans.filter((p) => p.id !== action.id),\n activePlan,\n };\n }\n case \"resolve_checkpoint\":\n return {\n ...state,\n pendingCheckpoints: state.pendingCheckpoints.filter((c) => c.id !== action.id),\n };\n case \"resolve_revision\": {\n const removed = state.pendingRevisions.find((r) => r.id === action.id);\n let activePlan = state.activePlan;\n if (removed && action.verdict.type === \"accepted\" && activePlan) {\n const doneIds = new Set(activePlan.completedStepIds);\n const keptDone = activePlan.steps.filter((s) => doneIds.has(s.id));\n activePlan = {\n ...activePlan,\n steps: [...keptDone, ...removed.remainingSteps],\n };\n }\n return {\n ...state,\n pendingRevisions: state.pendingRevisions.filter((r) => r.id !== action.id),\n activePlan,\n };\n }\n case \"dismiss_plan\":\n return { ...state, activePlan: null };\n case \"mention_results\":\n return { ...state, mentionResults: action.results };\n case \"mention_preview\":\n return { ...state, mentionPreview: action.preview };\n case \"enqueue_send\":\n return { ...state, queuedSends: [...state.queuedSends, action.text] };\n case \"dequeue_send\":\n return {\n ...state,\n queuedSends: state.queuedSends.filter((_, i) => i !== action.index),\n };\n case \"shift_queued_send\":\n return { ...state, queuedSends: state.queuedSends.slice(1) };\n }\n}\n\nconst READING_TOOLS = new Set([\"read_file\"]);\nconst MODIFYING_TOOLS = new Set([\"edit_file\", \"write_file\"]);\n\nfunction extractToolFiles(name: string, args: string): SessionFile[] {\n try {\n const parsed = JSON.parse(args) as { path?: unknown; edits?: unknown };\n if (READING_TOOLS.has(name) && typeof parsed?.path === \"string\") {\n return [{ path: parsed.path, status: \"c\" }];\n }\n if (MODIFYING_TOOLS.has(name) && typeof parsed?.path === \"string\") {\n return [{ path: parsed.path, status: \"m\" }];\n }\n if (name === \"multi_edit\" && Array.isArray(parsed?.edits)) {\n const out: SessionFile[] = [];\n const seen = new Set<string>();\n for (const e of parsed.edits as Array<{ path?: unknown }>) {\n if (typeof e?.path === \"string\" && !seen.has(e.path)) {\n seen.add(e.path);\n out.push({ path: e.path, status: \"m\" });\n }\n }\n return out;\n }\n } catch {\n // malformed args — skip; tool will error on the real side anyway\n }\n return [];\n}\n\nfunction mergeSessionFiles(existing: SessionFile[], adds: SessionFile[]): SessionFile[] {\n if (adds.length === 0) return existing;\n const next = [...existing];\n const indexByPath = new Map<string, number>();\n next.forEach((f, i) => indexByPath.set(f.path, i));\n let changed = false;\n for (const add of adds) {\n const idx = indexByPath.get(add.path);\n if (idx === undefined) {\n indexByPath.set(add.path, next.length);\n next.push(add);\n changed = true;\n continue;\n }\n const prev = next[idx];\n if (!prev || prev.status === \"m\") continue; // never downgrade m → c\n if (prev.status === add.status) continue;\n next[idx] = add;\n changed = true;\n }\n return changed ? next : existing;\n}\n\nfunction zeroUsage(): UsageStats {\n return {\n totalCostUsd: 0,\n totalPromptTokens: 0,\n totalCompletionTokens: 0,\n cacheHitTokens: 0,\n cacheMissTokens: 0,\n lastCallCacheHit: null,\n lastCallCacheMiss: null,\n reservedTokens: 0,\n };\n}\n\nfunction appendTextSegment(\n segments: AssistantSegment[],\n kind: \"text\" | \"reasoning\",\n text: string,\n): AssistantSegment[] {\n const last = segments[segments.length - 1];\n if (last && last.kind === kind) {\n return [...segments.slice(0, -1), { ...last, text: last.text + text }];\n }\n return [...segments, { kind, text }];\n}\n\nexport function applyIncoming(state: State, ev: IncomingEvent): State {\n switch (ev.type) {\n case \"user.message\": {\n const last = state.messages[state.messages.length - 1];\n if (state.busy && last?.kind === \"user\" && last.text === ev.text) {\n return state;\n }\n return {\n ...state,\n busy: true,\n messages: [\n ...state.messages,\n {\n kind: \"user\",\n text: ev.text,\n clientId: `remote-${ev.id}`,\n turn: ev.turn > 0 ? ev.turn : nextMessageTurn(state.messages),\n },\n ],\n };\n }\n case \"$ready\":\n return { ...state, ready: true, needsSetup: false };\n case \"$needs_setup\":\n return { ...state, needsSetup: true, ready: false };\n case \"$turn_complete\":\n return { ...state, busy: false, activeSkill: null };\n case \"$confirm_required\":\n return {\n ...state,\n pendingConfirms: [\n ...state.pendingConfirms,\n { id: ev.id, kind: ev.kind, command: ev.command },\n ],\n };\n case \"$path_access_required\":\n return {\n ...state,\n pendingPathAccess: [\n ...state.pendingPathAccess,\n {\n id: ev.id,\n path: ev.path,\n intent: ev.intent,\n toolName: ev.toolName,\n sandboxRoot: ev.sandboxRoot,\n allowPrefix: ev.allowPrefix,\n },\n ],\n };\n case \"$choice_required\":\n return {\n ...state,\n pendingChoices: [\n ...state.pendingChoices,\n {\n id: ev.id,\n question: ev.question,\n options: ev.options,\n allowCustom: ev.allowCustom,\n },\n ],\n };\n case \"$plan_required\": {\n const steps = Array.isArray(ev.steps) ? (ev.steps as PlanStep[]) : undefined;\n return {\n ...state,\n pendingPlans: [\n ...state.pendingPlans,\n { id: ev.id, plan: ev.plan, summary: ev.summary, ...(steps ? { steps } : {}) },\n ],\n };\n }\n case \"$checkpoint_required\":\n return {\n ...state,\n pendingCheckpoints: [\n ...state.pendingCheckpoints,\n {\n id: ev.id,\n stepId: ev.stepId,\n title: ev.title,\n result: ev.result,\n notes: ev.notes,\n completed: ev.completed,\n total: ev.total,\n },\n ],\n };\n case \"$revision_required\":\n return {\n ...state,\n pendingRevisions: [\n ...state.pendingRevisions,\n {\n id: ev.id,\n reason: ev.reason,\n remainingSteps: ev.remainingSteps,\n summary: ev.summary,\n },\n ],\n };\n case \"$step_completed\": {\n if (!state.activePlan) return state;\n const stepIds = new Set(state.activePlan.completedStepIds);\n stepIds.add(ev.stepId);\n return {\n ...state,\n activePlan: {\n ...state.activePlan,\n completedStepIds: [...stepIds],\n stepResults: { ...state.activePlan.stepResults, [ev.stepId]: ev.result },\n },\n };\n }\n case \"$plan_cleared\":\n return {\n ...state,\n activePlan: null,\n pendingCheckpoints: [],\n pendingRevisions: [],\n };\n case \"$sessions\":\n return { ...state, sessions: ev.items };\n case \"$mcp_specs\":\n return {\n ...state,\n mcpSpecs: Array.isArray(ev.specs) ? ev.specs : [],\n mcpBridged: Boolean(ev.bridged),\n };\n case \"$skills\":\n return { ...state, skills: ev.items };\n case \"$ctx_breakdown\":\n return { ...state, usage: { ...state.usage, reservedTokens: ev.reservedTokens } };\n case \"$memory\":\n return { ...state, memory: ev.entries };\n case \"$jobs\":\n return { ...state, jobs: ev.items };\n case \"$balance\":\n return {\n ...state,\n balance: {\n currency: ev.currency,\n total: ev.total,\n isAvailable: ev.isAvailable,\n },\n };\n case \"$qq_settings\":\n return {\n ...state,\n qq: {\n appId: ev.appId,\n appSecret: ev.appSecret,\n sandbox: ev.sandbox,\n enabled: ev.enabled,\n configured: ev.configured,\n runtimeState: ev.runtimeState,\n lastError: ev.lastError,\n appIdPreview: ev.appIdPreview,\n access: ev.access,\n },\n };\n case \"$settings\": {\n const prevWs = state.settings?.workspaceDir;\n const wsChanged = prevWs !== undefined && prevWs !== ev.workspaceDir;\n return {\n ...state,\n busy: wsChanged ? false : state.busy,\n messages: wsChanged ? [] : state.messages,\n pendingConfirms: wsChanged ? [] : state.pendingConfirms,\n pendingPathAccess: wsChanged ? [] : state.pendingPathAccess,\n pendingChoices: wsChanged ? [] : state.pendingChoices,\n pendingPlans: wsChanged ? [] : state.pendingPlans,\n pendingCheckpoints: wsChanged ? [] : state.pendingCheckpoints,\n pendingRevisions: wsChanged ? [] : state.pendingRevisions,\n activePlan: wsChanged ? null : state.activePlan,\n usage: wsChanged ? zeroUsage() : state.usage,\n sessionFiles: wsChanged ? [] : state.sessionFiles,\n retryNonce: wsChanged ? 0 : state.retryNonce,\n settings: {\n reasoningEffort: ev.reasoningEffort,\n editMode: ev.editMode,\n budgetUsd: ev.budgetUsd,\n baseUrl: ev.baseUrl,\n apiKeyPrefix: ev.apiKeyPrefix,\n workspaceDir: ev.workspaceDir,\n recentWorkspaces: ev.recentWorkspaces,\n model: ev.model,\n editor: ev.editor,\n webSearchEngine: ev.webSearchEngine,\n subagentModels: ev.subagentModels,\n showSystemEvents: ev.showSystemEvents,\n version: ev.version,\n },\n };\n }\n case \"$session_loaded\": {\n const sessionName = ev.name;\n const loaded: ChatMessage[] = ev.messages.map((m, i) => {\n if (m.kind === \"user\") {\n return { kind: \"user\", text: m.text, clientId: `c-loaded-${i}`, turn: i + 1 };\n }\n const segments: AssistantSegment[] = m.segments.map((s) => {\n if (s.kind === \"tool\") {\n return {\n kind: \"tool\",\n callId: s.callId,\n name: s.name,\n args: s.args,\n startedAt: 0,\n result: s.result,\n ok: s.ok,\n durationMs: 0,\n };\n }\n return s;\n });\n return { kind: \"assistant\", turn: m.turn, segments, pending: false };\n });\n let sessionFiles: SessionFile[] = [];\n for (const m of loaded) {\n if (m.kind !== \"assistant\") continue;\n for (const s of m.segments) {\n if (s.kind !== \"tool\") continue;\n // For replayed sessions we don't have tool.result ok-status here, but\n // segments only survive into history if the call completed. Trust it.\n sessionFiles = mergeSessionFiles(sessionFiles, extractToolFiles(s.name, s.args));\n }\n }\n return {\n ...state,\n busy: false,\n currentSession: sessionName,\n messages: loaded,\n pendingConfirms: [],\n pendingPathAccess: [],\n pendingChoices: [],\n pendingPlans: [],\n pendingCheckpoints: [],\n pendingRevisions: [],\n activePlan: null,\n usage: {\n ...zeroUsage(),\n totalCostUsd: ev.carryover.totalCostUsd,\n totalPromptTokens: ev.carryover.cacheHitTokens + ev.carryover.cacheMissTokens,\n cacheHitTokens: ev.carryover.cacheHitTokens,\n cacheMissTokens: ev.carryover.cacheMissTokens,\n },\n sessionFiles,\n activeSkill: null,\n queuedSends: [],\n retryNonce: 0,\n };\n }\n case \"$session_empty\": {\n // The sidecar successfully ran loadSessionMessages but the jsonl is\n // empty / all-malformed. Without this, the click looks like a no-op\n // because the chat just re-renders empty. Issue #1179.\n const sizeNote = ev.sizeBytes === 0 ? \"0 bytes\" : `${ev.sizeBytes} bytes, no valid entries`;\n return {\n ...state,\n messages: [\n ...state.messages,\n {\n kind: \"error\",\n message:\n `Session \"${ev.name}\" loaded with no messages (${sizeNote}). ` +\n `The file ~/.reasonix/sessions/${ev.name}.jsonl exists but couldn't be parsed — ` +\n `start a new chat or restore from .jsonl.bak if you have one.`,\n },\n ],\n };\n }\n case \"$error\":\n case \"error\":\n return {\n ...state,\n busy: false,\n activeSkill: null,\n messages: [...state.messages, { kind: \"error\", message: ev.message }],\n };\n case \"model.turn.started\":\n if (state.messages.some((m) => m.kind === \"assistant\" && m.turn === ev.turn)) {\n return { ...state, model: ev.model };\n }\n return {\n ...state,\n model: ev.model,\n messages: [\n ...state.messages,\n { kind: \"assistant\", turn: ev.turn, segments: [], pending: true },\n ],\n };\n case \"model.delta\":\n return {\n ...state,\n messages: state.messages.map((m) => {\n if (m.kind !== \"assistant\" || m.turn !== ev.turn) return m;\n if (ev.channel === \"content\") {\n return { ...m, segments: appendTextSegment(m.segments, \"text\", ev.text) };\n }\n if (ev.channel === \"reasoning\") {\n return { ...m, segments: appendTextSegment(m.segments, \"reasoning\", ev.text) };\n }\n return m;\n }),\n };\n case \"model.final\": {\n const u = ev.usage;\n const callHit = u?.prompt_cache_hit_tokens ?? 0;\n const callMiss = u?.prompt_cache_miss_tokens ?? 0;\n const hasCall = callHit > 0 || callMiss > 0;\n const usage: UsageStats = {\n totalCostUsd: state.usage.totalCostUsd + (ev.costUsd ?? 0),\n totalPromptTokens: state.usage.totalPromptTokens + (u?.prompt_tokens ?? 0),\n totalCompletionTokens: state.usage.totalCompletionTokens + (u?.completion_tokens ?? 0),\n cacheHitTokens: state.usage.cacheHitTokens + callHit,\n cacheMissTokens: state.usage.cacheMissTokens + callMiss,\n lastCallCacheHit: hasCall ? callHit : state.usage.lastCallCacheHit,\n lastCallCacheMiss: hasCall ? callMiss : state.usage.lastCallCacheMiss,\n reservedTokens: state.usage.reservedTokens,\n };\n return {\n ...state,\n usage,\n messages: state.messages.map((m) => {\n if (m.kind !== \"assistant\" || m.turn !== ev.turn) return m;\n return { ...m, pending: false };\n }),\n };\n }\n case \"tool.preparing\":\n return {\n ...state,\n messages: state.messages.map((m) => {\n if (m.kind !== \"assistant\" || m.turn !== ev.turn) return m;\n if (m.segments.some((s) => s.kind === \"tool\" && s.callId === ev.callId)) return m;\n return {\n ...m,\n segments: [\n ...m.segments,\n {\n kind: \"tool\",\n callId: ev.callId,\n name: ev.name,\n args: \"\",\n startedAt: Date.now(),\n },\n ],\n };\n }),\n };\n case \"tool.intent\": {\n const adds = extractToolFiles(ev.name, ev.args);\n return {\n ...state,\n sessionFiles: mergeSessionFiles(state.sessionFiles, adds),\n messages: state.messages.map((m) => {\n if (m.kind !== \"assistant\" || m.turn !== ev.turn) return m;\n const idx = m.segments.findIndex((s) => s.kind === \"tool\" && s.callId === ev.callId);\n if (idx >= 0) {\n const segs = [...m.segments];\n const seg = segs[idx];\n if (seg?.kind === \"tool\") {\n segs[idx] = { ...seg, args: ev.args };\n }\n return { ...m, segments: segs };\n }\n return {\n ...m,\n segments: [\n ...m.segments,\n {\n kind: \"tool\",\n callId: ev.callId,\n name: ev.name,\n args: ev.args,\n startedAt: Date.now(),\n },\n ],\n };\n }),\n };\n }\n case \"tool.result\":\n return {\n ...state,\n messages: state.messages.map((m) => {\n if (m.kind !== \"assistant\") return m;\n let mutated = false;\n const segs = m.segments.map((s) => {\n if (s.kind === \"tool\" && s.callId === ev.callId) {\n mutated = true;\n return {\n ...s,\n result: ev.output,\n ok: ev.ok,\n durationMs: Date.now() - s.startedAt,\n };\n }\n return s;\n });\n return mutated ? { ...m, segments: segs } : m;\n }),\n };\n case \"$retry_result\":\n return { ...state, retryText: ev.text, retryNonce: state.retryNonce + 1 };\n case \"$btw_result\":\n return {\n ...state,\n messages: [\n ...state.messages,\n { kind: \"status\", text: `≫ btw\\n${ev.answer}` },\n ],\n };\n case \"status\":\n return state;\n case \"warning\":\n // High-severity only — eventize already drops \"low\". Render as a quiet\n // inline divider so users see compaction / abort / rate-limit events\n // without confusing them for errors.\n if (ev.severity !== \"high\") return state;\n return {\n ...state,\n messages: [\n ...state.messages,\n {\n kind: \"warning\",\n id: `w-${ev.id}`,\n text: ev.text,\n severity: ev.severity,\n },\n ],\n };\n default:\n return state;\n }\n}\n\nfunction formatConversationMarkdown(messages: ChatMessage[], userLabel: string): string {\n return messages\n .map((m) => {\n if (m.kind === \"user\") return `### ${userLabel}\\n\\n${m.text}`;\n if (m.kind === \"assistant\") {\n const body = m.segments\n .map((s) => {\n if (s.kind === \"text\") return s.text;\n if (s.kind === \"reasoning\")\n return `<details>\\n<summary>${t(\"app.exportReasoningSummary\")}</summary>\\n\\n${s.text}\\n\\n</details>`;\n if (s.kind === \"tool\") {\n const arg = s.args ? `\\n\\n\\`\\`\\`json\\n${s.args}\\n\\`\\`\\`` : \"\";\n const res = s.result ? `\\n\\n\\`\\`\\`\\n${s.result}\\n\\`\\`\\`` : \"\";\n return `> **${t(\"app.exportToolLabel\")} · \\`${s.name}\\`**${arg}${res}`;\n }\n return \"\";\n })\n .filter(Boolean)\n .join(\"\\n\\n\");\n return `### Reasonix\\n\\n${body}`;\n }\n if (m.kind === \"error\") return `### Error\\n\\n${m.message}`;\n return \"\";\n })\n .filter(Boolean)\n .join(\"\\n\\n---\\n\\n\");\n}\n\nfunction sanitizeFilename(name: string): string {\n return name.replace(/[<>:\"/\\\\|?*\\x00-\\x1f]/g, \"_\").replace(/^\\.+/, \"\").slice(0, 200) || \"session\";\n}\n\nfunction defaultExportFilename(session: string): string {\n const safe = sanitizeFilename(session);\n return `${safe}.md`;\n}\n\ntype TabAction = Action;\ntype TabDispatcher = (action: TabAction) => void;\n\ninterface TabRuntimeProps {\n tabId: string;\n active: boolean;\n currency: \"CNY\" | \"USD\";\n registerDispatch: (tabId: string, d: TabDispatcher | null) => void;\n onNewTab: () => void;\n onCloseTab: () => void;\n canCloseTab: boolean;\n theme: Theme;\n themeStyle: ThemeStyle;\n onSetTheme: (theme: Theme) => void;\n onSetThemeStyle: (style: ThemeStyle) => void;\n onToggleTheme: () => void;\n fontScale: FontScale;\n onSetFontScale: (scale: FontScale) => void;\n fontFamily: FontFamily;\n onSetFontFamily: (family: FontFamily) => void;\n sideCollapsed: boolean;\n ctxCollapsed: boolean;\n onToggleSide: () => void;\n onToggleCtx: () => void;\n onToggleCurrency: () => void;\n tabsList: { id: string; workspaceDir?: string }[];\n activeTabId: string;\n setActiveTabId: (id: string) => void;\n /** 移动端专用:当前侧边栏抽屉是否展开 */\n mobileSideOpen: boolean;\n onToggleMobileSide: () => void;\n}\n\nfunction TabRuntime({\n tabId,\n active,\n currency,\n registerDispatch,\n onNewTab,\n onCloseTab,\n canCloseTab,\n theme,\n themeStyle,\n onSetTheme,\n onSetThemeStyle,\n onToggleTheme,\n fontScale,\n onSetFontScale,\n fontFamily,\n onSetFontFamily,\n sideCollapsed,\n ctxCollapsed,\n onToggleSide,\n onToggleCtx,\n onToggleCurrency,\n tabsList,\n activeTabId,\n setActiveTabId,\n mobileSideOpen,\n onToggleMobileSide,\n}: TabRuntimeProps) {\n const [state, dispatch] = useReducer(reduce, {\n ready: false,\n needsSetup: false,\n busy: false,\n messages: [],\n pendingConfirms: [],\n pendingPathAccess: [],\n pendingChoices: [],\n pendingPlans: [],\n pendingCheckpoints: [],\n pendingRevisions: [],\n activePlan: null,\n usage: zeroUsage(),\n sessions: [],\n settings: null,\n qq: null,\n balance: null,\n mentionResults: null,\n mentionPreview: null,\n mcpSpecs: [],\n mcpBridged: false,\n skills: [],\n sessionFiles: [],\n memory: [],\n jobs: [],\n activeSkill: null,\n queuedSends: [],\n retryNonce: 0,\n });\n useLang();\n useDisableTextAssist();\n const [draft, setDraft] = useState(\"\");\n const [toast, setToast] = useState<{ msg: string; yolo?: boolean } | null>(null);\n const [splashOn, setSplashOn] = useState<boolean>(() => shouldShowSplash());\n const [wdOpen, setWdOpen] = useState(false);\n const [wdAnchor, setWdAnchor] = useState<\n { top?: number; bottom?: number; left: number } | undefined\n >(undefined);\n const composerRef = useRef<HTMLTextAreaElement>(null);\n const threadRef = useRef<HTMLDivElement>(null);\n const threadInnerRef = useRef<HTMLDivElement>(null);\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [settingsPage, setSettingsPage] = useState<SettingsPageId>(\"general\");\n const [jobsOpen, setJobsOpen] = useState(false);\n const [aboutOpen, setAboutOpen] = useState(false);\n // Pending session swap — set on sidebar click, cleared once the bridge's\n // $session_loaded lands (via the effect below). Big sessions take a beat to\n // pull off disk; without this the click looks dead.\n const [loadingSession, setLoadingSession] = useState<string | null>(null);\n const [workdirModalOpen, setWorkdirModalOpen] = useState(false);\n useEffect(() => {\n if (loadingSession && state.currentSession === loadingSession) {\n setLoadingSession(null);\n }\n }, [loadingSession, state.currentSession]);\n const openSettingsAt = useCallback((page: SettingsPageId = \"general\") => {\n setSettingsPage(page);\n setSettingsOpen(true);\n }, []);\n const palette = useCommandPalette(active);\n\n useEffect(() => {\n registerDispatch(tabId, dispatch);\n return () => registerDispatch(tabId, null);\n }, [tabId, registerDispatch]);\n\n const sendRpc = useCallback(\n (cmd: OutgoingCommand) => {\n const payload = { tabId, ...cmd };\n invoke(\"rpc_send\", { line: JSON.stringify(payload) }).catch((err) =>\n console.error(`${cmd.cmd} failed`, err),\n );\n },\n [tabId],\n );\n\n const queryMentions = useCallback(\n (query: string, nonce: number) => sendRpc({ cmd: \"mention_query\", query, nonce }),\n [sendRpc],\n );\n const previewMention = useCallback(\n (path: string, nonce: number) => sendRpc({ cmd: \"mention_preview\", path, nonce }),\n [sendRpc],\n );\n const markMentionPicked = useCallback(\n (path: string) => sendRpc({ cmd: \"mention_picked\", path }),\n [sendRpc],\n );\n const saveSettings = useCallback(\n (patch: SettingsPatch) => sendRpc({ cmd: \"settings_save\", ...patch }),\n [sendRpc],\n );\n const loadQQSettings = useCallback(() => sendRpc({ cmd: \"qq_status_get\" }), [sendRpc]);\n const connectQQ = useCallback(() => sendRpc({ cmd: \"qq_connect\" }), [sendRpc]);\n const disconnectQQ = useCallback(() => sendRpc({ cmd: \"qq_disconnect\" }), [sendRpc]);\n const saveQQConfig = useCallback(\n (patch: { appId?: string; appSecret?: string; sandbox: boolean }) =>\n sendRpc({ cmd: \"qq_config_save\", ...patch }),\n [sendRpc],\n );\n const saveApiKey = useCallback(\n (key: string) => sendRpc({ cmd: \"setup_save_key\", key }),\n [sendRpc],\n );\n const addMcpSpec = useCallback(\n (spec: string) => sendRpc({ cmd: \"mcp_specs_add\", spec }),\n [sendRpc],\n );\n const removeMcpSpec = useCallback(\n (spec: string) => sendRpc({ cmd: \"mcp_specs_remove\", spec }),\n [sendRpc],\n );\n const newChat = useCallback(() => {\n sendRpc({ cmd: \"new_chat\" });\n dispatch({ t: \"clear\" });\n }, [sendRpc]);\n\n const pickWorkspace = useCallback(async () => {\n // Browsers can't expose absolute filesystem paths (webkitdirectory only\n // hands back relative + File handles), so the web runtime opens a custom\n // server-backed directory browser instead of the native dialog. Desktop\n // (Tauri) still gets the OS picker for free.\n if (isWebRuntime) {\n setWorkdirModalOpen(true);\n return;\n }\n try {\n const picked = await openDialog({\n directory: true,\n multiple: false,\n title: t(\"workdir.title\"),\n defaultPath: state.settings?.workspaceDir,\n });\n if (typeof picked === \"string\" && picked.length > 0) {\n saveSettings({ workspaceDir: picked });\n }\n } catch (err) {\n console.error(\"pickWorkspace failed\", err);\n }\n }, [saveSettings, state.settings?.workspaceDir]);\n\n const flashToast = useCallback(\n (msg: string, opts?: { yolo?: boolean; duration?: number }) => {\n setToast({ msg, yolo: opts?.yolo });\n window.setTimeout(() => setToast(null), opts?.duration ?? 1600);\n },\n [],\n );\n\n // Drag-and-drop: dropping files/folders onto the window inserts them\n // as @-mentions in the draft (relative to workspaceDir when inside it).\n // activeRef gates the handler — without it, a single drop hits every\n // mounted tab's draft (issue #1027, exposed once #1063 restored tabs).\n const dropActiveRef = useRef(active);\n useEffect(() => {\n dropActiveRef.current = active;\n }, [active]);\n useEffect(() => {\n const ws = state.settings?.workspaceDir;\n let unlisten: (() => void) | null = null;\n let cancelled = false;\n void (async () => {\n try {\n const mod = await import(\"@tauri-apps/api/webview\");\n const webview = mod.getCurrentWebview();\n const handle = await webview.onDragDropEvent((event: any) => {\n if (!dropActiveRef.current) return;\n if (event.payload.type === \"enter\") {\n document.body.style.setProperty(\n \"--drop-overlay-label\",\n `\"${t(\"dragDrop.overlay\")}\"`,\n );\n document.body.dataset.dragOver = \"1\";\n return;\n }\n if (event.payload.type === \"leave\") {\n delete document.body.dataset.dragOver;\n return;\n }\n if (event.payload.type !== \"drop\") return;\n delete document.body.dataset.dragOver;\n const paths = event.payload.paths ?? [];\n if (paths.length === 0) return;\n const mentions = paths.map((p: string) => {\n const norm = p.replace(/\\\\/g, \"/\");\n if (ws) {\n const wsNorm = ws.replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\");\n if (norm === wsNorm || norm.startsWith(`${wsNorm}/`)) {\n return norm.slice(wsNorm.length).replace(/^\\/+/, \"\") || \".\";\n }\n }\n return norm;\n });\n setDraft((d) => {\n const prefix = d.trim() ? `${d.replace(/\\s+$/, \"\")} ` : \"\";\n return `${prefix}${mentions.map((m: string) => `@${m}`).join(\" \")} `;\n });\n for (const m of mentions) markMentionPicked(m as string);\n composerRef.current?.focus();\n });\n if (cancelled) handle();\n else unlisten = handle;\n } catch (err) {\n console.error(\"drag-drop listen failed\", err);\n }\n })();\n return () => {\n cancelled = true;\n unlisten?.();\n delete document.body.dataset.dragOver;\n };\n }, [state.settings?.workspaceDir, markMentionPicked]);\n\n const send = useCallback(\n (override?: string) => {\n const text = (override ?? draft).trim();\n if (!text || !state.ready || state.busy) return;\n\n // /btw <question> — route to side-question RPC instead of user_input\n const btwMatch = /^\\/btw(?:\\s+([\\s\\S]+))?$/.exec(text);\n if (btwMatch) {\n const question = btwMatch[1]?.trim() ?? \"\";\n if (!question) return;\n sendRpc({ cmd: \"btw\", text: question });\n if (!override) setDraft(\"\");\n return;\n }\n\n const skillMatch = text.match(/^\\/([a-zA-Z0-9_-]+)(\\s+.*)?$/);\n if (skillMatch) {\n const [, name, args] = skillMatch;\n const skill = state.skills.find((s) => s.name === name);\n if (skill) {\n const clientId = `skill-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n const trimmedArgs = args?.trim() ?? \"\";\n dispatch({ t: \"start_skill\", skill: { name: skill.name, runAs: skill.runAs }, args: trimmedArgs, clientId });\n sendRpc({ cmd: \"skill_run\", name: skill.name, args: trimmedArgs || undefined });\n if (!override) setDraft(\"\");\n return;\n }\n }\n const clientId = `c-${Date.now()}`;\n dispatch({ t: \"send_user\", text, clientId });\n sendRpc({ cmd: \"user_input\", text });\n if (!override) setDraft(\"\");\n },\n [draft, state.ready, state.busy, state.skills, sendRpc],\n );\n\n const abort = useCallback(() => sendRpc({ cmd: \"abort\" }), [sendRpc]);\n\n // When /retry returns the last user text, set it as the composer draft\n useEffect(() => {\n if (state.retryNonce > 0 && state.retryText) {\n setDraft(state.retryText);\n composerRef.current?.focus();\n }\n // Only fire when retryNonce changes — retryText alone would re-fire on re-renders\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [state.retryNonce]);\n\n useEffect(() => {\n if (state.busy || !state.ready || state.queuedSends.length === 0) return;\n const next = state.queuedSends[0];\n if (!next) return;\n dispatch({ t: \"shift_queued_send\" });\n send(next);\n }, [state.busy, state.ready, state.queuedSends, send]);\n\n const resolveConfirm = useCallback(\n (id: number, response: ConfirmationChoice) => {\n sendRpc({ cmd: \"confirm_response\", id, response });\n dispatch({ t: \"resolve_confirm\", id });\n },\n [sendRpc],\n );\n const onApproveConfirm = useCallback(\n (id: number) => resolveConfirm(id, { type: \"run_once\" }),\n [resolveConfirm],\n );\n const onRejectConfirm = useCallback(\n (id: number) => resolveConfirm(id, { type: \"deny\" }),\n [resolveConfirm],\n );\n const onAlwaysAllowConfirm = useCallback(\n (id: number, prefix: string) => resolveConfirm(id, { type: \"always_allow\", prefix }),\n [resolveConfirm],\n );\n const resolvePathAccess = useCallback(\n (id: number, response: ConfirmationChoice) => {\n sendRpc({ cmd: \"confirm_response\", id, response });\n dispatch({ t: \"resolve_path_access\", id });\n },\n [sendRpc],\n );\n const resolveChoice = useCallback(\n (id: number, response: ChoiceVerdict) => {\n sendRpc({ cmd: \"choice_response\", id, response });\n dispatch({ t: \"resolve_choice\", id });\n },\n [sendRpc],\n );\n const resolvePlan = useCallback(\n (id: number, response: PlanVerdict) => {\n sendRpc({ cmd: \"plan_response\", id, response });\n dispatch({ t: \"resolve_plan\", id, verdict: response });\n },\n [sendRpc],\n );\n const resolveCheckpoint = useCallback(\n (id: number, response: CheckpointVerdict) => {\n sendRpc({ cmd: \"checkpoint_response\", id, response });\n dispatch({ t: \"resolve_checkpoint\", id, verdict: response });\n },\n [sendRpc],\n );\n const resolveRevision = useCallback(\n (id: number, response: RevisionVerdict) => {\n sendRpc({ cmd: \"revision_response\", id, response });\n dispatch({ t: \"resolve_revision\", id, verdict: response });\n },\n [sendRpc],\n );\n\n // Read the latest session inside the stable restore callback below.\n const currentSessionRef = useRef(state.currentSession);\n currentSessionRef.current = state.currentSession;\n const restoreScrollTop = useCallback(() => {\n const session = currentSessionRef.current;\n if (!session) return null;\n const raw = localStorage.getItem(`reasonix.scroll.${session}`);\n const n = raw ? Number(raw) : Number.NaN;\n return Number.isFinite(n) ? n : null;\n }, []);\n\n const { showJumpButton, scrollToBottom } = useAutoScroll(\n threadRef,\n threadInnerRef,\n state.busy,\n restoreScrollTop,\n );\n\n // Persist the transcript scroll offset per session so a restart reopens\n // the conversation where the user left it (#1244).\n useEffect(() => {\n const el = threadRef.current;\n const session = state.currentSession;\n if (!el || !session) return;\n const key = `reasonix.scroll.${session}`;\n let timer: ReturnType<typeof setTimeout>;\n const onScroll = () => {\n clearTimeout(timer);\n timer = setTimeout(() => {\n const atBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - 80;\n if (atBottom) localStorage.removeItem(key);\n else localStorage.setItem(key, String(Math.round(el.scrollTop)));\n }, 250);\n };\n el.addEventListener(\"scroll\", onScroll, { passive: true });\n return () => {\n el.removeEventListener(\"scroll\", onScroll);\n clearTimeout(timer);\n };\n }, [state.currentSession]);\n\n useEffect(() => {\n if (!active) return;\n if (!jobsOpen) return;\n sendRpc({ cmd: \"jobs_list\" });\n const id = window.setInterval(() => sendRpc({ cmd: \"jobs_list\" }), 1500);\n return () => window.clearInterval(id);\n }, [active, jobsOpen, sendRpc]);\n\n useEffect(() => {\n if (!active) return;\n if (state.busy) return;\n sendRpc({ cmd: \"jobs_list\" });\n }, [active, state.busy, sendRpc]);\n\n useEffect(() => {\n if (!active) return;\n loadQQSettings();\n }, [active, loadQQSettings]);\n\n const initialUrlSession = useRef<string | null>(readSessionFromUrl());\n const urlSessionDispatched = useRef(false);\n useEffect(() => {\n if (!active) return;\n if (urlSessionDispatched.current) return;\n if (!state.ready) return;\n if (state.sessions.length === 0) return;\n urlSessionDispatched.current = true;\n const target = initialUrlSession.current;\n if (!target) return;\n if (target === state.currentSession) return;\n if (!state.sessions.some((s) => s.name === target)) {\n writeSessionToUrl(null);\n return;\n }\n sendRpc({ cmd: \"session_load\", name: target });\n }, [active, state.ready, state.sessions, state.currentSession, sendRpc]);\n\n useEffect(() => {\n // Every TabRuntime stays mounted (display:none on inactive), so each registers its own keydown — without this gate Cmd+N would fire newChat() in every tab and wipe the inactive ones' sessions.\n if (!active) return;\n const onKey = (e: KeyboardEvent) => {\n const mod = e.ctrlKey || e.metaKey;\n if (mod && (e.key === \"a\" || e.key === \"A\")) {\n const tag = (e.target as HTMLElement)?.tagName;\n if (tag !== \"INPUT\" && tag !== \"TEXTAREA\") e.preventDefault();\n return;\n }\n if (mod && (e.key === \"l\" || e.key === \"L\")) {\n e.preventDefault();\n composerRef.current?.focus();\n } else if (mod && (e.key === \"n\" || e.key === \"N\")) {\n e.preventDefault();\n newChat();\n } else if (mod && (e.key === \"o\" || e.key === \"O\")) {\n e.preventDefault();\n setWdAnchor(undefined);\n setWdOpen((v) => !v);\n } else if (mod && e.key === \",\") {\n e.preventDefault();\n if (settingsOpen) setSettingsOpen(false);\n else openSettingsAt(\"general\");\n } else if (mod && (e.key === \"j\" || e.key === \"J\")) {\n e.preventDefault();\n setJobsOpen((v) => !v);\n } else if (e.key === \"Escape\" && state.busy) {\n const target = e.target as HTMLElement | null;\n if (target?.tagName === \"INPUT\" || target?.tagName === \"TEXTAREA\") return;\n e.preventDefault();\n abort();\n }\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [active, state.busy, abort, newChat, settingsOpen, openSettingsAt]);\n\n const commands = buildCommands({\n newChat: () => {\n newChat();\n flashToast(t(\"app.toast.newSession\"));\n },\n clearChat: () => {\n dispatch({ t: \"clear\" });\n flashToast(t(\"app.toast.cleared\"));\n },\n focusComposer: () => composerRef.current?.focus(),\n openSettings: () => openSettingsAt(\"general\"),\n about: () => setAboutOpen(true),\n abort,\n copyLast: () => {\n const last = [...state.messages].reverse().find((m) => m.kind === \"assistant\");\n if (!last || last.kind !== \"assistant\") return;\n const text = last.segments\n .filter((s): s is { kind: \"text\"; text: string } => s.kind === \"text\")\n .map((s) => s.text)\n .join(\"\\n\\n\")\n .trim();\n if (text) {\n void navigator.clipboard.writeText(text);\n flashToast(t(\"app.toast.copied\"));\n }\n },\n conversationCopy: () => {\n conversationCopy();\n },\n exportMarkdown: () => {\n exportConversation();\n },\n pickWorkspace,\n newTab: onNewTab,\n closeTab: onCloseTab,\n busy: state.busy,\n canCloseTab,\n hasMessages: state.messages.length > 0,\n });\n\n const slashCommands: SlashCmd[] = [\n {\n cmd: \"/help\",\n desc: t(\"app.cmd.help\"),\n run: () => {\n setDraft(\"/\");\n composerRef.current?.focus();\n },\n },\n { cmd: \"/new\", desc: t(\"app.cmd.newSession\"), run: () => newChat(), kb: shortcutText([\"mod\", \"N\"]) },\n { cmd: \"/clear\", desc: t(\"app.cmd.clearChat\"), run: () => dispatch({ t: \"clear\" }) },\n { cmd: \"/abort\", desc: t(\"app.cmd.abort\"), run: () => abort(), kb: \"esc\" },\n {\n cmd: \"/copy\",\n desc: t(\"app.cmd.copyLast\"),\n run: () => {\n const last = [...state.messages].reverse().find((m) => m.kind === \"assistant\");\n if (last?.kind === \"assistant\") {\n const text = last.segments\n .filter((s): s is { kind: \"text\"; text: string } => s.kind === \"text\")\n .map((s) => s.text)\n .join(\"\\n\\n\");\n if (text) {\n void navigator.clipboard.writeText(text);\n flashToast(t(\"app.toast.copied\"));\n }\n }\n },\n },\n { cmd: \"/model\", desc: t(\"app.cmd.switchModel\"), run: () => openSettingsAt(\"models\") },\n { cmd: \"/theme\", desc: t(\"app.cmd.toggleTheme\"), run: onToggleTheme },\n {\n cmd: \"/currency\",\n desc: t(\"app.cmd.toggleCurrency\"),\n run: onToggleCurrency,\n },\n {\n cmd: \"/lang\",\n desc: t(\"app.cmd.toggleLang\"),\n run: () => {\n const next = getLang() === \"zh-CN\" ? \"en\" : \"zh-CN\";\n setLang(next);\n const langName = next === \"zh-CN\" ? t(\"app.langZH\") : t(\"app.langEN\");\n flashToast(t(\"app.toast.langSwitched\", { lang: langName }));\n },\n },\n {\n cmd: \"/export\",\n desc: t(\"app.cmd.exportMd\"),\n run: () => exportConversation(),\n },\n {\n cmd: \"/feedback\",\n desc: t(\"app.cmd.feedback\"),\n run: () => {\n void openUrl(\"https://github.com/esengine/DeepSeek-Reasonix/issues/new/choose\").catch(\n () => undefined,\n );\n },\n },\n {\n cmd: \"/compact\",\n desc: t(\"app.cmd.compact\"),\n run: () => sendRpc({ cmd: \"compact_history\" }),\n },\n {\n cmd: \"/retry\",\n desc: t(\"app.cmd.retry\"),\n run: () => sendRpc({ cmd: \"retry\" }),\n },\n {\n cmd: \"/btw\",\n desc: t(\"app.cmd.btw\"),\n run: () => {\n // Sets the draft to /btw so the user can type their question.\n // The send() handler detects the /btw prefix and routes to the btw RPC.\n setDraft(\"/btw \");\n composerRef.current?.focus();\n },\n },\n ...state.skills.map((s) => ({\n cmd: `/${s.name}`,\n desc: s.description?.trim() || fallbackSkillDesc(s),\n insertOnly: true,\n run: () => {\n dispatch({\n t: \"start_skill\",\n skill: { name: s.name, runAs: s.runAs },\n clientId: `skill-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n });\n sendRpc({ cmd: \"skill_run\", name: s.name });\n },\n })),\n ];\n\n const elapsed = useElapsed(state.busy);\n const workspaceLabel = state.settings?.workspaceDir\n ? state.settings.workspaceDir.split(/[\\\\/]/).pop() || \"workspace\"\n : \"Reasonix\";\n const session = (() => {\n const firstUser = state.messages.find((m) => m.kind === \"user\");\n if (firstUser && firstUser.kind === \"user\") {\n const cleaned = firstUser.text.replace(/\\s+/g, \" \").trim();\n if (cleaned) return cleaned.length > 60 ? `${cleaned.slice(0, 60)}…` : cleaned;\n }\n if (state.currentSession) {\n const s = state.sessions.find((x) => x.name === state.currentSession);\n if (s?.summary?.trim()) return s.summary.trim();\n const m = state.currentSession.match(/^desktop-(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})/);\n if (m)\n return t(\"app.session.format\", {\n month: m[2],\n day: m[3],\n hour: m[4],\n minute: m[5],\n });\n }\n return state.messages.length === 0\n ? t(\"app.session.new\", { workspace: workspaceLabel })\n : workspaceLabel;\n })();\n\n const exportConversation = useCallback(async () => {\n const userLabel = t(\"app.exportUserLabel\");\n const md = formatConversationMarkdown(state.messages, userLabel);\n if (!md) {\n flashToast(t(\"app.toast.emptySession\"));\n return;\n }\n try {\n const filename = defaultExportFilename(session);\n const path = await saveDialog({\n defaultPath: filename,\n filters: [{ name: \"Markdown\", extensions: [\"md\"] }],\n title: t(\"app.toast.exportDialogTitle\"),\n });\n if (!path) return;\n await invoke(\"write_text_file\", { path, content: md });\n flashToast(t(\"app.toast.exportedMd\"));\n } catch (err) {\n console.error(\"export failed\", err);\n flashToast(t(\"app.toast.exportFailed\", { error: String(err) }));\n }\n }, [state.messages, session, flashToast]);\n\n const conversationCopy = useCallback(() => {\n const userLabel = t(\"app.exportUserLabel\");\n const md = formatConversationMarkdown(state.messages, userLabel);\n if (!md) {\n flashToast(t(\"app.toast.emptySession\"));\n return;\n }\n void navigator.clipboard.writeText(md);\n flashToast(t(\"app.toast.copiedMd\"));\n }, [state.messages, flashToast]);\n\n return (\n <WorkspaceProvider\n value={{ dir: state.settings?.workspaceDir, editor: state.settings?.editor }}\n >\n <div\n className=\"app\"\n data-theme={theme}\n data-theme-style={themeStyle}\n data-side-collapsed={sideCollapsed}\n data-ctx-collapsed={ctxCollapsed}\n data-mobile-side-open={mobileSideOpen}\n style={{ display: active ? undefined : \"none\" }}\n >\n {/* 移动端遮罩层:点击关闭侧边栏抽屉 */}\n <div\n className=\"mobile-overlay\"\n aria-hidden=\"true\"\n onClick={onToggleMobileSide}\n />\n\n <TitleBar\n session={session}\n model={state.settings?.model}\n sideOn={!sideCollapsed}\n ctxOn={!ctxCollapsed}\n onToggleSide={onToggleSide}\n onToggleCtx={onToggleCtx}\n onOpenCommands={() => palette.setOpen(true)}\n onOpenSettings={() => openSettingsAt(\"general\")}\n onCopy={conversationCopy}\n onExport={exportConversation}\n onClear={() => dispatch({ t: \"clear\" })}\n hasMessages={state.messages.length > 0}\n mobileSideOpen={mobileSideOpen}\n onToggleMobileSide={onToggleMobileSide}\n />\n\n <TabBar\n tabs={tabsList}\n activeId={activeTabId}\n setActive={setActiveTabId}\n onClose={(id) => {\n if (tabsList.length <= 1) return;\n invoke(\"rpc_send\", {\n line: JSON.stringify({ cmd: \"tab_close\", tabId: id }),\n }).catch((err) => console.error(\"tab_close failed\", err));\n }}\n onNew={onNewTab}\n singleTab={tabsList.length <= 1}\n />\n\n <Sidebar\n sessions={state.sessions}\n activeName={state.currentSession}\n loadingName={loadingSession}\n onNewChat={() => { newChat(); onToggleMobileSide && mobileSideOpen && onToggleMobileSide(); }}\n onLoadSession={(name) => {\n if (name === state.currentSession || name === loadingSession) return;\n setLoadingSession(name);\n sendRpc({ cmd: \"session_load\", name });\n // 移动端选择会话后自动收起抽屉\n if (mobileSideOpen) onToggleMobileSide();\n }}\n onDeleteSession={(name) => sendRpc({ cmd: \"session_delete\", name })}\n onOpenSettings={() => { openSettingsAt(\"general\"); if (mobileSideOpen) onToggleMobileSide(); }}\n onOpenRules={() => { openSettingsAt(\"rules\"); if (mobileSideOpen) onToggleMobileSide(); }}\n onOpenCommands={() => { palette.setOpen(true); if (mobileSideOpen) onToggleMobileSide(); }}\n onOpenAbout={() => { setAboutOpen(true); if (mobileSideOpen) onToggleMobileSide(); }}\n />\n\n <main className=\"main\" style={{ position: \"relative\" }}>\n {state.needsSetup ? (\n <NeedsSetupView\n workspaceDir={state.settings?.workspaceDir}\n onPickWorkspace={pickWorkspace}\n onSubmit={(key) => sendRpc({ cmd: \"setup_save_key\", key })}\n />\n ) : (\n <>\n <MainHead\n session={session}\n model={state.settings?.model}\n workspaceDir={state.settings?.workspaceDir}\n busy={state.busy}\n hasMessages={state.messages.length > 0}\n onAbort={abort}\n onNewChat={newChat}\n onCopy={conversationCopy}\n onExport={exportConversation}\n onOpenWorkdir={(anchor) => {\n setWdAnchor(anchor);\n setWdOpen(true);\n }}\n />\n <div className=\"thread\" ref={threadRef} style={{ position: \"relative\" }}>\n {loadingSession ? (\n <div className=\"thread-loading-overlay\">\n {t(\"sidebarPanel.loading\")} {loadingSession}\n </div>\n ) : null}\n <div className=\"thread-inner\" ref={threadInnerRef}>\n {state.activePlan ? (\n <>\n <PlanBanner\n plan={state.activePlan}\n onDismiss={state.busy ? undefined : () => dispatch({ t: \"dismiss_plan\" })}\n />\n <ActivePlanTaskCard plan={state.activePlan} />\n </>\n ) : null}\n\n {state.messages.length === 0 ? (\n <EmptyState\n onPick={(text) => {\n const trimmed = text.trim();\n if (trimmed.startsWith(\"/\")) {\n const cmd = trimmed.split(/\\s+/)[0] ?? \"\";\n const match = slashCommands.find((s) => s.cmd === cmd);\n if (match) {\n match.run();\n return;\n }\n }\n send(text);\n }}\n workspaceDir={state.settings?.workspaceDir}\n />\n ) : null}\n\n {state.messages.map((m, i) => {\n if (m.kind === \"user\") {\n const dividerLabel = `turn ${m.turn}`;\n const prev = state.messages[i - 1];\n const needsDivider = !prev || prev.kind === \"user\";\n return (\n <div key={`u-${i}`}>\n {needsDivider ? <TurnDivider label={dividerLabel} /> : null}\n <UserMsg text={m.text} skill={m.skill} />\n </div>\n );\n }\n if (m.kind === \"assistant\") {\n return (\n <AssistantMsg\n // Index, not turn — replayed transcripts arrive with turn=0\n // for every assistant row (the server doesn't reconstruct\n // turn numbers from JSONL), so a turn-keyed list collapsed\n // every assistant into one slot and switching sessions left\n // the same stale row visible.\n key={`a-${i}`}\n segments={m.segments}\n pending={m.pending}\n model={state.model}\n onApproveConfirm={onApproveConfirm}\n onRejectConfirm={onRejectConfirm}\n onAlwaysAllowConfirm={onAlwaysAllowConfirm}\n pendingConfirms={state.pendingConfirms}\n />\n );\n }\n if (m.kind === \"error\") {\n return (\n <div\n key={`e-${i}`}\n className=\"warn-card\"\n style={{\n borderColor: \"var(--tone-err)\",\n background: \"var(--danger-soft)\",\n }}\n >\n <span className=\"ico\" style={{ color: \"var(--tone-err)\" }}>\n <I.warning size={16} />\n </span>\n <div>\n <div className=\"tt\">{t(\"app.errorLabel\")}</div>\n <div className=\"ds\">{m.message}</div>\n </div>\n </div>\n );\n }\n if (m.kind === \"warning\") {\n if (state.settings?.showSystemEvents === false) return null;\n return (\n <div key={m.id} className=\"sys-event-row\" title={m.text}>\n <span className=\"line\" />\n <span className=\"label\">{m.text}</span>\n <span className=\"line\" />\n </div>\n );\n }\n return null;\n })}\n\n {/* Pending approvals */}\n {state.pendingPlans.map((p) => (\n <PlanApprovalCard\n key={`pp-${p.id}`}\n p={p}\n onApprove={() => resolvePlan(p.id, { type: \"approve\" })}\n onRefine={() => resolvePlan(p.id, { type: \"refine\" })}\n onCancel={() => resolvePlan(p.id, { type: \"cancel\" })}\n />\n ))}\n {state.pendingCheckpoints.map((c) => (\n <CheckpointApprovalCard\n key={`cp-${c.id}`}\n c={c}\n onContinue={() => resolveCheckpoint(c.id, { type: \"continue\" })}\n onRevise={() => resolveCheckpoint(c.id, { type: \"revise\" })}\n onStop={() => resolveCheckpoint(c.id, { type: \"stop\" })}\n />\n ))}\n {state.pendingRevisions.map((r) => (\n <RevisionApprovalCard\n key={`rv-${r.id}`}\n r={r}\n onAccept={() => resolveRevision(r.id, { type: \"accepted\" })}\n onReject={() => resolveRevision(r.id, { type: \"rejected\" })}\n />\n ))}\n {state.pendingConfirms.map((c) => (\n <ConfirmApprovalCard\n key={`cc-${c.id}`}\n c={c}\n onAllow={() => resolveConfirm(c.id, { type: \"run_once\" })}\n onAlwaysAllow={(prefix) =>\n resolveConfirm(c.id, { type: \"always_allow\", prefix })\n }\n onDeny={() => resolveConfirm(c.id, { type: \"deny\" })}\n />\n ))}\n {state.pendingPathAccess.map((p) => (\n <PathAccessApprovalCard\n key={`pa-${p.id}`}\n p={p}\n onAllow={() => resolvePathAccess(p.id, { type: \"run_once\" })}\n onAlwaysAllow={(prefix) =>\n resolvePathAccess(p.id, { type: \"always_allow\", prefix })\n }\n onDeny={() => resolvePathAccess(p.id, { type: \"deny\" })}\n />\n ))}\n {state.pendingChoices.map((c) => (\n <ChoiceApprovalCard\n key={`ch-${c.id}`}\n c={c}\n onPick={(optionId) => resolveChoice(c.id, { type: \"pick\", optionId })}\n onCancel={() => resolveChoice(c.id, { type: \"cancel\" })}\n />\n ))}\n\n {!state.ready ? (\n <div\n style={{\n padding: 12,\n color: \"var(--muted)\",\n fontFamily: \"Geist Mono, monospace\",\n fontSize: 11,\n }}\n >\n {t(\"app.connecting\")}\n </div>\n ) : null}\n </div>\n {showJumpButton ? (\n <button\n className=\"thread-jump-bottom\"\n onClick={() => scrollToBottom(true)}\n title={t(\"app.jumpToBottom\") ?? \"Jump to bottom\"}\n aria-label={t(\"app.jumpToBottom\") ?? \"Jump to bottom\"}\n >\n <I.chev size={16} />\n </button>\n ) : null}\n </div>\n\n <Composer\n draft={draft}\n setDraft={setDraft}\n onSend={() => send()}\n onAbort={abort}\n disabled={!state.ready}\n busy={state.busy}\n busyLabel={\n state.busy\n ? state.activeSkill\n ? `Skill · ${state.activeSkill.name}`\n : \"Reasoning\"\n : undefined\n }\n busyElapsedMs={elapsed}\n textareaRef={composerRef}\n modelLabel={state.settings?.model ?? \"deepseek-v4-flash\"}\n reasoningEffort={state.settings?.reasoningEffort ?? \"high\"}\n onModelChange={(model) => {\n saveSettings({ model });\n flashToast(t(\"app.toast.modelSwitched\", { model }));\n }}\n onEffortChange={(reasoningEffort) => {\n saveSettings({ reasoningEffort });\n flashToast(t(\"app.toast.effortSwitched\", { effort: reasoningEffort }));\n }}\n editMode={state.settings?.editMode ?? \"review\"}\n onEditModeChange={(mode) => {\n saveSettings({ editMode: mode });\n if (mode === \"yolo\") {\n flashToast(t(\"app.yolo.toast\"), { yolo: true, duration: 3000 });\n } else {\n flashToast(t(\"app.toast.modeSwitched\", { mode: mode.toUpperCase() }));\n }\n }}\n workspaceDir={state.settings?.workspaceDir}\n slashCommands={slashCommands}\n onMentionQuery={queryMentions}\n onMentionPreview={previewMention}\n onMentionPicked={markMentionPicked}\n mentionResults={state.mentionResults}\n queuedSends={state.queuedSends}\n onQueueWhileBusy={(text) => {\n dispatch({ t: \"enqueue_send\", text });\n setDraft(\"\");\n }}\n onDequeueSend={(index) => dispatch({ t: \"dequeue_send\", index })}\n />\n </>\n )}\n </main>\n\n <ContextPanel\n settings={state.settings}\n usage={state.usage}\n mcpSpecs={state.mcpSpecs}\n mcpBridged={state.mcpBridged}\n sessionFiles={state.sessionFiles}\n memory={state.memory}\n />\n\n <StatusBar\n settings={state.settings}\n balance={state.balance}\n usage={state.usage}\n busy={state.busy}\n ready={state.ready}\n currency={currency}\n theme={theme}\n themeStyle={themeStyle}\n jobs={state.jobs}\n jobsOpen={jobsOpen}\n onToggleJobs={() => setJobsOpen((v) => !v)}\n onSetThemeStyle={onSetThemeStyle}\n onToggleCurrency={onToggleCurrency}\n onOpenSettings={() => openSettingsAt(\"general\")}\n onOpenWorkdir={(anchor) => {\n setWdAnchor(anchor);\n setWdOpen(true);\n }}\n />\n\n <CommandPalette\n open={palette.open}\n onClose={() => palette.setOpen(false)}\n commands={commands}\n />\n\n <WorkdirPop\n open={wdOpen}\n onClose={() => setWdOpen(false)}\n recent={state.settings?.recentWorkspaces ?? []}\n current={state.settings?.workspaceDir}\n anchor={wdAnchor}\n onPick={(path) => saveSettings({ workspaceDir: path })}\n onBrowse={pickWorkspace}\n />\n\n <WorkdirInputModal\n open={workdirModalOpen}\n initialPath={state.settings?.workspaceDir}\n onCancel={() => setWorkdirModalOpen(false)}\n onConfirm={(path) => {\n saveSettings({ workspaceDir: path });\n setWorkdirModalOpen(false);\n }}\n />\n\n {aboutOpen ? <AboutModal onClose={() => setAboutOpen(false)} /> : null}\n\n {settingsOpen && state.settings ? (\n <SettingsModal\n settings={state.settings}\n balance={state.balance}\n usage={state.usage}\n currency={currency}\n theme={theme}\n themeStyle={themeStyle}\n onSetTheme={onSetTheme}\n onSetThemeStyle={onSetThemeStyle}\n fontScale={fontScale}\n onSetFontScale={onSetFontScale}\n fontFamily={fontFamily}\n onSetFontFamily={onSetFontFamily}\n initialPage={settingsPage}\n mcpSpecs={state.mcpSpecs}\n mcpBridged={state.mcpBridged}\n skills={state.skills}\n qq={state.qq}\n onClose={() => setSettingsOpen(false)}\n onSave={saveSettings}\n onSaveApiKey={saveApiKey}\n onLoadQQ={loadQQSettings}\n onConnectQQ={connectQQ}\n onDisconnectQQ={disconnectQQ}\n onSaveQQConfig={saveQQConfig}\n onOpenQQApplyLink={() =>\n openUrl(\"https://q.qq.com/qqbot/openclaw/login.html\").catch(() => undefined)\n }\n onPickWorkspace={pickWorkspace}\n onAddMcpSpec={addMcpSpec}\n onRemoveMcpSpec={removeMcpSpec}\n />\n ) : null}\n\n <JobsPop\n open={jobsOpen}\n onClose={() => setJobsOpen(false)}\n jobs={state.jobs}\n onStop={(jobId) => sendRpc({ cmd: \"jobs_stop\", jobId })}\n onStopAll={() => sendRpc({ cmd: \"jobs_stop_all\" })}\n />\n\n <Toast message={toast} />\n\n {splashOn ? <Splash onDone={() => setSplashOn(false)} /> : null}\n </div>\n </WorkspaceProvider>\n );\n}\n\nfunction WinMinimize() {\n return (\n <svg width=\"10\" height=\"1\" viewBox=\"0 0 10 1\" aria-hidden>\n <rect width=\"10\" height=\"1\" fill=\"currentColor\" />\n </svg>\n );\n}\nfunction WinMaximize() {\n return (\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden>\n <rect x=\"0.5\" y=\"0.5\" width=\"9\" height=\"9\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1\" />\n </svg>\n );\n}\nfunction WinRestore() {\n return (\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden>\n <rect x=\"2.5\" y=\"0.5\" width=\"7\" height=\"7\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1\" />\n <rect x=\"0.5\" y=\"2.5\" width=\"7\" height=\"7\" fill=\"var(--bg-2, #eee)\" stroke=\"currentColor\" strokeWidth=\"1\" />\n </svg>\n );\n}\nfunction WinClose() {\n return (\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden>\n <line x1=\"0.5\" y1=\"0.5\" x2=\"9.5\" y2=\"9.5\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\" />\n <line x1=\"9.5\" y1=\"0.5\" x2=\"0.5\" y2=\"9.5\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\" />\n </svg>\n );\n}\n\nfunction TitleBar({\n session,\n model,\n sideOn,\n ctxOn,\n onToggleSide,\n onToggleCtx,\n onOpenCommands,\n onOpenSettings,\n onCopy,\n onExport,\n onClear,\n hasMessages,\n mobileSideOpen,\n onToggleMobileSide,\n}: {\n session: string;\n model?: string;\n sideOn: boolean;\n ctxOn: boolean;\n onToggleSide: () => void;\n onToggleCtx: () => void;\n onOpenCommands: () => void;\n onOpenSettings: () => void;\n onCopy: () => void;\n onExport: () => void;\n onClear: () => void;\n hasMessages: boolean;\n /** 移动端:汉堡菜单状态 */\n mobileSideOpen: boolean;\n onToggleMobileSide: () => void;\n}) {\n useLang();\n const [menuOpen, setMenuOpen] = useState(false);\n const [isMaximized, setIsMaximized] = useState(false);\n const moreWrapRef = useRef<HTMLDivElement>(null);\n const isMac = document.documentElement.dataset.platform === \"macos\";\n // Web 模式下隐藏原生窗口控件\n const isWeb = document.documentElement.dataset.web === \"true\";\n\n useEffect(() => {\n const win = getCurrentWindow();\n win.isMaximized().then(setIsMaximized);\n let unlisten: (() => void) | undefined;\n win.listen(\"tauri://resize\", async () => {\n setIsMaximized(await win.isMaximized());\n }).then((fn: (() => void) | undefined) => { unlisten = fn; });\n return () => unlisten?.();\n }, []);\n\n useEffect(() => {\n if (!menuOpen) return;\n const onDown = (e: MouseEvent) => {\n if (moreWrapRef.current && !moreWrapRef.current.contains(e.target as Node))\n setMenuOpen(false);\n };\n window.addEventListener(\"mousedown\", onDown);\n return () => window.removeEventListener(\"mousedown\", onDown);\n }, [menuOpen]);\n\n const win = getCurrentWindow();\n\n return (\n <header className=\"titlebar\">\n {/* left: sidebar toggle + brand */}\n <div className=\"tb-left\">\n {isMac && !isWeb ? (\n <div className=\"mac-controls\" aria-label={t(\"app.titlebar.windowControls\")}>\n <button\n type=\"button\"\n className=\"mac-ctrl close\"\n title={t(\"app.titlebar.close\")}\n aria-label={t(\"app.titlebar.close\")}\n onMouseDown={(e) => {\n e.stopPropagation();\n win.close();\n }}\n >\n <WinClose />\n </button>\n <button\n type=\"button\"\n className=\"mac-ctrl minimize\"\n title={t(\"app.titlebar.minimize\")}\n aria-label={t(\"app.titlebar.minimize\")}\n onMouseDown={(e) => {\n e.stopPropagation();\n win.minimize();\n }}\n >\n <WinMinimize />\n </button>\n <button\n type=\"button\"\n className=\"mac-ctrl zoom\"\n title={isMaximized ? t(\"app.titlebar.restore\") : t(\"app.titlebar.maximize\")}\n aria-label={isMaximized ? t(\"app.titlebar.restore\") : t(\"app.titlebar.maximize\")}\n onMouseDown={(e) => {\n e.stopPropagation();\n win.toggleMaximize();\n }}\n >\n {isMaximized ? <WinRestore /> : <WinMaximize />}\n </button>\n </div>\n ) : null}\n {/* 移动端汉堡菜单按钮(仅在 xs 断点可见,通过 CSS 控制) */}\n <button\n type=\"button\"\n className=\"tb-mobile-menu\"\n aria-label=\"打开会话列表\"\n aria-expanded={mobileSideOpen}\n onClick={onToggleMobileSide}\n >\n {mobileSideOpen ? <I.x size={18} /> : <I.panel_l size={18} />}\n </button>\n {/* 桌面端侧边栏切换按钮 */}\n <button\n type=\"button\"\n className=\"iconbtn tb-desktop-side-btn\"\n data-on={sideOn}\n title={localizeShortcutText(t(\"app.titlebar.sidebar\"))}\n onClick={onToggleSide}\n >\n <I.panel_l size={14} />\n </button>\n <div className=\"tb-meta\" data-tauri-drag-region>\n <div className=\"brand\" data-tauri-drag-region>\n <span className=\"mark\" />\n <span className=\"brand-name\">Reasonix</span>\n </div>\n {session && (\n <div className=\"crumbs\" data-tauri-drag-region>\n <span className=\"sep\">/</span>\n <span className=\"cur\">{model ?? \"—\"}</span>\n </div>\n )}\n </div>\n </div>\n\n {/* center: drag region */}\n <span className=\"grow\" data-tauri-drag-region />\n\n {/* right: panel toggles + more + window controls */}\n <div className=\"tb-right\">\n <button\n type=\"button\"\n className=\"iconbtn\"\n data-on={ctxOn}\n title={t(\"app.titlebar.contextPanel\")}\n onClick={onToggleCtx}\n >\n <I.panel_r size={14} />\n </button>\n\n <div ref={moreWrapRef} style={{ position: \"relative\" }}>\n <button\n type=\"button\"\n className=\"iconbtn\"\n title={t(\"app.titlebar.more\")}\n onClick={() => setMenuOpen((v) => !v)}\n >\n <I.more size={14} />\n </button>\n {menuOpen ? (\n <div\n className=\"popup\"\n style={{ top: \"calc(100% + 6px)\", right: 0, left: \"auto\", bottom: \"auto\", width: 220 }}\n >\n <div className=\"popup-list\">\n <div className=\"popup-item\" onClick={() => { onOpenCommands(); setMenuOpen(false); }}>\n <span className=\"ico\"><I.search size={12} /></span>\n <div className=\"nm\"><span>{t(\"app.titlebar.commandPalette\")}</span></div>\n <span className=\"kb\">\n <Shortcut keys={[\"mod\", \"K\"]} />\n </span>\n </div>\n <div\n className=\"popup-item\"\n onClick={() => { if (hasMessages) onCopy(); setMenuOpen(false); }}\n style={{ opacity: hasMessages ? 1 : 0.5 }}\n >\n <span className=\"ico\"><I.copy size={12} /></span>\n <div className=\"nm\"><span>{t(\"app.titlebar.copyMd\")}</span></div>\n </div>\n <div\n className=\"popup-item\"\n onClick={() => { if (hasMessages) onExport(); setMenuOpen(false); }}\n style={{ opacity: hasMessages ? 1 : 0.5 }}\n >\n <span className=\"ico\"><I.download size={12} /></span>\n <div className=\"nm\"><span>{t(\"app.titlebar.exportMd\")}</span></div>\n </div>\n <div className=\"popup-item\" onClick={() => { onClear(); setMenuOpen(false); }}>\n <span className=\"ico\"><I.x size={12} /></span>\n <div className=\"nm\"><span>{t(\"app.titlebar.clearChat\")}</span></div>\n </div>\n <div className=\"popup-item\" onClick={() => { onOpenSettings(); setMenuOpen(false); }}>\n <span className=\"ico\"><I.cog size={12} /></span>\n <div className=\"nm\"><span>{t(\"app.titlebar.settings\")}</span></div>\n <span className=\"kb\">\n <Shortcut keys={[\"mod\", \",\"]} />\n </span>\n </div>\n </div>\n </div>\n ) : null}\n </div>\n\n {/* window controls — 仅在非 Web 的原生 Tauri 窗口环境下渲染 */}\n {!isMac && !isWeb ? (\n <div className=\"win-controls\">\n <button\n type=\"button\"\n className=\"win-ctrl\"\n title={t(\"app.titlebar.minimize\")}\n onMouseDown={(e) => { e.stopPropagation(); win.minimize(); }}\n >\n <WinMinimize />\n </button>\n <button\n type=\"button\"\n className=\"win-ctrl\"\n title={isMaximized ? t(\"app.titlebar.restore\") : t(\"app.titlebar.maximize\")}\n onMouseDown={(e) => { e.stopPropagation(); win.toggleMaximize(); }}\n >\n {isMaximized ? <WinRestore /> : <WinMaximize />}\n </button>\n <button\n type=\"button\"\n className=\"win-ctrl close\"\n title={t(\"app.titlebar.close\")}\n onMouseDown={(e) => { e.stopPropagation(); win.close(); }}\n >\n <WinClose />\n </button>\n </div>\n ) : null}\n </div>\n </header>\n );\n}\n\nfunction TabBar({\n tabs,\n activeId,\n setActive,\n onClose,\n onNew,\n singleTab,\n}: {\n tabs: { id: string; workspaceDir?: string }[];\n activeId: string;\n setActive: (id: string) => void;\n onClose: (id: string) => void;\n onNew: () => void;\n singleTab?: boolean;\n}) {\n useLang();\n return (\n <div className=\"tabbar\">\n {tabs.map((t) => {\n const ws = t.workspaceDir ?? \"\";\n const label =\n ws\n .replace(/[\\\\/]$/, \"\")\n .split(/[\\\\/]/)\n .pop() || \"workspace\";\n return (\n <div\n key={t.id}\n className=\"tab\"\n data-active={t.id === activeId}\n onClick={() => setActive(t.id)}\n title={ws || label}\n >\n <span className=\"dot\" data-state=\"running\" />\n <span className=\"label\">{label}</span>\n {!singleTab ? (\n <span\n className=\"close\"\n onClick={(e) => {\n e.stopPropagation();\n onClose(t.id);\n }}\n >\n <I.x size={11} />\n </span>\n ) : null}\n </div>\n );\n })}\n </div>\n );\n}\n\nfunction MainHead({\n session,\n model,\n workspaceDir,\n busy,\n hasMessages,\n onAbort,\n onNewChat,\n onCopy,\n onExport,\n onOpenWorkdir,\n}: {\n session: string;\n model?: string;\n workspaceDir?: string;\n busy: boolean;\n hasMessages: boolean;\n onAbort: () => void;\n onNewChat: () => void;\n onCopy: () => void;\n onExport: () => void;\n onOpenWorkdir: (anchor: { top?: number; bottom?: number; left: number }) => void;\n}) {\n useLang();\n const wsLabel = workspaceDir\n ? workspaceDir.split(/[\\\\/]/).pop() || \"workspace\"\n : t(\"app.header.noWorkspace\");\n return (\n <div className=\"main-head\">\n <div className=\"title-wrap\">\n <h1>\n <span className=\"editable\">{session}</span>\n {busy ? (\n <span className=\"pill\" style={{ color: \"var(--accent)\" }}>\n <span className=\"dot\" />\n <span className=\"shimmer\">{t(\"app.header.running\")}</span>\n </span>\n ) : null}\n </h1>\n <div className=\"sub\">\n <span\n className=\"ws-crumb\"\n onClick={(e) => {\n const r = (e.currentTarget as HTMLElement).getBoundingClientRect();\n onOpenWorkdir({ top: r.bottom + 6, left: r.left });\n }}\n style={{ cursor: \"pointer\" }}\n title={workspaceDir ?? t(\"app.header.clickToSelect\")}\n >\n <I.folder size={10} /> {wsLabel}\n </span>\n {model ? (\n <span className=\"pill\">\n <I.brain size={10} /> {model}\n </span>\n ) : null}\n </div>\n </div>\n <span className=\"grow\" />\n <button\n type=\"button\"\n className=\"h-btn\"\n onClick={onCopy}\n disabled={!hasMessages}\n title={t(\"app.header.copyMd\")}\n >\n <I.copy size={12} /> {t(\"app.header.copy\")}\n </button>\n <button\n type=\"button\"\n className=\"h-btn\"\n onClick={onExport}\n disabled={!hasMessages}\n title={t(\"app.header.exportMd\")}\n >\n <I.download size={12} /> {t(\"app.header.export\")}\n </button>\n <button type=\"button\" className=\"h-btn\" onClick={onNewChat}>\n <I.plus size={12} /> {t(\"app.header.newChat\")}\n </button>\n {busy ? (\n <button type=\"button\" className=\"h-btn primary\" onClick={onAbort}>\n <I.stop size={12} /> {t(\"app.header.abort\")}\n </button>\n ) : null}\n </div>\n );\n}\n\nfunction EmptyState({\n onPick,\n workspaceDir,\n}: {\n onPick: (text: string) => void;\n workspaceDir?: string;\n}) {\n useLang();\n const suggestions = [\n t(\"app.empty.suggestion0\"),\n t(\"app.empty.suggestion1\"),\n t(\"app.empty.suggestion2\"),\n t(\"app.empty.suggestion3\"),\n \"/help\",\n ];\n const wsLabel = workspaceDir ? workspaceDir.split(/[\\\\/]/).pop() : null;\n return (\n <div\n style={{\n padding: \"48px 16px 24px\",\n textAlign: \"center\",\n color: \"var(--muted)\",\n fontFamily: \"var(--font-sans, 'Geist', sans-serif)\",\n }}\n >\n <div\n style={{\n width: 56,\n height: 56,\n borderRadius: 12,\n margin: \"0 auto 14px\",\n background: \"linear-gradient(135deg, var(--accent), var(--violet))\",\n position: \"relative\",\n }}\n >\n <span\n style={{\n position: \"absolute\",\n inset: 8,\n borderRadius: 6,\n background: \"var(--bg)\",\n }}\n />\n </div>\n <div style={{ fontSize: 18, fontWeight: 600, color: \"var(--fg)\", marginBottom: 4 }}>\n {t(\"app.empty.welcome\")}\n </div>\n <div style={{ fontSize: 12, marginBottom: 18 }}>\n {wsLabel ? (\n <>\n {t(\"app.empty.currentWorkspace\")}\n <code style={{ fontFamily: \"Geist Mono, monospace\" }}>{wsLabel}</code>\n </>\n ) : (\n t(\"app.empty.selectWorkspace\")\n )}\n </div>\n <div\n style={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: 8,\n justifyContent: \"center\",\n maxWidth: 540,\n margin: \"0 auto\",\n }}\n >\n {suggestions.map((s) => (\n <button\n key={s}\n type=\"button\"\n className=\"btn\"\n style={{ fontSize: 11.5 }}\n onClick={() => onPick(s)}\n >\n {s}\n </button>\n ))}\n </div>\n </div>\n );\n}\n\nfunction NeedsSetupView({\n workspaceDir,\n onPickWorkspace,\n onSubmit,\n}: {\n workspaceDir?: string;\n onPickWorkspace: () => void;\n onSubmit: (key: string) => void;\n}) {\n useLang();\n const [key, setKey] = useState(\"\");\n return (\n <div\n style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 24,\n gap: 18,\n }}\n >\n <div style={{ fontSize: 18, fontWeight: 600 }}>{t(\"app.setup.welcome\")}</div>\n <div style={{ fontSize: 12.5, color: \"var(--muted)\", maxWidth: 400, textAlign: \"center\" }}>\n {t(\"app.setup.description\")}\n </div>\n <div\n style={{\n width: \"min(420px, 100%)\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 10,\n }}\n >\n <div className=\"setting-row\" style={{ borderBottom: \"none\" }}>\n <div className=\"l\">\n <div className=\"n\">{t(\"app.setup.workspace\")}</div>\n <div className=\"h\">{workspaceDir || t(\"app.setup.notSelected\")}</div>\n </div>\n <button type=\"button\" className=\"btn\" onClick={onPickWorkspace}>\n {t(\"app.setup.choose\")}\n </button>\n </div>\n <input\n className=\"field mono\"\n type=\"password\"\n value={key}\n onChange={(e) => setKey(e.target.value)}\n placeholder=\"sk-…\"\n style={{ width: \"100%\" }}\n />\n <button\n type=\"button\"\n className=\"btn primary\"\n disabled={!key.trim()}\n onClick={() => onSubmit(key.trim())}\n >\n {t(\"app.setup.saveAndStart\")}\n </button>\n </div>\n </div>\n );\n}\n\nfunction formatBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n if (n < 1024 * 1024 * 1024) return `${(n / (1024 * 1024)).toFixed(1)} MB`;\n return `${(n / (1024 * 1024 * 1024)).toFixed(2)} GB`;\n}\n\ntype TabMeta = { id: string; workspaceDir?: string; busy?: boolean };\n\nexport function App() {\n const [tabs, setTabs] = useState<TabMeta[]>([]);\n const [activeTabId, setActiveTabId] = useState<string>(\"\");\n const dispatchersRef = useRef<Map<string, TabDispatcher>>(new Map());\n const pendingEventsRef = useRef<Map<string, TabAction[]>>(new Map());\n const pendingDeltasRef = useRef<Map<string, DeltaBatchItem[]>>(new Map());\n const rafScheduledRef = useRef(false);\n const tabsRef = useRef<TabMeta[]>([]);\n useEffect(() => {\n tabsRef.current = tabs;\n }, [tabs]);\n\n const [currency, setCurrency] = useState<\"CNY\" | \"USD\">(() => {\n const v = localStorage.getItem(\"reasonix.currency\");\n return v === \"USD\" ? \"USD\" : \"CNY\";\n });\n const [theme, setTheme] = useState<Theme>(() => {\n const v = localStorage.getItem(\"reasonix.theme\");\n const style = localStorage.getItem(\"reasonix.themeStyle\");\n if (isThemeStyle(style)) return themeForStyle(style);\n return isTheme(v) ? v : THEME.DARK;\n });\n const [themeStyle, setThemeStyle] = useState<ThemeStyle>(() => {\n const style = localStorage.getItem(\"reasonix.themeStyle\");\n if (isThemeStyle(style)) return style;\n const storedTheme = localStorage.getItem(\"reasonix.theme\");\n return defaultStyleForTheme(isTheme(storedTheme) ? storedTheme : THEME.DARK);\n });\n const [fontScale, setFontScale] = useState<FontScale>(() => {\n const v = localStorage.getItem(\"reasonix.fontScale\");\n return isFontScale(v) ? v : FONT_SCALE.MEDIUM;\n });\n const [fontFamily, setFontFamily] = useState<FontFamily>(() => {\n const v = localStorage.getItem(\"reasonix.fontFamily\");\n return isFontFamily(v) ? v : FONT_FAMILY.SANS;\n });\n const [sideCollapsed, setSideCollapsed] = useState(\n () => localStorage.getItem(\"reasonix.sideCollapsed\") === \"1\",\n );\n const [ctxCollapsed, setCtxCollapsed] = useState(\n () => localStorage.getItem(\"reasonix.ctxCollapsed\") === \"1\",\n );\n\n useEffect(() => {\n document.documentElement.dataset.theme = theme;\n document.documentElement.dataset.themeStyle = themeStyle;\n localStorage.setItem(\"reasonix.theme\", theme);\n localStorage.setItem(\"reasonix.themeStyle\", themeStyle);\n }, [theme, themeStyle]);\n\n useEffect(() => {\n localStorage.setItem(\"reasonix.sideCollapsed\", sideCollapsed ? \"1\" : \"0\");\n }, [sideCollapsed]);\n\n useEffect(() => {\n localStorage.setItem(\"reasonix.ctxCollapsed\", ctxCollapsed ? \"1\" : \"0\");\n }, [ctxCollapsed]);\n\n useEffect(() => {\n // Chromium webview supports `zoom`; scales every px-based size without touching CSS rules.\n document.documentElement.style.setProperty(\"zoom\", String(FONT_SCALE_ZOOM[fontScale]));\n localStorage.setItem(\"reasonix.fontScale\", fontScale);\n }, [fontScale]);\n\n useEffect(() => {\n // CSS rules use var(--font-sans); changing it here re-styles every sans surface in one shot. Mono stays put because code/transcripts hardcode \"Geist Mono\".\n document.documentElement.style.setProperty(\"--font-sans\", FONT_FAMILY_STACK[fontFamily]);\n localStorage.setItem(\"reasonix.fontFamily\", fontFamily);\n }, [fontFamily]);\n\n useEffect(() => {\n const onCur = (e: Event) => {\n const detail = (e as CustomEvent).detail;\n if (detail === \"CNY\" || detail === \"USD\") setCurrency(detail);\n };\n window.addEventListener(\"reasonix:currency\", onCur);\n return () => window.removeEventListener(\"reasonix:currency\", onCur);\n }, []);\n\n const deliverToTab = useCallback((tabId: string, action: TabAction) => {\n const dispatch = dispatchersRef.current.get(tabId);\n if (dispatch) {\n dispatch(action);\n } else {\n const buf = pendingEventsRef.current.get(tabId) ?? [];\n buf.push(action);\n pendingEventsRef.current.set(tabId, buf);\n }\n }, []);\n\n const registerDispatch = useCallback((tabId: string, d: TabDispatcher | null) => {\n if (d) {\n dispatchersRef.current.set(tabId, d);\n const buf = pendingEventsRef.current.get(tabId);\n if (buf && buf.length > 0) {\n for (const action of buf) d(action);\n pendingEventsRef.current.delete(tabId);\n }\n } else {\n dispatchersRef.current.delete(tabId);\n }\n }, []);\n\n useEffect(() => {\n let cancelled = false;\n const cleanups: Array<() => void> = [];\n\n const flushDeltas = () => {\n rafScheduledRef.current = false;\n for (const [tabId, items] of pendingDeltasRef.current) {\n if (items.length === 0) continue;\n deliverToTab(tabId, { t: \"batch_delta\", items });\n pendingDeltasRef.current.set(tabId, []);\n }\n };\n const scheduleFlush = () => {\n if (rafScheduledRef.current || cancelled) return;\n rafScheduledRef.current = true;\n requestAnimationFrame(flushDeltas);\n };\n const flushTabDeltas = (tabId: string) => {\n const bucket = pendingDeltasRef.current.get(tabId);\n if (bucket && bucket.length > 0) {\n deliverToTab(tabId, { t: \"batch_delta\", items: bucket });\n pendingDeltasRef.current.set(tabId, []);\n }\n };\n\n const setup = async () => {\n const subs = await Promise.all([\n listen<{ data: string }>(\"rpc:event\", (e) => {\n try {\n const ev = JSON.parse(e.payload.data) as IncomingEvent;\n const tabId = ev.tabId;\n\n if (ev.type === \"$tab_opened\" && tabId) {\n setTabs((prev) =>\n prev.some((t) => t.id === tabId)\n ? prev\n : [...prev, { id: tabId, workspaceDir: ev.workspaceDir }],\n );\n // Focus the tab the backend marked active (user-opened, or the\n // restored focused tab); otherwise keep focus, but make sure\n // *some* tab is active during a multi-tab restore.\n setActiveTabId((prev) => (ev.active || !prev ? tabId : prev));\n return;\n }\n if (ev.type === \"$tab_closed\" && tabId) {\n setTabs((prev) => prev.filter((t) => t.id !== tabId));\n setActiveTabId((prev) => {\n if (prev !== tabId) return prev;\n const remaining = tabsRef.current.filter((t) => t.id !== tabId);\n return remaining[0]?.id ?? \"\";\n });\n dispatchersRef.current.delete(tabId);\n pendingEventsRef.current.delete(tabId);\n pendingDeltasRef.current.delete(tabId);\n return;\n }\n\n if (ev.type === \"model.delta\" && tabId) {\n if (ev.channel === \"content\" || ev.channel === \"reasoning\") {\n const bucket = pendingDeltasRef.current.get(tabId) ?? [];\n bucket.push({ turn: ev.turn, channel: ev.channel, text: ev.text });\n pendingDeltasRef.current.set(tabId, bucket);\n scheduleFlush();\n return;\n }\n }\n\n if (ev.type === \"$settings\" && tabId) {\n setTabs((prev) =>\n prev.map((t) => (t.id === tabId ? { ...t, workspaceDir: ev.workspaceDir } : t)),\n );\n }\n\n if (ev.type === \"$jobs\") {\n for (const id of dispatchersRef.current.keys()) {\n deliverToTab(id, { t: \"incoming\", event: ev });\n }\n return;\n }\n\n const target = tabId;\n if (target) {\n flushTabDeltas(target);\n if (ev.type === \"$mention_results\") {\n deliverToTab(target, {\n t: \"mention_results\",\n results: { nonce: ev.nonce, query: ev.query, results: ev.results },\n });\n return;\n }\n if (ev.type === \"$mention_preview\") {\n deliverToTab(target, {\n t: \"mention_preview\",\n preview: {\n nonce: ev.nonce,\n path: ev.path,\n head: ev.head,\n totalLines: ev.totalLines,\n },\n });\n return;\n }\n deliverToTab(target, { t: \"incoming\", event: ev });\n }\n } catch {\n console.error(\"bad rpc:event line\", e.payload.data);\n }\n }),\n listen<{ data: string }>(\"rpc:stderr\", (e) => {\n console.warn(\"[reasonix stderr]\", e.payload.data);\n }),\n listen<{ code: number | null }>(\"rpc:exit\", (e) => {\n for (const tabId of dispatchersRef.current.keys()) flushTabDeltas(tabId);\n for (const dispatch of dispatchersRef.current.values()) {\n dispatch({ t: \"rpc_exit\", code: e.payload.code });\n }\n }),\n ]);\n if (cancelled) {\n for (const u of subs) u();\n return;\n }\n cleanups.push(...subs);\n try {\n await invoke(\"rpc_spawn\");\n } catch (err) {\n if (!cancelled) console.error(\"rpc_spawn failed\", err);\n }\n };\n void setup();\n return () => {\n cancelled = true;\n for (const c of cleanups) c();\n };\n }, [deliverToTab]);\n\n // Tell the backend which tab is focused so a restart can reopen on it (#1244).\n useEffect(() => {\n if (!activeTabId) return;\n invoke(\"rpc_send\", {\n line: JSON.stringify({ cmd: \"tab_activate\", tabId: activeTabId }),\n }).catch(() => {});\n }, [activeTabId]);\n\n const openTab = useCallback(() => {\n invoke(\"rpc_send\", { line: JSON.stringify({ cmd: \"tab_open\" }) }).catch((err) =>\n console.error(\"tab_open failed\", err),\n );\n }, []);\n\n const closeTab = useCallback(\n (id: string) => {\n if (tabs.length <= 1) return;\n invoke(\"rpc_send\", { line: JSON.stringify({ cmd: \"tab_close\", tabId: id }) }).catch((err) =>\n console.error(\"tab_close failed\", err),\n );\n },\n [tabs.length],\n );\n\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n const mod = e.ctrlKey || e.metaKey;\n if (mod && (e.key === \"t\" || e.key === \"T\")) {\n e.preventDefault();\n openTab();\n } else if (mod && (e.key === \"w\" || e.key === \"W\") && activeTabId && tabs.length > 1) {\n e.preventDefault();\n closeTab(activeTabId);\n } else if (mod && e.key === \"Tab\") {\n if (tabs.length <= 1) return;\n e.preventDefault();\n const idx = tabs.findIndex((t) => t.id === activeTabId);\n const next = e.shiftKey ? (idx - 1 + tabs.length) % tabs.length : (idx + 1) % tabs.length;\n const target = tabs[next];\n if (target) setActiveTabId(target.id);\n } else if (mod && (e.key === \"b\" || e.key === \"B\")) {\n if (e.altKey) {\n e.preventDefault();\n setCtxCollapsed((v) => !v);\n } else {\n e.preventDefault();\n setSideCollapsed((v) => !v);\n }\n }\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [openTab, closeTab, activeTabId, tabs]);\n\n const onSetTheme = useCallback((nextTheme: Theme) => {\n setTheme(nextTheme);\n setThemeStyle(defaultStyleForTheme(nextTheme));\n }, []);\n\n const onSetThemeStyle = useCallback((nextStyle: ThemeStyle) => {\n setThemeStyle(nextStyle);\n setTheme(themeForStyle(nextStyle));\n }, []);\n\n const onToggleTheme = useCallback(() => {\n onSetTheme(theme === THEME.DARK ? THEME.LIGHT : THEME.DARK);\n }, [onSetTheme, theme]);\n\n const [mobileSideOpen, setMobileSideOpen] = useState(false);\n const onToggleMobileSide = useCallback(() => setMobileSideOpen((v) => !v), []);\n\n const onToggleCurrency = useCallback(() => {\n setCurrency((c) => {\n const next = c === \"CNY\" ? \"USD\" : \"CNY\";\n localStorage.setItem(\"reasonix.currency\", next);\n window.dispatchEvent(new CustomEvent(\"reasonix:currency\", { detail: next }));\n return next;\n });\n }, []);\n\n return (\n <>\n {tabs.map((t) => (\n <TabRuntime\n key={t.id}\n tabId={t.id}\n active={t.id === activeTabId}\n currency={currency}\n registerDispatch={registerDispatch}\n onNewTab={openTab}\n onCloseTab={() => closeTab(t.id)}\n canCloseTab={tabs.length > 1}\n theme={theme}\n themeStyle={themeStyle}\n onSetTheme={onSetTheme}\n onSetThemeStyle={onSetThemeStyle}\n onToggleTheme={onToggleTheme}\n fontScale={fontScale}\n onSetFontScale={setFontScale}\n fontFamily={fontFamily}\n onSetFontFamily={setFontFamily}\n sideCollapsed={sideCollapsed}\n ctxCollapsed={ctxCollapsed}\n onToggleSide={() => setSideCollapsed((v) => !v)}\n onToggleCtx={() => setCtxCollapsed((v) => !v)}\n onToggleCurrency={onToggleCurrency}\n mobileSideOpen={mobileSideOpen}\n onToggleMobileSide={onToggleMobileSide}\n tabsList={tabs}\n activeTabId={activeTabId}\n setActiveTabId={setActiveTabId}\n />\n ))}\n </>\n );\n}\n","import \"@fontsource/geist/400.css\";\nimport \"@fontsource/geist/500.css\";\nimport \"@fontsource/geist/600.css\";\nimport \"@fontsource/geist/700.css\";\nimport \"@fontsource/geist-mono/400.css\";\nimport \"@fontsource/geist-mono/500.css\";\nimport \"@fontsource/geist-mono/600.css\";\nimport \"@fontsource/inter/400.css\";\nimport \"@fontsource/inter/500.css\";\nimport \"@fontsource/inter/600.css\";\nimport \"@fontsource/inter/700.css\";\nimport \"./styles.css\";\nimport \"katex/dist/katex.min.css\";\nimport { createRoot } from \"react-dom/client\";\nimport { App } from \"./App\";\nimport {\n defaultStyleForTheme,\n isTheme,\n isThemeStyle,\n themeForStyle,\n} from \"./theme\";\n\nconst stored = localStorage.getItem(\"reasonix.theme\");\nconst storedStyle = localStorage.getItem(\"reasonix.themeStyle\");\nif (isThemeStyle(storedStyle)) {\n document.documentElement.dataset.themeStyle = storedStyle;\n document.documentElement.dataset.theme = themeForStyle(storedStyle);\n} else if (isTheme(stored)) {\n document.documentElement.dataset.theme = stored;\n document.documentElement.dataset.themeStyle = defaultStyleForTheme(stored);\n}\n\nconst platform = /Mac|macOS/i.test(navigator.userAgent)\n ? \"macos\"\n : /Windows/i.test(navigator.userAgent)\n ? \"windows\"\n : \"default\";\ndocument.documentElement.dataset.platform = platform;\ndocument.body.dataset.platform = platform;\n\nconst host = document.getElementById(\"root\");\nif (!host) throw new Error(\"#root missing\");\n\ncreateRoot(host).render(<App />);\n"],"file":"app.js"}
|
|
1
|
+
{"version":3,"mappings":"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Y,eACZ,OAAQ,WACR,YAAa,eACb,QAAS,8CACT,aAAc,gBACd,YAAa,qBACb,YAAa,eACb,WAAY,cACZ,SAAU,YACV,QAAS,WACT,WAAY,oBACZ,YAAa,eACb,YAAa,gBACb,OAAQ,WACR,QAAS,0BACT,OAAQ,SACR,MAAO,SACP,YAAa,uBACb,SAAU,WACV,OAAQ,UAEV,MAAO,CACL,QAAS,iBACT,OAAQ,wBACR,QAAS,kBACT,WAAY,cACZ,UAAW,6BACX,OAAQ,4EACR,QAAS,kBACT,UAAW,SACX,SAAU,QACV,YAAa,YACb,QAAS,aACT,cAAe,cACf,YAAa,YACb,SAAU,QACV,SAAU,OACV,QAAS,MACT,UAAW,QACX,WAAY,OACZ,iBAAkB,cAClB,YAAa,QACb,SAAU,mBACV,SAAU,SAEZ,SAAU,CACR,QAAS,oBACT,OAAQ,2BACR,WAAY,yBACZ,kBAAmB,kBACnB,KAAM,OACN,SAAU,qDACV,YAAa,gBACb,WACE,kHACF,kBAAmB,sBACnB,gBAAiB,oBACjB,SAAU,qBACV,OAAQ,cACR,QAAS,yDACT,UAAW,yBACX,UAAW,SACX,cAAe,kFACf,iBAAkB,0DAClB,eACE,kIACF,WAAY,SACZ,WAAY,UAEd,MAAO,CACL,QAAS,iBACT,OAAQ,wBACR,QAAS,uBACT,SAAU,2BACV,QAAS,OACT,SAAU,QACV,QAAS,cACT,SAAU,YACV,MAAO,QACP,KAAM,OACN,KAAM,CACJ,WACE,gLACF,UACE,sIACF,YACE,qKACF,eACE,yKACF,WACE,6HACF,aACE,sHACF,SACE,6GACF,UACE,2GACF,SACE,kKACF,OACE,mIACF,cACE,qFACF,UACE,yIACF,eACE,sGACF,eACE,mHACF,aACE,uHACF,eACE,4IACF,KAAM,6HACN,cAAe,8EACf,WACE,+FACF,UACE,4GACF,WACE,6GACF,iBAAkB,uEAClB,UAAW,6DACX,YACE,gGACF,iBACE,+GACF,UACE,iGACF,YACE,iIACF,mBACE,2FACF,YACE,6FACF,UACE,wHACF,eACE,4HACF,WACE,qHACF,WACE,8GACF,aACE,qGACF,eACE,8HACJ,EAEF,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Y,sCACZ,kBAAmB,oBACnB,KAAM,QACN,SAAU,wDACV,YAAa,oBACb,WACE,6KACF,kBAAmB,mBACnB,gBAAiB,qBACjB,SAAU,uBACV,OAAQ,eACR,QAAS,oDACT,UAAW,6BACX,UAAW,UACX,cAAe,wGACf,iBAAkB,4DAClB,eACE,gJACF,WAAY,QACZ,WAAY,SAEd,MAAO,CACL,GAAGA,EAAG,MACN,QAAS,cACT,OAAQ,gCACR,QAAS,2BACT,SAAU,yCACV,QAAS,OACT,SAAU,QACV,QAAS,eACT,SAAU,mBACV,MAAO,YACP,KAAM,QACN,KAAM,CACJ,GAAGA,EAAG,MAAM,KACZ,WACE,uNACF,UACE,wKACF,YACE,kMACF,eACE,uLACF,WACE,yHACF,aACE,sIACF,SACE,kHACF,UACE,0HACF,SACE,gNACF,OACE,0JACF,cACE,iHACF,UACE,uKACF,eACE,iIACF,eACE,4IACF,aACE,mKACF,eACE,0KACF,KAAM,iKACN,cAAe,+GACf,WACE,4HACF,UACE,2IACF,WACE,qJACF,iBAAkB,uFAClB,UAAW,wFACX,YACE,sGACF,iBACE,4HACF,UACE,sHACF,YACE,kKACF,mBACE,kHACF,YACE,2GACF,UACE,mJACF,eACE,8JACF,WACE,kKACF,WACE,2IACF,aACE,uIACF,eACE,oJACJ,EAEF,YAAa,CACX,GAAGA,EAAG,YACN,QAAS,uBACT,OAAQ,yCACR,UAAW,aACX,SACE,gGACF,QAAS,UACT,QAAS,YACT,UAAW,oBACX,eAAgB,wCAChB,SAAU,eACV,UAAW,gCACX,MAAO,wBACP,QAAS,qBACT,QAAS,qCACT,cAAe,0DACf,aAAc,+EACd,iBAAkB,8BAClB,cAAe,8CACf,OAAQ,IACR,UAAW,SACX,aAAc,yCACd,kBACE,iLAEJ,IAAK,CACH,GAAGA,EAAG,IACN,QAAS,YACT,QAAS,iCACT,IAAK,OACL,KAAM,OACN,UAAW,cACX,gBAAiB,kDACjB,MAAO,cACP,aAAc,wEACd,QAAS,2DACT,cAAe;AAAA;AAAA,QACf,UAAW,sCACX,MAAO,QACP,SAAU,mCACV,eAAgB,iCAChB,UAAW,YACX,KAAM,OACN,aAAc,qBACd,iBACE,qNACF,iBAAkB,8EAClB,aAAc,4BACd,kBAAmB,+CACnB,iBACE,gOACF,SAAU,iFACV,WAAY,kBACZ,eAAgB,uBAChB,aAAc,oBACd,QAAS,OACT,QAAS,eACT,OAAQ,MACR,YAAa,aACb,kBAAmB,wBACnB,mBAAoB,iBACpB,gBAAiB,yBACjB,qBAAsB,4CACtB,oBAAqB,0CACrB,0BAA2B,qDAC3B,qBAAsB,sBACtB,yBAA0B,mDAC1B,iBAAkB,kEAClB,wBAAyB,yBACzB,qBAAsB,iEACtB,mBAAoB,eACpB,oBAAqB,+CACrB,qBAAsB,uBACtB,4BAA6B,mCAC7B,mBAAoB,sBACpB,oBAAqB,sCACrB,qBAAsB,aACtB,qBACE,mHACF,0BACE,2KACF,0BAA2B,cAC3B,qBAAsB,iBACtB,oBAAqB,mCACrB,mBACE,mHACF,uBACE,8IAEJ,OAAQ,CACN,GAAGA,EAAG,OACN,QAAS,eACT,MAAO,2BACP,OAAQ,YACR,OAAQ,YACR,QAAS,6BACT,SAAU,iCACV,SAAU,sFACV,MAAO,kBACP,MAAO,sBACP,WAAY,gEAEd,MAAO,CACL,GAAGA,EAAG,MACN,QAAS,cACT,SAAU,YACV,YAAa,iBACb,UAAW,8CACX,QAAS,8EACT,UAAW,SACX,UAAW,6FACX,WAAY,wBACZ,QAAS,uBACT,cAAe,oCACf,WAAY,sBACZ,OAAQ,oDACR,QAAS,OACT,SAAU,QACV,QAAS,OACT,WAAY,YAEd,OAAQ,CACN,GAAGA,EAAG,OACN,QAAS,eACT,kBAAmB,iBACnB,QAAS,UACT,OAAQ,oBACR,OAAQ,SACR,QAAS,YACT,SAAU,cACV,cAAe,uBACf,OAAQ,oBACR,SAAU,0DACV,gBAAiB,+BACjB,eAAgB,8CAChB,YACE,oLACF,MAAO,6BACP,cAAe,gCACf,WAAY,6DAEd,OAAQ,CACN,GAAGA,EAAG,OACN,QAAS,mBACT,OAAQ,2CACR,aAAc,uBACd,QAAS,UACT,SAAU,QACV,OAAQ,YACR,UAAW,aACX,eAAgB,6BAChB,SAAU,UACV,UAAW,qBACX,SAAU,YACV,GAAI,OACJ,OAAQ,SACR,cAAe,qBACf,MAAO,aACP,KAAM,UACN,SAAU,yCACV,SAAU,cACV,eAAgB,mBAChB,UAAW,kBACX,QAAS,kBACT,WAAY,qCACZ,WAAY,gBACZ,MAAO,QACP,KAAM,OACN,aAAc,YACd,WAAY,SACZ,aAAc,aACd,UAAW,WAEb,MAAO,CACL,GAAGA,EAAG,MACN,QAAS,cACT,OAAQ,gCACR,QAAS,wGACT,kBAAmB,gBACnB,OAAQ,QACR,KAAM,WACN,KAAM,UACN,MAAO,WACP,SAAU,0BACV,QAAS,eACT,aAAc,wCACd,KAAM,eAER,SAAU,CACR,GAAGA,EAAG,SACN,aAAc,uCACd,WAAY,iBACZ,QAAS,kBACT,MAAO,SACP,YAAa,qBACb,cAAe,sBACf,kBACE,mGACF,WAAY,mBACZ,SAAU,wCACV,MAAO,SACP,YACE,kHACF,OAAQ,SACR,WAAY,iEACZ,YAAa,iBACb,WAAY,kCACZ,MAAO,SACP,aAAc,sCACd,UAAW,4BACX,QAAS,SACT,UAAW,iBACX,YAAa,eACb,YAAa,aACb,mBAAoB,iBACpB,OAAQ,SACR,MAAO,UACP,IAAK,MACL,KAAM,QACN,UAAW,oBACX,UAAW,eACX,cAAe,iBACf,iBACE,8IACF,aAAc,2DACd,QAAS,iBACT,MAAO,YACP,QAAS,gBACT,KAAM,QACN,SAAU,WACV,aAAc,YACd,aAAc,oBACd,OAAQ,UACR,OAAQ,gBACR,iBAAkB,uFAClB,kBAAmB,mCACnB,yBAA0B,uEAC1B,8BAA+B,iEAC/B,gBAAiB,iEACjB,UAAW,oBACX,UAAW,cACX,gBAAiB,oDACjB,eAAgB,4BAChB,mBACE,qIACF,OAAQ,SACR,OAAQ,aACR,MAAO,WACP,QAAS,QACT,aAAc,SACd,GAAI,QACJ,KAAM,UACN,OAAQ,UACR,YAAa,sBACb,MAAO,eACP,YAAa,6BACb,aAAc,uBACd,YAAa,6BACb,gBAAiB,sBACjB,KAAM,OACN,iBAAkB,sBAClB,aAAc,kBACd,WAAY,6CACZ,QAAS,WACT,kBAAmB,oEACnB,UAAW,SACX,QAAS,0CACT,UAAW,wCACX,eAAgB,2EAChB,eAAgB,qEAChB,cAAe,sCACf,IAAK,MACL,WAAY,eACZ,UAAW,kBACX,WAAY,mBACZ,WAAY,kBACZ,UAAW,WACX,WAAY,SACZ,eAAgB,cAChB,YAAa,uBACb,SAAU,SACV,QAAS,mBACT,QAAS,mBACT,QAAS,uBACT,eAAgB,4BAChB,OAAQ,WACR,MAAO,sBACP,QAAS,mBACT,OAAQ,yBACR,aAAc,8BACd,eAAgB,0BAChB,mBAAoB,sCACpB,cAAe,gEACf,eAAgB,sCAChB,SAAU,mBACV,cAAe,wEACf,aAAc,8EACd,YAAa,oFACb,eAAgB,4CAChB,QAAS,gBAEX,MAAO,CACL,GAAGA,EAAG,MACN,WAAY,eACZ,aAAc,qBACd,cAAe,6CACf,gBAAiB,4CACjB,UAAW,8BACX,aAAc,sBACd,SAAU,QACV,UAAW,YACX,iBAAkB,UAClB,qBAAsB,kBACtB,QAAS,mBACT,YAAa,4BACb,KAAM,WACN,YAAa,gCACb,QAAS,0BACT,eAAgB,6DAChB,gBAAiB,6BACjB,KAAM,SACN,OAAQ,YACR,cAAe,6DACf,UAAW,mBACX,aAAc,6DACd,oBACE,qFACF,kBAAmB,qCACnB,QAAS,aACT,OAAQ,aACR,eAAgB,sBAChB,UAAW,kCACX,aAAc,uDACd,OAAQ,SACR,MAAO,UACP,eAAgB,wCAChB,kBAAmB,mFACnB,UAAW,mBACX,QAAS,iBACT,aAAc,iCACd,YAAa,aACb,UAAW,gBACX,QAAS,QACT,cAAe,kDACf,aAAc,uBACd,OAAQ,cACR,OAAQ,WACR,UAAW,YACX,kBAAmB,6EACnB,aAAc,UACd,YAAa,qBACb,eAAgB,aAChB,WAAY,SACZ,cAAe,eACf,gBAAiB,iBACjB,aAAc,cACd,UAAW,OACX,qBAAsB,kCACtB,YAAa,aAEf,MAAO,CACL,GAAGA,EAAG,MACN,MAAO,wCACP,KAAM,6JACN,YAAa,mBACb,OAAQ,YACR,eAAgB,oBAChB,QAAS,kBACT,SAAU,0CACV,MAAO,mBACP,WAAY,qBAEd,IAAK,CACH,GAAGA,EAAG,IACN,QAAS,cACT,WAAY,WACZ,SAAU,WACV,QAAS,YAEX,MAAO,CACL,GAAGA,EAAG,MACN,QAAS,aACT,SAAU,gBACV,iBAAkB,wBAClB,KAAM,SACN,UAAW,WACX,iBAAkB,sBAClB,aAAc,yBACd,YAAa,YACb,KAAM,SACN,QAAS,cACT,MAAO,SACP,UAAW,SACX,OAAQ,iBACR,KAAM,UACN,kBAAmB,eACnB,WAAY,SACZ,OAAQ,UACR,iBAAkB,OAClB,OAAQ,SACR,eAAgB,kBAChB,eAAgB,wBAChB,kBAAmB,0BACnB,cAAe,YACf,OAAQ,WACR,QAAS,QACT,WAAY,QACZ,iBAAkB,iBAClB,cAAe,yBACf,iBAAkB,2BAClB,YAAa,WACb,SAAU,YACV,aAAc,QACd,UAAW,UACX,aAAc,oBACd,qBAAsB,6BACtB,eAAgB,0BAChB,gBAAiB,kBAEnB,UAAW,CACT,GAAGA,EAAG,UACN,QAAS,YACT,KAAM,WACN,OAAQ,iBACR,QAAS,aACT,QAAS,SAEX,SAAU,CACR,GAAGA,EAAG,SACN,SAAU,mBACV,MAAO,YACP,eAAgB,mBAChB,SAAU,UACV,cAAe,UACf,QAAS,aACT,gBAAiB,SACjB,WAAY,iBACZ,YAAa,gBACb,UAAW,eACX,aAAc,mBACd,aAAc,WACd,QAAS,aACT,UAAW,gBACX,YAAa,mBACb,MAAO,gBACP,WAAY,2BACZ,OAAQ,YACR,KAAM,SACN,YAAa,gBACb,YAAa,kBACb,aAAc,4BACd,cAAe,uBAEjB,aAAc,CACZ,GAAGA,EAAG,aACN,MAAO,WACP,IAAK,SACL,iBAAkB,kBAClB,SAAU,QACV,cAAe,iBACf,cAAe,aACf,aAAc,WACd,WAAY,kBACZ,SAAU,UACV,WAAY,UACZ,QAAS,OACT,UAAW,mBACX,cAAe,eACf,cAAe,YACf,YAAa,cACb,SAAU,mBACV,UAAW,iBACX,SAAU,SACV,YAAa,cACb,aAAc,eACd,SAAU,MACV,SAAU,QACV,UAAW,SACX,YAAa,SACb,WAAY,2BACZ,cAAe,qBACf,YAAa,aACb,aAAc,mBACd,WAAY,cACZ,mBAAoB,kBACpB,SAAU,SACV,cAAe,mBACf,SAAU,OACV,YAAa,SACb,aAAc,UACd,SAAU,QACV,QAAS,aAEX,SAAU,CACR,GAAGA,EAAG,SACN,QAAS,wBAEX,WAAY,CACV,GAAGA,EAAG,WACN,QAAS,aACT,QAAS,WACT,MAAO,QACP,SAAU,gBACV,cAAe,iBACf,YAAa,WACb,OAAQ,UACR,OAAQ,SACR,UAAW,YACX,OAAQ,WACR,YAAa,iBACb,aAAc,kBACd,cAAe,YACf,YAAa,YACb,WAAY,WACZ,eAAgB,WAChB,cAAe,UACf,gBAAiB,YAEnB,KAAM,CACJ,GAAGA,EAAG,KACN,MAAO,yBACP,OAAQ,UACR,QAAS,YACT,SAAU,aACV,QAAS,QACT,KAAM,QACN,QAAS,eACT,WAAY,oBACZ,QAAS,QACT,MAAO,oBAET,KAAM,CACJ,GAAGA,EAAG,KACN,iBAAkB,8BAClB,UAAW,YACX,QAAS,QACT,WAAY,WACZ,IAAK,MAEP,SAAU,CACR,GAAGA,EAAG,SACN,OAAQ,WACR,KAAM,WACN,kBAAmB,sBACnB,cAAe,eACf,eAAgB,eAElB,QAAS,CACP,GAAGA,EAAG,QACN,MAAO,YACP,UAAW,6BACX,MAAO,OACP,UAAW,cACX,cAAe,sBACf,SAAU,gBACV,aAAc,0BACd,SAAU,wBACV,aAAc,qCACd,SAAU,0BACV,aAAc,uCACd,YAAa,WACb,MAAO,0BACP,SAAU,2BACV,aAAc,sCACd,cAAe,uBACf,UAAW,YACX,SAAU,UACV,QAAS,YACT,YAAa,WACb,SAAU,aACV,cAAe,gBACf,eAAgB,iBAChB,QAAS,aACT,YAAa,0BACb,OAAQ,YACR,WAAY,mBACZ,cAAe,0BACf,kBAAmB,wBACnB,kBAAmB,kBACnB,SAAU,gBACV,aAAc,wBAEhB,MAAO,CACL,GAAGA,EAAG,MACN,YAAa,oBAEf,aAAc,CACZ,GAAGA,EAAG,aACN,cAAe,qBACf,OAAQ,YACR,eAAgB,mBAChB,QAAS,WACT,OAAQ,UACR,cAAe,kBACf,SAAU,WACV,QAAS,cACT,QAAS,QACT,aAAc,sBACd,WAAY,WACZ,QAAS,aACT,UAAW,gBACX,WAAY,kBACZ,OAAQ,SACR,eAAgB,yBAChB,aAAc,YACd,SAAU,gBACV,SAAU,YAEZ,UAAW,CACT,GAAGA,EAAG,UACN,QAAS,WACT,KAAM,cACN,MAAO,QACP,SAAU,gBACV,KAAM,OACN,QAAS,mBACT,QAAS,UACT,OAAQ,SACR,eAAgB,mBAChB,YAAa,iBACb,gBAAiB,0BACjB,UAAW,SACX,WAAY,OACZ,mBAAoB,UACpB,oBAAqB,YACrB,oBAAqB,YACrB,mBAAoB,cACpB,SAAU,cACV,OAAQ,UAEV,OAAQ,CACN,GAAGA,EAAG,OACN,WAAY,eACZ,UAAW,iBACX,WAAY,qBACZ,YAAa,iBACb,kBAAmB,0BACnB,QAAS,aACT,eAAgB,2BAChB,OAAQ,YACR,eAAgB,aAChB,cAAe,8BACf,gBAAiB,uBACjB,SAAU,aACV,SAAU,aACV,YAAa,qBACb,aAAc,mBACd,QAAS,YACT,aAAc,oBACd,UAAW,oBACX,YAAa,mBACb,eAAgB,cAChB,qBAAsB,mBACtB,iBAAkB,qBAClB,YAAa,sBACb,cAAe,yBACf,uBAAwB,mCACxB,OAAQ,aACR,OAAQ,WACR,OAAQ,eACR,aAAc,gBACd,YAAa,mBACb,KAAM,kBACN,WAAY,mBACZ,qBAAsB,2BACtB,WAAY,mBACZ,sBAAuB,oBACvB,UAAW,eACX,KAAM,QACN,SAAU,WACV,eAAgB,kBAChB,wBAAyB,uCACzB,IAAK,MAEP,QAAS,CACP,GAAGA,EAAG,QACN,OAAQ,eACR,OAAQ,YACR,MAAO,wBACP,SAAU,4BACV,GAAI,UACJ,MAAO,4BACP,QAAS,QACT,SAAU,uBACV,gBAAiB,kBACjB,UAAW,4DACX,kBAAmB,+BACnB,MAAO,kBAET,MAAO,CACL,GAAGA,EAAG,MACN,MAAO,YACP,KAAM,aACN,aAAc,OACd,QAAS,iCACT,QAAS,WAEX,OAAQ,CACN,GAAGA,EAAG,OACN,QAAS,uCACT,WAAY,aACZ,SAAU,qCACV,QAAS,2DAEX,SAAU,CACR,GAAGA,EAAG,SACN,KAAM,OACN,SAAU,qEACV,OAAQ,aACR,WAAY,+DACZ,KAAM,OACN,SAAU,6CACV,KAAM,OACN,SAAU,qDAEd,EC91CaE,GAAO,CAClB,IAAK,CACH,iBAAkB,MAClB,eAAgB,KAChB,iBAAkB,KAClB,QAAS,KACT,SAAU,KACV,YAAa,KACb,YAAa,KACb,SAAU,KACV,UAAW,KACX,YAAa,KACb,SAAU,KACV,eAAgB,KAChB,OAAQ,MACR,UAAW,KACX,UAAW,KACX,SAAU,KACV,YAAa,KACb,eAAgB,KAChB,WAAY,KACZ,OAAQ,yBACR,YAAa,OACb,WAAY,KACZ,UAAW,KACX,MAAO,CACL,MAAO,CACL,QAAS,KACT,OAAQ,KACR,QAAS,MAEX,MAAO,CACL,SAAU,MACV,OAAQ,MAEV,QAAS,MAEX,uBAAwB,OACxB,gBAAiB,OACjB,gBAAiB,OACjB,MAAO,CACL,iBAAkB,QAClB,gBAAiB,YACjB,YAAa,QACb,YAAa,OACb,YAAa,OACb,YAAa,OACb,QAAS,iBAEX,WAAY,KACZ,WAAY,OACZ,QAAS,CACP,OAAQ,KACR,IAAK,QAEP,MAAO,CACL,OAAQ,QACR,YAAa,cACb,YAAa,SACb,aAAc,QACd,QAAS,KACT,UAAW,OAEb,IAAK,CACH,OAAQ,SACR,YAAa,SAEf,SAAU,CACR,UAAW,OACX,MAAO,KACP,eAAgB,OAChB,aAAc,QACd,OAAQ,eACR,SAAU,eACV,SAAU,MACV,SAAU,MACV,KAAM,KACN,QAAS,KACT,SAAU,KACV,QAAS,MACT,eAAgB,QAElB,MAAO,CACL,QAAS,QACT,OAAQ,UACR,SAAU,gBACV,aAAc,SACd,kBAAmB,OACnB,WAAY,gBACZ,aAAc,OACd,aAAc,QACd,cAAe,eACf,eAAgB,gBAChB,aAAc,QACd,WAAY,UAEd,KAAM,CACJ,MAAO,cAET,IAAK,CACH,MAAO,KACP,IAAK,QACL,UAAW,OACX,QAAS,KACT,SAAU,OACV,SAAU,eACV,SAAU,KACV,KAAM,KACN,WAAY,OACZ,MAAO,KACP,YAAa,OACb,eAAgB,OAChB,WAAY,OACZ,YAAa,QAEf,OAAQ,CACN,MAAO,KACP,cAAe,OACf,KAAM,KACN,OAAQ,eACR,OAAQ,KACR,SAAU,eACV,QAAS,OACT,YAAa,OACb,QAAS,QAEX,aAAc,OACd,OAAQ,UACR,OAAQ,KACR,eAAgB,cAElB,QAAS,CACP,gBAAiB,UACjB,YAAa,mBACb,SAAU,KACV,kBAAmB,WACnB,UAAW,MACX,SAAU,OACV,gBAAiB,KACjB,kBAAmB,KACnB,SAAU,iBACV,WAAY,sBACZ,eAAgB,oBAChB,WAAY,eACZ,SAAU,MACV,WAAY,UACZ,UAAW,kBACX,YAAa,oBACb,YAAa,KACb,cAAe,KACf,gBAAiB,QACjB,eAAgB,KAChB,aAAc,YACd,OAAQ,KACR,SAAU,OACV,QAAS,KACT,aAAc,SACd,mBAAoB,QACpB,cAAe,KACf,cAAe,KACf,YAAa,IACb,YAAa,KACb,cAAe,KACf,cAAe,SACf,kBAAmB,QACnB,qBAAsB,MACtB,gBAAiB,QACjB,WAAY,KACZ,eAAgB,8BAChB,UAAW,KACX,cAAe,qBACf,UAAW,KACX,kBAAmB,SACnB,WAAY,OACZ,YAAa,WACb,iBAAkB,OAClB,eAAgB,OAChB,UAAW,OACX,YAAa,OACb,aAAc,OACd,cAAe,OACf,aAAc,QAEhB,OAAQ,CACN,QAAS,OACT,cAAe,mBACf,KAAM,OACN,KAAM,KACN,OAAQ,KACR,OAAQ,KACR,OAAQ,KACR,IAAK,KACL,QAAS,KACT,OAAQ,YACR,IAAK,KACL,IAAK,IACL,GAAI,IACJ,GAAI,KACJ,IAAK,KACL,QAAS,MACT,SAAU,OAEZ,SAAU,CACR,MAAO,KACP,QAAS,QACT,MAAO,eACP,WAAY,eACZ,OAAQ,SACR,aAAc,MACd,WAAY,OACZ,UAAW,MACX,WAAY,SACZ,OAAQ,QACR,QAAS,KACT,SAAU,eACV,QAAS,OACT,QAAS,SACT,mBAAoB,+BACpB,YAAa,gBACb,gBAAiB,OACjB,cAAe,OACf,YAAa,WACb,gBAAiB,4CACjB,kBAAmB,qBACnB,gBAAiB,QACjB,OAAQ,OACR,UAAW,0CACX,WAAY,+BACZ,aAAc,SACd,UAAW,UACX,UAAW,OACX,cAAe,4BACf,gBAAiB,OACjB,oBAAqB,2BACrB,uBAAwB,0CACxB,sBAAuB,+CACvB,sBAAuB,0CACvB,0BAA2B,8CAC3B,mBAAoB,4CACpB,oBAAqB,sBACrB,cAAe,KACf,OAAQ,KACR,WAAY,SACZ,kBAAmB,SACnB,SAAU,IACV,aAAc,OACd,aAAc,MACd,eAAgB,UAChB,YAAa,OACb,eAAgB,uBAChB,eAAgB,uBAChB,eAAgB,qBAChB,YAAa,KACb,aAAc,oBACd,aAAc,uBACd,aAAc,KACd,WAAY,MACZ,eAAgB,iBAChB,WAAY,MACZ,sBAAuB,mBACvB,UAAW,OACX,SAAU,KACV,YAAa,MACb,SAAU,aACV,YAAa,kBACb,cAAe,KACf,WAAY,OACZ,sBAAuB,uCACvB,eAAgB,0BAChB,YAAa,SACb,aAAc,QACd,mBAAoB,QACpB,iBAAkB,MAClB,kBAAmB,yBACnB,eAAgB,MAChB,YAAa,OACb,MAAO,KACP,eAAgB,mBAChB,aAAc,eACd,iBAAkB,mDAClB,SAAU,OACV,aAAc,aACd,aAAc,SACd,iBAAkB,OAClB,qBAAsB,8BACtB,MAAO,KACP,OAAQ,KACR,QAAS,OACT,gBAAiB,KACjB,SAAU,KACV,aAAc,OACd,OAAQ,UACR,SAAU,OACV,kBAAmB,KACnB,gBAAiB,KACjB,qBAAsB,WACtB,wBAAyB,SACzB,MAAO,KACP,UAAW,KACX,UAAW,eACX,WAAY,KACZ,WAAY,OACZ,eAAgB,SAChB,mBAAoB,KACpB,uBAAwB,iBACxB,oBAAqB,KACrB,wBAAyB,iBACzB,oBAAqB,KACrB,wBAAyB,eACzB,mBAAoB,KACpB,uBAAwB,eACxB,iBAAkB,KAClB,gBAAiB,iBACjB,gBAAiB,KACjB,eAAgB,aAChB,aAAc,UACd,YAAa,aACb,gBAAiB,KACjB,eAAgB,uBAChB,gBAAiB,KACjB,eAAgB,cAChB,eAAgB,KAChB,cAAe,sBACf,iBAAkB,KAClB,gBAAiB,mBACjB,mBAAoB,MACpB,kBAAmB,WACnB,WAAY,KACZ,eAAgB,OAChB,eAAgB,MAChB,gBAAiB,KACjB,iBAAkB,KAClB,UAAW,OACX,cAAe,SACf,eAAgB,IAChB,gBAAiB,IACjB,eAAgB,IAChB,iBAAkB,QAClB,oBAAqB,OACrB,OAAQ,MACR,WAAY,UACZ,UAAW,OACX,gBAAiB,OACjB,oBAAqB,SACrB,YAAa,OACb,iBAAkB,KAClB,aAAc,KACd,WAAY,OACZ,aAAc,QACd,UAAW,QACX,YAAa,MACb,WAAY,OACZ,gBAAiB,KACjB,iBAAkB,MAClB,OAAQ,KACR,cAAe,aACf,WAAY,MACZ,cAAe,MACf,SAAU,YACV,cAAe,MACf,UAAW,KACX,cAAe,UACf,aAAc,QACd,WAAY,SACZ,cAAe,KACf,cAAe,KACf,iBAAkB,OAClB,uBAAwB,OACxB,sBAAuB,QACvB,gBAAiB,OACjB,eAAgB,OAChB,iBAAkB,KAClB,kBAAmB,OACnB,kBAAmB,OACnB,aAAc,KACd,cAAe,MACf,2BAA4B,aAC5B,gBAAiB,MACjB,QAAS,SACT,cAAe,KACf,aAAc,KACd,YAAa,aACb,OAAQ,KACR,YAAa,KACb,gBAAiB,WACjB,iBAAkB,QAClB,YAAa,MACb,aAAc,OACd,eAAgB,MAChB,cAAe,KACf,SAAU,KACV,aAAc,OACd,UAAW,OACX,OAAQ,KACR,iBAAkB,QAClB,UAAW,QACX,eAAgB,SAChB,gBAAiB,KACjB,iBAAkB,MAClB,QAAS,UAEX,KAAM,CACJ,WAAY,SACZ,SAAU,OACV,YAAa,8CACb,gBAAiB,aACjB,qBAAsB,6BACtB,UAAW,kBACX,KAAM,KACN,IAAK,KACL,MAAO,KACP,SAAU,8BACV,WAAY,6BACZ,eAAgB,mBAChB,eAAgB,oBAChB,WAAY,eACZ,SAAU,MACV,WAAY,UACZ,UAAW,kBACX,YAAa,oBACb,iBAAkB,gBAClB,eAAgB,cAChB,mBACE,oDACF,kBAAmB,OACnB,sBAAuB,WACvB,cAAe,OACf,aAAc,OACd,YAAa,2BACb,eAAgB,mBAChB,gBAAiB,+BACjB,kBAAmB,SACnB,eAAgB,UAChB,cAAe,6BACf,gBAAiB,mCACjB,cAAe,2BACf,cAAe,gCACf,YAAa,KACb,UAAW,KACX,cAAe,YACf,SAAU,KACV,aAAc,OACd,eAAgB,OAChB,UAAW,KACX,eAAgB,OAChB,aAAc,KACd,YAAa,KACb,UAAW,MACX,YAAa,KACb,WAAY,KACZ,cAAe,KACf,cAAe,KACf,YAAa,YACb,aAAc,gBACd,cAAe,UACf,gBAAiB,MACjB,iBAAkB,MAClB,kBAAmB,MACnB,gBAAiB,MACjB,kBAAmB,gBACnB,YAAa,gBACb,SAAU,WACV,WAAY,SACZ,UAAW,SACX,aAAc,WACd,YAAa,gBAEf,SAAU,CACR,QAAS,QACT,OAAQ,eACR,gBAAiB,OACjB,eACE,2DACF,QAAS,MACT,QAAS,KACT,SAAU,eACV,SAAU,OACV,aAAc,eACd,OAAQ,KACR,eAAgB,OAChB,UAAW,+CACX,UAAW,YACX,cAAe,YACf,KAAM,KACN,UAAW,YACX,WAAY,OACZ,OAAQ,QACR,YAAa,OACb,QAAS,8BACT,aAAc,OACd,YAAa,UACb,YAAa,QACb,WAAY,UACZ,SAAU,OACV,QAAS,WACT,WAAY,OACZ,YAAa,QACb,YAAa,QACb,OAAQ,OACR,QAAS,qBACT,OAAQ,KACR,MAAO,OACP,YAAa,UACb,SAAU,MACV,OAAQ,MAEV,MAAO,CACL,QAAS,QACT,OAAQ,eACR,QAAS,cACT,WAAY,OACZ,UAAW,iBACX,OAAQ,oDACR,QAAS,OACT,UAAW,OACX,SAAU,KACV,YAAa,OACb,QAAS,WACT,cAAe,OACf,YAAa,YACb,SAAU,KACV,SAAU,KACV,QAAS,KACT,UAAW,KACX,WAAY,KACZ,iBAAkB,OAClB,YAAa,KACb,SAAU,QACV,SAAU,MAEZ,SAAU,CACR,QAAS,QACT,OAAQ,eACR,WAAY,YACZ,kBAAmB,OACnB,KAAM,MACN,SAAU,kBACV,YAAa,YACb,WAAY,yCACZ,kBAAmB,SACnB,gBAAiB,SACjB,SAAU,cACV,OAAQ,OACR,QAAS,eACT,UAAW,SACX,UAAW,KACX,cAAe,gCACf,iBAAkB,qBAClB,eACE,4DACF,WAAY,KACZ,WAAY,MAEd,MAAO,CACL,QAAS,QACT,OAAQ,eACR,QAAS,WACT,SAAU,cACV,QAAS,KACT,SAAU,KACV,QAAS,KACT,SAAU,KACV,MAAO,KACP,KAAM,KACN,KAAM,CACJ,WACE,iEACF,UACE,uDACF,YACE,iEACF,eACE,iEACF,WAAY,oCACZ,aAAc,2CACd,SAAU,iDACV,UAAW,+CACX,SACE,sDACF,OACE,oDACF,cAAe,2BACf,UACE,+DACF,eAAgB,2BAChB,eAAgB,uCAChB,aAAc,yCACd,eACE,0DACF,KAAM,sEACN,cAAe,kCACf,WAAY,2BACZ,UAAW,6CACX,WACE,yDACF,iBAAkB,2BAClB,UAAW,sBACX,YAAa,iDACb,iBAAkB,4CAClB,UAAW,6BACX,YACE,4CACF,mBAAoB,kCACpB,YAAa,mCACb,UACE,kDACF,eAAgB,uCAChB,WAAY,wCACZ,WAAY,mCACZ,aAAc,4CACd,eACE,4DACJ,EAEF,YAAa,CACX,QAAS,QACT,OAAQ,eACR,UAAW,UACX,SAAU,uDACV,QAAS,KACT,QAAS,KACT,UAAW,OACX,eAAgB,mCAChB,SAAU,OACV,UAAW,iBACX,MAAO,eACP,QAAS,eACT,QAAS,gBACT,cAAe,2BACf,aAAc,yBACd,iBAAkB,mBAClB,cAAe,cACf,OAAQ,IACR,UAAW,KACX,aAAc,oBACd,kBACE,0FAEJ,IAAK,CACH,QAAS,UACT,QAAS,yBACT,IAAK,KACL,KAAM,KACN,UAAW,MACX,gBAAiB,8CACjB,MAAO,MACP,aAAc,iCACd,QAAS,kBACT,cAAe;AAAA;AAAA,QACf,UAAW,iBACX,MAAO,MACP,SAAU,aACV,eAAgB,aAChB,UAAW,KACX,KAAM,KACN,aAAc,UACd,iBACE,8EACF,iBAAkB,kCAClB,aAAc,OACd,kBAAmB,cACnB,iBACE,wEACF,SAAU,gCACV,WAAY,eACZ,eAAgB,eAChB,aAAc,eACd,QAAS,KACT,QAAS,KACT,OAAQ,MACR,YAAa,KACb,kBAAmB,SACnB,mBAAoB,SACpB,gBAAiB,UACjB,qBAAsB,oCACtB,oBAAqB,eACrB,0BAA2B,aAC3B,qBAAsB,SACtB,yBAA0B,0BAC1B,iBAAkB,oDAClB,wBAAyB,SACzB,qBAAsB,oBACtB,mBAAoB,KACpB,oBAAqB,kBACrB,qBAAsB,eACtB,4BAA6B,kBAC7B,mBAAoB,OACpB,oBAAqB,kBACrB,qBAAsB,aACtB,qBACE,oEACF,0BACE,mFACF,0BAA2B,MAC3B,qBAAsB,KACtB,oBAAqB,UACrB,mBAAoB,mDACpB,uBACE,wEAEJ,OAAQ,CACN,QAAS,QACT,MAAO,mBACP,OAAQ,MACR,OAAQ,KACR,QAAS,UACT,SAAU,aACV,SAAU,kDACV,MAAO,cACP,MAAO,cACP,WAAY,uBAEd,MAAO,CACL,QAAS,QACT,SAAU,MACV,YAAa,OACb,UAAW,+BACX,QAAS,wBACT,UAAW,KACX,UAAW,kDACX,WAAY,QACZ,QAAS,OACT,cAAe,iBACf,WAAY,OACZ,OAAQ,kBACR,QAAS,KACT,SAAU,KACV,QAAS,KACT,WAAY,MAEd,OAAQ,CACN,QAAS,QACT,kBAAmB,OACnB,QAAS,KACT,OAAQ,MACR,OAAQ,KACR,QAAS,KACT,SAAU,MACV,cAAe,QACf,OAAQ,YACR,SAAU,qBACV,gBAAiB,UACjB,eAAgB,aAChB,YACE,mDACF,MAAO,qBACP,cAAe,uBACf,WAAY,uBAEd,OAAQ,CACN,QAAS,UACT,OAAQ,iBACR,aAAc,OACd,QAAS,KACT,SAAU,MACV,OAAQ,OACR,UAAW,SACX,eAAgB,QAChB,SAAU,OACV,UAAW,eACX,SAAU,KACV,GAAI,OACJ,OAAQ,KACR,cAAe,OACf,MAAO,QACP,KAAM,MACN,SAAU,wBACV,SAAU,OACV,eAAgB,OAChB,UAAW,QACX,QAAS,eACT,WAAY,YACZ,WAAY,aACZ,MAAO,KACP,KAAM,MACN,aAAc,KACd,WAAY,KACZ,aAAc,KACd,UAAW,MAEb,MAAO,CACL,QAAS,QACT,OAAQ,eACR,QAAS,sDACT,kBAAmB,OACnB,OAAQ,MACR,KAAM,MACN,KAAM,MACN,MAAO,KACP,SAAU,WACV,QAAS,QACT,aAAc,2BACd,KAAM,UAER,SAAU,CACR,aAAc,cACd,WAAY,QACZ,QAAS,OACT,MAAO,KACP,YAAa,OACb,cAAe,YACf,kBAAmB,wCACnB,WAAY,mBACZ,SAAU,2BACV,MAAO,SACP,YAAa,uCACb,OAAQ,OACR,WAAY,oCACZ,YAAa,SACb,WAAY,uBACZ,MAAO,KACP,aAAc,gBACd,UAAW,gBACX,QAAS,OACT,UAAW,aACX,YAAa,OACb,YAAa,QACb,mBAAoB,QACpB,OAAQ,KACR,MAAO,KACP,IAAK,KACL,KAAM,KACN,UAAW,OACX,UAAW,OACX,cAAe,OACf,iBACE,mDACF,aAAc,2BACd,QAAS,OACT,MAAO,KACP,QAAS,OACT,KAAM,KACN,SAAU,MACV,aAAc,OACd,aAAc,oBACd,OAAQ,UACR,OAAQ,UACR,iBAAkB,2BAClB,kBAAmB,SACnB,yBAA0B,2BAC1B,8BAA+B,qBAC/B,gBAAiB,kBACjB,UAAW,QACX,UAAW,OACX,gBAAiB,cACjB,eAAgB,SAChB,mBACE,0EACF,OAAQ,SACR,OAAQ,MACR,MAAO,MACP,QAAS,KACT,aAAc,OACd,GAAI,MACJ,KAAM,MACN,OAAQ,MACR,YAAa,OACb,MAAO,KACP,YAAa,OACb,aAAc,OACd,YAAa,QACb,gBAAiB,OACjB,KAAM,OACN,iBAAkB,gBAClB,aAAc,UACd,WAAY,uBACZ,QAAS,KACT,kBAAmB,wBACnB,UAAW,OACX,QAAS,iCACT,UAAW,eACX,eAAgB,yCAChB,eAAgB,sBAChB,cAAe,mBACf,IAAK,KACL,WAAY,OACZ,UAAW,OACX,WAAY,OACZ,WAAY,OACZ,UAAW,KACX,WAAY,KACZ,eAAgB,MAChB,YAAa,QACb,SAAU,MACV,QAAS,cACT,QAAS,cACT,QAAS,cACT,eAAgB,2BAChB,OAAQ,KACR,MAAO,cACP,QAAS,cACT,OAAQ,aACR,aAAc,yBACd,eAAgB,UAChB,mBAAoB,UACpB,cAAe,sBACf,eAAgB,4BAChB,SAAU,UACV,cAAe,qCACf,aAAc,6BACd,YAAa,mCACb,eAAgB,iBAChB,QAAS,MAEX,MAAO,CACL,WAAY,WACZ,aAAc,OACd,cAAe,oBACf,gBAAiB,kBACjB,UAAW,UACX,aAAc,uBACd,SAAU,KACV,UAAW,KACX,iBAAkB,KAClB,qBAAsB,OACtB,QAAS,OACT,YAAa,kBACb,KAAM,KACN,YAAa,UACb,QAAS,UACT,eAAgB,yBAChB,gBAAiB,aACjB,KAAM,KACN,OAAQ,KACR,cAAe,sBACf,UAAW,QACX,aAAc,mBACd,oBAAqB,iCACrB,kBAAmB,gBACnB,QAAS,KACT,OAAQ,KACR,eAAgB,OAChB,UAAW,QACX,aAAc,sCACd,OAAQ,MACR,MAAO,MACP,eAAgB,YAChB,kBAAmB,iCACnB,UAAW,aACX,QAAS,WACT,aAAc,gBACd,YAAa,KACb,UAAW,MACX,QAAS,KACT,cAAe,YACf,aAAc,OACd,OAAQ,KACR,OAAQ,KACR,UAAW,KACX,kBAAmB,uBACnB,aAAc,MACd,YAAa,QACb,eAAgB,OAChB,WAAY,KACZ,cAAe,KACf,gBAAiB,KACjB,aAAc,OACd,UAAW,MACX,qBAAsB,aACtB,YAAa,MAEf,MAAO,CACL,MAAO,SACP,KAAM,iDACN,YAAa,OACb,OAAQ,QACR,eAAgB,eAChB,QAAS,WACT,SAAU,mBACV,MAAO,KACP,WAAY,QAEd,IAAK,CACH,QAAS,KACT,WAAY,UACZ,SAAU,UACV,QAAS,UAEX,MAAO,CACL,QAAS,MACT,SAAU,OACV,iBAAkB,QAClB,KAAM,KACN,UAAW,KACX,iBAAkB,OAClB,aAAc,MACd,YAAa,KACb,KAAM,KACN,QAAS,KACT,MAAO,KACP,UAAW,KACX,OAAQ,KACR,KAAM,KACN,kBAAmB,MACnB,WAAY,KACZ,OAAQ,KACR,iBAAkB,KAClB,OAAQ,MACR,eAAgB,aAChB,eAAgB,QAChB,kBAAmB,OACnB,cAAe,KACf,OAAQ,KACR,QAAS,MACT,WAAY,KACZ,iBAAkB,OAClB,cAAe,MACf,iBAAkB,SAClB,YAAa,KACb,SAAU,KACV,aAAc,MACd,UAAW,MACX,aAAc,QACd,qBAAsB,iBACtB,eAAgB,QAChB,gBAAiB,UAEnB,UAAW,CACT,QAAS,MACT,KAAM,KACN,OAAQ,KACR,QAAS,MACT,QAAS,OAEX,SAAU,CACR,SAAU,OACV,MAAO,KACP,eAAgB,OAChB,SAAU,KACV,cAAe,KACf,QAAS,KACT,gBAAiB,KACjB,WAAY,OACZ,YAAa,OACb,UAAW,KACX,aAAc,OACd,aAAc,KACd,QAAS,KACT,UAAW,MACX,YAAa,SACb,MAAO,KACP,WAAY,cACZ,OAAQ,KACR,KAAM,KACN,YAAa,OACb,YAAa,OACb,aAAc,SACd,cAAe,UAEjB,aAAc,CACZ,MAAO,KACP,IAAK,KACL,iBAAkB,OAClB,SAAU,KACV,cAAe,aACf,cAAe,QACf,aAAc,MACd,WAAY,cACZ,SAAU,KACV,WAAY,KACZ,QAAS,KACT,UAAW,cACX,cAAe,MACf,cAAe,OACf,YAAa,MACb,SAAU,YACV,UAAW,KACX,SAAU,KACV,YAAa,OACb,aAAc,OACd,SAAU,MACV,SAAU,KACV,UAAW,KACX,YAAa,KACb,WAAY,UACZ,cAAe,MACf,YAAa,KACb,aAAc,KACd,WAAY,KACZ,mBAAoB,aACpB,SAAU,KACV,cAAe,QACf,SAAU,OACV,YAAa,KACb,aAAc,KACd,SAAU,KACV,QAAS,MAEX,SAAU,CACR,QAAS,WAEX,WAAY,CACV,QAAS,KACT,QAAS,KACT,MAAO,KACP,SAAU,OACV,cAAe,QACf,YAAa,KACb,OAAQ,KACR,OAAQ,MACR,UAAW,KACX,OAAQ,KACR,YAAa,OACb,aAAc,OACd,cAAe,OACf,YAAa,KACb,WAAY,KACZ,eAAgB,KAChB,cAAe,KACf,gBAAiB,MAEnB,KAAM,CACJ,MAAO,QACP,OAAQ,MACR,QAAS,KACT,SAAU,KACV,QAAS,MACT,KAAM,KACN,QAAS,OACT,WAAY,SACZ,QAAS,KACT,MAAO,QAET,KAAM,CACJ,iBAAkB,UAClB,UAAW,KACX,QAAS,MACT,WAAY,SACZ,IAAK,KAEP,SAAU,CACR,OAAQ,OACR,KAAM,KACN,kBAAmB,UACnB,cAAe,OACf,eAAgB,QAElB,QAAS,CACP,MAAO,KACP,UAAW,SACX,MAAO,KACP,UAAW,OACX,cAAe,OACf,SAAU,OACV,aAAc,SACd,SAAU,OACV,aAAc,iBACd,SAAU,SACV,aAAc,WACd,YAAa,MACb,MAAO,QACP,SAAU,eACV,aAAc,oBACd,cAAe,QACf,UAAW,KACX,SAAU,KACV,QAAS,KACT,YAAa,KACb,SAAU,KACV,cAAe,KACf,eAAgB,MAChB,QAAS,OACT,YAAa,QACb,OAAQ,OACR,WAAY,QACZ,cAAe,QACf,kBAAmB,QACnB,kBAAmB,QACnB,SAAU,KACV,aAAc,QAEhB,MAAO,CACL,YAAa,QAEf,aAAc,CACZ,cAAe,OACf,OAAQ,KACR,eAAgB,OAChB,QAAS,SACT,OAAQ,KACR,cAAe,OACf,SAAU,UACV,QAAS,KACT,QAAS,OACT,aAAc,cACd,WAAY,UACZ,QAAS,OACT,UAAW,MACX,WAAY,MACZ,OAAQ,KACR,eAAgB,QAChB,aAAc,KACd,SAAU,KACV,SAAU,UAEZ,UAAW,CACT,QAAS,KACT,KAAM,KACN,MAAO,KACP,SAAU,OACV,KAAM,KACN,QAAS,OACT,QAAS,KACT,OAAQ,KACR,eAAgB,OAChB,YAAa,OACb,gBAAiB,QACjB,UAAW,KACX,WAAY,KACZ,mBAAoB,KACpB,oBAAqB,KACrB,oBAAqB,KACrB,mBAAoB,KACpB,SAAU,KACV,OAAQ,UAEV,OAAQ,CACN,WAAY,OACZ,UAAW,OACX,WAAY,OACZ,YAAa,OACb,kBAAmB,gBACnB,QAAS,KACT,eAAgB,OAChB,OAAQ,KACR,eAAgB,MAChB,cAAe,SACf,gBAAiB,QACjB,SAAU,KACV,SAAU,KACV,YAAa,OACb,aAAc,OACd,QAAS,KACT,aAAc,OACd,UAAW,OACX,YAAa,cACb,eAAgB,OAChB,qBAAsB,OACtB,iBAAkB,OAClB,YAAa,QACb,cAAe,oBACf,uBAAwB,UACxB,OAAQ,KACR,OAAQ,KACR,OAAQ,KACR,aAAc,KACd,YAAa,OACb,KAAM,OACN,WAAY,OACZ,qBAAsB,OACtB,WAAY,OACZ,sBAAuB,WACvB,UAAW,OACX,KAAM,KACN,SAAU,MACV,eAAgB,OAChB,wBAAyB,UACzB,IAAK,KAEP,QAAS,CACP,OAAQ,MACR,OAAQ,KACR,MAAO,OACP,SAAU,QACV,GAAI,KACJ,MAAO,SACP,QAAS,OACT,SAAU,QACV,gBAAiB,QACjB,UAAW,iBACX,kBAAmB,SACnB,MAAO,OAET,MAAO,CACL,MAAO,KACP,KAAM,KACN,aAAc,KACd,QAAS,aACT,QAAS,MAEX,OAAQ,CACN,QAAS,YACT,WAAY,KACZ,SAAU,uBACV,QAAS,oCAEX,SAAU,CACR,KAAM,KACN,SAAU,oBACV,OAAQ,KACR,WAAY,0BACZ,KAAM,KACN,SAAU,oBACV,KAAM,OACN,SAAU,yBAEd,ECzwCMC,GAAmC,CAAC,KAAM,QAAS,IAAI,EACvDC,GAA+B,IAAI,IAAUD,EAAe,EAC5DE,GAAoC,CAAE,GAAI,UAAW,QAAS,OAAQ,GAAI,WAC1EC,GAAc,gBAGdxH,GAAwB,GAE9B,SAASyH,IAAsB,CAC7B,GAAI,CACF,MAAMC,EAAS,aAAa,QAAQF,EAAW,EAC/C,GAAIE,GAAUJ,GAAU,IAAII,CAAc,EAAG,OAAOA,CACtD,MAAQ,CAER,CAEA,MAAMC,GADM,OAAO,UAAc,IAAc,UAAU,SAAW,IAClD,cAClB,OAAIA,EAAM,WAAW,IAAI,EAAU,QAC/BA,EAAM,WAAW,IAAI,EAAU,KAC5B,IACT,CAEA,IAAIC,GAAoBH,GAAA,EAExB,SAASI,GAAaC,EAAkB,CACtC,GAAI,SAAO,SAAa,KACxB,GAAI,CACF,SAAS,gBAAgB,KAAOA,CAClC,MAAQ,CAER,CACF,CAEAD,GAAaD,EAAW,EAEjB,SAASG,IAAgB,CAC9B,OAAOH,EACT,CAEO,SAASI,IAAqC,CACnD,OAAOX,EACT,CAEO,SAASY,GAAaH,EAAoB,CAC/C,OAAOP,GAAYO,CAAI,CACzB,CAEO,SAASI,GAAQJ,EAAkB,CACxC,GAAI,GAACR,GAAU,IAAIQ,CAAI,GAAKA,IAASF,IACrC,CAAAA,GAAcE,EACd,GAAI,CACF,aAAa,QAAQN,GAAaM,CAAI,CACxC,MAAQ,CAER,CACAD,GAAaC,CAAI,EACjB,UAAWlH,KAAMZ,GAAWY,EAAA,EAC9B,CAEO,SAASuH,GAAgB,CAC9B,KAAM,EAAGC,CAAO,EAAIC,WAAS,CAAC,EAC9BC,mBAAU,IAAM,CACd,MAAM1H,EAAK,IAAMwH,EAASG,GAAMA,EAAI,CAAC,EACrC,OAAAvI,GAAU,KAAKY,CAAE,EACV,IAAM,CACX,MAAM4H,EAAMxI,GAAU,QAAQY,CAAE,EAC5B4H,GAAO,GAAGxI,GAAU,OAAOwI,EAAK,CAAC,CACvC,CACF,EAAG,EAAE,EACEZ,EACT,CAEA,MAAMa,GAAQ,CAAE,GAAAvB,EAAI,QAASE,GAAM,GAAAD,EAAA,EAUnC,SAASuB,GAAQC,EAAYC,EAAqB,CAChD,MAAMC,EAAQD,EAAI,MAAM,GAAG,EAC3B,IAAIE,EAAkBH,EACtB,UAAWI,KAAKF,EACd,GAAIC,GAAU,OAAOA,GAAW,UAAYC,KAAMD,EAChDA,EAAUA,EAAmCC,CAAC,MAE9C,QAAOH,EAGX,OAAO,OAAOE,GAAW,SAAWA,EAASF,CAC/C,CAEO,SAASI,EAAEJ,EAAWK,EAAkD,CAC7E,MAAMjE,EAAM0D,GAAQD,GAAMb,EAAW,EAAGgB,CAAG,EAC3C,OAAKK,EACEjE,EAAI,QAAQ,aAAc,CAACkE,EAAGC,IAAOA,KAAKF,EAAS,OAAOA,EAAOE,CAAC,CAAC,EAAI,IAAIA,CAAC,GAAI,EADnEnE,CAEtB,CCtGA,SAASoE,IAAyB,CAChC,OAAI,OAAO,SAAa,IAAoB,GACrC,SAAS,gBAAgB,QAAQ,WAAa,OACvD,CAEA,SAASC,GAAST,EAAkBU,EAAsB,CACxD,OAAQV,EAAA,CACN,IAAK,MACL,IAAK,IACH,OAAOU,EAAM,IAAM,OACrB,IAAK,QACL,IAAK,IACH,OAAOA,EAAM,IAAM,QACrB,IAAK,QACL,IAAK,IACH,MAAO,QACT,IAAK,MACL,IAAK,IACH,MAAO,MACT,IAAK,MACH,MAAO,MACT,IAAK,SACL,IAAK,KACH,MAAO,KACT,QACE,OAAOV,CAAA,CAEb,CAEO,SAASW,GAAaC,EAAsC,CACjE,MAAMF,EAAMF,GAAA,EACZ,OAAOI,EAAK,IAAKZ,GAAQS,GAAST,EAAKU,CAAG,CAAC,EAAE,KAAKA,EAAM,GAAK,GAAG,CAClE,CAEO,SAASG,GAAqB1G,EAAsB,CACzD,OAAOA,EAAK,QAAQ,KAAMsG,GAAS,MAAOD,GAAA,CAAe,CAAC,CAC5D,CAEO,SAASM,EAAS,CACvB,KAAAF,EACA,UAAAG,CACF,EAGc,CACZ,MAAML,EAAMF,GAAA,EACZ,OACEQ,MAAC,QAAK,UAAW,CAAC,WAAYD,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAC9D,WAAK,IAAI,CAACf,EAAKiB,IACdD,MAAC,OAA4B,WAAUhB,EACpC,YAASA,EAAKU,CAAG,GADV,GAAGV,CAAG,IAAIiB,CAAK,EAEzB,CACD,EACH,CAEJ,CC7BO,SAASC,GAAkBC,EAAkB,GAAM,CACxD,KAAM,CAACxD,EAAMyD,CAAO,EAAI3B,WAAS,EAAK,EACtCC,mBAAU,IAAM,CAEd,GAAI,CAACyB,EAAQ,OACb,MAAME,EAASC,GAAqB,EACtBA,EAAE,SAAWA,EAAE,WACfA,EAAE,MAAQ,KAAOA,EAAE,MAAQ,MACrCA,EAAE,iBACFF,EAASG,GAAM,CAACA,CAAC,GACRD,EAAE,MAAQ,UACnBF,EAAQ,EAAK,CAEjB,EACA,cAAO,iBAAiB,UAAWC,CAAK,EACjC,IAAM,OAAO,oBAAoB,UAAWA,CAAK,CAC1D,EAAG,CAACF,CAAM,CAAC,EACJ,CAAE,KAAAxD,EAAM,QAAAyD,CAAA,CACjB,CAoBO,SAASI,GAAcC,EAAsC,CAClE,MAAMC,EAAkB,CACtB,CACE,GAAI,WACJ,MAAO,MACP,MAAOtB,EAAE,iBAAiB,EAC1B,KAAMA,EAAE,qBAAqB,EAC7B,KAAMY,MAACW,GAAA,CAAS,KAAM,GAAI,EAC1B,SAAU,CAAC,MAAO,GAAG,EACrB,IAAKF,EAAS,SAEhB,CACE,GAAI,UACJ,MAAO,MACP,MAAOrB,EAAE,gBAAgB,EACzB,KAAMA,EAAE,oBAAoB,EAC5B,KAAMY,MAACY,GAAA,CAAK,KAAM,GAAI,EACtB,SAAU,CAAC,MAAO,GAAG,EACrB,IAAKH,EAAS,OAChB,EAEF,OAAIA,EAAS,aACXC,EAAK,KAAK,CACR,GAAI,YACJ,MAAO,MACP,MAAOtB,EAAE,kBAAkB,EAC3B,KAAMA,EAAE,sBAAsB,EAC9B,KAAMY,MAACa,GAAA,CAAQ,KAAM,GAAI,EACzB,SAAU,CAAC,MAAO,GAAG,EACrB,IAAKJ,EAAS,SACf,EAEHC,EAAK,KAAK,CACR,GAAI,iBACJ,MAAO,MACP,MAAOtB,EAAE,uBAAuB,EAChC,KAAMY,MAACc,GAAA,CAAU,KAAM,GAAI,EAC3B,SAAU,CAAC,MAAO,GAAG,EACrB,IAAKL,EAAS,cACf,EACGA,EAAS,MACXC,EAAK,KAAK,CACR,GAAI,QACJ,MAAO,SACP,MAAOtB,EAAE,eAAe,EACxB,KAAMA,EAAE,mBAAmB,EAC3B,KAAMY,MAACe,GAAA,CAAW,KAAM,GAAI,EAC5B,SAAU,CAAC,KAAK,EAChB,IAAKN,EAAS,MACf,EAECA,EAAS,cACXC,EAAK,KAAK,CACR,GAAI,YACJ,MAAO,SACP,MAAOtB,EAAE,kBAAkB,EAC3B,KAAMA,EAAE,sBAAsB,EAC9B,KAAMY,MAACgB,GAAA,CAAc,KAAM,GAAI,EAC/B,IAAKP,EAAS,SACf,EACDC,EAAK,KAAK,CACR,GAAI,YACJ,MAAO,SACP,MAAOtB,EAAE,kBAAkB,EAC3B,KAAMA,EAAE,sBAAsB,EAC9B,KAAMY,MAACgB,GAAA,CAAc,KAAM,GAAI,EAC/B,IAAKP,EAAS,iBACf,EACDC,EAAK,KAAK,CACR,GAAI,YACJ,MAAO,SACP,MAAOtB,EAAE,kBAAkB,EAC3B,KAAMA,EAAE,sBAAsB,EAC9B,KAAMY,MAACiB,GAAA,CAAS,KAAM,GAAI,EAC1B,IAAKR,EAAS,eACf,EACDC,EAAK,KAAK,CACR,GAAI,aACJ,MAAO,SACP,MAAOtB,EAAE,mBAAmB,EAC5B,KAAMA,EAAE,uBAAuB,EAC/B,KAAMY,MAACkB,GAAA,CAAO,KAAM,GAAI,EACxB,IAAKT,EAAS,UACf,GAEHC,EAAK,KAAK,CACR,GAAI,iBACJ,MAAO,YACP,MAAOtB,EAAE,uBAAuB,EAChC,KAAMA,EAAE,2BAA2B,EACnC,KAAMY,MAACmB,GAAA,CAAW,KAAM,GAAI,EAC5B,IAAKV,EAAS,cACf,EACDC,EAAK,KAAK,CACR,GAAI,WACJ,MAAO,WACP,MAAOtB,EAAE,kBAAkB,EAC3B,KAAMA,EAAE,sBAAsB,EAC9B,KAAMY,MAACoB,GAAA,CAAS,KAAM,GAAI,EAC1B,IAAKX,EAAS,aACf,EACDC,EAAK,KAAK,CACR,GAAI,QACJ,MAAO,WACP,MAAOtB,EAAE,eAAe,EACxB,KAAMY,MAACqB,GAAA,CAAK,KAAM,GAAI,EACtB,IAAKZ,EAAS,MACf,EACMC,CACT,CAEA,MAAMY,GAA8B,CAAC,MAAO,SAAU,YAAa,UAAU,EAE7E,SAASC,GAAWC,EAAyB,CAC3C,OAAQA,EAAA,CACN,IAAK,MAAO,OAAOpC,EAAE,kBAAkB,EACvC,IAAK,SAAU,OAAOA,EAAE,qBAAqB,EAC7C,IAAK,YAAa,OAAOA,EAAE,wBAAwB,EACnD,IAAK,WAAY,OAAOA,EAAE,uBAAuB,EAErD,CAEO,SAASqC,GAAe,CAC7B,KAAA9E,EACA,QAAA+E,EACA,SAAAC,CACF,EAIG,CACDpD,EAAA,EACA,KAAM,CAACqD,EAAOC,CAAQ,EAAIpD,WAAS,EAAE,EAC/B,CAAC0B,EAAQ2B,CAAS,EAAIrD,WAAS,CAAC,EAChCsD,EAAWC,SAAyB,IAAI,EACxCC,EAAUD,SAAuB,IAAI,EAErCE,EAAWC,UAAQ,IAAM,CAC7B,MAAMC,EAAIR,EAAM,OAAO,cACvB,OAAKQ,EACET,EAAS,OAAQU,GACtB,CAACA,EAAE,MAAOA,EAAE,IAAI,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAAE,cAAc,SAASD,CAAC,GAFvDT,CAIjB,EAAG,CAACC,EAAOD,CAAQ,CAAC,EAEpBjD,YAAU,IAAM,CACV/B,IACFkF,EAAS,EAAE,EACXC,EAAU,CAAC,EACX,sBAAsB,IAAMC,EAAS,SAAS,OAAO,EAEzD,EAAG,CAACpF,CAAI,CAAC,EAET+B,YAAU,IAAM,CACdoD,EAAWQ,GAAM,KAAK,IAAIA,EAAG,KAAK,IAAI,EAAGJ,EAAS,OAAS,CAAC,CAAC,CAAC,CAChE,EAAG,CAACA,EAAS,MAAM,CAAC,EAEpBxD,YAAU,IAAM,CACHuD,EAAQ,SAAS,cAA2B,cAAc9B,CAAM,IAAI,GAC3E,eAAe,CAAE,MAAO,UAAW,CACzC,EAAG,CAACA,CAAM,CAAC,EAEX,MAAMoC,EAAUJ,UAAQ,IAAM,CAC5B,MAAMK,MAAc,IACpB,UAAWH,KAAKH,EAAU,CACxB,MAAMO,EAAMD,EAAQ,IAAIH,EAAE,KAAK,GAAK,GACpCI,EAAI,KAAKJ,CAAC,EACVG,EAAQ,IAAIH,EAAE,MAAOI,CAAG,CAC1B,CACA,OAAOnB,GACJ,IAAKE,IAAO,CAAE,MAAOA,EAAG,MAAOgB,EAAQ,IAAIhB,CAAC,GAAK,EAAC,EAAI,EACtD,OAAQ9H,GAAMA,EAAE,MAAM,OAAS,CAAC,CACrC,EAAG,CAACwI,CAAQ,CAAC,EAEb,GAAI,CAACvF,EAAM,OAAO,KAElB,MAAM+F,EAAOzH,GAAiB,CAC5BA,EAAI,MACJyG,EAAA,CACF,EAEA,OACE1B,MAAC,OAAI,UAAU,YAAY,YAAa0B,EACtC,SAAAiB,OAAC,OAAI,UAAU,OAAO,YAAcrC,GAAMA,EAAE,kBAC1C,UAAAqC,OAAC,OAAI,UAAU,YACb,UAAA3C,MAAC4C,GAAA,CAAO,KAAM,GAAI,EAClB5C,MAAC,SACC,IAAK+B,EACL,YAAa3C,EAAE,2BAA2B,EAC1C,MAAOwC,EACP,SAAWtB,GAAMuB,EAASvB,EAAE,OAAO,KAAK,EACxC,UAAYA,GAAM,CAChB,GAAIA,EAAE,MAAQ,YACZA,EAAE,iBACFwB,EAAWQ,GAAM,KAAK,IAAIA,EAAI,EAAGJ,EAAS,OAAS,CAAC,CAAC,UAC5C5B,EAAE,MAAQ,UACnBA,EAAE,iBACFwB,EAAWQ,GAAM,KAAK,IAAIA,EAAI,EAAG,CAAC,CAAC,UAC1BhC,EAAE,MAAQ,QAAS,CAC5BA,EAAE,iBACF,MAAMrF,EAAMiH,EAAS/B,CAAM,EACvBlF,KAASA,CAAG,CAClB,CACF,IAEF+E,MAAC,QAAK,UAAU,OACd,SAAAA,MAACF,GAAS,KAAM,CAAC,KAAK,EAAG,EAC3B,GACF,EACA6C,OAAC,OAAI,UAAU,YAAY,IAAKV,EAC7B,UAAAC,EAAS,SAAW,EACnBlC,MAAC,OAAI,UAAU,aAAc,SAAAZ,EAAE,eAAe,EAAE,EAC9C,KACHmD,EAAQ,IAAKM,GACZF,OAAC,OAAI,UAAU,aACb,UAAA3C,MAAC,OAAI,UAAU,UAAW,SAAAuB,GAAWsB,EAAQ,KAAK,EAAE,EACnDA,EAAQ,MAAM,IAAKR,GAAM,CACxB,MAAMS,EAAIZ,EAAS,QAAQG,CAAC,EAC5B,OACEM,OAAC,OAEC,WAAUG,EACV,UAAU,WACV,cAAaA,IAAM3C,EACnB,aAAc,IAAM2B,EAAUgB,CAAC,EAC/B,QAAS,IAAMJ,EAAIL,CAAC,EAEpB,UAAArC,MAAC,QAAK,UAAU,KAAM,SAAAqC,EAAE,KAAK,EAC7BrC,MAAC,QAAK,UAAU,IAAK,WAAE,MAAM,QAC5B,QAAK,UAAU,IAAK,SAAAuB,GAAWc,EAAE,KAAK,EAAE,EACxCA,EAAE,SACDrC,MAAC,QAAK,UAAU,KACd,SAAAA,MAACF,EAAA,CAAS,KAAMuC,EAAE,SAAU,EAC9B,EAEArC,MAAC,QAAK,UAAU,WAAW,IAfxBqC,EAAE,GAmBb,CAAC,IAzB8BQ,EAAQ,KA0BzC,CACD,GACH,EACAF,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,QACC,UAAA3C,MAACF,EAAA,CAAS,KAAM,CAAC,QAAQ,EAAG,EAC3BV,EAAE,kBAAkB,GACvB,SACC,QACC,UAAAY,MAACF,EAAA,CAAS,KAAM,CAAC,OAAO,EAAG,EAC1BV,EAAE,iBAAiB,GACtB,SACC,QACC,UAAAY,MAACF,EAAA,CAAS,KAAM,CAAC,KAAK,EAAG,EACxBV,EAAE,mBAAmB,GACxB,EACAuD,OAAC,QAAK,MAAO,CAAE,WAAY,OAAQ,MAAO,gBACvC,UAAAT,EAAS,OAAO,IAAE9C,EAAE,qBAAqB,GAC5C,GACF,GACF,EACF,CAEJ,CAEO,SAAS2D,GAAM,CAAE,QAAAC,GAAgE,CACtF,OAAKA,EACDA,EAAQ,KAERL,OAAC,OAAI,UAAU,mBACb,UAAA3C,MAAC,QAAK,UAAU,mBAAmB,gBAAI,EACtCgD,EAAQ,KACX,EAGGhD,MAAC,OAAI,UAAU,QAAS,WAAQ,IAAI,EATtB,IAUvB,CCrVA,MAAMiD,GAAyB,CAC7B,MAAO,CAAE,MAAO,UAAW,gBAAiB,eAC5C,OAAQ,CACN,CAAE,MAAO,CAAC,UAAW,SAAU,UAAW,OAAO,EAAG,MAAO,CAAE,MAAO,UAAW,UAAW,SAAS,EACnG,CAAE,MAAO,CAAC,aAAa,EAAG,MAAO,CAAE,MAAO,UAAU,EACpD,CAAE,MAAO,CAAC,WAAY,MAAO,UAAW,SAAU,WAAY,SAAU,SAAS,EAAG,MAAO,CAAE,MAAO,UAAU,EAC9G,CAAE,MAAO,CAAC,WAAY,YAAa,SAAU,OAAQ,UAAW,UAAU,EAAG,MAAO,CAAE,MAAO,UAAU,EACvG,CAAE,MAAO,CAAC,WAAY,SAAU,KAAK,EAAG,MAAO,CAAE,MAAO,UAAU,EAClE,CAAE,MAAO,CAAC,SAAU,aAAc,SAAS,EAAG,MAAO,CAAE,MAAO,UAAU,EACxE,CAAE,MAAO,CAAC,WAAY,aAAc,kBAAkB,EAAG,MAAO,CAAE,MAAO,UAAW,WAAY,MAAM,EACtG,CAAE,MAAO,CAAC,QAAS,YAAa,UAAU,EAAG,MAAO,CAAE,MAAO,UAAU,EACvE,CAAE,MAAO,CAAC,YAAa,MAAM,EAAG,MAAO,CAAE,WAAY,OAAO,EAC5D,CAAE,MAAO,CAAC,QAAQ,EAAG,MAAO,CAAE,UAAW,SAAS,CAAE,CAExD,EAEMC,GAA0B,CAC9B,MAAO,CAAE,MAAO,UAAW,gBAAiB,eAC5C,OAAQ,CACN,CAAE,MAAO,CAAC,UAAW,SAAU,UAAW,OAAO,EAAG,MAAO,CAAE,MAAO,UAAW,UAAW,SAAS,EACnG,CAAE,MAAO,CAAC,aAAa,EAAG,MAAO,CAAE,MAAO,UAAU,EACpD,CAAE,MAAO,CAAC,WAAY,MAAO,UAAW,SAAU,WAAY,SAAU,SAAS,EAAG,MAAO,CAAE,MAAO,UAAU,EAC9G,CAAE,MAAO,CAAC,WAAY,YAAa,SAAU,OAAQ,UAAW,UAAU,EAAG,MAAO,CAAE,MAAO,UAAU,EACvG,CAAE,MAAO,CAAC,WAAY,SAAU,KAAK,EAAG,MAAO,CAAE,MAAO,UAAU,EAClE,CAAE,MAAO,CAAC,SAAU,aAAc,SAAS,EAAG,MAAO,CAAE,MAAO,UAAU,EACxE,CAAE,MAAO,CAAC,WAAY,aAAc,kBAAkB,EAAG,MAAO,CAAE,MAAO,UAAW,WAAY,MAAM,EACtG,CAAE,MAAO,CAAC,QAAS,YAAa,UAAU,EAAG,MAAO,CAAE,MAAO,UAAU,EACvE,CAAE,MAAO,CAAC,YAAa,MAAM,EAAG,MAAO,CAAE,WAAY,OAAO,EAC5D,CAAE,MAAO,CAAC,QAAQ,EAAG,MAAO,CAAE,UAAW,SAAS,CAAE,CAExD,EAEA,SAASC,IAA4B,CACnC,KAAM,CAACC,EAAOC,CAAQ,EAAI5E,WAA2B,IACnD,SAAS,gBAAgB,QAAQ,QAAU,QAAU,QAAU,QAE3D6E,EAAUtB,SAAOoB,CAAK,EAC5B1E,mBAAU,IAAM,CACd,MAAM6E,EAAK,SAAS,gBACdvM,EAAK,IAAM,CACf,MAAMoI,EAAImE,EAAG,QAAQ,QAAU,QAAU,QAAU,OAC/CnE,IAAMkE,EAAQ,UAChBA,EAAQ,QAAUlE,EAClBiE,EAASjE,CAAC,EAEd,EACMoE,EAAK,IAAI,iBAAiBxM,CAAE,EAClC,OAAAwM,EAAG,QAAQD,EAAI,CAAE,WAAY,GAAM,gBAAiB,CAAC,YAAY,EAAG,EAC7D,IAAMC,EAAG,YAClB,EAAG,EAAE,EACEJ,IAAU,OAASH,GAAaC,EACzC,CAiDO,SAASO,GAAS,CACvB,KAAAtK,EACA,KAAA+E,EACA,UAAAwF,EAAY,EACZ,gBAAAC,EAAkB,EACpB,EAKG,CACD,MAAMP,EAAQD,GAAA,EACd,OACEnD,MAAC4D,GAAA,CAAU,MAAAR,EAAc,KAAMjK,EAAM,SAAU+E,EAC5C,UAAC,CAAE,UAAA6B,EAAW,OAAA8D,EAAQ,aAAAC,EAAc,cAAAC,CAAA,UAClC,OAAI,UAAW,YAAYhE,CAAS,GAClC,SAAA8D,EAAO,IAAI,CAAC1G,EAAM2F,IACjBH,OAAC,OAAa,GAAGmB,EAAa,CAAE,KAAA3G,CAAA,CAAM,EAAG,UAAU,gBAChD,UAAAwG,GACC3D,MAAC,QAAK,UAAU,oBAAqB,WAAI0D,EAAU,QAEpD,QAAK,UAAU,wBACb,SAAAvG,EAAK,IAAI,CAACnF,EAAOuH,UACf,QAAc,GAAGwE,EAAc,CAAE,MAAA/L,EAAO,GAA9BuH,CAAiC,CAC7C,EACH,IARQuD,CASV,CACD,EACH,EAEJ,CAEJ,CClHA,eAAekB,GACbC,EACAC,EACA/G,EACe,CACf,GAAI8G,GAAUA,EAAO,OAAQ,CAC3B,MAAMrI,GAAO,iBAAkB,CAAE,QAASqI,EAAQ,KAAMC,EAAK,KAAM/G,GAAQ,KAAM,EACjF,MACF,CACA,MAAMJ,GAASmH,CAAG,CACpB,CAGA,MAAMC,GAAmBC,gBAA4B,EAAE,EAC1CC,GAAoBF,GAAiB,SAElD,SAASG,GAAwBC,EAAaC,EAAgC,CAE5E,GADI,CAACA,GACD,kBAAkB,KAAKD,CAAG,GAAKA,EAAI,WAAW,GAAG,EAAG,OAAOA,EAC/D,MAAME,EAAMD,EAAG,SAAS,IAAI,EAAI,KAAO,IAEvC,MAAO,GADSA,EAAG,QAAQ,SAAU,EAAE,CACtB,GAAGC,CAAG,GAAGF,EAAI,QAAQ,WAAY,EAAE,CAAC,EACvD,CAEA,MAAMG,GACJ,iPAKIC,GAAe,IAAI,OACvB,mDAAmDD,EAAU,qDAC7D,GACF,EAEA,SAASE,GAAS,CAAE,KAAAhK,EAAM,KAAAuC,GAAyC,CACjEoB,EAAA,EACA,MAAMsG,EAAMC,aAAWX,EAAgB,EACjC,CAACY,EAAMC,CAAO,EAAIvG,WAAiC,IAAI,EACvDwG,EAAU9H,EAAO,GAAGvC,CAAI,IAAIuC,CAAI,GAAKvC,EACrCsK,EAAe,SAAY,CAC/B,GAAI,CACF,MAAMhB,EAAMI,GAAwB1J,EAAMiK,EAAI,GAAG,EAC3CM,EAAUhI,EAAO,OAAO,SAASA,EAAK,MAAM,GAAG,EAAE,CAAC,GAAKA,EAAM,EAAE,EAAI,OACzE,MAAM6G,GAAea,EAAI,OAAQX,EAAK,OAAO,SAASiB,CAAO,EAAIA,EAAU,MAAS,EACpFH,EAAQ,MAAM,EACd,WAAW,IAAMA,EAAQ,IAAI,EAAG,IAAI,CACtC,MAAQ,CACN,GAAI,CACF,MAAM,UAAU,UAAU,UAAUC,CAAO,EAC3CD,EAAQ,MAAM,EACd,WAAW,IAAMA,EAAQ,IAAI,EAAG,IAAI,CACtC,MAAQ,CAER,CACF,CACF,EACMI,EAAW,MAAO9E,GAAwB,CAC9CA,EAAE,kBACF,GAAI,CACF,MAAM,UAAU,UAAU,UAAU2E,CAAO,EAC3CD,EAAQ,MAAM,EACd,WAAW,IAAMA,EAAQ,IAAI,EAAG,IAAI,CACtC,MAAQ,CAER,CACF,EACA,OACErC,OAAC,QACC,UAAW,aAAaoC,EAAO,OAAS,EAAE,GAC1C,KAAK,SACL,SAAU,EACV,QAASG,EACT,cAAgB5E,GAAM,CACpBA,EAAE,iBACG8E,EAAS9E,CAAC,CACjB,EACA,UAAYA,GAAM,EACZA,EAAE,MAAQ,SAAWA,EAAE,MAAQ,OACjCA,EAAE,iBACG4E,EAAA,EAET,EACA,MAAO9F,EAAE,wBAAwB,EAEjC,UAAAY,MAACqF,GAAA,CAAS,KAAM,GAAI,UAAU,iBAAiB,EAC/CrF,MAAC,QAAK,UAAU,iBAAkB,SAAApF,EAAK,EACtCuC,GAAQwF,OAAC,QAAK,UAAU,iBAAiB,cAAExF,CAAA,EAAK,EAChD4H,GAAQ/E,MAACsF,GAAA,CAAM,KAAM,GAAI,UAAU,kBAAkB,IAG5D,CAEA,SAASC,GAAepM,EAAoC,CAC1DwL,GAAa,UAAY,EACzB,MAAMhL,EAAmB,GACzB,IAAI6L,EAAO,EACP1N,EAA4B6M,GAAa,KAAKxL,CAAI,EACtD,KAAOrB,IAAM,MAAM,CACjB,MAAM2N,EAAS3N,EAAE,CAAC,GAAK,GACjB8C,EAAO9C,EAAE,CAAC,EACVqF,EAAOrF,EAAE,CAAC,EACV4N,EAAY5N,EAAE,MAAQ2N,EAAO,OAC/BC,EAAYF,GAAM7L,EAAI,KAAKR,EAAK,MAAMqM,EAAME,CAAS,CAAC,EAC1D/L,EAAI,WAAMiL,GAAA,CAAiC,KAAAhK,EAAY,KAAAuC,GAA/B,MAAMuI,CAAS,EAA4B,CAAE,EACrEF,EAAOE,EAAY9K,EAAK,QAAUuC,EAAOA,EAAK,OAAS,EAAI,GAC3DrF,EAAI6M,GAAa,KAAKxL,CAAI,CAC5B,CACA,OAAIQ,EAAI,SAAW,EAAUR,GACzBqM,EAAOrM,EAAK,QAAQQ,EAAI,KAAKR,EAAK,MAAMqM,CAAI,CAAC,EAC1C7L,EACT,CAIA,SAASgM,GAAcC,EAAgC,CACrD,OAAOC,WAAS,IAAID,EAAWE,GAAU,CACvC,GAAI,OAAOA,GAAU,SAAU,OAAOP,GAAeO,CAAK,EAC1D,GAAIC,iBAAeD,CAAK,EAAG,CACzB,MAAME,EAAQF,EAAM,MACpB,GAAIE,EAAM,WAAa,OACrB,OAAOC,eAAaH,EAAO,OAAWH,GAAcK,EAAM,QAAQ,CAAC,CAEvE,CACA,OAAOF,CACT,CAAC,CACH,CAEO,MAAMI,GAAWC,OAAK,SAAkB,CAAE,OAAAC,GAA8B,CAC7E,OACEpG,MAAC,OAAI,UAAU,WACb,SAAAA,MAACqG,GAAA,CACC,cAAe,CAACC,GAAWC,GAAcC,EAAU,EACnD,cAAe,CAAC,CAACC,GAAa,CAAE,aAAc,GAAO,CAAC,EACtD,WAAY,CACV,IAAK,CAAC,CAAE,SAAAb,KAAe,CAErB,MAAMc,EAAUC,GAAiBf,CAAQ,EAAE,UAC3C,aAAQgB,GAAA,CAAU,KAAMC,GAAkBjB,CAAQ,EAAG,KAAMc,EAAS,CACtE,EACA,KAAM,CAAC,CAAE,UAAA3G,EAAW,SAAA6F,KAAe5F,MAAC,QAAK,UAAAD,EAAuB,SAAA6F,EAAS,EACzE,EAAG,CAAC,CAAE,KAAAkB,EAAM,SAAAlB,KAAe5F,MAAC+G,GAAA,CAAS,KAAAD,EAAa,SAAAlB,EAAS,EAC3D,EAAG,CAAC,CAAE,SAAAA,CAAA,IAAe5F,MAAC,KAAG,SAAA2F,GAAcC,CAAQ,EAAE,EACjD,GAAI,CAAC,CAAE,SAAAA,CAAA,IAAe5F,MAAC,MAAI,SAAA2F,GAAcC,CAAQ,EAAE,EACnD,GAAI,CAAC,CAAE,SAAAA,CAAA,IAAe5F,MAAC,MAAI,SAAA2F,GAAcC,CAAQ,EAAE,GAGpD,SAAAQ,CAAA,GAEL,CAEJ,CAAC,EAED,SAASW,GAAS,CAAE,KAAAD,EAAM,SAAAlB,GAAoD,CAC5ErH,EAAA,EACA,MAAMsG,EAAMC,aAAWX,EAAgB,EACjC,CAACY,EAAMC,CAAO,EAAIvG,WAAS,EAAK,EAChCuI,EAAa,CAAC,CAACF,GAAQ,gBAAgB,KAAKA,CAAI,EAChDG,EAAU,MAAO3G,GAAwB,CAE7C,GADAA,EAAE,iBACE,EAACwG,EACL,IAAIE,EAAY,CACd,GAAI,CACF,MAAMnK,GAAQiK,CAAI,CACpB,MAAQ,CACN,OAAO,KAAKA,EAAM,SAAU,qBAAqB,CACnD,CACA,MACF,CACA,GAAI,CACF,MAAMI,EAAWJ,EAAK,QAAQ,aAAc,EAAE,EACxC5C,EAAMI,GAAwB4C,EAAUrC,EAAI,GAAG,EACrD,MAAMb,GAAea,EAAI,OAAQX,CAAG,CACtC,MAAQ,CACN,GAAI,CACF,MAAM,UAAU,UAAU,UAAU4C,CAAI,EACxC9B,EAAQ,EAAI,EACZ,WAAW,IAAMA,EAAQ,EAAK,EAAG,IAAI,CACvC,MAAQ,CAER,CACF,EACF,EACA,OACErC,OAAC,KACC,KAAMmE,GAAQ,IACd,QAAAG,EACA,UAAW,WAAWD,EAAa,WAAa,OAAO,IAAIjC,EAAO,OAAS,EAAE,GAC7E,MACEiC,EACI5H,EAAE,6BAA8B,CAAE,KAAM0H,GAAQ,GAAI,EACpD1H,EAAE,0BAA2B,CAAE,KAAM0H,GAAQ,GAAI,EAGtD,UAAAlB,EACAoB,EACChH,MAACmH,GAAA,CAAa,KAAM,GAAI,UAAU,eAAe,EAC/CpC,QACDO,GAAA,CAAM,KAAM,GAAI,UAAU,eAAe,EACxC,OAGV,CAEO,SAASuB,GAAkBjB,EAA6B,CAC7D,UAAWwB,KAAOvB,WAAS,QAAQD,CAAQ,EACzC,GAAIG,iBAAeqB,CAAG,EAAG,CACvB,MAAMC,EAAOD,EAAI,MAAkC,UACnD,GAAI,OAAOC,GAAQ,SAAU,CAC3B,MAAMvP,EAAIuP,EAAI,MAAM,mBAAmB,EACvC,GAAIvP,EAAG,OAAOA,EAAE,CAAC,CACnB,CACF,CAEF,MAAO,MACT,CAEA,SAAS6O,GAAiBW,EAAyB,CACjD,OAAI,OAAOA,GAAS,UAAY,OAAOA,GAAS,SAAiB,OAAOA,CAAI,EACxE,MAAM,QAAQA,CAAI,EAAUA,EAAK,IAAIX,EAAgB,EAAE,KAAK,EAAE,EAC9DZ,iBAAeuB,CAAI,EACdX,GAAkBW,EAAK,MAAmC,QAAQ,EACpE,EACT,CAEA,SAASV,GAAU,CAAE,KAAA1I,EAAM,KAAA/E,GAAmD,CAC5EoF,EAAA,EACA,KAAM,CAACgJ,EAAQC,CAAS,EAAI/I,WAAS,EAAK,EACpCgJ,EAAS,SAAY,CACzB,GAAI,CACF,MAAM,UAAU,UAAU,UAAUtO,CAAI,EACxCqO,EAAU,EAAI,EACd,WAAW,IAAMA,EAAU,EAAK,EAAG,IAAI,CACzC,MAAQ,CAER,CACF,EACA,OACE7E,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,iBACb,UAAA3C,MAAC,QAAK,UAAU,iBAAkB,SAAA9B,EAAK,EACvCyE,OAAC,UAAO,KAAK,SAAS,UAAW,YAAY4E,EAAS,OAAS,EAAE,GAAI,QAASE,EAC3E,UAAAF,EAASvH,MAACsF,IAAM,KAAM,GAAI,EAAKtF,MAAC0H,GAAA,CAAK,KAAM,GAAI,EACtCtI,EAATmI,EAAW,kBAAuB,eAAN,CAAqB,EACpD,GACF,EACAvH,MAACyD,GAAA,CAAS,KAAAtK,EAAY,KAAA+E,CAAA,CAAY,GACpC,CAEJ,CC1QA,SAASyJ,EAAG,CAAE,KAAAC,EAAO,GAAI,SAAAhC,EAAU,GAAGiC,GAAmD,CACvF,OACE7H,MAAC,OACC,MAAM,6BACN,MAAO4H,EACP,OAAQA,EACR,QAAQ,YACR,KAAK,OACL,OAAO,eACP,YAAY,MACZ,cAAc,QACd,eAAe,QACd,GAAGC,EAEH,SAAAjC,CAAA,EAGP,CAEO,MAAMkC,EAAI,CACf,KAAO3I,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,mBAAmB,EAAE,EACjE,OAASb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,UAAO,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI,EAAEA,MAAC,QAAK,EAAE,iBAAiB,GAAE,EACjG,KAAOb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,4BAA4B,EAAE,EAC1E,KAAOb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,eAAe,EAAE,EAC7D,MAAQb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,eAAe,EAAE,EAC9D,MAAQb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,iBAAiB,EAAE,EAChE,EAAIb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,uBAAuB,EAAE,EAClE,SAAWb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,IAAI,EAAE,IAAI,MAAM,KAAK,OAAO,KAAK,GAAG,IAAI,EAAEA,MAAC,QAAK,EAAE,uBAAuB,GAAE,EAC3H,MAAQb,GACNwD,OAACgF,EAAA,CAAI,GAAGxI,EACN,UAAAa,MAAC,QAAK,EAAE,mFAAmF,EAC3FA,MAAC,QAAK,EAAE,gEAAgE,GAC1E,EAEF,KAAOb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,8CAA8C,EAAE,EAC5F,KAAOb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,mDAAmD,QAAG,UAAO,GAAG,IAAI,GAAG,KAAK,EAAE,IAAI,QAAG,UAAO,GAAG,KAAK,GAAG,IAAI,EAAE,IAAI,GAAE,EAC/J,MAAQb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,UAAO,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI,EAAEA,MAAC,QAAK,EAAE,uDAAuD,GAAE,EACtI,KAAOb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,8CAA8C,EAAEA,MAAC,QAAK,EAAE,8CAA8C,GAAE,EACpJ,OAASb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,2EAA2E,EAAE,EAC3H,IAAMb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,IAAI,EAAE,IAAI,MAAM,KAAK,OAAO,KAAK,GAAG,IAAI,EAAEA,MAAC,QAAK,EAAE,oCAAoC,GAAE,EACnI,QAAUb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,IAAI,EAAE,IAAI,MAAM,KAAK,OAAO,IAAI,GAAG,IAAI,EAAEA,MAAC,QAAK,EAAE,mDAAmD,GAAE,EACrJ,SAAWb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,uBAAuB,EAAE,EACzE,QAAUb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,iBAAiB,EAAEA,MAAC,QAAK,EAAE,qBAAqB,GAAE,EACjG,IAAMb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,6BAA6B,EAAE,EAC1E,SAAWb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,WAAQ,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAEA,MAAC,QAAK,EAAE,yEAAyE,GAAE,EACnK,IAAMb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,IAAI,EAAE,IAAI,MAAM,KAAK,OAAO,KAAK,GAAG,IAAI,EAAEA,MAAC,QAAK,EAAE,IAAI,EAAE,IAAI,MAAM,IAAI,OAAO,IAAI,EAAEA,MAAC,QAAK,EAAE,2DAA2D,GAAE,EACnM,KAAOb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,UAAO,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI,EAAEA,MAAC,QAAK,EAAE,kCAAkC,GAAE,EAChH,KAAOb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,6DAA6D,EAAEA,MAAC,QAAK,EAAE,YAAY,GAAE,EACjI,OAASb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,4EAA4E,EAAE,EAC5H,MAAQb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,IAAI,EAAE,IAAI,MAAM,KAAK,OAAO,KAAK,GAAG,IAAI,QAAG,UAAO,GAAG,IAAI,GAAG,KAAK,EAAE,IAAI,EAAEA,MAAC,QAAK,EAAE,wBAAwB,GAAE,EACxJ,UAAYb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,uEAAuE,EAAE,EAC1H,IAAMb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,IAAI,EAAE,IAAI,MAAM,IAAI,OAAO,KAAK,GAAG,IAAI,EAAEA,MAAC,QAAK,EAAE,sCAAsC,GAAE,EACpI,IAAMb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,UAAO,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI,EAAEA,MAAC,QAAK,EAAE,wFAAwF,GAAE,EACrK,KAAOb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,+CAA+C,EAAE,EAC7F,QAAUb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,IAAI,EAAE,IAAI,MAAM,KAAK,OAAO,KAAK,GAAG,IAAI,EAAEA,MAAC,QAAK,EAAE,UAAU,GAAE,EAC7G,QAAUb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,IAAI,EAAE,IAAI,MAAM,KAAK,OAAO,KAAK,GAAG,IAAI,EAAEA,MAAC,QAAK,EAAE,WAAW,GAAE,EAC9G,IAAMb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,6CAA6C,QAAG,UAAO,GAAG,KAAK,GAAG,KAAK,EAAE,MAAM,GAAE,EAC5H,KAAOb,SAAmBwI,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,IAAI,EAAE,IAAI,MAAM,KAAK,OAAO,KAAK,GAAG,IAAI,EAAE,EACtF,KAAOb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,gBAAgB,EAAE,EAC9D,KAAOb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,UAAO,GAAG,IAAI,GAAG,KAAK,EAAE,MAAM,KAAK,eAAe,EAAEA,MAAC,UAAO,GAAG,KAAK,GAAG,KAAK,EAAE,MAAM,KAAK,eAAe,EAAEA,MAAC,UAAO,GAAG,KAAK,GAAG,KAAK,EAAE,MAAM,KAAK,eAAe,GAAE,EACrM,IAAMb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,uCAAuC,EAAE,EACpF,OAASb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,4BAA4B,EAAEA,MAAC,QAAK,EAAE,WAAW,GAAE,EACjG,OAASb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,UAAO,GAAG,IAAI,GAAG,IAAI,EAAE,IAAI,QAAG,UAAO,GAAG,IAAI,GAAG,KAAK,EAAE,IAAI,QAAG,UAAO,GAAG,KAAK,GAAG,IAAI,EAAE,IAAI,EAAEA,MAAC,QAAK,EAAE,+BAA+B,GAAE,EAC3K,GAAKb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,UAAO,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI,EAAEA,MAAC,QAAK,EAAE,sCAAsC,GAAE,EAClH,MAAQb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,aAAa,EAAE,EAC5D,OAASb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,qBAAqB,EAAEA,MAAC,QAAK,EAAE,6BAA6B,GAAE,EAC5G,SAAWb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,gCAAgC,EAAE,EAClF,OAASb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,+BAA+B,EAAE,EAC/E,QAAUb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,uCAAuC,EAAE,EACxF,OAASb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,6CAA6C,EAAEA,MAAC,QAAK,EAAE,gBAAgB,GAAE,EACvH,KAAOb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,iBAAiB,EAAEA,MAAC,QAAK,EAAE,qBAAqB,GAAE,EAC9F,KAAOb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,UAAO,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI,EAAEA,MAAC,QAAK,EAAE,uDAAuD,GAAE,EACrI,QAAUb,GAAkBa,MAAC2H,EAAA,CAAI,GAAGxI,EAAG,SAAAa,MAAC,QAAK,EAAE,8EAA8E,EAAE,EAC/H,KAAOb,GAAkBwD,OAACgF,EAAA,CAAI,GAAGxI,EAAG,UAAAa,MAAC,QAAK,EAAE,IAAI,EAAE,IAAI,MAAM,KAAK,OAAO,KAAK,GAAG,IAAI,EAAEA,MAAC,QAAK,EAAE,2BAA2B,GAAE,CAC7H,EC9Ea+H,GAAQ,CACnB,KAAM,OACN,MAAO,OACT,EAIO,SAASC,GAAQC,EAAgC,CACtD,OAAOA,IAAUF,GAAM,MAAQE,IAAUF,GAAM,KACjD,CAEO,MAAMG,GAAc,CACzB,SAAU,WACV,UAAW,YACX,UAAW,YACX,SAAU,UACZ,EAIaC,GAAiD,CAC5D,KAAMD,GAAY,SAClB,MAAOA,GAAY,SACrB,EAEaE,GAA+C,CAC1D,SAAUL,GAAM,KAChB,UAAWA,GAAM,MACjB,UAAWA,GAAM,MACjB,SAAUA,GAAM,IAClB,EAEaM,GAAe,CAC1BH,GAAY,SACZA,GAAY,UACZA,GAAY,UACZA,GAAY,QACd,EAEO,SAASI,GAAaL,EAAqC,CAChE,OACEA,IAAUC,GAAY,UACtBD,IAAUC,GAAY,WACtBD,IAAUC,GAAY,WACtBD,IAAUC,GAAY,QAE1B,CAEO,SAASK,GAAcC,EAA0B,CACtD,OAAOJ,GAAkBI,CAAK,CAChC,CAEO,SAASC,GAAqBrF,EAA0B,CAC7D,OAAO+E,GAAoB/E,CAAK,CAClC,CAEO,MAAMsF,GAAa,CACxB,MAAO,QACP,OAAQ,SACR,MAAO,OACT,EAIO,SAASC,GAAYV,EAAoC,CAC9D,OAAOA,IAAUS,GAAW,OAAST,IAAUS,GAAW,QAAUT,IAAUS,GAAW,KAC3F,CAEO,MAAME,GAA6C,CACxD,MAAO,KACP,OAAQ,EACR,MAAO,KACT,EAEaC,GAAc,CACzB,KAAM,OACN,OAAQ,SACR,MAAO,OACT,EAIO,SAASC,GAAab,EAAqC,CAChE,OAAOA,IAAUY,GAAY,MAAQZ,IAAUY,GAAY,QAAUZ,IAAUY,GAAY,KAC7F,CAEO,MAAME,GAAgD,CAC3D,KAAM,iCACN,OAAQ,2DACR,MAAO,mCACT,EC1FMC,GAAgB,UAEf,SAASC,IAAoC,CAClD,GAAI,OAAO,OAAW,IAAa,OAAO,KAC1C,MAAM7N,EAAM,IAAI,gBAAgB,OAAO,SAAS,MAAM,EAAE,IAAI4N,EAAa,EACzE,GAAI,CAAC5N,EAAK,OAAO,KACjB,MAAM8N,EAAU9N,EAAI,OACpB,OAAO8N,EAAQ,OAAS,EAAIA,EAAU,IACxC,CAEO,SAASC,GAAkBC,EAA2B,CAC3D,GAAI,OAAO,OAAW,IAAa,OACnC,MAAMtM,EAAM,IAAI,IAAI,OAAO,SAAS,IAAI,EAItCA,EAAI,aAAa,OAAOkM,EAAa,EAEnClM,EAAI,OAAS,OAAO,SAAS,MACjC,OAAO,QAAQ,aAAa,KAAM,GAAIA,EAAI,IAAI,CAChD,CChBO,SAASuM,GAAWC,EAAoB,CAC7C,MAAM5P,EAAI4P,EAAK,IACf,OAAO5P,EAAI,GAAK,GAAGA,EAAE,QAAQ,CAAC,CAAC,IAAM,GAAG,KAAK,MAAMA,CAAC,CAAC,GACvD,CAEO,SAAS6P,GAAWpJ,EAAiBqJ,EAA0B,CACpE,KAAM,CAACF,EAAIG,CAAK,EAAIhL,WAAS,CAAC,EACxBiL,EAAQ1H,SAAsB,IAAI,EACxCtD,mBAAU,IAAM,CACd,GAAI,CAACyB,EAAQ,CACXsJ,EAAM,CAAC,EACPC,EAAM,QAAU,KAChB,MACF,CACAA,EAAM,QAAqB,YAAY,MACvC,MAAMC,EAAK,YAAY,IAAM,CACvBD,EAAM,UAAY,MAAMD,EAAM,YAAY,MAAQC,EAAM,OAAO,CACrE,EAAG,EAAE,EACL,MAAO,IAAM,cAAcC,CAAE,CAC/B,EAAG,CAACxJ,EAAQqJ,CAAO,CAAC,EACbF,CACT,CCJA,MAAMM,GAAsC,CAAC,MAAO,SAAU,OAAQ,KAAK,EAErEC,GAAyB,CAC7B,CAAE,EAAG,OAAQ,MAAO,gBAAiB,KAAM7J,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EAAI,KAAM,qBACvE,CAAE,EAAG,SAAU,MAAO,kBAAmB,KAAM9H,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EAAI,KAAM,uBAC7E,CAAE,EAAG,OAAQ,MAAO,gBAAiB,KAAM9H,MAAC8H,EAAE,IAAF,CAAM,KAAM,GAAI,EAAI,KAAM,qBACtE,CAAE,EAAG,OAAQ,MAAO,gBAAiB,KAAM9H,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EAAI,KAAM,oBACzE,EAEO,SAASgC,GAAW,CACzB,KAAAC,EACA,SAAAC,CACF,EAGG,CACD,OACEhK,MAAC,OAAI,UAAU,cAAc,YAAW+J,EACrC,SAAAF,GAAU,IAAK/R,GACd6K,OAAC,UAEC,KAAK,SACL,UAAU,SACV,UAASoH,IAASjS,EAAE,EACpB,SAAQA,EAAE,EACV,QAAS,IAAMkS,EAASlS,EAAE,CAAC,EAC3B,MAAOsH,EAAEtH,EAAE,IAAI,EAEd,UAAAA,EAAE,KACHkI,MAAC,QAAM,SAAAZ,EAAEtH,EAAE,KAAK,EAAE,IATbA,EAAE,EAWV,EACH,CAEJ,CAwBA,SAASmS,GAAUhP,EAAa,CAW9B,MAV2C,CACzC,SAAU+E,MAAC8H,EAAE,EAAF,CAAI,KAAM,GAAI,EACzB,OAAQ9H,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EAC1B,SAAU9H,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EAC5B,QAAS9H,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EAC7B,UAAW9H,MAAC8H,EAAE,SAAF,CAAW,KAAM,GAAI,EACjC,SAAU9H,MAAC8H,EAAE,IAAF,CAAM,KAAM,GAAI,EAC3B,SAAU9H,MAAC8H,EAAE,IAAF,CAAM,KAAM,GAAI,EAC3B,QAAS9H,MAAC8H,EAAE,MAAF,CAAQ,KAAM,GAAI,GAErB7M,CAAG,GAAK+E,MAAC8H,EAAE,MAAF,CAAQ,KAAM,GAAI,CACtC,CAGA,SAASoC,GAAgBtI,EAA8B,CACrD,MAAMuI,EAAavI,EAAM,QAAQ,MAAO,GAAG,EACrCwI,EAAgBD,EAAW,SAAS,GAAG,EACvCE,EAAYF,EAAW,YAAY,GAAG,EAC5C,GAAIE,EAAY,EAAG,OAAO,KAC1B,MAAMC,EAAaF,EAAgBD,EAAW,MAAM,EAAG,EAAE,EAAIA,EAAW,MAAM,EAAGE,CAAS,EAC1F,GAAI,CAACC,EAAY,OAAO,KACxB,MAAMC,EAAYD,EAAW,YAAY,GAAG,EAC5C,OAAOC,GAAa,EAAI,GAAGD,EAAW,MAAM,EAAGC,CAAS,CAAC,IAAM,EACjE,CAEA,SAASC,GAAOjL,EAAwB,CACtC,OAAIA,IAAM,OAAeS,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EACvCvI,IAAM,MAAcS,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EACxCvI,IAAM,MAAcS,MAAC8H,EAAE,MAAF,CAAQ,KAAM,GAAI,EACvCvI,IAAM,QAAgBS,MAAC8H,EAAE,IAAF,CAAM,KAAM,GAAI,EACvCvI,IAAM,OAAeS,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EACtC9H,MAAC8H,EAAE,GAAF,CAAK,KAAM,GAAI,CACzB,CAEO,SAAS2C,GAAS,CACvB,MAAAC,EACA,SAAAC,EACA,OAAAC,EACA,QAAAC,EACA,SAAAC,EACA,KAAAC,EACA,UAAAC,EACA,cAAAC,EACA,WAAAC,EACA,gBAAAC,EACA,cAAAC,EACA,eAAAC,EACA,SAAAC,EACA,iBAAAC,EACA,YAAAC,EACA,cAAAC,EACA,eAAAC,EACA,iBAAAC,EACA,gBAAAC,EACA,eAAAC,EACA,aAAAC,EACA,YAAAC,EACA,iBAAAC,EACA,cAAAC,CACF,EA4BG,CACD,KAAM,CAACC,GAAOC,CAAQ,EAAI1N,WAAiB,EAAE,EACvC,CAAC2N,EAAOC,CAAQ,EAAI5N,WAAgB,IAAI,EACxC,CAAC6N,GAAWC,EAAY,EAAI9N,WAAS,CAAC,EACtC,CAAC+N,GAAeC,CAAgB,EAAIhO,WAAS,EAAK,EAClDiO,GAAW1K,SAAO,CAAC,EACnB2K,GAAe3K,SAAuB,IAAI,EAE1C4K,EAAe5K,SAAO,EAAK,EAC3B6K,EAAwB7K,SAAO,CAAC,EAGhC8K,EAAe9K,SAAO0I,CAAK,EACjChM,YAAU,IAAM,CACd,MAAMqO,EAAOD,EAAa,QAC1BA,EAAa,QAAUpC,EACnBA,IAAU,KAAOqC,IAAS,KAC5BV,EAAS,CAAE,KAAM,QAAS,MAAO,GAAI,CAEzC,EAAG,CAAC3B,CAAK,CAAC,EAEVhM,YAAU,IAAM,CACd,GAAI,CAAC8N,GAAe,OACpB,MAAMQ,EAAU1M,GAAkB,CAE9BqM,GAAa,SACb,CAACA,GAAa,QAAQ,SAASrM,EAAE,MAAc,GAE/CmM,EAAiB,EAAK,CAE1B,EACA,cAAO,iBAAiB,YAAaO,CAAM,EACpC,IAAM,OAAO,oBAAoB,YAAaA,CAAM,CAC7D,EAAG,CAACR,EAAa,CAAC,EAElB,MAAMS,GAAa,MAAOC,GAAqB,CAC7C,GAAI,CACF,MAAMC,EAAS,MAAMC,GAAe,CAClC,SAAU,GACV,UAAW,GACX,YAAatB,EACb,QACEoB,IAAW,QACP,CACE,CACE,KAAM9N,EAAE,0BAA0B,EAClC,WAAY,CAAC,MAAO,MAAO,OAAQ,MAAO,OAAQ,KAAK,EACzD,EAEF,OACP,EACD,GAAI,OAAO+N,GAAW,UAAY,CAACA,EAAQ,OAC3C,MAAM5I,EACJuH,GAAgBqB,EAAO,WAAWrB,CAAY,EAC1CqB,EAAO,MAAMrB,EAAa,MAAM,EAAE,QAAQ,UAAW,EAAE,EACvDqB,EACNxC,EAASD,EAAQ,GAAGA,EAAM,QAAQ,OAAQ,EAAE,CAAC,KAAKnG,CAAG,IAAM,IAAIA,CAAG,GAAG,EACrE4H,EAAU9J,IAAM,CAAC,GAAGA,GAAG,CAAE,KAAM,KAAM,MAAOkC,CAAA,CAAK,CAAC,EAClDqH,IAAkBrH,CAAG,EACrBiH,EAAY,SAAS,OACvB,OAASlT,EAAK,CACZ,QAAQ,MAAM,gBAAiBA,CAAG,CACpC,CACF,EAEM+U,GAAalL,UAAQ,IAAM,CAC/B,GAAI,CAACiK,GAASA,EAAM,OAAS,cAAgB,GAC7C,MAAMhK,EAAIgK,EAAM,MAAM,cACtB,OAAKhK,EACEqJ,EAAc,OAAQpJ,GAAMA,EAAE,IAAI,cAAc,SAASD,CAAC,CAAC,EADnDqJ,CAEjB,EAAG,CAACW,EAAOX,CAAa,CAAC,EAEnB6B,GAAUnL,UAAuB,IAAM,CAC3C,GAAI,CAACiK,GAASA,EAAM,OAAS,WAAa,GAC1C,GAAI,CAACP,GAAkBA,EAAe,QAAUO,EAAM,YAAc,GACpE,MAAMmB,EAAsB1B,EAAe,QAAQ,IAAKjR,IAAU,CAChE,KAAMA,EACN,KAAMA,EAAK,SAAS,GAAG,GAAKA,EAAK,SAAS,IAAI,EAAI,MAAQ,OAC1D,KAAMA,CAAA,EACN,EAEI4S,EAAStD,GAAgBkC,EAAM,KAAK,EAC1C,OAAIoB,IAAW,MACbD,EAAK,QAAQ,CACX,KAAM,KACN,KAAM,MACN,KAAMC,EAAS,KAAKA,CAAM,GAAK,KAAKpO,EAAE,wBAAwB,CAAC,GAChE,EAEImO,CACT,EAAG,CAACnB,EAAOP,CAAc,CAAC,EAEpB9R,EACJqS,GAAO,OAAS,QAAUiB,GAAajB,GAAO,OAAS,KAAOkB,GAAU,GAE1E5O,YAAU,IAAM,CACd6N,GAAa,CAAC,CAChB,EAAG,CAACxS,EAAM,OAAQqS,GAAO,IAAI,CAAC,EAE9B1N,YAAU,IAAM,CACV,CAAC0N,GAASA,EAAM,OAAS,MAAQ,CAACV,GACtCA,EAAeU,EAAM,MAAOA,EAAM,KAAK,CACzC,EAAG,CAACA,EAAOV,CAAc,CAAC,EAE1B,MAAM+B,EAAgBnN,GAAwC,CAC5D,MAAMC,EAAID,EAAE,OAAO,MACnBqK,EAASpK,CAAC,EACV,MAAMmN,EAAQnN,EAAE,MAAM,uBAAuB,EAC7C,GAAImN,EAAO,CACT,MAAMC,GAAQD,EAAM,CAAC,EACf9L,EAAQ8L,EAAM,CAAC,GAAK,GAC1B,GAAIC,KAAU,IACZtB,EAAS,CAAE,KAAM,QAAS,MAAAzK,CAAA,CAAO,MAC5B,CACL,MAAMgM,GAAQ,EAAElB,GAAS,QACzBL,EAAS,CAAE,KAAM,KAAM,MAAAzK,EAAO,MAAAgM,GAAO,CACvC,CACF,MAAWxB,GACTC,EAAS,IAAI,CAEjB,EAEMwB,EAAU,IAAMxB,EAAS,IAAI,EAE7ByB,EAAYlP,GAAgB,CAChC,MAAMmP,EAAKhU,EAAM6E,CAAG,EACpB,GAAI,GAACmP,GAAM,CAAC3B,GACZ,IAAIA,EAAM,OAAS,QAAS,CAC1B,MAAMnR,EAAO8S,EAAgB,IAE7B,GADoBA,EAAgB,aAAe,GACnC,CACd,MAAMC,EAAOtD,EAAM,QAAQ,cAAe,EAAE,EAAE,UAC9CC,EAASqD,EAAO,GAAGA,CAAI,IAAI/S,CAAG,IAAM,GAAGA,CAAG,GAAG,EAC7CkR,EAAU9J,IAAM,CAAC,GAAGA,GAAG,CAAE,KAAM,QAAS,MAAOpH,EAAI,QAAQ,MAAO,EAAE,EAAG,CAAC,CAC1E,KAAO,CACL,MAAM+S,EAAOtD,EAAM,QAAQ,cAAe,EAAE,EAAE,UAC9CC,EAASqD,CAAI,EACb7B,EAAU9J,IAAM,CAAC,GAAGA,GAAG,CAAE,KAAM,QAAS,MAAOpH,EAAI,QAAQ,MAAO,EAAE,EAAG,CAAC,EACvE8S,EAAgB,KACnB,CACF,KAAO,CACL,MAAME,EAAUF,EAChB,GAAIE,EAAQ,OAAS,KAAM,CACzB,MAAMT,EAAStD,GAAgBkC,EAAM,KAAK,GAAK,GACzC4B,GAAOtD,EAAM,QAAQ,aAAc,IAAI8C,CAAM,EAAE,EACrD7C,EAASqD,EAAI,EACb,MAAMJ,GAAQ,EAAElB,GAAS,QACzBL,EAAS,CAAE,KAAM,KAAM,MAAOmB,EAAQ,MAAAI,GAAO,EAC7CpC,EAAY,SAAS,QACrB,MACF,CACA,MAAMwC,GAAOtD,EAAM,QAAQ,cAAe,EAAE,EAAE,UAC9CC,EAASqD,GAAO,GAAGA,EAAI,KAAKC,EAAQ,IAAI,IAAM,IAAIA,EAAQ,IAAI,GAAG,EACjE9B,EAAU9J,GAAM,CAAC,GAAGA,EAAG,CAAE,KAAM,KAAM,MAAO4L,EAAQ,KAAM,CAAC,EAC3DrC,IAAkBqC,EAAQ,IAAI,CAChC,CACA5B,EAAS,IAAI,EACbb,EAAY,SAAS,QACvB,EAEM0C,GAAiB5N,GAA0C,CAC/D,GAAI8L,EAAO,CACT,GAAI9L,EAAE,MAAQ,YAAa,CACzBA,EAAE,iBACFiM,GAAczJ,GAAO/I,EAAM,QAAU+I,EAAI,GAAK/I,EAAM,OAAS,CAAE,EAC/D,MACF,CACA,GAAIuG,EAAE,MAAQ,UAAW,CACvBA,EAAE,iBACFiM,GAAczJ,GACZ/I,EAAM,QAAU+I,EAAI,EAAI/I,EAAM,QAAUA,EAAM,OAAS,GAEzD,MACF,CACA,GAAIuG,EAAE,MAAQ,SAAU,CACtBA,EAAE,iBACFuN,EAAA,EACA,MACF,CACA,GAAIvN,EAAE,MAAQ,OAAS8L,EAAM,OAAS,MAAQrS,EAAM,OAAS,EAAG,CAK9D,MAAMgU,EAAKhU,EAAMuS,EAAS,EAC1B,GAAIyB,GAAOA,EAAmB,OAAS,MAAO,CAC5CzN,EAAE,iBACF,MAAM2N,EAAUF,EAChB,GAAIE,EAAQ,OAAS,KAAM,CACzB,MAAMT,GAAStD,GAAgBkC,EAAM,KAAK,GAAK,GACzC4B,GAAOtD,EAAM,QAAQ,aAAc,IAAI8C,EAAM,EAAE,EACrD7C,EAASqD,EAAI,EACb,MAAMJ,GAAQ,EAAElB,GAAS,QACzBL,EAAS,CAAE,KAAM,KAAM,MAAOmB,GAAQ,MAAAI,GAAO,EAC7C,MACF,CACA,MAAMO,GAAUF,EAAQ,KAAK,QAAQ,OAAQ,EAAE,EACzCD,EAAOtD,EAAM,QAAQ,aAAc,IAAIyD,EAAO,GAAG,EACvDxD,EAASqD,CAAI,EACb,MAAMJ,GAAQ,EAAElB,GAAS,QACzBL,EAAS,CAAE,KAAM,KAAM,MAAO,GAAG8B,EAAO,IAAK,MAAAP,GAAO,EACpD,MACF,CACF,CACA,GAAItN,EAAE,MAAQ,QAAS,CACrB,GAAIvG,EAAM,OAAS,EAAG,CACpBuG,EAAE,iBACFwN,EAASxB,EAAS,EAClB,MACF,CACAuB,EAAA,CACF,CACF,CACA,GAAI,EAAAjB,EAAa,SAAW,KAAK,MAAQC,EAAsB,QAAU,KACrEvM,EAAE,MAAQ,SAAW,CAACA,EAAE,UAAY,CAAC8L,EAEvC,GADA9L,EAAE,iBACEyK,EAAM,CACR,MAAM5R,EAAOuR,EAAM,OACfvR,GAAQ6S,IACVA,EAAiB7S,CAAI,EACrBgT,EAAS,EAAE,EAEf,KAAW,CAACrB,GAAYJ,EAAM,SAC5BE,EAAA,EACAuB,EAAS,EAAE,EAGjB,EAEA,aACG,OAAI,UAAU,gBACb,SAAAxJ,OAAC,OAAI,UAAU,iBACZ,UAAAoJ,GAAeA,EAAY,OAAS,EACnCpJ,OAAC,OAAI,UAAU,kBACb,UAAA3C,MAAC,QAAK,UAAU,wBACb,SAAAZ,EAAE,sBAAuB,CAAE,MAAO2M,EAAY,OAAQ,EACzD,EACCA,EAAY,IAAI,CAAC5S,EAAM2J,WACrB,QAAa,UAAU,sBAAsB,MAAO3J,EACnD,UAAA6G,MAAC,QAAK,UAAU,OAAQ,SAAA7G,EAAK,EAC5B8S,EACCjM,MAAC,QAAK,UAAU,IAAI,QAAS,IAAMiM,EAAcnJ,CAAC,EAChD,eAACgF,EAAE,EAAF,CAAI,KAAM,GAAI,EACjB,EACE,OANKhF,CAOX,CACD,GACH,EACE,WAEH,OAAI,UAAU,WACZ,SAAAiI,GAAQC,EACPrI,OAAAyL,WAAA,CACE,UAAAzL,OAAC,QAAK,UAAU,uBACd,UAAA3C,MAAC,QAAK,UAAU,oBAAoB,EACpCA,MAAC,QAAK,UAAU,sBAAuB,SAAAgL,EAAU,QAChD,QAAK,UAAU,qBACb,SAAA3B,GAAW4B,GAAiB,CAAC,EAChC,GACF,EACAjL,MAAC,QAAK,UAAU,OAAO,EACvBA,MAAC8J,GAAA,CAAW,KAAMwB,EAAU,SAAUC,EAAkB,EACxDvL,MAAC,QAAK,UAAU,WAAW,SAC1B,QACC,UAAAA,MAACF,EAAA,CAAS,KAAM,CAAC,OAAO,EAAG,EAAE,IAAEV,EAAE,gBAAgB,EAAE,OAAe,IAClEY,MAACF,EAAA,CAAS,KAAM,CAAC,KAAK,EAAG,EAAE,IAAEV,EAAE,oBAAoB,GACrD,GACF,EAEAuD,OAAAyL,WAAA,CACE,UAAAzL,OAAC,QACC,UAAA3C,MAACF,EAAA,CAAS,KAAM,CAAC,GAAG,EAAG,EAAE,IAAEV,EAAE,mBAAmB,EAAE,OAAe,IACjEY,MAACF,EAAA,CAAS,KAAM,CAAC,GAAG,EAAG,EAAE,IAAEV,EAAE,uBAAuB,EAAE,aACvCU,EAAA,CAAS,KAAM,CAAC,MAAO,GAAG,EAAG,EAAE,IAAEV,EAAE,yBAAyB,GAC7E,EACAY,MAAC,QAAK,UAAU,OAAO,EACvBA,MAAC8J,GAAA,CAAW,KAAMwB,EAAU,SAAUC,EAAkB,EACxDvL,MAAC,QAAK,UAAU,WAAW,SAC1B,QACC,UAAAA,MAACF,EAAA,CAAS,KAAM,CAAC,OAAO,EAAG,EAAE,IAAEV,EAAE,eAAe,EAAE,KAAQ,UACzDU,EAAA,CAAS,KAAM,CAAC,QAAS,OAAO,EAAG,EAAE,IAAEV,EAAE,kBAAkB,GAC9D,GACF,EAEJ,EAEAuD,OAAC,OAAI,UAAU,WACZ,UAAAuJ,GAAM,OAAS,EACdlM,MAAC,OAAI,UAAU,gBACZ,SAAAkM,GAAM,IAAI,CAAC7J,EAAGS,IACbH,OAAC,QAAa,UAAW,QAAQN,EAAE,IAAI,GACpC,UAAAA,EAAE,OAAS,QACVrC,MAAC8H,EAAE,MAAF,CAAQ,KAAM,GAAI,EAEnB9H,MAAC8H,EAAE,GAAF,CAAK,KAAM,GAAI,EAElB9H,MAAC,QAAM,SAAAqC,EAAE,MAAM,EACfrC,MAAC,QACC,UAAU,IACV,QAAS,IACPmM,EAAUkC,GAAOA,EAAG,OAAO,CAAC/O,GAAGgP,IAAMA,IAAMxL,CAAC,CAAC,EAG/C,SAAA9C,MAAC8H,EAAE,EAAF,CAAI,KAAM,GAAI,GACjB,GAdShF,CAeX,CACD,EACH,EACE,KAEJ9C,MAAC,YACC,IAAKwL,EACL,MAAOd,EACP,YAAatL,EAAE,sBAAsB,EACrC,SAAUqO,EACV,UAAWS,GACX,mBAAoB,IAAM,CACxBtB,EAAa,QAAU,EACzB,EACA,iBAAkB,IAAM,CACtBA,EAAa,QAAU,GACvBC,EAAsB,QAAU,KAAK,KACvC,EACA,KAAM,EACN,SAAA/B,CAAA,GAGFnI,OAAC,OAAI,UAAU,gBACb,UAAA3C,MAAC,UACC,KAAK,SACL,UAAU,SACV,MAAOZ,EAAE,qBAAqB,EAC9B,QAAS,IAAM,KAAK6N,GAAA,EAEpB,SAAAjN,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,UAAF,CAAY,KAAM,GAAI,EACzB,IAEF9H,MAAC,UACC,KAAK,SACL,UAAU,SACV,MAAOZ,EAAE,sBAAsB,EAC/B,QAAS,IAAM,KAAK6N,GAAW,OAAO,EAEtC,SAAAjN,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,MAAF,CAAQ,KAAM,GAAI,EACrB,IAEFnF,OAAC,UACC,KAAK,SACL,UAAU,SACV,QAAS,IAAM0J,EAAS,CAAE,KAAM,QAAS,MAAO,GAAI,EAEpD,UAAArM,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,MAAF,CAAQ,KAAM,GAAI,EACrB,QACC,QAAK,UAAU,QAAS,SAAA1I,EAAE,wBAAwB,EAAE,KAEvDuD,OAAC,UACC,KAAK,SACL,UAAU,SACV,QAAS,IAAM,CACb,MAAMiL,EAAQ,EAAElB,GAAS,QACzBL,EAAS,CAAE,KAAM,KAAM,MAAO,GAAI,MAAAuB,EAAO,CAC3C,EAEA,UAAA5N,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,GAAF,CAAK,KAAM,GAAI,EAClB,QACC,QAAK,UAAU,QAAS,SAAA1I,EAAE,uBAAuB,EAAE,KAGtDY,MAAC,QAAK,UAAU,OAAO,EAEvB2C,OAAC,OAAI,IAAKgK,GAAc,MAAO,CAAE,SAAU,YACzC,UAAAhK,OAAC,UACC,KAAK,SACL,UAAU,aACV,QAAS,IAAM8J,EAAkBlM,GAAM,CAACA,CAAC,EACzC,MAAOnB,EAAE,sBAAsB,EAE/B,UAAAY,MAAC8H,EAAE,MAAF,CAAQ,KAAM,GAAI,EACnB9H,MAAC,QAAM,SAAAkL,CAAA,CAAW,EAClBlL,MAAC,QAAK,UAAU,QAAS,SAAAmL,EAAgB,EACzCnL,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,KAEnB0E,GACCxM,MAACuO,GAAA,CACC,WAAArD,EACA,cAAeC,EACf,YAAcrT,GAAM,CAClBsT,EAActT,CAAC,EACf2U,EAAiB,EAAK,CACxB,EACA,aAAenM,GAAM,CACnB+K,EAAe/K,CAAC,EAChBmM,EAAiB,EAAK,CACxB,IAEA,MACN,EACC1B,EACC/K,MAAC,UACC,KAAK,SACL,UAAU,WACV,MAAO,CAAE,WAAY,iBACrB,QAAS6K,EACT,MAAOzL,EAAE,oBAAoB,EAE7B,SAAAY,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,IAGpB9H,MAAC,UACC,KAAK,SACL,UAAU,WACV,SAAU8K,GAAY,CAACJ,EAAM,OAC7B,QAAS,IAAM,CACT,CAACI,GAAYJ,EAAM,SACrBE,EAAA,EACAuB,EAAS,EAAE,EAEf,EAEA,SAAAnM,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,GACpB,EAEJ,EAECsE,EACCpM,MAACwO,GAAA,CACC,KAAMpC,EAAM,KACZ,MAAArS,EACA,UAAAuS,GACA,OAASxJ,GAAMgL,EAAShL,CAAC,EACzB,QAAS+K,EACT,QAAS,CAAC/K,EAAG2L,IAAS,CAEpB,GADAlC,GAAazJ,CAAC,EACVsJ,EAAM,OAAS,MAAQT,EAAkB,CAC3C,MAAM/Q,EAAQ6T,EAAqB,KACnC9C,EAAiB/Q,EAAMwR,EAAM,KAAK,CACpC,CACF,IAEA,MACN,GACF,EACF,CAEJ,CAEA,SAASoC,GAAM,CACb,KAAAE,EACA,MAAA3U,EACA,UAAAuS,EACA,OAAAqC,EACA,QAAAjN,EACA,QAAAkN,CACF,EAOG,CACD,MAAM3M,EAAUD,SAAuB,IAAI,EAE3CtD,mBAAU,IAAM,CACd,sBAAsB,IAAM,CACfuD,EAAQ,SAAS,cAA2B,sBAAsB,GACzE,eAAe,CAAE,MAAO,UAAW,CACzC,CAAC,CACH,EAAG,CAACqK,CAAS,CAAC,EAGZ3J,OAAC,OAAI,UAAU,QAAQ,YAAcrC,GAAMA,EAAE,iBAC3C,UAAAqC,OAAC,OAAI,UAAU,KACb,UAAA3C,MAAC,QAAK,UAAU,MAAO,SAAA0O,IAAS,QAAU,IAAM,IAAI,EACpD1O,MAAC,QACE,SACGZ,EADHsP,IAAS,QACJ,uBACA,mBADsB,CACH,CAC3B,EACA1O,MAAC,QAAK,UAAU,OAAO,EACvBA,MAAC,QAAK,MAAO,CAAE,OAAQ,WAAa,QAAS0B,EAC3C,eAACoG,EAAE,EAAF,CAAI,KAAM,GAAI,EACjB,GACF,EACAnF,OAAC,OAAI,UAAU,aAAa,IAAKV,EAC9B,UAAAlI,EAAM,SAAW,EAChBiG,MAAC,OACC,MAAO,CACL,QAAS,WACT,SAAU,KACV,MAAO,iBACP,WAAY,yBAGb,WAAE,oBAAoB,IAEvB,KACHjG,EAAM,IAAI,CAACgU,EAAIjL,IACdH,OAAC,OAEC,UAAU,aACV,cAAaG,IAAMwJ,EACnB,QAAS,IAAMqC,EAAO7L,CAAC,EACvB,aAAc,IAAM8L,EAAQ9L,EAAGiL,CAAE,EAEjC,UAAA/N,MAAC,QAAK,UAAU,MACb,SAAA0O,IAAS,QACNzE,GAAW8D,EAAgB,GAAG,EAC9BvD,GAAQuD,EAAmB,IAAI,EACrC,QACC,OAAI,UAAU,KACZ,SAAAW,IAAS,QACR/L,OAAAyL,WAAA,CACE,UAAApO,MAAC,QAAK,UAAU,MAAQ,SAAA+N,EAAgB,IAAI,EAC5C/N,MAAC,QAAK,UAAU,OAAS,WAAgB,KAAK,GAChD,EAEA2C,OAAAyL,WAAA,CACE,UAAApO,MAAC,QAAO,WAAmB,KAAK,EAC9B+N,EAAmB,KACnB/N,MAAC,OAAI,UAAU,OAAS,SAAA+N,EAAmB,KAAK,EAC9C,MACN,EAEJ,EACA/N,MAAC,QAAK,UAAU,KACb,aAAS,QAAY+N,EAAgB,IAAM,GAAM,GACpD,IA5BKjL,CAAA,CA8BR,GACH,EACAH,OAAC,OAAI,UAAU,aACb,UAAAA,OAAC,QACC,UAAA3C,MAACF,EAAA,CAAS,KAAM,CAAC,QAAQ,EAAG,EAAE,IAAEV,EAAE,iBAAiB,GACrD,SACC,QACC,UAAAY,MAACF,EAAA,CAAS,KAAM,CAAC,OAAO,EAAG,EAAE,IAAEV,EAAE,kBAAkB,GACrD,SACC,QACC,UAAAY,MAACF,EAAA,CAAS,KAAM,CAAC,KAAK,EAAG,EAAE,IAAEV,EAAE,gBAAgB,GACjD,GACF,GACF,CAEJ,CAEA,MAAMyP,GAAkC,CAAC,oBAAqB,iBAAiB,EAE/E,SAASN,GAAgB,CACvB,WAAArD,EACA,cAAA4D,EACA,YAAAC,EACA,aAAAC,CACF,EAKG,CACD,KAAM,CAACtE,EAAOC,CAAQ,EAAIlM,WAASyM,CAAU,EAC7C,OACEvI,OAAC,OACC,UAAU,QACV,MAAO,CACL,OAAQ,mBACR,KAAM,OACN,MAAO,EACP,MAAO,IACP,SAAU,YAGZ,UAAAA,OAAC,OAAI,UAAU,KACb,UAAA3C,MAAC,QAAK,UAAU,MAAM,aAAC,EACvBA,MAAC,QAAM,SAAAZ,EAAE,sBAAsB,EAAE,GACnC,EACAuD,OAAC,OAAI,UAAU,aACZ,UAAAkM,GAAa,IAAK/W,GACjB6K,OAAC,OAEC,UAAU,aACV,cAAa7K,IAAMoT,EACnB,QAAS,IAAM6D,EAAYjX,CAAC,EAE5B,UAAAkI,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,MAAF,CAAQ,KAAM,GAAI,EACrB,EACA9H,MAAC,OAAI,UAAU,KACb,eAAC,QAAK,UAAU,MAAO,SAAAlI,CAAA,CAAE,EAC3B,IAVKA,CAAA,CAYR,EACD6K,OAAC,OAAI,MAAO,CAAE,QAAS,UAAW,QAAS,OAAQ,IAAK,GACtD,UAAA3C,MAAC,SACC,UAAU,aACV,MAAO,CAAE,KAAM,GACf,MAAO0K,EACP,SAAWpK,GAAMqK,EAASrK,EAAE,OAAO,KAAK,EACxC,YAAY,oBAEdN,MAAC,UACC,KAAK,SACL,UAAU,MACV,SAAU,CAAC0K,EAAM,QAAUA,EAAM,SAAWQ,EAC5C,QAAS,IAAM6D,EAAYrE,EAAM,MAAM,EAEtC,WAAE,kBAAkB,GACvB,EACF,GACF,EACA/H,OAAC,OAAI,UAAU,KAAK,MAAO,CAAE,UAAW,GACtC,UAAA3C,MAAC,QAAK,UAAU,MAAM,aAAC,EACvBA,MAAC,QAAM,SAAAZ,EAAE,uBAAuB,EAAE,GACpC,QACC,OAAI,UAAU,aACZ,SAAAwK,GAAQ,IAAKtJ,GACZqC,OAAC,OAEC,UAAU,aACV,cAAarC,IAAMwO,EACnB,QAAS,IAAME,EAAa1O,CAAC,EAE7B,UAAAN,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,IAAF,CAAM,KAAM,GAAI,EACnB,EACAnF,OAAC,OAAI,UAAU,KACb,UAAA3C,MAAC,QAAK,UAAU,MAAO,SAAAM,EAAE,EACzBN,MAAC,OAAI,UAAU,OAAQ,WAAE,UAAUM,CAAC,MAAc,EAAE,GACtD,IAXKA,CAAA,CAaR,EACH,IAGN,CC9xBO,MAAM2O,WAA2BC,WAAwB,CAC9D,MAAe,CAAE,MAAO,MAExB,OAAO,yBAAyBC,EAAqB,CACnD,MAAO,CAAE,MAAAA,CAAA,CACX,CAEA,kBAAkBA,EAAcC,EAAgD,CAC9E,QAAQ,MAAM,UAAU,KAAK,MAAM,KAAK,iBAAkBD,EAAOC,CAAI,CACvE,CAEA,QAAoB,CAClB,OAAK,KAAK,MAAM,MAEdzM,OAAC,OACC,UAAU,YACV,MAAO,CACL,MAAO,yBACP,QAAS,GACT,SAAU,GACV,WAAY,WACZ,UAAW,cAGZ,UAAAvD,EAAE,oBAAqB,CAAE,MAAO,KAAK,MAAM,MAAO,EAClD,KACA,KAAK,MAAM,MAAM,WAdQ,KAAK,MAAM,QAiB3C,CACF,CC3BA,MAAMiQ,GAAqB,IAEpB,SAASC,GAAa,CAC3B,SAAAjW,EACA,MAAAkW,EACA,SAAAC,EACA,WAAAC,EACA,aAAAC,EACA,OAAAC,EACA,aAAAC,EACA,aAAAC,CACF,EASG,CACDtR,EAAA,EACA,KAAM,CAACuR,EAAKC,CAAM,EAAItR,WAAc,OAAO,EACrCuR,EAAWT,EAAM,eAIjBU,EAAS,KAAK,IAAI,EAAGV,EAAM,eAAiBS,CAAQ,EACpDE,EAAO,KAAK,IAAI,EAAGX,EAAM,gBAAkB,KAAK,IAAI,EAAGS,EAAWT,EAAM,cAAc,CAAC,EACvFY,EAAc,KAAK,IAAI,IAAMH,EAAWX,GAAsB,GAAG,EACjEe,EAAU,KAAK,IAAI,IAAMF,EAAOb,GAAsB,GAAG,EACzDgB,EAAY,KAAK,IAAI,IAAMJ,EAASZ,GAAsB,GAAG,EAC7DiB,EAAO,KAAK,IAAI,EAAGjB,GAAqBW,EAAWE,EAAOD,CAAM,EACtE,OACEtN,OAAC,SAAM,UAAU,MACf,UAAAA,OAAC,OAAI,UAAU,WACb,UAAA3C,MAAC,OAAI,UAAU,UAAU,cAAa8P,IAAQ,QAAS,QAAS,IAAMC,EAAO,OAAO,EACjF,SAAA3Q,EAAE,uBAAuB,EAC5B,EACAY,MAAC,OAAI,UAAU,UAAU,cAAa8P,IAAQ,QAAS,QAAS,IAAMC,EAAO,OAAO,EACjF,SAAA3Q,EAAE,uBAAuB,EAC5B,EACAY,MAAC,OAAI,UAAU,UAAU,cAAa8P,IAAQ,SAAU,QAAS,IAAMC,EAAO,QAAQ,EACnF,SAAA3Q,EAAE,wBAAwB,EAC7B,EACAY,MAAC,OAAI,UAAU,UAAU,cAAa8P,IAAQ,QAAS,QAAS,IAAMC,EAAO,OAAO,EACjF,SAAA3Q,EAAE,uBAAuB,EAC5B,GACF,EAEAuD,OAAC,OAAI,UAAU,WACb,UAAAA,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,QAAM,SAAAZ,EAAE,4BAA4B,EAAE,EACvCuD,OAAC,QAAK,UAAU,QACZ,WAAAqN,EAAWE,EAAOD,GAAQ,iBAAiB,KAAG,IAC/CZ,GAAmB,gBAAe,EACrC,GACF,EACA1M,OAAC,OAAI,UAAU,QACb,UAAA3C,MAAC,QAAK,UAAU,OAAO,MAAO,CAAE,MAAO,GAAGmQ,CAAW,IAAI,CAAG,EAC5DnQ,MAAC,QAAK,UAAU,SAAS,MAAO,CAAE,MAAO,GAAGqQ,CAAS,IAAI,CAAG,EAC5DrQ,MAAC,QAAK,UAAU,OAAO,MAAO,CAAE,MAAO,GAAGoQ,CAAO,IAAI,CAAG,GAC1D,EACAzN,OAAC,OAAI,UAAU,SACb,UAAAA,OAAC,QAAK,UAAU,IACd,UAAA3C,MAAC,QAAK,UAAU,OAAO,EACtBZ,EAAE,0BAA0B,EAAE,UAAE,QAAK,UAAU,IAAK,SAAA4Q,EAAS,gBAAe,CAAE,GACjF,EACArN,OAAC,QAAK,UAAU,IACd,UAAA3C,MAAC,QAAK,UAAU,OAAO,EACtBZ,EAAE,uBAAuB,EAAE,UAAE,QAAK,UAAU,IAAK,SAAA6Q,EAAO,gBAAe,CAAE,GAC5E,EACAtN,OAAC,QAAK,UAAU,IACd,UAAA3C,MAAC,QAAK,UAAU,OAAO,EACtBZ,EAAE,sBAAsB,EAAE,UAAE,QAAK,UAAU,IAAK,SAAA8Q,EAAK,gBAAe,CAAE,GACzE,EACAvN,OAAC,QAAK,UAAU,IACb,UAAAvD,EAAE,sBAAsB,EAAE,UAAE,QAAK,UAAU,IAAK,SAAAkR,EAAK,gBAAe,CAAE,GACzE,GACF,GACF,EAEA3N,OAACsM,GAAA,CAA6B,MAAOa,EAClC,UAAAA,IAAQ,SAAW9P,MAACuQ,GAAA,CAAS,MAAOb,EAAc,EAClDI,IAAQ,SAAW9P,MAACwQ,IAAS,MAAOhB,EAAU,QAASC,EAAY,EACnEK,IAAQ,UACP9P,MAACyQ,GAAA,CAAU,QAASd,EAAQ,OAAQC,EAAc,OAAQC,CAAA,CAAc,EAEzEC,IAAQ,SAAW9P,MAAC0Q,GAAA,CAAS,SAAArX,CAAA,CAAoB,IAN3ByW,CAOzB,GACF,GACF,CAEJ,CAMA,SAASa,GAAiBC,EAAkC,CAC1D,MAAMC,EAAS,CAAC,GAAGD,CAAK,EAAE,KAAK,CAACtO,EAAGhG,IACjCgG,EAAE,KAAK,QAAQ,MAAO,GAAG,EAAE,cAAchG,EAAE,KAAK,QAAQ,MAAO,GAAG,CAAC,GAE/D3C,EAAkB,GAClBmX,MAAe,IACrB,UAAWC,KAAKF,EAAQ,CACtB,MAAM5R,EAAQ8R,EAAE,KAAK,QAAQ,MAAO,GAAG,EAAE,MAAM,GAAG,EAAE,OAAO,OAAO,EAClE,GAAI9R,EAAM,SAAW,EAAG,SACxB,IAAIwG,EAAS,GACb,QAAS3C,EAAI,EAAGA,EAAI7D,EAAM,OAAS,EAAG6D,IAAK,CACzC,MAAMkO,EAAM/R,EAAM6D,CAAC,GAAK,GACxB2C,EAASA,EAAS,GAAGA,CAAM,IAAIuL,CAAG,GAAKA,EAClCF,EAAS,IAAIrL,CAAM,IACtBqL,EAAS,IAAIrL,CAAM,EACnB9L,EAAI,KAAK,CAAE,KAAM,MAAO,MAAOmJ,EAAG,KAAMkO,EAAK,IAAK,KAAKvL,CAAM,GAAI,EAErE,CACA,MAAMwL,EAAOhS,EAAMA,EAAM,OAAS,CAAC,GAAK,GACxCtF,EAAI,KAAK,CACP,KAAM,OACN,MAAOsF,EAAM,OAAS,EACtB,KAAMgS,EACN,IAAK,KAAKF,EAAE,IAAI,GAChB,OAAQA,EAAE,OACX,CACH,CACA,OAAOpX,CACT,CAEA,SAAS4W,GAAS,CAAE,MAAAK,GAAmC,CACrD,MAAMM,EAAO/O,UAAQ,IAAMwO,GAAiBC,CAAK,EAAG,CAACA,CAAK,CAAC,EAC3D,OACEjO,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,QAAM,SAAAZ,EAAE,yBAAyB,EAAE,EACpCY,MAAC,QAAK,UAAU,QACb,WAAM,SAAW,EAAI,IAAMZ,EAAE,0BAA2B,CAAE,MAAOwR,EAAM,OAAQ,EAClF,GACF,EACA5Q,MAAC,OAAI,UAAU,OACZ,WAAM,SAAW,EAChBA,MAAC,OAAI,UAAU,YAAa,SAAAZ,EAAE,yBAAyB,EAAE,EAEzD8R,EAAK,IAAKvS,GACRA,EAAE,OAAS,MACTgE,OAAC,OAAI,UAAU,OAAmB,SAAQhE,EAAE,MAAO,YAAU,MAC3D,UAAAqB,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EACtB,EACAnF,OAAC,QAAK,UAAU,KAAM,UAAAhE,EAAE,KAAK,KAAC,IAJLA,EAAE,GAK7B,EAEAgE,OAAC,OACC,UAAU,OAEV,SAAQhE,EAAE,MACV,YAAU,OACV,MAAOA,EAAE,KAET,UAAAqB,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EACpB,EACA9H,MAAC,QAAK,UAAU,KAAM,WAAE,KAAK,EAC7BA,MAAC,QACC,UAAU,MACV,SAAQrB,EAAE,OACV,MAAOA,EAAE,SAAW,IAAMS,EAAE,2BAA2B,EAAIA,EAAE,4BAA4B,GAC3F,GAbKT,EAAE,IAcT,CAEJ,CAEJ,GACF,CAEJ,CAEA,SAAS6R,GAAS,CAAE,MAAAjX,EAAO,QAAAC,GAAuD,CAChF,MAAM2X,EAAa5X,EAAM,OAAQG,GAAMA,EAAE,SAAW,WAAW,EAAE,OACjE,OACEiJ,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,QAAM,SAAAZ,EAAE,uBAAuB,EAAE,EAClCY,MAAC,QAAK,UAAU,QACb,SAAAzG,EAAM,SAAW,EACd,IACAC,EACE4F,EAAE,2BAA4B,CAAE,MAAO7F,EAAM,OAAQ,EACrD6F,EAAE,4BAA6B,CAAE,MAAO+R,EAAY,MAAO5X,EAAM,OAAQ,EACjF,GACF,EACCA,EAAM,SAAW,EAChByG,MAAC,OAAI,UAAU,YAAa,SAAAZ,EAAE,uBAAuB,EAAE,EAEvD7F,EAAM,IAAKG,GAAM,CACf,MAAM0X,EACJ1X,EAAE,SAAW,YACT,KACAA,EAAE,SAAW,UAAYA,EAAE,WACzB,MACA,UACF2X,EAAS3X,EAAE,aACb,MAAMA,EAAE,YAAY,GACpBA,EAAE,SAAW,YACX,OAAOA,EAAE,WAAc,SACrB,MAAM0F,EAAE,wBAAyB,CAAE,MAAO1F,EAAE,UAAW,CAAC,GACxD,MAAM0F,EAAE,uBAAuB,CAAC,GAClC1F,EAAE,SAAW,YACX,MAAM0F,EAAE,4BAA4B,CAAC,GACrC1F,EAAE,SAAW,WACX,MAAM0F,EAAE,0BAA0B,CAAC,GACnC1F,EAAE,SAAW,SACX,MAAM0F,EAAE,wBAAwB,CAAC,GACjC,MAAMA,EAAE,4BAA4B,CAAC,GACjD,OACEuD,OAAC,OAAI,UAAU,UACb,UAAA3C,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EACtB,EACAnF,OAAC,OAAI,UAAU,OACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAtG,EAAE,MAAQA,EAAE,QAAQ,EACxCiJ,OAAC,OAAI,UAAU,IACZ,UAAAjJ,EAAE,UACF2X,CAAA,EACH,GACF,EACArR,MAAC,QAAK,UAAU,SAAS,SAAQoR,CAAA,CAAK,IAXV1X,EAAE,GAYhC,CAEJ,CAAC,GAEL,CAEJ,CAEA,SAAS+W,GAAU,CACjB,QAAApW,EACA,OAAAiX,EACA,OAAAC,CACF,EAIG,CACD,OACE5O,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,QAAM,SAAAZ,EAAE,0BAA0B,EAAE,EACrCY,MAAC,QAAK,UAAU,QACb,WAAQ,SAAW,EAAI,IAAMZ,EAAE,yBAA0B,CAAE,MAAO/E,EAAQ,OAAQ,EACrF,GACF,EACCA,EAAQ,SAAW,EAClB2F,MAAC,OAAI,UAAU,YAAa,SAAAZ,EAAE,4BAA4B,EAAE,EAE5DuD,OAAC,OAAI,UAAU,MACZ,UAAAtI,EAAQ,IAAKvC,GACZ6K,OAAC,UACC,KAAK,SACL,UAAU,UACV,cAAa2O,GAAQ,OAASxZ,EAAE,KAEhC,QAAS,IAAMyZ,EAAOzZ,EAAE,IAAI,EAE5B,UAAAkI,MAAC,QAAK,UAAU,QAAQ,SAAQlI,EAAE,MAC/B,SAAAA,EAAE,QAAU,UAAYsH,EAAE,2BAA2B,EAAIA,EAAE,0BAA0B,EACxF,QACC,QAAK,UAAU,MAAO,SAAAtH,EAAE,aAAeA,EAAE,KAAK,IAN1CA,EAAE,KAQV,EACAwZ,EAAStR,MAAC,OAAI,UAAU,aAAc,SAAAsR,EAAO,KAAK,EAAS,MAC9D,GAEJ,CAEJ,CAEA,SAASZ,GAAS,CAAE,SAAArX,GAA2C,CAC7D,MAAMiS,EAAWjS,GAAU,UAAY,SACjCU,EACJuR,IAAa,OACT,CAAC,CAAE,EAAG,IAAK,MAAO,GAAM,KAAMlM,EAAE,uBAAuB,EAAG,EAC1DkM,IAAa,OACX,CACE,CAAE,EAAG,6CAA8C,MAAO,GAAM,KAAMlM,EAAE,2BAA2B,GACnG,CAAE,EAAG,0BAA2B,MAAO,GAAM,KAAMA,EAAE,iCAAiC,GACtF,CAAE,EAAG,6CAA8C,MAAO,GAAO,KAAMA,EAAE,4BAA4B,EAAE,EAEzG,CACE,CAAE,EAAG,IAAK,MAAO,GAAO,KAAMA,EAAE,yBAAyB,EAAE,EAErE,OACEuD,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,QAAM,SAAAZ,EAAE,+BAA+B,EAAE,EAC1CY,MAAC,QAAK,UAAU,QAAS,SAAAsL,CAAA,CAAS,GACpC,EACCvR,EAAM,IAAKI,GACVwI,OAAC,OAAI,UAAU,OACb,UAAAA,OAAC,OAAI,UAAU,MACb,UAAA3C,MAAC,QAAK,UAAW,OAAO7F,EAAE,MAAQ,GAAK,MAAM,GAAK,SAAAA,EAAE,EAAE,QACrD,QAAK,UAAW,MAAMA,EAAE,MAAQ,GAAK,MAAM,GACzC,SAAAA,EAAE,MAAQiF,EAAE,oBAAoB,EAAIA,EAAE,kBAAkB,EAC3D,GACF,EACAY,MAAC,OAAI,UAAU,OAAQ,WAAE,KAAK,IAPL7F,EAAE,CAQ7B,CACD,GACH,CAEJ,CC1TO,SAASqX,GAAQ,CACtB,KAAA7U,EACA,QAAA+E,EACA,KAAA+P,EACA,OAAAC,EACA,UAAAC,CACF,EAMG,CACDpT,EAAA,EACA,KAAM,CAACqT,EAAMpT,CAAO,EAAIC,WAAS,CAAC,EAClCC,YAAU,IAAM,CACd,GAAI,CAAC/B,EAAM,OACX,MAAMgN,EAAK,OAAO,YAAY,IAAMnL,EAASG,GAAMA,EAAI,CAAC,EAAG,GAAG,EAC9D,MAAO,IAAM,OAAO,cAAcgL,CAAE,CACtC,EAAG,CAAChN,CAAI,CAAC,EACT+B,YAAU,IAAM,CACd,GAAI,CAAC/B,EAAM,OACX,MAAM0D,EAASC,GAAqB,CAC9BA,EAAE,MAAQ,WACZA,EAAE,iBACFoB,EAAA,EAEJ,EACA,cAAO,iBAAiB,UAAWrB,CAAK,EACjC,IAAM,OAAO,oBAAoB,UAAWA,CAAK,CAC1D,EAAG,CAAC1D,EAAM+E,CAAO,CAAC,EAElB,MAAMmQ,EAAU1P,UAAQ,IAAMsP,EAAK,OAAQnD,GAAMA,EAAE,OAAO,EAAG,CAACmD,CAAI,CAAC,EAC7DK,EAAS3P,UAAQ,IAAMsP,EAAK,OAAQnD,GAAM,CAACA,EAAE,OAAO,EAAG,CAACmD,CAAI,CAAC,EAEnE,OAAK9U,EAGHqD,MAAC,OAAI,UAAU,YAAY,QAAS0B,EAClC,SAAAiB,OAAC,OAAI,UAAU,WAAW,QAAUrC,GAAMA,EAAE,kBAC1C,UAAAqC,OAAC,OAAI,UAAU,YACb,UAAA3C,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,IAAF,CAAM,KAAM,GAAI,EACnB,SACC,OACC,UAAA9H,MAAC,OAAI,UAAU,KAAM,SAAAZ,EAAE,YAAY,EAAE,EACrCuD,OAAC,OAAI,UAAU,KACb,UAAA3C,MAAC,QAAK,UAAU,OAAQ,SAAA6R,EAAQ,OAAO,EAAO,IAAEzS,EAAE,cAAc,EAAE,KAAG,IACrEY,MAAC,QAAK,UAAU,QAAS,WAAO,OAAO,EAAO,IAAEZ,EAAE,aAAa,GACjE,GACF,EACAY,MAAC,QAAK,UAAU,OAAO,EACtB6R,EAAQ,OAAS,EAChBlP,OAAC,UACC,KAAK,SACL,UAAU,gBACV,QAASgP,EACT,MAAOvS,EAAE,iBAAiB,EAE1B,UAAAY,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EAAE,IAAE1I,EAAE,cAAc,KAEtC,MACN,EAEAY,MAAC,OAAI,UAAU,YACZ,WAAK,SAAW,EACfA,MAAC,OAAI,UAAU,aAAc,SAAAZ,EAAE,YAAY,EAAE,EAE7CuD,OAAAyL,WAAA,CACG,UAAAyD,EAAQ,OAAS,EAAI7R,MAAC,OAAI,UAAU,WAAY,SAAAZ,EAAE,cAAc,EAAE,EAAS,KAC3EyS,EAAQ,IAAKvD,GACZtO,MAAC+R,GAAA,CAAkB,IAAKzD,EAAG,KAAAsD,EAAY,OAAAF,CAAA,EAA1BpD,EAAE,EAAwC,CACxD,EACAwD,EAAO,OAAS,EAAI9R,MAAC,OAAI,UAAU,WAAY,SAAAZ,EAAE,aAAa,EAAE,EAAS,KACzE0S,EAAO,IAAKxD,GACXtO,MAAC+R,GAAA,CAAkB,IAAKzD,EAAG,KAAAsD,EAAY,OAAAF,GAA1BpD,EAAE,EAAwC,CACxD,GACH,EAEJ,QAEC,OAAI,UAAU,YACb,SAAA3L,OAAC,OAAI,UAAU,MACb,UAAA3C,MAAC8H,EAAE,IAAF,CAAM,KAAM,GAAI,SAChB,QACE,UAAA1I,EAAE,cAAc,EAAE,IAACY,MAAC,QAAK,UAAU,IAAK,WAAQ,OAAO,GAC1D,EACAA,MAAC,QAAK,aAAC,SACN,QACE,UAAAZ,EAAE,aAAa,EAAE,IAACY,MAAC,QAAK,UAAU,IAAK,WAAO,OAAO,GACxD,EACAA,MAAC,QAAK,UAAU,OAAO,SACtB,QACC,UAAAA,MAACF,EAAA,CAAS,KAAM,CAAC,MAAO,GAAG,EAAG,EAAE,IAAEV,EAAE,eAAe,EAAE,KAAG,IACxDY,MAACF,EAAA,CAAS,KAAM,CAAC,KAAK,EAAG,EAAE,IAAEV,EAAE,cAAc,GAC/C,GACF,EACF,GACF,EACF,EAhEgB,IAkEpB,CAEA,SAAS4S,GAAc1I,EAAoB,CACzC,GAAIA,EAAK,IAAM,MAAO,GAAGA,CAAE,KAC3B,MAAM5P,EAAI4P,EAAK,IACf,GAAI5P,EAAI,GAAI,MAAO,GAAGA,EAAE,QAAQ,CAAC,CAAC,IAClC,MAAM5B,EAAI,KAAK,MAAM4B,EAAI,EAAE,EACrBS,EAAI,KAAK,MAAMT,EAAI,EAAE,EAC3B,MAAO,GAAG5B,CAAC,IAAIqC,CAAC,GAClB,CAEA,SAAS4X,GAAO,CACd,IAAAE,EACA,KAAAL,EACA,OAAAF,CACF,EAIG,CACD,KAAM,CAACQ,EAAKC,CAAM,EAAI1T,WAAS,EAAK,EAC9B2T,GAAaH,EAAI,QAAU,KAAK,MAAQA,EAAI,UAAY,GAAKA,EAAI,UACjEI,EAASJ,EAAI,QAAU,KAAK,MAAQA,EAAI,UAAYG,EAG1D,OACEzP,OAAC,OAAI,UAAU,UAAU,cAAasP,EAAI,QAAU,UAAY,SAC9D,UAAAtP,OAAC,OAAI,UAAU,UAAU,QAAS,IAAMwP,EAAQ5R,GAAM,CAACA,CAAC,EACtD,UAAAP,MAAC,QAAK,UAAU,WACb,SAAAiS,EAAI,QACHjS,MAAC,QAAK,UAAU,OAAO,QAEtB8H,EAAE,QAAF,CAAU,KAAM,GAAI,MAAO,CAAE,MAAO,iBAAiB,CAAG,EAE7D,EACAnF,OAAC,QAAK,UAAU,UACd,UAAA3C,MAAC8H,EAAE,SAAF,CAAW,KAAM,GAAI,EACtB9H,MAAC,QAAK,iBAAK,GACb,EACA2C,OAAC,OAAI,UAAU,UACb,UAAA3C,MAAC,OAAI,UAAU,KAAK,MAAOiS,EAAI,QAC5B,WAAI,QACP,EACAtP,OAAC,OAAI,UAAU,MACb,UAAA3C,MAAC,QAAK,UAAU,MAAO,SAAAiS,EAAI,aAAa,EACvCA,EAAI,WAAatP,OAAC,QAAK,UAAU,KAAK,eAAGsP,EAAI,YAAW,EAAU,KAClE,CAACA,EAAI,SAAWA,EAAI,WAAa,MAAQA,EAAI,WAAa,EACzDtP,OAAC,QAAK,UAAU,KAAK,oBAAQsP,EAAI,UAAS,EACxC,MACN,GACF,QACC,OAAI,UAAU,UAAW,SAAAD,GAAcK,CAAM,EAAE,EAChDrS,MAAC,OAAI,UAAU,SACZ,WAAI,QACH2C,OAAC,UACC,KAAK,SACL,UAAU,gBACV,MAAOvD,EAAE,cAAc,EACvB,QAAUkB,GAAM,CACdA,EAAE,kBACFoR,EAAOO,EAAI,EAAE,CACf,EAEA,UAAAjS,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EAAE,IAAE1I,EAAE,WAAW,WAGpC,QAAK,UAAU,UAAU,MAAO,QAAQ6S,EAAI,UAAY,GAAG,GACzD,SAAAA,EAAI,WAAa,EAAI,KAAO,QAAQA,EAAI,UAAY,GAAG,GAC1D,EAEJ,GACF,EACCC,EACCvP,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,UACb,UAAAA,OAAC,OACC,UAAA3C,MAAC,QAAK,UAAU,IAAI,kBAAM,EAC1BA,MAAC,QAAK,UAAU,IAAK,WAAI,GAAG,GAC9B,SACC,OACC,UAAAA,MAAC,QAAK,UAAU,IAAI,eAAG,QACtB,QAAK,UAAU,IAAK,SAAAiS,EAAI,KAAO,IAAI,GACtC,SACC,OACC,UAAAjS,MAAC,QAAK,UAAU,IAAI,mBAAO,QAC1B,QAAK,UAAU,IAAK,SAAAgS,GAAcK,CAAM,EAAE,GAC7C,GACF,EACCJ,EAAI,WAAajS,MAAC,OAAI,UAAU,SAAU,SAAAiS,EAAI,WAAW,EAAS,MACrE,EACE,MACN,CAEJ,CCpMA,MAAMK,GAAW,gDAEV,SAASC,GAAW,CAAE,QAAA7Q,GAAoC,CAC/D,MAAM8Q,EAAa,IAAM,CAClB3V,GAAQyV,EAAQ,EAAE,MAAM,MAAe,CAC9C,EAEA,aACG,OAAI,UAAU,aAAa,QAAS5Q,EACnC,SAAAiB,OAAC,OAAI,UAAU,cAAc,QAAUrC,GAAMA,EAAE,kBAC7C,UAAAN,MAAC,UAAO,KAAK,SAAS,UAAU,cAAc,QAAS0B,EAAS,aAAYtC,EAAE,aAAa,EACzF,eAAC0I,EAAE,EAAF,CAAI,KAAM,GAAI,EACjB,EACAnF,OAAC,OAAI,UAAU,cACb,gBAAC,OAAI,UAAU,aAAa,oBAAQ,QACnC,OAAI,UAAU,gBAAiB,SAAAvD,EAAE,eAAe,EAAE,GACrD,EACAuD,OAAC,OAAI,UAAU,aACb,UAAAA,OAAC,OAAI,UAAU,YACb,UAAA3C,MAAC,QAAK,UAAU,cAAe,SAAAZ,EAAE,eAAe,EAAE,QACjD,QAAK,UAAU,cAAe,kBAAgB,GACjD,EACAuD,OAAC,OAAI,UAAU,YACb,UAAA3C,MAAC,QAAK,UAAU,cAAe,SAAAZ,EAAE,YAAY,EAAE,SAC9C,UAAO,KAAK,SAAS,UAAU,aAAa,QAASoT,EACpD,gBAAC1K,EAAE,KAAF,CAAO,KAAM,GAAI,EAClB9H,MAAC,QAAK,sCAA0B,GAClC,GACF,GACF,GACF,EACF,CAEJ,CCvBO,SAASyS,GAAYC,EAA+C,CACzE,GAAKA,EACL,OAAOA,EAAM,OAAS,EAAI,GAAGA,EAAM,MAAM,EAAG,CAAC,CAAC,MAAQA,CACxD,CAEO,SAASC,GAAmBC,EAAqD,CACtF,OAAOA,EAAG,WAAa,UAAY,WACrC,CAEO,SAASC,GAAiBD,EAAoC,CACnE,OAAQA,EAAG,cACT,IAAK,YACH,OAAOxT,EAAE,sBAAsB,EACjC,IAAK,aACH,OAAOA,EAAE,uBAAuB,EAClC,IAAK,SACH,OAAOA,EAAE,mBAAmB,EAC9B,QACE,OAAOA,EAAE,yBAAyB,EAExC,CAEO,SAAS0T,GAAsBC,EAAwB,CAC5D,MAAMC,EAAQ,sCAAsC,KAAKD,CAAM,EAC/D,GAAIC,EAAO,CACT,MAAMC,EAASD,EAAM,CAAC,GAAK,UACrBE,EAAQF,EAAM,CAAC,EACrB,OAAIE,EAAc9T,EAAE,sCAAuC,CAAE,OAAA6T,EAAQ,MAAAC,EAAO,EACrE9T,EAAE,yBAA0B,CAAE,OAAA6T,EAAQ,CAC/C,CAEA,MAAME,EAAY,oBAAoB,KAAKJ,CAAM,EACjD,GAAII,EAAW,OAAO/T,EAAE,6BAA8B,CAAE,MAAO+T,EAAU,CAAC,GAAK,IAAK,EAEpF,MAAMC,EAAU,wCAAwC,KAAKL,CAAM,EACnE,OAAIK,EAAgBhU,EAAE,2BAA4B,CAAE,OAAQgU,EAAQ,CAAC,GAAK,UAAW,EAE9EhU,EAAE,uBAAuB,CAClC,CAEO,SAASiU,GAAqBT,EAAoC,CACvE,GAAI,CAACA,EAAG,WAAY,OAAOxT,EAAE,2BAA2B,EACxD,MAAMsT,EAAQE,EAAG,cAAgBH,GAAYG,EAAG,KAAK,GAAK,UAC1D,OAAOxT,EAAE,2BAA4B,CACnC,MAAOA,EAAE,0BAA2B,CAAE,MAAAsT,EAAO,EAC7C,YAAaE,EAAG,QAAUxT,EAAE,oBAAoB,EAAIA,EAAE,uBAAuB,EAC7E,OAAQ0T,GAAsBF,EAAG,MAAM,EACxC,CACH,CCtBA,MAAMU,GAAiE,CACrE,CAAE,GAAI,UAAW,KAAM,OACvB,CAAE,GAAI,SAAU,KAAM,SACtB,CAAE,GAAI,MAAO,KAAM,UACnB,CAAE,GAAI,SAAU,KAAM,OACtB,CAAE,GAAI,SAAU,KAAM,YACtB,CAAE,GAAI,QAAS,KAAM,UACrB,CAAE,GAAI,UAAW,KAAM,QACvB,CAAE,GAAI,YAAa,KAAM,MAC3B,EAEO,SAASC,GAAc,CAC5B,SAAAla,EACA,QAAAma,EACA,MAAAjE,EACA,SAAAkE,EACA,MAAArQ,EACA,WAAAsQ,EACA,WAAAC,EACA,gBAAAC,EACA,UAAAC,EACA,eAAAC,EACA,WAAAC,EACA,gBAAAC,EACA,YAAAC,EACA,SAAAzE,EACA,WAAAC,EACA,OAAAyE,EACA,OAAAvE,EACA,aAAAC,EACA,GAAAgD,EACA,QAAAlR,EACA,OAAAyS,EACA,aAAAC,EACA,SAAAC,EACA,YAAAC,EACA,eAAAC,GACA,eAAAC,EACA,kBAAAC,EACA,gBAAAC,EACA,aAAAC,GACA,gBAAAC,GACA,aAAA/E,EACF,EAgCG,CACD,KAAM,CAACgF,EAAMC,EAAO,EAAIrW,WAAiBwV,GAAe,SAAS,EAC3D,CAACc,GAAiBC,CAAkB,EAAIvW,WAAS,EAAK,EACtDwW,EAAc3B,GAAU,KAAMnU,GAAMA,EAAE,KAAO0V,CAAI,GAAKvB,GAAU,CAAC,EACvE,OACEtT,MAAC,OAAI,UAAU,gBAAgB,QAAS0B,EACtC,SAAAiB,OAAC,OAAI,UAAU,WAAW,QAAUrC,GAAMA,EAAE,kBAC1C,UAAAqC,OAAC,OAAI,UAAU,gBACb,UAAA3C,MAAC,OAAI,UAAU,KAAM,SAAAZ,EAAE,gBAAgB,EAAE,EACxCkU,GAAU,IAAKnU,GACdwD,OAAC,OAEC,UAAU,MACV,cAAakS,IAAS1V,EAAE,GACxB,QAAS,IAAM2V,GAAQ3V,EAAE,EAAE,EAE3B,UAAAa,MAAC,QAAK,UAAU,MAAO,SAAA8H,EAAE3I,EAAE,IAAI,EAAE,CAAE,KAAM,GAAI,EAAE,QAC9C,QAAM,SAAAC,EAAE,gBAAgBD,EAAE,GAAG,CAAC,EAAG,aAAa,GAAGA,EAAE,GAAG,MAAM,CAAC,CAAC,OAAc,EAAE,IAN1EA,EAAE,GAQV,GACH,EACAwD,OAAC,OAAI,UAAU,gBACb,UAAAA,OAAC,OAAI,UAAU,gBACb,UAAAA,OAAC,OACC,UAAA3C,MAAC,MACE,SAAAZ,EACC,gBAAgB6V,EAAY,GAAG,CAAC,EAAG,aAAa,GAAGA,EAAY,GAAG,MAAM,CAAC,CAAC,SAE9E,EACAjV,MAAC,OAAI,UAAU,OACZ,SAAAZ,EACC,gBAAgB6V,EAAY,GAAG,CAAC,EAAG,aAAa,GAAGA,EAAY,GAAG,MAAM,CAAC,CAAC,OAC5E,CACF,GACF,EACAjV,MAAC,QAAK,UAAU,OAAO,EACvBA,MAAC,UAAO,KAAK,SAAS,UAAU,YAAY,QAAS0B,EACnD,SAAA1B,MAAC8H,EAAE,EAAF,CAAI,KAAM,GAAI,EACjB,GACF,EACAnF,OAAC,OAAI,UAAU,gBACZ,UAAAkS,IAAS,WACR7U,MAACkV,GAAA,CACC,SAAA7b,EACA,MAAA+J,EACA,WAAAsQ,EACA,WAAAC,EACA,gBAAAC,EACA,UAAAC,EACA,eAAAC,EACA,WAAAC,EACA,gBAAAC,EACA,OAAAG,EACA,gBAAAO,CAAA,GAGHG,IAAS,UAAY7U,MAACmV,GAAA,CAAW,SAAA9b,EAAoB,OAAA8a,EAAgB,EACrEU,IAAS,OACR7U,MAACoV,GAAA,CACC,MAAO5F,EACP,QAASC,EACT,MAAOkF,GACP,SAAUC,EAAA,GAGbC,IAAS,UACR7U,MAACqV,GAAA,CACC,OAAAnB,EACA,eAAgB7a,EAAS,gBAAkB,GAC3C,OAAA8a,CAAA,GAGHU,IAAS,UACR7U,MAACsV,GAAA,CAAW,QAAS3F,EAAQ,OAAQC,EAAc,OAAQC,EAAA,CAAc,EAE1EgF,IAAS,SAAW7U,MAACuV,GAAA,CAAU,SAAAlc,EAAoB,OAAA8a,EAAgB,EACnEU,IAAS,WACR7U,MAACwV,GAAA,CAAY,QAAAhC,EAAkB,MAAAjE,EAAc,SAAAkE,EAAoB,EAElEoB,IAAS,aAAe7U,MAACyV,GAAA,EAAc,EACvCZ,IAAS,UACRlS,OAAAyL,WAAA,CACE,UAAApO,MAAC0V,GAAA,CACC,QAASrc,EAAS,QAClB,aAAcA,EAAS,aACvB,OAAA8a,EACA,aAAAC,CAAA,GAEFpU,MAAC2V,GAAA,CACC,GAAA/C,EACA,cAAemC,GACf,gBAAiB,IAAM,CACrBV,EAAA,EACAW,EAAmB,EAAI,CACzB,EACA,iBAAkB,IAAMA,EAAmB,EAAK,EAChD,UAAWV,EACX,aAAcC,GACd,aAAcC,EACd,iBAAmBoB,GAAU,CAC3BpB,EAAeoB,CAAK,EACpBtB,EAAA,CACF,EACA,gBAAiBG,CAAA,EACnB,EACF,EACE,MACN,GACF,GACF,EACF,CAEJ,CAEO,SAASkB,GAAiB,CAC/B,GAAA/C,EACA,cAAAiD,EACA,gBAAAC,EACA,iBAAAC,EACA,UAAAC,EACA,aAAAC,EACA,aAAAC,EACA,iBAAAC,EACA,gBAAAC,CACF,EAUG,CACD,MAAMC,EAAUzD,GAAM,CACpB,MAAO,OACP,UAAW,OACX,QAAS,GAET,WAAY,GACZ,aAAc,eACd,OAAQ,kBAEJ,CAACF,EAAO4D,CAAQ,EAAI7X,WAAS4X,EAAQ,OAAS,EAAE,EAChD,CAACE,EAAWC,CAAY,EAAI/X,WAAS4X,EAAQ,WAAa,EAAE,EAC5D,CAACI,EAASC,CAAU,EAAIjY,WAAS4X,EAAQ,SAAW,EAAI,EAE9D3X,YAAU,IAAM,CACd4X,EAASD,EAAQ,OAAS,EAAE,EAC5BG,EAAaH,EAAQ,WAAa,EAAE,EACpCK,EAAWL,EAAQ,SAAW,EAAI,CACpC,EAAG,CAACA,EAAQ,MAAOA,EAAQ,UAAWA,EAAQ,QAASR,CAAa,CAAC,EAErE,MAAMc,EAAY,CAAE,MAAAjE,EAAO,UAAA6D,EAAW,QAAAE,CAAA,EAEtC,OACE9T,OAAC,WAAQ,UAAU,UACjB,UAAA3C,MAAC,OAAI,UAAU,SAAU,SAAAZ,EAAE,oBAAoB,EAAE,EAC/CyW,EAsCAlT,OAAC,OAAI,UAAU,iBACb,UAAAA,OAAC,OAAI,UAAU,iBACb,UAAAA,OAAC,OACC,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,2BAA2B,EAAE,QAClD,OAAI,UAAU,IAAK,SAAAA,EAAE,0BAA0B,EAAE,GACpD,EACAY,MAAC,UAAO,KAAK,SAAS,UAAU,MAAM,QAAS+V,EAC5C,SAAA3W,EAAE,iBAAiB,EACtB,GACF,EACAuD,OAAC,OAAI,UAAU,cACb,UAAA3C,MAAC,OAAI,UAAU,IACb,SAAAA,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,kBAAkB,EAAE,EAC5C,EACAY,MAAC,SACC,UAAU,aACV,MAAO0S,EACP,SAAWpS,GAAMgW,EAAShW,EAAE,OAAO,KAAK,EACxC,YAAY,2BACd,EACF,EACAqC,OAAC,OAAI,UAAU,cACb,UAAA3C,MAAC,OAAI,UAAU,IACb,SAAAA,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,sBAAsB,EAAE,EAChD,EACAY,MAAC,SACC,UAAU,aACV,KAAK,WACL,MAAOuW,EACP,SAAWjW,GAAMkW,EAAalW,EAAE,OAAO,KAAK,EAC5C,YAAY,+BACd,EACF,EACAqC,OAAC,OAAI,UAAU,cACb,UAAA3C,MAAC,OAAI,UAAU,IACb,SAAAA,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,wBAAwB,EAAE,EAClD,EACAuD,OAAC,OAAI,UAAU,WACb,UAAA3C,MAAC,UAAO,KAAK,SAAS,UAASyW,EAAS,QAAS,IAAMC,EAAW,EAAI,EACnE,SAAAtX,EAAE,oBAAoB,EACzB,EACAY,MAAC,UAAO,KAAK,SAAS,UAAS,CAACyW,EAAS,QAAS,IAAMC,EAAW,EAAK,EACrE,SAAAtX,EAAE,uBAAuB,EAC5B,GACF,GACF,EACAuD,OAAC,OAAI,UAAU,cACb,UAAA3C,MAAC,OAAI,UAAU,IACb,SAAAA,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,uBAAuB,EAAE,EACjD,EACAY,MAAC,UAAO,KAAK,SAAS,UAAU,MAAM,QAASoW,EAC5C,SAAAhX,EAAE,wBAAwB,EAC7B,GACF,EACAuD,OAAC,OAAI,UAAU,oBACb,UAAA3C,MAAC,UACC,KAAK,SACL,UAAU,MACV,QAAS,IAAM,CACbkW,EAAaS,CAAS,EACtBZ,EAAA,CACF,EAEC,WAAE,iBAAiB,IAEtB/V,MAAC,UACC,KAAK,SACL,UAAU,cACV,QAAS,IAAM,CACbmW,EAAiBQ,CAAS,EAC1BZ,EAAA,CACF,EAEC,WAAE,2BAA2B,GAChC,EACF,GACF,EAjHApT,OAAC,OAAI,UAAU,6BACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,kBAAkB,EAAE,QACzC,OAAI,UAAU,IAAK,SAAAiU,GAAqBgD,CAAO,EAAE,GACpD,EACA1T,OAAC,OAAI,UAAU,iBACb,UAAA3C,MAAC,UACC,KAAK,SACL,UAAW,+BACTqW,EAAQ,eAAiB,YACrB,KACAA,EAAQ,eAAiB,aACvB,aACAA,EAAQ,eAAiB,SACvB,SACA,KACV,GACA,QAAS,IAAM,CACb,GAAI1D,GAAmB0D,CAAO,IAAM,YAAa,CAC/CP,EAAA,EACA,MACF,CACA,GAAIO,EAAQ,eAAiB,YAAa,CACxCJ,EAAA,EACA,MACF,CACAD,EAAA,CACF,EAEC,YAAiBK,CAAO,IAE3BrW,MAAC,UAAO,KAAK,SAAS,UAAU,MAAM,QAAS8V,EAC5C,SAAA1W,EAAE,sBAAsB,EAC3B,GACF,GACF,CA8EA,EAEJ,CAEJ,CAEA,SAAS8V,GAAY,CACnB,SAAA7b,EACA,MAAA+J,EACA,WAAAsQ,EACA,WAAAC,EACA,gBAAAC,EACA,UAAAC,EACA,eAAAC,EACA,WAAAC,EACA,gBAAAC,EACA,OAAAG,EACA,gBAAAO,CACF,EAYG,CACD,KAAM,CAACkC,EAAaC,CAAc,EAAIpY,WAASpF,EAAS,QAAU,EAAE,EAC9D6E,EAAOK,EAAA,EACb,OACEoE,OAAAyL,WAAA,CACE,UAAAzL,OAAC,WAAQ,UAAU,UACjB,UAAA3C,MAAC,OAAI,UAAU,SAAU,SAAAZ,EAAE,4BAA4B,EAAE,EACzDuD,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,gBAAgB,EAAE,QACvC,OAAI,UAAU,IAAK,SAAAA,EAAE,oBAAoB,EAAE,GAC9C,EACAuD,OAAC,OAAI,UAAU,WACb,UAAA3C,MAAC,UACC,KAAK,SACL,UAASoD,IAAU2E,GAAM,KACzB,QAAS,IAAM4L,EAAW5L,GAAM,IAAI,EAEnC,WAAE,oBAAoB,IAEzB/H,MAAC,UACC,KAAK,SACL,UAASoD,IAAU2E,GAAM,MACzB,QAAS,IAAM4L,EAAW5L,GAAM,KAAK,EAEpC,WAAE,qBAAqB,GAC1B,EACF,GACF,EACApF,OAAC,OAAI,UAAU,8BACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,qBAAqB,EAAE,QAC5C,OAAI,UAAU,IAAK,SAAAA,EAAE,yBAAyB,EAAE,GACnD,QACC,OAAI,UAAU,aACZ,SAAAiJ,GAAa,IAAKG,GACjB7F,OAAC,UAEC,KAAK,SACL,UAAU,aACV,UAAS+Q,IAAelL,EACxB,aAAYA,EACZ,QAAS,IAAMoL,EAAgBpL,CAAK,EAEpC,UAAA7F,OAAC,QAAK,UAAU,kBACd,UAAA3C,MAAC,QAAK,UAAU,aACb,SAAAZ,EAAE,sBAAsBoJ,EAAM,CAAC,EAAG,aAAa,GAAGA,EAAM,MAAM,CAAC,CAAC,EAAS,EAC5E,EACAxI,MAAC,QAAK,UAAU,aACb,YAAcwI,CAAK,IAAMT,GAAM,KAC5B3I,EAAE,oBAAoB,EACtBA,EAAE,qBAAqB,EAC7B,GACF,EACAuD,OAAC,QAAK,UAAU,iBAAiB,cAAY,OAC3C,UAAA3C,MAAC,SAAK,QACL,SAAK,QACL,SAAK,GACR,QACC,QAAK,UAAU,aACb,SAAAZ,EAAE,sBAAsBoJ,EAAM,CAAC,EAAG,aAAa,GAAGA,EAAM,MAAM,CAAC,CAAC,MAAa,EAChF,IAxBKA,CAAA,CA0BR,EACH,GACF,EACA7F,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,oBAAoB,EAAE,QAC3C,OAAI,UAAU,IAAK,SAAAA,EAAE,wBAAwB,EAAE,GAClD,EACAuD,OAAC,OAAI,UAAU,WACb,UAAA3C,MAAC,UACC,KAAK,SACL,UAAS6T,IAAcnL,GAAW,MAClC,QAAS,IAAMoL,EAAepL,GAAW,KAAK,EAE7C,WAAE,yBAAyB,IAE9B1I,MAAC,UACC,KAAK,SACL,UAAS6T,IAAcnL,GAAW,OAClC,QAAS,IAAMoL,EAAepL,GAAW,MAAM,EAE9C,WAAE,0BAA0B,IAE/B1I,MAAC,UACC,KAAK,SACL,UAAS6T,IAAcnL,GAAW,MAClC,QAAS,IAAMoL,EAAepL,GAAW,KAAK,EAE7C,WAAE,yBAAyB,GAC9B,EACF,GACF,EACA/F,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,qBAAqB,EAAE,QAC5C,OAAI,UAAU,IAAK,SAAAA,EAAE,yBAAyB,EAAE,GACnD,EACAuD,OAAC,OAAI,UAAU,WACb,UAAA3C,MAAC,UACC,KAAK,SACL,UAAS+T,IAAelL,GAAY,KACpC,QAAS,IAAMmL,EAAgBnL,GAAY,IAAI,EAE9C,WAAE,yBAAyB,IAE9B7I,MAAC,UACC,KAAK,SACL,UAAS+T,IAAelL,GAAY,OACpC,QAAS,IAAMmL,EAAgBnL,GAAY,MAAM,EAEhD,WAAE,2BAA2B,IAEhC7I,MAAC,UACC,KAAK,SACL,UAAS+T,IAAelL,GAAY,MACpC,QAAS,IAAMmL,EAAgBnL,GAAY,KAAK,EAE/C,WAAE,0BAA0B,GAC/B,EACF,GACF,EACAlG,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,mBAAmB,EAAE,QAC1C,OAAI,UAAU,IAAK,SAAAA,EAAE,uBAAuB,EAAE,GACjD,EACAY,MAAC,OAAI,UAAU,WACZ,SAAA5B,KAAoB,IAAK0Y,GACxB9W,MAAC,UAAO,KAAK,SAAoB,UAAS9B,IAAS4Y,EAAM,QAAS,IAAMxY,GAAQwY,CAAI,EACjF,SAAAzY,GAAayY,CAAI,GADOA,CAE3B,CACD,EACH,GACF,GACF,EAEAnU,OAAC,WAAQ,UAAU,UACjB,UAAA3C,MAAC,OAAI,UAAU,SAAU,SAAAZ,EAAE,2BAA2B,EAAE,EACxDuD,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,2BAA2B,EAAE,EACnDY,MAAC,OAAI,UAAU,IAAK,WAAS,cAAgBZ,EAAE,sBAAsB,EAAE,GACzE,EACAY,MAAC,UAAO,KAAK,SAAS,UAAU,MAAM,QAAS0U,EAC5C,SAAAtV,EAAE,0BAA0B,EAC/B,GACF,EACAuD,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,iBAAiB,EAAE,QACxC,OAAI,UAAU,IAAK,SAAAA,EAAE,qBAAqB,EAAE,GAC/C,EACAY,MAAC,SACC,UAAU,aACV,MAAO4W,EACP,YAAY,gBACZ,SAAWtW,GAAMuW,EAAevW,EAAE,OAAO,KAAK,EAC9C,OAAQ,IAAM6T,EAAO,CAAE,OAAQyC,GAAe,OAAW,GAC3D,EACF,GACF,EAEAjU,OAAC,WAAQ,UAAU,UACjB,UAAA3C,MAAC,OAAI,UAAU,SAAU,SAAAZ,EAAE,0BAA0B,EAAE,EACvDuD,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,0BAA0B,EAAE,QACjD,OAAI,UAAU,IAAK,SAAAA,EAAE,8BAA8B,EAAE,GACxD,EACAY,MAAC,OAAI,UAAU,WACX,UAAC,MAAO,SAAU,OAAQ,KAAK,EAAY,IAAKM,GAChDN,MAAC,UACC,KAAK,SAEL,UAAS3G,EAAS,kBAAoBiH,EACtC,QAAS,IAAM6T,EAAO,CAAE,gBAAiB7T,EAAG,EAE3C,SAAAA,CAAA,EAJIA,CAAA,CAMR,EACH,GACF,EACAqC,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,mBAAmB,EAAE,QAC1C,OAAI,UAAU,IAAK,SAAAA,EAAE,uBAAuB,EAAE,GACjD,EACAY,MAAC,OAAI,UAAU,WACX,UAAC,OAAQ,SAAU,OAAQ,MAAM,EAAY,IAAKlI,GAClDkI,MAAC,UACC,KAAK,SAEL,UAAS3G,EAAS,WAAavB,EAC/B,QAAS,IAAMqc,EAAO,CAAE,SAAUrc,EAAG,EAEpC,SAAAA,CAAA,EAJIA,CAAA,CAMR,EACH,GACF,EACA6K,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,2BAA2B,EAAE,QAClD,OAAI,UAAU,IAAK,SAAAA,EAAE,+BAA+B,EAAE,GACzD,EACAuD,OAAC,OAAI,UAAU,WACb,UAAA3C,MAAC,UACC,KAAK,SACL,UAAS3G,EAAS,mBAAqB,GACvC,QAAS,IAAM8a,EAAO,CAAE,iBAAkB,GAAM,EAE/C,WAAE,gBAAgB,IAErBnU,MAAC,UACC,KAAK,SACL,UAAS3G,EAAS,mBAAqB,GACvC,QAAS,IAAM8a,EAAO,CAAE,iBAAkB,GAAO,EAEhD,WAAE,iBAAiB,GACtB,EACF,GACF,EACAxR,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,iBAAiB,EAAE,QACxC,OAAI,UAAU,IAAK,SAAAA,EAAE,qBAAqB,EAAE,GAC/C,EACAY,MAAC,SACC,UAAU,QACV,KAAK,SACL,aAAc3G,EAAS,WAAa,GACpC,YAAa+F,EAAE,4BAA4B,EAC3C,OAASkB,GAAM,CACb,MAAMC,EAAID,EAAE,OAAO,MAAM,OACzB6T,EAAO,CAAE,UAAW5T,IAAM,GAAK,KAAO,OAAOA,CAAC,EAAG,CACnD,GACF,EACF,EACAoC,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,0BAA0B,EAAE,QACjD,OAAI,UAAU,IAAK,SAAAA,EAAE,8BAA8B,EAAE,GACxD,EACAuD,OAAC,UACC,UAAU,QACV,MAAOtJ,EAAS,iBAAmB,OACnC,SAAWiH,GACT6T,EAAO,CACL,gBAAiB7T,EAAE,OAAO,MAO3B,EAGH,UAAAN,MAAC,UAAO,MAAM,OAAQ,SAAAZ,EAAE,8BAA8B,EAAE,QACvD,UAAO,MAAM,UAAW,SAAAA,EAAE,iCAAiC,EAAE,QAC7D,UAAO,MAAM,SAAU,SAAAA,EAAE,gCAAgC,EAAE,QAC3D,UAAO,MAAM,SAAU,SAAAA,EAAE,gCAAgC,EAAE,QAC3D,UAAO,MAAM,aAAc,SAAAA,EAAE,oCAAoC,EAAE,QACnE,UAAO,MAAM,MAAO,SAAAA,EAAE,6BAA6B,EAAE,IACxD,EACF,GACF,GACF,CAEJ,CAEA,SAASsW,GAAc,CACrB,QAAAqB,EACA,aAAAC,EACA,OAAA7C,EACA,aAAAC,CACF,EAKG,CACD,KAAM,CAACpV,EAAKiY,CAAM,EAAIxY,WAAS,EAAE,EAC3B,CAACyY,EAAUC,CAAW,EAAI1Y,WAASsY,GAAW,EAAE,EACtD,OACEpU,OAAC,WAAQ,UAAU,UACjB,UAAA3C,MAAC,OAAI,UAAU,SAAU,SAAAZ,EAAE,qBAAqB,EAAE,EAClDuD,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,iBAAiB,EAAE,EACzCY,MAAC,OAAI,UAAU,IACZ,WACGZ,EAAE,qBAAsB,CAAE,OAAQ4X,CAAA,CAAc,EAChD5X,EAAE,uBAAuB,EAC/B,GACF,EACAuD,OAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,IAAK,GAClC,UAAA3C,MAAC,SACC,UAAU,aACV,KAAK,WACL,MAAOhB,EACP,SAAWsB,GAAM2W,EAAO3W,EAAE,OAAO,KAAK,EACtC,YAAY,SAEdN,MAAC,UACC,KAAK,SACL,UAAU,cACV,SAAU,CAAChB,EACX,QAAS,IAAM,CACRA,IACLoV,EAAapV,CAAG,EAChBiY,EAAO,EAAE,EACX,EAEC,WAAE,qBAAqB,GAC1B,EACF,GACF,EACAtU,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,kBAAkB,EAAE,QACzC,OAAI,UAAU,IAAK,SAAAA,EAAE,sBAAsB,EAAE,GAChD,EACAY,MAAC,SACC,UAAU,aACV,MAAOkX,EACP,SAAW5W,GAAM6W,EAAY7W,EAAE,OAAO,KAAK,EAC3C,OAAQ,IAAM6T,EAAO,CAAE,QAAS+C,EAAS,QAAU,OAAW,GAChE,EACF,GACF,CAEJ,CAEA,MAAMrI,GAAe,CAAC,oBAAqB,iBAAiB,EAEtDuI,GAAgB,CAAC,MAAO,SAAU,OAAQ,KAAK,EAGrD,SAASjC,GAAW,CAClB,SAAA9b,EACA,OAAA8a,CACF,EAGG,CACD,KAAM,CAACzJ,EAAOC,CAAQ,EAAIlM,WAASpF,EAAS,KAAK,EACjDqF,YAAU,IAAMiM,EAAStR,EAAS,KAAK,EAAG,CAACA,EAAS,KAAK,CAAC,EAC1D,MAAMge,EAAWxI,GAAmC,SAASxV,EAAS,KAAK,EAC3E,OACEsJ,OAAAyL,WAAA,CACE,UAAAzL,OAAC,WAAQ,UAAU,UACjB,UAAA3C,MAAC,OAAI,UAAU,SAAU,SAAAZ,EAAE,+BAAgC,CAAE,MAAO/F,EAAS,MAAO,EAAE,QACrF,OAAI,UAAU,aACZ,SAAAwV,GAAa,IAAKlF,GACjB3J,MAAC,OAEC,UAAU,QACV,UAAS3G,EAAS,QAAUsQ,EAC5B,QAAS,IAAMwK,EAAO,CAAE,MAAOxK,EAAI,EAEnC,SAAA3J,MAAC,OAAI,UAAU,KAAM,SAAA2J,CAAA,CAAG,GALnBA,CAAA,CAOR,EACH,EACAhH,OAAC,OAAI,UAAU,cAAc,MAAO,CAAE,UAAW,IAC/C,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,sBAAsB,EAAE,QAC7C,OAAI,UAAU,IAAK,SAAAA,EAAE,0BAA0B,EAAE,GACpD,EACAuD,OAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,IAAK,GAClC,UAAA3C,MAAC,SACC,UAAU,aACV,MAAO0K,EACP,SAAWpK,GAAMqK,EAASrK,EAAE,OAAO,KAAK,EACxC,YAAY,sBAEdN,MAAC,UACC,KAAK,SACL,UAAU,cACV,SAAU,CAAC0K,EAAM,QAAUA,EAAM,SAAWrR,EAAS,MACrD,QAAS,IAAM8a,EAAO,CAAE,MAAOzJ,EAAM,OAAQ,EAE5C,WAAE,qBAAqB,GAC1B,EACF,GACF,EACE2M,EAIE,KAHFrX,MAAC,OAAI,UAAU,IAAI,MAAO,CAAE,UAAW,GACpC,SAAAZ,EAAE,6BAA8B,CAAE,MAAO/F,EAAS,MAAO,EAC5D,CACE,EACN,EACAsJ,OAAC,WAAQ,UAAU,UACjB,UAAA3C,MAAC,OAAI,UAAU,SAAU,SAAAZ,EAAE,wBAAwB,EAAE,EACrDuD,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,0BAA0B,EAAE,QACjD,OAAI,UAAU,IAAK,SAAAA,EAAE,8BAA8B,EAAE,GACxD,QACC,OAAI,UAAU,WACZ,SAAAgY,GAAc,IAAK9W,GAClBN,MAAC,UACC,KAAK,SAEL,UAAS3G,EAAS,kBAAoBiH,EACtC,QAAS,IAAM6T,EAAO,CAAE,gBAAiB7T,EAAkB,EAE1D,SAAAA,CAAA,EAJIA,CAAA,CAMR,EACH,GACF,GACF,GACF,CAEJ,CAEA,SAAS8U,GAAQ,CACf,MAAA7b,EACA,QAAAC,EACA,MAAA8d,EACA,SAAAC,CACF,EAKG,CACD,KAAM,CAAC7M,EAAOC,CAAQ,EAAIlM,WAAS,EAAE,EAC/B+Y,EAAS,IAAM,CACnB,MAAMjX,EAAImK,EAAM,OACXnK,IACL+W,EAAM/W,CAAC,EACPoK,EAAS,EAAE,EACb,EACA,OACEhI,OAAAyL,WAAA,CACE,UAAAzL,OAAC,WAAQ,UAAU,UACjB,UAAAA,OAAC,OAAI,UAAU,SACZ,UAAAvD,EAAE,yBAA0B,CAAE,MAAO7F,EAAM,OAAQ,EACnDC,EACCwG,MAAC,QAAK,MAAO,CAAE,MAAO,gBAAiB,WAAY,EAAG,SAAU,IAC7D,SAAAZ,EAAE,qBAAqB,EAC1B,EAEAY,MAAC,QAAK,MAAO,CAAE,MAAO,eAAgB,WAAY,EAAG,SAAU,IAC5D,SAAAZ,EAAE,wBAAwB,EAC7B,GAEJ,EACC7F,EAAM,SAAW,EAChByG,MAAC,OACC,MAAO,CACL,QAAS,GACT,WAAY,cACZ,OAAQ,0BACR,aAAc,GACd,SAAU,GACV,MAAO,gBAGR,WAAE,mBAAmB,IAGxBzG,EAAM,IAAKG,GACTiJ,OAAC,OAAI,UAAU,QACb,UAAAA,OAAC,OAAI,UAAU,MACb,UAAA3C,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EACtB,SACC,OACC,UAAA9H,MAAC,OAAI,UAAU,KAAM,SAAAtG,EAAE,MAAQ,cAAc,EAC7CsG,MAAC,OAAI,UAAU,MAAO,WAAE,QAAQ,GAClC,EACAA,MAAC,QAAK,UAAU,OAAO,EACvBA,MAAC,UACC,KAAK,SACL,UAAU,YACV,MAAO,CAAE,MAAO,iBAChB,QAAS,IAAMuX,EAAS7d,EAAE,GAAG,EAE5B,WAAE,oBAAoB,GACzB,EACF,EACCA,EAAE,WACDsG,MAAC,OAAI,UAAU,OAAO,MAAO,CAAE,MAAO,iBACnC,SAAAZ,EAAE,sBAAuB,CAAE,MAAO1F,EAAE,WAAY,EACnD,EACE,OAvBsBA,EAAE,GAwB9B,CACD,GAEL,EACAiJ,OAAC,WAAQ,UAAU,UACjB,UAAA3C,MAAC,OAAI,UAAU,SAAU,SAAAZ,EAAE,wBAAwB,EAAE,EACrDuD,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,uBAAuB,EAAE,EAC/CY,MAAC,OAAI,UAAU,IAAI,wBAAyB,CAAE,OAAQZ,EAAE,wBAAwB,EAAE,CAAG,GACvF,EACAuD,OAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,IAAK,GAClC,UAAA3C,MAAC,SACC,UAAU,aACV,MAAO0K,EACP,SAAWpK,GAAMqK,EAASrK,EAAE,OAAO,KAAK,EACxC,YAAY,kCACZ,UAAYA,GAAM,CACZA,EAAE,MAAQ,SAASkX,EAAA,CACzB,IAEFxX,MAAC,UAAO,KAAK,SAAS,UAAU,cAAc,SAAU,CAAC0K,EAAM,OAAQ,QAAS8M,EAC7E,SAAApY,EAAE,iBAAiB,EACtB,GACF,GACF,GACF,GACF,CAEJ,CAEA,SAASiW,GAAW,CAClB,OAAAnB,EACA,eAAAuD,EACA,OAAAtD,CACF,EAIG,CACD,MAAMuD,EAAmB,CAACtO,EAAcnB,IAA2B,CACjEkM,EAAO,CAAE,eAAgB,CAAE,GAAGsD,EAAgB,CAACrO,CAAI,EAAGnB,CAAA,EAAS,CACjE,EACA,OACEtF,OAAC,WAAQ,UAAU,UACjB,UAAA3C,MAAC,OAAI,UAAU,SAAU,SAAAZ,EAAE,wBAAyB,CAAE,MAAO8U,EAAO,OAAQ,EAAE,EAC7EA,EAAO,SAAW,EACjBlU,MAAC,OACC,MAAO,CACL,QAAS,GACT,WAAY,cACZ,OAAQ,0BACR,aAAc,GACd,SAAU,GACV,MAAO,gBAGR,WAAE,sBAAsB,IAG3BkU,EAAO,IAAKxa,GACViJ,OAAC,OAAI,UAAU,QACb,UAAAA,OAAC,OAAI,UAAU,MACb,UAAA3C,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,IAAF,CAAM,KAAM,GAAI,EACnB,SACC,OACC,UAAA9H,MAAC,OAAI,UAAU,KACb,SAAA2C,OAAC,QACC,MAAO,CACL,WAAY,wBACZ,MAAO,iBAEV,cACGjJ,EAAE,QAER,EACAiJ,OAAC,OAAI,UAAU,MACZ,UAAAjJ,EAAE,MAAM,MAAIA,EAAE,MACdA,EAAE,MAAQ,MAAMA,EAAE,KAAK,GAAK,IAC/B,GACF,EACCA,EAAE,QAAU,WACXiJ,OAAC,UACC,UAAU,QACV,MAAO,CAAE,WAAY,OAAQ,SAAU,IACvC,MAAO8U,EAAe/d,EAAE,IAAI,GAAK,QACjC,SAAW4G,GACToX,EAAiBhe,EAAE,KAAM4G,EAAE,OAAO,KAAwB,EAE5D,MAAOlB,EAAE,4BAA4B,EAErC,UAAAY,MAAC,UAAO,MAAM,QAAS,SAAAZ,EAAE,6BAA6B,EAAE,QACvD,UAAO,MAAM,MAAO,SAAAA,EAAE,2BAA2B,EAAE,KAEpD,MACN,EACAY,MAAC,OAAI,UAAU,OAAQ,WAAE,YAAY,EACrCA,MAAC,OACC,MAAO,CACL,WAAY,wBACZ,SAAU,KACV,MAAO,iBACP,UAAW,GAGZ,SAAAtG,EAAE,MACL,GA9C0B,GAAGA,EAAE,KAAK,IAAIA,EAAE,IAAI,EA+ChD,CACD,GAEL,CAEJ,CAEA,SAAS4b,GAAW,CAClB,QAAAjb,EACA,OAAAiX,EACA,OAAAC,CACF,EAIG,CACD,OACE5O,OAAC,WAAQ,UAAU,UACjB,UAAA3C,MAAC,OAAI,UAAU,SAAU,SAAAZ,EAAE,wBAAwB,EAAE,EACpD/E,EAAQ,SAAW,EAClB2F,MAAC,OAAI,UAAU,aAAc,SAAAZ,EAAE,qBAAqB,EAAE,EAEtDuD,OAAC,OAAI,UAAU,iBACb,UAAA3C,MAAC,OAAI,UAAU,cACZ,SAAA3F,EAAQ,IAAKvC,GACZ6K,OAAC,UACC,KAAK,SACL,UAAU,cACV,cAAa2O,GAAQ,OAASxZ,EAAE,KAEhC,QAAS,IAAMyZ,EAAOzZ,EAAE,IAAI,EAE5B,UAAAkI,MAAC,QAAK,UAAU,cAAe,SAAAlI,EAAE,KAAK,QAAQ,IAAK,GAAG,EAAE,QACvD,QAAK,UAAU,cAAe,SAAAA,EAAE,aAAeA,EAAE,KAAK,EACvDkI,MAAC,QAAK,UAAU,cAAe,WAAE,KAAK,IALjClI,EAAE,KAOV,EACH,EACAkI,MAAC,OAAI,UAAU,gBACZ,WAASsR,EAAO,KAAOlS,EAAE,qBAAqB,EACjD,GACF,GAEJ,CAEJ,CAEA,SAASmW,GAAU,CACjB,SAAAlc,EACA,OAAA8a,CACF,EAGG,CACD,OACExR,OAAAyL,WAAA,CACE,UAAAzL,OAAC,WAAQ,UAAU,UACjB,UAAA3C,MAAC,OAAI,UAAU,SAAU,SAAAZ,EAAE,mBAAmB,EAAE,EAChDuD,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,kBAAkB,EAAE,QACzC,OAAI,UAAU,IAAK,SAAAA,EAAE,uBAAuB,EAAE,GACjD,EACAY,MAAC,OAAI,UAAU,WACX,UAAC,OAAQ,SAAU,OAAQ,MAAM,EAAY,IAAKlI,GAClDkI,MAAC,UACC,KAAK,SAEL,UAAS3G,EAAS,WAAavB,EAC/B,QAAS,IAAMqc,EAAO,CAAE,SAAUrc,EAAG,EAEpC,SAAAA,CAAA,EAJIA,CAAA,CAMR,EACH,GACF,GACF,EACA6K,OAAC,WAAQ,UAAU,UACjB,UAAA3C,MAAC,OAAI,UAAU,SAAU,SAAAZ,EAAE,kCAAkC,EAAE,EAC/DY,MAAC,OACC,MAAO,CACL,QAAS,GACT,WAAY,cACZ,OAAQ,0BACR,aAAc,GACd,SAAU,GACV,MAAO,gBAGR,WAAE,+BAA+B,GACpC,EACF,GACF,CAEJ,CAEA,SAASwV,GAAY,CACnB,QAAAhC,EACA,MAAAjE,EACA,SAAAkE,CACF,EAIG,CACD,MAAMkE,EAASlE,IAAa,MAAQ,IAAM,IACpCmE,EAAcnE,IAAa,MAAQlE,EAAM,aAAe,IAAMA,EAAM,aACpEzW,EAAcyW,EAAM,eAAiBA,EAAM,gBAC3CsI,EAAS/e,EAAc,EAAI,KAAK,MAAOyW,EAAM,eAAiBzW,EAAe,GAAG,EAAI,EAC1F,OACEkH,MAAAoO,WAAA,CACE,SAAAzL,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,YACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,uBAAuB,EAAE,QAC9C,OAAI,UAAU,OACZ,SAAAoU,EACG,GAAGA,EAAQ,WAAa,MAAQ,IAAM,GAAG,IAAIA,EAAQ,MAAM,QAAQ,CAAC,CAAC,GACrE,IACN,EACAxT,MAAC,OAAI,UAAU,MACZ,SAAAwT,GAAW,CAACA,EAAQ,YACjBpU,EAAE,qBAAqB,EACvBA,EAAE,2BAA2B,EACnC,GACF,EACAuD,OAAC,OAAI,UAAU,YACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,sBAAsB,EAAE,EAC9CuD,OAAC,OAAI,UAAU,IACZ,UAAAgV,EAAO,IAAEC,EAAY,QAAQ,CAAC,GACjC,EACAjV,OAAC,OAAI,UAAU,MAAM,oBAAQ4M,EAAM,kBAAkB,iBAAiB,MAAE,GAC1E,EACA5M,OAAC,OAAI,UAAU,YACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,uBAAuB,EAAE,EAC/CuD,OAAC,OAAI,UAAU,QAAS,UAAAkV,EAAO,KAAC,EAChClV,OAAC,OAAI,UAAU,MAAM,iBACd4M,EAAM,eAAe,iBAAiB,UAAQ,IAClDA,EAAM,gBAAgB,gBAAe,EACxC,GACF,GACF,EACF,CAEJ,CAEA,SAASkG,IAAgB,CACvB,MAAMxb,EAA8C,CAClD,CAAE,GAAImF,EAAE,0BAA0B,EAAG,KAAM,CAAC,MAAO,GAAG,GACtD,CAAE,GAAIA,EAAE,yBAAyB,EAAG,KAAM,CAAC,MAAO,GAAG,GACrD,CAAE,GAAIA,EAAE,2BAA2B,EAAG,KAAM,CAAC,MAAO,GAAG,GACvD,CAAE,GAAIA,EAAE,iCAAiC,EAAG,KAAM,CAAC,MAAO,GAAG,GAC7D,CAAE,GAAIA,EAAE,gCAAgC,EAAG,KAAM,CAAC,MAAO,GAAG,GAC5D,CAAE,GAAIA,EAAE,4BAA4B,EAAG,KAAM,CAAC,MAAO,KAAK,GAC1D,CAAE,GAAIA,EAAE,wBAAwB,EAAG,KAAM,CAAC,KAAK,GAC/C,CAAE,GAAIA,EAAE,2BAA2B,EAAG,KAAM,CAAC,MAAO,GAAG,EAAE,EAE3D,OACEY,MAAC,WAAQ,UAAU,UACjB,SAAAA,MAAC,OAAI,UAAU,WACZ,SAAA/F,EAAK,IAAI,CAACP,EAAGoJ,IACZ9C,MAAC8X,GAAA,CAAmB,GAAIpe,EAAE,GAAI,KAAMA,EAAE,MAArBoJ,CAA2B,CAC7C,EACH,EACF,CAEJ,CAEA,SAASgV,GAAW,CAAE,GAAAC,EAAI,KAAAnY,GAAwD,CAChF,OACE+C,OAAAyL,WAAA,CACE,UAAApO,MAAC,OAAI,UAAU,KAAM,SAAA+X,EAAG,QACvB,OAAI,UAAU,OACb,SAAA/X,MAACF,EAAA,CAAS,KAAAF,EAAY,EACxB,GACF,CAEJ,CC9pCA,SAASoY,GAAWte,EAAwB,CAC1C,GAAIA,EAAE,SAAWA,EAAE,QAAQ,OAAQ,OAAOA,EAAE,QAAQ,OACpD,MAAM5B,EAAI4B,EAAE,KAAK,MAAM,0DAA0D,EACjF,GAAI5B,EAAG,CACL,KAAM,GAAKmgB,EAAOC,EAAKC,EAAIC,EAAItI,CAAG,EAAIhY,EACtC,MAAO,GAAGsH,EAAE,4BAA6B,CACvC,MAAA6Y,EACA,IAAAC,EACA,KAAMC,EACN,OAAQC,CAAA,CACT,CAAC,GAAGtI,GAAOA,IAAQ,IAAM,OAAOA,CAAG,GAAK,EAAE,EAC7C,CACA,OAAOpW,EAAE,KAAK,QAAQ,YAAa,EAAE,EAAE,QAAQ,SAAU,GAAG,CAC9D,CAEA,SAAS2e,GAAS/O,EAAoB,CACpC,MAAMgP,EAAMhP,EAAK,IACjB,GAAIgP,EAAM,EAAG,OAAOlZ,EAAE,sBAAsB,EAC5C,GAAIkZ,EAAM,GAAI,OAAOlZ,EAAE,0BAA2B,CAAE,EAAG,KAAK,MAAMkZ,CAAG,EAAG,EACxE,MAAMC,EAAKD,EAAM,GACjB,GAAIC,EAAK,GAAI,OAAOnZ,EAAE,wBAAyB,CAAE,EAAG,KAAK,MAAMmZ,CAAE,EAAG,EACpE,MAAMC,EAAID,EAAK,GACf,OAAIC,EAAI,EAAUpZ,EAAE,uBAAwB,CAAE,EAAG,KAAK,MAAMoZ,CAAC,EAAG,EACzDpZ,EAAE,wBAAyB,CAAE,EAAG,KAAK,MAAMoZ,EAAI,CAAC,EAAG,CAC5D,CAEO,SAASC,GAAQ,CACtB,SAAAC,EACA,WAAAC,EACA,YAAAC,EACA,UAAAC,EACA,cAAAC,EACA,gBAAAC,EACA,eAAAC,EACA,YAAAC,EACA,eAAAC,EACA,YAAAC,CACF,EAYG,CACD5a,EAAA,EACA,KAAM,CAACqD,EAAOC,CAAQ,EAAIpD,WAAS,EAAE,EAC/B,CAAC2a,EAAeC,CAAgB,EAAI5a,WAA+B,IAAI,EACvEyD,EAAWN,EACb8W,EAAS,OAAQhf,GAAM,CACrB,MAAM0I,EAAIR,EAAM,cAChB,OACEoW,GAAWte,CAAC,EAAE,cAAc,SAAS0I,CAAC,GAAK1I,EAAE,KAAK,cAAc,SAAS0I,CAAC,CAE9E,CAAC,EACDsW,EAEJha,mBAAU,IAAM,CACd,GAAI,CAAC0a,EAAe,OACpB,MAAME,EAAehZ,GAAkB,CACtBA,EAAE,QACJ,QAAQ,yBAAyB,KAAoB,IAAI,CACxE,EACMD,EAASC,GAAqB,CAC9BA,EAAE,MAAQ,UAAU+Y,EAAiB,IAAI,CAC/C,EACA,cAAO,iBAAiB,YAAaC,CAAW,EAChD,OAAO,iBAAiB,UAAWjZ,CAAK,EACjC,IAAM,CACX,OAAO,oBAAoB,YAAaiZ,CAAW,EACnD,OAAO,oBAAoB,UAAWjZ,CAAK,CAC7C,CACF,EAAG,CAAC+Y,CAAa,CAAC,EAGhBzW,OAAC,SAAM,UAAU,UACf,UAAAA,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,UAAO,KAAK,SAAS,UAAU,UAAU,QAASkW,EACjD,UAAA7Y,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EAClB9H,MAAC,QAAM,SAAAZ,EAAE,sBAAsB,EAAE,QAChCU,EAAA,CAAS,KAAM,CAAC,MAAO,GAAG,EAAG,GAChC,EACAE,MAAC,UACC,KAAK,SACL,UAAU,WACV,MAAOZ,EAAE,6BAA6B,EACtC,QAAS8Z,EAET,SAAAlZ,MAAC8H,EAAE,QAAF,CAAU,KAAM,GAAI,GACvB,EACF,QAEC,OAAI,UAAU,aACb,SAAAnF,OAAC,OAAI,UAAU,QACb,UAAA3C,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EACpB9H,MAAC,SACC,YAAaZ,EAAE,6BAA6B,EAC5C,MAAOwC,EACP,SAAWtB,GAAMuB,EAASvB,EAAE,OAAO,KAAK,UAEzCR,EAAA,CAAS,KAAM,CAAC,MAAO,GAAG,EAAG,GAChC,EACF,QAEC,OAAI,UAAU,eACb,SAAA6C,OAAC,OAAI,UAAU,eACb,UAAAA,OAAC,OAAI,UAAU,QACb,UAAA3C,MAAC,QAAM,SAAAZ,EAAE,qBAAqB,EAAE,EAChCY,MAAC,QAAK,UAAU,QAAS,WAAS,OAAO,GAC3C,EACC0Y,EAAS,SAAW,EACnB1Y,MAAC,OACC,MAAO,CACL,QAAS,WACT,SAAU,GACV,MAAO,iBACP,WAAY,yBAGb,WAAE,yBAAyB,IAE5BkC,EAAS,SAAW,EACtBlC,MAAC,OACC,MAAO,CACL,QAAS,WACT,SAAU,GACV,MAAO,iBACP,WAAY,yBAGb,WAAE,wBAAwB,IAE3B,KACHkC,EAAS,IAAKxI,GAAM,CACnB,MAAMyG,EAASzG,EAAE,OAASif,EACpBY,EAAU7f,EAAE,OAASkf,EACrBY,EAAQ,KAAK,MAAM9f,EAAE,KAAK,EAC1B+f,EAAU,OAAO,SAASD,CAAK,EAAInB,GAAS,KAAK,MAAQmB,CAAK,EAAI9f,EAAE,MAC1E,OACEiJ,OAAC,OAEC,UAAU,eACV,cAAaxC,EACb,eAAcoZ,GAAW,OACzB,MAAOX,GAAe,CAACW,EAAU,CAAE,QAAS,GAAK,cAAe,QAAW,OAC3E,QAAS,IAAMT,EAAcpf,EAAE,IAAI,EACnC,KAAK,SACL,SAAU,EACV,MAAOA,EAAE,KACT,UAAY4G,GAAM,CACZA,EAAE,MAAQ,SAASwY,EAAcpf,EAAE,IAAI,CAC7C,EAEA,UAAAsG,MAAC,QACC,UAAU,QACV,MAAO,CACL,WAAYuZ,GAERpZ,EADA,gBAGE,uBACN,UAAWoZ,EAAU,0CAA4C,OACnE,GAEF5W,OAAC,OAAI,UAAU,OACb,UAAA3C,MAAC,QAAK,UAAU,QAAS,SAAAgY,GAAWte,CAAC,EAAE,EACvCsG,MAAC,QAAK,UAAU,OACb,SAAAuZ,EACCvZ,MAAC,QAAM,SAAAZ,EAAE,sBAAsB,EAAE,EAEjCuD,OAAAyL,WAAA,CACE,UAAApO,MAAC,QAAM,WAAE,4BAA6B,CAAE,MAAOtG,EAAE,aAAc,EAAE,EACjEsG,MAAC,QAAK,UAAU,MAAM,aAAC,EACvBA,MAAC,QAAM,SAAAyZ,CAAA,CAAQ,GACjB,EAEJ,GACF,EACAzZ,MAAC,UACC,KAAK,SACL,UAAU,aACV,MAAOZ,EAAE,4BAA4B,EACrC,aAAYA,EAAE,4BAA4B,EAC1C,QAAUkB,GAAM,CACdA,EAAE,kBACF,MAAMoZ,EAAOpZ,EAAE,cAAc,wBAC7B+Y,EAAiB,CACf,KAAM3f,EAAE,KACR,OAAQse,GAAWte,CAAC,EACpB,EAAGggB,EAAK,MACR,EAAGA,EAAK,OACT,CACH,EACA,UAAYpZ,GAAM,EACZA,EAAE,MAAQ,SAAWA,EAAE,MAAQ,QAAO,iBAC5C,EAEA,SAAAN,MAAC8H,EAAE,EAAF,CAAI,KAAM,GAAI,GACjB,GA1DKpO,EAAE,KA6Db,CAAC,GACH,EACF,EAEAiJ,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,MAAM,QAASsW,EAC5B,UAAAjZ,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EACtB,EACA9H,MAAC,QAAM,SAAAZ,EAAE,4BAA4B,EAAE,GACzC,EACAuD,OAAC,OAAI,UAAU,MAAM,QAASwW,EAC5B,UAAAnZ,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EACpB,EACA9H,MAAC,QAAM,SAAAZ,EAAE,oBAAoB,EAAE,GACjC,EACAuD,OAAC,OAAI,UAAU,MAAM,QAASqW,EAC5B,UAAAhZ,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,IAAF,CAAM,KAAM,GAAI,EACnB,EACA9H,MAAC,QAAM,SAAAZ,EAAE,uBAAuB,EAAE,EAClCY,MAAC,QAAK,UAAU,QACd,SAAAA,MAACF,EAAA,CAAS,KAAM,CAAC,MAAO,GAAG,EAAG,EAChC,GACF,GACF,EAECsZ,EACCpZ,MAAC2Z,GAAA,CACC,OAAQP,EACR,SAAU,IAAMC,EAAiB,IAAI,EACrC,UAAW,IAAM,CACfN,EAAgBK,EAAc,IAAI,EAClCC,EAAiB,IAAI,CACvB,IAEA,MACN,CAEJ,CAEA,SAASM,GAAqB,CAC5B,OAAAC,EACA,SAAAC,EACA,UAAAC,CACF,EAIG,CACD,MAAMC,EAAM/X,SAAuB,IAAI,EACjCgY,EAAYhY,SAA0B,IAAI,EAC1C,CAACiY,EAAKC,CAAM,EAAIzb,WAAwC,CAC5D,KAAMmb,EAAO,EACb,IAAKA,EAAO,EACb,EAEDO,yBAAgB,IAAM,CACpB,MAAM5W,EAAKwW,EAAI,QACf,GAAI,CAACxW,EAAI,OACT,MAAMmW,EAAOnW,EAAG,wBACV6W,EAAM,EACNC,EAAK,OAAO,WACZC,EAAK,OAAO,YAClB,IAAIC,EAAOX,EAAO,EACdY,EAAMZ,EAAO,EACbW,EAAOb,EAAK,MAAQU,EAAMC,IAAIE,EAAO,KAAK,IAAIH,EAAKC,EAAKX,EAAK,MAAQU,CAAG,GACxEI,EAAMd,EAAK,OAASU,EAAME,IAAIE,EAAM,KAAK,IAAIJ,EAAKE,EAAKZ,EAAK,OAASU,CAAG,IACxEG,IAASN,EAAI,MAAQO,IAAQP,EAAI,MAAKC,EAAO,CAAE,KAAAK,EAAM,IAAAC,EAAK,EAC9DR,EAAU,SAAS,OACrB,EAAG,CAACJ,EAAO,EAAGA,EAAO,EAAGK,EAAI,KAAMA,EAAI,GAAG,CAAC,EAGxCtX,OAAC,OACC,IAAAoX,EACA,UAAU,yBACV,KAAK,SACL,aAAW,OACX,MAAO,CAAE,KAAME,EAAI,KAAM,IAAKA,EAAI,KAElC,UAAAtX,OAAC,OAAI,UAAU,MACZ,UAAAvD,EAAE,4BAA4B,EAC/BY,MAAC,QAAK,UAAU,OAAQ,WAAO,OAAO,GACxC,EACA2C,OAAC,OAAI,UAAU,UACb,UAAA3C,MAAC,UAAO,IAAKga,EAAW,KAAK,SAAS,UAAU,SAAS,QAASH,EAC/D,SAAAza,EAAE,qBAAqB,EAC1B,SACC,UAAO,KAAK,SAAS,UAAU,UAAU,QAAS0a,EACjD,UAAA9Z,MAAC8H,EAAE,EAAF,CAAI,KAAM,GAAI,EACd1I,EAAE,qBAAqB,GAC1B,GACF,IAGN,CCxTA,MAAMqb,GAAc,wBAEb,SAASC,IAA4B,CAC1C,GAAI,CACF,OAAO,eAAe,QAAQD,EAAW,IAAM,GACjD,MAAQ,CACN,MAAO,EACT,CACF,CAEA,SAASE,IAAkB,CACzB,GAAI,CACF,eAAe,QAAQF,GAAa,GAAG,CACzC,MAAQ,CAER,CACF,CAEO,SAASG,GAAO,CAAE,OAAAC,GAAkC,CACzD,KAAM,CAACC,EAASC,CAAU,EAAItc,WAAS,EAAK,EACtCuc,EAAYhZ,SAAO6Y,CAAM,EAC/BG,EAAU,QAAUH,EAEpBnc,YAAU,IAAM,CACd,MAAMuc,EAAK,OAAO,WAAW,IAAMF,EAAW,EAAI,EAAG,IAAI,EACnDG,EAAK,OAAO,WAAW,IAAM,CACjCP,GAAA,EACAK,EAAU,SACZ,EAAG,IAAI,EACP,MAAO,IAAM,CACX,OAAO,aAAaC,CAAE,EACtB,OAAO,aAAaC,CAAE,CACxB,CACF,EAAG,EAAE,EAELxc,YAAU,IAAM,CACd,MAAMyc,EAAQ7a,GAAqB,CAC7BA,EAAE,MAAQ,UAAYA,EAAE,MAAQ,SAAWA,EAAE,MAAQ,MACzDqa,GAAA,EACAK,EAAU,UACZ,EACA,cAAO,iBAAiB,UAAWG,CAAI,EAChC,IAAM,OAAO,oBAAoB,UAAWA,CAAI,CACzD,EAAG,EAAE,EAEL,MAAMC,EAAY,IAAM,CACtBT,GAAA,EACAE,EAAA,CACF,EAEA,OACE7a,MAAC,OAAI,UAAU,SAAS,eAAc8a,EAAS,QAASM,EACtD,SAAAzY,OAAC,OAAI,UAAU,cACb,UAAA3C,MAAC,OAAI,UAAU,cAAc,EAC7BA,MAAC,OAAI,UAAU,cAAc,oBAAQ,QACpC,OAAI,UAAU,aAAc,SAAAZ,EAAE,oBAAoB,EAAE,EACrDuD,OAAC,OAAI,UAAU,cACb,UAAA3C,MAAC,SAAK,QACL,SAAK,QACL,SAAK,GACR,GACF,EACF,CAEJ,CC3DA,MAAMqb,GAAa,IAEnB,SAASC,GAAYC,EAAmB9H,EAAiC,CACvE,MAAMkE,EAASlE,IAAa,MAAQ,IAAM,IACpC+H,EAAS/H,IAAa,MAAQ8H,EAAYF,GAAaE,EAC7D,MAAO,GAAG5D,CAAM,IAAI6D,EAAO,QAAQ,CAAC,CAAC,EACvC,CAEA,SAASC,GAAW9c,EAAmB,CACrC,OAAIA,GAAK,IAAa,IAAIA,EAAI,KAAM,QAAQ,CAAC,CAAC,IACvC,GAAGA,CAAC,EACb,CAEO,SAAS+c,GAAU,CACxB,SAAAriB,EACA,QAAAma,EACA,MAAAjE,EACA,KAAAxE,EACA,MAAA4Q,EACA,SAAAlI,EACA,MAAArQ,EACA,WAAAsQ,EACA,KAAAjC,EACA,SAAAmK,EACA,aAAAC,EACA,gBAAAjI,EACA,iBAAAkI,EACA,eAAA9C,EACA,cAAA+C,CACF,EAgBG,CACD,MAAMjjB,EAAcyW,EAAM,eAAiBA,EAAM,gBAC3CyM,EAAcljB,EAAc,EAAI,KAAK,MAAOyW,EAAM,eAAiBzW,EAAe,GAAG,EAAI,EACzFmjB,EAAcxK,EAAK,OAAQnD,GAAMA,EAAE,OAAO,EAAE,OAC5C4N,EAAQZ,GAAY/L,EAAM,aAAckE,CAAQ,EAChD0I,EAAe3I,EACjB,GAAGA,EAAQ,WAAa,MAAQ,IAAM,GAAG,IAAIA,EAAQ,MAAM,QAAQ,CAAC,CAAC,GACrE,IACE4I,EAAaT,EAAgB5Q,EAAO,UAAY,SAA3B,MACrB,CAACsR,EAAWC,CAAY,EAAI7d,WAAS,EAAK,EAC1C8d,EAAcva,SAA8B,IAAI,EAChDwa,GAAiBxa,SAA+B,IAAI,EAE1DtD,mBAAU,IAAM,CACd,GAAI,CAAC2d,EAAW,OAChB,MAAMI,EAAiBvlB,GAAwB,CAC7C,MAAM0iB,EAAS1iB,EAAM,OACjBqlB,EAAY,SAAS,SAAS3C,CAAM,GAAK4C,GAAe,SAAS,SAAS5C,CAAM,GACpF0C,EAAa,EAAK,CACpB,EACA,cAAO,iBAAiB,cAAeG,CAAa,EAC7C,IAAM,OAAO,oBAAoB,cAAeA,CAAa,CACtE,EAAG,CAACJ,CAAS,CAAC,EAGZ1Z,OAAC,UAAO,UAAU,YAChB,UAAAA,OAAC,QAAK,UAAU,MAAM,MAAO,SAAStJ,GAAU,SAAW,kBAAkB,GAC3E,UAAA2G,MAAC,QACC,UAAWoc,IAAc,MAAQ,UAAY,KAC7C,MAAOA,IAAc,MAAQ,CAAE,WAAY,iBAAoB,SAEjEpc,MAAC,QAAM,SAAA3G,GAAU,SAAS,QAAQ,eAAgB,EAAE,GAAK,mBAAmB,EAC5E2G,MAAC,QAAK,UAAU,IAAK,SAAyCZ,EAAxCuc,EAAiC5Q,EAAS,iBAAsB,mBAAtD,mBAAgD,CAAwB,CAAE,GAC5G,SACC,QAAK,UAAU,MAAM,MAAO3L,EAAE,oBAAoB,EACjD,UAAAY,MAAC8H,EAAE,IAAF,CAAM,KAAM,GAAI,MAAO,CAAE,MAAO,iBAAmB,EACpD9H,MAAC,QAAM,SAAAZ,EAAE,iBAAiB,EAAE,EAC5BuD,OAAC,QAAK,UAAU,QAAS,UAAAqZ,EAAY,KAAC,GACxC,EACArZ,OAAC,QAAK,UAAU,MACd,UAAA3C,MAAC8H,EAAE,IAAF,CAAM,KAAM,GAAI,EACjB9H,MAAC,QAAM,SAAAZ,EAAE,kBAAkB,EAAE,QAC5B,QAAK,UAAU,IAAK,SAAAqc,GAAW3iB,CAAW,EAAE,GAC/C,EACA6J,OAAC,QAAK,UAAU,MACd,UAAA3C,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EAClB9H,MAAC,QAAM,SAAAZ,EAAE,oBAAoB,EAAE,EAC/BY,MAAC,QAAK,UAAU,OAAQ,SAAAkc,CAAA,CAAM,GAChC,EAEAlc,MAAC,QAAK,UAAU,OAAO,EAEvB2C,OAAC,QACC,UAAW,YAAYiZ,EAAW,SAAW,EAAE,GAC/C,QAASC,EACT,MAAOhc,GAAqBT,EAAE,mBAAmB,CAAC,EAElD,UAAAY,MAAC8H,EAAE,IAAF,CAAM,KAAM,GAAI,EACjB9H,MAAC,QAAM,SAAAZ,EAAE,gBAAgB,EAAE,QAC1B,QAAK,UAAW6c,EAAc,EAAI,QAAU,IAAM,SAAAA,CAAA,CAAY,KAGhE5iB,GAAU,aACTsJ,OAAC,QACC,UAAU,MACV,MAAOvD,EAAE,4BAA6B,CAAE,UAAW/F,EAAS,aAAc,EAC1E,MAAO0iB,EAAgB,CAAE,OAAQ,WAAc,OAC/C,QAAUzb,GAAM,CACd,GAAI,CAACyb,EAAe,OACpB,MAAM5hB,EAAKmG,EAAE,cAA8B,wBAC3Cyb,EAAc,CAAE,OAAQ,OAAO,YAAc5hB,EAAE,IAAM,EAAG,KAAMA,EAAE,KAAM,CACxE,EAEA,UAAA6F,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EACpB9H,MAAC,QAAK,UAAU,IAAK,SAAA3G,EAAS,aAAa,MAAM,OAAO,EAAE,OAAS,KAAK,KAExE,KACJsJ,OAAC,QACC,UAAU,MACV,MAAO,kBAAkBtJ,GAAU,iBAAmB,MAAM,GAC5D,QAAS2f,EAET,UAAAhZ,MAAC8H,EAAE,MAAF,CAAQ,KAAM,GAAI,MAAO,CAAE,MAAO,iBAAmB,QACrD,QAAK,UAAU,QAAS,SAAAzO,GAAU,OAAS,IAAI,QAC/C,QAAK,UAAU,IAAK,SAAAA,GAAU,iBAAmB,OAAO,KAE3DsJ,OAAC,QAAK,UAAU,MAAM,MAAOvD,EAAE,0BAA0B,EAAG,QAAS0c,EACnE,UAAA9b,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EAClB9H,MAAC,QAAM,SAAAZ,EAAE,mBAAmB,EAAE,EAC9BY,MAAC,QAAK,UAAU,OAAQ,SAAAmc,CAAA,CAAa,GACvC,EACAxZ,OAAC,QACC,IAAK6Z,GACL,UAAW,qBAAqBH,EAAY,SAAW,EAAE,GACzD,MAAOjd,EAAE,uBAAuB,EAChC,QAAS,IAAMkd,EAAc3f,GAAS,CAACA,CAAI,EAE1C,UAAAyG,IAAU2E,GAAM,KAAO/H,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EAAK9H,MAAC8H,EAAE,IAAF,CAAM,KAAM,GAAI,QAC/D,QAAK,UAAU,IACb,SAAA1I,EAAE,uBAAuBsU,EAAW,CAAC,EAAG,aAAa,GAAGA,EAAW,MAAM,CAAC,CAAC,EAAS,EACvF,KAED2I,EACC1Z,OAAC,OAAI,IAAK4Z,EAAa,UAAU,YAAY,KAAK,OAAO,aAAYnd,EAAE,qBAAqB,EAC1F,UAAAuD,OAAC,OAAI,UAAU,iBACb,UAAA3C,MAAC,OAAI,UAAU,KAAM,SAAAZ,EAAE,qBAAqB,EAAE,QAC7C,OAAI,UAAU,KAAM,SAAAA,EAAE,uBAAuB,EAAE,GAClD,QACC,OAAI,UAAU,iBACZ,SAAAiJ,GAAa,IAAKG,GACjB7F,OAAC,UAEC,KAAK,SACL,UAAU,iBACV,UAAS+Q,IAAelL,EACxB,aAAYA,EACZ,QAAS,IAAM,CACboL,EAAgBpL,CAAK,EACrB8T,EAAa,EAAK,CACpB,EAEA,UAAA3Z,OAAC,QAAK,UAAU,iBAAiB,cAAY,OAC3C,UAAA3C,MAAC,SAAK,QACL,SAAK,QACL,SAAK,GACR,EACA2C,OAAC,QAAK,UAAU,MACd,UAAA3C,MAAC,QAAK,UAAU,KACb,SAAAZ,EAAE,uBAAuBoJ,EAAM,CAAC,EAAG,aAAa,GAAGA,EAAM,MAAM,CAAC,CAAC,EAAS,EAC7E,EACAxI,MAAC,QAAK,UAAU,KACb,YAAcwI,CAAK,IAAMT,GAAM,KAC5B3I,EAAE,qBAAqB,EACvBA,EAAE,sBAAsB,EAC9B,GACF,EACCsU,IAAelL,EAAQxI,MAAC8H,EAAE,MAAF,CAAQ,KAAM,GAAI,EAAK,OAzB3CU,CAAA,CA2BR,EACH,GACF,EACE,MACN,CAEJ,CClMO,MAAMkU,GACX;AAAA;AAAA,EAEK,SAASC,GAAoBxjB,EAA0C,CAC5E,OAAO,OAAOA,GAAS,UAAYA,EAAK,WAAWujB,EAAyB,CAC9E,CAEO,SAASE,GAAsBzjB,EAAsB,CAC1D,OAAOA,EAAK,WAAWujB,EAAyB,EAC5CvjB,EAAK,MAAMujB,GAA0B,MAAM,EAC3CvjB,CACN,CCRO,SAAS0jB,GAAaC,EAAyB,CACpD,MAAMjZ,EAASiZ,EAAQ,OAAO,MAAM,KAAK,EAAE,OAAO,OAAO,EACzD,GAAIjZ,EAAO,SAAW,EAAG,MAAO,GAChC,GAAIA,EAAO,SAAW,EAAG,OAAOA,EAAO,CAAC,EACxC,MAAMkZ,EAAQlZ,EAAO,CAAC,EAsBtB,WArB+B,IAAI,CACjC,MACA,MACA,OACA,OACA,MACA,MACA,QACA,KACA,SACA,UACA,SACA,UACA,OACA,MACA,OACA,OACA,OACA,SACA,MACD,EACyB,IAAIkZ,CAAK,EAAI,GAAGA,CAAK,IAAIlZ,EAAO,CAAC,CAAC,GAAKkZ,CACnE,CCzBO,SAASC,GAAK,CACnB,KAAAC,EAAO,UACP,KAAAC,EACA,KAAAxO,EACA,KAAAtF,EACA,KAAA+T,EACA,YAAAC,EAAc,GACd,QAAAC,EAAU,GACV,SAAAzX,EACA,UAAA0X,CACF,EAYG,CACD,KAAM,CAAC3gB,EAAMyD,CAAO,EAAI3B,WAAS2e,CAAW,EAC5C,OACEza,OAAC,OAAI,UAAW0a,EAAU,kBAAoB,OAAQ,YAAWJ,EAAM,YAAWtgB,EAChF,UAAAgG,OAAC,UACC,KAAK,SACL,UAAU,YACV,QAAS,IAAMvC,EAAS,GAAM,CAAC,CAAC,EAChC,MAAO,CACL,MAAO,OACP,WAAY,OACZ,OAAQ,OACR,UAAW,OACX,KAAM,UACN,MAAO,WAGT,UAAAJ,MAAC,QAAK,UAAU,MAAO,SAAAkd,EAAK,EAC5Bld,MAAC,QAAK,UAAU,OAAQ,SAAA0O,EAAK,EAC5BtF,EAAOpJ,MAAC,QAAK,UAAU,OAAQ,WAAK,EAAU,KAC/CA,MAAC,QAAK,UAAU,OAAO,EACtBmd,EAAOnd,MAAC,QAAK,UAAU,OAAQ,WAAK,EAAU,KAC9Csd,EACDtd,MAAC,QAAK,UAAU,OACd,SAAAA,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EACpB,KAEDnL,EAAOqD,MAAC,OAAI,UAAU,YAAa,SAAA4F,EAAS,EAAS,MACxD,CAEJ,CAoBA,SAAS2X,GAAW,CAAE,MAAAC,EAAO,MAAAC,GAA0F,CACrH,OAAQD,EAAA,CACN,IAAK,UACH,OAAOxd,MAAC,QAAK,UAAU,YAAY,KAAK,MAAM,aAAYyd,EAAO,MAAOA,CAAA,CAAO,EACjF,IAAK,OACH,OAAOzd,MAAC8H,EAAE,MAAF,CAAQ,KAAM,GAAI,MAAO,CAAE,MAAO,kBAAoB,aAAY2V,CAAA,CAAO,EACnF,IAAK,SACH,OAAOzd,MAAC8H,EAAE,EAAF,CAAI,KAAM,GAAI,MAAO,CAAE,MAAO,iBAAmB,aAAY2V,CAAA,CAAO,EAC9E,IAAK,UACH,OAAOzd,MAAC,QAAK,UAAU,kBAAkB,KAAK,MAAM,aAAYyd,EAAO,MAAOA,CAAA,CAAO,EACvF,IAAK,UACH,OAAOzd,MAAC8H,EAAE,MAAF,CAAQ,KAAM,GAAI,MAAO,CAAE,MAAO,kBAAoB,aAAY2V,CAAA,CAAO,EAEvF,CA8CO,SAASC,GAAc,CAC5B,KAAAvkB,EACA,UAAAwkB,EACA,OAAA9Z,EACA,QAAA+Z,EACA,MAAAC,CACF,EAMG,CACD,OAAAtf,EAAA,EAEEyB,MAACgd,GAAA,CACC,KAAK,SACL,KAAMhd,MAAC8H,EAAE,MAAF,CAAQ,KAAM,GAAI,EACzB,KAAK,YACL,KAAM1I,EAAE,qBAAqB,EAC7B,KACEuD,OAAAyL,WAAA,CACG,UAAAwP,GAAW/Z,SACT,QACE,UAAA+Z,GAAW,GACXA,GAAW/Z,EAAS,MAAQ,GAC5BA,EAAS,GAAGA,EAAO,gBAAgB,KAAO,IAC7C,EACE,KACH8Z,EACC3d,MAACud,GAAA,CAAW,MAAM,UAAU,MAAOne,EAAE,iBAAiB,EAAG,QAExDme,GAAA,CAAW,MAAM,OAAO,MAAOne,EAAE,yBAAyB,EAAG,GAElE,EAEF,YAAaue,EACb,QAAO,GAEP,SAAAhb,OAAC,OAAI,UAAU,SACb,UAAA3C,MAAC,OAAI,UAAU,SACZ,SAAA7G,EAAK,MAAM,OAAO,EAAE,IAAI,CAAC2kB,EAAMhb,IAC9B9C,MAAC,KAEC,wBAAyB,CACvB,OAAQ8d,EACL,QAAQ,aAAc,4BAA4B,EAClD,QAAQ,mBAAoB,qBAAqB,EACtD,EALKhb,CAAA,CAOR,EACH,EACC+a,GAASha,IAAW,OACnBlB,OAAC,OAAI,UAAU,OACZ,UAAAkb,SACE,QACC,UAAA7d,MAAC,QAAK,UAAU,IAAK,SAAAZ,EAAE,gBAAgB,EAAE,EAAO,IAAEye,CAAA,EACpD,EACE,KACHha,IAAW,OACVlB,OAAC,QACC,UAAA3C,MAAC,QAAK,UAAU,IAAK,SAAAZ,EAAE,kBAAkB,EAAE,EAAO,IAAEyE,EAAO,gBAAe,EAC5E,EACE,MACN,EACE,MACN,GAGN,CAIO,SAASka,GAAU,CACxB,QAAAjB,EACA,OAAAkB,EACA,MAAAR,EACA,WAAAS,EACA,UAAAC,EACA,SAAAC,EACA,cAAAC,CACF,EAQG,CACD7f,EAAA,EACA,MAAM0e,EAAaO,IAAU,SAAW,SAAWA,IAAU,OAAS,UAAY,UAClF,OACExd,MAACgd,GAAA,CACC,KAAAC,EACA,KAAMjd,MAAC8H,EAAE,SAAF,CAAW,KAAM,GAAI,EAC5B,KAAK,QACL,KAAK,QACL,QAAO,GACP,KACEnF,OAAAyL,WAAA,CACG,UAAAoP,IAAU,QACTxd,MAACud,GAAA,CAAW,MAAM,UAAU,MAAOne,EAAE,qBAAqB,EAAG,EAC3Doe,IAAU,UACZxd,MAACud,IAAW,MAAM,UAAU,MAAOne,EAAE,oBAAoB,EAAG,EAC1Doe,IAAU,SACZxd,MAACud,IAAW,MAAM,SAAS,MAAOne,EAAE,cAAc,EAAG,QAEpDme,GAAA,CAAW,MAAM,OAAO,MAAOne,EAAE,YAAY,EAAG,GAEjDoe,IAAU,QAAUA,IAAU,WAAaS,EAC3Ctb,OAAC,QAAK,UAAU,WAAa,WAAAsb,EAAa,KAAM,QAAQ,CAAC,EAAE,KAAC,EAC1D,MACN,EAGF,SAAAtb,OAAC,OAAI,UAAU,QACb,UAAAA,OAAC,OAAI,UAAU,MACb,UAAA3C,MAAC,QAAK,UAAU,SAAS,aAAC,EAC1BA,MAAC,QAAK,UAAU,OAAQ,SAAA8c,CAAA,CAAQ,GAClC,EACCkB,EACChe,MAAC,OAAI,UAAU,MACZ,SAAAge,EAAO,MAAM;AAAA,CAAI,EAAE,IAAI,CAACK,EAAIvb,IACvBub,EAAG,WAAW,IAAI,GAAKA,EAAG,WAAW,GAAG,EAExCre,MAAC,OACC,SAAAA,MAAC,QAAK,UAAU,KAAM,SAAAqe,CAAA,CAAG,GADjBvb,CAEV,EAEAub,EAAG,WAAW,IAAI,GAAKA,EAAG,WAAW,GAAG,GAAK,SAAS,KAAKA,CAAE,EAE7Dre,MAAC,OACC,SAAAA,MAAC,QAAK,UAAU,MAAO,SAAAqe,CAAA,CAAG,GADlBvb,CAEV,EAEG9C,MAAC,OAAa,SAAAqe,CAAA,EAAJvb,CAAO,CACzB,EACH,EACE,KACH0a,IAAU,SAAWU,EACpBvb,OAAC,OAAI,UAAU,cACb,UAAAA,OAAC,OAAI,UAAU,MACb,UAAA3C,MAAC,KAAG,SAAAZ,EAAE,qBAAqB,EAAE,EAAI,MAAIA,EAAE,wBAAwB,GACjE,EACAuD,OAAC,OAAI,UAAU,UACZ,UAAAyb,EACCpe,MAAC,UAAO,KAAK,SAAS,UAAU,YAAY,QAASoe,EAClD,SAAAhf,EAAE,wBAAwB,EAC7B,EACE,KACH+e,SACE,UAAO,KAAK,SAAS,UAAU,MAAM,QAASA,EAC5C,UAAA/e,EAAE,mBAAmB,EAAE,UAAEU,EAAA,CAAS,KAAM,CAAC,MAAO,GAAG,EAAG,GACzD,EACE,YACH,UAAO,KAAK,SAAS,UAAU,cAAc,QAASoe,EACpD,UAAA9e,EAAE,gBAAgB,EAAE,UAAEU,EAAA,CAAS,KAAM,CAAC,MAAO,OAAO,EAAG,GAC1D,GACF,GACF,EACE,MACN,GAGN,CAIO,SAASwe,GAAe,CAAE,QAAAC,GAAgC,CAC/DhgB,EAAA,EACA,MAAMigB,EAAYD,EAAQ,OAC1B,OACEve,MAACgd,GAAA,CACC,KAAK,UACL,KAAMhd,MAAC8H,EAAE,QAAF,CAAU,KAAM,GAAI,EAC3B,KAAK,aACL,KAAM1I,EAAE,sBAAsB,EAC9B,KAAMY,MAAC,QAAM,SAAAZ,EAAE,uBAAwB,CAAE,MAAOof,EAAU,gBAAe,CAAG,EAAE,EAC9E,YAAa,GACb,QAAO,GAEP,SAAAxe,MAAC,OAAI,UAAU,kBACb,eAACkG,GAAA,CAAS,OAAQqY,EAAS,EAC7B,GAGN,CAIO,SAASE,GAAS,CACvB,KAAArV,EACA,KAAAvN,EACA,OAAAX,EACA,GAAAwjB,EACA,WAAAT,CACF,EAMG,CACD1f,EAAA,EACA,MAAMsT,EAAU3W,IAAW,OACrB+hB,EAAapL,EAAU,UAAY6M,IAAO,GAAQ,SAAW,UACnE,OACE1e,MAACgd,GAAA,CACC,KAAAC,EACA,KAAMjd,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EAC1B,KAAK,OACL,KAAAsB,EACA,YAAa,GACb,QAAO,GACP,KACEzG,OAAAyL,WAAA,CACG,UAAAyD,EACC7R,MAACud,GAAA,CAAW,MAAM,UAAU,MAAOne,EAAE,eAAe,EAAG,EACrDsf,IAAO,GACT1e,MAACud,GAAA,CAAW,MAAM,SAAS,MAAOne,EAAE,aAAa,EAAG,EAEpDY,MAACud,GAAA,CAAW,MAAM,OAAO,MAAOne,EAAE,YAAY,EAAG,EAElD,CAACyS,GAAWoM,IAAe,OAC1Btb,OAAC,QAAK,UAAU,WAAY,UAAAsb,EAAW,OAAG,EACxC,MACN,EAGF,SAAAtb,OAAC,OAAI,UAAU,YACZ,UAAA9G,EACC8G,OAAC,OAAI,UAAU,MACb,UAAA3C,MAAC,QAAK,UAAU,IAAI,gBAAI,QACvB,QAAK,UAAU,IACd,SAAAA,MAAC,QAAK,UAAU,MAAO,SAAAnE,EAAK,OAAS,IAAM,GAAGA,EAAK,MAAM,EAAG,GAAG,CAAC,IAAMA,EAAK,EAC7E,GACF,EACE,KACHX,IAAW,OACVyH,OAAC,OAAI,UAAU,MACb,UAAA3C,MAAC,QAAK,UAAU,IAAK,SAAeZ,EAAfsf,IAAO,GAAU,cAAmB,cAAN,CAAoB,CAAE,EACzE1e,MAAC,QAAK,UAAU,IACd,eAAC,QAAK,UAAW0e,IAAO,GAAQ,MAAQ,MACrC,WAAO,OAAS,KAAO,GAAGxjB,EAAO,MAAM,EAAG,IAAI,CAAC,IAAMA,CAAA,CACxD,EACF,GACF,EACE,MACN,GAGN,CAgWO,MAAMyjB,GAAgBxY,OAAK,SAAuB,CAAE,KAAAhN,GAA0B,CACnF,OACE6G,MAAC,OAAI,UAAU,WACb,eAACkG,GAAA,CAAS,OAAQ/M,EAAM,EAC1B,CAEJ,CAAC,ECvuBM,SAASylB,GAAa,CAC3B,KAAAlQ,EACA,KAAAuO,EAAO,OACP,MAAA4B,EACA,IAAAC,EACA,KAAAnjB,EACA,QAAAojB,EACA,KAAA5B,EACA,aAAA6B,EACA,eAAAC,EACA,cAAAC,EACA,UAAAC,EACA,YAAAC,EACA,WAAAC,CACF,EAcG,CACD,OAAA9gB,EAAA,EAEEoE,OAAC,OAAI,UAAU,WAAW,YAAWsa,EACnC,UAAAta,OAAC,OAAI,UAAU,UACb,UAAA3C,MAAC,QAAK,UAAU,SACd,SAAAA,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EACtB,SACC,OACC,UAAA9H,MAAC,OAAI,UAAU,UAAW,SAAA0O,EAAK,EAC/B1O,MAAC,OAAI,UAAU,WAAY,SAAA6e,EAAM,EAChCC,EAAM9e,MAAC,OAAI,UAAU,SAAU,WAAI,EAAS,MAC/C,GACF,EACCrE,EAAOqE,MAAC,OAAI,UAAU,UAAW,WAAK,EAAS,KAC/C+e,EAAU/e,MAAC,OAAI,UAAU,aAAc,WAAQ,EAAS,KACzD2C,OAAC,OAAI,UAAU,UACZ,UAAAwc,EACCnf,MAAC,UAAO,KAAK,SAAS,UAAU,cAAc,QAASmf,EACpD,SAAAH,GAAgB5f,EAAE,oBAAoB,EACzC,EACE,KACHggB,EACCpf,MAAC,UAAO,KAAK,SAAS,UAAU,YAAY,QAASof,EAClD,SAAAH,GAAkB7f,EAAE,mBAAmB,EAC1C,EACE,KACHigB,GAAcH,EACblf,MAAC,UAAO,KAAK,SAAS,UAAU,YAAY,QAASqf,EAClD,SAAAH,CAAA,CACH,EACE,KACJlf,MAAC,QAAK,UAAU,OAAO,EACtBmd,EAAOnd,MAAC,QAAK,UAAU,OAAQ,WAAK,EAAU,MACjD,GACF,CAEJ,CAYO,SAASsf,GAAS,CACvB,MAAAT,EACA,SAAAU,EACA,MAAAC,CACF,EAIG,CACDjhB,EAAA,EACA,MAAMwG,EAAOya,EAAM,OAAQC,GAAMA,EAAE,QAAU,MAAM,EAAE,OAC/CC,EAAMF,EAAM,OAAUza,EAAOya,EAAM,OAAU,IAAM,EACzD,OACE7c,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,KACb,UAAA3C,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EACpB,SACC,OACC,UAAA9H,MAAC,OAAI,UAAU,KAAM,SAAA6e,EAAM,EAC1BU,EAAWvf,MAAC,OAAI,UAAU,KAAM,WAAS,EAAS,MACrD,EACAA,MAAC,QAAK,UAAU,OAAO,EACvB2C,OAAC,QAAK,UAAU,KACb,UAAAoC,EAAK,IAAEya,EAAM,QAChB,EACAxf,MAAC,OAAI,UAAU,QACb,SAAAA,MAAC,QAAK,MAAO,CAAE,MAAO,GAAG0f,CAAG,KAAO,EACrC,GACF,EACA1f,MAAC,OAAI,UAAU,KACZ,WAAM,IAAK2f,GACVhd,OAAC,OAAI,UAAU,YAAuB,aAAYgd,EAAG,MACnD,UAAAhd,OAAC,QAAK,UAAU,KAAK,kBAAMgd,EAAG,GAAE,EAChC3f,MAAC,QAAK,UAAU,KAAK,EACrB2C,OAAC,OAAI,UAAU,IACZ,UAAAgd,EAAG,MACHA,EAAG,KAAO3f,MAAC,OAAI,UAAU,IAAK,SAAA2f,EAAG,KAAK,EAAS,MAClD,QACC,QAAK,UAAU,IAAK,SAAAA,EAAG,eAAiB,IAAI,IAPfA,EAAG,CAQnC,CACD,EACH,GACF,CAEJ,CCtHO,SAASC,GAAY,CAAE,MAAAnC,GAA4B,CACxD,OACE9a,OAAC,OAAI,UAAU,eACb,UAAA3C,MAAC,QAAM,SAAAyd,CAAA,CAAM,EACbzd,MAAC,QAAK,UAAU,OAAO,GACzB,CAEJ,CAEO,MAAM6f,GAAU1Z,OAAK,SAAiB,CAC3C,KAAAhN,EACA,KAAA2mB,EACA,MAAAC,CACF,EAIG,CACDxhB,EAAA,EACA,KAAM,CAACgJ,EAAQC,CAAS,EAAI/I,WAAS,EAAK,EACpCgJ,EAAS,SAAY,CACzB,GAAI,CACF,MAAM,UAAU,UAAU,UAAUtO,CAAI,EACxCqO,EAAU,EAAI,EACd,WAAW,IAAMA,EAAU,EAAK,EAAG,IAAI,CACzC,MAAQ,CAER,CACF,EACA,OACE7E,OAAC,OAAI,UAAU,WACb,UAAA3C,MAAC,OAAI,UAAU,SAAS,eAAG,EAC3B2C,OAAC,OAAI,UAAU,OACb,UAAAA,OAAC,OAAI,UAAU,MACb,UAAA3C,MAAC,QAAK,UAAU,OAAQ,SAAAZ,EAAE,YAAY,EAAE,EACvC2gB,SACE,QAAK,UAAU,aAAa,MAAO,WAAWA,EAAM,KAAK,GACxD,UAAA/f,MAAC8H,EAAE,IAAF,CAAM,KAAM,GAAI,EAAE,KAAGiY,EAAM,KAC3BA,EAAM,QAAU,WAAa/f,MAAC,QAAK,UAAU,MAAO,SAAAZ,EAAE,iBAAiB,EAAE,EAAU,MACtF,EACE,KACH0gB,EAAO9f,MAAC,QAAK,UAAU,OAAQ,WAAK,EAAU,MACjD,EACAA,MAAC,OAAI,UAAU,WAAY,SAAA7G,EAAK,EAChC6G,MAAC,OAAI,UAAU,cACb,SAAA2C,OAAC,UACC,KAAK,SACL,UAAW,YAAY4E,EAAS,OAAS,EAAE,GAC3C,QAASE,EACT,MAAOrI,EAAE,oBAAoB,EAE7B,UAAAY,MAAC0H,GAAA,CAAK,KAAM,GAAI,EACfH,EAASnI,EAAE,iBAAiB,EAAI,OACnC,CACF,GACF,GACF,CAEJ,CAAC,EAEY4gB,GAAe7Z,OAAK,SAAsB,CACrD,SAAA5K,EACA,QAAA0kB,EACA,MAAApC,EACA,KAAAiC,EACA,iBAAAI,EACA,gBAAAC,EACA,qBAAAC,EACA,gBAAAC,CACF,EASG,CACD,KAAM,CAAC9Y,EAAQC,CAAS,EAAI/I,WAAS,EAAK,EACpC6hB,EAAU/kB,EACb,OAAQ7B,GAAgDA,EAAE,OAAS,MAAM,EACzE,IAAKA,GAAMA,EAAE,IAAI,EACjB,KAAK;AAAA;AAAA,CAAM,EACR+N,EAAS,SAAY,CACzB,GAAI,CACF,MAAM,UAAU,UAAU,UAAU6Y,CAAO,EAC3C9Y,EAAU,EAAI,EACd,WAAW,IAAMA,EAAU,EAAK,EAAG,IAAI,CACzC,MAAQ,CAER,CACF,EACA,OACE7E,OAAC,OAAI,UAAU,gBACb,UAAA3C,MAAC,OAAI,UAAU,SAAS,cAAE,EAC1B2C,OAAC,OAAI,UAAU,OACb,UAAAA,OAAC,OAAI,UAAU,MACb,UAAA3C,MAAC,QAAK,UAAU,OAAO,oBAAQ,EAC9B6d,EAAQ7d,MAAC,QAAK,UAAU,QAAS,WAAM,EAAU,KACjD8f,EAAO9f,MAAC,QAAK,UAAU,OAAQ,WAAK,EAAU,MACjD,EACCzE,EAAS,IAAI,CAAC7B,EAAGoJ,IAAM,CACtB,GAAIpJ,EAAE,OAAS,OACb,OAAKA,EAAE,KAAK,OACRijB,GAAoBjjB,EAAE,IAAI,QACpB4kB,GAAA,CAAuB,QAAS1B,GAAsBljB,EAAE,IAAI,GAAxCoJ,CAA2C,EAElE9C,MAAC2e,GAAA,CAAsB,KAAMjlB,EAAE,MAAXoJ,CAAiB,EAJjB,KAM7B,GAAIpJ,EAAE,OAAS,YACb,OACEsG,MAAC0d,GAAA,CAEC,KAAMhkB,EAAE,KACR,UAAWumB,GAAWnd,IAAMvH,EAAS,OAAS,GAFzCuH,CAAA,EAOX,MAAMyd,GACH7mB,EAAE,OAAS,eAAiBA,EAAE,OAAS,mBAAqBA,EAAE,SAAW,OACtE2mB,EAAgB,KAAMhe,GAAMA,EAAE,UAAYme,GAAe9mB,EAAE,IAAI,CAAC,EAChE,OACN,GAAIA,EAAE,OAAS,eAAiBA,EAAE,OAAS,iBAAkB,CAC3D,MAAMuB,EAAMulB,GAAe9mB,EAAE,IAAI,GAAKA,EAAE,KAClC8jB,EACJ9jB,EAAE,SAAW,OACT6mB,EACE,QACA,UACF7mB,EAAE,KAAO,GACP,SACA,OACR,OACEsG,MAAC+d,GAAA,CAEC,QAAS9iB,EACT,OAAQvB,EAAE,OACV,MAAA8jB,EACA,WAAY9jB,EAAE,WACd,UAAW6mB,EAAiB,IAAML,EAAiBK,EAAe,EAAE,EAAI,OACxE,SAAUA,EAAiB,IAAMJ,EAAgBI,EAAe,EAAE,EAAI,OACtE,cACEA,EACI,IAAM,CACJH,EAAqBG,EAAe,GAAI1D,GAAa5hB,CAAG,CAAC,CAC3D,EACA,QAZD6H,CAAA,CAgBX,CACA,OACE9C,MAACye,GAAA,CAEC,KAAM/kB,EAAE,KACR,KAAMA,EAAE,KACR,OAAQA,EAAE,OACV,GAAIA,EAAE,GACN,WAAYA,EAAE,YALToJ,CAAA,CAQX,CAAC,EACAwd,EACCtgB,MAAC,OAAI,UAAU,cACb,SAAA2C,OAAC,UACC,KAAK,SACL,UAAW,YAAY4E,EAAS,OAAS,EAAE,GAC3C,QAASE,EACT,MAAOrI,EAAE,qBAAqB,EAE9B,UAAAY,MAAC0H,GAAA,CAAK,KAAM,GAAI,EACfH,EAASnI,EAAE,iBAAiB,EAAI,QAErC,EACE,MACN,GACF,CAEJ,CAAC,EAED,SAASohB,GAAe3kB,EAAkC,CACxD,GAAKA,EACL,GAAI,CACF,MAAM0E,EAAI,KAAK,MAAM1E,CAAI,EACzB,GAAI0E,GAAK,OAAOA,GAAM,UAAY,OAAOA,EAAE,SAAY,SAAU,OAAOA,EAAE,OAC5E,MAAQ,CAER,CAEF,CAEO,SAASkgB,GAAW,CACzB,KAAAC,EACA,UAAAC,CACF,EAGG,CACDpiB,EAAA,EACA,MAAMqiB,EAAQF,EAAK,MAAM,QAAU,EAC7B3b,EAAO2b,EAAK,iBAAiB,OAC7BhB,EAAO3a,EAAO6b,EAAS,IACvBvK,EAAUqK,EAAK,MAAM,KAAMhnB,GAAM,CAACgnB,EAAK,iBAAiB,SAAShnB,EAAE,EAAE,CAAC,EAC5E,OACEiJ,OAAC,OAAI,UAAU,cACb,UAAA3C,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EACpB,EACAnF,OAAC,OAAI,UAAU,OACb,UAAAA,OAAC,OAAI,UAAU,IACZ,UAAAvD,EAAE,qBAAsB,CAAE,KAAM,KAAK,IAAI2F,EAAO,EAAG6b,CAAK,EAAG,MAAAA,EAAO,EAClEvK,EAAU,MAAMA,EAAQ,KAAK,GAAK,IACrC,EACArW,MAAC,OAAI,UAAU,IAAK,WAAK,KAAK,GAChC,EACA2C,OAAC,OAAI,UAAU,OACb,UAAA3C,MAAC,OAAI,UAAU,aACb,SAAAA,MAAC,QAAK,MAAO,CAAE,MAAO,GAAG0f,CAAG,IAAI,CAAG,EACrC,EACCiB,EACC3gB,MAAC,UAAO,KAAK,SAAS,QAAS2gB,EAC5B,SAAAvhB,EAAE,iBAAiB,EACtB,EACE,MACN,GACF,CAEJ,CAuBO,SAASyhB,GAAiB,CAC/B,EAAA1hB,EACA,UAAA+e,EACA,SAAA4C,EACA,SAAAjH,CACF,EAKG,CACDtb,EAAA,EACA,MAAMwiB,EAAY5hB,EAAE,OAAO,QAAU,EAC/B2f,EAAMiC,EAAY,EAAI3hB,EAAE,uBAAwB,CAAE,MAAO2hB,CAAA,CAAW,EAAI,OAC9E,OACE/gB,MAAC4e,GAAA,CACC,KAAMxf,EAAE,6BAA6B,EACrC,KAAK,OACL,MAAOA,EAAE,kBAAkB,EAC3B,IAAA0f,EACA,KACEnc,OAAAyL,WAAA,CACG,UAAAjP,EAAE,QAAUa,MAAC,OAAI,MAAO,CAAE,aAAc,GAAM,SAAAb,EAAE,QAAQ,EAAS,KAClEa,MAAC,OAAI,MAAO,CAAE,WAAY,YAAe,WAAE,KAAK,GAClD,EAEF,KAAM,SAASb,EAAE,EAAE,GACnB,aAAcC,EAAE,gBAAgB,EAChC,eAAgBA,EAAE,eAAe,EACjC,cAAeA,EAAE,eAAe,EAChC,UAAW8e,EACX,YAAarE,EACb,WAAYiH,CAAA,EAGlB,CAEO,SAASE,GAAuB,CACrC,EAAA3e,EACA,WAAA4e,EACA,SAAAC,EACA,OAAAxP,CACF,EAKG,CACD,OAAAnT,EAAA,EAEEyB,MAAC4e,GAAA,CACC,KAAMxf,EAAE,uBAAuB,EAC/B,KAAK,QACL,MAAOiD,EAAE,OAASjD,EAAE,yBAA0B,CAAE,UAAWiD,EAAE,UAAW,MAAOA,EAAE,MAAO,EACxF,IAAKjD,EAAE,uBAAwB,CAAE,UAAWiD,EAAE,UAAW,MAAOA,EAAE,MAAO,EACzE,KACEM,OAAAyL,WAAA,CACE,UAAApO,MAAC,OAAI,MAAO,CAAE,WAAY,YAAe,WAAE,OAAO,EACjDqC,EAAE,MACDrC,MAAC,OAAI,MAAO,CAAE,UAAW,EAAG,SAAU,KAAM,MAAO,gBAAmB,SAAAqC,EAAE,MAAM,EAC5E,MACN,EAEF,KAAM,gBAAgBA,EAAE,MAAM,GAC9B,aAAcjD,EAAE,iBAAiB,EACjC,eAAgBA,EAAE,aAAa,EAC/B,cAAeA,EAAE,eAAe,EAChC,UAAW6hB,EACX,YAAavP,EACb,WAAYwP,CAAA,EAGlB,CAEO,SAASC,GAAqB,CACnC,EAAAhnB,EACA,SAAAinB,EACA,SAAAjD,CACF,EAIG,CACD,OAAA5f,EAAA,EAEEyB,MAAC4e,GAAA,CACC,KAAMxf,EAAE,yBAAyB,EACjC,KAAK,OACL,MAAOA,EAAE,oBAAoB,EAC7B,IAAKA,EAAE,mBAAoB,CAAE,EAAGjF,EAAE,eAAe,OAAQ,EACzD,KACEwI,OAAAyL,WAAA,CACE,UAAApO,MAAC,OAAI,MAAO,CAAE,aAAc,GAAM,WAAE,OAAO,EAC1C7F,EAAE,QACD6F,MAAC,OAAI,MAAO,CAAE,SAAU,KAAM,MAAO,eAAgB,aAAc,GAAM,SAAA7F,EAAE,QAAQ,EACjF,KACJ6F,MAAC,MAAG,MAAO,CAAE,OAAQ,EAAG,YAAa,IAClC,SAAA7F,EAAE,eAAe,IAAKT,UACpB,MAAc,MAAO,CAAE,SAAU,GAAI,aAAc,GACjD,UAAAA,EAAE,MACFA,EAAE,KACDiJ,OAAC,QACC,MAAO,CACL,WAAY,EACZ,SAAU,GACV,MACEjJ,EAAE,OAAS,OACP,kBACAA,EAAE,OAAS,MACT,mBACA,gBAEX,cACGA,EAAE,KAAK,OAET,OAjBGA,EAAE,EAkBX,CACD,EACH,GACF,EAEF,KAAM0F,EAAE,qBAAqB,EAC7B,aAAcA,EAAE,uBAAuB,EACvC,eAAgBA,EAAE,qBAAqB,EACvC,UAAWgiB,EACX,YAAajD,CAAA,EAGnB,CAEO,SAASkD,GAAoB,CAClC,EAAAhf,EACA,QAAAif,EACA,cAAAlD,EACA,OAAAmD,CACF,EAKG,CACDhjB,EAAA,EACA,MAAMijB,EAAenf,EAAE,OAAS,iBAC1BoD,EAASoX,GAAaxa,EAAE,OAAO,EACrC,OACErC,MAAC4e,GAAA,CACC,KAAMxf,EAAE,8BAA8B,EACtC,KAAK,OACL,MAAsBA,EAAfoiB,EAAiB,8BAAmC,mBAAN,EACrD,IAAKnf,EAAE,QAAQ,OAAS,GAAK,GAAGA,EAAE,QAAQ,MAAM,EAAG,EAAE,CAAC,IAAMA,EAAE,QAC9D,QACEM,OAAAyL,WAAA,CACE,UAAApO,MAAC,QAAK,MAAO,CAAE,MAAO,iBAAmB,aAAC,EAAO,IAAEqC,EAAE,SACvD,EAEF,KAAMjD,EAAE,oBAAqB,CAAE,KAAMiD,EAAE,KAAM,EAC7C,aAAcjD,EAAE,gBAAgB,EAChC,eAAgBA,EAAE,eAAe,EACjC,cAAeA,EAAE,qBAAsB,CAAE,OAAAqG,EAAQ,EACjD,UAAW6b,EACX,YAAaC,EACb,WAAY,IAAMnD,EAAc3Y,CAAM,GAG5C,CAEO,SAASgc,GAAuB,CACrC,EAAAtiB,EACA,QAAAmiB,EACA,cAAAlD,EACA,OAAAmD,CACF,EAYG,CACDhjB,EAAA,EACA,MAAMmjB,EAAUviB,EAAE,SAAW,QAC7B,OACEa,MAAC4e,GAAA,CACC,KAAMxf,EAAE,uBAAuB,EAC/B,KAAK,OACL,MAAiBA,EAAVsiB,EAAY,iCAAsC,+BAAN,EACnD,IAAKviB,EAAE,KACP,QACEwD,OAAAyL,WAAA,CACE,UAAAzL,OAAC,OAAK,UAAAxD,EAAE,SAAS,MAAIA,EAAE,MAAK,EAC5BwD,OAAC,OAAI,MAAO,CAAE,MAAO,eAAgB,UAAW,GAAK,wBACvCxD,EAAE,aAChB,GACF,EAEF,KAAMC,EAAE,oBAAqB,CAAE,KAAMD,EAAE,OAAQ,EAC/C,aAAwBC,EAAVsiB,EAAY,oBAAyB,kBAAN,EAC7C,eAAgBtiB,EAAE,eAAe,EACjC,cAAeA,EAAE,2BAA4B,CAAE,OAAQD,EAAE,YAAa,EACtE,UAAWmiB,EACX,YAAaC,EACb,WAAY,IAAMnD,EAAcjf,EAAE,WAAW,GAGnD,CAEO,SAASwiB,GAAmB,CACjC,EAAAtf,EACA,OAAAsM,EACA,SAAAkL,CACF,EAIG,CACD,OAAAtb,EAAA,EAEEyB,MAAC4e,GAAA,CACC,KAAMxf,EAAE,uBAAuB,EAC/B,KAAK,OACL,MAAOiD,EAAE,SACT,IAAKjD,EAAE,qBAAsB,CAAE,MAAOiD,EAAE,QAAQ,OAAQ,EACxD,KACErC,MAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,GAC1D,SAAAqC,EAAE,QAAQ,IAAKuf,GACd5hB,MAAC,UAEC,KAAK,SACL,UAAU,MACV,MAAO,CAAE,eAAgB,aAAc,UAAW,QAClD,QAAS,IAAM2O,EAAOiT,EAAE,EAAE,EAE1B,gBAAC,OACC,UAAA5hB,MAAC,OAAI,MAAO,CAAE,WAAY,KAAQ,WAAE,MAAM,EACzC4hB,EAAE,QACD5hB,MAAC,OAAI,MAAO,CAAE,SAAU,GAAI,MAAO,eAAgB,UAAW,GAC3D,SAAA4hB,EAAE,QACL,EACE,MACN,GAbKA,EAAE,GAeV,EACH,EAEF,aAAcxiB,EAAE,eAAe,EAC/B,UAAWya,CAAA,EAGjB,CAEO,SAASgI,GAAsBnB,EAAkC,CACtE,MAAM3b,EAAO,IAAI,IAAI2b,EAAK,gBAAgB,EAC1C,OAAOA,EAAK,MAAM,IAAI,CAAC,EAAG,KAAO,CAC/B,EAAG,OAAO,EAAI,CAAC,EACf,MAAO3b,EAAK,IAAI,EAAE,EAAE,EAAI,OAAS,IAAM2b,EAAK,iBAAiB,OAAS,UAAY,SAClF,MAAO,EAAE,MACT,KAAM,EAAE,OACR,cAAe,QACf,CACJ,CAEO,SAASoB,GAAmB,CAAE,KAAApB,GAA8B,CACjE,OAAAniB,EAAA,EAEEyB,MAACsf,GAAA,CACC,MAAOlgB,EAAE,mBAAmB,EAC5B,SAAUshB,EAAK,QACf,MAAOmB,GAAsBnB,CAAI,GAGvC,CClhBO,SAASqB,GAAW,CACzB,KAAAplB,EACA,QAAA+E,EACA,OAAAsgB,EACA,QAAA3L,EACA,OAAA4L,EACA,OAAAtT,EACA,SAAAuT,CACF,EAQG,CACD3jB,EAAA,EACA,KAAM,CAACqD,EAAOC,CAAQ,EAAIpD,WAAS,EAAE,EAC/BsD,EAAWC,SAAyB,IAAI,EAE9CtD,YAAU,IAAM,CACd,GAAI,CAAC/B,EAAM,OACXkF,EAAS,EAAE,EACX,MAAM8H,EAAK,OAAO,WAAW,IAAM5H,EAAS,SAAS,QAAS,EAAE,EAChE,MAAO,IAAM,OAAO,aAAa4H,CAAE,CACrC,EAAG,CAAChN,CAAI,CAAC,EAET,MAAM5C,EAAQoI,UAAQ,IAAM,CAC1B,MAAMzB,EAAOshB,EAAO,OAAS,EAAIA,EAAS3L,EAAU,CAACA,CAAO,EAAI,GAC1DjU,EAAIR,EAAM,OAAO,cACvB,OAAKQ,EACE1B,EAAK,OAAQvB,GAAMA,EAAE,cAAc,SAASiD,CAAC,CAAC,EADtC1B,CAEjB,EAAG,CAACshB,EAAQ3L,EAASzU,CAAK,CAAC,EAE3B,GAAI,CAACjF,EAAM,OAAO,KAElB,MAAM4d,EAAO0H,GAAQ,MAAQ,IACvBE,EACJF,GAAQ,SAAW,OACf,CAAE,OAAQA,EAAO,OAAQ,KAAA1H,CAAA,EACzB,CAAE,IAAK0H,GAAQ,KAAO,GAAI,KAAA1H,CAAA,EAEhC,aACG,OAAI,UAAU,UAAU,YAAa7Y,EACpC,SAAAiB,OAAC,OAAI,UAAU,SAAS,MAAOwf,EAAe,YAAc7hB,GAAMA,EAAE,kBAClE,UAAAqC,OAAC,OAAI,UAAU,UACb,UAAA3C,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EACpB9H,MAAC,QAAM,SAAAZ,EAAE,eAAe,EAAE,EAC1BY,MAAC,QACC,MAAO,CACL,WAAY,OACZ,WAAY,wBACZ,SAAU,GACV,MAAO,gBAGT,eAACF,EAAA,CAAS,KAAM,CAAC,MAAO,GAAG,EAAG,GAChC,EACF,EACAE,MAAC,SACC,IAAK+B,EACL,UAAU,YACV,YAAa3C,EAAE,2BAA2B,EAC1C,MAAOwC,EACP,SAAWtB,GAAMuB,EAASvB,EAAE,OAAO,KAAK,EACxC,UAAYA,GAAM,CACZA,EAAE,MAAQ,UACZA,EAAE,iBACFoB,EAAA,GACSpB,EAAE,MAAQ,SAAWvG,EAAM,CAAC,IACrCuG,EAAE,iBACFqO,EAAO5U,EAAM,CAAC,CAAC,EACf2H,EAAA,EAEJ,IAEFiB,OAAC,OAAI,UAAU,UACZ,UAAA5I,EAAM,SAAW,EAChBiG,MAAC,OACC,MAAO,CACL,QAAS,YACT,SAAU,KACV,MAAO,eACP,WAAY,yBAGb,WAAE,eAAe,IAElB,KACHjG,EAAM,IAAKoF,GAAM,CAChB,MAAMijB,EAAYjjB,IAAMkX,EAClBjN,EAAOjK,EAAE,MAAM,OAAO,EAAE,OAAO,OAAO,EAAE,OAASA,EACvD,OACEwD,OAAC,OAEC,UAAU,SACV,QAAS,IAAM,CACRyf,GAAWzT,EAAOxP,CAAC,EACxBuC,EAAA,CACF,EACA,MAAOvC,EAEP,UAAAa,MAAC,QAAK,UAAU,KACd,SAAAA,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EACtB,EACAnF,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAoJ,EAAK,EACzBpJ,MAAC,OAAI,UAAU,KAAM,SAAAb,CAAA,CAAE,GACzB,EACCijB,EACCpiB,MAAC,QAAK,UAAU,MACd,SAAAA,MAAC8H,EAAE,MAAF,CAAQ,KAAM,GAAI,EACrB,EACE,OAnBC3I,CAAA,CAsBX,CAAC,GACH,EACAa,MAAC,OAAI,UAAU,UACb,SAAA2C,OAAC,UACC,KAAK,SACL,UAAU,YACV,QAAS,IAAM,CACbuf,EAAA,EACAxgB,EAAA,CACF,EAEA,UAAA1B,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EAAE,IAAE1I,EAAE,gBAAgB,IAC1C,CACF,GACF,EACF,CAEJ,CC9HA,eAAeijB,GAAYznB,EAAqC,CAC9D,MAAM5C,EAAQ,SACX,cAAc,6BAA6B,GAC1C,aAAa,SAAS,GAAK,GACzBqH,EAAS,IAAI,gBACfzE,GAAMyE,EAAO,IAAI,OAAQzE,CAAI,EAC7B5C,GAASA,IAAU,sBAAsBqH,EAAO,IAAI,QAASrH,CAAK,EACtE,MAAMkB,EAAM,MAAM,MAAM,eAAemG,EAAO,UAAU,EAAE,EAC1D,GAAI,CAACnG,EAAI,GAAI,CACX,MAAMC,EAAO,MAAMD,EAAI,OACvB,MAAM,IAAI,MAAMC,GAAQ,kBAAkBD,EAAI,MAAM,GAAG,CACzD,CACA,OAAQ,MAAMA,EAAI,MACpB,CAEO,SAASopB,GAAkB,CAChC,KAAA3lB,EACA,YAAA4lB,EACA,SAAA1I,EACA,UAAAC,CACF,EAKG,CACDvb,EAAA,EACA,KAAM,CAACikB,EAAOC,CAAQ,EAAIhkB,WAAiB8jB,GAAe,EAAE,EACtD,CAACG,EAAQC,CAAS,EAAIlkB,WAA8B,IAAI,EACxD,CAAC0Q,EAAOyT,CAAQ,EAAInkB,WAAiB,EAAE,EACvC,CAAC8a,EAASsJ,CAAU,EAAIpkB,WAAS,EAAK,EACtCqkB,EAAY9gB,SAAO,EAAK,EAExB+gB,EAAWC,cAAY,MAAOpoB,GAAiB,CACnDioB,EAAW,EAAI,EACfD,EAAS,EAAE,EACX,GAAI,CACF,MAAM1nB,EAAS,MAAMmnB,GAAYznB,CAAI,EACrC+nB,EAAUznB,CAAM,EAChBunB,EAASvnB,EAAO,IAAI,CACtB,OAAS5C,EAAK,CACZsqB,EAAStqB,aAAe,MAAQA,EAAI,QAAU,OAAOA,CAAG,CAAC,CAC3D,SACEuqB,EAAW,EAAK,CAClB,CACF,EAAG,EAAE,EAYL,GAVAnkB,YAAU,IAAM,CACd,GAAI,CAAC/B,EAAM,CACTmmB,EAAU,QAAU,GACpB,MACF,CACIA,EAAU,UACdA,EAAU,QAAU,GACfC,EAASR,GAAe,EAAE,EACjC,EAAG,CAAC5lB,EAAM4lB,EAAaQ,CAAQ,CAAC,EAE5B,CAACpmB,EAAM,OAAO,KAElB,MAAMsmB,EAAeT,EAAM,OACrBU,EAAaD,EAAa,OAAS,GAAK,CAAC1J,EACzC4J,EAAgBT,IAAW,MAAQO,IAAiBP,EAAO,KAE3DU,EAAgB,IAAM,CACrBF,GACLpJ,EAAUmJ,CAAY,CACxB,EAEMI,EAAkB/iB,GAA6C,CAC/DA,EAAE,MAAQ,UACZA,EAAE,iBACFuZ,EAAA,GACSvZ,EAAE,MAAQ,UACnBA,EAAE,iBACE6iB,EACFC,EAAA,EAEKL,EAASE,CAAY,EAGhC,EAEA,OACEjjB,MAAC,OAAI,UAAU,gBAAgB,YAAa6Z,EAC1C,SAAAlX,OAAC,OACC,UAAU,gBACV,YAAcrC,GAAMA,EAAE,kBAEtB,UAAAqC,OAAC,OAAI,UAAU,qBACb,UAAA3C,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EACpB9H,MAAC,QAAM,SAAAZ,EAAE,eAAe,EAAE,EAC1BY,MAAC,UACC,KAAK,SACL,UAAU,YACV,QAAS6Z,EACT,MAAOza,EAAE,gBAAgB,EAEzB,SAAAY,MAAC8H,EAAE,EAAF,CAAI,KAAM,GAAI,GACjB,EACF,EACAnF,OAAC,OAAI,UAAU,wBACb,UAAA3C,MAAC,SACC,UAAS,GACT,UAAU,qBACV,MAAOwiB,EACP,YAAapjB,EAAE,yBAAyB,EACxC,SAAWkB,GAAMmiB,EAASniB,EAAE,OAAO,KAAK,EACxC,UAAW+iB,EACX,WAAY,KAEdrjB,MAAC,UACC,KAAK,SACL,UAAU,YACV,QAAS,IAAM,KAAK+iB,EAASE,CAAY,EACzC,SAAU1J,GAAW0J,EAAa,SAAW,EAC7C,MAAO7jB,EAAE,eAAe,EAEvB,WAAE,YAAY,GACjB,EACF,EACC+P,EAAQnP,MAAC,OAAI,UAAU,sBAAuB,WAAM,EAAS,KAC9D2C,OAAC,OAAI,UAAU,qBACZ,UAAA+f,GAAQ,OACP/f,OAAC,OACC,UAAU,uBACV,QAAS,IAAM,KAAKogB,EAASL,EAAO,MAAO,EAC3C,KAAK,SACL,SAAU,EACV,UAAYpiB,GAAM,EACZA,EAAE,MAAQ,SAAWA,EAAE,MAAQ,MAAUyiB,EAASL,EAAO,MAAO,CACtE,EAEA,UAAA1iB,MAAC,QAAK,UAAU,KAAK,aAAC,EACtBA,MAAC,QAAK,cAAE,KAER,KACH0iB,GAAQ,QAAQ,SAAW,GAAK,CAACnJ,EAChCvZ,MAAC,OAAI,UAAU,sBAAuB,SAAAZ,EAAE,kBAAkB,EAAE,EAC1D,KACHsjB,GAAQ,QAAQ,IAAKpiB,GACpBqC,OAAC,OAEC,UAAU,oBACV,QAAS,IAAM,KAAKogB,EAASziB,EAAE,IAAI,EACnC,cAAe,IAAMwZ,EAAUxZ,EAAE,IAAI,EACrC,KAAK,SACL,SAAU,EACV,MAAOA,EAAE,KACT,UAAY1I,GAAO,CACbA,EAAG,MAAQ,SAAcmrB,EAASziB,EAAE,IAAI,CAC9C,EAEA,UAAAN,MAAC,QAAK,UAAU,KAAK,SAAAA,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EAAE,EAC3C9H,MAAC,QAAK,UAAU,IAAK,WAAE,KAAK,IAZvBM,EAAE,KAcV,EACAiZ,QAAW,OAAI,UAAU,sBAAuB,SAAAna,EAAE,iBAAiB,EAAE,EAAS,MACjF,EACAuD,OAAC,OAAI,UAAU,qBACb,UAAA3C,MAAC,UAAO,KAAK,SAAS,UAAU,YAAY,QAAS6Z,EAClD,SAAAza,EAAE,gBAAgB,EACrB,EACAY,MAAC,UACC,KAAK,SACL,UAAU,cACV,QAASojB,EACT,SAAU,CAACF,EAEV,WAAE,kBAAkB,GACvB,EACF,KAEJ,CAEJ,CC3LA,MAAMI,GAAgB,GAIf,SAASC,GACdC,EACAC,EACA1Y,EAEA2Y,EACA,CACA,KAAM,CAACC,EAAgBC,CAAiB,EAAInlB,WAAS,EAAK,EACpDolB,EAAc7hB,SAAO,EAAI,EACzB8hB,EAAa9hB,SAAO+I,CAAI,EACxBgZ,EAAW/hB,SAAe,CAAC,EAE3BgiB,EAAahB,cAAY,IAAM,CACnC,MAAMzf,EAAKigB,EAAa,QACxB,OAAKjgB,EACEA,EAAG,UAAYA,EAAG,cAAgBA,EAAG,aAAe+f,GAD3C,EAElB,EAAG,CAACE,CAAY,CAAC,EAEXS,EAAoBjB,cAAY,IAAM,CAC1C,MAAMzf,EAAKigB,EAAa,QACnBjgB,GACLqgB,EACE,CAACC,EAAY,SAAWtgB,EAAG,aAAeA,EAAG,aAAe+f,EAAA,CAEhE,EAAG,CAACE,CAAY,CAAC,EAEXU,EAAiBlB,cACrB,CAACmB,EAAS,KAAS,CACjB,MAAM5gB,EAAKigB,EAAa,QACnBjgB,IACLsgB,EAAY,QAAU,GACtBD,EAAkB,EAAK,EACvBrgB,EAAG,SAAS,CACV,IAAKA,EAAG,aACR,SAAU4gB,EAAS,SAAW,UAC/B,EACH,EACA,CAACX,CAAY,GAMf9kB,mBAAU,IAAM,CACd,MAAM6E,EAAKigB,EAAa,QACxB,GAAI,CAACjgB,EAAI,OAGT,IAAI6gB,EAAe,EACnB,MAAMC,EAAgB,IAAM,CACtBD,wBAAmCA,CAAY,EACnDA,EAAe,sBAAsB,IAAM,CACzCA,EAAe,EACfP,EAAY,QAAUG,EAAA,EACtBC,EAAA,CACF,CAAC,CACH,EAEA,OAAA1gB,EAAG,iBAAiB,QAAS8gB,EAAe,CAAE,QAAS,GAAM,EAC7D9gB,EAAG,iBAAiB,YAAa8gB,EAAe,CAAE,QAAS,GAAM,EACjE9gB,EAAG,iBAAiB,UAAW8gB,CAAa,EAI5C9gB,EAAG,iBAAiB,cAAe8gB,CAAa,EAEzC,IAAM,CACPD,wBAAmCA,CAAY,EACnD7gB,EAAG,oBAAoB,QAAS8gB,CAAa,EAC7C9gB,EAAG,oBAAoB,YAAa8gB,CAAa,EACjD9gB,EAAG,oBAAoB,UAAW8gB,CAAa,EAC/C9gB,EAAG,oBAAoB,cAAe8gB,CAAa,CACrD,CACF,EAAG,CAACb,EAAcQ,EAAYC,CAAiB,CAAC,EAIhDvlB,YAAU,IAAM,CACVolB,EAAW,UAAY/Y,GACzBmZ,EAAe,EAAI,EAErBJ,EAAW,QAAU/Y,CACvB,EAAG,CAACA,EAAMmZ,CAAc,CAAC,EAIzBxlB,YAAU,IAAM,CACd,MAAM4hB,EAAUmD,EAAW,QAC3B,GAAI,CAACnD,EAAS,OAEd,MAAMgE,EAAK,IAAI,eAAe,IAAM,CAC9BP,EAAS,SAAS,qBAAqBA,EAAS,OAAO,EAC3DA,EAAS,QAAU,sBAAsB,IAAM,CAC7CA,EAAS,QAAU,EACnB,MAAMxgB,EAAKigB,EAAa,QACnBjgB,IACDsgB,EAAY,QACdtgB,EAAG,SAAS,CAAE,IAAKA,EAAG,aAAc,SAAU,UAAW,EAEzD0gB,EAAA,EAEJ,CAAC,CACH,CAAC,EAED,OAAAK,EAAG,QAAQhE,CAAO,EACX,IAAM,CACXgE,EAAG,aACCP,EAAS,UACX,qBAAqBA,EAAS,OAAO,EACrCA,EAAS,QAAU,EAEvB,CACF,EAAG,CAACP,EAAcC,EAAYQ,CAAiB,CAAC,EAIhDvlB,YAAU,IAAM,CACd,MAAM6E,EAAKigB,EAAa,QACxB,GAAI,CAACjgB,EAAI,OACT,MAAMoG,EAAK,WAAW,IAAM,CAC1B,MAAM4a,EAAUb,OAA2B,KACvCa,GAAW,MAAQA,EAAUjB,IAG/BO,EAAY,QAAU,GACtBtgB,EAAG,UAAYghB,EACfN,EAAA,IAEAJ,EAAY,QAAU,GACtBD,EAAkB,EAAK,EACvBrgB,EAAG,SAAS,CAAE,IAAKA,EAAG,aAAc,SAAU,UAAW,EAE7D,EAAG,EAAE,EACL,MAAO,IAAM,aAAaoG,CAAE,CAC9B,EAAG,CAAC6Z,EAAcE,EAAqBO,CAAiB,CAAC,EAElD,CAAE,eAAAN,EAAgB,eAAAO,CAAA,CAC3B,CC7IA,MAAMM,GACJ,sGAEF,SAASC,IAAqB,CAC5B,MAAO,CACL,YAAa,MACb,eAAgB,MAChB,WAAY,GAEhB,CAEA,SAASjlB,IAAgB,CACvB,OAAI,OAAO,SAAa,IAAoB,GACrC,SAAS,gBAAgB,QAAQ,WAAa,OACvD,CAEA,SAASklB,GAAqBC,EAAkB,CAE9C,GADI,EAAEA,aAAmB,cAEvB,EAAEA,aAAmB,mBACrB,EAAEA,aAAmB,sBACrB,CAACA,EAAQ,kBAET,OAGF,MAAMC,EAAQH,GAAA,EACdE,EAAQ,aAAa,cAAeC,EAAM,WAAW,EACrDD,EAAQ,aAAa,iBAAkBC,EAAM,cAAc,EAC3DD,EAAQ,aAAa,aAAc,OAAOC,EAAM,UAAU,CAAC,EAC3DD,EAAQ,WAAaC,EAAM,UAC7B,CAEA,SAASC,GAAYC,EAAkB,CACjCA,aAAgB,SAClBJ,GAAqBI,CAAI,EAE3BA,EAAK,iBAAiBN,EAAmB,EAAE,QAAQE,EAAoB,CACzE,CAEO,SAASK,IAAuB,CACrCrmB,YAAU,IAAM,CACd,GAAI,OAAO,SAAa,KAAe,CAACc,KAAiB,OAEzD,MAAMslB,EAAO,SAAS,KACtB,GAAI,CAACA,EAAM,OAEXD,GAAYC,CAAI,EAEhB,MAAME,EAAiB9tB,GAAsB,CACvCA,EAAM,kBAAkB,SAC1BwtB,GAAqBxtB,EAAM,MAAM,CAErC,EAEM+tB,EAAW,IAAI,iBAAkBC,GAAc,CACnD,UAAWC,KAAYD,EACrBC,EAAS,WAAW,QAAS7d,GAAS,CAChCA,aAAgB,SAClBud,GAAYvd,CAAI,CAEpB,CAAC,CAEL,CAAC,EAED,gBAAS,iBAAiB,UAAW0d,EAAe,EAAI,EACxDC,EAAS,QAAQH,EAAM,CAAE,UAAW,GAAM,QAAS,GAAM,EAElD,IAAM,CACX,SAAS,oBAAoB,UAAWE,EAAe,EAAI,EAC3DC,EAAS,YACX,CACF,EAAG,EAAE,CACP,CCkNA,SAASG,GAAkBrF,EAA0B,CACnD,MAAM7lB,EACJ6lB,EAAM,QAAU,UACZ3gB,EAAE,yBAAyB,EAC3B2gB,EAAM,QAAU,SACd3gB,EAAE,wBAAwB,EAC1BA,EAAE,yBAAyB,EAC7BimB,EACJtF,EAAM,QAAU,WACZ3gB,EAAE,0BAA0B,EAC5BA,EAAE,wBAAwB,EAChC,OAAOA,EAAE,oBAAqB,CAAE,MAAAlF,EAAO,MAAAmrB,EAAO,CAChD,CAEA,SAASC,GAAgBhqB,EAAiC,CAKxD,OAJiBA,EAAS,OAAO,CAACiqB,EAAKztB,IACjCA,EAAE,OAAS,QAAUA,EAAE,OAAS,YAAoB,KAAK,IAAIytB,EAAKztB,EAAE,IAAI,EACrEytB,EACN,CAAC,EACc,CACpB,CAEA,SAASC,GAAOhI,EAAciI,EAAuB,CACnD,OAAQA,EAAO,GACb,IAAK,YACH,MAAO,CACL,GAAGjI,EACH,KAAM,GACN,SAAU,CACR,GAAGA,EAAM,SACT,CAAE,KAAM,OAAQ,KAAMiI,EAAO,KAAM,SAAUA,EAAO,SAAU,KAAMH,GAAgB9H,EAAM,QAAQ,EAAE,CACtG,EAGJ,IAAK,cAAe,CAClB,MAAMkI,EAAWD,EAAO,KAAO,IAAIA,EAAO,IAAI,GAAK,GACnD,MAAO,CACL,GAAGjI,EACH,KAAM,GACN,YAAaiI,EAAO,MACpB,SAAU,CACR,GAAGjI,EAAM,SACT,CACE,KAAM,OACN,KAAM,IAAIiI,EAAO,MAAM,IAAI,GAAGC,CAAQ,GACtC,SAAUD,EAAO,SACjB,KAAMH,GAAgB9H,EAAM,QAAQ,EACpC,MAAOiI,EAAO,MAChB,CACF,CAEJ,CACA,IAAK,WACH,MAAO,CACL,GAAGjI,EACH,MAAO,GACP,KAAM,GACN,YAAa,KACb,YAAa,GACb,SAAU,CACR,GAAGA,EAAM,SACT,CAAE,KAAM,QAAS,QAAS,yBAAyBiI,EAAO,MAAQ,GAAG,IAAI,CAC3E,EAEJ,IAAK,WACH,OAAOE,GAAcnI,EAAOiI,EAAO,KAAK,EAC1C,IAAK,cAAe,CAClB,MAAMG,EAA8B,GACpC,UAAWnX,KAAQgX,EAAO,MAAO,CAC/B,MAAMjgB,EAAOogB,EAAUA,EAAU,OAAS,CAAC,EACvCpgB,GAAQA,EAAK,OAASiJ,EAAK,MAAQjJ,EAAK,UAAYiJ,EAAK,QAC3DjJ,EAAK,MAAQiJ,EAAK,KAElBmX,EAAU,KAAK,CAAE,GAAGnX,EAAM,CAE9B,CACA,MAAO,CACL,GAAG+O,EACH,SAAUA,EAAM,SAAS,IAAK1lB,GAAM,CAClC,GAAIA,EAAE,OAAS,YAAa,OAAOA,EACnC,MAAM+tB,EAAWD,EAAU,OAAQ7X,GAAOA,EAAG,OAASjW,EAAE,IAAI,EAC5D,GAAI+tB,EAAS,SAAW,EAAG,OAAO/tB,EAClC,IAAIyD,EAAWzD,EAAE,SACjB,UAAWiW,KAAM8X,EACftqB,EAAWuqB,GACTvqB,EACAwS,EAAG,UAAY,UAAY,OAAS,YACpCA,EAAG,MAGP,MAAO,CAAE,GAAGjW,EAAG,SAAAyD,CAAA,CACjB,CAAC,EAEL,CACA,IAAK,QACH,MAAO,CACL,GAAGiiB,EACH,KAAM,GACN,eAAgB,OAChB,SAAU,GACV,gBAAiB,GACjB,kBAAmB,GACnB,eAAgB,GAChB,aAAc,GACd,mBAAoB,GACpB,iBAAkB,GAClB,WAAY,KACZ,MAAOuI,GAAA,EACP,aAAc,GACd,YAAa,KACb,YAAa,GACb,WAAY,GAEhB,IAAK,kBACH,MAAO,CACL,GAAGvI,EACH,gBAAiBA,EAAM,gBAAgB,OAAQnb,GAAMA,EAAE,KAAOojB,EAAO,EAAE,GAE3E,IAAK,sBACH,MAAO,CACL,GAAGjI,EACH,kBAAmBA,EAAM,kBAAkB,OAAQre,GAAMA,EAAE,KAAOsmB,EAAO,EAAE,GAE/E,IAAK,iBACH,MAAO,CACL,GAAGjI,EACH,eAAgBA,EAAM,eAAe,OAAQnb,GAAMA,EAAE,KAAOojB,EAAO,EAAE,GAEzE,IAAK,eAAgB,CACnB,MAAMO,EAAUxI,EAAM,aAAa,KAAMre,GAAMA,EAAE,KAAOsmB,EAAO,EAAE,EACjE,IAAIQ,EAAazI,EAAM,WACvB,GAAIwI,GAAWP,EAAO,QAAQ,OAAS,UAAW,CAChD,MAAMS,EAAgBF,EAAiD,MACvEC,EAAa,CACX,KAAMD,EAAQ,KACd,QAASA,EAAQ,QACjB,MAAOE,GAAgB,GACvB,iBAAkB,GAClB,YAAa,EAAC,CAElB,CACA,MAAO,CACL,GAAG1I,EACH,aAAcA,EAAM,aAAa,OAAQre,GAAMA,EAAE,KAAOsmB,EAAO,EAAE,EACjE,WAAAQ,CAAA,CAEJ,CACA,IAAK,qBACH,MAAO,CACL,GAAGzI,EACH,mBAAoBA,EAAM,mBAAmB,OAAQnb,GAAMA,EAAE,KAAOojB,EAAO,EAAE,GAEjF,IAAK,mBAAoB,CACvB,MAAMO,EAAUxI,EAAM,iBAAiB,KAAM,GAAM,EAAE,KAAOiI,EAAO,EAAE,EACrE,IAAIQ,EAAazI,EAAM,WACvB,GAAIwI,GAAWP,EAAO,QAAQ,OAAS,YAAcQ,EAAY,CAC/D,MAAME,EAAU,IAAI,IAAIF,EAAW,gBAAgB,EAC7CG,EAAWH,EAAW,MAAM,OAAQvsB,GAAMysB,EAAQ,IAAIzsB,EAAE,EAAE,CAAC,EACjEusB,EAAa,CACX,GAAGA,EACH,MAAO,CAAC,GAAGG,EAAU,GAAGJ,EAAQ,cAAc,EAElD,CACA,MAAO,CACL,GAAGxI,EACH,iBAAkBA,EAAM,iBAAiB,OAAQ,GAAM,EAAE,KAAOiI,EAAO,EAAE,EACzE,WAAAQ,CAAA,CAEJ,CACA,IAAK,eACH,MAAO,CAAE,GAAGzI,EAAO,WAAY,MACjC,IAAK,kBACH,MAAO,CAAE,GAAGA,EAAO,eAAgBiI,EAAO,SAC5C,IAAK,kBACH,MAAO,CAAE,GAAGjI,EAAO,eAAgBiI,EAAO,SAC5C,IAAK,eACH,MAAO,CAAE,GAAGjI,EAAO,YAAa,CAAC,GAAGA,EAAM,YAAaiI,EAAO,IAAI,GACpE,IAAK,eACH,MAAO,CACL,GAAGjI,EACH,YAAaA,EAAM,YAAY,OAAO,CAACle,EAAG,IAAM,IAAMmmB,EAAO,KAAK,GAEtE,IAAK,oBACH,MAAO,CAAE,GAAGjI,EAAO,YAAaA,EAAM,YAAY,MAAM,CAAC,EAAE,CAEjE,CAEA,MAAM6I,GAAgB,IAAI,IAAI,CAAC,WAAW,CAAC,EACrCC,GAAkB,IAAI,IAAI,CAAC,YAAa,YAAY,CAAC,EAE3D,SAASC,GAAiBnd,EAAcvN,EAA6B,CACnE,GAAI,CACF,MAAM2qB,EAAS,KAAK,MAAM3qB,CAAI,EAC9B,GAAIwqB,GAAc,IAAIjd,CAAI,GAAK,OAAOod,GAAQ,MAAS,SACrD,MAAO,CAAC,CAAE,KAAMA,EAAO,KAAM,OAAQ,IAAK,EAE5C,GAAIF,GAAgB,IAAIld,CAAI,GAAK,OAAOod,GAAQ,MAAS,SACvD,MAAO,CAAC,CAAE,KAAMA,EAAO,KAAM,OAAQ,IAAK,EAE5C,GAAIpd,IAAS,cAAgB,MAAM,QAAQod,GAAQ,KAAK,EAAG,CACzD,MAAM7sB,EAAqB,GACrB8sB,MAAW,IACjB,UAAWnmB,KAAKkmB,EAAO,MACjB,OAAOlmB,GAAG,MAAS,UAAY,CAACmmB,EAAK,IAAInmB,EAAE,IAAI,IACjDmmB,EAAK,IAAInmB,EAAE,IAAI,EACf3G,EAAI,KAAK,CAAE,KAAM2G,EAAE,KAAM,OAAQ,IAAK,GAG1C,OAAO3G,CACT,CACF,MAAQ,CAER,CACA,MAAO,EACT,CAEA,SAAS+sB,GAAkBC,EAAyBC,EAAoC,CACtF,GAAIA,EAAK,SAAW,EAAG,OAAOD,EAC9B,MAAM3Y,EAAO,CAAC,GAAG2Y,CAAQ,EACnBE,MAAkB,IACxB7Y,EAAK,QAAQ,CAAC+C,EAAGjO,IAAM+jB,EAAY,IAAI9V,EAAE,KAAMjO,CAAC,CAAC,EACjD,IAAIgkB,EAAU,GACd,UAAWC,KAAOH,EAAM,CACtB,MAAMhoB,EAAMioB,EAAY,IAAIE,EAAI,IAAI,EACpC,GAAInoB,IAAQ,OAAW,CACrBioB,EAAY,IAAIE,EAAI,KAAM/Y,EAAK,MAAM,EACrCA,EAAK,KAAK+Y,CAAG,EACbD,EAAU,GACV,QACF,CACA,MAAM/Z,EAAOiB,EAAKpP,CAAG,EACjB,CAACmO,GAAQA,EAAK,SAAW,KACzBA,EAAK,SAAWga,EAAI,SACxB/Y,EAAKpP,CAAG,EAAImoB,EACZD,EAAU,GACZ,CACA,OAAOA,EAAU9Y,EAAO2Y,CAC1B,CAEA,SAASZ,IAAwB,CAC/B,MAAO,CACL,aAAc,EACd,kBAAmB,EACnB,sBAAuB,EACvB,eAAgB,EAChB,gBAAiB,EACjB,iBAAkB,KAClB,kBAAmB,KACnB,eAAgB,EAEpB,CAEA,SAASD,GACPvqB,EACAmT,EACAvV,EACoB,CACpB,MAAMqM,EAAOjK,EAASA,EAAS,OAAS,CAAC,EACzC,OAAIiK,GAAQA,EAAK,OAASkJ,EACjB,CAAC,GAAGnT,EAAS,MAAM,EAAG,EAAE,EAAG,CAAE,GAAGiK,EAAM,KAAMA,EAAK,KAAOrM,EAAM,EAEhE,CAAC,GAAGoC,EAAU,CAAE,KAAAmT,EAAM,KAAAvV,EAAM,CACrC,CAEO,SAASwsB,GAAcnI,EAAc5lB,EAA0B,CACpE,OAAQA,EAAG,MACT,IAAK,eAAgB,CACnB,MAAM4N,EAAOgY,EAAM,SAASA,EAAM,SAAS,OAAS,CAAC,EACrD,OAAIA,EAAM,MAAQhY,GAAM,OAAS,QAAUA,EAAK,OAAS5N,EAAG,KACnD4lB,EAEF,CACL,GAAGA,EACH,KAAM,GACN,SAAU,CACR,GAAGA,EAAM,SACT,CACE,KAAM,OACN,KAAM5lB,EAAG,KACT,SAAU,UAAUA,EAAG,EAAE,GACzB,KAAMA,EAAG,KAAO,EAAIA,EAAG,KAAO0tB,GAAgB9H,EAAM,QAAQ,EAC9D,CACF,CAEJ,CACA,IAAK,SACH,MAAO,CAAE,GAAGA,EAAO,MAAO,GAAM,WAAY,IAC9C,IAAK,eACH,MAAO,CAAE,GAAGA,EAAO,WAAY,GAAM,MAAO,IAC9C,IAAK,iBACH,MAAO,CAAE,GAAGA,EAAO,KAAM,GAAO,YAAa,MAC/C,IAAK,oBACH,MAAO,CACL,GAAGA,EACH,gBAAiB,CACf,GAAGA,EAAM,gBACT,CAAE,GAAI5lB,EAAG,GAAI,KAAMA,EAAG,KAAM,QAASA,EAAG,QAAQ,CAClD,EAEJ,IAAK,wBACH,MAAO,CACL,GAAG4lB,EACH,kBAAmB,CACjB,GAAGA,EAAM,kBACT,CACE,GAAI5lB,EAAG,GACP,KAAMA,EAAG,KACT,OAAQA,EAAG,OACX,SAAUA,EAAG,SACb,YAAaA,EAAG,YAChB,YAAaA,EAAG,YAClB,CACF,EAEJ,IAAK,mBACH,MAAO,CACL,GAAG4lB,EACH,eAAgB,CACd,GAAGA,EAAM,eACT,CACE,GAAI5lB,EAAG,GACP,SAAUA,EAAG,SACb,QAASA,EAAG,QACZ,YAAaA,EAAG,YAClB,CACF,EAEJ,IAAK,iBAAkB,CACrB,MAAM4nB,EAAQ,MAAM,QAAQ5nB,EAAG,KAAK,EAAKA,EAAG,MAAuB,OACnE,MAAO,CACL,GAAG4lB,EACH,aAAc,CACZ,GAAGA,EAAM,aACT,CAAE,GAAI5lB,EAAG,GAAI,KAAMA,EAAG,KAAM,QAASA,EAAG,QAAS,GAAI4nB,EAAQ,CAAE,MAAAA,CAAA,EAAU,EAAC,CAAG,CAC/E,CAEJ,CACA,IAAK,uBACH,MAAO,CACL,GAAGhC,EACH,mBAAoB,CAClB,GAAGA,EAAM,mBACT,CACE,GAAI5lB,EAAG,GACP,OAAQA,EAAG,OACX,MAAOA,EAAG,MACV,OAAQA,EAAG,OACX,MAAOA,EAAG,MACV,UAAWA,EAAG,UACd,MAAOA,EAAG,MACZ,CACF,EAEJ,IAAK,qBACH,MAAO,CACL,GAAG4lB,EACH,iBAAkB,CAChB,GAAGA,EAAM,iBACT,CACE,GAAI5lB,EAAG,GACP,OAAQA,EAAG,OACX,eAAgBA,EAAG,eACnB,QAASA,EAAG,QACd,CACF,EAEJ,IAAK,kBAAmB,CACtB,GAAI,CAAC4lB,EAAM,WAAY,OAAOA,EAC9B,MAAMwJ,EAAU,IAAI,IAAIxJ,EAAM,WAAW,gBAAgB,EACzD,OAAAwJ,EAAQ,IAAIpvB,EAAG,MAAM,EACd,CACL,GAAG4lB,EACH,WAAY,CACV,GAAGA,EAAM,WACT,iBAAkB,CAAC,GAAGwJ,CAAO,EAC7B,YAAa,CAAE,GAAGxJ,EAAM,WAAW,YAAa,CAAC5lB,EAAG,MAAM,EAAGA,EAAG,OAAO,CACzE,CAEJ,CACA,IAAK,gBACH,MAAO,CACL,GAAG4lB,EACH,WAAY,KACZ,mBAAoB,GACpB,iBAAkB,EAAC,EAEvB,IAAK,YACH,MAAO,CAAE,GAAGA,EAAO,SAAU5lB,EAAG,OAClC,IAAK,aACH,MAAO,CACL,GAAG4lB,EACH,SAAU,MAAM,QAAQ5lB,EAAG,KAAK,EAAIA,EAAG,MAAQ,GAC/C,WAAY,EAAQA,EAAG,OAAO,EAElC,IAAK,UACH,MAAO,CAAE,GAAG4lB,EAAO,OAAQ5lB,EAAG,OAChC,IAAK,iBACH,MAAO,CAAE,GAAG4lB,EAAO,MAAO,CAAE,GAAGA,EAAM,MAAO,eAAgB5lB,EAAG,eAAe,EAChF,IAAK,UACH,MAAO,CACL,GAAG4lB,EACH,OAAQ5lB,EAAG,QACX,aACE4lB,EAAM,cAAgB5lB,EAAG,QAAQ,KAAMqvB,GAAUA,EAAM,OAASzJ,EAAM,cAAc,IAAI,EACpFA,EAAM,aACN,MAEV,IAAK,iBACH,MAAO,CAAE,GAAGA,EAAO,aAAc5lB,EAAG,QACtC,IAAK,QACH,MAAO,CAAE,GAAG4lB,EAAO,KAAM5lB,EAAG,OAC9B,IAAK,WACH,MAAO,CACL,GAAG4lB,EACH,QAAS,CACP,SAAU5lB,EAAG,SACb,MAAOA,EAAG,MACV,YAAaA,EAAG,YAClB,EAEJ,IAAK,eACH,MAAO,CACL,GAAG4lB,EACH,GAAI,CACF,MAAO5lB,EAAG,MACV,UAAWA,EAAG,UACd,QAASA,EAAG,QACZ,QAASA,EAAG,QACZ,WAAYA,EAAG,WACf,aAAcA,EAAG,aACjB,UAAWA,EAAG,UACd,aAAcA,EAAG,aACjB,OAAQA,EAAG,OACb,EAEJ,IAAK,YAAa,CAChB,MAAMsvB,EAAS1J,EAAM,UAAU,aACzB2J,EAAYD,IAAW,QAAaA,IAAWtvB,EAAG,aACxD,MAAO,CACL,GAAG4lB,EACH,KAAM2J,EAAY,GAAQ3J,EAAM,KAChC,SAAU2J,EAAY,GAAK3J,EAAM,SACjC,gBAAiB2J,EAAY,GAAK3J,EAAM,gBACxC,kBAAmB2J,EAAY,GAAK3J,EAAM,kBAC1C,eAAgB2J,EAAY,GAAK3J,EAAM,eACvC,aAAc2J,EAAY,GAAK3J,EAAM,aACrC,mBAAoB2J,EAAY,GAAK3J,EAAM,mBAC3C,iBAAkB2J,EAAY,GAAK3J,EAAM,iBACzC,WAAY2J,EAAY,KAAO3J,EAAM,WACrC,MAAO2J,EAAYpB,GAAA,EAAcvI,EAAM,MACvC,aAAc2J,EAAY,GAAK3J,EAAM,aACrC,WAAY2J,EAAY,EAAI3J,EAAM,WAClC,SAAU,CACR,gBAAiB5lB,EAAG,gBACpB,SAAUA,EAAG,SACb,UAAWA,EAAG,UACd,QAASA,EAAG,QACZ,aAAcA,EAAG,aACjB,aAAcA,EAAG,aACjB,iBAAkBA,EAAG,iBACrB,MAAOA,EAAG,MACV,OAAQA,EAAG,OACX,gBAAiBA,EAAG,gBACpB,eAAgBA,EAAG,eACnB,iBAAkBA,EAAG,iBACrB,QAASA,EAAG,QACd,CAEJ,CACA,IAAK,kBAAmB,CACtB,MAAMwvB,EAAcxvB,EAAG,KACjByvB,EAAwBzvB,EAAG,SAAS,IAAI,CAACE,EAAGgL,IAAM,CACtD,GAAIhL,EAAE,OAAS,OACb,MAAO,CAAE,KAAM,OAAQ,KAAMA,EAAE,KAAM,SAAU,YAAYgL,CAAC,GAAI,KAAMA,EAAI,GAE5E,MAAMvH,EAA+BzD,EAAE,SAAS,IAAK4B,GAC/CA,EAAE,OAAS,OACN,CACL,KAAM,OACN,OAAQA,EAAE,OACV,KAAMA,EAAE,KACR,KAAMA,EAAE,KACR,UAAW,EACX,OAAQA,EAAE,OACV,GAAIA,EAAE,GACN,WAAY,GAGTA,CACR,EACD,MAAO,CAAE,KAAM,YAAa,KAAM5B,EAAE,KAAM,SAAAyD,EAAU,QAAS,GAC/D,CAAC,EACD,IAAImU,EAA8B,GAClC,UAAW5X,KAAKuvB,EACd,GAAIvvB,EAAE,OAAS,YACf,UAAW4B,KAAK5B,EAAE,SACZ4B,EAAE,OAAS,SAGfgW,EAAegX,GAAkBhX,EAAc6W,GAAiB7sB,EAAE,KAAMA,EAAE,IAAI,CAAC,GAGnF,MAAO,CACL,GAAG8jB,EACH,KAAM,GACN,eAAgB4J,EAChB,SAAUC,EACV,gBAAiB,GACjB,kBAAmB,GACnB,eAAgB,GAChB,aAAc,GACd,mBAAoB,GACpB,iBAAkB,GAClB,WAAY,KACZ,MAAO,CACL,GAAGtB,GAAA,EACH,aAAcnuB,EAAG,UAAU,aAC3B,kBAAmBA,EAAG,UAAU,eAAiBA,EAAG,UAAU,gBAC9D,eAAgBA,EAAG,UAAU,eAC7B,gBAAiBA,EAAG,UAAU,iBAEhC,aAAA8X,EACA,YAAa,KACb,YAAa,GACb,WAAY,EAEhB,CACA,IAAK,iBAAkB,CAIrB,MAAM4X,EAAW1vB,EAAG,YAAc,EAAI,UAAY,GAAGA,EAAG,SAAS,2BACjE,MAAO,CACL,GAAG4lB,EACH,SAAU,CACR,GAAGA,EAAM,SACT,CACE,KAAM,QACN,QACE,YAAY5lB,EAAG,IAAI,8BAA8B0vB,CAAQ,oCACxB1vB,EAAG,IAAI,sGAE5C,CACF,CAEJ,CACA,IAAK,SACL,IAAK,QACH,MAAO,CACL,GAAG4lB,EACH,KAAM,GACN,YAAa,KACb,SAAU,CAAC,GAAGA,EAAM,SAAU,CAAE,KAAM,QAAS,QAAS5lB,EAAG,QAAS,GAExE,IAAK,qBACH,OAAI4lB,EAAM,SAAS,KAAM1lB,GAAMA,EAAE,OAAS,aAAeA,EAAE,OAASF,EAAG,IAAI,EAClE,CAAE,GAAG4lB,EAAO,MAAO5lB,EAAG,OAExB,CACL,GAAG4lB,EACH,MAAO5lB,EAAG,MACV,SAAU,CACR,GAAG4lB,EAAM,SACT,CAAE,KAAM,YAAa,KAAM5lB,EAAG,KAAM,SAAU,GAAI,QAAS,GAAK,CAClE,EAEJ,IAAK,cACH,MAAO,CACL,GAAG4lB,EACH,SAAUA,EAAM,SAAS,IAAK1lB,GACxBA,EAAE,OAAS,aAAeA,EAAE,OAASF,EAAG,KAAaE,EACrDF,EAAG,UAAY,UACV,CAAE,GAAGE,EAAG,SAAUguB,GAAkBhuB,EAAE,SAAU,OAAQF,EAAG,IAAI,GAEpEA,EAAG,UAAY,YACV,CAAE,GAAGE,EAAG,SAAUguB,GAAkBhuB,EAAE,SAAU,YAAaF,EAAG,IAAI,GAEtEE,CACR,GAEL,IAAK,cAAe,CAClB,MAAMyvB,EAAI3vB,EAAG,MACP4vB,EAAUD,GAAG,yBAA2B,EACxCE,EAAWF,GAAG,0BAA4B,EAC1CG,EAAUF,EAAU,GAAKC,EAAW,EACpClY,EAAoB,CACxB,aAAciO,EAAM,MAAM,cAAgB5lB,EAAG,SAAW,GACxD,kBAAmB4lB,EAAM,MAAM,mBAAqB+J,GAAG,eAAiB,GACxE,sBAAuB/J,EAAM,MAAM,uBAAyB+J,GAAG,mBAAqB,GACpF,eAAgB/J,EAAM,MAAM,eAAiBgK,EAC7C,gBAAiBhK,EAAM,MAAM,gBAAkBiK,EAC/C,iBAAkBC,EAAUF,EAAUhK,EAAM,MAAM,iBAClD,kBAAmBkK,EAAUD,EAAWjK,EAAM,MAAM,kBACpD,eAAgBA,EAAM,MAAM,gBAE9B,MAAO,CACL,GAAGA,EACH,MAAAjO,EACA,SAAUiO,EAAM,SAAS,IAAK1lB,GACxBA,EAAE,OAAS,aAAeA,EAAE,OAASF,EAAG,KAAaE,EAClD,CAAE,GAAGA,EAAG,QAAS,GACzB,EAEL,CACA,IAAK,iBACH,MAAO,CACL,GAAG0lB,EACH,SAAUA,EAAM,SAAS,IAAK1lB,GACxBA,EAAE,OAAS,aAAeA,EAAE,OAASF,EAAG,MACxCE,EAAE,SAAS,KAAM4B,GAAMA,EAAE,OAAS,QAAUA,EAAE,SAAW9B,EAAG,MAAM,EAAUE,EACzE,CACL,GAAGA,EACH,SAAU,CACR,GAAGA,EAAE,SACL,CACE,KAAM,OACN,OAAQF,EAAG,OACX,KAAMA,EAAG,KACT,KAAM,GACN,UAAW,KAAK,KAAI,CACtB,CACF,CAEH,GAEL,IAAK,cAAe,CAClB,MAAMgvB,EAAOL,GAAiB3uB,EAAG,KAAMA,EAAG,IAAI,EAC9C,MAAO,CACL,GAAG4lB,EACH,aAAckJ,GAAkBlJ,EAAM,aAAcoJ,CAAI,EACxD,SAAUpJ,EAAM,SAAS,IAAK1lB,GAAM,CAClC,GAAIA,EAAE,OAAS,aAAeA,EAAE,OAASF,EAAG,KAAM,OAAOE,EACzD,MAAM8G,EAAM9G,EAAE,SAAS,UAAW4B,GAAMA,EAAE,OAAS,QAAUA,EAAE,SAAW9B,EAAG,MAAM,EACnF,GAAIgH,GAAO,EAAG,CACZ,MAAM+oB,EAAO,CAAC,GAAG7vB,EAAE,QAAQ,EACrBkZ,EAAM2W,EAAK/oB,CAAG,EACpB,OAAIoS,GAAK,OAAS,SAChB2W,EAAK/oB,CAAG,EAAI,CAAE,GAAGoS,EAAK,KAAMpZ,EAAG,OAE1B,CAAE,GAAGE,EAAG,SAAU6vB,CAAA,CAC3B,CACA,MAAO,CACL,GAAG7vB,EACH,SAAU,CACR,GAAGA,EAAE,SACL,CACE,KAAM,OACN,OAAQF,EAAG,OACX,KAAMA,EAAG,KACT,KAAMA,EAAG,KACT,UAAW,KAAK,KAAI,CACtB,CACF,CAEJ,CAAC,EAEL,CACA,IAAK,cACH,MAAO,CACL,GAAG4lB,EACH,SAAUA,EAAM,SAAS,IAAK1lB,GAAM,CAClC,GAAIA,EAAE,OAAS,YAAa,OAAOA,EACnC,IAAI8vB,EAAU,GACd,MAAMD,EAAO7vB,EAAE,SAAS,IAAK4B,GACvBA,EAAE,OAAS,QAAUA,EAAE,SAAW9B,EAAG,QACvCgwB,EAAU,GACH,CACL,GAAGluB,EACH,OAAQ9B,EAAG,OACX,GAAIA,EAAG,GACP,WAAY,KAAK,MAAQ8B,EAAE,YAGxBA,CACR,EACD,OAAOkuB,EAAU,CAAE,GAAG9vB,EAAG,SAAU6vB,GAAS7vB,CAC9C,CAAC,GAEL,IAAK,gBACH,MAAO,CAAE,GAAG0lB,EAAO,UAAW5lB,EAAG,KAAM,WAAY4lB,EAAM,WAAa,GACxE,IAAK,cACH,MAAO,CACL,GAAGA,EACH,SAAU,CACR,GAAGA,EAAM,SACT,CAAE,KAAM,SAAU,KAAM;AAAA,EAAU5lB,EAAG,MAAM,GAAG,CAChD,EAEJ,IAAK,SACH,OAAO4lB,EACT,IAAK,UAIH,OAAI5lB,EAAG,WAAa,OAAe4lB,EAC5B,CACL,GAAGA,EACH,SAAU,CACR,GAAGA,EAAM,SACT,CACE,KAAM,UACN,GAAI,KAAK5lB,EAAG,EAAE,GACd,KAAMA,EAAG,KACT,SAAUA,EAAG,SACf,CACF,EAEJ,QACE,OAAO4lB,CAAA,CAEb,CAEA,SAASqK,GAA2BvsB,EAAyBwsB,EAA2B,CACtF,OAAOxsB,EACJ,IAAKxD,GACAA,EAAE,OAAS,OAAe,OAAOgwB,CAAS;AAAA;AAAA,EAAOhwB,EAAE,IAAI,GACvDA,EAAE,OAAS,YAeN;AAAA;AAAA,EAdMA,EAAE,SACZ,IAAK4B,GAAM,CACV,GAAIA,EAAE,OAAS,OAAQ,OAAOA,EAAE,KAChC,GAAIA,EAAE,OAAS,YACb,MAAO;AAAA,WAAuB0F,EAAE,4BAA4B,CAAC;AAAA;AAAA,EAAiB1F,EAAE,IAAI;AAAA;AAAA,YACtF,GAAIA,EAAE,OAAS,OAAQ,CACrB,MAAMquB,EAAMruB,EAAE,KAAO;AAAA;AAAA;AAAA,EAAmBA,EAAE,IAAI;AAAA,QAAa,GACrDR,EAAMQ,EAAE,OAAS;AAAA;AAAA;AAAA,EAAeA,EAAE,MAAM;AAAA,QAAa,GAC3D,MAAO,OAAO0F,EAAE,qBAAqB,CAAC,QAAQ1F,EAAE,IAAI,OAAOquB,CAAG,GAAG7uB,CAAG,EACtE,CACA,MAAO,EACT,CAAC,EACA,OAAO,OAAO,EACd,KAAK;AAAA;AAAA,CAAM,CACgB,GAE5BpB,EAAE,OAAS,QAAgB;AAAA;AAAA,EAAgBA,EAAE,OAAO,GACjD,EACR,EACA,OAAO,OAAO,EACd,KAAK;AAAA;AAAA;AAAA;AAAA,CAAa,CACvB,CAEA,SAASkwB,GAAiB5e,EAAsB,CAC9C,OAAOA,EAAK,QAAQ,yBAA0B,GAAG,EAAE,QAAQ,OAAQ,EAAE,EAAE,MAAM,EAAG,GAAG,GAAK,SAC1F,CAEA,SAAS6e,GAAsBC,EAAyB,CAEtD,MAAO,GADMF,GAAiBE,CAAO,CACvB,KAChB,CAmCA,SAASC,GAAW,CAClB,MAAAC,EACA,OAAAjoB,EACA,SAAAsT,EACA,iBAAA4U,EACA,SAAAC,EACA,WAAAC,EACA,YAAAC,EACA,MAAAplB,EACA,WAAAsQ,EACA,WAAAC,EACA,gBAAAC,EACA,cAAA6U,EACA,UAAA5U,EACA,eAAAC,EACA,WAAAC,EACA,gBAAAC,EACA,cAAA0U,EACA,aAAAC,EACA,aAAAC,EACA,YAAAC,EACA,iBAAA/M,EACA,SAAAgN,EACA,YAAAC,EACA,eAAAC,EACA,eAAAC,GACA,mBAAAC,CACF,EAAoB,CAClB,KAAM,CAAC1L,EAAO2L,CAAQ,EAAIC,aAAW5D,GAAQ,CAC3C,MAAO,GACP,WAAY,GACZ,KAAM,GACN,SAAU,GACV,gBAAiB,GACjB,kBAAmB,GACnB,eAAgB,GAChB,aAAc,GACd,mBAAoB,GACpB,iBAAkB,GAClB,WAAY,KACZ,MAAOO,GAAA,EACP,SAAU,GACV,SAAU,KACV,GAAI,KACJ,QAAS,KACT,eAAgB,KAChB,eAAgB,KAChB,SAAU,GACV,WAAY,GACZ,OAAQ,GACR,aAAc,GACd,OAAQ,GACR,aAAc,KACd,KAAM,GACN,YAAa,KACb,YAAa,GACb,WAAY,EACb,EACDxnB,EAAA,EACAwmB,GAAA,EACA,KAAM,CAACra,GAAOC,EAAQ,EAAIlM,WAAS,EAAE,EAC/B,CAAC4qB,GAAOC,CAAQ,EAAI7qB,WAAiD,IAAI,EACzE,CAAC8qB,GAAUC,EAAW,EAAI/qB,WAAkB,IAAMic,IAAkB,EACpE,CAAC+O,EAAQC,CAAS,EAAIjrB,WAAS,EAAK,EACpC,CAACkrB,EAAUC,EAAW,EAAInrB,WAE9B,MAAS,EACLorB,GAAc7nB,SAA4B,IAAI,EAC9C8nB,GAAY9nB,SAAuB,IAAI,EACvC+nB,EAAiB/nB,SAAuB,IAAI,EAC5C,CAACgoB,EAAcC,CAAe,EAAIxrB,WAAS,EAAK,EAChD,CAACyrB,EAAcC,EAAe,EAAI1rB,WAAyB,SAAS,EACpE,CAACmd,EAAUwO,CAAW,EAAI3rB,WAAS,EAAK,EACxC,CAAC4rB,EAAWC,EAAY,EAAI7rB,WAAS,EAAK,EAI1C,CAAC8rB,EAAgBC,EAAiB,EAAI/rB,WAAwB,IAAI,EAClE,CAACgsB,GAAkBC,EAAmB,EAAIjsB,WAAS,EAAK,EAC9DC,YAAU,IAAM,CACV6rB,GAAkB/M,EAAM,iBAAmB+M,GAC7CC,GAAkB,IAAI,CAE1B,EAAG,CAACD,EAAgB/M,EAAM,cAAc,CAAC,EACzC,MAAMmN,GAAiB3H,cAAY,CAACnO,EAAuB,YAAc,CACvEsV,GAAgBtV,CAAI,EACpBoV,EAAgB,EAAI,CACtB,EAAG,EAAE,EACCW,GAAU1qB,GAAkBC,CAAM,EAExCzB,YAAU,KACR2pB,EAAiBD,EAAOe,CAAQ,EACzB,IAAMd,EAAiBD,EAAO,IAAI,GACxC,CAACA,EAAOC,CAAgB,CAAC,EAE5B,MAAMwC,EAAU7H,cACb/nB,GAAyB,CACxB,MAAMnE,EAAU,CAAE,MAAAsxB,EAAO,GAAGntB,CAAA,EAC5BW,GAAO,WAAY,CAAE,KAAM,KAAK,UAAU9E,CAAO,EAAG,EAAE,MAAOwB,GAC3D,QAAQ,MAAM,GAAG2C,EAAI,GAAG,UAAW3C,CAAG,EAE1C,EACA,CAAC8vB,CAAK,GAGF0C,GAAgB9H,cACpB,CAACphB,EAAegM,IAAkBid,EAAQ,CAAE,IAAK,gBAAiB,MAAAjpB,EAAO,MAAAgM,EAAO,EAChF,CAACid,CAAO,GAEJE,GAAiB/H,cACrB,CAACpoB,EAAcgT,IAAkBid,EAAQ,CAAE,IAAK,kBAAmB,KAAAjwB,EAAM,MAAAgT,EAAO,EAChF,CAACid,CAAO,GAEJG,GAAoBhI,cACvBpoB,GAAiBiwB,EAAQ,CAAE,IAAK,iBAAkB,KAAAjwB,EAAM,EACzD,CAACiwB,CAAO,GAEJI,GAAejI,cAClBpN,GAAyBiV,EAAQ,CAAE,IAAK,gBAAiB,GAAGjV,EAAO,EACpE,CAACiV,CAAO,GAEJK,GAAiBlI,cAAY,IAAM6H,EAAQ,CAAE,IAAK,gBAAiB,EAAG,CAACA,CAAO,CAAC,EAC/EM,GAAYnI,cAAY,IAAM6H,EAAQ,CAAE,IAAK,aAAc,EAAG,CAACA,CAAO,CAAC,EACvEO,GAAepI,cAAY,IAAM6H,EAAQ,CAAE,IAAK,gBAAiB,EAAG,CAACA,CAAO,CAAC,EAC7EQ,GAAerI,cAClBpN,GACCiV,EAAQ,CAAE,IAAK,iBAAkB,GAAGjV,EAAO,EAC7C,CAACiV,CAAO,GAEJS,GAAatI,cAChBhkB,GAAgB6rB,EAAQ,CAAE,IAAK,iBAAkB,IAAA7rB,EAAK,EACvD,CAAC6rB,CAAO,GAEJU,GAAavI,cAChBwI,GAAiBX,EAAQ,CAAE,IAAK,gBAAiB,KAAAW,EAAM,EACxD,CAACX,CAAO,GAEJY,GAAgBzI,cACnBwI,GAAiBX,EAAQ,CAAE,IAAK,mBAAoB,KAAAW,EAAM,EAC3D,CAACX,CAAO,GAEJa,GAAU1I,cAAY,IAAM,CAChC6H,EAAQ,CAAE,IAAK,WAAY,EAC3B1B,EAAS,CAAE,EAAG,QAAS,CACzB,EAAG,CAAC0B,CAAO,CAAC,EAENc,GAAgB3I,cAAY,SAAY,CAK5C,GAAIrsB,GAAc,CAChB+zB,GAAoB,EAAI,EACxB,MACF,CACA,GAAI,CACF,MAAMvd,EAAS,MAAMye,GAAW,CAC9B,UAAW,GACX,SAAU,GACV,MAAOxsB,EAAE,eAAe,EACxB,YAAaoe,EAAM,UAAU,aAC9B,EACG,OAAOrQ,GAAW,UAAYA,EAAO,OAAS,GAChD8d,GAAa,CAAE,aAAc9d,EAAQ,CAEzC,OAAS7U,EAAK,CACZ,QAAQ,MAAM,uBAAwBA,CAAG,CAC3C,CACF,EAAG,CAAC2yB,GAAczN,EAAM,UAAU,YAAY,CAAC,EAEzCqO,GAAa7I,cACjB,CAAC9qB,EAAa4zB,IAAiD,CAC7DxC,EAAS,CAAE,IAAApxB,EAAK,KAAM4zB,GAAM,KAAM,EAClC,OAAO,WAAW,IAAMxC,EAAS,IAAI,EAAGwC,GAAM,UAAY,IAAI,CAChE,EACA,EAAC,EAOGC,GAAgB/pB,SAAO7B,CAAM,EACnCzB,YAAU,IAAM,CACdqtB,GAAc,QAAU5rB,CAC1B,EAAG,CAACA,CAAM,CAAC,EACXzB,YAAU,IAAM,CACd,MAAM8F,EAAKgZ,EAAM,UAAU,aAC3B,IAAIwO,EAAgC,KAChCC,EAAY,GAChB,OAAM,SAAY,CAChB,GAAI,CAGF,MAAMC,GAAS,MAFH,MAAAC,GAAA,IAAM,2BAAAC,EAAA,EAAgC,SAC9B,oBACS,gBAAiBl1B,IAAe,CAC3D,GAAI,CAAC60B,GAAc,QAAS,OAC5B,GAAI70B,GAAM,QAAQ,OAAS,QAAS,CAClC,SAAS,KAAK,MAAM,YAClB,uBACA,IAAIkI,EAAE,kBAAkB,CAAC,KAE3B,SAAS,KAAK,QAAQ,SAAW,IACjC,MACF,CACA,GAAIlI,GAAM,QAAQ,OAAS,QAAS,CAClC,OAAO,SAAS,KAAK,QAAQ,SAC7B,MACF,CACA,GAAIA,GAAM,QAAQ,OAAS,OAAQ,OACnC,OAAO,SAAS,KAAK,QAAQ,SAC7B,MAAMm1B,GAAQn1B,GAAM,QAAQ,OAAS,GACrC,GAAIm1B,GAAM,SAAW,EAAG,OACxB,MAAMC,GAAWD,GAAM,IAAKltB,IAAc,CACxC,MAAMotB,GAAOptB,GAAE,QAAQ,MAAO,GAAG,EACjC,GAAIqF,EAAI,CACN,MAAMgoB,GAAShoB,EAAG,QAAQ,MAAO,GAAG,EAAE,QAAQ,OAAQ,EAAE,EACxD,GAAI+nB,KAASC,IAAUD,GAAK,WAAW,GAAGC,EAAM,GAAG,EACjD,OAAOD,GAAK,MAAMC,GAAO,MAAM,EAAE,QAAQ,OAAQ,EAAE,GAAK,GAE5D,CACA,OAAOD,EACT,CAAC,EACD5hB,GAAU6N,IAED,GADQA,GAAE,OAAS,GAAGA,GAAE,QAAQ,OAAQ,EAAE,CAAC,IAAM,EACxC,GAAG8T,GAAS,IAAKx0B,IAAc,IAAIA,EAAC,EAAE,EAAE,KAAK,GAAG,CAAC,GAClE,EACD,UAAWA,MAAKw0B,GAAUtB,GAAkBlzB,EAAW,EACvD+xB,GAAY,SAAS,OACvB,CAAC,EACGoC,EAAWC,GAAA,EACVF,EAAWE,EAClB,OAAS5zB,EAAK,CACZ,QAAQ,MAAM,0BAA2BA,CAAG,CAC9C,CACF,KACO,IAAM,CACX2zB,EAAY,GACZD,IAAA,EACA,OAAO,SAAS,KAAK,QAAQ,QAC/B,CACF,EAAG,CAACxO,EAAM,UAAU,aAAcwN,EAAiB,CAAC,EAEpD,MAAMyB,GAAOzJ,cACV0J,GAAsB,CACrB,MAAMvzB,GAAQuzB,GAAYhiB,IAAO,OACjC,GAAI,CAACvR,GAAQ,CAACqkB,EAAM,OAASA,EAAM,KAAM,OAGzC,MAAMmP,EAAW,2BAA2B,KAAKxzB,CAAI,EACrD,GAAIwzB,EAAU,CACZ,MAAMC,GAAWD,EAAS,CAAC,GAAG,QAAU,GACxC,GAAI,CAACC,GAAU,OACf/B,EAAQ,CAAE,IAAK,MAAO,KAAM+B,GAAU,EACjCF,GAAU/hB,GAAS,EAAE,EAC1B,MACF,CAEA,MAAMkiB,EAAa1zB,EAAK,MAAM,8BAA8B,EAC5D,GAAI0zB,EAAY,CACd,KAAM,EAAGzjB,GAAMvN,EAAI,EAAIgxB,EACjB9M,GAAQvC,EAAM,OAAO,KAAM9jB,IAAMA,GAAE,OAAS0P,EAAI,EACtD,GAAI2W,GAAO,CACT,MAAM+M,GAAW,SAAS,KAAK,KAAK,IAAI,KAAK,SAAS,SAAS,EAAE,EAAE,MAAM,EAAG,CAAC,CAAC,GACxEC,GAAclxB,IAAM,QAAU,GACpCstB,EAAS,CAAE,EAAG,cAAe,MAAO,CAAE,KAAMpJ,GAAM,KAAM,MAAOA,GAAM,OAAS,KAAMgN,GAAa,SAAAD,GAAU,EAC3GjC,EAAQ,CAAE,IAAK,YAAa,KAAM9K,GAAM,KAAM,KAAMgN,IAAe,OAAW,EACzEL,GAAU/hB,GAAS,EAAE,EAC1B,MACF,CACF,CACA,MAAMmiB,GAAW,KAAK,KAAK,KAAK,GAChC3D,EAAS,CAAE,EAAG,YAAa,KAAAhwB,EAAM,SAAA2zB,GAAU,EAC3CjC,EAAQ,CAAE,IAAK,aAAc,KAAA1xB,CAAA,CAAM,EAC9BuzB,GAAU/hB,GAAS,EAAE,CAC5B,EACA,CAACD,GAAO8S,EAAM,MAAOA,EAAM,KAAMA,EAAM,OAAQqN,CAAO,GAGlDmC,GAAQhK,cAAY,IAAM6H,EAAQ,CAAE,IAAK,QAAS,EAAG,CAACA,CAAO,CAAC,EAGpEnsB,YAAU,IAAM,CACV8e,EAAM,WAAa,GAAKA,EAAM,YAChC7S,GAAS6S,EAAM,SAAS,EACxBqM,GAAY,SAAS,QAIzB,EAAG,CAACrM,EAAM,UAAU,CAAC,EAErB9e,YAAU,IAAM,CACd,GAAI8e,EAAM,MAAQ,CAACA,EAAM,OAASA,EAAM,YAAY,SAAW,EAAG,OAClE,MAAMxP,EAAOwP,EAAM,YAAY,CAAC,EAC3BxP,IACLmb,EAAS,CAAE,EAAG,oBAAqB,EACnCsD,GAAKze,CAAI,EACX,EAAG,CAACwP,EAAM,KAAMA,EAAM,MAAOA,EAAM,YAAaiP,EAAI,CAAC,EAErD,MAAMQ,GAAiBjK,cACrB,CAACrZ,EAAYujB,IAAiC,CAC5CrC,EAAQ,CAAE,IAAK,mBAAoB,GAAAlhB,EAAI,SAAAujB,EAAU,EACjD/D,EAAS,CAAE,EAAG,kBAAmB,GAAAxf,CAAA,CAAI,CACvC,EACA,CAACkhB,CAAO,GAEJ3K,GAAmB8C,cACtBrZ,GAAesjB,GAAetjB,EAAI,CAAE,KAAM,WAAY,EACvD,CAACsjB,EAAc,GAEX9M,GAAkB6C,cACrBrZ,GAAesjB,GAAetjB,EAAI,CAAE,KAAM,OAAQ,EACnD,CAACsjB,EAAc,GAEX7M,GAAuB4C,cAC3B,CAACrZ,EAAYlE,IAAmBwnB,GAAetjB,EAAI,CAAE,KAAM,eAAgB,OAAAlE,EAAQ,EACnF,CAACwnB,EAAc,GAEXE,GAAoBnK,cACxB,CAACrZ,EAAYujB,IAAiC,CAC5CrC,EAAQ,CAAE,IAAK,mBAAoB,GAAAlhB,EAAI,SAAAujB,EAAU,EACjD/D,EAAS,CAAE,EAAG,sBAAuB,GAAAxf,CAAA,CAAI,CAC3C,EACA,CAACkhB,CAAO,GAEJuC,GAAgBpK,cACpB,CAACrZ,EAAYujB,IAA4B,CACvCrC,EAAQ,CAAE,IAAK,kBAAmB,GAAAlhB,EAAI,SAAAujB,EAAU,EAChD/D,EAAS,CAAE,EAAG,iBAAkB,GAAAxf,CAAA,CAAI,CACtC,EACA,CAACkhB,CAAO,GAEJwC,GAAcrK,cAClB,CAACrZ,EAAYujB,IAA0B,CACrCrC,EAAQ,CAAE,IAAK,gBAAiB,GAAAlhB,EAAI,SAAAujB,EAAU,EAC9C/D,EAAS,CAAE,EAAG,eAAgB,GAAAxf,EAAI,QAASujB,EAAU,CACvD,EACA,CAACrC,CAAO,GAEJyC,GAAoBtK,cACxB,CAACrZ,EAAYujB,IAAgC,CAC3CrC,EAAQ,CAAE,IAAK,sBAAuB,GAAAlhB,EAAI,SAAAujB,EAAU,EACpD/D,EAAS,CAAE,EAAG,qBAAsB,GAAAxf,EAAI,QAASujB,EAAU,CAC7D,EACA,CAACrC,CAAO,GAEJ0C,GAAkBvK,cACtB,CAACrZ,EAAYujB,IAA8B,CACzCrC,EAAQ,CAAE,IAAK,oBAAqB,GAAAlhB,EAAI,SAAAujB,EAAU,EAClD/D,EAAS,CAAE,EAAG,mBAAoB,GAAAxf,EAAI,QAASujB,EAAU,CAC3D,EACA,CAACrC,CAAO,GAIJ2C,GAAoBxrB,SAAOwb,EAAM,cAAc,EACrDgQ,GAAkB,QAAUhQ,EAAM,eAClC,MAAMiQ,GAAmBzK,cAAY,IAAM,CACzC,MAAMkF,EAAUsF,GAAkB,QAClC,GAAI,CAACtF,EAAS,OAAO,KACrB,MAAM9sB,EAAM,aAAa,QAAQ,mBAAmB8sB,CAAO,EAAE,EACvDvpB,EAAIvD,EAAM,OAAOA,CAAG,EAAI,OAAO,IACrC,OAAO,OAAO,SAASuD,CAAC,EAAIA,EAAI,IAClC,EAAG,EAAE,EAEC,CAAE,eAAAglB,GAAgB,eAAAO,EAAA,EAAmBX,GACzCuG,GACAC,EACAvM,EAAM,KACNiQ,EAAA,EAKF/uB,YAAU,IAAM,CACd,MAAM6E,EAAKumB,GAAU,QACf5B,EAAU1K,EAAM,eACtB,GAAI,CAACja,GAAM,CAAC2kB,EAAS,OACrB,MAAMlpB,EAAM,mBAAmBkpB,CAAO,GACtC,IAAIwF,EACJ,MAAMC,GAAW,IAAM,CACrB,aAAaD,CAAK,EAClBA,EAAQ,WAAW,IAAM,CACNnqB,EAAG,UAAYA,EAAG,cAAgBA,EAAG,aAAe,GACvD,aAAa,WAAWvE,CAAG,EACpC,aAAa,QAAQA,EAAK,OAAO,KAAK,MAAMuE,EAAG,SAAS,CAAC,CAAC,CACjE,EAAG,GAAG,CACR,EACA,OAAAA,EAAG,iBAAiB,SAAUoqB,GAAU,CAAE,QAAS,GAAM,EAClD,IAAM,CACXpqB,EAAG,oBAAoB,SAAUoqB,EAAQ,EACzC,aAAaD,CAAK,CACpB,CACF,EAAG,CAAClQ,EAAM,cAAc,CAAC,EAEzB9e,YAAU,IAAM,CAEd,GADI,CAACyB,GACD,CAACyb,EAAU,OACfiP,EAAQ,CAAE,IAAK,YAAa,EAC5B,MAAMlhB,EAAK,OAAO,YAAY,IAAMkhB,EAAQ,CAAE,IAAK,YAAa,EAAG,IAAI,EACvE,MAAO,IAAM,OAAO,cAAclhB,CAAE,CACtC,EAAG,CAACxJ,EAAQyb,EAAUiP,CAAO,CAAC,EAE9BnsB,YAAU,IAAM,CACTyB,IACDqd,EAAM,MACVqN,EAAQ,CAAE,IAAK,YAAa,EAC9B,EAAG,CAAC1qB,EAAQqd,EAAM,KAAMqN,CAAO,CAAC,EAEhCnsB,YAAU,IAAM,CACTyB,GACL+qB,GAAA,CACF,EAAG,CAAC/qB,EAAQ+qB,EAAc,CAAC,EAE3B,MAAM0C,GAAoB5rB,SAAsBiH,IAAoB,EAC9D4kB,GAAuB7rB,SAAO,EAAK,EACzCtD,YAAU,IAAM,CAId,GAHI,CAACyB,GACD0tB,GAAqB,SACrB,CAACrQ,EAAM,OACPA,EAAM,SAAS,SAAW,EAAG,OACjCqQ,GAAqB,QAAU,GAC/B,MAAMjU,EAASgU,GAAkB,QACjC,GAAKhU,GACDA,IAAW4D,EAAM,eACrB,IAAI,CAACA,EAAM,SAAS,KAAM9jB,GAAMA,EAAE,OAASkgB,CAAM,EAAG,CAClDzQ,GAAsB,EACtB,MACF,CACA0hB,EAAQ,CAAE,IAAK,eAAgB,KAAMjR,EAAQ,EAC/C,EAAG,CAACzZ,EAAQqd,EAAM,MAAOA,EAAM,SAAUA,EAAM,eAAgBqN,CAAO,CAAC,EAEvEnsB,YAAU,IAAM,CAEd,GAAI,CAACyB,EAAQ,OACb,MAAME,EAASC,GAAqB,CAClC,MAAMwtB,EAAMxtB,EAAE,SAAWA,EAAE,QAC3B,GAAIwtB,IAAQxtB,EAAE,MAAQ,KAAOA,EAAE,MAAQ,KAAM,CAC3C,MAAMtG,EAAOsG,EAAE,QAAwB,QACnCtG,IAAQ,SAAWA,IAAQ,cAAc,iBAC7C,MACF,CACA,GAAI8zB,IAAQxtB,EAAE,MAAQ,KAAOA,EAAE,MAAQ,KACrCA,EAAE,iBACFupB,GAAY,SAAS,gBACZiE,IAAQxtB,EAAE,MAAQ,KAAOA,EAAE,MAAQ,KAC5CA,EAAE,iBACForB,GAAA,UACSoC,IAAQxtB,EAAE,MAAQ,KAAOA,EAAE,MAAQ,KAC5CA,EAAE,iBACFspB,GAAY,MAAS,EACrBF,EAAWnpB,GAAM,CAACA,CAAC,UACVutB,GAAOxtB,EAAE,MAAQ,IAC1BA,EAAE,iBACE0pB,IAA8B,EAAK,KACnB,SAAS,UACpB8D,IAAQxtB,EAAE,MAAQ,KAAOA,EAAE,MAAQ,KAC5CA,EAAE,iBACF8pB,EAAa7pB,GAAM,CAACA,CAAC,UACZD,EAAE,MAAQ,UAAYkd,EAAM,KAAM,CAC3C,MAAM5D,EAAStZ,EAAE,OACjB,GAAIsZ,GAAQ,UAAY,SAAWA,GAAQ,UAAY,WAAY,OACnEtZ,EAAE,iBACF0sB,GAAA,CACF,CACF,EACA,cAAO,iBAAiB,UAAW3sB,CAAK,EACjC,IAAM,OAAO,oBAAoB,UAAWA,CAAK,CAC1D,EAAG,CAACF,EAAQqd,EAAM,KAAMwP,GAAOtB,GAAS1B,EAAcW,EAAc,CAAC,EAErE,MAAMhpB,GAAWnB,GAAc,CAC7B,QAAS,IAAM,CACbkrB,GAAA,EACAG,GAAWzsB,EAAE,sBAAsB,CAAC,CACtC,EACA,UAAW,IAAM,CACf+pB,EAAS,CAAE,EAAG,QAAS,EACvB0C,GAAWzsB,EAAE,mBAAmB,CAAC,CACnC,EACA,cAAe,IAAMyqB,GAAY,SAAS,QAC1C,aAAc,IAAMc,GAAe,SAAS,EAC5C,MAAO,IAAML,GAAa,EAAI,EAC9B,MAAA0C,GACA,SAAU,IAAM,CACd,MAAMxnB,EAAO,CAAC,GAAGgY,EAAM,QAAQ,EAAE,UAAU,KAAM1lB,GAAMA,EAAE,OAAS,WAAW,EAC7E,GAAI,CAAC0N,GAAQA,EAAK,OAAS,YAAa,OACxC,MAAMrM,EAAOqM,EAAK,SACf,OAAQ9L,GAA2CA,EAAE,OAAS,MAAM,EACpE,IAAKA,GAAMA,EAAE,IAAI,EACjB,KAAK;AAAA;AAAA,CAAM,EACX,OACCP,IACG,UAAU,UAAU,UAAUA,CAAI,EACvC0yB,GAAWzsB,EAAE,kBAAkB,CAAC,EAEpC,EACA,iBAAkB,IAAM,CACtB2uB,GAAA,CACF,EACA,eAAgB,IAAM,CACpBC,GAAA,CACF,EACA,cAAArC,GACA,OAAQrD,EACR,SAAUC,EACV,KAAM/K,EAAM,KACZ,YAAAgL,EACA,YAAahL,EAAM,SAAS,OAAS,EACtC,EAEK/R,GAA4B,CAChC,CACE,IAAK,QACL,KAAMrM,EAAE,cAAc,EACtB,IAAK,IAAM,CACTuL,GAAS,GAAG,EACZkf,GAAY,SAAS,OACvB,GAEF,CAAE,IAAK,OAAQ,KAAMzqB,EAAE,oBAAoB,EAAG,IAAK,IAAMssB,GAAA,EAAW,GAAI/rB,GAAa,CAAC,MAAO,GAAG,CAAC,GACjG,CAAE,IAAK,SAAU,KAAMP,EAAE,mBAAmB,EAAG,IAAK,IAAM+pB,EAAS,CAAE,EAAG,QAAS,GACjF,CAAE,IAAK,SAAU,KAAM/pB,EAAE,eAAe,EAAG,IAAK,IAAM4tB,KAAS,GAAI,OACnE,CACE,IAAK,QACL,KAAM5tB,EAAE,kBAAkB,EAC1B,IAAK,IAAM,CACT,MAAMoG,EAAO,CAAC,GAAGgY,EAAM,QAAQ,EAAE,UAAU,KAAM1lB,GAAMA,EAAE,OAAS,WAAW,EAC7E,GAAI0N,GAAM,OAAS,YAAa,CAC9B,MAAMrM,EAAOqM,EAAK,SACf,OAAQ9L,GAA2CA,EAAE,OAAS,MAAM,EACpE,IAAKA,GAAMA,EAAE,IAAI,EACjB,KAAK;AAAA;AAAA,CAAM,EACVP,IACG,UAAU,UAAU,UAAUA,CAAI,EACvC0yB,GAAWzsB,EAAE,kBAAkB,CAAC,EAEpC,CACF,GAEF,CAAE,IAAK,SAAU,KAAMA,EAAE,qBAAqB,EAAG,IAAK,IAAMurB,GAAe,QAAQ,GACnF,CAAE,IAAK,SAAU,KAAMvrB,EAAE,qBAAqB,EAAG,IAAKqpB,CAAA,EACtD,CACE,IAAK,YACL,KAAMrpB,EAAE,wBAAwB,EAChC,IAAK0c,CAAA,EAEP,CACE,IAAK,QACL,KAAM1c,EAAE,oBAAoB,EAC5B,IAAK,IAAM,CACT,MAAM6uB,EAAQ7vB,GAAA,EACR4P,EAAOigB,GAAOA,EAAM,QAAQ9vB,GAAA,CAAS,EAAI,GAAK8vB,EAAM,MAAM,GAAK,KACrE3vB,GAAQ0P,CAAI,EACZ,MAAMkgB,EAAW7vB,GAAa2P,CAAI,EAClC6d,GAAWzsB,EAAE,yBAA0B,CAAE,KAAM8uB,CAAA,CAAU,CAAC,CAC5D,GAEF,CACE,IAAK,UACL,KAAM9uB,EAAE,kBAAkB,EAC1B,IAAK,IAAM4uB,GAAA,CAAmB,EAEhC,CACE,IAAK,YACL,KAAM5uB,EAAE,kBAAkB,EAC1B,IAAK,IAAM,CACJvC,GAAQ,iEAAiE,EAAE,MAC9E,MAAM,CAEV,GAEF,CACE,IAAK,WACL,KAAMuC,EAAE,iBAAiB,EACzB,IAAK,IAAMyrB,EAAQ,CAAE,IAAK,kBAAmB,GAE/C,CACE,IAAK,SACL,KAAMzrB,EAAE,eAAe,EACvB,IAAK,IAAMyrB,EAAQ,CAAE,IAAK,QAAS,GAErC,CACE,IAAK,OACL,KAAMzrB,EAAE,aAAa,EACrB,IAAK,IAAM,CAGTuL,GAAS,OAAO,EAChBkf,GAAY,SAAS,OACvB,GAEF,GAAGrM,EAAM,OAAO,IAAK9jB,IAAO,CAC1B,IAAK,IAAIA,EAAE,IAAI,GACf,KAAMA,EAAE,aAAa,QAAU0rB,GAAkB1rB,CAAC,EAClD,WAAY,GACZ,IAAK,IAAM,CACTyvB,EAAS,CACP,EAAG,cACH,MAAO,CAAE,KAAMzvB,EAAE,KAAM,MAAOA,EAAE,OAChC,SAAU,SAAS,KAAK,KAAK,IAAI,KAAK,SAAS,SAAS,EAAE,EAAE,MAAM,EAAG,CAAC,CAAC,GACxE,EACDmxB,EAAQ,CAAE,IAAK,YAAa,KAAMnxB,EAAE,KAAM,CAC5C,GACA,GAGEkkB,GAAUrU,GAAWiU,EAAM,IAAI,EAC/B2Q,GAAiB3Q,EAAM,UAAU,aACnCA,EAAM,SAAS,aAAa,MAAM,OAAO,EAAE,OAAS,YACpD,WACE0K,IAAW,IAAM,CACrB,MAAMkG,EAAY5Q,EAAM,SAAS,KAAM1lB,GAAMA,EAAE,OAAS,MAAM,EAC9D,GAAIs2B,GAAaA,EAAU,OAAS,OAAQ,CAC1C,MAAMC,EAAUD,EAAU,KAAK,QAAQ,OAAQ,GAAG,EAAE,OACpD,GAAIC,EAAS,OAAOA,EAAQ,OAAS,GAAK,GAAGA,EAAQ,MAAM,EAAG,EAAE,CAAC,IAAMA,CACzE,CACA,GAAI7Q,EAAM,eAAgB,CACxB,MAAM9jB,EAAI8jB,EAAM,SAAS,KAAMiC,GAAMA,EAAE,OAASjC,EAAM,cAAc,EACpE,GAAI9jB,GAAG,SAAS,OAAQ,OAAOA,EAAE,QAAQ,OACzC,MAAM5B,EAAI0lB,EAAM,eAAe,MAAM,8CAA8C,EACnF,GAAI1lB,EACF,OAAOsH,EAAE,qBAAsB,CAC7B,MAAOtH,EAAE,CAAC,EACV,IAAKA,EAAE,CAAC,EACR,KAAMA,EAAE,CAAC,EACT,OAAQA,EAAE,CAAC,EACZ,CACL,CACA,OAAO0lB,EAAM,SAAS,SAAW,EAC7Bpe,EAAE,kBAAmB,CAAE,UAAW+uB,EAAA,CAAgB,EAClDA,EACN,KAEMH,GAAqBhL,cAAY,SAAY,CACjD,MAAM8E,EAAY1oB,EAAE,qBAAqB,EACnCkvB,EAAKzG,GAA2BrK,EAAM,SAAUsK,CAAS,EAC/D,GAAI,CAACwG,EAAI,CACPzC,GAAWzsB,EAAE,wBAAwB,CAAC,EACtC,MACF,CACA,GAAI,CACF,MAAMmvB,EAAWtG,GAAsBC,EAAO,EACxCttB,EAAO,MAAM4zB,GAAW,CAC5B,YAAaD,EACb,QAAS,CAAC,CAAE,KAAM,WAAY,WAAY,CAAC,IAAI,EAAG,EAClD,MAAOnvB,EAAE,6BAA6B,EACvC,EACD,GAAI,CAACxE,EAAM,OACX,MAAMgB,GAAO,kBAAmB,CAAE,KAAAhB,EAAM,QAAS0zB,EAAI,EACrDzC,GAAWzsB,EAAE,sBAAsB,CAAC,CACtC,OAAS9G,EAAK,CACZ,QAAQ,MAAM,gBAAiBA,CAAG,EAClCuzB,GAAWzsB,EAAE,yBAA0B,CAAE,MAAO,OAAO9G,CAAG,EAAG,CAAC,CAChE,CACF,EAAG,CAACklB,EAAM,SAAU0K,GAAS2D,EAAU,CAAC,EAElCkC,GAAmB/K,cAAY,IAAM,CACzC,MAAM8E,EAAY1oB,EAAE,qBAAqB,EACnCkvB,EAAKzG,GAA2BrK,EAAM,SAAUsK,CAAS,EAC/D,GAAI,CAACwG,EAAI,CACPzC,GAAWzsB,EAAE,wBAAwB,CAAC,EACtC,MACF,CACK,UAAU,UAAU,UAAUkvB,CAAE,EACrCzC,GAAWzsB,EAAE,oBAAoB,CAAC,CACpC,EAAG,CAACoe,EAAM,SAAUqO,EAAU,CAAC,EAE/B,OACE7rB,MAACqE,GAAA,CACC,MAAO,CAAE,IAAKmZ,EAAM,UAAU,aAAc,OAAQA,EAAM,UAAU,QAEpE,SAAA7a,OAAC,OACC,UAAU,MACV,aAAYS,EACZ,mBAAkBsQ,EAClB,sBAAqBgV,EACrB,qBAAoBC,EACpB,wBAAuBM,GACvB,MAAO,CAAE,QAAS9oB,EAAS,OAAY,QAGvC,UAAAH,MAAC,OACC,UAAU,iBACV,cAAY,OACZ,QAASkpB,CAAA,GAGXlpB,MAACyuB,GAAA,CACC,QAAAvG,GACA,MAAO1K,EAAM,UAAU,MACvB,OAAQ,CAACkL,EACT,MAAO,CAACC,EACR,aAAAC,EACA,YAAAC,EACA,eAAgB,IAAM+B,GAAQ,QAAQ,EAAI,EAC1C,eAAgB,IAAMD,GAAe,SAAS,EAC9C,OAAQoD,GACR,SAAUC,GACV,QAAS,IAAM7E,EAAS,CAAE,EAAG,QAAS,EACtC,YAAa3L,EAAM,SAAS,OAAS,EACrC,eAAAyL,GACA,mBAAAC,CAAA,GAGFlpB,MAAC0uB,GAAA,CACC,KAAM5F,EACN,SAAUC,EACV,UAAWC,EACX,QAAUrf,GAAO,CACXmf,EAAS,QAAU,GACvBltB,GAAO,WAAY,CACjB,KAAM,KAAK,UAAU,CAAE,IAAK,YAAa,MAAO+N,EAAI,EACrD,EAAE,MAAOrR,GAAQ,QAAQ,MAAM,mBAAoBA,CAAG,CAAC,CAC1D,EACA,MAAOgwB,EACP,UAAWQ,EAAS,QAAU,IAGhC9oB,MAACyY,GAAA,CACC,SAAU+E,EAAM,SAChB,WAAYA,EAAM,eAClB,YAAa+M,EACb,UAAW,IAAM,CAAEmB,GAAA,EAAWxC,GAAsBD,IAAkBC,EAAA,CAAsB,EAC5F,cAAgB9f,GAAS,CACnBA,IAASoU,EAAM,gBAAkBpU,IAASmhB,IAC9CC,GAAkBphB,CAAI,EACtByhB,EAAQ,CAAE,IAAK,eAAgB,KAAAzhB,CAAA,CAAM,EAEjC6f,IAAgBC,EAAA,EACtB,EACA,gBAAkB9f,GAASyhB,EAAQ,CAAE,IAAK,iBAAkB,KAAAzhB,EAAM,EAClE,eAAgB,IAAM,CAAEuhB,GAAe,SAAS,EAAO1B,IAAgBC,EAAA,CAAsB,EAC7F,YAAa,IAAM,CAAEyB,GAAe,OAAO,EAAO1B,IAAgBC,EAAA,CAAsB,EACxF,eAAgB,IAAM,CAAE0B,GAAQ,QAAQ,EAAI,EAAO3B,IAAgBC,EAAA,CAAsB,EACzF,YAAa,IAAM,CAAEoB,GAAa,EAAI,EAAOrB,IAAgBC,EAAA,CAAsB,IAGrFlpB,MAAC,QAAK,UAAU,OAAO,MAAO,CAAE,SAAU,YACvC,SAAAwd,EAAM,WACLxd,MAAC2uB,GAAA,CACC,aAAcnR,EAAM,UAAU,aAC9B,gBAAiBmO,GACjB,SAAW3sB,GAAQ6rB,EAAQ,CAAE,IAAK,iBAAkB,IAAA7rB,EAAK,IAG3D2D,OAAAyL,WAAA,CACE,UAAApO,MAAC4uB,GAAA,CACC,QAAA1G,GACA,MAAO1K,EAAM,UAAU,MACvB,aAAcA,EAAM,UAAU,aAC9B,KAAMA,EAAM,KACZ,YAAaA,EAAM,SAAS,OAAS,EACrC,QAASwP,GACT,UAAWtB,GACX,OAAQqC,GACR,SAAUC,GACV,cAAgB/L,GAAW,CACzB2H,GAAY3H,CAAM,EAClByH,EAAU,EAAI,CAChB,IAEF/mB,OAAC,OAAI,UAAU,SAAS,IAAKmnB,GAAW,MAAO,CAAE,SAAU,YACxD,UAAAS,EACC5nB,OAAC,OAAI,UAAU,yBACZ,UAAAvD,EAAE,sBAAsB,EAAE,IAAEmrB,CAAA,EAC/B,EACE,KACJ5nB,OAAC,OAAI,UAAU,eAAe,IAAKonB,EAChC,UAAAvM,EAAM,WACL7a,OAAAyL,WAAA,CACE,UAAApO,MAACygB,GAAA,CACC,KAAMjD,EAAM,WACZ,UAAWA,EAAM,KAAO,OAAY,IAAM2L,EAAS,CAAE,EAAG,eAAgB,IAE1EnpB,MAAC8hB,GAAA,CAAmB,KAAMtE,EAAM,WAAY,GAC9C,EACE,KAEHA,EAAM,SAAS,SAAW,EACzBxd,MAAC6uB,GAAA,CACC,OAAS11B,GAAS,CAChB,MAAM+P,EAAU/P,EAAK,OACrB,GAAI+P,EAAQ,WAAW,GAAG,EAAG,CAC3B,MAAMjO,EAAMiO,EAAQ,MAAM,KAAK,EAAE,CAAC,GAAK,GACjC4lB,EAAQrjB,GAAc,KAAM/R,IAAMA,GAAE,MAAQuB,CAAG,EACrD,GAAI6zB,EAAO,CACTA,EAAM,MACN,MACF,CACF,CACArC,GAAKtzB,CAAI,CACX,EACA,aAAcqkB,EAAM,UAAU,eAE9B,KAEHA,EAAM,SAAS,IAAI,CAAC1lB,EAAGgL,IAAM,CAC5B,GAAIhL,EAAE,OAAS,OAAQ,CACrB,MAAMi3B,EAAe,QAAQj3B,EAAE,IAAI,GAC7BiV,EAAOyQ,EAAM,SAAS1a,EAAI,CAAC,EAC3BksB,GAAe,CAACjiB,GAAQA,EAAK,OAAS,OAC5C,cACG,OACE,UAAAiiB,GAAehvB,MAAC4f,GAAA,CAAY,MAAOmP,CAAA,CAAc,EAAK,WACtDlP,GAAA,CAAQ,KAAM/nB,EAAE,KAAM,MAAOA,EAAE,MAAO,IAF/B,KAAKgL,CAAC,EAGhB,CAEJ,CACA,OAAIhL,EAAE,OAAS,YAEXkI,MAACggB,GAAA,CAOC,SAAUloB,EAAE,SACZ,QAASA,EAAE,QACX,MAAO0lB,EAAM,MACb,iBAAA0C,GACA,gBAAAC,GACA,qBAAAC,GACA,gBAAiB5C,EAAM,iBAPlB,KAAK1a,CAAC,IAWbhL,EAAE,OAAS,QAEX6K,OAAC,OAEC,UAAU,YACV,MAAO,CACL,YAAa,kBACb,WAAY,sBAGd,UAAA3C,MAAC,QAAK,UAAU,MAAM,MAAO,CAAE,MAAO,mBACpC,SAAAA,MAAC8H,EAAE,QAAF,CAAU,KAAM,GAAI,EACvB,SACC,OACC,UAAA9H,MAAC,OAAI,UAAU,KAAM,SAAAZ,EAAE,gBAAgB,EAAE,EACzCY,MAAC,OAAI,UAAU,KAAM,WAAE,QAAQ,GACjC,IAbK,KAAK8C,CAAC,IAiBbhL,EAAE,OAAS,UACT0lB,EAAM,UAAU,mBAAqB,GAAc,YAEpD,OAAe,UAAU,gBAAgB,MAAO1lB,EAAE,KACjD,UAAAkI,MAAC,QAAK,UAAU,OAAO,EACvBA,MAAC,QAAK,UAAU,QAAS,WAAE,KAAK,EAChCA,MAAC,QAAK,UAAU,OAAO,IAHflI,EAAE,EAIZ,EAGG,IACT,CAAC,EAGA0lB,EAAM,aAAa,IAAKre,GACvBa,MAAC6gB,GAAA,CAEC,EAAA1hB,EACA,UAAW,IAAMkuB,GAAYluB,EAAE,GAAI,CAAE,KAAM,UAAW,EACtD,SAAU,IAAMkuB,GAAYluB,EAAE,GAAI,CAAE,KAAM,SAAU,EACpD,SAAU,IAAMkuB,GAAYluB,EAAE,GAAI,CAAE,KAAM,SAAU,GAJ/C,MAAMA,EAAE,EAAE,GAMlB,EACAqe,EAAM,mBAAmB,IAAK,GAC7Bxd,MAACghB,GAAA,CAEC,EACA,WAAY,IAAMsM,GAAkB,EAAE,GAAI,CAAE,KAAM,WAAY,EAC9D,SAAU,IAAMA,GAAkB,EAAE,GAAI,CAAE,KAAM,SAAU,EAC1D,OAAQ,IAAMA,GAAkB,EAAE,GAAI,CAAE,KAAM,OAAQ,GAJjD,MAAM,EAAE,EAAE,GAMlB,EACA9P,EAAM,iBAAiB,IAAKrjB,GAC3B6F,MAACmhB,GAAA,CAEC,EAAAhnB,EACA,SAAU,IAAMozB,GAAgBpzB,EAAE,GAAI,CAAE,KAAM,WAAY,EAC1D,SAAU,IAAMozB,GAAgBpzB,EAAE,GAAI,CAAE,KAAM,WAAY,GAHrD,MAAMA,EAAE,EAAE,GAKlB,EACAqjB,EAAM,gBAAgB,IAAK,GAC1Bxd,MAACqhB,GAAA,CAEC,EACA,QAAS,IAAM4L,GAAe,EAAE,GAAI,CAAE,KAAM,WAAY,EACxD,cAAgBxnB,GACdwnB,GAAe,EAAE,GAAI,CAAE,KAAM,eAAgB,OAAAxnB,EAAQ,EAEvD,OAAQ,IAAMwnB,GAAe,EAAE,GAAI,CAAE,KAAM,OAAQ,GAN9C,MAAM,EAAE,EAAE,GAQlB,EACAzP,EAAM,kBAAkB,IAAKre,GAC5Ba,MAACyhB,GAAA,CAEC,EAAAtiB,EACA,QAAS,IAAMguB,GAAkBhuB,EAAE,GAAI,CAAE,KAAM,WAAY,EAC3D,cAAgBsG,GACd0nB,GAAkBhuB,EAAE,GAAI,CAAE,KAAM,eAAgB,OAAAsG,EAAQ,EAE1D,OAAQ,IAAM0nB,GAAkBhuB,EAAE,GAAI,CAAE,KAAM,OAAQ,GANjD,MAAMA,EAAE,EAAE,GAQlB,EACAqe,EAAM,eAAe,IAAK,GACzBxd,MAAC2hB,GAAA,CAEC,EACA,OAASsN,GAAa7B,GAAc,EAAE,GAAI,CAAE,KAAM,OAAQ,SAAA6B,EAAU,EACpE,SAAU,IAAM7B,GAAc,EAAE,GAAI,CAAE,KAAM,SAAU,GAHjD,MAAM,EAAE,EAAE,GAKlB,EAEC5P,EAAM,MAWJ,KAVFxd,MAAC,OACC,MAAO,CACL,QAAS,GACT,MAAO,eACP,WAAY,wBACZ,SAAU,IAGX,WAAE,gBAAgB,GAEnB,EACN,EACC2jB,GACC3jB,MAAC,UACC,UAAU,qBACV,QAAS,IAAMkkB,GAAe,EAAI,EAClC,MAAO9kB,EAAE,kBAAkB,GAAK,iBAChC,aAAYA,EAAE,kBAAkB,GAAK,iBAErC,SAAAY,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,IAElB,MACN,EAEA9H,MAACyK,GAAA,CACC,MAAAC,GACA,SAAAC,GACA,OAAQ,IAAM8hB,GAAA,EACd,QAASO,GACT,SAAU,CAACxP,EAAM,MACjB,KAAMA,EAAM,KACZ,UACEA,EAAM,KACFA,EAAM,YACJ,WAAWA,EAAM,YAAY,IAAI,GACjC,YACF,OAEN,cAAeI,GACf,YAAaiM,GACb,WAAYrM,EAAM,UAAU,OAAS,oBACrC,gBAAiBA,EAAM,UAAU,iBAAmB,OACpD,cAAgBK,GAAU,CACxBoN,GAAa,CAAE,MAAApN,EAAO,EACtBgO,GAAWzsB,EAAE,0BAA2B,CAAE,MAAAye,CAAA,CAAO,CAAC,CACpD,EACA,eAAiB1S,GAAoB,CACnC8f,GAAa,CAAE,gBAAA9f,EAAiB,EAChC0gB,GAAWzsB,EAAE,2BAA4B,CAAE,OAAQ+L,CAAA,CAAiB,CAAC,CACvE,EACA,SAAUqS,EAAM,UAAU,UAAY,SACtC,iBAAmBzT,GAAS,CAC1BkhB,GAAa,CAAE,SAAUlhB,EAAM,EAC3BA,IAAS,OACX8hB,GAAWzsB,EAAE,gBAAgB,EAAG,CAAE,KAAM,GAAM,SAAU,IAAM,EAE9DysB,GAAWzsB,EAAE,yBAA0B,CAAE,KAAM2K,EAAK,aAAY,CAAG,CAAC,CAExE,EACA,aAAcyT,EAAM,UAAU,aAC9B,cAAA/R,GACA,eAAgBqf,GAChB,iBAAkBC,GAClB,gBAAiBC,GACjB,eAAgBxN,EAAM,eACtB,YAAaA,EAAM,YACnB,iBAAmBrkB,GAAS,CAC1BgwB,EAAS,CAAE,EAAG,eAAgB,KAAAhwB,CAAA,CAAM,EACpCwR,GAAS,EAAE,CACb,EACA,cAAgB1K,GAAUkpB,EAAS,CAAE,EAAG,eAAgB,MAAAlpB,EAAO,GACjE,EACF,EAEJ,EAEAD,MAACsP,GAAA,CACC,SAAUkO,EAAM,SAChB,MAAOA,EAAM,MACb,SAAUA,EAAM,SAChB,WAAYA,EAAM,WAClB,aAAcA,EAAM,aACpB,OAAQA,EAAM,OACd,aAAcA,EAAM,aACpB,aAAe5iB,GAASiwB,EAAQ,CAAE,IAAK,cAAe,KAAAjwB,EAAM,IAG9DoF,MAAC0b,GAAA,CACC,SAAU8B,EAAM,SAChB,QAASA,EAAM,QACf,MAAOA,EAAM,MACb,KAAMA,EAAM,KACZ,MAAOA,EAAM,MACb,SAAA/J,EACA,MAAArQ,EACA,WAAAsQ,EACA,KAAM8J,EAAM,KACZ,SAAA5B,EACA,aAAc,IAAMwO,EAAa7pB,GAAM,CAACA,CAAC,EACzC,gBAAAqT,EACA,iBAAAkI,EACA,eAAgB,IAAM6O,GAAe,SAAS,EAC9C,cAAgB1I,GAAW,CACzB2H,GAAY3H,CAAM,EAClByH,EAAU,EAAI,CAChB,IAGF1pB,MAACyB,GAAA,CACC,KAAMmpB,GAAQ,KACd,QAAS,IAAMA,GAAQ,QAAQ,EAAK,EACpC,SAAAjpB,EAAA,GAGF3B,MAAC+hB,GAAA,CACC,KAAM0H,EACN,QAAS,IAAMC,EAAU,EAAK,EAC9B,OAAQlM,EAAM,UAAU,kBAAoB,GAC5C,QAASA,EAAM,UAAU,aACzB,OAAQmM,EACR,OAAS/uB,GAASqwB,GAAa,CAAE,aAAcrwB,EAAM,EACrD,SAAU+wB,EAAA,GAGZ3rB,MAACsiB,GAAA,CACC,KAAMmI,GACN,YAAajN,EAAM,UAAU,aAC7B,SAAU,IAAMkN,GAAoB,EAAK,EACzC,UAAY9vB,GAAS,CACnBqwB,GAAa,CAAE,aAAcrwB,EAAM,EACnC8vB,GAAoB,EAAK,CAC3B,IAGDL,QAAa9X,GAAA,CAAW,QAAS,IAAM+X,GAAa,EAAK,EAAG,EAAK,KAEjEN,GAAgBxM,EAAM,SACrBxd,MAACuT,GAAA,CACC,SAAUiK,EAAM,SAChB,QAASA,EAAM,QACf,MAAOA,EAAM,MACb,SAAA/J,EACA,MAAArQ,EACA,WAAAsQ,EACA,WAAAC,EACA,gBAAAC,EACA,UAAAC,EACA,eAAAC,EACA,WAAAC,EACA,gBAAAC,EACA,YAAakW,EACb,SAAU1M,EAAM,SAChB,WAAYA,EAAM,WAClB,OAAQA,EAAM,OACd,OAAQA,EAAM,OACd,aAAcA,EAAM,aACpB,GAAIA,EAAM,GACV,QAAS,IAAMyM,EAAgB,EAAK,EACpC,OAAQgB,GACR,aAAcK,GACd,SAAUJ,GACV,YAAaC,GACb,eAAgBC,GAChB,eAAgBC,GAChB,kBAAmB,IACjBxuB,GAAQ,4CAA4C,EAAE,MAAM,MAAe,EAE7E,gBAAiB8uB,GACjB,aAAcJ,GACd,gBAAiBE,GACjB,aAAe7wB,GAASiwB,EAAQ,CAAE,IAAK,cAAe,KAAAjwB,EAAM,IAE5D,KAEJoF,MAACwR,GAAA,CACC,KAAMoK,EACN,QAAS,IAAMwO,EAAY,EAAK,EAChC,KAAM5M,EAAM,KACZ,OAAS0R,GAAUrE,EAAQ,CAAE,IAAK,YAAa,MAAAqE,EAAO,EACtD,UAAW,IAAMrE,EAAQ,CAAE,IAAK,gBAAiB,IAGnD7qB,MAAC+C,GAAA,CAAM,QAASsmB,EAAA,CAAO,EAEtBE,SAAY3O,GAAA,CAAO,OAAQ,IAAM4O,GAAY,EAAK,EAAG,EAAK,OAC7D,EAGN,CAEA,SAAS2F,IAAc,CACrB,aACG,OAAI,MAAM,KAAK,OAAO,IAAI,QAAQ,WAAW,cAAW,GACvD,SAAAnvB,MAAC,QAAK,MAAM,KAAK,OAAO,IAAI,KAAK,eAAe,EAClD,CAEJ,CACA,SAASovB,IAAc,CACrB,OACEpvB,MAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,cAAW,GACzD,SAAAA,MAAC,QAAK,EAAE,MAAM,EAAE,MAAM,MAAM,IAAI,OAAO,IAAI,KAAK,OAAO,OAAO,eAAe,YAAY,IAAI,EAC/F,CAEJ,CACA,SAASqvB,IAAa,CACpB,OACE1sB,OAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,cAAW,GACzD,UAAA3C,MAAC,QAAK,EAAE,MAAM,EAAE,MAAM,MAAM,IAAI,OAAO,IAAI,KAAK,OAAO,OAAO,eAAe,YAAY,IAAI,EAC7FA,MAAC,QAAK,EAAE,MAAM,EAAE,MAAM,MAAM,IAAI,OAAO,IAAI,KAAK,oBAAoB,OAAO,eAAe,YAAY,IAAI,GAC5G,CAEJ,CACA,SAASsvB,IAAW,CAClB,OACE3sB,OAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,cAAW,GACzD,UAAA3C,MAAC,QAAK,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,OAAO,eAAe,YAAY,MAAM,cAAc,QAAQ,EACxGA,MAAC,QAAK,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,OAAO,eAAe,YAAY,MAAM,cAAc,QAAQ,GAC1G,CAEJ,CAEA,SAASyuB,GAAS,CAChB,QAAAvG,EACA,MAAArK,EACA,OAAA0R,EACA,MAAAC,EACA,aAAA5G,EACA,YAAAC,EACA,eAAA3P,EACA,eAAAF,EACA,OAAAvR,EACA,SAAAgoB,EACA,QAAAC,EACA,YAAAC,EACA,eAAA1G,EACA,mBAAAC,CACF,EAgBG,CACD3qB,EAAA,EACA,KAAM,CAACqxB,EAAUC,CAAW,EAAIpxB,WAAS,EAAK,EACxC,CAACqxB,EAAaC,CAAc,EAAItxB,WAAS,EAAK,EAC9CuxB,EAAchuB,SAAuB,IAAI,EACzCiuB,EAAQ,SAAS,gBAAgB,QAAQ,WAAa,QAEtDC,EAAQ,SAAS,gBAAgB,QAAQ,MAAQ,OAEvDxxB,YAAU,IAAM,CACd,MAAMyxB,EAAM1zB,GAAA,EACZ0zB,EAAI,cAAc,KAAKJ,CAAc,EACrC,IAAI/D,EACJmE,SAAI,OAAO,iBAAkB,SAAY,CACvCJ,EAAe,MAAMI,EAAI,aAAa,CACxC,CAAC,EAAE,KAAMC,IAAiC,CAAEpE,EAAWoE,EAAI,CAAC,EACrD,IAAMpE,IAAA,CACf,EAAG,EAAE,EAELttB,YAAU,IAAM,CACd,GAAI,CAACkxB,EAAU,OACf,MAAM5iB,EAAU1M,GAAkB,CAC5B0vB,EAAY,SAAW,CAACA,EAAY,QAAQ,SAAS1vB,EAAE,MAAc,GACvEuvB,EAAY,EAAK,CACrB,EACA,cAAO,iBAAiB,YAAa7iB,CAAM,EACpC,IAAM,OAAO,oBAAoB,YAAaA,CAAM,CAC7D,EAAG,CAAC4iB,CAAQ,CAAC,EAEb,MAAMO,EAAM1zB,GAAA,EAEZ,OACEkG,OAAC,UAAO,UAAU,WAEhB,UAAAA,OAAC,OAAI,UAAU,UACZ,UAAAstB,GAAS,CAACC,EACTvtB,OAAC,OAAI,UAAU,eAAe,aAAYvD,EAAE,6BAA6B,EACvE,UAAAY,MAAC,UACC,KAAK,SACL,UAAU,iBACV,MAAOZ,EAAE,oBAAoB,EAC7B,aAAYA,EAAE,oBAAoB,EAClC,YAAckB,GAAM,CAClBA,EAAE,kBACF6vB,EAAI,OACN,EAEA,eAACb,GAAA,EAAS,IAEZtvB,MAAC,UACC,KAAK,SACL,UAAU,oBACV,MAAOZ,EAAE,uBAAuB,EAChC,aAAYA,EAAE,uBAAuB,EACrC,YAAckB,GAAM,CAClBA,EAAE,kBACF6vB,EAAI,UACN,EAEA,eAAChB,GAAA,EAAY,IAEfnvB,MAAC,UACC,KAAK,SACL,UAAU,gBACV,MAAqBZ,EAAd0wB,EAAgB,uBAA4B,uBAAN,EAC7C,aAA0B1wB,EAAd0wB,EAAgB,uBAA4B,uBAAN,EAClD,YAAcxvB,GAAM,CAClBA,EAAE,kBACF6vB,EAAI,gBACN,EAEC,SAAAL,EAAc9vB,MAACqvB,GAAA,EAAW,QAAMD,GAAA,EAAY,GAC/C,EACF,EACE,KAEJpvB,MAAC,UACC,KAAK,SACL,UAAU,iBACV,aAAW,SACX,gBAAeipB,EACf,QAASC,EAER,SAAAD,EAAiBjpB,MAAC8H,EAAE,EAAF,CAAI,KAAM,GAAI,EAAK9H,MAAC8H,EAAE,QAAF,CAAU,KAAM,GAAI,IAG7D9H,MAAC,UACC,KAAK,SACL,UAAU,8BACV,UAASuvB,EACT,MAAO1vB,GAAqBT,EAAE,sBAAsB,CAAC,EACrD,QAASwpB,EAET,SAAA5oB,MAAC8H,EAAE,QAAF,CAAU,KAAM,GAAI,IAEvBnF,OAAC,OAAI,UAAU,UAAU,yBAAsB,GAC7C,UAAAA,OAAC,OAAI,UAAU,QAAQ,yBAAsB,GAC3C,UAAA3C,MAAC,QAAK,UAAU,OAAO,EACvBA,MAAC,QAAK,UAAU,aAAa,oBAAQ,GACvC,EACCkoB,GACCvlB,OAAC,OAAI,UAAU,SAAS,yBAAsB,GAC5C,UAAA3C,MAAC,QAAK,UAAU,MAAM,aAAC,EACvBA,MAAC,QAAK,UAAU,MAAO,YAAS,IAAI,GACtC,GAEJ,GACF,EAGAA,MAAC,QAAK,UAAU,OAAO,yBAAsB,GAAC,EAG9C2C,OAAC,OAAI,UAAU,WACb,UAAA3C,MAAC,UACC,KAAK,SACL,UAAU,UACV,UAASwvB,EACT,MAAOpwB,EAAE,2BAA2B,EACpC,QAASypB,EAET,SAAA7oB,MAAC8H,EAAE,QAAF,CAAU,KAAM,GAAI,IAGvBnF,OAAC,OAAI,IAAKqtB,EAAa,MAAO,CAAE,SAAU,YACxC,UAAAhwB,MAAC,UACC,KAAK,SACL,UAAU,UACV,MAAOZ,EAAE,mBAAmB,EAC5B,QAAS,IAAMywB,EAAatvB,GAAM,CAACA,CAAC,EAEpC,SAAAP,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,IAEnB8nB,EACC5vB,MAAC,OACC,UAAU,QACV,MAAO,CAAE,IAAK,mBAAoB,MAAO,EAAG,KAAM,OAAQ,OAAQ,OAAQ,MAAO,KAEjF,SAAA2C,OAAC,OAAI,UAAU,aACb,UAAAA,OAAC,OAAI,UAAU,aAAa,QAAS,IAAM,CAAEuW,EAAA,EAAkB2W,EAAY,EAAK,CAAG,EACjF,UAAA7vB,MAAC,QAAK,UAAU,MAAM,SAAAA,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EAAE,EAC5C9H,MAAC,OAAI,UAAU,KAAK,eAAC,QAAM,SAAAZ,EAAE,6BAA6B,EAAE,EAAO,EACnEY,MAAC,QAAK,UAAU,KACd,SAAAA,MAACF,EAAA,CAAS,KAAM,CAAC,MAAO,GAAG,EAAG,EAChC,GACF,EACA6C,OAAC,OACC,UAAU,aACV,QAAS,IAAM,CAAMgtB,GAAaloB,EAAA,EAAUooB,EAAY,EAAK,CAAG,EAChE,MAAO,CAAE,QAASF,EAAc,EAAI,IAEpC,UAAA3vB,MAAC,QAAK,UAAU,MAAM,SAAAA,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EAAE,EAC1C9H,MAAC,OAAI,UAAU,KAAK,eAAC,QAAM,SAAAZ,EAAE,qBAAqB,EAAE,EAAO,KAE7DuD,OAAC,OACC,UAAU,aACV,QAAS,IAAM,CAAMgtB,GAAaF,EAAA,EAAYI,EAAY,EAAK,CAAG,EAClE,MAAO,CAAE,QAASF,EAAc,EAAI,IAEpC,UAAA3vB,MAAC,QAAK,UAAU,MAAM,SAAAA,MAAC8H,EAAE,SAAF,CAAW,KAAM,GAAI,EAAE,EAC9C9H,MAAC,OAAI,UAAU,KAAK,eAAC,QAAM,SAAAZ,EAAE,uBAAuB,EAAE,EAAO,KAE/DuD,OAAC,OAAI,UAAU,aAAa,QAAS,IAAM,CAAE+sB,EAAA,EAAWG,EAAY,EAAK,CAAG,EAC1E,UAAA7vB,MAAC,QAAK,UAAU,MAAM,SAAAA,MAAC8H,EAAE,EAAF,CAAI,KAAM,GAAI,EAAE,EACvC9H,MAAC,OAAI,UAAU,KAAK,eAAC,QAAM,SAAAZ,EAAE,wBAAwB,EAAE,EAAO,GAChE,EACAuD,OAAC,OAAI,UAAU,aAAa,QAAS,IAAM,CAAEqW,EAAA,EAAkB6W,EAAY,EAAK,CAAG,EACjF,UAAA7vB,MAAC,QAAK,UAAU,MAAM,SAAAA,MAAC8H,EAAE,IAAF,CAAM,KAAM,GAAI,EAAE,EACzC9H,MAAC,OAAI,UAAU,KAAK,eAAC,QAAM,SAAAZ,EAAE,uBAAuB,EAAE,EAAO,EAC7DY,MAAC,QAAK,UAAU,KACd,SAAAA,MAACF,EAAA,CAAS,KAAM,CAAC,MAAO,GAAG,EAAG,EAChC,GACF,GACF,IAEA,MACN,EAGC,CAACmwB,GAAS,CAACC,EACVvtB,OAAC,OAAI,UAAU,eACb,UAAA3C,MAAC,UACC,KAAK,SACL,UAAU,WACV,MAAOZ,EAAE,uBAAuB,EAChC,YAAckB,GAAM,CAAEA,EAAE,kBAAmB6vB,EAAI,UAAY,EAE3D,eAAChB,GAAA,EAAY,IAEfnvB,MAAC,UACC,KAAK,SACL,UAAU,WACV,MAAqBZ,EAAd0wB,EAAgB,uBAA4B,uBAAN,EAC7C,YAAcxvB,GAAM,CAAEA,EAAE,kBAAmB6vB,EAAI,gBAAkB,EAEhE,SAAAL,EAAc9vB,MAACqvB,GAAA,EAAW,QAAMD,GAAA,EAAY,IAE/CpvB,MAAC,UACC,KAAK,SACL,UAAU,iBACV,MAAOZ,EAAE,oBAAoB,EAC7B,YAAckB,GAAM,CAAEA,EAAE,kBAAmB6vB,EAAI,OAAS,EAExD,eAACb,GAAA,EAAS,GACZ,EACF,EACE,MACN,GACF,CAEJ,CAEA,SAASZ,GAAO,CACd,KAAA2B,EACA,SAAAC,EACA,UAAAxuB,EACA,QAAAJ,EACA,MAAA6uB,EACA,UAAAC,CACF,EAOG,CACD,OAAAjyB,EAAA,QAEG,OAAI,UAAU,SACZ,SAAA8xB,EAAK,IAAKjxB,GAAM,CACf,MAAMoF,EAAKpF,EAAE,cAAgB,GACvBqe,EACJjZ,EACG,QAAQ,SAAU,EAAE,EACpB,MAAM,OAAO,EACb,OAAS,YACd,OACE7B,OAAC,OAEC,UAAU,MACV,cAAavD,EAAE,KAAOkxB,EACtB,QAAS,IAAMxuB,EAAU1C,EAAE,EAAE,EAC7B,MAAOoF,GAAMiZ,EAEb,UAAAzd,MAAC,QAAK,UAAU,MAAM,aAAW,UAAU,EAC3CA,MAAC,QAAK,UAAU,QAAS,SAAAyd,EAAM,EAC7B+S,EAUE,KATFxwB,MAAC,QACC,UAAU,QACV,QAAUM,GAAM,CACdA,EAAE,kBACFoB,EAAQtC,EAAE,EAAE,CACd,EAEA,SAAAY,MAAC8H,EAAE,EAAF,CAAI,KAAM,GAAI,GAEf,GAlBC1I,EAAE,GAqBb,CAAC,EACH,CAEJ,CAEA,SAASwvB,GAAS,CAChB,QAAA1G,EACA,MAAArK,EACA,aAAA/R,EACA,KAAAf,EACA,YAAA4kB,EACA,QAAA9kB,EACA,UAAAgO,EACA,OAAApR,EACA,SAAAgoB,EACA,cAAA1T,CACF,EAWG,CACDxd,EAAA,EACA,MAAMkyB,EAAU3kB,EACZA,EAAa,MAAM,OAAO,EAAE,OAAS,YACrC1M,EAAE,wBAAwB,EAC9B,OACEuD,OAAC,OAAI,UAAU,YACb,UAAAA,OAAC,OAAI,UAAU,aACb,UAAAA,OAAC,MACC,UAAA3C,MAAC,QAAK,UAAU,WAAY,SAAAkoB,EAAQ,EACnCnd,SACE,QAAK,UAAU,OAAO,MAAO,CAAE,MAAO,iBACrC,UAAA/K,MAAC,QAAK,UAAU,MAAM,QACrB,QAAK,UAAU,UAAW,SAAAZ,EAAE,oBAAoB,EAAE,GACrD,EACE,MACN,EACAuD,OAAC,OAAI,UAAU,MACb,UAAAA,OAAC,QACC,UAAU,WACV,QAAUrC,GAAM,CACd,MAAMnG,EAAKmG,EAAE,cAA8B,wBAC3Cyb,EAAc,CAAE,IAAK5hB,EAAE,OAAS,EAAG,KAAMA,EAAE,KAAM,CACnD,EACA,MAAO,CAAE,OAAQ,WACjB,MAAO2R,GAAgB1M,EAAE,0BAA0B,EAEnD,UAAAY,MAAC8H,EAAE,OAAF,CAAS,KAAM,GAAI,EAAE,IAAE2oB,CAAA,IAEzB5S,EACClb,OAAC,QAAK,UAAU,OACd,UAAA3C,MAAC8H,EAAE,MAAF,CAAQ,KAAM,GAAI,EAAE,IAAE+V,CAAA,EACzB,EACE,MACN,GACF,EACA7d,MAAC,QAAK,UAAU,OAAO,EACvB2C,OAAC,UACC,KAAK,SACL,UAAU,QACV,QAAS8E,EACT,SAAU,CAACkoB,EACX,MAAOvwB,EAAE,mBAAmB,EAE5B,UAAAY,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EAAE,IAAE1I,EAAE,iBAAiB,KAE3CuD,OAAC,UACC,KAAK,SACL,UAAU,QACV,QAAS8sB,EACT,SAAU,CAACE,EACX,MAAOvwB,EAAE,qBAAqB,EAE9B,UAAAY,MAAC8H,EAAE,SAAF,CAAW,KAAM,GAAI,EAAE,IAAE1I,EAAE,mBAAmB,YAEhD,UAAO,KAAK,SAAS,UAAU,QAAQ,QAASyZ,EAC/C,UAAA7Y,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EAAE,IAAE1I,EAAE,oBAAoB,GAC9C,EACC2L,SACE,UAAO,KAAK,SAAS,UAAU,gBAAgB,QAASF,EACvD,UAAA7K,MAAC8H,EAAE,KAAF,CAAO,KAAM,GAAI,EAAE,IAAE1I,EAAE,kBAAkB,GAC5C,EACE,MACN,CAEJ,CAEA,SAASyvB,GAAW,CAClB,OAAAlgB,EACA,aAAA7C,CACF,EAGG,CACDvN,EAAA,EACA,MAAMmyB,EAAc,CAClBtxB,EAAE,uBAAuB,EACzBA,EAAE,uBAAuB,EACzBA,EAAE,uBAAuB,EACzBA,EAAE,uBAAuB,EACzB,SAEIqxB,EAAU3kB,EAAeA,EAAa,MAAM,OAAO,EAAE,MAAQ,KACnE,OACEnJ,OAAC,OACC,MAAO,CACL,QAAS,iBACT,UAAW,SACX,MAAO,eACP,WAAY,yCAGd,UAAA3C,MAAC,OACC,MAAO,CACL,MAAO,GACP,OAAQ,GACR,aAAc,GACd,OAAQ,cACR,WAAY,wDACZ,SAAU,YAGZ,SAAAA,MAAC,QACC,MAAO,CACL,SAAU,WACV,MAAO,EACP,aAAc,EACd,WAAY,YACd,EACF,GAEFA,MAAC,OAAI,MAAO,CAAE,SAAU,GAAI,WAAY,IAAK,MAAO,YAAa,aAAc,GAC5E,SAAAZ,EAAE,mBAAmB,EACxB,EACAY,MAAC,OAAI,MAAO,CAAE,SAAU,GAAI,aAAc,IACvC,SAAAywB,EACC9tB,OAAAyL,WAAA,CACG,UAAAhP,EAAE,4BAA4B,QAC9B,QAAK,MAAO,CAAE,WAAY,yBAA4B,SAAAqxB,CAAA,CAAQ,GACjE,EAEArxB,EAAE,2BAA2B,EAEjC,EACAY,MAAC,OACC,MAAO,CACL,QAAS,OACT,SAAU,OACV,IAAK,EACL,eAAgB,SAChB,SAAU,IACV,OAAQ,UAGT,SAAA0wB,EAAY,IAAKh3B,GAChBsG,MAAC,UAEC,KAAK,SACL,UAAU,MACV,MAAO,CAAE,SAAU,MACnB,QAAS,IAAM2O,EAAOjV,CAAC,EAEtB,SAAAA,CAAA,EANIA,CAAA,CAQR,GACH,GAGN,CAEA,SAASi1B,GAAe,CACtB,aAAA7iB,EACA,gBAAA4I,EACA,SAAAic,CACF,EAIG,CACDpyB,EAAA,EACA,KAAM,CAACS,EAAKiY,CAAM,EAAIxY,WAAS,EAAE,EACjC,OACEkE,OAAC,OACC,MAAO,CACL,KAAM,EACN,QAAS,OACT,cAAe,SACf,WAAY,SACZ,eAAgB,SAChB,QAAS,GACT,IAAK,IAGP,UAAA3C,MAAC,OAAI,MAAO,CAAE,SAAU,GAAI,WAAY,KAAQ,SAAAZ,EAAE,mBAAmB,EAAE,EACvEY,MAAC,OAAI,MAAO,CAAE,SAAU,KAAM,MAAO,eAAgB,SAAU,IAAK,UAAW,UAC5E,SAAAZ,EAAE,uBAAuB,EAC5B,EACAuD,OAAC,OACC,MAAO,CACL,MAAO,mBACP,QAAS,OACT,cAAe,SACf,IAAK,IAGP,UAAAA,OAAC,OAAI,UAAU,cAAc,MAAO,CAAE,aAAc,QAClD,UAAAA,OAAC,OAAI,UAAU,IACb,UAAA3C,MAAC,OAAI,UAAU,IAAK,SAAAZ,EAAE,qBAAqB,EAAE,QAC5C,OAAI,UAAU,IAAK,SAAA0M,GAAgB1M,EAAE,uBAAuB,EAAE,GACjE,EACAY,MAAC,UAAO,KAAK,SAAS,UAAU,MAAM,QAAS0U,EAC5C,SAAAtV,EAAE,kBAAkB,EACvB,GACF,EACAY,MAAC,SACC,UAAU,aACV,KAAK,WACL,MAAOhB,EACP,SAAWsB,GAAM2W,EAAO3W,EAAE,OAAO,KAAK,EACtC,YAAY,OACZ,MAAO,CAAE,MAAO,OAAO,GAEzBN,MAAC,UACC,KAAK,SACL,UAAU,cACV,SAAU,CAAChB,EAAI,OACf,QAAS,IAAM2xB,EAAS3xB,EAAI,MAAM,EAEjC,WAAE,wBAAwB,GAC7B,GACF,GAGN,CAWO,SAAS4xB,IAAM,CACpB,KAAM,CAACP,EAAMQ,CAAO,EAAIpyB,WAAoB,EAAE,EACxC,CAACsqB,EAAaC,CAAc,EAAIvqB,WAAiB,EAAE,EACnDqyB,EAAiB9uB,SAAmC,IAAI,GAAK,EAC7D+uB,EAAmB/uB,SAAiC,IAAI,GAAK,EAC7DgvB,EAAmBhvB,SAAsC,IAAI,GAAK,EAClEivB,EAAkBjvB,SAAO,EAAK,EAC9BkvB,EAAUlvB,SAAkB,EAAE,EACpCtD,YAAU,IAAM,CACdwyB,EAAQ,QAAUb,CACpB,EAAG,CAACA,CAAI,CAAC,EAET,KAAM,CAAC5c,EAAU0d,CAAW,EAAI1yB,WAAwB,IAC5C,aAAa,QAAQ,mBAAmB,IACrC,MAAQ,MAAQ,KAC9B,EACK,CAAC2E,EAAOC,CAAQ,EAAI5E,WAAgB,IAAM,CAC9C,MAAM8B,EAAI,aAAa,QAAQ,gBAAgB,EACzCiI,EAAQ,aAAa,QAAQ,qBAAqB,EACxD,OAAIF,GAAaE,CAAK,EAAUD,GAAcC,CAAK,EAC5CR,GAAQzH,CAAC,EAAIA,EAAIwH,GAAM,IAChC,CAAC,EACK,CAAC2L,EAAY0d,CAAa,EAAI3yB,WAAqB,IAAM,CAC7D,MAAM+J,EAAQ,aAAa,QAAQ,qBAAqB,EACxD,GAAIF,GAAaE,CAAK,EAAG,OAAOA,EAChC,MAAM6oB,EAAc,aAAa,QAAQ,gBAAgB,EACzD,OAAO5oB,GAAqBT,GAAQqpB,CAAW,EAAIA,EAActpB,GAAM,IAAI,CAC7E,CAAC,EACK,CAAC8L,EAAWyd,CAAY,EAAI7yB,WAAoB,IAAM,CAC1D,MAAM8B,EAAI,aAAa,QAAQ,oBAAoB,EACnD,OAAOoI,GAAYpI,CAAC,EAAIA,EAAImI,GAAW,MACzC,CAAC,EACK,CAACqL,EAAYwd,CAAa,EAAI9yB,WAAqB,IAAM,CAC7D,MAAM8B,EAAI,aAAa,QAAQ,qBAAqB,EACpD,OAAOuI,GAAavI,CAAC,EAAIA,EAAIsI,GAAY,IAC3C,CAAC,EACK,CAAC6f,EAAe8I,CAAgB,EAAI/yB,WACxC,IAAM,aAAa,QAAQ,wBAAwB,IAAM,KAErD,CAACkqB,EAAc8I,CAAe,EAAIhzB,WACtC,IAAM,aAAa,QAAQ,uBAAuB,IAAM,KAG1DC,YAAU,IAAM,CACd,SAAS,gBAAgB,QAAQ,MAAQ0E,EACzC,SAAS,gBAAgB,QAAQ,WAAasQ,EAC9C,aAAa,QAAQ,iBAAkBtQ,CAAK,EAC5C,aAAa,QAAQ,sBAAuBsQ,CAAU,CACxD,EAAG,CAACtQ,EAAOsQ,CAAU,CAAC,EAEtBhV,YAAU,IAAM,CACd,aAAa,QAAQ,yBAA0BgqB,EAAgB,IAAM,GAAG,CAC1E,EAAG,CAACA,CAAa,CAAC,EAElBhqB,YAAU,IAAM,CACd,aAAa,QAAQ,wBAAyBiqB,EAAe,IAAM,GAAG,CACxE,EAAG,CAACA,CAAY,CAAC,EAEjBjqB,YAAU,IAAM,CAEd,SAAS,gBAAgB,MAAM,YAAY,OAAQ,OAAOkK,GAAgBiL,CAAS,CAAC,CAAC,EACrF,aAAa,QAAQ,qBAAsBA,CAAS,CACtD,EAAG,CAACA,CAAS,CAAC,EAEdnV,YAAU,IAAM,CAEd,SAAS,gBAAgB,MAAM,YAAY,cAAeqK,GAAkBgL,CAAU,CAAC,EACvF,aAAa,QAAQ,sBAAuBA,CAAU,CACxD,EAAG,CAACA,CAAU,CAAC,EAEfrV,YAAU,IAAM,CACd,MAAMgzB,EAASpxB,GAAa,CAC1B,MAAMgR,EAAUhR,EAAkB,QAC9BgR,IAAW,OAASA,IAAW,UAAmBA,CAAM,CAC9D,EACA,cAAO,iBAAiB,oBAAqBogB,CAAK,EAC3C,IAAM,OAAO,oBAAoB,oBAAqBA,CAAK,CACpE,EAAG,EAAE,EAEL,MAAMC,EAAe3O,cAAY,CAACoF,EAAe3C,IAAsB,CACrE,MAAM0D,EAAW2H,EAAe,QAAQ,IAAI1I,CAAK,EACjD,GAAIe,EACFA,EAAS1D,CAAM,MACV,CACL,MAAMmM,GAAMb,EAAiB,QAAQ,IAAI3I,CAAK,GAAK,GACnDwJ,GAAI,KAAKnM,CAAM,EACfsL,EAAiB,QAAQ,IAAI3I,EAAOwJ,EAAG,CACzC,CACF,EAAG,EAAE,EAECvJ,GAAmBrF,cAAY,CAACoF,EAAe5P,IAA4B,CAC/E,GAAIA,EAAG,CACLsY,EAAe,QAAQ,IAAI1I,EAAO5P,CAAC,EACnC,MAAMoZ,EAAMb,EAAiB,QAAQ,IAAI3I,CAAK,EAC9C,GAAIwJ,GAAOA,EAAI,OAAS,EAAG,CACzB,UAAWnM,MAAUmM,EAAKpZ,EAAEiN,EAAM,EAClCsL,EAAiB,QAAQ,OAAO3I,CAAK,CACvC,CACF,MACE0I,EAAe,QAAQ,OAAO1I,CAAK,CAEvC,EAAG,EAAE,EAEL1pB,YAAU,IAAM,CACd,IAAIutB,EAAY,GAChB,MAAM4F,EAA8B,GAE9BC,EAAc,IAAM,CACxBb,EAAgB,QAAU,GAC1B,SAAW,CAAC7I,EAAOruB,CAAK,IAAKi3B,EAAiB,QACxCj3B,EAAM,SAAW,IACrB43B,EAAavJ,EAAO,CAAE,EAAG,cAAe,MAAAruB,EAAO,EAC/Ci3B,EAAiB,QAAQ,IAAI5I,EAAO,EAAE,EAE1C,EACM2J,GAAgB,IAAM,CACtBd,EAAgB,SAAWhF,IAC/BgF,EAAgB,QAAU,GAC1B,sBAAsBa,CAAW,EACnC,EACME,GAAkB5J,GAAkB,CACxC,MAAM/rB,EAAS20B,EAAiB,QAAQ,IAAI5I,CAAK,EAC7C/rB,GAAUA,EAAO,OAAS,IAC5Bs1B,EAAavJ,EAAO,CAAE,EAAG,cAAe,MAAO/rB,EAAQ,EACvD20B,EAAiB,QAAQ,IAAI5I,EAAO,EAAE,EAE1C,EA0GA,OAxGc,SAAY,CACxB,MAAM6J,EAAO,MAAM,QAAQ,IAAI,CAC7B91B,GAAyB,YAAcmE,GAAM,CAC3C,GAAI,CACF,MAAM1I,EAAK,KAAK,MAAM0I,EAAE,QAAQ,IAAI,EAC9B8nB,EAAQxwB,EAAG,MAEjB,GAAIA,EAAG,OAAS,eAAiBwwB,EAAO,CACtCyI,EAAS9jB,GACPA,EAAK,KAAM3N,GAAMA,EAAE,KAAOgpB,CAAK,EAC3Brb,EACA,CAAC,GAAGA,EAAM,CAAE,GAAIqb,EAAO,aAAcxwB,EAAG,aAAc,GAK5DoxB,EAAgBjc,GAAUnV,EAAG,QAAU,CAACmV,EAAOqb,EAAQrb,CAAK,EAC5D,MACF,CACA,GAAInV,EAAG,OAAS,eAAiBwwB,EAAO,CACtCyI,EAAS9jB,GAASA,EAAK,OAAQ3N,GAAMA,EAAE,KAAOgpB,CAAK,CAAC,EACpDY,EAAgBjc,GACVA,IAASqb,EAAcrb,EACTmkB,EAAQ,QAAQ,OAAQ9xB,GAAMA,EAAE,KAAOgpB,CAAK,EAC7C,CAAC,GAAG,IAAM,EAC5B,EACD0I,EAAe,QAAQ,OAAO1I,CAAK,EACnC2I,EAAiB,QAAQ,OAAO3I,CAAK,EACrC4I,EAAiB,QAAQ,OAAO5I,CAAK,EACrC,MACF,CAEA,GAAIxwB,EAAG,OAAS,eAAiBwwB,IAC3BxwB,EAAG,UAAY,WAAaA,EAAG,UAAY,aAAa,CAC1D,MAAMyE,EAAS20B,EAAiB,QAAQ,IAAI5I,CAAK,GAAK,GACtD/rB,EAAO,KAAK,CAAE,KAAMzE,EAAG,KAAM,QAASA,EAAG,QAAS,KAAMA,EAAG,KAAM,EACjEo5B,EAAiB,QAAQ,IAAI5I,EAAO/rB,CAAM,EAC1C01B,GAAA,EACA,MACF,CASF,GANIn6B,EAAG,OAAS,aAAewwB,GAC7ByI,EAAS9jB,GACPA,EAAK,IAAK3N,GAAOA,EAAE,KAAOgpB,EAAQ,CAAE,GAAGhpB,EAAG,aAAcxH,EAAG,cAAiBwH,CAAE,GAI9ExH,EAAG,OAAS,QAAS,CACvB,UAAW+R,KAAMmnB,EAAe,QAAQ,OACtCa,EAAahoB,EAAI,CAAE,EAAG,WAAY,MAAO/R,EAAI,EAE/C,MACF,CAEA,MAAMgiB,GAASwO,EACf,GAAIxO,GAAQ,CAEV,GADAoY,GAAepY,EAAM,EACjBhiB,EAAG,OAAS,mBAAoB,CAClC+5B,EAAa/X,GAAQ,CACnB,EAAG,kBACH,QAAS,CAAE,MAAOhiB,EAAG,MAAO,MAAOA,EAAG,MAAO,QAASA,EAAG,QAAQ,CAClE,EACD,MACF,CACA,GAAIA,EAAG,OAAS,mBAAoB,CAClC+5B,EAAa/X,GAAQ,CACnB,EAAG,kBACH,QAAS,CACP,MAAOhiB,EAAG,MACV,KAAMA,EAAG,KACT,KAAMA,EAAG,KACT,WAAYA,EAAG,WACjB,CACD,EACD,MACF,CACA+5B,EAAa/X,GAAQ,CAAE,EAAG,WAAY,MAAOhiB,EAAI,CACnD,CACF,MAAQ,CACN,QAAQ,MAAM,qBAAsB0I,EAAE,QAAQ,IAAI,CACpD,CACF,CAAC,EACDnE,GAAyB,aAAemE,GAAM,CAC5C,QAAQ,KAAK,oBAAqBA,EAAE,QAAQ,IAAI,CAClD,CAAC,EACDnE,GAAgC,WAAamE,GAAM,CACjD,UAAW8nB,KAAS0I,EAAe,QAAQ,UAAuB1I,CAAK,EACvE,UAAWe,KAAY2H,EAAe,QAAQ,SAC5C3H,EAAS,CAAE,EAAG,WAAY,KAAM7oB,EAAE,QAAQ,KAAM,CAEpD,CAAC,EACF,EACD,GAAI2rB,EAAW,CACb,UAAW1E,KAAK0K,EAAM1K,EAAA,EACtB,MACF,CACAsK,EAAS,KAAK,GAAGI,CAAI,EACrB,GAAI,CACF,MAAMr2B,GAAO,WAAW,CAC1B,OAAStD,EAAK,CACP2zB,GAAW,QAAQ,MAAM,mBAAoB3zB,CAAG,CACvD,CACF,GACK,EACE,IAAM,CACX2zB,EAAY,GACZ,UAAW5pB,KAAKwvB,EAAUxvB,EAAA,CAC5B,CACF,EAAG,CAACsvB,CAAY,CAAC,EAGjBjzB,YAAU,IAAM,CACTqqB,GACLntB,GAAO,WAAY,CACjB,KAAM,KAAK,UAAU,CAAE,IAAK,eAAgB,MAAOmtB,EAAa,EACjE,EAAE,MAAM,IAAM,CAAC,CAAC,CACnB,EAAG,CAACA,CAAW,CAAC,EAEhB,MAAMmJ,EAAUlP,cAAY,IAAM,CAChCpnB,GAAO,WAAY,CAAE,KAAM,KAAK,UAAU,CAAE,IAAK,WAAY,EAAG,EAAE,MAAOtD,GACvE,QAAQ,MAAM,kBAAmBA,CAAG,EAExC,EAAG,EAAE,EAEC65B,EAAWnP,cACdrZ,GAAe,CACV0mB,EAAK,QAAU,GACnBz0B,GAAO,WAAY,CAAE,KAAM,KAAK,UAAU,CAAE,IAAK,YAAa,MAAO+N,EAAI,EAAG,EAAE,MAAOrR,GACnF,QAAQ,MAAM,mBAAoBA,CAAG,EAEzC,EACA,CAAC+3B,EAAK,MAAM,GAGd3xB,YAAU,IAAM,CACd,MAAM2B,EAASC,GAAqB,CAClC,MAAMwtB,EAAMxtB,EAAE,SAAWA,EAAE,QAC3B,GAAIwtB,IAAQxtB,EAAE,MAAQ,KAAOA,EAAE,MAAQ,KACrCA,EAAE,iBACF4xB,EAAA,UACSpE,IAAQxtB,EAAE,MAAQ,KAAOA,EAAE,MAAQ,MAAQyoB,GAAesH,EAAK,OAAS,EACjF/vB,EAAE,iBACF6xB,EAASpJ,CAAW,UACX+E,GAAOxtB,EAAE,MAAQ,MAAO,CACjC,GAAI+vB,EAAK,QAAU,EAAG,OACtB/vB,EAAE,iBACF,MAAM1B,GAAMyxB,EAAK,UAAWjxB,GAAMA,EAAE,KAAO2pB,CAAW,EAChD/a,GAAO1N,EAAE,UAAY1B,GAAM,EAAIyxB,EAAK,QAAUA,EAAK,QAAUzxB,GAAM,GAAKyxB,EAAK,OAC7EzW,GAASyW,EAAKriB,EAAI,EACpB4L,IAAQoP,EAAepP,GAAO,EAAE,CACtC,MAAWkU,IAAQxtB,EAAE,MAAQ,KAAOA,EAAE,MAAQ,OACxCA,EAAE,QACJA,EAAE,iBACFmxB,EAAiBlxB,IAAM,CAACA,EAAC,IAEzBD,EAAE,iBACFkxB,EAAkBjxB,IAAM,CAACA,EAAC,GAGhC,EACA,cAAO,iBAAiB,UAAWF,CAAK,EACjC,IAAM,OAAO,oBAAoB,UAAWA,CAAK,CAC1D,EAAG,CAAC6xB,EAASC,EAAUpJ,EAAasH,CAAI,CAAC,EAEzC,MAAM1c,EAAaqP,cAAaoP,GAAqB,CACnD/uB,EAAS+uB,CAAS,EAClBhB,EAAc3oB,GAAqB2pB,CAAS,CAAC,CAC/C,EAAG,EAAE,EAECxe,GAAkBoP,cAAaqP,GAA0B,CAC7DjB,EAAciB,CAAS,EACvBhvB,EAASkF,GAAc8pB,CAAS,CAAC,CACnC,EAAG,EAAE,EAEC5J,GAAgBzF,cAAY,IAAM,CACtCrP,EAAWvQ,IAAU2E,GAAM,KAAOA,GAAM,MAAQA,GAAM,IAAI,CAC5D,EAAG,CAAC4L,EAAYvQ,CAAK,CAAC,EAEhB,CAAC6lB,GAAgBqJ,CAAiB,EAAI7zB,WAAS,EAAK,EACpDyqB,GAAqBlG,cAAY,IAAMsP,EAAmB/xB,GAAM,CAACA,CAAC,EAAG,EAAE,EAEvEub,GAAmBkH,cAAY,IAAM,CACzCmO,EAAa9uB,GAAM,CACjB,MAAM2L,EAAO3L,IAAM,MAAQ,MAAQ,MACnC,oBAAa,QAAQ,oBAAqB2L,CAAI,EAC9C,OAAO,cAAc,IAAI,YAAY,oBAAqB,CAAE,OAAQA,CAAA,CAAM,CAAC,EACpEA,CACT,CAAC,CACH,EAAG,EAAE,EAEL,OACEhO,MAAAoO,WAAA,CACG,SAAAiiB,EAAK,IAAKjxB,GACTY,MAACmoB,GAAA,CAEC,MAAO/oB,EAAE,GACT,OAAQA,EAAE,KAAO2pB,EACjB,SAAAtV,EACA,iBAAA4U,GACA,SAAU6J,EACV,WAAY,IAAMC,EAAS/yB,EAAE,EAAE,EAC/B,YAAaixB,EAAK,OAAS,EAC3B,MAAAjtB,EACA,WAAAsQ,EACA,WAAAC,EACA,gBAAAC,GACA,cAAA6U,GACA,UAAA5U,EACA,eAAgByd,EAChB,WAAAvd,EACA,gBAAiBwd,EACjB,cAAA7I,EACA,aAAAC,EACA,aAAc,IAAM6I,EAAkBjxB,GAAM,CAACA,CAAC,EAC9C,YAAa,IAAMkxB,EAAiBlxB,GAAM,CAACA,CAAC,EAC5C,iBAAAub,GACA,eAAAmN,GACA,mBAAAC,GACA,SAAUmH,EACV,YAAAtH,EACA,eAAAC,CAAA,EA1BK5pB,EAAE,GA4BV,EACH,CAEJ,CCxgGA,MAAMtB,GAAS,aAAa,QAAQ,gBAAgB,EAC9Cy0B,GAAc,aAAa,QAAQ,qBAAqB,EAC1DjqB,GAAaiqB,EAAW,GAC1B,SAAS,gBAAgB,QAAQ,WAAaA,GAC9C,SAAS,gBAAgB,QAAQ,MAAQhqB,GAAcgqB,EAAW,GACzDvqB,GAAQlK,EAAM,IACvB,SAAS,gBAAgB,QAAQ,MAAQA,GACzC,SAAS,gBAAgB,QAAQ,WAAa2K,GAAqB3K,EAAM,GAG3E,MAAM00B,GAAW,aAAa,KAAK,UAAU,SAAS,EAClD,QACA,WAAW,KAAK,UAAU,SAAS,EACjC,UACA,UACN,SAAS,gBAAgB,QAAQ,SAAWA,GAC5C,SAAS,KAAK,QAAQ,SAAWA,GAEjC,MAAMC,GAAO,SAAS,eAAe,MAAM,EAC3C,GAAI,CAACA,GAAM,MAAM,IAAI,MAAM,eAAe,EAE1CC,cAAWD,EAAI,EAAE,OAAOzyB,MAAC4wB,KAAI,CAAE","names":["listeners","eventIdCounter","currentTurn","modeMeta","rawMode","isServerMode","MODE","isWebRuntime","broadcast","eventName","payload","callbacks","cb","emitEvent","event","sse","sseTurnStarted","sseReconnectAttempts","SSE_MAX_RECONNECT_ATTEMPTS","SSE_RECONNECT_BASE_DELAY","cliDisconnected","notifyCliStatus","connected","sseToIncoming","ev","results","m","connectSSE","token","sseUrl","msg","dashboardEvent","events","evt","err","delay","startStatsPolling","statsPollTimer","overview","apiFetch","stats","firstBalance","totalTokens","endpoint","options","headers","res","text","emitServerSettings","settings","emitMcpSpecsFromServer","specs","bridged","live","s","out","liveEntry","emitSkillsFromServer","data","items","tag","rows","scope","r","emitMemoryEntriesFromServer","entries","loadAndEmitMcp","specsResp","liveResp","loadAndEmitSkills","loadAndEmitMemory","loadAndEmitMemoryDetail","path","serverInit","wsDir","sessionsData","serverRpc","cmd","result","switchData","raw","toolResults","messages","segments","tc","newName","listData","body","invoke","args","mockSetupAndReady","mockAssistantTurn","mockSessions","mockMessages","mockSettings","listen","callback","bucket","b","getCurrentWebview","_callback","getCurrentWindow","_event","open","save","openUrl","url","openPath","relaunch","_promptText","lines","line","chunks","chunk","en","de","zhCN","SUPPORTED_LANGS","SUPPORTED","LANG_LABELS","STORAGE_KEY","detectDefault","stored","lower","currentLang","syncHtmlLang","lang","getLang","getSupportedLangs","getLangLabel","setLang","useLang","setTick","useState","useEffect","n","idx","dicts","resolve","dict","key","parts","cursor","p","t","params","_","k","isMacPlatform","keyLabel","mac","shortcutText","keys","localizeShortcutText","Shortcut","className","jsx","index","useCommandPalette","active","setOpen","onKey","e","v","buildCommands","handlers","list","FilePlus","Plus","SquareX","FocusIcon","StopCircle","ClipboardCopy","Download","Trash2","FolderOpen","Settings","Info","GROUP_ORDER","groupLabel","g","CommandPalette","onClose","commands","query","setQuery","setActive","inputRef","useRef","listRef","filtered","useMemo","q","c","a","grouped","byGroup","arr","run","jsxs","Search","section","i","Toast","message","DARK_THEME","LIGHT_THEME","usePrismTheme","theme","setTheme","prevRef","el","mo","CodeView","startLine","showLineNumbers","Highlight","tokens","getLineProps","getTokenProps","openWithEditor","editor","abs","WorkspaceContext","createContext","WorkspaceProvider","resolveAgainstWorkspace","rel","ws","sep","KNOWN_EXTS","FILE_PATH_RE","FilePill","ctx","useContext","done","setDone","display","openInEditor","lineNum","copyOnly","FileText","Check","splitFilePaths","last","prefix","pillStart","withFilePills","children","Children","child","isValidElement","props","cloneElement","Markdown","memo","source","ReactMarkdown","remarkGfm","remarkBreaks","remarkMath","rehypeKatex","rawText","flattenChildText","CodeBlock","extractFencedLang","href","SafeLink","isExternal","onClick","stripped","ExternalLink","kid","cls","node","copied","setCopied","onCopy","Copy","Ic","size","rest","I","THEME","isTheme","value","THEME_STYLE","DEFAULT_THEME_STYLE","THEME_STYLE_THEME","THEME_STYLES","isThemeStyle","themeForStyle","style","defaultStyleForTheme","FONT_SCALE","isFontScale","FONT_SCALE_ZOOM","FONT_FAMILY","isFontFamily","FONT_FAMILY_STACK","SESSION_PARAM","readSessionFromUrl","trimmed","writeSessionToUrl","name","fmtElapsed","ms","useElapsed","startAt","setMs","start","id","EFFORTS","MODE_INFO","ModeSwitch","mode","onChange","slashIcon","parentOfAtQuery","normalized","trailingSlash","lastSlash","dirContext","parentIdx","atIcon","Composer","draft","setDraft","onSend","onAbort","disabled","busy","busyLabel","busyElapsedMs","modelLabel","reasoningEffort","onModelChange","onEffortChange","editMode","onEditModeChange","textareaRef","slashCommands","onMentionQuery","onMentionPreview","onMentionPicked","mentionResults","workspaceDir","queuedSends","onQueueWhileBusy","onDequeueSend","chips","setChips","popup","setPopup","activeIdx","setActiveIdx","modelMenuOpen","setModelMenuOpen","nonceRef","modelWrapRef","composingRef","compositionEndedAtRef","prevDraftRef","prev","onDown","attachFile","filter","picked","openFileDialog","slashItems","atItems","base","parent","handleChange","trail","sigil","nonce","dismiss","pickItem","it","next","mention","handleKeyDown","dirPath","Fragment","cs","j","ModelEffortMenu","Popup","item","kind","onPick","onHover","KNOWN_MODELS","currentEffort","onPickModel","onPickEffort","PanelErrorBoundary","Component","error","info","CONTEXT_MAX_TOKENS","ContextPanel","usage","mcpSpecs","mcpBridged","sessionFiles","memory","memoryDetail","onReadMemory","tab","setTab","reserved","cached","used","reservedPct","usedPct","cachedPct","free","CtxFiles","CtxTools","CtxMemory","CtxRules","buildSessionTree","files","sorted","seenDirs","f","seg","leaf","tree","readyCount","dot","suffix","detail","onRead","JobsPop","jobs","onStop","onStopAll","tick","running","exited","JobRow","formatElapsed","job","exp","setExp","elapsedMs","liveMs","REPO_URL","AboutModal","openGitHub","maskQQAppId","appId","getQQConnectIntent","qq","getQQStatusLabel","describeQQAccessLabel","access","owner","openId","count","allowlist","runtime","describeQQRowSummary","PAGE_META","SettingsModal","balance","currency","themeStyle","onSetTheme","onSetThemeStyle","fontScale","onSetFontScale","fontFamily","onSetFontFamily","initialPage","skills","onSave","onSaveApiKey","onLoadQQ","onConnectQQ","onDisconnectQQ","onSaveQQConfig","onOpenQQApplyLink","onPickWorkspace","onAddMcpSpec","onRemoveMcpSpec","page","setPage","qqConfigureOpen","setQQConfigureOpen","currentMeta","PageGeneral","PageModels","PageMCP","PageSkills","PageMemory","PageRules","PageBilling","PageShortcuts","ApiKeySection","QQChannelSection","patch","configureOpen","onOpenConfigure","onCloseConfigure","onConnect","onDisconnect","onSaveConfig","onSaveAndConnect","onOpenApplyLink","current","setAppId","appSecret","setAppSecret","sandbox","setSandbox","savePatch","editorDraft","setEditorDraft","code","baseUrl","apiKeyPrefix","setKey","urlDraft","setUrlDraft","EFFORT_VALUES","isKnown","onAdd","onRemove","submit","subagentModels","setSubagentModel","symbol","sessionCost","hitPct","SectionRow","nm","prettyName","month","day","hh","mm","relative","min","hr","d","Sidebar","sessions","activeName","loadingName","onNewChat","onLoadSession","onDeleteSession","onOpenSettings","onOpenRules","onOpenCommands","onOpenAbout","pendingDelete","setPendingDelete","onMouseDown","loading","mtime","updated","rect","SessionDeletePopover","target","onCancel","onConfirm","ref","cancelRef","pos","setPos","useLayoutEffect","pad","vw","vh","left","top","SPLASH_FLAG","shouldShowSplash","markSplashShown","Splash","onDone","leaving","setLeaving","onDoneRef","t1","t2","skip","skipClick","USD_TO_CNY","formatMoney","amountUsd","amount","tokenLabel","StatusBar","ready","jobsOpen","onToggleJobs","onToggleCurrency","onOpenWorkdir","cacheHitPct","runningJobs","spent","balanceLabel","connState","themeOpen","setThemeOpen","themePopRef","themeButtonRef","onPointerDown","COMPACTION_SUMMARY_MARKER","isCompactionSummary","stripCompactionMarker","derivePrefix","command","first","Card","tone","icon","meta","defaultOpen","compact","headRight","StatusIcon","state","label","ReasoningCard","streaming","elapsed","model","para","ShellCard","output","durationMs","onApprove","onReject","onAlwaysAllow","ln","CompactionCard","summary","charCount","ToolCard","ok","AssistantText","ApprovalCard","title","sub","preview","primaryLabel","secondaryLabel","tertiaryLabel","onPrimary","onSecondary","onTertiary","TaskCard","subtitle","steps","x","pct","st","TurnDivider","UserMsg","time","skill","AssistantMsg","pending","onApproveConfirm","onRejectConfirm","onAlwaysAllowConfirm","pendingConfirms","content","pendingConfirm","extractCommand","PlanBanner","plan","onDismiss","total","PlanApprovalCard","onRefine","stepCount","CheckpointApprovalCard","onContinue","onRevise","RevisionApprovalCard","onAccept","ConfirmApprovalCard","onAllow","onDeny","isBackground","PathAccessApprovalCard","isWrite","ChoiceApprovalCard","o","activePlanToTaskSteps","ActivePlanTaskCard","WorkdirPop","recent","anchor","onBrowse","positionStyle","isCurrent","fetchBrowse","WorkdirInputModal","initialPath","typed","setTyped","browse","setBrowse","setError","setLoading","seededRef","navigate","useCallback","trimmedTyped","canConfirm","sameAsCurrent","handleConfirm","handleTypedKey","PIN_THRESHOLD","useAutoScroll","containerRef","contentRef","getRestoreScrollTop","showJumpButton","setShowJumpButton","isPinnedRef","wasBusyRef","rafIdRef","isAtBottom","refreshJumpButton","scrollToBottom","smooth","pendingFrame","onUserGesture","ro","restore","TEXT_INPUT_SELECTOR","getTextAssistAttrs","applyTextAssistAttrs","element","attrs","applyWithin","root","useDisableTextAssist","handleFocusIn","observer","mutations","mutation","fallbackSkillDesc","runAs","nextMessageTurn","max","reduce","action","argsLine","applyIncoming","collapsed","relevant","appendTextSegment","zeroUsage","removed","activePlan","pendingSteps","doneIds","keptDone","READING_TOOLS","MODIFYING_TOOLS","extractToolFiles","parsed","seen","mergeSessionFiles","existing","adds","indexByPath","changed","add","stepIds","entry","prevWs","wsChanged","sessionName","loaded","sizeNote","u","callHit","callMiss","hasCall","segs","mutated","formatConversationMarkdown","userLabel","arg","sanitizeFilename","defaultExportFilename","session","TabRuntime","tabId","registerDispatch","onNewTab","onCloseTab","canCloseTab","onToggleTheme","sideCollapsed","ctxCollapsed","onToggleSide","onToggleCtx","tabsList","activeTabId","setActiveTabId","mobileSideOpen","onToggleMobileSide","dispatch","useReducer","toast","setToast","splashOn","setSplashOn","wdOpen","setWdOpen","wdAnchor","setWdAnchor","composerRef","threadRef","threadInnerRef","settingsOpen","setSettingsOpen","settingsPage","setSettingsPage","setJobsOpen","aboutOpen","setAboutOpen","loadingSession","setLoadingSession","workdirModalOpen","setWorkdirModalOpen","openSettingsAt","palette","sendRpc","queryMentions","previewMention","markMentionPicked","saveSettings","loadQQSettings","connectQQ","disconnectQQ","saveQQConfig","saveApiKey","addMcpSpec","spec","removeMcpSpec","newChat","pickWorkspace","openDialog","flashToast","opts","dropActiveRef","unlisten","cancelled","handle","__vitePreload","tauriBridge","paths","mentions","norm","wsNorm","send","override","btwMatch","question","skillMatch","clientId","trimmedArgs","abort","resolveConfirm","response","resolvePathAccess","resolveChoice","resolvePlan","resolveCheckpoint","resolveRevision","currentSessionRef","restoreScrollTop","timer","onScroll","initialUrlSession","urlSessionDispatched","mod","conversationCopy","exportConversation","langs","langName","workspaceLabel","firstUser","cleaned","md","filename","saveDialog","TitleBar","TabBar","NeedsSetupView","MainHead","EmptyState","match","dividerLabel","needsDivider","optionId","jobId","WinMinimize","WinMaximize","WinRestore","WinClose","sideOn","ctxOn","onExport","onClear","hasMessages","menuOpen","setMenuOpen","isMaximized","setIsMaximized","moreWrapRef","isMac","isWeb","win","fn","tabs","activeId","onNew","singleTab","wsLabel","suggestions","onSubmit","App","setTabs","dispatchersRef","pendingEventsRef","pendingDeltasRef","rafScheduledRef","tabsRef","setCurrency","setThemeStyle","storedTheme","setFontScale","setFontFamily","setSideCollapsed","setCtxCollapsed","onCur","deliverToTab","buf","cleanups","flushDeltas","scheduleFlush","flushTabDeltas","subs","openTab","closeTab","nextTheme","nextStyle","setMobileSideOpen","storedStyle","platform","host","createRoot"],"ignoreList":[],"sources":["../src/lib/tauri-bridge.ts","../src/i18n/en.ts","../src/i18n/de.ts","../src/i18n/zh-CN.ts","../src/i18n/index.ts","../src/ui/shortcut.tsx","../src/CommandPalette.tsx","../src/CodeView.tsx","../src/Markdown.tsx","../src/icons.tsx","../src/theme.ts","../src/lib/session-url.ts","../src/ui/live.tsx","../src/ui/composer.tsx","../src/ui/error-boundary.tsx","../src/ui/context-panel.tsx","../src/ui/jobs-pop.tsx","../src/ui/about.tsx","../src/qq-settings.ts","../src/ui/settings.tsx","../src/ui/sidebar.tsx","../src/ui/splash.tsx","../src/ui/statusbar.tsx","../../packages/core-utils/src/compaction.ts","../../packages/core-utils/src/derive-prefix.ts","../src/ui/cards.tsx","../src/ui/extra-cards.tsx","../src/ui/thread.tsx","../src/ui/workdir-pop.tsx","../src/ui/workdir-input-modal.tsx","../src/ui/useAutoScroll.ts","../src/ui/useDisableTextAssist.ts","../src/App.tsx","../src/main.tsx"],"sourcesContent":["// Tauri API 兼容别名桥接器 (Tauri Bridge for Web/Mobile)\n// 双模式:Mock 模式(Vite 开发) + Server 模式(真实 CLI 后端)\n\ntype UnlistenFn = () => void;\ntype EventCallback<T = any> = (event: { payload: T; event: string }) => void;\n\n// 事件监听中心\nconst listeners = new Map<string, Set<EventCallback>>();\nlet eventIdCounter = 0;\nlet currentTurn = 1;\n\n// 模式检测\nconst modeMeta = document.querySelector('meta[name=\"reasonix-mode\"]');\nconst rawMode = modeMeta?.getAttribute(\"content\") ?? \"\";\nconst isServerMode = rawMode !== \"\" && rawMode !== \"__REASONIX_MODE__\";\nconst MODE = isServerMode ? \"server\" : \"mock\";\n\n/** Web vs. native dispatcher hint — `true` whenever the dashboard is served by the CLI server, false in the Tauri desktop wrapper where native dialogs work. */\nexport const isWebRuntime = isServerMode;\n\nconsole.log(`[tauri-bridge] mode=${MODE}${isServerMode ? ` mode=\"${rawMode}\"` : \"\"}`);\n\n// 事件广播\nfunction broadcast(eventName: string, payload: any) {\n const callbacks = listeners.get(eventName);\n if (callbacks) {\n for (const cb of callbacks) {\n cb({ payload, event: eventName });\n }\n }\n}\n\nfunction emitEvent(event: Record<string, any>) {\n broadcast(\"rpc:event\", { data: JSON.stringify(event) });\n}\n\n// SSE 连接(Server 模式)\nlet sse: EventSource | null = null;\nlet sseTurnStarted = false;\nlet sseReconnectAttempts = 0;\nconst SSE_MAX_RECONNECT_ATTEMPTS = 10;\nconst SSE_RECONNECT_BASE_DELAY = 1000;\n\nlet cliDisconnected = false;\n\nfunction notifyCliStatus(connected: boolean) {\n if (cliDisconnected !== connected) {\n cliDisconnected = !connected;\n if (!connected) {\n emitEvent({ type: \"status\", text: \"正在重连…\", tabId: \"tab-1\" });\n } else {\n emitEvent({ type: \"status\", text: \"连接已恢复\", tabId: \"tab-1\" });\n }\n }\n}\n\n// SSE DashboardEvent → IncomingEvent 转换\nfunction sseToIncoming(ev: any): Record<string, any>[] {\n const results: Record<string, any>[] = [];\n\n switch (ev.kind) {\n case \"assistant_delta\": {\n if (!sseTurnStarted) {\n sseTurnStarted = true;\n currentTurn++;\n results.push({\n type: \"model.turn.started\",\n tabId: \"tab-1\",\n id: ev.id,\n turn: currentTurn,\n model: \"deepseek-reasoner\",\n });\n }\n if (ev.contentDelta) {\n results.push({\n type: \"model.delta\",\n tabId: \"tab-1\",\n channel: \"content\",\n text: ev.contentDelta,\n turn: currentTurn,\n });\n }\n if (ev.reasoningDelta) {\n results.push({\n type: \"model.delta\",\n tabId: \"tab-1\",\n channel: \"reasoning\",\n text: ev.reasoningDelta,\n turn: currentTurn,\n });\n }\n break;\n }\n case \"assistant_final\": {\n // Loop's `assistant_final` fires per model iteration (mid-turn it\n // precedes tool dispatch); the real turn end is signaled by\n // `busy-change` (busy=false), handled below.\n results.push({\n type: \"model.final\",\n tabId: \"tab-1\",\n turn: currentTurn,\n content: ev.text ?? \"\",\n reasoningContent: ev.reasoning ?? \"\",\n usage: ev.usage ?? undefined,\n costUsd: ev.costUsd ?? undefined,\n });\n break;\n }\n case \"tool_start\": {\n results.push({\n type: \"tool.preparing\",\n tabId: \"tab-1\",\n turn: currentTurn,\n callId: ev.id,\n name: ev.toolName,\n });\n results.push({\n type: \"tool.intent\",\n tabId: \"tab-1\",\n turn: currentTurn,\n callId: ev.id,\n name: ev.toolName,\n args: ev.args ?? \"\",\n });\n break;\n }\n case \"tool\": {\n results.push({\n type: \"tool.result\",\n tabId: \"tab-1\",\n turn: currentTurn,\n callId: ev.id,\n name: ev.toolName,\n output: ev.content,\n ok: true,\n });\n break;\n }\n case \"user\": {\n results.push({\n type: \"user.message\",\n tabId: \"tab-1\",\n id: ev.id,\n turn: currentTurn,\n text: ev.text,\n });\n break;\n }\n case \"busy-change\": {\n if (!ev.busy && sseTurnStarted) {\n results.push({ type: \"$turn_complete\", tabId: \"tab-1\" });\n sseTurnStarted = false;\n }\n break;\n }\n case \"modal-up\": {\n const m = ev.modal;\n if (m?.kind === \"shell\") {\n results.push({\n type: \"$confirm_required\",\n tabId: \"tab-1\",\n id: m.id ?? ++eventIdCounter,\n kind: \"run_command\",\n command: m.command,\n });\n } else if (m?.kind === \"choice\") {\n results.push({\n type: \"$choice_required\",\n tabId: \"tab-1\",\n id: m.id ?? ++eventIdCounter,\n question: m.question,\n options: m.options ?? [],\n allowCustom: m.allowCustom ?? false,\n });\n } else if (m?.kind === \"plan\") {\n results.push({\n type: \"$plan_required\",\n tabId: \"tab-1\",\n id: m.id ?? ++eventIdCounter,\n plan: m.plan ?? \"\",\n summary: m.summary,\n steps: m.steps,\n });\n } else if (m?.kind === \"checkpoint\") {\n results.push({\n type: \"$checkpoint_required\",\n tabId: \"tab-1\",\n id: m.id ?? ++eventIdCounter,\n stepId: m.stepId,\n title: m.title,\n result: m.result,\n notes: m.notes,\n completed: m.completed,\n total: m.total,\n });\n }\n break;\n }\n case \"modal-down\": {\n // Modal closed — normally handled by user action response\n break;\n }\n case \"warning\":\n case \"error\": {\n results.push({\n type: \"$error\",\n tabId: \"tab-1\",\n message: ev.text,\n });\n break;\n }\n case \"status\": {\n results.push({\n type: \"status\",\n tabId: \"tab-1\",\n text: ev.text,\n });\n break;\n }\n case \"ping\":\n break; // keep-alive, no action needed\n default:\n console.warn(\"[tauri-bridge] unhandled SSE event kind:\", ev.kind);\n }\n return results;\n}\n\nfunction connectSSE(): void {\n if (sse) sse.close();\n const token =\n document.querySelector('meta[name=\"reasonix-token\"]')?.getAttribute(\"content\") ?? \"\";\n const sseUrl =\n token && token !== \"__REASONIX_TOKEN__\"\n ? `/api/events?token=${encodeURIComponent(token)}`\n : \"/api/events\";\n sse = new EventSource(sseUrl);\n sse.onmessage = (msg: MessageEvent) => {\n try {\n const dashboardEvent = JSON.parse(msg.data);\n // Token 无效时显示过期提示\n if (dashboardEvent.kind === \"error\" && dashboardEvent.text?.includes(\"token\")) {\n emitEvent({\n type: \"$error\",\n tabId: \"tab-1\",\n message: \"链接已过期,请重新从 CLI 打开\",\n });\n return;\n }\n const events = sseToIncoming(dashboardEvent);\n for (const evt of events) emitEvent(evt);\n // 成功收到事件,重置重连计数\n sseReconnectAttempts = 0;\n notifyCliStatus(true);\n } catch (err) {\n console.warn(\"[tauri-bridge] bad SSE event:\", err);\n }\n };\n sse.onerror = () => {\n console.warn(\"[tauri-bridge] SSE connection lost, retrying…\");\n sse?.close();\n sse = null;\n notifyCliStatus(false);\n\n sseReconnectAttempts++;\n if (sseReconnectAttempts > SSE_MAX_RECONNECT_ATTEMPTS) {\n emitEvent({\n type: \"$error\",\n tabId: \"tab-1\",\n message: \"CLI 已停止,请重新启动\",\n });\n return;\n }\n\n const delay = SSE_RECONNECT_BASE_DELAY * Math.pow(2, sseReconnectAttempts - 1);\n setTimeout(connectSSE, Math.min(delay, 30000));\n };\n\n // SSE 连接成功后,开始定期轮询 overview 更新 balance/stats\n startStatsPolling();\n}\n\n// 定期轮询 stats/balance\nlet statsPollTimer: ReturnType<typeof setInterval> | null = null;\n\nfunction startStatsPolling(): void {\n if (statsPollTimer) clearInterval(statsPollTimer);\n // 每 5 秒轮询一次 overview 获取最新 stats/balance\n statsPollTimer = setInterval(async () => {\n try {\n const overview = await apiFetch(\"overview\");\n if (overview?.stats) {\n const stats = overview.stats;\n // 更新 balance\n if (stats.balance) {\n const firstBalance = stats.balance[0];\n if (firstBalance) {\n emitEvent({\n type: \"$balance\",\n tabId: \"tab-1\",\n currency: firstBalance.currency,\n total: Number.parseFloat(firstBalance.total_balance) || 0,\n isAvailable: true,\n });\n }\n }\n // 更新 usage stats(缓存命中率、tokens、金额)\n const totalTokens = Math.round(stats.totalCostUsd > 0 ? stats.cacheHitRatio * 10000 : 0);\n // 通过 $settings 事件附带更新 usage 相关信息\n // 注意:usage 主要由 model.final 事件更新,这里只更新 balance\n }\n } catch {\n // 静默失败,等待下次轮询\n }\n }, 5000);\n}\n\n// REST API 辅助\nasync function apiFetch(endpoint: string, options?: RequestInit): Promise<any> {\n const token = document.querySelector('meta[name=\"reasonix-token\"]')?.getAttribute(\"content\");\n const headers: Record<string, string> = {\n ...((options?.headers as Record<string, string>) ?? {}),\n };\n if (token && token !== \"__REASONIX_TOKEN__\") {\n headers[\"x-reasonix-token\"] = token;\n }\n if (options?.body && !headers[\"content-type\"]) {\n headers[\"content-type\"] = \"application/json\";\n }\n const res = await fetch(`/api/${endpoint}`, { ...options, headers });\n if (res.status === 204) return null;\n const text = await res.text();\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nfunction emitServerSettings(settings: any, overview?: any): void {\n emitEvent({\n type: \"$settings\",\n tabId: \"tab-1\",\n reasoningEffort: settings?.reasoningEffort ?? overview?.reasoningEffort ?? \"high\",\n editMode: settings?.editMode ?? overview?.editMode ?? \"review\",\n budgetUsd: settings?.budgetUsd ?? overview?.budgetUsd ?? null,\n workspaceDir: overview?.cwd ?? \"\",\n recentWorkspaces: [],\n model: overview?.model ?? settings?.model ?? \"deepseek-v4-flash\",\n editor: \"code\",\n webSearchEngine: settings?.webSearchEngine ?? \"bing\",\n subagentModels: settings?.subagentModels ?? {},\n version: overview?.version ?? \"\",\n baseUrl: settings?.baseUrl ?? \"\",\n apiKeyPrefix: settings?.apiKey ?? \"\",\n });\n}\n\n// 初始化 Server 状态\nfunction emitMcpSpecsFromServer(specs: any[] | undefined, bridged: any[] | undefined): void {\n const live = new Map<string, any>();\n for (const s of bridged ?? []) {\n if (typeof s?.spec === \"string\") live.set(s.spec, s);\n }\n const out = (specs ?? []).map((s: any) => {\n const liveEntry = live.get(s.raw);\n return {\n raw: s.raw,\n name: s.name ?? null,\n transport: s.transport,\n summary: s.summary,\n parseError: s.parseError,\n status: liveEntry ? \"connected\" : s.parseError ? \"failed\" : \"configured\",\n statusReason: liveEntry ? undefined : s.parseError,\n toolCount: liveEntry?.toolCount,\n };\n });\n emitEvent({\n type: \"$mcp_specs\",\n tabId: \"tab-1\",\n specs: out,\n bridged: out.length > 0 && out.every((s) => s.status === \"connected\"),\n });\n}\n\nfunction emitSkillsFromServer(data: any): void {\n const items: any[] = [];\n const tag = (rows: any[] | undefined, scope: string) => {\n for (const r of rows ?? []) {\n items.push({\n name: r.name,\n description: r.description ?? \"\",\n scope,\n path: r.path ?? \"\",\n runAs: r.runAs ?? \"inline\",\n model: r.model,\n });\n }\n };\n tag(data?.builtin, \"builtin\");\n tag(data?.global, \"global\");\n tag(data?.custom, \"global\");\n tag(data?.project, \"project\");\n emitEvent({ type: \"$skills\", tabId: \"tab-1\", items });\n}\n\nfunction emitMemoryEntriesFromServer(entries: any[] | undefined): void {\n emitEvent({ type: \"$memory\", tabId: \"tab-1\", entries: entries ?? [] });\n}\n\nasync function loadAndEmitMcp(): Promise<void> {\n try {\n const [specsResp, liveResp] = await Promise.all([apiFetch(\"mcp/specs\"), apiFetch(\"mcp\")]);\n emitMcpSpecsFromServer(specsResp?.specs, liveResp?.servers);\n } catch (err) {\n console.warn(\"[tauri-bridge] mcp fetch failed:\", err);\n }\n}\n\nasync function loadAndEmitSkills(): Promise<void> {\n try {\n const data = await apiFetch(\"skills\");\n if (data) emitSkillsFromServer(data);\n } catch (err) {\n console.warn(\"[tauri-bridge] skills fetch failed:\", err);\n }\n}\n\nasync function loadAndEmitMemory(): Promise<void> {\n try {\n const data = await apiFetch(\"memory/entries\");\n emitMemoryEntriesFromServer(data?.entries);\n } catch (err) {\n console.warn(\"[tauri-bridge] memory fetch failed:\", err);\n }\n}\n\nasync function loadAndEmitMemoryDetail(path: string): Promise<void> {\n try {\n const data = await apiFetch(`memory/read?path=${encodeURIComponent(path)}`);\n if (data?.detail) emitEvent({ type: \"$memory_detail\", tabId: \"tab-1\", detail: data.detail });\n } catch (err) {\n console.warn(\"[tauri-bridge] memory read failed:\", err);\n }\n}\n\nasync function serverInit(): Promise<void> {\n document.documentElement.dataset.web = \"true\";\n\n // 加载初始设置和会话;overview 提供 workspace 等信息\n let wsDir = \"\";\n try {\n const [settings, sessionsData, overview] = await Promise.all([\n apiFetch(\"settings\"),\n apiFetch(\"sessions\"),\n apiFetch(\"overview\"),\n ]);\n wsDir = overview?.cwd ?? \"\";\n if (settings) emitServerSettings(settings, overview);\n if (sessionsData?.sessions) {\n const items = sessionsData.sessions.map((s: any) => ({\n name: s.name,\n messageCount: s.messageCount,\n mtime: new Date(s.mtime).toISOString(),\n summary: s.summary,\n }));\n emitEvent({\n type: \"$sessions\",\n tabId: \"tab-1\",\n items,\n });\n }\n // 从 overview 中提取 balance 和 stats\n const stats = overview?.stats;\n if (stats?.balance) {\n const firstBalance = stats.balance[0];\n if (firstBalance) {\n emitEvent({\n type: \"$balance\",\n tabId: \"tab-1\",\n currency: firstBalance.currency,\n total: Number.parseFloat(firstBalance.total_balance) || 0,\n isAvailable: true,\n });\n }\n }\n } catch (err) {\n console.warn(\"[tauri-bridge] server init failed:\", err);\n }\n\n // Sidebar/right-rail panels — desktop pushes these on tab open; web has\n // to pull them or every panel renders empty forever (#1715).\n void Promise.all([loadAndEmitMcp(), loadAndEmitSkills(), loadAndEmitMemory()]);\n\n emitEvent({ type: \"$ready\", tabId: \"tab-1\" });\n emitEvent({\n type: \"$tab_opened\",\n tabId: \"tab-1\",\n workspaceDir: wsDir,\n active: true,\n });\n\n // 连接 SSE\n connectSSE();\n}\n\n// RPC 命令 → REST API 映射\nasync function serverRpc(payload: Record<string, any>): Promise<void> {\n const cmd = payload.cmd;\n\n switch (cmd) {\n case \"user_input\": {\n const result = await apiFetch(\"submit\", {\n method: \"POST\",\n body: JSON.stringify({ prompt: payload.text }),\n }).catch((err) => {\n console.warn(\"[tauri-bridge] submit failed:\", err);\n return null;\n });\n // 提交失败时通知前端保留草稿\n if (!result?.accepted) {\n emitEvent({\n type: \"$error\",\n tabId: \"tab-1\",\n message: result?.reason ?? \"提交失败,请重试\",\n });\n }\n break;\n }\n case \"abort\": {\n await apiFetch(\"abort\", { method: \"POST\" }).catch(() => {});\n break;\n }\n case \"session_list\": {\n try {\n const data = await apiFetch(\"sessions\");\n if (data?.sessions) {\n const items = data.sessions.map((s: any) => ({\n name: s.name,\n messageCount: s.messageCount,\n mtime: new Date(s.mtime).toISOString(),\n summary: s.summary,\n }));\n emitEvent({ type: \"$sessions\", tabId: \"tab-1\", items });\n }\n } catch {\n /* ignore */\n }\n break;\n }\n case \"session_load\": {\n try {\n const switchData = await apiFetch(`sessions/${encodeURIComponent(payload.name)}/switch`, {\n method: \"POST\",\n });\n if (!switchData?.ok) {\n console.warn(\"[tauri-bridge] session switch failed:\", payload.name, switchData);\n break;\n }\n const data = await apiFetch(`sessions/${encodeURIComponent(payload.name)}`);\n if (!Array.isArray(data?.messages)) {\n console.warn(\"[tauri-bridge] session_load: GET response missing messages\", data);\n break;\n }\n const raw = data.messages as any[];\n // Pre-pass: map tool-result rows by their call id so we can stitch\n // them into the assistant message that issued the call. Without\n // this, every tool segment in the replay shows \"(no result)\".\n const toolResults = new Map<string, { content: string; name?: string }>();\n for (const m of raw) {\n if (m?.role === \"tool\" && typeof m.toolCallId === \"string\") {\n toolResults.set(m.toolCallId, {\n content: typeof m.content === \"string\" ? m.content : \"\",\n name: typeof m.toolName === \"string\" ? m.toolName : undefined,\n });\n }\n }\n const messages: any[] = [];\n for (const m of raw) {\n if (m?.role === \"user\") {\n messages.push({ kind: \"user\" as const, text: m.content ?? \"\" });\n continue;\n }\n if (m?.role === \"assistant\") {\n const segments: any[] = [];\n if (typeof m.reasoning === \"string\" && m.reasoning.length > 0) {\n segments.push({ kind: \"reasoning\" as const, text: m.reasoning });\n }\n if (typeof m.content === \"string\" && m.content.length > 0) {\n segments.push({ kind: \"text\" as const, text: m.content });\n }\n if (Array.isArray(m.toolCalls)) {\n for (const tc of m.toolCalls) {\n const result = toolResults.get(tc.id);\n segments.push({\n kind: \"tool\" as const,\n callId: tc.id,\n name: tc.name || result?.name || \"tool\",\n args: tc.arguments ?? \"\",\n startedAt: 0,\n result: result?.content,\n ok: result != null,\n durationMs: 0,\n });\n }\n }\n messages.push({\n kind: \"assistant\" as const,\n turn: m.turn ?? 0,\n segments,\n pending: false,\n });\n }\n // tool-role messages are absorbed into their matching assistant segment above.\n }\n emitEvent({\n type: \"$session_loaded\",\n tabId: \"tab-1\",\n name: payload.name,\n messages,\n carryover: { totalCostUsd: 0, cacheHitTokens: 0, cacheMissTokens: 0 },\n });\n } catch (err) {\n console.warn(\"[tauri-bridge] session load failed:\", err);\n }\n break;\n }\n case \"session_delete\": {\n try {\n await apiFetch(`sessions/${encodeURIComponent(payload.name)}`, { method: \"DELETE\" });\n // 删除后刷新列表\n const data = await apiFetch(\"sessions\");\n if (data?.sessions) {\n const items = data.sessions.map((s: any) => ({\n name: s.name,\n messageCount: s.messageCount,\n mtime: new Date(s.mtime).toISOString(),\n summary: s.summary,\n }));\n emitEvent({ type: \"$sessions\", tabId: \"tab-1\", items });\n }\n } catch {\n /* ignore */\n }\n break;\n }\n case \"new_chat\": {\n try {\n const data = await apiFetch(\"sessions/new\", { method: \"POST\" });\n if (data?.ok) {\n const newName = typeof data.name === \"string\" ? data.name : \"default\";\n // Treat a fresh session like a loaded-empty session so the reducer\n // resets state.currentSession + messages. `$session_empty` is for\n // \"file exists but unparseable\" and would render a scary error.\n emitEvent({\n type: \"$session_loaded\",\n tabId: \"tab-1\",\n name: newName,\n messages: [],\n carryover: { totalCostUsd: 0, cacheHitTokens: 0, cacheMissTokens: 0 },\n });\n const listData = await apiFetch(\"sessions\");\n if (listData?.sessions) {\n const items = listData.sessions.map((s: any) => ({\n name: s.name,\n messageCount: s.messageCount,\n mtime: new Date(s.mtime).toISOString(),\n summary: s.summary,\n }));\n emitEvent({ type: \"$sessions\", tabId: \"tab-1\", items });\n }\n }\n } catch {\n /* fallback */\n }\n break;\n }\n case \"settings_get\": {\n try {\n const [settings, overview] = await Promise.all([\n apiFetch(\"settings\"),\n apiFetch(\"overview\"),\n ]);\n if (settings) emitServerSettings(settings, overview);\n } catch {\n /* ignore */\n }\n break;\n }\n case \"settings_save\": {\n try {\n await apiFetch(\"settings\", {\n method: \"POST\",\n body: JSON.stringify(payload),\n });\n // 保存后主动拉取最新设置以同步 UI\n const [settings, overview] = await Promise.all([\n apiFetch(\"settings\"),\n apiFetch(\"overview\"),\n ]);\n if (settings) emitServerSettings(settings, overview);\n } catch {\n /* ignore */\n }\n break;\n }\n case \"setup_save_key\": {\n await apiFetch(\"settings\", {\n method: \"POST\",\n body: JSON.stringify({ apiKey: payload.key }),\n }).catch(() => {});\n break;\n }\n case \"confirm_response\": {\n await apiFetch(\"modal\", {\n method: \"POST\",\n body: JSON.stringify({ id: payload.id, response: payload.response }),\n }).catch(() => {});\n break;\n }\n case \"choice_response\": {\n await apiFetch(\"modal\", {\n method: \"POST\",\n body: JSON.stringify({ id: payload.id, response: payload.response }),\n }).catch(() => {});\n break;\n }\n case \"plan_response\": {\n await apiFetch(\"modal\", {\n method: \"POST\",\n body: JSON.stringify({ id: payload.id, response: payload.response }),\n }).catch(() => {});\n break;\n }\n case \"checkpoint_response\": {\n await apiFetch(\"modal\", {\n method: \"POST\",\n body: JSON.stringify({ id: payload.id, response: payload.response }),\n }).catch(() => {});\n break;\n }\n case \"revision_response\": {\n await apiFetch(\"modal\", {\n method: \"POST\",\n body: JSON.stringify({ id: payload.id, response: payload.response }),\n }).catch(() => {});\n break;\n }\n case \"jobs_list\": {\n try {\n const data = await apiFetch(\"usage\");\n if (data?.jobs) {\n emitEvent({ type: \"$jobs\", tabId: \"tab-1\", items: data.jobs });\n }\n } catch {\n /* ignore */\n }\n break;\n }\n case \"mention_query\": {\n try {\n const data = await apiFetch(\n `files/search?q=${encodeURIComponent(payload.query)}&nonce=${payload.nonce}`,\n );\n if (data) {\n emitEvent({\n type: \"$mention_results\",\n tabId: \"tab-1\",\n nonce: payload.nonce,\n query: payload.query,\n results: data.results ?? [],\n });\n }\n } catch {\n /* ignore */\n }\n break;\n }\n case \"mention_preview\": {\n try {\n const data = await apiFetch(\n `file-read?path=${encodeURIComponent(payload.path)}&nonce=${payload.nonce}`,\n );\n if (data) {\n emitEvent({\n type: \"$mention_preview\",\n tabId: \"tab-1\",\n nonce: payload.nonce,\n path: payload.path,\n head: data.head ?? \"\",\n totalLines: data.totalLines ?? 0,\n });\n }\n } catch {\n /* ignore */\n }\n break;\n }\n // ── 桌面端特有操作(Web 版无操作或静默忽略) ──\n case \"qq_status_get\":\n case \"qq_connect\":\n case \"qq_disconnect\":\n case \"qq_config_save\":\n case \"tab_activate\":\n case \"tab_open\":\n case \"tab_close\":\n case \"mention_picked\":\n case \"btw\": {\n // 这些命令在 Web Server 模式下无对应 REST API,静默忽略\n break;\n }\n case \"jobs_stop\": {\n try {\n await apiFetch(`jobs/${payload.jobId}/stop`, { method: \"POST\" });\n } catch {}\n break;\n }\n case \"jobs_stop_all\": {\n try {\n await apiFetch(\"jobs/stop-all\", { method: \"POST\" });\n } catch {}\n break;\n }\n case \"compact_history\": {\n try {\n await apiFetch(\"messages/compact\", { method: \"POST\" });\n } catch {}\n break;\n }\n case \"retry\": {\n try {\n await apiFetch(\"submit\", { method: \"POST\", body: JSON.stringify({ retry: true }) });\n } catch {}\n break;\n }\n case \"skill_run\": {\n const body: Record<string, any> = { name: payload.name };\n if (payload.args) body.args = payload.args;\n try {\n await apiFetch(\"skills/run\", { method: \"POST\", body: JSON.stringify(body) });\n } catch {}\n break;\n }\n case \"mcp_specs_get\": {\n await loadAndEmitMcp();\n break;\n }\n case \"skills_get\": {\n await loadAndEmitSkills();\n break;\n }\n case \"memory_get\": {\n await loadAndEmitMemory();\n break;\n }\n case \"memory_read\": {\n if (typeof payload.path === \"string\") await loadAndEmitMemoryDetail(payload.path);\n break;\n }\n case \"mcp_specs_add\":\n case \"mcp_specs_remove\": {\n // MCP 操作通过 REST API 管理\n try {\n await apiFetch(\"mcp\", {\n method: \"POST\",\n body: JSON.stringify({\n action: cmd === \"mcp_specs_add\" ? \"add\" : \"remove\",\n spec: payload.spec,\n }),\n });\n await loadAndEmitMcp();\n } catch {}\n break;\n }\n default:\n console.warn(\"[tauri-bridge] unhandled RPC cmd:\", cmd);\n }\n}\n\n// // ═══ 导出接口(Mock + Server 双模式)\n// Tauri core API\nexport async function invoke(cmd: string, args?: any): Promise<any> {\n console.log(`[tauri-bridge] invoke -> cmd: ${cmd}${args ? \" \" + JSON.stringify(args) : \"\"}`);\n\n if (MODE === \"server\") {\n if (cmd === \"rpc_spawn\") {\n serverInit().catch(console.warn);\n return Promise.resolve();\n }\n if (cmd === \"rpc_send\") {\n const payload = JSON.parse(args.line);\n payload.tabId = payload.tabId ?? \"tab-1\";\n serverRpc(payload).catch(console.warn);\n return Promise.resolve();\n }\n if (cmd === \"open_in_editor\") {\n console.log(\"[tauri-bridge] open in editor:\", args);\n return Promise.resolve();\n }\n return Promise.resolve();\n }\n\n // Mock mode\n if (cmd === \"rpc_spawn\") {\n mockSetupAndReady();\n return Promise.resolve();\n }\n\n if (cmd === \"rpc_send\") {\n const payload = JSON.parse(args.line);\n if (payload.cmd === \"user_input\") {\n emitEvent({\n type: \"user.message\",\n tabId: \"tab-1\",\n id: Date.now(),\n ts: new Date().toISOString(),\n turn: 2,\n text: payload.text,\n });\n mockAssistantTurn(payload.text);\n } else if (payload.cmd === \"session_list\") {\n emitEvent({ type: \"$sessions\", tabId: \"tab-1\", items: mockSessions });\n } else if (payload.cmd === \"session_load\") {\n emitEvent({\n type: \"$session_loaded\",\n tabId: \"tab-1\",\n name: payload.name,\n messages: mockMessages,\n carryover: { totalCostUsd: 0.045, cacheHitTokens: 2500, cacheMissTokens: 1400 },\n });\n } else if (payload.cmd === \"new_chat\") {\n emitEvent({\n type: \"$session_empty\",\n tabId: \"tab-1\",\n name: \"desktop-new-session\",\n sizeBytes: 0,\n });\n } else if (payload.cmd === \"settings_get\") {\n emitEvent({ type: \"$settings\", tabId: \"tab-1\", ...mockSettings });\n }\n return Promise.resolve();\n }\n\n if (cmd === \"open_in_editor\") {\n console.log(\"[tauri-bridge] open in editor simulation:\", args);\n return Promise.resolve();\n }\n\n return Promise.resolve();\n}\n\n// 2. @tauri-apps/api/event\nexport async function listen<T = any>(\n eventName: string,\n callback: EventCallback<T>,\n): Promise<UnlistenFn> {\n let bucket = listeners.get(eventName);\n if (!bucket) {\n bucket = new Set();\n listeners.set(eventName, bucket);\n }\n bucket.add(callback);\n return () => {\n const b = listeners.get(eventName);\n if (b) b.delete(callback);\n };\n}\n\n// 3a. @tauri-apps/api/webview\nexport function getCurrentWebview(): any {\n return {\n onDragDropEvent: async (_callback: any): Promise<() => void> => {\n console.log(\"[tauri-bridge] onDragDropEvent (no-op in web)\");\n return () => {};\n },\n };\n}\n\n// 3b. @tauri-apps/api/window\nexport function getCurrentWindow(): any {\n return {\n isMaximized: async () => false,\n minimize: async () => {\n console.log(\"[tauri-bridge] minimize (no-op)\");\n },\n close: async () => {\n console.log(\"[tauri-bridge] close (no-op)\");\n },\n toggleMaximize: async () => {\n console.log(\"[tauri-bridge] toggleMaximize (no-op)\");\n },\n listen:\n async (_event: string, _callback: any): Promise<() => void> =>\n () => {},\n label: \"main\",\n };\n}\n\n// 4. @tauri-apps/plugin-dialog\nexport async function open(options?: any): Promise<any> {\n console.log(\"[tauri-bridge] dialog open:\", options);\n return Promise.resolve(\"\");\n}\n\nexport async function save(options?: any): Promise<any> {\n console.log(\"[tauri-bridge] dialog save:\", options);\n return Promise.resolve(\"\");\n}\n\n// 5. @tauri-apps/plugin-opener\nexport async function openUrl(url: string): Promise<void> {\n console.log(`[tauri-bridge] open url -> ${url}`);\n window.open(url, \"_blank\");\n return Promise.resolve();\n}\n\nexport async function openPath(path: string): Promise<void> {\n console.log(`[tauri-bridge] open path -> ${path}`);\n return Promise.resolve();\n}\n\n// 6. @tauri-apps/plugin-process\nexport async function relaunch(): Promise<void> {\n console.log(\"[tauri-bridge] process relaunch (reload page)\");\n window.location.reload();\n return Promise.resolve();\n}\n\n// // ═══ Mock 数据(仅 Vite 开发模式使用)\n//\nconst mockSessions = [\n {\n name: \"desktop-20260520-1\",\n messageCount: 8,\n mtime: new Date().toISOString(),\n summary: \"项目工程模块重构及自适应 UI 设计\",\n },\n {\n name: \"desktop-20260519-2\",\n messageCount: 14,\n mtime: new Date(Date.now() - 86400000).toISOString(),\n summary: \"编写 WebSocket 桥接与 RPC 行协议对接逻辑\",\n },\n {\n name: \"desktop-20260518-3\",\n messageCount: 4,\n mtime: new Date(Date.now() - 172800000).toISOString(),\n summary: \"测试移动端 TextArea 与 Dynamic Viewport\",\n },\n];\n\nconst mockSettings = {\n reasoningEffort: \"high\",\n editMode: \"review\",\n budgetUsd: null,\n workspaceDir: \"\",\n recentWorkspaces: [],\n model: \"deepseek-v4-flash\",\n version: \"0.47.2\",\n};\n\nconst mockMessages: any[] = [\n { kind: \"user\", text: \"你好 Reasonix,帮我列出这个项目的主要技术栈以及前端架构体系。\" },\n {\n kind: \"assistant\",\n turn: 1,\n segments: [\n { kind: \"reasoning\", text: \"用户询问项目的技术栈和前端架构。\" },\n { kind: \"text\", text: \"你好!**DeepSeek-Reasonix** 是一个以 DeepSeek 为内核的智能代码助手…\" },\n ],\n pending: false,\n },\n];\n\nfunction mockAssistantTurn(_promptText: string) {\n emitEvent({ type: \"status\", text: \"DeepSeek R1 思考中...\", tabId: \"tab-1\" });\n setTimeout(() => {\n emitEvent({\n type: \"model.turn.started\",\n tabId: \"tab-1\",\n id: Date.now(),\n turn: 2,\n model: \"deepseek-reasoner\",\n reasoningEffort: \"high\",\n });\n }, 600);\n // reasoning deltas\n const lines = [\"分析用户的输入内容。\\n\", \"用户要求提供自适应 UI 重构的验证指令。\\n\"];\n let delay = 1200;\n lines.forEach((line) => {\n setTimeout(() => {\n emitEvent({ type: \"model.delta\", tabId: \"tab-1\", channel: \"reasoning\", text: line, turn: 2 });\n }, delay);\n delay += 800;\n });\n // tool call\n setTimeout(() => {\n emitEvent({ type: \"tool.preparing\", tabId: \"tab-1\", name: \"list_dir\", callId: \"call_12345\" });\n }, delay);\n delay += 500;\n setTimeout(() => {\n emitEvent({\n type: \"tool.intent\",\n tabId: \"tab-1\",\n name: \"list_dir\",\n args: JSON.stringify({ DirectoryPath: \"d:/AI/workspace/dashboard\" }),\n callId: \"call_12345\",\n });\n }, delay);\n delay += 1000;\n setTimeout(() => {\n emitEvent({\n type: \"tool.result\",\n tabId: \"tab-1\",\n name: \"list_dir\",\n ok: true,\n output: JSON.stringify([\n { name: \"package.json\", sizeBytes: 864 },\n { name: \"src\", isDir: true },\n ]),\n callId: \"call_12345\",\n });\n }, delay);\n delay += 800;\n // text response\n const chunks = [\n \"您的 dashboard 目录结构已确认。在**独立 Mock 开发预览阶段**,\\n\",\n \"您可以使用 `npm run dev` 启动 Vite 开发服务,\\n\",\n \"配合 Chrome 设备模拟器或真实手机进行移动端自适应效果验证。\\n\",\n \"手机端支持侧滑拉出会话抽屉,输入框紧贴虚拟键盘。\",\n ];\n chunks.forEach((chunk) => {\n setTimeout(() => {\n emitEvent({ type: \"model.delta\", tabId: \"tab-1\", channel: \"content\", text: chunk, turn: 2 });\n }, delay);\n delay += 500;\n });\n setTimeout(() => {\n emitEvent({\n type: \"model.final\",\n tabId: \"tab-1\",\n turn: 2,\n content: chunks.join(\"\"),\n reasoningContent: lines.join(\"\"),\n costUsd: 0.002,\n });\n emitEvent({ type: \"$turn_complete\", tabId: \"tab-1\" });\n }, delay + 400);\n}\n\nfunction mockSetupAndReady() {\n document.documentElement.dataset.web = \"true\";\n setTimeout(() => emitEvent({ type: \"$ready\", tabId: \"tab-1\" }), 100);\n setTimeout(() => {\n emitEvent({\n type: \"$tab_opened\",\n tabId: \"tab-1\",\n workspaceDir: \"d:\\\\AI\\\\workspace\",\n active: true,\n });\n }, 150);\n setTimeout(() => emitEvent({ type: \"$settings\", tabId: \"tab-1\", ...mockSettings }), 200);\n setTimeout(() => emitEvent({ type: \"$sessions\", tabId: \"tab-1\", items: mockSessions }), 350);\n}\n","export const en = {\n app: {\n sectionWorkspace: \"workspace\",\n sectionObserve: \"observe\",\n sectionConfigure: \"configure\",\n tabChat: \"Chat\",\n tabPlans: \"Plans\",\n tabSessions: \"Sessions\",\n tabOverview: \"Overview\",\n tabUsage: \"Usage\",\n tabSystem: \"System\",\n tabSemantic: \"Semantic\",\n tabTools: \"Tools\",\n tabPermissions: \"Permissions\",\n tabMcp: \"MCP\",\n tabSkills: \"Skills\",\n tabMemory: \"Memory\",\n tabHooks: \"Hooks\",\n tabSettings: \"Settings\",\n sectionChanges: \"Changes\",\n tabChanges: \"Changes\",\n footer: \"127.0.0.1 only · token-gated\",\n themeToggle: \"Toggle theme\",\n themeLight: \"Light\",\n themeDark: \"Dark\",\n skill: {\n scope: {\n builtin: \"Built-in\",\n global: \"Global\",\n project: \"Project\",\n },\n runAs: {\n subagent: \"Subagent\",\n inline: \"Inline\",\n },\n generic: \"Skill\",\n },\n exportReasoningSummary: \"Reasoning Summary\",\n exportToolLabel: \"Tool Calls\",\n exportUserLabel: \"User Messages\",\n empty: {\n currentWorkspace: \"Current workspace\",\n selectWorkspace: \"Select a workspace to get started\",\n suggestion0: \"Start a new conversation\",\n suggestion1: \"Open settings\",\n suggestion2: \"View overview\",\n suggestion3: \"Browse sessions\",\n welcome: \"Welcome to Reasonix\",\n },\n errorLabel: \"Error\",\n connecting: \"Connecting…\",\n session: {\n format: \"Session\",\n new: \"New Session\",\n },\n setup: {\n choose: \"Choose a workspace\",\n description: \"Select a workspace to start working\",\n notSelected: \"No workspace selected\",\n saveAndStart: \"Save & Start\",\n welcome: \"Welcome\",\n workspace: \"Workspace\",\n },\n tab: {\n newTab: \"+ New Tab\",\n newTabTitle: \"Open a new tab\",\n },\n titlebar: {\n clearChat: \"Clear Chat\",\n close: \"Close\",\n commandPalette: \"Command Palette\",\n contextPanel: \"Context Panel\",\n copyMd: \"Copy as Markdown\",\n exportMd: \"Export as Markdown\",\n maximize: \"Maximize\",\n minimize: \"Minimize\",\n more: \"More\",\n restore: \"Restore\",\n settings: \"Settings\",\n sidebar: \"Sidebar\",\n windowControls: \"Window Controls\",\n },\n toast: {\n cleared: \"Chat cleared\",\n copied: \"Copied to clipboard\",\n copiedMd: \"Copied as Markdown\",\n emptySession: \"No messages to export\",\n exportDialogTitle: \"Export Chat\",\n exportedMd: \"Exported as Markdown\",\n exportFailed: \"Export failed\",\n langSwitched: \"Language switched\",\n modelSwitched: \"Model → {model}\",\n effortSwitched: \"Effort → {effort}\",\n modeSwitched: \"Mode switched\",\n newSession: \"New session created\",\n },\n yolo: {\n toast: \"YOLO mode enabled\",\n },\n cmd: {\n abort: \"Abort\",\n btw: \"BTW\",\n clearChat: \"Clear Chat\",\n compact: \"Compact\",\n copyLast: \"Copy Last\",\n exportMd: \"Export as Markdown\",\n feedback: \"Feedback\",\n help: \"Help\",\n newSession: \"New Session\",\n retry: \"Retry\",\n switchModel: \"Switch Model\",\n toggleCurrency: \"Toggle Currency\",\n toggleLang: \"Toggle Language\",\n toggleTheme: \"Toggle Theme\",\n },\n header: {\n abort: \"Abort\",\n clickToSelect: \"Click to select\",\n copy: \"Copy\",\n copyMd: \"Copy as Markdown\",\n export: \"Export\",\n exportMd: \"Export as Markdown\",\n newChat: \"New Chat\",\n noWorkspace: \"No workspace\",\n running: \"Running…\",\n },\n jumpToBottom: \"Jump to bottom\",\n langEN: \"English\",\n langZH: \"中文\",\n splashSubtitle: \"AI-powered coding assistant\",\n },\n changes: {\n chatPlaceholder: \"Ask about your code...\",\n chatWelcome: \"Changes — ask questions about your project files.\",\n chatSend: \"Send\",\n viewerPlaceholder: \"Select a file to view\",\n treeEmpty: \"(empty)\",\n tabClose: \"Close tab\",\n newConversation: \"New\",\n clearConversation: \"Clear\",\n newTitle: \"/new — wipe conversation context\",\n clearTitle: \"/clear — wipe visible scrollback\",\n newConfirmBusy: \"A turn is in flight. Abort and start a new conversation?\",\n newConfirm: \"Clear current conversation and start fresh?\",\n newToast: \"new conversation\",\n clearToast: \"scrollback cleared\",\n newFailed: \"/new failed: {error}\",\n clearFailed: \"/clear failed: {error}\",\n chatSendBtn: \"Send\",\n fileTreeTitle: \"Files\",\n codeViewerTitle: \"Code Viewer\",\n chatPanelTitle: \"Chat\",\n loadingFiles: \"Loading project files…\",\n review: \"Review\",\n allFiles: \"All Files\",\n changes: \"changes\",\n commentLabel: \"Commenting on line\",\n commentPlaceholder: \"Add a comment…\",\n commentCancel: \"Cancel\",\n commentSubmit: \"Comment\",\n commentLine: \"Line\",\n commentEdit: \"Edit\",\n commentDelete: \"Delete\",\n diffSourceGit: \"Git changes\",\n diffSourceSession: \"Previous session\",\n diffSourceCheckpoint: \"Checkpoint\",\n checkpointEmpty: \"No checkpoints in this workspace yet.\",\n restoreBtn: \"Restore\",\n restoreConfirm: 'Restore \"{name}\"? This will overwrite current files.',\n deleteBtn: \"Delete\",\n deleteConfirm: 'Delete checkpoint \"{name}\"? Snapshot will be removed, files stay unchanged.',\n createBtn: \"Snapshot\",\n createPlaceholder: \"name for snapshot…\",\n backToList: \"back to list\",\n reviewEmpty: \"No pending reviews.\",\n diffStyleUnified: \"Unified\",\n diffStyleSplit: \"Split\",\n expandAll: \"Expand all\",\n collapseAll: \"Collapse all\",\n createFailed: \"create failed\",\n restoreFailed: \"restore failed\",\n deleteFailed: \"delete failed\",\n },\n common: {\n loading: \"loading…\",\n loadingFailed: \"{name} failed: {error}\",\n back: \"← back\",\n save: \"Save\",\n remove: \"remove\",\n cancel: \"Cancel\",\n delete: \"Delete\",\n add: \"Add\",\n confirm: \"Confirm\",\n noData: \"No {name} yet.\",\n all: \"all\",\n yes: \"yes\",\n no: \"no\",\n on: \"ON\",\n off: \"off\",\n enabled: \"enabled\",\n disabled: \"disabled\",\n },\n settings: {\n title: \"Settings\",\n loading: \"loading settings…\",\n saved: \"saved: {fields}\",\n sectionApi: \"DeepSeek API\",\n apiKey: \"API key\",\n apiKeyNotSet: \"Not set\",\n apiKeySave: \"Save key\",\n apiKeySet: \"Set\",\n apiSection: \"API Configuration\",\n notSet: \"(not set)\",\n replace: \"replace\",\n pasteKey: \"paste a fresh sk-… token\",\n saveKey: \"Save key\",\n baseUrl: \"base url\",\n baseUrlPlaceholder: \"https://api.deepseek.com (default)\",\n baseUrlHint: \"Base URL for API requests\",\n sectionDefaults: \"Defaults\",\n effortSection: \"Reasoning effort\",\n modelCustom: \"Custom model id\",\n modelCustomHint: \"Any OpenAI-compatible id your endpoint serves (vLLM, Ollama, Together, …).\",\n modelCustomActive: \"Currently running on a custom id: {model}\",\n appliesNextTurn: \"applies next turn\",\n effort: \"effort\",\n effortMax: \"max (DeepSeek extension — rejected by stock OpenAI / vLLM)\",\n effortHigh: \"high (safe default — vLLM / Azure compatible)\",\n effortMedium: \"medium\",\n effortLow: \"low (fastest)\",\n webSearch: \"web search\",\n webSearchNote: \"web_fetch + web_search tools\",\n webSearchEngine: \"search engine\",\n webSearchEngineBing: \"bing — default, works from CN without proxy\",\n webSearchEngineSearxng: \"searxng — self-hosted (set endpoint via /se searxng <url>)\",\n webSearchEngineMetaso: \"metaso — 100/day free (CN-friendly, free key at metaso.cn)\",\n webSearchEngineTavily: \"tavily — 1000/mo free (set TAVILY_API_KEY)\",\n webSearchEnginePerplexity: \"perplexity — AI-native (set PERPLEXITY_API_KEY)\",\n webSearchEngineExa: \"exa — AI-native 1000/mo free (set EXA_API_KEY)\",\n webSearchEngineNote: \"applies to the next web_search call\",\n sectionBudget: \"Budget\",\n budget: \"Budget\",\n budgetHint: \"Set spending limits\",\n budgetPlaceholder: \"Enter budget amount\",\n budgetOf: \"of\",\n budgetSetCap: \"set a cap\",\n budgetCustom: \"custom\",\n budgetBumpHint: \"bump the cap to keep going\",\n budgetClear: \"Clear cap\",\n budgetIdleLine: \"warns at 80% · refuses past 100%\",\n budgetWarnLine: \"approaching cap — loop will refuse past 100%\",\n budgetRefusing: \"cap exhausted — next turn refused until bumped or cleared\",\n sectionLoop: \"Loop\",\n loopIdleHint: \"Auto-resubmit a prompt on a fixed interval.\",\n loopCostHint: \"Each iteration costs ~{cost} (last turn).\",\n loopInterval: \"interval\",\n loopCustom: \"custom\",\n loopRangeError: \"interval must fall in 5s..6h\",\n loopPrompt: \"prompt\",\n loopPromptPlaceholder: \"e.g. check the deploy status and report any errors\",\n loopStart: \"Start loop\",\n loopStop: \"Stop\",\n loopRunning: \"running\",\n loopIter: \"iter {iter}\",\n loopFiresIn: \"fires in {remaining}\",\n sectionSkills: \"Skills\",\n skillPaths: \"skill paths\",\n skillPathsPlaceholder: \"/path/to/skills-a, /path/to/skills-b\",\n skillPathsNote: \"comma-separated · next /new or new session\",\n skillsEmpty: \"No skills loaded\",\n skillsLoaded: \"Skills loaded\",\n subagentModelFlash: \"flash\",\n subagentModelPro: \"pro\",\n subagentModelHint: \"Model used when this skill spawns its isolated subagent\",\n sectionRuntime: \"Runtime\",\n activeModel: \"active model\",\n model: \"Model\",\n modelFlashDesc: \"Flash — always flash\",\n modelProDesc: \"Pro — always pro\",\n modelPricingLine: \"${hit} hit · ${miss} miss · ${out} out per 1M tok\",\n editMode: \"edit mode\",\n editModeNote: \"switch from the Chat tab header\",\n editModeHint: \"Configure edit mode\",\n showSystemEvents: \"system events\",\n showSystemEventsHint: \"Show quiet inline notices for context compaction, abort, rate-limit.\",\n shown: \"shown\",\n hidden: \"hidden\",\n sectionLanguage: \"Language\",\n language: \"language\",\n languageHint: \"Switch language\",\n langEn: \"English\",\n langZhCn: \"简体中文\",\n appMode: \"App mode\",\n appearanceSection: \"Appearance\",\n behaviorSection: \"Behavior\",\n ruleAutoApprovalHint: \"Configure auto-approval rules\",\n ruleAutoApprovalSection: \"Auto-approval Rules\",\n theme: \"Theme\",\n themeDark: \"Dark\",\n themeHint: \"Switch between light and dark themes\",\n themeLight: \"Light\",\n themeStyle: \"Theme style\",\n themeStyleHint: \"Choose theme style\",\n themeStyleGraphite: \"Graphite\",\n themeStyleGraphiteDesc: \"Cool dark neutrals — best for long sessions.\",\n themeStyleSandstone: \"Sandstone\",\n themeStyleSandstoneDesc: \"Warm light tones — easy on bright rooms.\",\n themeStylePorcelain: \"Porcelain\",\n themeStylePorcelainDesc: \"Clean light with extra contrast.\",\n themeStyleMidnight: \"Midnight\",\n themeStyleMidnightDesc: \"Deep dark with cooler highlights.\",\n pageGeneralLabel: \"General\",\n pageGeneralDesc: \"Theme, fonts, language and workspace.\",\n pageModelsLabel: \"Models\",\n pageModelsDesc: \"Default model and reasoning effort.\",\n pageMcpLabel: \"MCP servers\",\n pageMcpDesc: \"Connect external tool servers.\",\n pageSkillsLabel: \"Skills\",\n pageSkillsDesc: \"User-defined skills you can run with /skill.\",\n pageMemoryLabel: \"Memory\",\n pageMemoryDesc: \"Long-lived notes carried across sessions.\",\n pageRulesLabel: \"Rules\",\n pageRulesDesc: \"Auto-approval rules for shell + path access.\",\n pageBillingLabel: \"Billing\",\n pageBillingDesc: \"API key, balance and per-session budget.\",\n pageShortcutsLabel: \"Shortcuts\",\n pageShortcutsDesc: \"Keyboard shortcuts reference.\",\n fontFamily: \"Font family\",\n fontFamilyHint: \"Choose font family\",\n fontFamilySans: \"Sans-serif\",\n fontFamilySerif: \"Serif\",\n fontFamilySystem: \"System\",\n fontScale: \"Font scale\",\n fontScaleHint: \"Adjust font size\",\n fontScaleLarge: \"Large\",\n fontScaleMedium: \"Medium\",\n fontScaleSmall: \"Small\",\n currentWorkspace: \"Current workspace\",\n defaultModelCurrent: \"Current model\",\n editor: \"Editor\",\n editorHint: \"Configure editor preferences\",\n maxOutput: \"Max output\",\n reasoningEffort: \"Reasoning effort\",\n reasoningEffortHint: \"Adjust reasoning depth\",\n sessionCost: \"Session cost\",\n balanceAvailable: \"Available\",\n balanceLabel: \"Balance\",\n balanceLow: \"Low balance\",\n cacheHitRate: \"Cache hit rate\",\n ctxWindow: \"Context window\",\n notSelected: \"Not selected\",\n parseError: \"Parse error\",\n workspaceChange: \"Change\",\n workspaceSection: \"Workspace\",\n mcpAdd: \"Add\",\n mcpAddSection: \"Add MCP Server\",\n mcpBridged: \"Bridged\",\n mcpConfigured: \"Configured\",\n mcpEmpty: \"No MCP servers\",\n mcpNotBridged: \"Not bridged\",\n mcpRemove: \"Remove\",\n mcpSpecFormat: \"JSON format\",\n mcpSpecLabel: \"Server spec\",\n memoryDesc: \"Configure memory settings\",\n memorySection: \"Memory\",\n shortcutAbort: \"Abort\",\n shortcutCloseTab: \"Close Tab\",\n shortcutCommandPalette: \"Command Palette\",\n shortcutFocusComposer: \"Focus Composer\",\n shortcutNewChat: \"New Chat\",\n shortcutNewTab: \"New Tab\",\n shortcutSettings: \"Settings\",\n shortcutSwitchTab: \"Switch Tab\",\n qqAccessAllowlist: \"Allowlist\",\n qqAccessOpen: \"Open\",\n qqAccessOwner: \"Owner\",\n qqAccessOwnerWithAllowlist: \"Owner + Allowlist\",\n qqAccessRuntime: \"Runtime\",\n qqAppId: \"App ID\",\n qqApplyAction: \"Apply\",\n qqApplyLabel: \"Apply\",\n qqAppSecret: \"App Secret\",\n qqBack: \"Back\",\n qqConfigure: \"Configure\",\n qqConfigureHint: \"Set up QQ integration\",\n qqConfigureTitle: \"QQ Configuration\",\n qqConnected: \"Connected\",\n qqConnecting: \"Connecting…\",\n qqDisconnected: \"Disconnected\",\n qqEnvironment: \"Environment\",\n qqFailed: \"Failed\",\n qqProduction: \"Production\",\n qqSandbox: \"Sandbox\",\n qqSave: \"Save\",\n qqSaveAndConnect: \"Save & Connect\",\n qqSection: \"QQ Integration\",\n qqSummaryAppId: \"App ID\",\n qqSummaryDetail: \"Details\",\n qqSummaryMissing: \"Not configured\",\n qqTitle: \"QQ Bot\",\n },\n chat: {\n modeMirror: \"TUI mirror\",\n modeView: \"session view\",\n placeholder: \"Type a prompt — Enter sends, Shift+Enter for a newline · / @ for pickers\",\n placeholderBusy: \"wait for the current turn to finish…\",\n placeholderSteerBusy: \"type to steer — commands and pickers are disabled while busy\",\n steerHint: \"message steers the current turn (added as instruction)\",\n send: \"Send\",\n new: \"New\",\n clear: \"Clear\",\n newTitle: \"/new — wipe conversation context (loop log + scrollback)\",\n clearTitle: \"/clear — wipe just visible scrollback (context kept)\",\n noConversation: \"No conversation yet. Send a prompt below to begin.\",\n newConfirmBusy: \"A turn is in flight. Abort and start a new conversation?\",\n newConfirm: \"Clear current conversation and start fresh?\",\n newToast: \"new conversation\",\n clearToast: \"scrollback cleared\",\n newFailed: \"/new failed: {error}\",\n clearFailed: \"/clear failed: {error}\",\n eventStreamError: \"event stream interrupted — reconnecting…\",\n semanticBanner: \"Semantic search isn't enabled for this project.\",\n semanticBannerDesc:\n 'Build the index once and the model can find code by meaning (\"where do we handle auth failures?\") instead of grep on exact strings.',\n semanticBannerBtn: \"Build it →\",\n semanticBannerDismiss: \"dismiss (don't show again)\",\n slashCommands: \"slash commands\",\n projectFiles: \"project files\",\n effortTitle: \"reasoning_effort — applies next turn\",\n effortMaxTitle: \"max (DeepSeek extension)\",\n effortHighTitle: \"high (safe default — vLLM / Azure compatible)\",\n effortMediumTitle: \"medium\",\n effortLowTitle: \"low (fastest)\",\n editGateTitle: \"edit gate — Shift+Tab cycles in TUI\",\n editReviewTitle: \"review — both edits and non-allowlisted shell ask first\",\n editAutoTitle: \"auto — edits auto-apply, shell still asks\",\n editYoloTitle: \"yolo — edits AND shell auto-run, allowlist bypassed\",\n railSession: \"Session\",\n railTurns: \"turns\",\n railPromptTok: \"prompt tok\",\n railCost: \"cost\",\n railCacheHit: \"cache hit\",\n railToolBudget: \"Tool budget\",\n railSpend: \"spend\",\n railActivePlan: \"Active plan\",\n railProgress: \"progress\",\n statusModel: \"model\",\n statusCtx: \"ctx\",\n statusCache: \"cache\",\n statusTurn: \"turn\",\n statusSession: \"session\",\n statusBalance: \"balance\",\n statusTurns: \"{count} turn{s}\",\n waitingStats: \"· · · waiting for live stats\",\n inflightPhase: \"{phase}\",\n inflightRunning: \"running\",\n inflightThinking: \"thinking\",\n inflightStreaming: \"streaming\",\n inflightWaiting: \"waiting\",\n inflightReasoning: \"reasoning {count} ch\",\n inflightOut: \"out {count} ch\",\n abortBtn: \"Abort (Esc)\",\n confirmBtn: \"Apply (y)\",\n rejectBtn: \"Reject (n)\",\n applyRestBtn: \"Apply rest (a)\",\n flipAutoBtn: \"Flip to AUTO (A)\",\n },\n overview: {\n loading: \"loading overview…\",\n failed: \"overview failed: {error}\",\n standaloneTitle: \"Standalone mode\",\n standaloneDesc:\n \"Read-only disk view. Start /dashboard from inside reasonix code for live session state, MCP, and tools.\",\n cockpit: \"Cockpit\",\n balance: \"balance\",\n tokens7d: \"tokens · 7d\",\n cacheHit: \"cache hit\",\n toolCalls24h: \"tool calls · 24h\",\n budget: \"budget\",\n currentSession: \"current session\",\n noSession: \"No live session — /dashboard from inside reasonix code to attach.\",\n promptTok: \"prompt tok\",\n completionTok: \"completion tok\",\n cost: \"cost\",\n costTrend: \"cost · 14 day\",\n noUsageYet: \"no usage yet\",\n dayAvg: \"/day avg\",\n recentPlans: \"recent plans\",\n noPlans: \"No plans yet — submit one with submit_plan.\",\n toolActivity: \"tool activity\",\n noToolCalls: \"No tool calls yet.\",\n toolsLoaded: \"tools loaded\",\n mcpServers: \"mcp servers\",\n editMode: \"edit mode\",\n version: \"Reasonix\",\n workingDir: \"Working directory\",\n projectRoot: \"project root\",\n noPriorData: \"no prior data\",\n stable: \"— stable\",\n vsPrior: \"{arrow} {pct}% vs prior\",\n active: \"active\",\n allUp: \"all up\",\n yoloWarning: \"all prompts bypassed\",\n checking: \"checking\",\n latest: \"latest\",\n },\n usage: {\n loading: \"loading usage…\",\n failed: \"usage failed: {error}\",\n records: \"{count} records\",\n dailyUsage: \"Daily usage\",\n dailyMeta: \"cost · cache saved · turns\",\n noData: \"No usage data yet — run a turn in reasonix chat / code / run and refresh.\",\n windows: \"Rolling windows\",\n colWindow: \"window\",\n colTurns: \"turns\",\n colCacheHit: \"cache hit\",\n colCost: \"cost (USD)\",\n colCacheSaved: \"cache saved\",\n colVsClaude: \"vs Claude\",\n colSaved: \"saved\",\n axisTime: \"time\",\n axisUsd: \"USD\",\n axisTurns: \"turns\",\n seriesCost: \"cost\",\n seriesCacheSaved: \"cache saved\",\n seriesTurns: \"turns\",\n mostUsed: \"Most used models\",\n colModel: \"model\",\n },\n sessions: {\n loading: \"loading sessions…\",\n failed: \"sessions failed: {error}\",\n noSessions: \"No saved sessions yet.\",\n filterPlaceholder: \"filter sessions\",\n msgs: \"msgs\",\n pickHint: \"Pick a session on the left to read its transcript.\",\n resumeTitle: \"Resume in TUI\",\n resumeDesc:\n \"Mid-session swap requires a restart so the message log can rewind cleanly. Quit your current session, then run:\",\n loadingTranscript: \"loading transcript…\",\n emptyTranscript: \"empty transcript.\",\n messages: \"{count} message{s}\",\n newBtn: \"New session\",\n newHint: \"Archive the current conversation and start a fresh one\",\n switchBtn: \"Switch to this session\",\n deleteBtn: \"Delete\",\n deleteConfirm: \"Delete session \\\"{name}\\\"? This removes the transcript file and cannot be undone.\",\n cantDeleteActive: \"Switch to a different session before deleting this one.\",\n attachRequired:\n \"Live session operations need an attached CLI session. Launch via reasonix chat or open the dashboard from inside a TUI session.\",\n activeChip: \"active\",\n activePill: \"active\",\n },\n tools: {\n loading: \"loading tools…\",\n failed: \"tools failed: {error}\",\n noTools: \"No tools registered.\",\n planMode: \"plan mode — writes gated\",\n colTool: \"tool\",\n colFlags: \"flags\",\n colDesc: \"description\",\n readOnly: \"read-only\",\n write: \"write\",\n flat: \"flat\",\n desc: {\n web_search:\n \"Search the public web. Returns ranked results with title, url, and snippet. Call this when the answer depends on current state — events, prices, releases, real-world status.\",\n web_fetch:\n \"Download a URL and return its visible text content (scripts/styles/nav stripped). Use after web_search when a snippet isn't enough.\",\n run_command:\n \"Run a shell command in the project root; returns combined stdout+stderr. Allowlisted read-only commands run immediately; mutations are gated by user confirmation.\",\n run_background:\n \"Spawn a long-running process and detach. Returns a job id for tailing logs, waiting for completion, or killing. Use for dev servers, watchers, and one-shot long jobs.\",\n job_output:\n \"Read the latest output of a background job. Returns the tail of the buffer and tells you whether the job is still running.\",\n wait_for_job:\n \"Block server-side until a background job finishes, bounded by timeout. Use instead of polling job_output in a loop.\",\n stop_job:\n \"Stop a background job. SIGTERM first, SIGKILL after a grace period. Safe to call on an already-exited job.\",\n list_jobs:\n \"List every background job started this session — running and exited — with id, command, pid, and status.\",\n remember:\n \"Save a memory for future sessions. Use when the user states a preference, corrects your approach, shares a non-obvious fact, or asks you to remember something.\",\n forget:\n \"Delete a memory file and remove it from MEMORY.md. Use when the user asks to forget something or a remembered fact is now wrong.\",\n recall_memory:\n \"Read the full body of a memory file when its one-line summary isn't enough detail.\",\n read_file:\n \"Read a file under the sandbox root. Supports head/tail/range scoping to save context. Auto-returns a preview for files over 200 lines.\",\n list_directory:\n \"List entries in a directory. Returns one line per entry, marking directories with a trailing slash.\",\n directory_tree:\n \"Recursively list entries in a directory as an indented tree. Budget-aware with auto-collapse for large subtrees.\",\n search_files:\n \"Find files whose NAME matches a substring or regex. Case-insensitive. Skips dependency/build directories by default.\",\n search_content:\n \"Recursively grep file CONTENTS for a substring or regex. Returns matches in path:line:text format. The right tool for finding references.\",\n glob: \"List files matching a glob pattern, sorted by mtime. Default limit 200, max 1000. Skips node_modules/.git/dist by default.\",\n get_file_info: \"Stat a path under the sandbox root. Returns type, size in bytes, and mtime.\",\n write_file:\n \"Create or overwrite a file with the given content. Parent directories are created as needed.\",\n edit_file:\n \"Apply a SEARCH/REPLACE edit to an existing file. The search must match exactly and be unique in the file.\",\n multi_edit:\n \"Apply N SEARCH/REPLACE edits across one or more files atomically. If any edit fails, no files are written.\",\n create_directory: \"Create a directory (and any missing parents) under the sandbox root.\",\n move_file: \"Rename or move a file or directory under the sandbox root.\",\n delete_file:\n \"Delete one file under the sandbox root. Refuses directories — use delete_directory for those.\",\n delete_directory:\n \"Recursively delete a directory under the sandbox root. Pass recursive:false to refuse non-empty directories.\",\n copy_file:\n \"Copy a file or directory under the sandbox root. Refuses to overwrite an existing destination.\",\n submit_plan:\n \"Submit one concrete plan for a review gate. Use for multi-file refactors, architecture changes, or anything expensive to undo.\",\n mark_step_complete:\n \"Mark one step of the approved plan as done. Call exactly once after finishing each step.\",\n revise_plan:\n \"Surgically replace the remaining steps of an in-flight plan. Done steps are never touched.\",\n run_skill:\n \"Invoke a playbook from the Skills index. Pass the bare skill name. Subagent-tagged skills spawn an isolated subagent.\",\n spawn_subagent:\n \"Spawn an isolated subagent for a self-contained subtask. Use for parallel fan-out or when the work needs many file reads.\",\n todo_write:\n \"In-session task tracker for multi-step work. Replaces the entire list every call. No approval gate or file writes.\",\n ask_choice:\n \"Present 2-6 alternatives to the user. Use when the user asks for options or you need a preference decision.\",\n create_skill:\n \"Scaffold a new skill the user can invoke later via /skill. Supports inline and subagent run modes.\",\n add_mcp_server:\n \"Register a new MCP server in the user's config. Takes effect on the next session. Supports stdio, SSE, and streamable-http.\",\n },\n },\n permissions: {\n loading: \"loading permissions…\",\n failed: \"permissions failed: {error}\",\n yoloTitle: \"YOLO mode\",\n yoloDesc:\n \"Every shell command auto-runs, allowlist bypassed. Switch back with /mode review in the TUI.\",\n project: \"project\",\n builtin: \"builtin\",\n addPrefix: \"add a prefix\",\n addPlaceholder: 'e.g. \"npm run build\" or \"deploy.sh\"',\n clearAll: \"Clear all\",\n alreadyIn: \"{prefix} already in list\",\n added: \"added: {prefix}\",\n removed: \"removed: {prefix}\",\n cleared: \"cleared {count} entr{y}\",\n removeConfirm: 'Remove \"{prefix}\" from this project\\'s allowlist?',\n clearConfirm: \"Wipe every project allowlist entry? Builtin entries are unaffected.\",\n projectAllowlist: \"Project allowlist · {count}\",\n nothingStored: \"Nothing stored yet for this project.\",\n colNum: \"#\",\n colPrefix: \"prefix\",\n builtinTitle: \"Builtin · {count} · read-only\",\n standaloneWarning:\n \"Mutations require /dashboard from inside an active reasonix code session — standalone reasonix dashboard can't tell which project's allowlist to edit.\",\n },\n mcp: {\n loading: \"loading MCP…\",\n servers: \"MCP servers · {count} bridged\",\n all: \"all\",\n live: \"live\",\n unbridged: \"unbridged\",\n specPlaceholder: \"spec — e.g. fs=npx -y @modelcontextprotocol/...\",\n saved: \"saved\",\n savedRestart: \"saved — restart reasonix code to bridge this server\",\n removed: \"removed — restart to drop the live bridge\",\n removeConfirm: \"Remove MCP spec from config?\\n\\n{spec}\",\n noServers: \"No MCP servers in this session.\",\n tools: \"tools\",\n inConfig: \"in config · not loaded\",\n unbridgedTitle: \"unbridged · in config\",\n removeBtn: \"Remove\",\n spec: \"spec\",\n whyUnbridged: \"Why unbridged?\",\n whyUnbridgedDesc:\n \"This spec lives in your config.json but isn't bridged into the live session. MCP servers attach when reasonix code starts; the dashboard alone can't spawn the child process.\",\n whyUnbridgedHint: \"To activate: restart reasonix code, then refresh this dashboard.\",\n bridgeFailed: \"Bridge failed\",\n bridgeFailedTitle: \"bridge failed · in config\",\n bridgeFailedHint:\n \"Reasonix tried to bridge this server and the attempt errored. Common causes: wrong URL, missing auth header, upstream 404/5xx, missing local command. Fix and restart reasonix code to retry.\",\n pickHint: \"Pick an MCP server on the left to inspect tools / resources / prompts.\",\n toolsTitle: \"Tools · {count}\",\n resourcesTitle: \"Resources · {count}\",\n promptsTitle: \"Prompts · {count}\",\n colName: \"name\",\n colDesc: \"description\",\n colUri: \"uri\",\n marketplace: \"marketplace\",\n marketplaceSearch: \"search the registry…\",\n marketplaceLoading: \"loading registry…\",\n marketplaceMore: \"load 5 more pages\",\n marketplaceMoreLabel: \"load 50 more · showing {shown} / {total}\",\n marketplaceMoreHint: \"fetches more pages from the registry\",\n marketplaceMoreCachedHint: \"more entries already cached locally\",\n marketplaceExhausted: \"all pages loaded\",\n marketplaceExhaustedFull: \"showing all {total} entries — registry exhausted\",\n marketplaceCount: \"{loaded} loaded · {matched} match · source: {source}{cached}\",\n marketplaceCachedSuffix: \" · cached\",\n marketplaceNoMatches: \"No matches. Try different terms or load more pages.\",\n marketplaceInstall: \"Install\",\n marketplacePickHint: \"Pick a server on the left, then Install.\",\n marketplaceInstalled: \"installed → {spec}\",\n marketplaceInstalledBridged: \"installed + bridged → {spec}\",\n marketplaceAlready: \"already installed\",\n marketplaceNeedsEnv: \"needs env: {names}\",\n marketplaceSourceTag: \"[{source}]\",\n marketplaceNoInstall:\n \"smithery listing — install metadata not exposed; use `npx -y @smithery/cli install {name}` directly\",\n marketplaceFetchOnInstall:\n \"Smithery listing — install detail fetched on Install. http servers map to streamable-http remotes; stdio servers run via @smithery/cli.\",\n marketplaceInstalledBadge: \"installed\",\n marketplaceUninstall: \"Uninstall\",\n marketplaceEnvTitle: \"Required environment variables\",\n marketplaceEnvHint:\n \"Set these in your shell before next `reasonix code` so the bridged server can authenticate.\",\n marketplaceRestartHint:\n \"Spec written to ~/.reasonix/config.json. Restart `reasonix code` to bridge the server (live hot-reload is on the roadmap).\",\n },\n memory: {\n loading: \"loading memory…\",\n files: \"memory · {count} files\",\n exists: \"exists\",\n create: \"create\",\n noFiles: \"No memory files yet.\",\n pickHint: \"Pick a memory file on the left.\",\n pickDesc: \"Project REASONIX.md is committable; global notes live in ~/.reasonix/memory/.\",\n chars: \"{count} chars\",\n saved: \"saved {scope}\",\n reloadHint: \"re-applied on next /new or session restart\",\n },\n hooks: {\n loading: \"loading hooks…\",\n resolved: \"resolved\",\n eventMatrix: \"Event matrix\",\n matrixSub: \"{scripts} script{s} × {events} event{s}\",\n noHooks: \"No hooks configured. Edit the JSON below to add some.\",\n colScript: \"script\",\n noProject: \"No active project — open /dashboard from reasonix code to edit project hooks.\",\n saveReload: \"Save + Reload\",\n discard: \"Discard changes\",\n savedReloaded: \"saved + reloaded {scope}\",\n recentRuns: \"Recent runs\",\n noRuns: \"No hook runs in the recent session log.\",\n colWhen: \"when\",\n colPhase: \"phase\",\n colHook: \"hook\",\n colOutcome: \"outcome\",\n },\n skills: {\n loading: \"loading skills…\",\n filterPlaceholder: \"filter skills\",\n project: \"project\",\n custom: \"custom\",\n global: \"global\",\n builtin: \"builtin\",\n newSkill: \"new skill\",\n noDescription: \"(no description)\",\n runs7d: \"runs · 7d\",\n pickHint: \"Pick a skill on the left, or create a new one above.\",\n readOnlyBuiltin: \"read-only · builtin\",\n readOnlyCustom: \"read-only · custom path\",\n builtinDesc:\n \"Built-in skills ship with Reasonix; the model picks them up automatically. To customize, create a project- or global-scoped skill with the same name.\",\n saved: \"saved {scope}/{name}\",\n deleteConfirm: \"Delete skill {scope}/{name}?\",\n reloadHint: \"re-loaded on next /new or session restart\",\n },\n system: {\n loading: \"loading health…\",\n failed: \"health failed: {error}\",\n healthChecks: \"Health checks\",\n version: \"version\",\n checking: \"checking\",\n latest: \"● latest\",\n outOfDate: \"● out of date\",\n versionPending: \"version check pending\",\n upToDate: \"up to date\",\n latestVer: \"latest: {version}\",\n sessions: \"sessions\",\n ok: \"● ok\",\n memory: \"memory\",\n semanticIndex: \"semantic index\",\n built: \"● built\",\n none: \"— none\",\n runIndex: \"run reasonix index to build\",\n usageLog: \"usage log\",\n backgroundJobs: \"background jobs\",\n noSession: \"— no session\",\n running: \"{count} running\",\n attachHint: \"attach a session to see jobs\",\n shellSpawn: \"shell + spawn\",\n paths: \"paths\",\n home: \"home\",\n sessionsPath: \"sessions\",\n memoryPath: \"memory\",\n semanticPath: \"semantic\",\n usagePath: \"usage\",\n },\n plans: {\n loading: \"loading plans…\",\n failed: \"plans failed: {error}\",\n noPlans: \"No archived plans yet — run a turn that calls submit_plan and mark_step_complete.\",\n filterPlaceholder: \"filter plans\",\n active: \"active\",\n done: \"done\",\n idle: \"idle\",\n steps: \"steps\",\n pickHint: \"Pick a plan on the left.\",\n noTitle: \"(no title)\",\n stepTimeline: \"Step timeline · {done} / {total}\",\n step: \"step {n}\",\n },\n semantic: {\n codeRequired: \"Semantic — code-mode required\",\n indexBuilt: \"index built\",\n noIndex: \"no index yet\",\n ready: \"ready\",\n setupNeeded: \"setup needed\",\n installOllama: \"Install Ollama\",\n installOllamaDesc:\n \"Reasonix doesn't run package managers for you. Install Ollama first, then come back:\",\n macWindows: \"macOS / Windows:\",\n download: \"download from ollama.com/download\",\n linux: \"Linux:\",\n refreshHint:\n \"Refresh after install — this panel will offer to start the daemon and pull {model}.\",\n daemon: \"Daemon\",\n daemonDesc: \"ollama is on your PATH but the HTTP daemon isn't reachable.\",\n startDaemon: \"Start daemon\",\n runsOllama: \"runs ollama serve detached\",\n model: \"Model\",\n modelMissing: \"{model} isn't installed yet.\",\n modelSize: \"~270 MB on first pull.\",\n pulling: \"pulling…\",\n pullModel: \"Pull {model}\",\n indexStatus: \"index status\",\n builtStatus: \"● built\",\n incompatibleStatus: \"● incompatible\",\n chunks: \"chunks\",\n files: \"files\",\n dim: \"dim\",\n size: \"size\",\n lastBuild: \"last build\",\n builtWith: \"built with\",\n currentTarget: \"current target\",\n incompatibleHint:\n \"This on-disk index was built for a different provider or model. Run Rebuild to replace it.\",\n runIndexHint: \"Run an index to enable semantic_search.\",\n reIndex: \"Re-index\",\n build: \"Build\",\n rebuild: \"Rebuild\",\n stop: \"Stop\",\n provider: \"provider\",\n providerType: \"service type\",\n openaiCompat: \"openai-compatible\",\n apiUrl: \"API URL\",\n apiKey: \"API key\",\n apiKeyStoredNote: \"API key is stored in ~/.reasonix/config.json — do not share that file.\",\n customRequestBody: \"custom request body\",\n invalidCustomRequestBody: \"Custom request body must be valid JSON: {error}\",\n customRequestBodyMustBeObject: \"Custom request body must be a JSON object.\",\n saveBeforeIndex: \"Save semantic settings before starting an index.\",\n extraBody: \"extra body\",\n batchSize: \"batch size\",\n keepExistingKey: \"leave blank to keep existing key\",\n remoteProvider: \"Remote embedding provider\",\n remoteProviderDesc:\n \"Configure the full OpenAI-compatible embeddings URL here. Reasonix will send requests exactly to the URL you provide.\",\n ollama: \"ollama\",\n binary: \"binary\",\n found: \"found\",\n missing: \"missing\",\n daemonStatus: \"daemon\",\n up: \"up\",\n down: \"down\",\n pulled: \"pulled\",\n indexConfig: \"index config\",\n reset: \"reset\",\n excludeDirs: \"exclude dirs\",\n excludeFiles: \"exclude files\",\n excludeExts: \"exclude exts\",\n excludePatterns: \"exclude patterns\",\n glob: \"glob\",\n respectGitignore: \"respect .gitignore\",\n maxFileBytes: \"max file bytes\",\n skipLarger: \"skip files larger than ~{size} MiB\",\n preview: \"Preview\",\n searchPlaceholder: \"describe what to find — 'where do we handle abort signals'\",\n searching: \"searching…\",\n results: \"{count} result{s} · {ms}ms · {model}\",\n noMatches: \"No matches above the score threshold.\",\n previewSummary: \"Preview — would index {included} file(s), skip {skipped}\",\n nothingSkipped: \"nothing skipped — all walked files would be indexed.\",\n firstIncluded: \"first {count} included file(s)\",\n job: \"Job\",\n phaseSetup: \"preparing\",\n phaseScan: \"scanning files\",\n phaseEmbed: \"embedding chunks\",\n phaseWrite: \"writing index\",\n phaseDone: \"done\",\n phaseError: \"error\",\n phaseCancelled: \"cancelled\",\n setupFailed: \"setup failed\",\n stopping: \"stopping\",\n scanned: \"scanned {count}\",\n changed: \"changed {count}\",\n skipped: \"skipped {count}\",\n chunksProgress: \"{done} / {total} ({pct}%)\",\n result: \"result\",\n added: \"added {count}\",\n removed: \"removed {count}\",\n failed: \"failed {count}\",\n skippedFiles: \"{total} files ({details})\",\n rebuildStarted: \"rebuild started\",\n incrementalStarted: \"incremental index started\",\n stopRequested: \"stopping requested — current chunk batch will finish first\",\n startingDaemon: \"starting ollama daemon (15s timeout)…\",\n daemonUp: \"daemon is up\",\n daemonTimeout: \"daemon didn't come up in time — check ollama serve manually\",\n pullingModel: \"pulling {model} — this may take a few minutes on first install\",\n savedConfig: \"saved · {count} fields updated · re-run index to apply\",\n runningPreview: \"running dry walk against project root…\",\n exclude: \"exclude\",\n },\n modal: {\n shellTitle: \"shell command\",\n shellBgTitle: \"background process\",\n shellSubtitle: \"model wants to run a shell command\",\n shellBgSubtitle: \"long-running — keeps running after approval\",\n pathTitle: \"file outside sandbox\",\n pathSubtitle: \"{intent} via {tool}\",\n pathRead: \"read\",\n pathWrite: \"write\",\n pathSandboxLabel: \"sandbox\",\n pathAllowPrefixLabel: \"allow prefix\",\n runOnce: \"Run once\",\n alwaysAllow: 'Always allow \"{prefix}\"',\n deny: \"Deny\",\n choiceTitle: \"model wants you to pick\",\n typeOwn: \"Type my own answer\",\n typeOwnSummary: \"None of the above fits — write a free-form reply.\",\n typePlaceholder: \"Type a free-form answer…\",\n send: \"Send\",\n cancel: \"Cancel\",\n cancelSummary: \"Drop the question. Model will ask what you actually want.\",\n planTitle: \"plan submitted\",\n planSubtitle: \"model proposed a plan; review then pick\",\n approveInstructions:\n \"Optional last instructions / answers to open questions (Enter to send blank)\",\n refinePlaceholder: \"What needs to change? Be specific.\",\n approve: \"Approve\",\n refine: \"Refine\",\n sendRefinement: \"Send refinement\",\n editTitle: \"edit pending review\",\n editSubtitle: \"{path} · {remaining} of {total} blocks remaining\",\n before: \"before\",\n after: \"after\",\n workspaceTitle: \"model wants to switch workspace\",\n workspaceSubtitle: \"every subsequent file / shell / memory tool resolves against the new root\",\n switchBtn: \"Switch (Enter)\",\n denyBtn: \"Deny (Esc)\",\n stepComplete: \"step complete{counter}\",\n continueBtn: \"Continue\",\n reviseBtn: \"Revise…\",\n stopBtn: \"Stop\",\n revisionTitle: \"model proposed a plan revision\",\n sendRevision: \"Send revision\",\n accept: \"Accept\",\n reject: \"Reject\",\n arguments: \"arguments\",\n revisePlaceholder: \"What needs to change before the next step? Leave blank to just continue.\",\n pickerFilter: \"Filter…\",\n pickerEmpty: \"Nothing to show.\",\n pickerLoadMore: \"Load more\",\n pickerPick: \"Open\",\n pickerInstall: \"Install\",\n pickerUninstall: \"Uninstall\",\n pickerRename: \"Rename…\",\n pickerNew: \"New…\",\n pickerNewPlaceholder: \"Name (leave blank for default)\",\n viewerClose: \"Close\",\n },\n error: {\n title: \"Something broke in the dashboard\",\n body: \"The TUI is unaffected — only this browser tab tripped. You can dismiss and keep working, or report it so we can fix the underlying cause.\",\n copyDetails: \"Copy details\",\n copied: \"Copied ✓\",\n reportOnGithub: \"Report on GitHub\",\n dismiss: \"Dismiss (Esc)\",\n crashing: \"this panel keeps crashing — {name}\",\n retry: \"Try again\",\n recovering: \"recovering…\",\n },\n fmt: {\n justNow: \"just now\",\n minutesAgo: \"{n}m ago\",\n hoursAgo: \"{n}h ago\",\n daysAgo: \"{n}d ago\",\n },\n cards: {\n applied: \"Applied\",\n cacheHit: \"Cache hit\",\n checkpointRewind: \"Checkpoint Rewind\",\n cost: \"Cost\",\n diffApply: \"Apply\",\n diffApplyChanges: \"Apply Changes\",\n diffAwaiting: \"Awaiting review\",\n diffDiscard: \"Discard\",\n done: \"Done\",\n elapsed: \"Elapsed\",\n error: \"Error\",\n errorName: \"Error\",\n failed: \"Failed\",\n hits: \"Hits\",\n memoryCountSuffix: \"memories\",\n memoryName: \"Memory\",\n output: \"Output\",\n planDefaultTitle: \"Plan\",\n prompt: \"Prompt\",\n compactionMeta: \"{chars} chars\",\n compactionName: \"Compacted history\",\n reasoningComplete: \"Reasoning complete\",\n reasoningName: \"Reasoning\",\n result: \"Result\",\n running: \"Running\",\n searchName: \"Search\",\n shellAlwaysAllow: \"Always Allow\",\n shellAwaiting: \"Awaiting approval\",\n shellExecuteHint: \"Execute this command?\",\n shellReject: \"Reject\",\n shellRun: \"Run\",\n shellRunning: \"Running\",\n streaming: \"Streaming\",\n subagentDone: \"Subagent done\",\n subagentDoneProgress: \"Subagent done ({pct}%)\",\n subagentFailed: \"Subagent failed\",\n subagentRunning: \"Subagent running\",\n },\n planBadge: {\n blocked: \"Blocked\",\n done: \"Done\",\n failed: \"Failed\",\n pending: \"Pending\",\n running: \"Running\",\n },\n composer: {\n atHeader: \"Mention files\",\n close: \"Close\",\n commandPalette: \"Command Palette\",\n commands: \"Commands\",\n commandsLabel: \"Commands\",\n confirm: \"Confirm\",\n imageFilterName: \"Images\",\n insertFile: \"Insert File\",\n insertImage: \"Insert Image\",\n interrupt: \"Interrupt\",\n mentionFiles: \"Mention Files\",\n mentionLabel: \"Mention\",\n newline: \"New Line\",\n noMatches: \"No matches\",\n placeholder: \"Type a prompt…\",\n queue: \"Queue\",\n queueCount: \"{count} queued\",\n select: \"Select\",\n send: \"Send\",\n slashHeader: \"Slash Commands\",\n switchModel: \"Switch Model\",\n switchEffort: \"Switch Reasoning Effort\",\n workspaceRoot: \"Workspace Root\",\n },\n contextPanel: {\n allow: \"Allow\",\n ask: \"Ask\",\n autoApproveTitle: \"Auto-approve\",\n cacheKey: \"Cache\",\n contextTokens: \"Context tokens\",\n fileInContext: \"In context\",\n fileModified: \"Modified\",\n filesCount: \"{count} files\",\n filesTab: \"Files\",\n filesTitle: \"Files\",\n freeKey: \"Free\",\n itemCount: \"{count} items\",\n mcpConfigured: \"Configured\",\n mcpConnecting: \"Connecting…\",\n mcpDisabled: \"Disabled\",\n mcpEmpty: \"No MCP servers\",\n mcpFailed: \"Failed\",\n mcpReady: \"Ready\",\n mcpReadyAll: \"All ready\",\n mcpReadySome: \"Some ready\",\n mcpTitle: \"MCP\",\n mcpTools: \"Tools\",\n memoryTab: \"Memory\",\n memoryTitle: \"Memory\",\n noFilesMsg: \"No files in context\",\n noMemoriesMsg: \"No memories\",\n reservedKey: \"Reserved\",\n ruleReadOnly: \"Read-only\",\n ruleReview: \"Review\",\n ruleShellAllowlist: \"Shell allowlist\",\n rulesTab: \"Rules\",\n ruleWritesAsk: \"Writes ask\",\n ruleYolo: \"YOLO\",\n scopeGlobal: \"Global\",\n scopeProject: \"Project\",\n toolsTab: \"Tools\",\n usedKey: \"Used\",\n },\n dragDrop: {\n overlay: \"Drop files here\",\n },\n extraCards: {\n approve: \"Approve\",\n balance: \"Balance\",\n cache: \"Cache\",\n cacheHit: \"Cache hit\",\n contextWindow: \"Context window\",\n doctorTitle: \"Diagnostics\",\n output: \"Output\",\n prompt: \"Prompt\",\n reasoning: \"Reasoning\",\n reject: \"Reject\",\n sessionCost: \"Session cost\",\n sessionUsage: \"Session usage\",\n topToolsUsage: \"Top tools\",\n unknownKind: \"Unknown\",\n memoryUser: \"User\",\n memoryFeedback: \"Feedback\",\n memoryProject: \"Project\",\n memoryReference: \"Reference\",\n },\n jobs: {\n empty: \"No background jobs\",\n exited: \"Exited\",\n kbClose: \"Close\",\n kbToggle: \"Toggle\",\n running: \"Running\",\n stop: \"Stop\",\n stopAll: \"Stop All\",\n stopAllTip: \"Stop all jobs\",\n stopOne: \"Stop\",\n title: \"Background Jobs\",\n },\n live: {\n deliveredWaiting: \"Waiting for next message\",\n reasoning: \"Reasoning\",\n running: \"Running\",\n secondsAgo: \"{n}s ago\",\n you: \"You\",\n },\n markdown: {\n copied: \"Copied!\",\n copy: \"Copy\",\n externalLinkTitle: \"Open in new tab\",\n filePillTitle: \"Open file\",\n localLinkTitle: \"Open link\",\n },\n palette: {\n abort: \"Abort\",\n abortHint: \"Abort current request\",\n about: \"About\",\n clearChat: \"Clear Chat\",\n clearChatHint: \"Clear conversation\",\n closeTab: \"Close Tab\",\n closeTabHint: \"Close current tab\",\n copyConv: \"Copy Conversation\",\n copyConvHint: \"Copy conversation as Markdown\",\n copyLast: \"Copy Last Response\",\n copyLastHint: \"Copy last assistant message\",\n countSuffix: \"items\",\n empty: \"No matching commands\",\n exportMd: \"Export as Markdown\",\n exportMdHint: \"Export chat as Markdown file\",\n focusComposer: \"Focus Composer\",\n footClose: \"Close\",\n footMove: \"Move\",\n footRun: \"Run\",\n groupAction: \"Actions\",\n groupNav: \"Navigation\",\n groupSettings: \"Settings\",\n groupWorkspace: \"Workspace\",\n newChat: \"New Chat\",\n newChatHint: \"Start a new conversation\",\n newTab: \"New Tab\",\n newTabHint: \"Open a new tab\",\n pickWorkspace: \"Switch Workspace\",\n pickWorkspaceHint: \"Change workspace\",\n searchPlaceholder: \"Search commands…\",\n settings: \"Settings\",\n settingsHint: \"Open settings\",\n },\n panel: {\n renderError: \"Panel crashed\",\n },\n sidebarPanel: {\n approvalRules: \"Approval Rules\",\n cancel: \"Cancel\",\n commandPalette: \"Command Palette\",\n daysAgo: \"{n}d ago\",\n delete: \"Delete\",\n deleteSession: \"Delete Session\",\n hoursAgo: \"{n}h ago\",\n justNow: \"Just now\",\n loading: \"Loading…\",\n messageCount: \"{count} messages\",\n minutesAgo: \"{n}m ago\",\n newChat: \"New Chat\",\n noMatches: \"No matches\",\n noSessions: \"No sessions\",\n recent: \"Recent\",\n searchSessions: \"Search sessions…\",\n sessionTitle: \"Sessions\",\n settings: \"Settings\",\n weeksAgo: \"{n}w ago\",\n },\n statusbar: {\n balance: \"Balance\",\n busy: \"Busy\",\n cache: \"Cache\",\n cacheHit: \"Cache hit\",\n jobs: \"Jobs\",\n jobsTip: \"Background jobs\",\n offline: \"Offline\",\n online: \"Online\",\n switchCurrency: \"Switch currency\",\n switchTheme: \"Switch theme\",\n switchWorkspace: \"Switch workspace\",\n themeDark: \"Dark\",\n themeLight: \"Light\",\n themeStyleGraphite: \"Graphite\",\n themeStyleSandstone: \"Sandstone\",\n themeStylePorcelain: \"Porcelain\",\n themeStyleMidnight: \"Midnight\",\n thisTurn: \"This turn\",\n tokens: \"Tokens\",\n },\n thread: {\n activePlan: \"Active plan\",\n allowRead: \"Allow read\",\n allowWrite: \"Allow write\",\n alwaysAllow: \"Always allow\",\n alwaysAllowPrefix: \"Always allow {prefix}\",\n approve: \"Approve\",\n approveRewrite: \"Approve rewrite\",\n cancel: \"Cancel\",\n checkpointKind: \"Checkpoint\",\n checkpointSub: \"Save current state\",\n checkpointTitle: \"Create checkpoint\",\n collapse: \"Collapse\",\n continue: \"Continue\",\n copyMessage: \"Copy message\",\n copyResponse: \"Copy response\",\n execute: \"Execute\",\n keepOriginal: \"Keep original\",\n keepSteps: \"Keep steps\",\n optionCount: \"{count} options\",\n pathAccessKind: \"Path access\",\n planConfirmationKind: \"Plan approval\",\n planRevisionKind: \"Plan revision\",\n planRunning: \"Plan in progress\",\n planStepCount: \"Step {done}/{total}\",\n readPathOutsideSandbox: \"Read path outside sandbox\",\n refine: \"Refine\",\n reject: \"Reject\",\n revise: \"Revise\",\n revisionMeta: \"Revision\",\n rewritePlan: \"Rewrite plan\",\n risk: \"Risk assessment\",\n riskMedium: \"Medium risk\",\n runBackgroundCommand: \"Run in background\",\n runCommand: \"Run command\",\n shellConfirmationKind: \"Shell confirmation\",\n startPlan: \"Start plan\",\n stop: \"Stop\",\n subagent: \"Subagent\",\n userChoiceKind: \"User choice\",\n writePathOutsideSandbox: \"Write path outside sandbox\",\n you: \"You\",\n },\n workdir: {\n browse: \"Browse…\",\n cancel: \"Cancel\",\n empty: \"No workspaces\",\n emptyDir: \"No subdirectories.\",\n go: \"Go\",\n goTip: \"Navigate to this path\",\n loading: \"Loading…\",\n openHere: \"Open this folder\",\n pathPlaceholder: \"Absolute path…\",\n promptWeb: \"Enter the absolute path of the workspace to open:\",\n searchPlaceholder: \"Search workspaces…\",\n title: \"Workspace\",\n },\n about: {\n close: \"Close\",\n repo: \"Repository\",\n sidebarLabel: \"About\",\n tagline: \"AI-powered coding assistant\",\n version: \"Version\",\n },\n effort: {\n lowDesc: \"fastest — minimal reasoning\",\n mediumDesc: \"balanced\",\n highDesc: \"default — safe for vLLM / Azure\",\n maxDesc: \"DeepSeek extension; rejected by stock OpenAI / vLLM\",\n },\n editMode: {\n plan: \"Plan\",\n planHint: \"read-only · all write tools refuse to dispatch\",\n review: \"Review\",\n reviewHint: \"both edits and non-allowlisted shell ask first\",\n auto: \"Auto\",\n autoHint: \"edits auto-apply, shell still asks\",\n yolo: \"YOLO\",\n yoloHint: \"edits AND shell auto-run, allowlist bypassed\",\n },\n};\n","import { en } from \"./en\";\n\nexport const de: typeof en = {\n ...en,\n app: {\n ...en.app,\n sectionWorkspace: \"Arbeitsbereich\",\n sectionObserve: \"Beobachten\",\n sectionConfigure: \"Konfigurieren\",\n tabChat: \"Chat\",\n tabPlans: \"Pläne\",\n tabSessions: \"Sitzungen\",\n tabOverview: \"Übersicht\",\n tabUsage: \"Nutzung\",\n tabSystem: \"System\",\n tabSemantic: \"Semantisch\",\n tabTools: \"Werkzeuge\",\n tabPermissions: \"Berechtigungen\",\n tabMcp: \"MCP\",\n tabSkills: \"Fertigkeiten\",\n tabMemory: \"Memory\",\n tabHooks: \"Hooks\",\n tabSettings: \"Einstellungen\",\n sectionChanges: \"Änderungen\",\n tabChanges: \"Änderungen\",\n footer: \"127.0.0.1 nur · token-gesichert\",\n themeToggle: \"Theme umschalten\",\n themeLight: \"Hell\",\n themeDark: \"Dunkel\",\n skill: {\n ...en.app.skill,\n scope: {\n ...en.app.skill.scope,\n builtin: \"Eingebaut\",\n global: \"Global\",\n project: \"Projekt\",\n },\n runAs: {\n subagent: \"Subagent\",\n inline: \"Inline\",\n },\n generic: \"Fertigkeit\",\n },\n exportReasoningSummary: \"Reasoning-Zusammenfassung\",\n exportToolLabel: \"Tool-Aufrufe\",\n exportUserLabel: \"Benutzernachrichten\",\n empty: {\n ...en.app.empty,\n currentWorkspace: \"Aktueller Arbeitsbereich\",\n selectWorkspace: \"Wähle einen Arbeitsbereich zum Starten\",\n suggestion0: \"Meine letzten Commit-Änderungen überprüfen\",\n suggestion1: \"Alle TypeScript-Fehler in der aktuellen Datei beheben\",\n suggestion2: \"README ins Chinesische/Englische übersetzen\",\n suggestion3: \"CHANGELOG für dieses Repo generieren\",\n welcome: \"Willkommen bei Reasonix\",\n },\n errorLabel: \"Fehler\",\n connecting: \"Verbinde…\",\n session: {\n ...en.app.session,\n format: \"Sitzung\",\n new: \"Neue Sitzung\",\n },\n setup: {\n ...en.app.setup,\n choose: \"Arbeitsbereich wählen\",\n description: \"Wähle einen Arbeitsbereich zum Starten\",\n notSelected: \"Kein Arbeitsbereich ausgewählt\",\n saveAndStart: \"Speichern & Starten\",\n welcome: \"Willkommen\",\n workspace: \"Arbeitsbereich\",\n },\n tab: {\n ...en.app.tab,\n newTab: \"+ Neuer Tab\",\n newTabTitle: \"Neuen Tab öffnen\",\n },\n titlebar: {\n ...en.app.titlebar,\n clearChat: \"Chat leeren\",\n close: \"Schließen\",\n commandPalette: \"Befehlsübersicht\",\n contextPanel: \"Kontext-Panel\",\n copyMd: \"Als Markdown kopieren\",\n exportMd: \"Als Markdown exportieren\",\n maximize: \"Maximieren\",\n minimize: \"Minimieren\",\n more: \"Mehr\",\n restore: \"Wiederherstellen\",\n settings: \"Einstellungen\",\n sidebar: \"Seitenleiste\",\n windowControls: \"Fenstersteuerung\",\n },\n toast: {\n ...en.app.toast,\n cleared: \"Chat geleert\",\n copied: \"In die Zwischenablage kopiert\",\n copiedMd: \"Als Markdown kopiert\",\n emptySession: \"Keine Nachrichten zum Exportieren\",\n exportDialogTitle: \"Chat exportieren\",\n exportedMd: \"Als Markdown exportiert\",\n exportFailed: \"Export fehlgeschlagen\",\n langSwitched: \"Sprache gewechselt\",\n modelSwitched: \"Modell → {model}\",\n effortSwitched: \"Effort → {effort}\",\n modeSwitched: \"Modus gewechselt\",\n newSession: \"Neue Sitzung erstellt\",\n },\n yolo: {\n ...en.app.yolo,\n toast: \"YOLO-Modus aktiviert\",\n },\n cmd: {\n ...en.app.cmd,\n abort: \"Abbrechen\",\n btw: \"BTW\",\n clearChat: \"Chat leeren\",\n compact: \"Komprimieren\",\n copyLast: \"Letzte kopieren\",\n exportMd: \"Als Markdown exportieren\",\n feedback: \"Feedback\",\n help: \"Hilfe\",\n newSession: \"Neue Sitzung\",\n retry: \"Erneut versuchen\",\n switchModel: \"Modell wechseln\",\n toggleCurrency: \"Währung wechseln\",\n toggleLang: \"Sprache wechseln\",\n toggleTheme: \"Theme wechseln\",\n },\n header: {\n ...en.app.header,\n abort: \"Abbrechen\",\n clickToSelect: \"Klicken zum Auswählen\",\n copy: \"Kopieren\",\n copyMd: \"Als Markdown kopieren\",\n export: \"Exportieren\",\n exportMd: \"Als Markdown exportieren\",\n newChat: \"Neuer Chat\",\n noWorkspace: \"Kein Arbeitsbereich\",\n running: \"Läuft…\",\n },\n jumpToBottom: \"Nach unten springen\",\n langEN: \"Englisch\",\n langZH: \"中文\",\n splashSubtitle: \"KI-gestützter Coding-Assistent\",\n },\n changes: {\n ...en.changes,\n chatPlaceholder: \"Frag etwas zu deinem Code...\",\n chatWelcome: \"Änderungen — stelle Fragen zu deinen Projektdateien.\",\n chatSend: \"Senden\",\n viewerPlaceholder: \"Wähle eine Datei zum Anzeigen\",\n treeEmpty: \"(leer)\",\n tabClose: \"Tab schließen\",\n newConversation: \"Neu\",\n clearConversation: \"Leeren\",\n newTitle: \"/new — Gesprächskontext löschen\",\n clearTitle: \"/clear — sichtbaren Scrollback leeren\",\n newConfirmBusy: \"Ein Turn läuft gerade. Abbrechen und neues Gespräch beginnen?\",\n newConfirm: \"Aktuelles Gespräch leeren und neu beginnen?\",\n newToast: \"neues Gespräch\",\n clearToast: \"Scrollback geleert\",\n newFailed: \"/new fehlgeschlagen: {error}\",\n clearFailed: \"/clear fehlgeschlagen: {error}\",\n chatSendBtn: \"Senden\",\n fileTreeTitle: \"Dateien\",\n codeViewerTitle: \"Code-Ansicht\",\n chatPanelTitle: \"Chat\",\n loadingFiles: \"Lade Projektdateien…\",\n review: \"Überprüfen\",\n allFiles: \"Alle Dateien\",\n changes: \"Änderungen\",\n commentLabel: \"Kommentar zu Zeile\",\n commentPlaceholder: \"Kommentar hinzufügen…\",\n commentCancel: \"Abbrechen\",\n commentSubmit: \"Kommentieren\",\n commentLine: \"Zeile\",\n commentEdit: \"Bearbeiten\",\n commentDelete: \"Löschen\",\n diffSourceGit: \"Git-Änderungen\",\n diffSourceSession: \"Vorherige Sitzung\",\n diffSourceCheckpoint: \"Checkpoint\",\n checkpointEmpty: \"Noch keine Checkpoints in diesem Arbeitsbereich.\",\n restoreBtn: \"Wiederherstellen\",\n restoreConfirm: '\"{name}\" wiederherstellen? Dies überschreibt aktuelle Dateien.',\n deleteBtn: \"Löschen\",\n deleteConfirm: 'Checkpoint \"{name}\" löschen? Der Schnappschuss wird entfernt, Dateien bleiben unverändert.',\n createBtn: \"Schnappschuss\",\n createPlaceholder: \"Name für Schnappschuss…\",\n backToList: \"zurück zur Liste\",\n reviewEmpty: \"Keine ausstehenden Überprüfungen.\",\n diffStyleUnified: \"Unifiziert\",\n diffStyleSplit: \"Geteilt\",\n expandAll: \"Alle erweitern\",\n collapseAll: \"Alle einklappen\",\n createFailed: \"Erstellen fehlgeschlagen\",\n restoreFailed: \"Wiederherstellen fehlgeschlagen\",\n deleteFailed: \"Löschen fehlgeschlagen\",\n },\n common: {\n ...en.common,\n loading: \"lade...\",\n loadingFailed: \"{name} fehlgeschlagen: {error}\",\n back: \"← zurück\",\n save: \"Speichern\",\n remove: \"entfernen\",\n cancel: \"Abbrechen\",\n delete: \"Löschen\",\n add: \"Hinzufügen\",\n confirm: \"Bestätigen\",\n noData: \"Noch keine {name}.\",\n all: \"alle\",\n yes: \"ja\",\n no: \"nein\",\n on: \"AN\",\n off: \"aus\",\n enabled: \"aktiviert\",\n disabled: \"deaktiviert\",\n },\n settings: {\n ...en.settings,\n title: \"Einstellungen\",\n loading: \"Einstellungen werden geladen...\",\n saved: \"gespeichert: {fields}\",\n sectionApi: \"DeepSeek API\",\n apiKey: \"API-Schlüssel\",\n apiKeyNotSet: \"Nicht gesetzt\",\n apiKeySave: \"Schlüssel speichern\",\n apiKeySet: \"Gesetzt\",\n apiSection: \"API-Konfiguration\",\n notSet: \"(nicht gesetzt)\",\n replace: \"ersetzen\",\n pasteKey: \"füge ein neues sk-…-Token ein\",\n saveKey: \"Schlüssel speichern\",\n baseUrl: \"Basis-URL\",\n baseUrlPlaceholder: \"https://api.deepseek.com (Standard)\",\n baseUrlHint: \"Basis-URL für API-Anfragen\",\n sectionDefaults: \"Standardwerte\",\n effortSection: \"Reasoning-Effort\",\n modelCustom: \"Benutzerdefinierte Modell-ID\",\n modelCustomHint: \"Jede OpenAI-kompatible ID, die dein Endpunkt bereitstellt (vLLM, Ollama, Together, …).\",\n modelCustomActive: \"Läuft aktuell auf benutzerdefinierter ID: {model}\",\n appliesNextTurn: \"gilt ab nächstem Turn\",\n effort: \"Effort\",\n effortMax: \"max (DeepSeek-Erweiterung — von stock OpenAI / vLLM abgelehnt)\",\n effortHigh: \"hoch (sicherer Standard — vLLM / Azure kompatibel)\",\n effortMedium: \"mittel\",\n effortLow: \"niedrig (am schnellsten)\",\n webSearch: \"Websuche\",\n webSearchNote: \"web_fetch + web_search Werkzeuge\",\n webSearchEngine: \"Suchmaschine\",\n webSearchEngineBing: \"bing — Standard, funktioniert von CN ohne Proxy\",\n webSearchEngineSearxng: \"searxng — selbst gehostet (Endpunkt via /se searxng <url>)\",\n webSearchEngineMetaso: \"metaso — 100/Tag kostenlos (CN-freundlich, kostenloser Schlüssel auf metaso.cn)\",\n webSearchEngineTavily: \"tavily — 1000/Monat kostenlos (TAVILY_API_KEY setzen)\",\n webSearchEnginePerplexity: \"perplexity — AI-native (PERPLEXITY_API_KEY setzen)\",\n webSearchEngineExa: \"exa — AI-native 1000/Monat kostenlos (EXA_API_KEY setzen)\",\n webSearchEngineNote: \"gilt für den nächsten web_search-Aufruf\",\n sectionBudget: \"Budget\",\n budget: \"Budget\",\n budgetHint: \"Ausgabengrenzen festlegen\",\n budgetPlaceholder: \"Budgetbetrag eingeben\",\n budgetOf: \"von\",\n budgetSetCap: \"Grenze setzen\",\n budgetCustom: \"benutzerdefiniert\",\n budgetBumpHint: \"Grenze erhöhen, um fortzufahren\",\n budgetClear: \"Grenze entfernen\",\n budgetIdleLine: \"warnt bei 80 % · verweigert ab 100 %\",\n budgetWarnLine: \"Grenze naht — Schleife wird ab 100 % verweigern\",\n budgetRefusing: \"Grenze erschöpft — nächster Turn verweigert bis Erhöhung oder Löschung\",\n sectionLoop: \"Schleife\",\n loopIdleHint: \"Prompt automatisch in festem Intervall erneut senden.\",\n loopCostHint: \"Jede Iteration kostet ~{cost} (letzter Turn).\",\n loopInterval: \"Intervall\",\n loopCustom: \"benutzerdefiniert\",\n loopRangeError: \"Intervall muss zwischen 5s und 6h liegen\",\n loopPrompt: \"Prompt\",\n loopPromptPlaceholder: \"z.B. überprüfe den Bereitstellungsstatus und melde Fehler\",\n loopStart: \"Schleife starten\",\n loopStop: \"Stopp\",\n loopRunning: \"läuft\",\n loopIter: \"Iteration {iter}\",\n loopFiresIn: \"startet in {remaining}\",\n sectionSkills: \"Fertigkeiten\",\n skillPaths: \"Skill-Pfade\",\n skillPathsPlaceholder: \"/pfad/zu/skills-a, /pfad/zu/skills-b\",\n skillPathsNote: \"kommagetrennt · nächstes /new oder neue Sitzung\",\n skillsEmpty: \"Keine Skills geladen\",\n skillsLoaded: \"Skills geladen\",\n subagentModelFlash: \"flash\",\n subagentModelPro: \"pro\",\n subagentModelHint: \"Modell, das verwendet wird, wenn dieser Skill seinen isolierten Subagenten startet\",\n sectionRuntime: \"Laufzeit\",\n activeModel: \"aktives Modell\",\n model: \"Modell\",\n modelFlashDesc: \"Flash — immer flash\",\n modelProDesc: \"Pro — immer pro\",\n modelPricingLine: \"${hit} Treffer · ${miss} Fehler · ${out} Ausgabe pro 1M Tokens\",\n editMode: \"Bearbeitungsmodus\",\n editModeNote: \"Umschaltung über den Chat-Tab-Header\",\n editModeHint: \"Bearbeitungsmodus konfigurieren\",\n showSystemEvents: \"Systemereignisse\",\n showSystemEventsHint: \"Zeige leise Inline-Hinweise zur Kontextkomprimierung, Abbruch, Ratelimit.\",\n shown: \"angezeigt\",\n hidden: \"ausgeblendet\",\n sectionLanguage: \"Sprache\",\n language: \"Sprache\",\n languageHint: \"Sprache wechseln\",\n langEn: \"English\",\n langZhCn: \"简体中文\",\n appMode: \"App-Modus\",\n appearanceSection: \"Darstellung\",\n behaviorSection: \"Verhalten\",\n ruleAutoApprovalHint: \"Auto-Genehmigungsregeln konfigurieren\",\n ruleAutoApprovalSection: \"Auto-Genehmigungsregeln\",\n theme: \"Theme\",\n themeDark: \"Dunkel\",\n themeHint: \"Zwischen hellem und dunklem Theme wechseln\",\n themeLight: \"Hell\",\n themeStyle: \"Theme-Stil\",\n themeStyleHint: \"Theme-Stil wählen\",\n themeStyleGraphite: \"Graphit\",\n themeStyleGraphiteDesc: \"Kühle dunkle Neutrale — am besten für lange Sitzungen.\",\n themeStyleSandstone: \"Sandstein\",\n themeStyleSandstoneDesc: \"Warme helle Töne — angenehm in hellen Räumen.\",\n themeStylePorcelain: \"Porzellan\",\n themeStylePorcelainDesc: \"Sauberes Hell mit extra Kontrast.\",\n themeStyleMidnight: \"Mitternacht\",\n themeStyleMidnightDesc: \"Tiefes Dunkel mit kühleren Highlights.\",\n pageGeneralLabel: \"Allgemein\",\n pageGeneralDesc: \"Theme, Schriften, Sprache und Arbeitsbereich.\",\n pageModelsLabel: \"Modelle\",\n pageModelsDesc: \"Standardmodell und Reasoning-Effort.\",\n pageMcpLabel: \"MCP-Server\",\n pageMcpDesc: \"Externe Tool-Server verbinden.\",\n pageSkillsLabel: \"Skills\",\n pageSkillsDesc: \"Benutzerdefinierte Skills, die mit /skill ausgeführt werden.\",\n pageMemoryLabel: \"Memory\",\n pageMemoryDesc: \"Langzeitnotizen, die sitzungsübergreifend mitgeführt werden.\",\n pageRulesLabel: \"Regeln\",\n pageRulesDesc: \"Auto-Genehmigungsregeln für Shell- und Pfadzugriff.\",\n pageBillingLabel: \"Abrechnung\",\n pageBillingDesc: \"API-Schlüssel, Guthaben und Sitzungsbudget.\",\n pageShortcutsLabel: \"Kürzel\",\n pageShortcutsDesc: \"Tastaturkürzel-Referenz.\",\n fontFamily: \"Schriftfamilie\",\n fontFamilyHint: \"Schriftfamilie wählen\",\n fontFamilySans: \"Serifenlos\",\n fontFamilySerif: \"Serife\",\n fontFamilySystem: \"System\",\n fontScale: \"Schriftgröße\",\n fontScaleHint: \"Schriftgröße anpassen\",\n fontScaleLarge: \"Groß\",\n fontScaleMedium: \"Mittel\",\n fontScaleSmall: \"Klein\",\n currentWorkspace: \"Aktueller Arbeitsbereich\",\n defaultModelCurrent: \"Aktuelles Modell\",\n editor: \"Editor\",\n editorHint: \"Editor-Einstellungen konfigurieren\",\n maxOutput: \"Max. Ausgabe\",\n reasoningEffort: \"Reasoning-Effort\",\n reasoningEffortHint: \"Reasoning-Tiefe anpassen\",\n sessionCost: \"Sitzungskosten\",\n balanceAvailable: \"Verfügbar\",\n balanceLabel: \"Guthaben\",\n balanceLow: \"Niedriges Guthaben\",\n cacheHitRate: \"Cache-Trefferquote\",\n ctxWindow: \"Kontextfenster\",\n notSelected: \"Nicht ausgewählt\",\n parseError: \"Parse-Fehler\",\n workspaceChange: \"Ändern\",\n workspaceSection: \"Arbeitsbereich\",\n mcpAdd: \"Hinzufügen\",\n mcpAddSection: \"MCP-Server hinzufügen\",\n mcpBridged: \"Verbunden\",\n mcpConfigured: \"Konfiguriert\",\n mcpEmpty: \"Keine MCP-Server\",\n mcpNotBridged: \"Nicht verbunden\",\n mcpRemove: \"Entfernen\",\n mcpSpecFormat: \"JSON-Format\",\n mcpSpecLabel: \"Server-Spec\",\n memoryDesc: \"Memory-Einstellungen konfigurieren\",\n memorySection: \"Memory\",\n shortcutAbort: \"Abbrechen\",\n shortcutCloseTab: \"Tab schließen\",\n shortcutCommandPalette: \"Befehlsübersicht\",\n shortcutFocusComposer: \"Composer fokussieren\",\n shortcutNewChat: \"Neuer Chat\",\n shortcutNewTab: \"Neuer Tab\",\n shortcutSettings: \"Einstellungen\",\n shortcutSwitchTab: \"Tab wechseln\",\n qqAccessAllowlist: \"Allowlist\",\n qqAccessOpen: \"Offen\",\n qqAccessOwner: \"Besitzer\",\n qqAccessOwnerWithAllowlist: \"Besitzer + Allowlist\",\n qqAccessRuntime: \"Laufzeit\",\n qqAppId: \"App-ID\",\n qqApplyAction: \"Anwenden\",\n qqApplyLabel: \"Anwenden\",\n qqAppSecret: \"App-Secret\",\n qqBack: \"Zurück\",\n qqConfigure: \"Konfigurieren\",\n qqConfigureHint: \"QQ-Integration einrichten\",\n qqConfigureTitle: \"QQ-Konfiguration\",\n qqConnected: \"Verbunden\",\n qqConnecting: \"Verbinde…\",\n qqDisconnected: \"Getrennt\",\n qqEnvironment: \"Umgebung\",\n qqFailed: \"Fehlgeschlagen\",\n qqProduction: \"Produktion\",\n qqSandbox: \"Sandbox\",\n qqSave: \"Speichern\",\n qqSaveAndConnect: \"Speichern & Verbinden\",\n qqSection: \"QQ-Integration\",\n qqSummaryAppId: \"App-ID\",\n qqSummaryDetail: \"Details\",\n qqSummaryMissing: \"Nicht konfiguriert\",\n qqTitle: \"QQ-Bot\",\n },\n chat: {\n ...en.chat,\n modeMirror: \"TUI-Spiegel\",\n modeView: \"Sitzungsansicht\",\n placeholder: \"Prompt eingeben – Enter sendet, Shift+Enter für neue Zeile · / @ für Auswahl\",\n placeholderBusy: \"warte auf Abschluss des aktuellen Turns…\",\n placeholderSteerBusy: \"tippe zum Steuern — Befehle und Auswahl sind während des Betriebs deaktiviert\",\n steerHint: \"Nachricht steuert den aktuellen Turn (wird als Anweisung hinzugefügt)\",\n send: \"Senden\",\n new: \"Neu\",\n clear: \"Leeren\",\n newTitle: \"/new — Gesprächskontext löschen (Schleifenlog + Scrollback)\",\n clearTitle: \"/clear — nur sichtbaren Scrollback leeren (Kontext bleibt)\",\n noConversation: \"Noch keine Unterhaltung. Sende unten einen Prompt.\",\n newConfirmBusy: \"Ein Turn läuft gerade. Abbrechen und neues Gespräch beginnen?\",\n newConfirm: \"Aktuelles Gespräch leeren und neu beginnen?\",\n newToast: \"neues Gespräch\",\n clearToast: \"Scrollback geleert\",\n newFailed: \"/new fehlgeschlagen: {error}\",\n clearFailed: \"/clear fehlgeschlagen: {error}\",\n eventStreamError: \"Ereignisstrom unterbrochen — verbinde neu…\",\n semanticBanner: \"Semantische Suche ist für dieses Projekt nicht aktiviert.\",\n semanticBannerDesc:\n \"Erstelle den Index einmal, und das Modell kann Code anhand der Bedeutung finden (»Wo behandeln wir Authentifizierungsfehler?«) statt nach exakten Zeichenketten zu greppen.\",\n semanticBannerBtn: \"Erstellen →\",\n semanticBannerDismiss: \"ausblenden (nicht wieder anzeigen)\",\n slashCommands: \"Slash-Befehle\",\n projectFiles: \"Projektdateien\",\n effortTitle: \"reasoning_effort — gilt ab nächstem Turn\",\n effortMaxTitle: \"max (DeepSeek-Erweiterung)\",\n effortHighTitle: \"hoch (sicherer Standard — vLLM / Azure kompatibel)\",\n effortMediumTitle: \"mittel\",\n effortLowTitle: \"niedrig (am schnellsten)\",\n editGateTitle: \"Edit-Gate — Shift+Tab schaltet in der TUI\",\n editReviewTitle: \"review — sowohl Edits als auch nicht-allowlistete Shell fragen zuerst\",\n editAutoTitle: \"auto — Edits auto-anwenden, Shell fragt weiterhin\",\n editYoloTitle: \"yolo — Edits UND Shell auto-ausführen, Allowlist umgangen\",\n railSession: \"Sitzung\",\n railTurns: \"Turns\",\n railPromptTok: \"Prompt-Tok\",\n railCost: \"Kosten\",\n railCacheHit: \"Cache-Treffer\",\n railToolBudget: \"Tool-Budget\",\n railSpend: \"Ausgaben\",\n railActivePlan: \"Aktiver Plan\",\n railProgress: \"Fortschritt\",\n statusModel: \"Modell\",\n statusCtx: \"Kontext\",\n statusCache: \"Cache\",\n statusTurn: \"Turn\",\n statusSession: \"Sitzung\",\n statusBalance: \"Guthaben\",\n statusTurns: \"{count} Turn{s}\",\n waitingStats: \"··· warte auf Live-Statistiken\",\n inflightPhase: \"{phase}\",\n inflightRunning: \"läuft\",\n inflightThinking: \"denkt nach\",\n inflightStreaming: \"streamt\",\n inflightWaiting: \"wartet\",\n inflightReasoning: \"Reasoning {count} Zch\",\n inflightOut: \"Ausgabe {count} Zch\",\n abortBtn: \"Abbrechen (Esc)\",\n confirmBtn: \"Anwenden (y)\",\n rejectBtn: \"Ablehnen (n)\",\n applyRestBtn: \"Rest anwenden (a)\",\n flipAutoBtn: \"Zu AUTO umschalten (A)\",\n },\n overview: {\n ...en.overview,\n loading: \"lade Übersicht…\",\n failed: \"Übersicht fehlgeschlagen: {error}\",\n standaloneTitle: \"Standalone-Modus\",\n standaloneDesc:\n \"Schreibgeschützte Plattenansicht. Starte /dashboard von innerhalb von reasonix code für Live-Sitzungsstatus, MCP und Tools.\",\n cockpit: \"Cockpit\",\n balance: \"Guthaben\",\n tokens7d: \"Tokens · 7d\",\n cacheHit: \"Cache-Treffer\",\n toolCalls24h: \"Tool-Aufrufe · 24h\",\n budget: \"Budget\",\n currentSession: \"aktuelle Sitzung\",\n noSession: \"Keine Live-Sitzung — /dashboard von reasonix code aus, um dich zu verbinden.\",\n promptTok: \"Prompt-Tok\",\n completionTok: \"Completion-Tok\",\n cost: \"Kosten\",\n costTrend: \"Kosten · 14 Tage\",\n noUsageYet: \"noch keine Nutzung\",\n dayAvg: \"/Tag Ø\",\n recentPlans: \"letzte Pläne\",\n noPlans: \"Noch keine Pläne — erstelle einen mit submit_plan.\",\n toolActivity: \"Tool-Aktivität\",\n noToolCalls: \"Noch keine Tool-Aufrufe.\",\n toolsLoaded: \"Tools geladen\",\n mcpServers: \"MCP-Server\",\n editMode: \"Bearbeitungsmodus\",\n version: \"Reasonix\",\n workingDir: \"Arbeitsverzeichnis\",\n projectRoot: \"Projekt-Root\",\n noPriorData: \"keine vorherigen Daten\",\n stable: \"— stabil\",\n vsPrior: \"{arrow} {pct}% vs. vorher\",\n active: \"aktiv\",\n allUp: \"alle betriebsbereit\",\n yoloWarning: \"alle Prompts umgangen\",\n checking: \"prüfe\",\n latest: \"neueste\",\n },\n usage: {\n ...en.usage,\n loading: \"lade Nutzung…\",\n failed: \"Nutzung fehlgeschlagen: {error}\",\n records: \"{count} Datensätze\",\n dailyUsage: \"Tägliche Nutzung\",\n dailyMeta: \"Kosten · Cache-Ersparnis · Turns\",\n noData: \"Noch keine Nutzungsdaten — führe einen Turn in reasonix chat / code / run aus und aktualisiere.\",\n windows: \"Rollierende Fenster\",\n colWindow: \"Fenster\",\n colTurns: \"Turns\",\n colCacheHit: \"Cache-Treffer\",\n colCost: \"Kosten (USD)\",\n colCacheSaved: \"Cache gespart\",\n colVsClaude: \"vs. Claude\",\n colSaved: \"gespart\",\n axisTime: \"Zeit\",\n axisUsd: \"USD\",\n axisTurns: \"Turns\",\n seriesCost: \"Kosten\",\n seriesCacheSaved: \"Cache gespart\",\n seriesTurns: \"Turns\",\n mostUsed: \"Meistgenutzte Modelle\",\n colModel: \"Modell\",\n },\n sessions: {\n ...en.sessions,\n loading: \"lade Sitzungen…\",\n failed: \"Sitzungen fehlgeschlagen: {error}\",\n noSessions: \"Noch keine gespeicherten Sitzungen.\",\n filterPlaceholder: \"Sitzungen filtern\",\n msgs: \"Nachr\",\n pickHint: \"Wähle links eine Sitzung, um ihr Transkript zu lesen.\",\n resumeTitle: \"In TUI fortsetzen\",\n resumeDesc:\n \"Ein Sitzungswechsel mid-Session erfordert einen Neustart, damit der Nachrichtenverlauf sauber zurückgespult werden kann. Beende deine aktuelle Sitzung und führe dann aus:\",\n loadingTranscript: \"lade Transkript…\",\n emptyTranscript: \"leeres Transkript.\",\n messages: \"{count} Nachricht{s}\",\n newBtn: \"Neue Sitzung\",\n newHint: \"Aktuelles Gespräch archivieren und neues beginnen\",\n switchBtn: \"Zu dieser Sitzung wechseln\",\n deleteBtn: \"Löschen\",\n deleteConfirm: 'Sitzung \"{name}\" löschen? Dies entfernt die Transkriptdatei und kann nicht rückgängig gemacht werden.',\n cantDeleteActive: \"Wechsle zu einer anderen Sitzung, bevor du diese löschst.\",\n attachRequired:\n \"Live-Sitzungsoperationen benötigen eine angehängte CLI-Sitzung. Starte über reasonix chat oder öffne das Dashboard von einer TUI-Sitzung aus.\",\n activeChip: \"aktiv\",\n activePill: \"aktiv\",\n },\n tools: {\n ...en.tools,\n loading: \"lade Tools…\",\n failed: \"Tools fehlgeschlagen: {error}\",\n noTools: \"Keine Tools registriert.\",\n planMode: \"Plan-Modus — Schreibzugriffe blockiert\",\n colTool: \"Tool\",\n colFlags: \"Flags\",\n colDesc: \"Beschreibung\",\n readOnly: \"schreibgeschützt\",\n write: \"schreiben\",\n flat: \"flach\",\n desc: {\n ...en.tools.desc,\n web_search:\n \"Durchsuche das öffentliche Web. Liefert sortierte Ergebnisse mit Titel, URL und Ausschnitt. Verwende dies, wenn die Antwort vom aktuellen Zustand abhängt — Ereignisse, Preise, Veröffentlichungen, Echtzeit-Status.\",\n web_fetch:\n \"Lade eine URL herunter und gib den sichtbaren Textinhalt zurück (Skripte/Styles/Navigation entfernt). Nach web_search verwenden, wenn ein Ausschnitt nicht ausreicht.\",\n run_command:\n \"Führe einen Shell-Befehl im Projekt-Root aus; gibt kombinierte stdout+stderr zurück. Allowlistete schreibgeschützte Befehle werden sofort ausgeführt; Änderungen benötigen Benutzerbestätigung.\",\n run_background:\n \"Starte einen langlebigen Prozess und trenne ihn. Liefert eine Job-ID zum Verfolgen der Logs, Warten auf Abschluss oder Beenden. Für Dev-Server, Watcher und einmalige Langzeit-Jobs.\",\n job_output:\n \"Lies die neueste Ausgabe eines Hintergrund-Jobs. Gibt das Ende des Puffers zurück und sagt dir, ob der Job noch läuft.\",\n wait_for_job:\n \"Blockiere serverseitig, bis ein Hintergrund-Job abgeschlossen ist, zeitlich begrenzt. Statt job_output in einer Schleife zu pollen.\",\n stop_job:\n \"Stoppe einen Hintergrund-Job. SIGTERM zuerst, SIGKILL nach einer Gnadenfrist. Sicher für bereits beendete Jobs.\",\n list_jobs:\n \"Liste jeden in dieser Sitzung gestarteten Hintergrund-Job auf — laufende und beendete — mit ID, Befehl, PID und Status.\",\n remember:\n \"Speichere eine Erinnerung für zukünftige Sitzungen. Verwende, wenn der Benutzer eine Präferenz angibt, deinen Ansatz korrigiert, eine nicht offensichtliche Tatsache teilt oder dich bittet, etwas zu merken.\",\n forget:\n \"Lösche eine Memory-Datei und entferne sie aus MEMORY.md. Verwende, wenn der Benutzer vergessen möchte oder eine gespeicherte Tatsache jetzt falsch ist.\",\n recall_memory:\n \"Lies den vollständigen Body einer Memory-Datei, wenn die einzeilige Zusammenfassung nicht genug Detail bietet.\",\n read_file:\n \"Lese eine Datei unter dem Sandbox-Root. Unterstützt head/tail/range-Begrenzung zum Kontextsparen. Gibt automatisch eine Vorschau für Dateien über 200 Zeilen zurück.\",\n list_directory:\n \"Liste Einträge in einem Verzeichnis auf. Gibt eine Zeile pro Eintrag zurück und markiert Verzeichnisse mit einem Schrägstrich.\",\n directory_tree:\n \"Liste Einträge in einem Verzeichnis rekursiv als eingerückten Baum auf. Budget-bewusst mit automatischem Einklappen für große Unterbäume.\",\n search_files:\n \"Finde Dateien, deren NAME einem Teilstring oder Regex entspricht. Groß-/Kleinschreibung unwichtig. Überspringt standardmäßig Abhängigkeits-/Build-Verzeichnisse.\",\n search_content:\n \"Durchsuche Dateiinhalte rekursiv mit grep nach einem Teilstring oder Regex. Liefert Treffer im Format pfad:zeile:text. Das richtige Werkzeug zum Finden von Referenzen.\",\n glob: \"Liste Dateien, die einem Glob-Muster entsprechen, sortiert nach Änderungsdatum. Standardlimit 200, max 1000. Überspringt node_modules/.git/dist standardmäßig.\",\n get_file_info: \"Ermittle Informationen zu einem Pfad unter dem Sandbox-Root. Liefert Typ, Größe in Bytes und Änderungsdatum.\",\n write_file:\n \"Erstelle oder überschreibe eine Datei mit dem angegebenen Inhalt. Übergeordnete Verzeichnisse werden bei Bedarf erstellt.\",\n edit_file:\n \"Wende eine SEARCH/REPLACE-Bearbeitung auf eine vorhandene Datei an. Die Suche muss exakt übereinstimmen und in der Datei eindeutig sein.\",\n multi_edit:\n \"Wende N SEARCH/REPLACE-Bearbeitungen atomar auf eine oder mehrere Dateien an. Wenn eine Bearbeitung fehlschlägt, werden keine Dateien geschrieben.\",\n create_directory: \"Erstelle ein Verzeichnis (und alle fehlenden übergeordneten) unter dem Sandbox-Root.\",\n move_file: \"Benenne eine Datei oder ein Verzeichnis unter dem Sandbox-Root um oder verschiebe es.\",\n delete_file:\n \"Lösche eine Datei unter dem Sandbox-Root. Lehnt Verzeichnisse ab — verwende delete_directory dafür.\",\n delete_directory:\n \"Lösche rekursiv ein Verzeichnis unter dem Sandbox-Root. Übergib recursive:false, um nicht-leere Verzeichnisse abzulehnen.\",\n copy_file:\n \"Kopiere eine Datei oder ein Verzeichnis unter dem Sandbox-Root. Lehnt das Überschreiben eines vorhandenen Ziels ab.\",\n submit_plan:\n \"Reiche einen konkreten Plan für ein Review-Gate ein. Für dateiübergreifende Refactorings, Architekturänderungen oder alles, was teuer rückgängig zu machen ist.\",\n mark_step_complete:\n \"Markiere einen Schritt des genehmigten Plans als erledigt. Genau einmal nach Abschluss jedes Schritts aufrufen.\",\n revise_plan:\n \"Ersetze gezielt die verbleibenden Schritte eines laufenden Plans. Erledigte Schritte werden nie berührt.\",\n run_skill:\n \"Rufe ein Playbook aus dem Skills-Index auf. Übergib den bloßen Skill-Namen. Subagent-gekennzeichnete Skills starten einen isolierten Subagenten.\",\n spawn_subagent:\n \"Starte einen isolierten Subagenten für eine in sich geschlossene Teilaufgabe. Für paralleles Fan-out oder wenn die Arbeit viele Dateilesevorgänge benötigt.\",\n todo_write:\n \"Aufgaben-Tracker innerhalb der Sitzung für mehrschrittige Arbeit. Ersetzt bei jedem Aufruf die gesamte Liste. Kein Genehmigungs-Gate oder Dateischreibvorgänge.\",\n ask_choice:\n \"Präsentiere 2–6 Alternativen dem Benutzer. Verwende, wenn der Benutzer nach Optionen fragt oder du eine Präferenzentscheidung benötigst.\",\n create_skill:\n \"Erstelle ein neues Skill-Gerüst, das der Benutzer später mit /skill aufrufen kann. Unterstützt Inline- und Subagent-Ausführungsmodi.\",\n add_mcp_server:\n \"Registriere einen neuen MCP-Server in der Konfiguration des Benutzers. Wirkt ab der nächsten Sitzung. Unterstützt stdio, SSE und streamable-http.\",\n },\n },\n permissions: {\n ...en.permissions,\n loading: \"lade Berechtigungen…\",\n failed: \"Berechtigungen fehlgeschlagen: {error}\",\n yoloTitle: \"YOLO-Modus\",\n yoloDesc:\n \"Jeder Shell-Befehl läuft automatisch, Allowlist umgangen. Zurück mit /mode review in der TUI.\",\n project: \"Projekt\",\n builtin: \"Eingebaut\",\n addPrefix: \"Präfix hinzufügen\",\n addPlaceholder: 'z.B. \"npm run build\" oder \"deploy.sh\"',\n clearAll: \"Alle löschen\",\n alreadyIn: \"{prefix} bereits in der Liste\",\n added: \"hinzugefügt: {prefix}\",\n removed: \"entfernt: {prefix}\",\n cleared: \"{count} Eintrag{Einträge} gelöscht\",\n removeConfirm: '\"{prefix}\" aus der Allowlist dieses Projekts entfernen?',\n clearConfirm: \"Alle Projekt-Allowlist-Einträge löschen? Builtin-Einträge bleiben unberührt.\",\n projectAllowlist: \"Projekt-Allowlist · {count}\",\n nothingStored: \"Noch nichts für dieses Projekt gespeichert.\",\n colNum: \"#\",\n colPrefix: \"Präfix\",\n builtinTitle: \"Eingebaut · {count} · schreibgeschützt\",\n standaloneWarning:\n \"Änderungen erfordern /dashboard von innerhalb einer aktiven reasonix code-Sitzung — das Standalone-Dashboard kann nicht erkennen, welche Projekt-Allowlist zu bearbeiten ist.\",\n },\n mcp: {\n ...en.mcp,\n loading: \"lade MCP…\",\n servers: \"MCP-Server · {count} verbunden\",\n all: \"alle\",\n live: \"live\",\n unbridged: \"unverbunden\",\n specPlaceholder: \"Spec — z.B. fs=npx -y @modelcontextprotocol/...\",\n saved: \"gespeichert\",\n savedRestart: \"gespeichert — starte reasonix code neu, um diesen Server zu verbinden\",\n removed: \"entfernt — starte neu, um die Live-Verbindung zu trennen\",\n removeConfirm: \"MCP-Spec aus Konfiguration entfernen?\\n\\n{spec}\",\n noServers: \"Keine MCP-Server in dieser Sitzung.\",\n tools: \"Tools\",\n inConfig: \"in Konfiguration · nicht geladen\",\n unbridgedTitle: \"unverbunden · in Konfiguration\",\n removeBtn: \"Entfernen\",\n spec: \"Spec\",\n whyUnbridged: \"Warum unverbunden?\",\n whyUnbridgedDesc:\n \"Diese Spec befindet sich in deiner config.json, ist aber nicht in die Live-Sitzung eingebunden. MCP-Server werden beim Start von reasonix code angehängt; das Dashboard allein kann den Kindprozess nicht starten.\",\n whyUnbridgedHint: \"Zum Aktivieren: starte reasonix code neu und aktualisiere dieses Dashboard.\",\n bridgeFailed: \"Verbindung fehlgeschlagen\",\n bridgeFailedTitle: \"Verbindung fehlgeschlagen · in Konfiguration\",\n bridgeFailedHint:\n \"Reasonix hat versucht, diesen Server zu verbinden, und der Versuch ist fehlgeschlagen. Häufige Ursachen: falsche URL, fehlender Auth-Header, upstream 404/5xx, fehlender lokaler Befehl. Behebe und starte reasonix code neu.\",\n pickHint: \"Wähle links einen MCP-Server zum Inspizieren von Tools / Ressourcen / Prompts.\",\n toolsTitle: \"Tools · {count}\",\n resourcesTitle: \"Ressourcen · {count}\",\n promptsTitle: \"Prompts · {count}\",\n colName: \"Name\",\n colDesc: \"Beschreibung\",\n colUri: \"URI\",\n marketplace: \"Marktplatz\",\n marketplaceSearch: \"Registry durchsuchen…\",\n marketplaceLoading: \"lade Registry…\",\n marketplaceMore: \"5 weitere Seiten laden\",\n marketplaceMoreLabel: \"50 mehr laden · zeige {shown} / {total}\",\n marketplaceMoreHint: \"ruft weitere Seiten von der Registry ab\",\n marketplaceMoreCachedHint: \"weitere Einträge bereits lokal zwischengespeichert\",\n marketplaceExhausted: \"alle Seiten geladen\",\n marketplaceExhaustedFull: \"zeige alle {total} Einträge — Registry erschöpft\",\n marketplaceCount: \"{loaded} geladen · {matched} Treffer · Quelle: {source}{cached}\",\n marketplaceCachedSuffix: \" · zwischengespeichert\",\n marketplaceNoMatches: \"Keine Treffer. Versuche andere Begriffe oder lade mehr Seiten.\",\n marketplaceInstall: \"Installieren\",\n marketplacePickHint: \"Wähle links einen Server, dann Installieren.\",\n marketplaceInstalled: \"installiert → {spec}\",\n marketplaceInstalledBridged: \"installiert + verbunden → {spec}\",\n marketplaceAlready: \"bereits installiert\",\n marketplaceNeedsEnv: \"benötigt Umgebungsvariable: {names}\",\n marketplaceSourceTag: \"[{source}]\",\n marketplaceNoInstall:\n \"Smithery-Eintrag — Installationsmetadaten nicht verfügbar; verwende `npx -y @smithery/cli install {name}` direkt\",\n marketplaceFetchOnInstall:\n \"Smithery-Eintrag — Installationsdetails werden bei Install abgerufen. HTTP-Server werden als streamable-http-Remotes abgebildet; stdio-Server laufen über @smithery/cli.\",\n marketplaceInstalledBadge: \"installiert\",\n marketplaceUninstall: \"Deinstallieren\",\n marketplaceEnvTitle: \"Erforderliche Umgebungsvariablen\",\n marketplaceEnvHint:\n \"Setze diese in deiner Shell vor dem nächsten `reasonix code`, damit der verbundene Server authentifizieren kann.\",\n marketplaceRestartHint:\n \"Spec in ~/.reasonix/config.json geschrieben. Starte `reasonix code` neu, um den Server zu verbinden (Live-Hot-Reload ist auf der Roadmap).\",\n },\n memory: {\n ...en.memory,\n loading: \"lade Memory…\",\n files: \"Memory · {count} Dateien\",\n exists: \"existiert\",\n create: \"erstellen\",\n noFiles: \"Noch keine Memory-Dateien.\",\n pickHint: \"Wähle links eine Memory-Datei.\",\n pickDesc: \"Projekt-REASONIX.md ist commitierbar; globale Notizen leben in ~/.reasonix/memory/.\",\n chars: \"{count} Zeichen\",\n saved: \"{scope} gespeichert\",\n reloadHint: \"wird beim nächsten /new oder Sitzungsneustart neu angewendet\",\n },\n hooks: {\n ...en.hooks,\n loading: \"lade Hooks…\",\n resolved: \"aufgelöst\",\n eventMatrix: \"Ereignismatrix\",\n matrixSub: \"{scripts} Skript{s} × {events} Ereignis{se}\",\n noHooks: \"Keine Hooks konfiguriert. Bearbeite das JSON unten, um welche hinzuzufügen.\",\n colScript: \"Skript\",\n noProject: \"Kein aktives Projekt — öffne /dashboard von reasonix code, um Projekt-Hooks zu bearbeiten.\",\n saveReload: \"Speichern + Neu laden\",\n discard: \"Änderungen verwerfen\",\n savedReloaded: \"{scope} gespeichert + neu geladen\",\n recentRuns: \"Letzte Ausführungen\",\n noRuns: \"Keine Hook-Ausführungen im aktuellen Sitzungslog.\",\n colWhen: \"Wann\",\n colPhase: \"Phase\",\n colHook: \"Hook\",\n colOutcome: \"Ergebnis\",\n },\n skills: {\n ...en.skills,\n loading: \"lade Skills…\",\n filterPlaceholder: \"Skills filtern\",\n project: \"Projekt\",\n custom: \"Benutzerdefiniert\",\n global: \"Global\",\n builtin: \"Eingebaut\",\n newSkill: \"neuer Skill\",\n noDescription: \"(keine Beschreibung)\",\n runs7d: \"Ausführungen · 7d\",\n pickHint: \"Wähle links einen Skill oder erstelle oben einen neuen.\",\n readOnlyBuiltin: \"schreibgeschützt · eingebaut\",\n readOnlyCustom: \"schreibgeschützt · benutzerdefinierter Pfad\",\n builtinDesc:\n \"Eingebaute Skills werden mit Reasonix ausgeliefert; das Modell nimmt sie automatisch auf. Zum Anpassen erstelle einen Skill mit gleichem Namen im Projekt- oder globalen Bereich.\",\n saved: \"{scope}/{name} gespeichert\",\n deleteConfirm: \"Skill {scope}/{name} löschen?\",\n reloadHint: \"wird beim nächsten /new oder Sitzungsneustart neu geladen\",\n },\n system: {\n ...en.system,\n loading: \"lade Gesundheit…\",\n failed: \"Gesundheitscheck fehlgeschlagen: {error}\",\n healthChecks: \"Gesundheitsprüfungen\",\n version: \"Version\",\n checking: \"prüfe\",\n latest: \"● aktuell\",\n outOfDate: \"● veraltet\",\n versionPending: \"Versionsprüfung ausstehend\",\n upToDate: \"aktuell\",\n latestVer: \"neueste: {version}\",\n sessions: \"Sitzungen\",\n ok: \"● ok\",\n memory: \"Memory\",\n semanticIndex: \"Semantischer Index\",\n built: \"● erstellt\",\n none: \"— keine\",\n runIndex: \"führe reasonix index zum Erstellen aus\",\n usageLog: \"Nutzungslog\",\n backgroundJobs: \"Hintergrund-Jobs\",\n noSession: \"— keine Sitzung\",\n running: \"{count} laufend\",\n attachHint: \"Sitzung anhängen, um Jobs zu sehen\",\n shellSpawn: \"Shell + Start\",\n paths: \"Pfade\",\n home: \"Home\",\n sessionsPath: \"Sitzungen\",\n memoryPath: \"Memory\",\n semanticPath: \"Semantisch\",\n usagePath: \"Nutzung\",\n },\n plans: {\n ...en.plans,\n loading: \"lade Pläne…\",\n failed: \"Pläne fehlgeschlagen: {error}\",\n noPlans: \"Noch keine archivierten Pläne — führe einen Turn aus, der submit_plan und mark_step_complete aufruft.\",\n filterPlaceholder: \"Pläne filtern\",\n active: \"aktiv\",\n done: \"erledigt\",\n idle: \"inaktiv\",\n steps: \"Schritte\",\n pickHint: \"Wähle links einen Plan.\",\n noTitle: \"(kein Titel)\",\n stepTimeline: \"Schritt-Zeitleiste · {done} / {total}\",\n step: \"Schritt {n}\",\n },\n semantic: {\n ...en.semantic,\n codeRequired: \"Semantisch — Code-Modus erforderlich\",\n indexBuilt: \"Index erstellt\",\n noIndex: \"noch kein Index\",\n ready: \"bereit\",\n setupNeeded: \"Setup erforderlich\",\n installOllama: \"Ollama installieren\",\n installOllamaDesc:\n \"Reasonix führt keine Paketverwaltung für dich aus. Installiere zuerst Ollama, dann komme zurück:\",\n macWindows: \"macOS / Windows:\",\n download: \"herunterladen von ollama.com/download\",\n linux: \"Linux:\",\n refreshHint:\n \"Nach der Installation aktualisieren — dieses Panel bietet dann an, den Daemon zu starten und {model} zu ziehen.\",\n daemon: \"Daemon\",\n daemonDesc: \"Ollama ist im PATH, aber der HTTP-Daemon ist nicht erreichbar.\",\n startDaemon: \"Daemon starten\",\n runsOllama: \"führt ollama serve getrennt aus\",\n model: \"Modell\",\n modelMissing: \"{model} ist noch nicht installiert.\",\n modelSize: \"~270 MB beim ersten Pull.\",\n pulling: \"ziehe…\",\n pullModel: \"{model} ziehen\",\n indexStatus: \"Index-Status\",\n builtStatus: \"● erstellt\",\n incompatibleStatus: \"● inkompatibel\",\n chunks: \"Chunks\",\n files: \"Dateien\",\n dim: \"Dim\",\n size: \"Größe\",\n lastBuild: \"letzte Erstellung\",\n builtWith: \"erstellt mit\",\n currentTarget: \"aktuelles Ziel\",\n incompatibleHint:\n \"Dieser Index auf der Platte wurde für einen anderen Anbieter oder ein anderes Modell erstellt. Führe Neu erstellen aus, um ihn zu ersetzen.\",\n runIndexHint: \"Führe einen Index aus, um semantic_search zu aktivieren.\",\n reIndex: \"Neu indizieren\",\n build: \"Erstellen\",\n rebuild: \"Neu erstellen\",\n stop: \"Stopp\",\n provider: \"Anbieter\",\n providerType: \"Diensttyp\",\n openaiCompat: \"OpenAI-kompatibel\",\n apiUrl: \"API-URL\",\n apiKey: \"API-Schlüssel\",\n apiKeyStoredNote: \"API-Schlüssel wird in ~/.reasonix/config.json gespeichert — teile diese Datei nicht.\",\n customRequestBody: \"benutzerdefinierter Request-Body\",\n invalidCustomRequestBody: \"Der benutzerdefinierte Request-Body muss gültiges JSON sein: {error}\",\n customRequestBodyMustBeObject: \"Der benutzerdefinierte Request-Body muss ein JSON-Objekt sein.\",\n saveBeforeIndex: \"Speichere semantische Einstellungen vor dem Start eines Index.\",\n extraBody: \"zusätzlicher Body\",\n batchSize: \"Batch-Größe\",\n keepExistingKey: \"leer lassen, um vorhandenen Schlüssel zu behalten\",\n remoteProvider: \"Remote-Embedding-Anbieter\",\n remoteProviderDesc:\n \"Konfiguriere hier die vollständige OpenAI-kompatible Embeddings-URL. Reasonix sendet Anfragen genau an die von dir angegebene URL.\",\n ollama: \"Ollama\",\n binary: \"Binärdatei\",\n found: \"gefunden\",\n missing: \"fehlt\",\n daemonStatus: \"Daemon\",\n up: \"aktiv\",\n down: \"inaktiv\",\n pulled: \"gezogen\",\n indexConfig: \"Index-Konfiguration\",\n reset: \"Zurücksetzen\",\n excludeDirs: \"Verzeichnisse ausschließen\",\n excludeFiles: \"Dateien ausschließen\",\n excludeExts: \"Erweiterungen ausschließen\",\n excludePatterns: \"Muster ausschließen\",\n glob: \"Glob\",\n respectGitignore: \".gitignore beachten\",\n maxFileBytes: \"max. Dateigröße\",\n skipLarger: \"überspringe Dateien größer als ~{size} MiB\",\n preview: \"Vorschau\",\n searchPlaceholder: \"beschreibe, was zu finden ist — »wo behandeln wir Abbruchsignale«\",\n searching: \"suche…\",\n results: \"{count} Ergebnis{se} · {ms}ms · {model}\",\n noMatches: \"Keine Treffer über dem Schwellenwert.\",\n previewSummary: \"Vorschau — würde {included} Datei(en) indizieren, {skipped} überspringen\",\n nothingSkipped: \"nichts übersprungen — alle durchlaufenen Dateien würden indiziert.\",\n firstIncluded: \"erste {count} einbezogene Datei(en)\",\n job: \"Job\",\n phaseSetup: \"Vorbereitung\",\n phaseScan: \"Dateien scannen\",\n phaseEmbed: \"Chunks einbetten\",\n phaseWrite: \"Index schreiben\",\n phaseDone: \"erledigt\",\n phaseError: \"Fehler\",\n phaseCancelled: \"abgebrochen\",\n setupFailed: \"Setup fehlgeschlagen\",\n stopping: \"stoppe\",\n scanned: \"{count} gescannt\",\n changed: \"{count} geändert\",\n skipped: \"{count} übersprungen\",\n chunksProgress: \"{done} / {total} ({pct}%)\",\n result: \"Ergebnis\",\n added: \"{count} hinzugefügt\",\n removed: \"{count} entfernt\",\n failed: \"{count} fehlgeschlagen\",\n skippedFiles: \"{total} Dateien ({details})\",\n rebuildStarted: \"Neuerstellung gestartet\",\n incrementalStarted: \"inkrementelle Indizierung gestartet\",\n stopRequested: \"Stopp angefordert — aktueller Chunk-Batch wird zuerst beendet\",\n startingDaemon: \"starte Ollama-Daemon (15s Timeout)…\",\n daemonUp: \"Daemon ist aktiv\",\n daemonTimeout: \"Daemon wurde nicht rechtzeitig aktiv — überprüfe ollama serve manuell\",\n pullingModel: \"ziehe {model} — dies kann bei der ersten Installation einige Minuten dauern\",\n savedConfig: \"gespeichert · {count} Felder aktualisiert · führe Index erneut aus, um anzuwenden\",\n runningPreview: \"führe Trockenlauf gegen Projekt-Root aus…\",\n exclude: \"ausschließen\",\n },\n modal: {\n ...en.modal,\n shellTitle: \"Shell-Befehl\",\n shellBgTitle: \"Hintergrundprozess\",\n shellSubtitle: \"Modell möchte einen Shell-Befehl ausführen\",\n shellBgSubtitle: \"langlebig — läuft nach Genehmigung weiter\",\n pathTitle: \"Datei außerhalb des Sandbox\",\n pathSubtitle: \"{intent} via {tool}\",\n pathRead: \"lesen\",\n pathWrite: \"schreiben\",\n pathSandboxLabel: \"Sandbox\",\n pathAllowPrefixLabel: \"Präfix erlauben\",\n runOnce: \"Einmal ausführen\",\n alwaysAllow: '\"{prefix}\" immer erlauben',\n deny: \"Ablehnen\",\n choiceTitle: \"Modell möchte, dass du wählst\",\n typeOwn: \"Eigene Antwort eingeben\",\n typeOwnSummary: \"Keine der Optionen passt — schreibe eine Freitext-Antwort.\",\n typePlaceholder: \"Freitext-Antwort eingeben…\",\n send: \"Senden\",\n cancel: \"Abbrechen\",\n cancelSummary: \"Frage verwerfen. Modell fragt, was du eigentlich möchtest.\",\n planTitle: \"Plan eingereicht\",\n planSubtitle: \"Modell hat einen Plan vorgeschlagen; überprüfe, dann wähle\",\n approveInstructions:\n \"Optionale letzte Anweisungen / Antworten auf offene Fragen (Enter zum Leer-Senden)\",\n refinePlaceholder: \"Was muss sich ändern? Sei konkret.\",\n approve: \"Genehmigen\",\n refine: \"Verfeinern\",\n sendRefinement: \"Verfeinerung senden\",\n editTitle: \"Edit ausstehend zur Überprüfung\",\n editSubtitle: \"{path} · {remaining} von {total} Blöcken verbleibend\",\n before: \"vorher\",\n after: \"nachher\",\n workspaceTitle: \"Modell möchte Arbeitsbereich wechseln\",\n workspaceSubtitle: \"jedes nachfolgende Datei-/Shell-/Memory-Tool wird gegen den neuen Root aufgelöst\",\n switchBtn: \"Wechseln (Enter)\",\n denyBtn: \"Ablehnen (Esc)\",\n stepComplete: \"Schritt abgeschlossen{counter}\",\n continueBtn: \"Fortsetzen\",\n reviseBtn: \"Überarbeiten…\",\n stopBtn: \"Stopp\",\n revisionTitle: \"Modell hat eine Planüberarbeitung vorgeschlagen\",\n sendRevision: \"Überarbeitung senden\",\n accept: \"Akzeptieren\",\n reject: \"Ablehnen\",\n arguments: \"Argumente\",\n revisePlaceholder: \"Was muss sich vor dem nächsten Schritt ändern? Leer lassen zum Fortfahren.\",\n pickerFilter: \"Filter…\",\n pickerEmpty: \"Nichts anzuzeigen.\",\n pickerLoadMore: \"Mehr laden\",\n pickerPick: \"Öffnen\",\n pickerInstall: \"Installieren\",\n pickerUninstall: \"Deinstallieren\",\n pickerRename: \"Umbenennen…\",\n pickerNew: \"Neu…\",\n pickerNewPlaceholder: \"Name (leer lassen für Standard)\",\n viewerClose: \"Schließen\",\n },\n error: {\n ...en.error,\n title: \"Etwas ist im Dashboard kaputtgegangen\",\n body: \"Die TUI ist nicht betroffen — nur dieser Browser-Tab ist gestolpert. Du kannst schließen und weiterarbeiten oder es melden, damit wir die Ursache beheben.\",\n copyDetails: \"Details kopieren\",\n copied: \"Kopiert ✓\",\n reportOnGithub: \"Auf GitHub melden\",\n dismiss: \"Schließen (Esc)\",\n crashing: \"dieses Panel stürzt ständig ab — {name}\",\n retry: \"Erneut versuchen\",\n recovering: \"wiederherstellen…\",\n },\n fmt: {\n ...en.fmt,\n justNow: \"gerade eben\",\n minutesAgo: \"vor {n}m\",\n hoursAgo: \"vor {n}h\",\n daysAgo: \"vor {n}T\",\n },\n cards: {\n ...en.cards,\n applied: \"Angewendet\",\n cacheHit: \"Cache-Treffer\",\n checkpointRewind: \"Checkpoint-Rückspulen\",\n cost: \"Kosten\",\n diffApply: \"Anwenden\",\n diffApplyChanges: \"Änderungen anwenden\",\n diffAwaiting: \"Wartet auf Überprüfung\",\n diffDiscard: \"Verwerfen\",\n done: \"Fertig\",\n elapsed: \"Verstrichen\",\n error: \"Fehler\",\n errorName: \"Fehler\",\n failed: \"Fehlgeschlagen\",\n hits: \"Treffer\",\n memoryCountSuffix: \"Erinnerungen\",\n memoryName: \"Memory\",\n output: \"Ausgabe\",\n planDefaultTitle: \"Plan\",\n prompt: \"Prompt\",\n compactionMeta: \"{chars} Zeichen\",\n compactionName: \"Komprimierter Verlauf\",\n reasoningComplete: \"Reasoning abgeschlossen\",\n reasoningName: \"Reasoning\",\n result: \"Ergebnis\",\n running: \"Läuft\",\n searchName: \"Suche\",\n shellAlwaysAllow: \"Immer erlauben\",\n shellAwaiting: \"Wartet auf Genehmigung\",\n shellExecuteHint: \"Diesen Befehl ausführen?\",\n shellReject: \"Ablehnen\",\n shellRun: \"Ausführen\",\n shellRunning: \"Läuft\",\n streaming: \"Streamt\",\n subagentDone: \"Subagent erledigt\",\n subagentDoneProgress: \"Subagent erledigt ({pct}%)\",\n subagentFailed: \"Subagent fehlgeschlagen\",\n subagentRunning: \"Subagent läuft\",\n },\n planBadge: {\n ...en.planBadge,\n blocked: \"Blockiert\",\n done: \"Erledigt\",\n failed: \"Fehlgeschlagen\",\n pending: \"Ausstehend\",\n running: \"Läuft\",\n },\n composer: {\n ...en.composer,\n atHeader: \"Dateien erwähnen\",\n close: \"Schließen\",\n commandPalette: \"Befehlsübersicht\",\n commands: \"Befehle\",\n commandsLabel: \"Befehle\",\n confirm: \"Bestätigen\",\n imageFilterName: \"Bilder\",\n insertFile: \"Datei einfügen\",\n insertImage: \"Bild einfügen\",\n interrupt: \"Unterbrechen\",\n mentionFiles: \"Dateien erwähnen\",\n mentionLabel: \"Erwähnen\",\n newline: \"Neue Zeile\",\n noMatches: \"Keine Treffer\",\n placeholder: \"Prompt eingeben…\",\n queue: \"Warteschlange\",\n queueCount: \"{count} in Warteschlange\",\n select: \"Auswählen\",\n send: \"Senden\",\n slashHeader: \"Slash-Befehle\",\n switchModel: \"Modell wechseln\",\n switchEffort: \"Reasoning-Effort wechseln\",\n workspaceRoot: \"Arbeitsbereich-Root\",\n },\n contextPanel: {\n ...en.contextPanel,\n allow: \"Erlauben\",\n ask: \"Fragen\",\n autoApproveTitle: \"Auto-genehmigen\",\n cacheKey: \"Cache\",\n contextTokens: \"Kontext-Tokens\",\n fileInContext: \"Im Kontext\",\n fileModified: \"Geändert\",\n filesCount: \"{count} Dateien\",\n filesTab: \"Dateien\",\n filesTitle: \"Dateien\",\n freeKey: \"Frei\",\n itemCount: \"{count} Einträge\",\n mcpConfigured: \"Konfiguriert\",\n mcpConnecting: \"Verbinde…\",\n mcpDisabled: \"Deaktiviert\",\n mcpEmpty: \"Keine MCP-Server\",\n mcpFailed: \"Fehlgeschlagen\",\n mcpReady: \"Bereit\",\n mcpReadyAll: \"Alle bereit\",\n mcpReadySome: \"Teils bereit\",\n mcpTitle: \"MCP\",\n mcpTools: \"Tools\",\n memoryTab: \"Memory\",\n memoryTitle: \"Memory\",\n noFilesMsg: \"Keine Dateien im Kontext\",\n noMemoriesMsg: \"Keine Erinnerungen\",\n reservedKey: \"Reserviert\",\n ruleReadOnly: \"Schreibgeschützt\",\n ruleReview: \"Überprüfung\",\n ruleShellAllowlist: \"Shell-Allowlist\",\n rulesTab: \"Regeln\",\n ruleWritesAsk: \"Schreiben fragen\",\n ruleYolo: \"YOLO\",\n scopeGlobal: \"Global\",\n scopeProject: \"Projekt\",\n toolsTab: \"Tools\",\n usedKey: \"Verwendet\",\n },\n dragDrop: {\n ...en.dragDrop,\n overlay: \"Dateien hier ablegen\",\n },\n extraCards: {\n ...en.extraCards,\n approve: \"Genehmigen\",\n balance: \"Guthaben\",\n cache: \"Cache\",\n cacheHit: \"Cache-Treffer\",\n contextWindow: \"Kontextfenster\",\n doctorTitle: \"Diagnose\",\n output: \"Ausgabe\",\n prompt: \"Prompt\",\n reasoning: \"Reasoning\",\n reject: \"Ablehnen\",\n sessionCost: \"Sitzungskosten\",\n sessionUsage: \"Sitzungsnutzung\",\n topToolsUsage: \"Top-Tools\",\n unknownKind: \"Unbekannt\",\n memoryUser: \"Benutzer\",\n memoryFeedback: \"Feedback\",\n memoryProject: \"Projekt\",\n memoryReference: \"Referenz\",\n },\n jobs: {\n ...en.jobs,\n empty: \"Keine Hintergrund-Jobs\",\n exited: \"Beendet\",\n kbClose: \"Schließen\",\n kbToggle: \"Umschalten\",\n running: \"Läuft\",\n stop: \"Stopp\",\n stopAll: \"Alle stoppen\",\n stopAllTip: \"Alle Jobs stoppen\",\n stopOne: \"Stopp\",\n title: \"Hintergrund-Jobs\",\n },\n live: {\n ...en.live,\n deliveredWaiting: \"Warte auf nächste Nachricht\",\n reasoning: \"Reasoning\",\n running: \"Läuft\",\n secondsAgo: \"vor {n}s\",\n you: \"Du\",\n },\n markdown: {\n ...en.markdown,\n copied: \"Kopiert!\",\n copy: \"Kopieren\",\n externalLinkTitle: \"In neuem Tab öffnen\",\n filePillTitle: \"Datei öffnen\",\n localLinkTitle: \"Link öffnen\",\n },\n palette: {\n ...en.palette,\n abort: \"Abbrechen\",\n abortHint: \"Aktuelle Anfrage abbrechen\",\n about: \"Über\",\n clearChat: \"Chat leeren\",\n clearChatHint: \"Unterhaltung leeren\",\n closeTab: \"Tab schließen\",\n closeTabHint: \"Aktuellen Tab schließen\",\n copyConv: \"Unterhaltung kopieren\",\n copyConvHint: \"Unterhaltung als Markdown kopieren\",\n copyLast: \"Letzte Antwort kopieren\",\n copyLastHint: \"Letzte Assistentennachricht kopieren\",\n countSuffix: \"Einträge\",\n empty: \"Keine passenden Befehle\",\n exportMd: \"Als Markdown exportieren\",\n exportMdHint: \"Chat als Markdown-Datei exportieren\",\n focusComposer: \"Composer fokussieren\",\n footClose: \"Schließen\",\n footMove: \"Bewegen\",\n footRun: \"Ausführen\",\n groupAction: \"Aktionen\",\n groupNav: \"Navigation\",\n groupSettings: \"Einstellungen\",\n groupWorkspace: \"Arbeitsbereich\",\n newChat: \"Neuer Chat\",\n newChatHint: \"Neues Gespräch beginnen\",\n newTab: \"Neuer Tab\",\n newTabHint: \"Neuen Tab öffnen\",\n pickWorkspace: \"Arbeitsbereich wechseln\",\n pickWorkspaceHint: \"Arbeitsbereich ändern\",\n searchPlaceholder: \"Befehle suchen…\",\n settings: \"Einstellungen\",\n settingsHint: \"Einstellungen öffnen\",\n },\n panel: {\n ...en.panel,\n renderError: \"Panel abgestürzt\",\n },\n sidebarPanel: {\n ...en.sidebarPanel,\n approvalRules: \"Genehmigungsregeln\",\n cancel: \"Abbrechen\",\n commandPalette: \"Befehlsübersicht\",\n daysAgo: \"vor {n}T\",\n delete: \"Löschen\",\n deleteSession: \"Sitzung löschen\",\n hoursAgo: \"vor {n}h\",\n justNow: \"Gerade eben\",\n loading: \"Lade…\",\n messageCount: \"{count} Nachrichten\",\n minutesAgo: \"vor {n}m\",\n newChat: \"Neuer Chat\",\n noMatches: \"Keine Treffer\",\n noSessions: \"Keine Sitzungen\",\n recent: \"Letzte\",\n searchSessions: \"Sitzungen durchsuchen…\",\n sessionTitle: \"Sitzungen\",\n settings: \"Einstellungen\",\n weeksAgo: \"vor {n}W\",\n },\n statusbar: {\n ...en.statusbar,\n balance: \"Guthaben\",\n busy: \"Beschäftigt\",\n cache: \"Cache\",\n cacheHit: \"Cache-Treffer\",\n jobs: \"Jobs\",\n jobsTip: \"Hintergrund-Jobs\",\n offline: \"Offline\",\n online: \"Online\",\n switchCurrency: \"Währung wechseln\",\n switchTheme: \"Theme wechseln\",\n switchWorkspace: \"Arbeitsbereich wechseln\",\n themeDark: \"Dunkel\",\n themeLight: \"Hell\",\n themeStyleGraphite: \"Graphit\",\n themeStyleSandstone: \"Sandstein\",\n themeStylePorcelain: \"Porzellan\",\n themeStyleMidnight: \"Mitternacht\",\n thisTurn: \"Dieser Turn\",\n tokens: \"Tokens\",\n },\n thread: {\n ...en.thread,\n activePlan: \"Aktiver Plan\",\n allowRead: \"Lesen erlauben\",\n allowWrite: \"Schreiben erlauben\",\n alwaysAllow: \"Immer erlauben\",\n alwaysAllowPrefix: \"{prefix} immer erlauben\",\n approve: \"Genehmigen\",\n approveRewrite: \"Neuschreibung genehmigen\",\n cancel: \"Abbrechen\",\n checkpointKind: \"Checkpoint\",\n checkpointSub: \"Aktuellen Zustand speichern\",\n checkpointTitle: \"Checkpoint erstellen\",\n collapse: \"Einklappen\",\n continue: \"Fortsetzen\",\n copyMessage: \"Nachricht kopieren\",\n copyResponse: \"Antwort kopieren\",\n execute: \"Ausführen\",\n keepOriginal: \"Original behalten\",\n keepSteps: \"Schritte behalten\",\n optionCount: \"{count} Optionen\",\n pathAccessKind: \"Pfadzugriff\",\n planConfirmationKind: \"Plan-Genehmigung\",\n planRevisionKind: \"Plan-Überarbeitung\",\n planRunning: \"Plan in Bearbeitung\",\n planStepCount: \"Schritt {done}/{total}\",\n readPathOutsideSandbox: \"Pfad außerhalb des Sandbox lesen\",\n refine: \"Verfeinern\",\n reject: \"Ablehnen\",\n revise: \"Überarbeiten\",\n revisionMeta: \"Überarbeitung\",\n rewritePlan: \"Plan umschreiben\",\n risk: \"Risikobewertung\",\n riskMedium: \"Mittleres Risiko\",\n runBackgroundCommand: \"Im Hintergrund ausführen\",\n runCommand: \"Befehl ausführen\",\n shellConfirmationKind: \"Shell-Bestätigung\",\n startPlan: \"Plan starten\",\n stop: \"Stopp\",\n subagent: \"Subagent\",\n userChoiceKind: \"Benutzerauswahl\",\n writePathOutsideSandbox: \"Pfad außerhalb des Sandbox schreiben\",\n you: \"Du\",\n },\n workdir: {\n ...en.workdir,\n browse: \"Durchsuchen…\",\n cancel: \"Abbrechen\",\n empty: \"Keine Arbeitsbereiche\",\n emptyDir: \"Keine Unterverzeichnisse.\",\n go: \"Gehe zu\",\n goTip: \"Zu diesem Pfad navigieren\",\n loading: \"Lade…\",\n openHere: \"Diesen Ordner öffnen\",\n pathPlaceholder: \"Absoluter Pfad…\",\n promptWeb: \"Absoluten Pfad des zu öffnenden Arbeitsbereichs eingeben:\",\n searchPlaceholder: \"Arbeitsbereiche durchsuchen…\",\n title: \"Arbeitsbereich\",\n },\n about: {\n ...en.about,\n close: \"Schließen\",\n repo: \"Repository\",\n sidebarLabel: \"Über\",\n tagline: \"KI-gestützter Coding-Assistent\",\n version: \"Version\",\n },\n effort: {\n ...en.effort,\n lowDesc: \"am schnellsten — minimales Reasoning\",\n mediumDesc: \"ausgewogen\",\n highDesc: \"Standard — sicher für vLLM / Azure\",\n maxDesc: \"DeepSeek-Erweiterung; von stock OpenAI / vLLM abgelehnt\",\n },\n editMode: {\n ...en.editMode,\n plan: \"Plan\",\n planHint: \"schreibgeschützt · alle Schreibwerkzeuge verweigern die Ausführung\",\n review: \"Überprüfen\",\n reviewHint: \"sowohl Edits als auch nicht-allowlistete Shell fragen zuerst\",\n auto: \"Auto\",\n autoHint: \"Edits auto-anwenden, Shell fragt weiterhin\",\n yolo: \"YOLO\",\n yoloHint: \"Edits UND Shell auto-ausführen, Allowlist umgangen\",\n },\n};\n","export const zhCN = {\n app: {\n sectionWorkspace: \"工作区\",\n sectionObserve: \"监控\",\n sectionConfigure: \"配置\",\n tabChat: \"对话\",\n tabPlans: \"计划\",\n tabSessions: \"会话\",\n tabOverview: \"概览\",\n tabUsage: \"用量\",\n tabSystem: \"系统\",\n tabSemantic: \"语义\",\n tabTools: \"工具\",\n tabPermissions: \"权限\",\n tabMcp: \"MCP\",\n tabSkills: \"技能\",\n tabMemory: \"记忆\",\n tabHooks: \"钩子\",\n tabSettings: \"设置\",\n sectionChanges: \"变更\",\n tabChanges: \"变更\",\n footer: \"仅 127.0.0.1 · Token 保护\",\n themeToggle: \"切换主题\",\n themeLight: \"浅色\",\n themeDark: \"深色\",\n skill: {\n scope: {\n builtin: \"内置\",\n global: \"全局\",\n project: \"项目\",\n },\n runAs: {\n subagent: \"子代理\",\n inline: \"内联\",\n },\n generic: \"技能\",\n },\n exportReasoningSummary: \"推理摘要\",\n exportToolLabel: \"工具调用\",\n exportUserLabel: \"用户消息\",\n empty: {\n currentWorkspace: \"当前工作区\",\n selectWorkspace: \"选择一个工作区开始\",\n suggestion0: \"开始新对话\",\n suggestion1: \"打开设置\",\n suggestion2: \"查看概览\",\n suggestion3: \"浏览会话\",\n welcome: \"欢迎使用 Reasonix\",\n },\n errorLabel: \"错误\",\n connecting: \"连接中…\",\n session: {\n format: \"会话\",\n new: \"新建会话\",\n },\n setup: {\n choose: \"选择工作区\",\n description: \"选择一个工作区开始工作\",\n notSelected: \"未选择工作区\",\n saveAndStart: \"保存并开始\",\n welcome: \"欢迎\",\n workspace: \"工作区\",\n },\n tab: {\n newTab: \"+ 新建标签\",\n newTabTitle: \"打开新标签\",\n },\n titlebar: {\n clearChat: \"清除对话\",\n close: \"关闭\",\n commandPalette: \"命令面板\",\n contextPanel: \"上下文面板\",\n copyMd: \"复制为 Markdown\",\n exportMd: \"导出为 Markdown\",\n maximize: \"最大化\",\n minimize: \"最小化\",\n more: \"更多\",\n restore: \"还原\",\n settings: \"设置\",\n sidebar: \"侧边栏\",\n windowControls: \"窗口控制\",\n },\n toast: {\n cleared: \"对话已清除\",\n copied: \"已复制到剪贴板\",\n copiedMd: \"已复制为 Markdown\",\n emptySession: \"无消息可导出\",\n exportDialogTitle: \"导出对话\",\n exportedMd: \"已导出为 Markdown\",\n exportFailed: \"导出失败\",\n langSwitched: \"语言已切换\",\n modelSwitched: \"模型 → {model}\",\n effortSwitched: \"强度 → {effort}\",\n modeSwitched: \"模式已切换\",\n newSession: \"新会话已创建\",\n },\n yolo: {\n toast: \"YOLO 模式已启用\",\n },\n cmd: {\n abort: \"中止\",\n btw: \"顺便说一下\",\n clearChat: \"清除对话\",\n compact: \"紧凑\",\n copyLast: \"复制上条\",\n exportMd: \"导出为 Markdown\",\n feedback: \"反馈\",\n help: \"帮助\",\n newSession: \"新建会话\",\n retry: \"重试\",\n switchModel: \"切换模型\",\n toggleCurrency: \"切换货币\",\n toggleLang: \"切换语言\",\n toggleTheme: \"切换主题\",\n },\n header: {\n abort: \"中止\",\n clickToSelect: \"点击选择\",\n copy: \"复制\",\n copyMd: \"复制为 Markdown\",\n export: \"导出\",\n exportMd: \"导出为 Markdown\",\n newChat: \"新建对话\",\n noWorkspace: \"无工作区\",\n running: \"运行中…\",\n },\n jumpToBottom: \"跳到底部\",\n langEN: \"English\",\n langZH: \"中文\",\n splashSubtitle: \"AI 驱动的编程助手\",\n },\n changes: {\n chatPlaceholder: \"询问代码问题…\",\n chatWelcome: \"变更 — 询问项目文件相关问题。\",\n chatSend: \"发送\",\n viewerPlaceholder: \"选择一个文件查看\",\n treeEmpty: \"(空)\",\n tabClose: \"关闭标签\",\n newConversation: \"新建\",\n clearConversation: \"清除\",\n newTitle: \"/new — 清除对话上下文\",\n clearTitle: \"/clear — 仅清除可见的滚动回放\",\n newConfirmBusy: \"有轮次正在执行。中止并开始新对话?\",\n newConfirm: \"清除当前对话并重新开始?\",\n newToast: \"新对话\",\n clearToast: \"滚动回放已清除\",\n newFailed: \"/new 失败:{error}\",\n clearFailed: \"/clear 失败:{error}\",\n chatSendBtn: \"发送\",\n fileTreeTitle: \"文件\",\n codeViewerTitle: \"代码查看器\",\n chatPanelTitle: \"对话\",\n loadingFiles: \"正在加载项目文件…\",\n review: \"审查\",\n allFiles: \"所有文件\",\n changes: \"更改\",\n commentLabel: \"正在评论 第\",\n commentPlaceholder: \"添加评论…\",\n commentCancel: \"取消\",\n commentSubmit: \"评论\",\n commentLine: \"第\",\n commentEdit: \"编辑\",\n commentDelete: \"删除\",\n diffSourceGit: \"Git 变更\",\n diffSourceSession: \"上一轮变更\",\n diffSourceCheckpoint: \"检查点\",\n checkpointEmpty: \"暂无检查点\",\n restoreBtn: \"恢复\",\n restoreConfirm: '确定要恢复检查点\"{name}\"吗?当前更改将被覆盖。',\n deleteBtn: \"删除\",\n deleteConfirm: '确定要删除检查点\"{name}\"吗?',\n createBtn: \"创建\",\n createPlaceholder: \"检查点名称…\",\n backToList: \"返回列表\",\n reviewEmpty: \"暂无可审查的更改\",\n diffStyleUnified: \"统一视图\",\n diffStyleSplit: \"分栏视图\",\n expandAll: \"全部展开\",\n collapseAll: \"全部折叠\",\n createFailed: \"创建失败\",\n restoreFailed: \"恢复失败\",\n deleteFailed: \"删除失败\",\n },\n common: {\n loading: \"加载中…\",\n loadingFailed: \"{name}失败:{error}\",\n back: \"← 返回\",\n save: \"保存\",\n remove: \"移除\",\n cancel: \"取消\",\n delete: \"删除\",\n add: \"添加\",\n confirm: \"确认\",\n noData: \"暂无{name}。\",\n all: \"全部\",\n yes: \"是\",\n no: \"否\",\n on: \"开启\",\n off: \"关闭\",\n enabled: \"已启用\",\n disabled: \"已禁用\",\n },\n settings: {\n title: \"设置\",\n loading: \"加载设置…\",\n saved: \"已保存:{fields}\",\n sectionApi: \"DeepSeek API\",\n apiKey: \"API 密钥\",\n apiKeyNotSet: \"未设置\",\n apiKeySave: \"保存密钥\",\n apiKeySet: \"已设置\",\n apiSection: \"API 配置\",\n notSet: \"(未设置)\",\n replace: \"替换\",\n pasteKey: \"粘贴新的 sk-… 令牌\",\n saveKey: \"保存密钥\",\n baseUrl: \"基础 URL\",\n baseUrlPlaceholder: \"https://api.deepseek.com(默认)\",\n baseUrlHint: \"API 请求的基础 URL\",\n sectionDefaults: \"默认设置\",\n effortSection: \"推理强度\",\n modelCustom: \"自定义模型 ID\",\n modelCustomHint: \"任何 OpenAI 兼容的 ID(vLLM、Ollama、Together …)。\",\n modelCustomActive: \"当前运行自定义 ID:{model}\",\n appliesNextTurn: \"下一轮生效\",\n effort: \"推理强度\",\n effortMax: \"max(DeepSeek 扩展 — 标准 OpenAI / vLLM 会拒绝)\",\n effortHigh: \"high(安全默认 — vLLM / Azure 兼容)\",\n effortMedium: \"medium\",\n effortLow: \"low(最快)\",\n webSearch: \"网页搜索\",\n webSearchNote: \"web_fetch + web_search 工具\",\n webSearchEngine: \"搜索引擎\",\n webSearchEngineBing: \"bing — 默认,国内裸 IP 直连,无需代理\",\n webSearchEngineSearxng: \"searxng — 自托管(端点用 /se searxng <url> 配置)\",\n webSearchEngineMetaso: \"metaso — 每日 100 次免费(国内友好,metaso.cn 可领免费 key)\",\n webSearchEngineTavily: \"tavily — 每月 1000 次免费(设置 TAVILY_API_KEY)\",\n webSearchEnginePerplexity: \"perplexity — AI 直接回答(设置 PERPLEXITY_API_KEY)\",\n webSearchEngineExa: \"exa — AI 直接回答,每月 1000 次免费(设置 EXA_API_KEY)\",\n webSearchEngineNote: \"下一次 web_search 调用生效\",\n sectionBudget: \"预算\",\n budget: \"预算\",\n budgetHint: \"设置支出限额\",\n budgetPlaceholder: \"输入预算金额\",\n budgetOf: \"/\",\n budgetSetCap: \"设置上限\",\n budgetCustom: \"自定义\",\n budgetBumpHint: \"提高上限以继续\",\n budgetClear: \"清除上限\",\n budgetIdleLine: \"80% 时提醒 · 100% 后拒绝执行\",\n budgetWarnLine: \"接近上限 — 超过 100% 将拒绝执行\",\n budgetRefusing: \"已超出上限 — 提高或清除后才会继续\",\n sectionLoop: \"循环\",\n loopIdleHint: \"按固定间隔自动重新提交一段提示词。\",\n loopCostHint: \"每次迭代约 {cost}(上一轮成本)。\",\n loopInterval: \"间隔\",\n loopCustom: \"自定义\",\n loopRangeError: \"间隔需在 5s..6h 之间\",\n loopPrompt: \"提示词\",\n loopPromptPlaceholder: \"例如:检查部署状态并汇报任何错误\",\n loopStart: \"启动循环\",\n loopStop: \"停止\",\n loopRunning: \"运行中\",\n loopIter: \"第 {iter} 次\",\n loopFiresIn: \"{remaining} 后触发\",\n sectionSkills: \"技能\",\n skillPaths: \"技能路径\",\n skillPathsPlaceholder: \"/path/to/skills-a, /path/to/skills-b\",\n skillPathsNote: \"英文逗号分隔 · 下次 /new 或新会话生效\",\n skillsEmpty: \"无已加载技能\",\n skillsLoaded: \"技能已加载\",\n subagentModelFlash: \"flash\",\n subagentModelPro: \"pro\",\n subagentModelHint: \"技能派生独立 subagent 时使用的模型\",\n sectionRuntime: \"运行时\",\n activeModel: \"当前模型\",\n model: \"模型\",\n modelFlashDesc: \"Flash — 始终 flash\",\n modelProDesc: \"Pro — 始终 pro\",\n modelPricingLine: \"${hit} 命中 · ${miss} 未命中 · ${out} 输出 / 100 万 tok\",\n editMode: \"编辑模式\",\n editModeNote: \"在对话标签页头部切换\",\n editModeHint: \"配置编辑模式\",\n showSystemEvents: \"系统事件\",\n showSystemEventsHint: \"在对话流中以细线显示压缩 / 中断 / 限速等系统事件\",\n shown: \"显示\",\n hidden: \"隐藏\",\n appMode: \"应用模式\",\n sectionLanguage: \"语言\",\n language: \"语言\",\n languageHint: \"切换语言\",\n langEn: \"English\",\n langZhCn: \"简体中文\",\n appearanceSection: \"外观\",\n behaviorSection: \"行为\",\n ruleAutoApprovalHint: \"配置自动审批规则\",\n ruleAutoApprovalSection: \"自动审批规则\",\n theme: \"主题\",\n themeDark: \"深色\",\n themeHint: \"在浅色和深色主题之间切换\",\n themeLight: \"浅色\",\n themeStyle: \"主题风格\",\n themeStyleHint: \"选择主题风格\",\n themeStyleGraphite: \"石墨\",\n themeStyleGraphiteDesc: \"冷色深色调,适合长时间使用。\",\n themeStyleSandstone: \"砂岩\",\n themeStyleSandstoneDesc: \"暖色浅色调,明亮环境更舒适。\",\n themeStylePorcelain: \"瓷白\",\n themeStylePorcelainDesc: \"高对比度浅色,简洁清爽。\",\n themeStyleMidnight: \"午夜\",\n themeStyleMidnightDesc: \"深色配冷色高光,更深邃。\",\n pageGeneralLabel: \"通用\",\n pageGeneralDesc: \"主题、字体、语言与工作目录。\",\n pageModelsLabel: \"模型\",\n pageModelsDesc: \"默认模型与推理强度。\",\n pageMcpLabel: \"MCP 服务器\",\n pageMcpDesc: \"接入外部工具服务器。\",\n pageSkillsLabel: \"技能\",\n pageSkillsDesc: \"可通过 /skill 调用的自定义技能。\",\n pageMemoryLabel: \"记忆\",\n pageMemoryDesc: \"跨会话保留的长期笔记。\",\n pageRulesLabel: \"规则\",\n pageRulesDesc: \"Shell 与路径访问的自动审批规则。\",\n pageBillingLabel: \"账单\",\n pageBillingDesc: \"API key、余额与会话预算。\",\n pageShortcutsLabel: \"快捷键\",\n pageShortcutsDesc: \"键盘快捷键参考。\",\n fontFamily: \"字体\",\n fontFamilyHint: \"选择字体\",\n fontFamilySans: \"无衬线\",\n fontFamilySerif: \"衬线\",\n fontFamilySystem: \"系统\",\n fontScale: \"字体大小\",\n fontScaleHint: \"调整字体大小\",\n fontScaleLarge: \"大\",\n fontScaleMedium: \"中\",\n fontScaleSmall: \"小\",\n currentWorkspace: \"当前工作区\",\n defaultModelCurrent: \"当前模型\",\n editor: \"编辑器\",\n editorHint: \"配置编辑器偏好\",\n maxOutput: \"最大输出\",\n reasoningEffort: \"推理强度\",\n reasoningEffortHint: \"调整推理深度\",\n sessionCost: \"会话成本\",\n balanceAvailable: \"可用\",\n balanceLabel: \"余额\",\n balanceLow: \"余额不足\",\n cacheHitRate: \"缓存命中率\",\n ctxWindow: \"上下文窗口\",\n notSelected: \"未选择\",\n parseError: \"解析错误\",\n workspaceChange: \"更改\",\n workspaceSection: \"工作区\",\n mcpAdd: \"添加\",\n mcpAddSection: \"添加 MCP 服务器\",\n mcpBridged: \"已桥接\",\n mcpConfigured: \"已配置\",\n mcpEmpty: \"无 MCP 服务器\",\n mcpNotBridged: \"未桥接\",\n mcpRemove: \"移除\",\n mcpSpecFormat: \"JSON 格式\",\n mcpSpecLabel: \"服务器规格\",\n memoryDesc: \"配置记忆设置\",\n memorySection: \"记忆\",\n shortcutAbort: \"中止\",\n shortcutCloseTab: \"关闭标签\",\n shortcutCommandPalette: \"命令面板\",\n shortcutFocusComposer: \"聚焦编辑器\",\n shortcutNewChat: \"新建对话\",\n shortcutNewTab: \"新建标签\",\n shortcutSettings: \"设置\",\n shortcutSwitchTab: \"切换标签\",\n qqAccessAllowlist: \"允许列表\",\n qqAccessOpen: \"开放\",\n qqAccessOwner: \"所有者\",\n qqAccessOwnerWithAllowlist: \"所有者 + 允许列表\",\n qqAccessRuntime: \"运行时\",\n qqAppId: \"App ID\",\n qqApplyAction: \"应用\",\n qqApplyLabel: \"应用\",\n qqAppSecret: \"App Secret\",\n qqBack: \"返回\",\n qqConfigure: \"配置\",\n qqConfigureHint: \"设置 QQ 集成\",\n qqConfigureTitle: \"QQ 配置\",\n qqConnected: \"已连接\",\n qqConnecting: \"连接中…\",\n qqDisconnected: \"已断开\",\n qqEnvironment: \"环境\",\n qqFailed: \"失败\",\n qqProduction: \"生产环境\",\n qqSandbox: \"沙箱环境\",\n qqSave: \"保存\",\n qqSaveAndConnect: \"保存并连接\",\n qqSection: \"QQ 集成\",\n qqSummaryAppId: \"App ID\",\n qqSummaryDetail: \"详情\",\n qqSummaryMissing: \"未配置\",\n qqTitle: \"QQ 机器人\",\n },\n chat: {\n modeMirror: \"TUI 镜像\",\n modeView: \"会话视图\",\n placeholder: \"输入提示词 — Enter 发送,Shift+Enter 换行 · / @ 打开选择器\",\n placeholderBusy: \"请等待当前轮次完成…\",\n placeholderSteerBusy: \"输入消息以引导当前任务 — 忙碌时不支持命令和选择器\",\n steerHint: \"消息将作为附加指示引导当前轮次\",\n send: \"发送\",\n new: \"新建\",\n clear: \"清除\",\n newTitle: \"/new — 清除对话上下文(循环日志 + 滚动回放)\",\n clearTitle: \"/clear — 仅清除可见的滚动回放(上下文保留)\",\n noConversation: \"暂无对话。在下方发送提示词开始。\",\n newConfirmBusy: \"有轮次正在执行。中止并开始新对话?\",\n newConfirm: \"清除当前对话并重新开始?\",\n newToast: \"新对话\",\n clearToast: \"滚动回放已清除\",\n newFailed: \"/new 失败:{error}\",\n clearFailed: \"/clear 失败:{error}\",\n eventStreamError: \"事件流中断 — 正在重连…\",\n semanticBanner: \"此项目未启用语义搜索。\",\n semanticBannerDesc:\n \"构建一次索引,模型即可按含义查找代码(\\u201C哪里处理认证失败?\\u201D),而不仅依赖精确字符串的 grep。\",\n semanticBannerBtn: \"构建 →\",\n semanticBannerDismiss: \"关闭(不再显示)\",\n slashCommands: \"斜杠命令\",\n projectFiles: \"项目文件\",\n effortTitle: \"reasoning_effort — 下一轮生效\",\n effortMaxTitle: \"max(DeepSeek 扩展)\",\n effortHighTitle: \"high(安全默认 — vLLM / Azure 兼容)\",\n effortMediumTitle: \"medium\",\n effortLowTitle: \"low(最快)\",\n editGateTitle: \"编辑门控 — Shift+Tab 在 TUI 中循环\",\n editReviewTitle: \"review — 编辑和非允许列表的 shell 命令都会先询问\",\n editAutoTitle: \"auto — 编辑自动应用,shell 仍会询问\",\n editYoloTitle: \"yolo — 编辑和 shell 都自动运行,绕过允许列表\",\n railSession: \"会话\",\n railTurns: \"轮次\",\n railPromptTok: \"提示 tokens\",\n railCost: \"费用\",\n railCacheHit: \"缓存命中\",\n railToolBudget: \"工具预算\",\n railSpend: \"已用\",\n railActivePlan: \"活跃计划\",\n railProgress: \"进度\",\n statusModel: \"模型\",\n statusCtx: \"上下文\",\n statusCache: \"缓存\",\n statusTurn: \"轮次\",\n statusSession: \"会话\",\n statusBalance: \"余额\",\n statusTurns: \"{count} 轮\",\n waitingStats: \"· · · 等待实时统计\",\n inflightPhase: \"{phase}\",\n inflightRunning: \"运行中\",\n inflightThinking: \"思考中\",\n inflightStreaming: \"输出中\",\n inflightWaiting: \"等待中\",\n inflightReasoning: \"推理 {count} 字符\",\n inflightOut: \"输出 {count} 字符\",\n abortBtn: \"中止 (Esc)\",\n confirmBtn: \"应用 (y)\",\n rejectBtn: \"拒绝 (n)\",\n applyRestBtn: \"应用剩余 (a)\",\n flipAutoBtn: \"切换为 AUTO (A)\",\n },\n overview: {\n loading: \"加载概览…\",\n failed: \"概览失败:{error}\",\n standaloneTitle: \"独立模式\",\n standaloneDesc:\n \"只读磁盘视图。在 reasonix code 内启动 /dashboard 以获取实时会话状态、MCP 和工具。\",\n cockpit: \"驾驶舱\",\n balance: \"余额\",\n tokens7d: \"tokens · 7 天\",\n cacheHit: \"缓存命中\",\n toolCalls24h: \"工具调用 · 24 小时\",\n budget: \"预算\",\n currentSession: \"当前会话\",\n noSession: \"无活跃会话 — 在 reasonix code 内执行 /dashboard 进行连接。\",\n promptTok: \"提示 tokens\",\n completionTok: \"补全 tokens\",\n cost: \"费用\",\n costTrend: \"费用 · 14 天\",\n noUsageYet: \"暂无用量\",\n dayAvg: \"/天 均值\",\n recentPlans: \"近期计划\",\n noPlans: \"暂无计划 — 使用 submit_plan 提交一个。\",\n toolActivity: \"工具活动\",\n noToolCalls: \"暂无工具调用。\",\n toolsLoaded: \"已加载工具\",\n mcpServers: \"MCP 服务器\",\n editMode: \"编辑模式\",\n version: \"Reasonix\",\n workingDir: \"工作目录\",\n projectRoot: \"项目根目录\",\n noPriorData: \"无历史数据\",\n stable: \"— 稳定\",\n vsPrior: \"{arrow} {pct}% 较上期\",\n active: \"活跃\",\n allUp: \"全部在线\",\n yoloWarning: \"所有提示被绕过\",\n checking: \"检查中\",\n latest: \"最新\",\n },\n usage: {\n loading: \"加载用量…\",\n failed: \"用量失败:{error}\",\n records: \"{count} 条记录\",\n dailyUsage: \"每日用量\",\n dailyMeta: \"费用 · 缓存节省 · 轮次\",\n noData: \"暂无用量数据 — 在 reasonix chat / code / run 中执行一轮,然后刷新。\",\n windows: \"滚动窗口\",\n colWindow: \"时间范围\",\n colTurns: \"轮次\",\n colCacheHit: \"缓存命中\",\n colCost: \"费用 (USD)\",\n colCacheSaved: \"缓存节省\",\n colVsClaude: \"对比 Claude\",\n colSaved: \"节省\",\n axisTime: \"时间\",\n axisUsd: \"美元\",\n axisTurns: \"轮次\",\n seriesCost: \"费用\",\n seriesCacheSaved: \"缓存节省\",\n seriesTurns: \"轮次\",\n mostUsed: \"最常用模型\",\n colModel: \"模型\",\n },\n sessions: {\n loading: \"加载会话…\",\n failed: \"会话失败:{error}\",\n noSessions: \"暂无已保存的会话。\",\n filterPlaceholder: \"筛选会话\",\n msgs: \"条消息\",\n pickHint: \"选择左侧的会话以查看其转录稿。\",\n resumeTitle: \"在 TUI 中恢复\",\n resumeDesc: \"会话中途切换需要重启,以便消息日志可以干净地回退。请退出当前会话,然后运行:\",\n loadingTranscript: \"加载转录稿…\",\n emptyTranscript: \"空的转录稿。\",\n messages: \"{count} 条消息\",\n newBtn: \"新建会话\",\n newHint: \"归档当前会话并开启新会话\",\n switchBtn: \"切换到此会话\",\n deleteBtn: \"删除\",\n deleteConfirm: \"确定删除会话「{name}」?转录文件将被移除,无法撤销。\",\n cantDeleteActive: \"请先切换到其他会话,再删除当前会话。\",\n attachRequired:\n \"实时会话操作需要已连接的 CLI 会话。请通过 reasonix chat 启动,或在 TUI 会话中打开仪表盘。\",\n activeChip: \"当前\",\n activePill: \"当前\",\n },\n tools: {\n loading: \"加载工具…\",\n failed: \"工具失败:{error}\",\n noTools: \"未注册任何工具。\",\n planMode: \"计划模式 — 写入受限\",\n colTool: \"工具\",\n colFlags: \"标志\",\n colDesc: \"描述\",\n readOnly: \"只读\",\n write: \"写入\",\n flat: \"扁平\",\n desc: {\n web_search:\n \"搜索公共网络。返回带标题、URL 和摘要的排序结果。当答案的正确性依赖于当前状态时调用——事件、价格、发布、现实世界的状态。\",\n web_fetch:\n \"下载 URL 并返回其可见文本内容(已剥离脚本/样式/导航)。在 web_search 摘要不够时使用。\",\n run_command:\n \"在项目根目录执行 shell 命令,返回合并的标准输出和标准错误。白名单中的只读命令立即执行;可能修改状态的操作需用户确认。\",\n run_background:\n \"启动一个长时间运行的进程并分离。返回任务 ID 用于查看日志、等待完成或终止。用于开发服务器、文件监听器和一次性长时间任务。\",\n job_output: \"读取后台任务的最新输出。返回缓冲区末尾内容并告知任务是否仍在运行。\",\n wait_for_job: \"在服务端阻塞直到后台任务完成(有超时限制)。用于替代轮询 job_output。\",\n stop_job: \"停止后台任务。先发送 SIGTERM,宽限期后发送 SIGKILL。可安全调用已退出的任务。\",\n list_jobs: \"列出本次会话启动的所有后台任务——运行中和已退出的——包含 ID、命令、PID 和状态。\",\n remember:\n \"保存一条记忆供未来会话使用。当用户陈述偏好、纠正你的方法、分享非显而易见的事实或要求你记住某事时使用。\",\n forget:\n \"删除记忆文件并从 MEMORY.md 中移除。当用户要求忘记某事或之前记住的事实已不再正确时使用。\",\n recall_memory: \"当记忆文件的一行摘要不够详细时,读取其完整内容。\",\n read_file:\n \"读取沙箱根目录下的文件。支持 head/tail/range 范围读取以节省上下文。超过 200 行的文件自动返回预览。\",\n list_directory: \"列出目录中的条目。每行一个条目,目录以斜杠标记。\",\n directory_tree: \"递归列出目录中的条目,以缩进树形结构显示。对大子目录自动折叠以节省预算。\",\n search_files: \"根据名称匹配子串或正则表达式查找文件。不区分大小写。默认跳过依赖/构建目录。\",\n search_content:\n \"递归搜索文件内容中的子串或正则表达式。以 path:line:text 格式返回匹配结果。查找引用的正确工具。\",\n glob: \"按 glob 模式列出文件,按修改时间排序。默认限制 200,最大 1000。默认跳过 node_modules/.git/dist。\",\n get_file_info: \"获取沙箱根目录下路径的状态信息。返回类型、字节大小和修改时间。\",\n write_file: \"创建或覆盖文件,内容由参数指定。按需创建父目录。\",\n edit_file: \"对现有文件应用 SEARCH/REPLACE 编辑。搜索必须完全匹配且在文件中唯一。\",\n multi_edit:\n \"跨一个或多个文件原子性地应用 N 个 SEARCH/REPLACE 编辑。如果任何编辑失败,不写入任何文件。\",\n create_directory: \"在沙箱根目录下创建目录(以及任何缺失的父目录)。\",\n move_file: \"重命名或移动沙箱根目录下的文件或目录。\",\n delete_file: \"删除沙箱根目录下的一个文件。拒绝目录——请使用 delete_directory 删除目录。\",\n delete_directory: \"递归删除沙箱根目录下的目录。传入 recursive:false 可拒绝非空目录。\",\n copy_file: \"复制沙箱根目录下的文件或目录。拒绝覆盖已存在的目标。\",\n submit_plan:\n \"提交一个具体的计划以供审查审批。用于多文件重构、架构变更或任何撤销代价高昂的操作。\",\n mark_step_complete: \"将已批准计划的一个步骤标记为完成。完成每个步骤后恰好调用一次。\",\n revise_plan: \"外科手术式替换进行中计划的剩余步骤。已完成的步骤永远不会被触及。\",\n run_skill:\n \"从技能索引中调用一个 playbook。传入裸技能名称。标记为子代理的技能将启动独立的子代理。\",\n spawn_subagent: \"为一个独立子任务启动隔离的子代理。用于并行分发或需要大量文件读取的工作。\",\n todo_write: \"多步工作的会话内任务跟踪器。每次调用替换整个列表。无审批关卡,不写入文件。\",\n ask_choice: \"向用户展示 2-6 个选项。当用户要求选择或需要偏好决策时使用。\",\n create_skill: \"创建一个新技能,用户可通过 /skill 命令调用。支持内联和子代理两种运行模式。\",\n add_mcp_server:\n \"在用户配置中注册新的 MCP 服务器。下次会话生效。支持 stdio、SSE 和 streamable-http。\",\n },\n },\n permissions: {\n loading: \"加载权限…\",\n failed: \"权限失败:{error}\",\n yoloTitle: \"YOLO 模式\",\n yoloDesc: \"所有 shell 命令自动运行,允许列表被绕过。在 TUI 中使用 /mode review 切换回来。\",\n project: \"项目\",\n builtin: \"内置\",\n addPrefix: \"添加前缀\",\n addPlaceholder: '例如 \"npm run build\" 或 \"deploy.sh\"',\n clearAll: \"清除全部\",\n alreadyIn: \"{prefix} 已在列表中\",\n added: \"已添加:{prefix}\",\n removed: \"已移除:{prefix}\",\n cleared: \"已清除 {count} 条\",\n removeConfirm: '从此项目的允许列表中移除 \"{prefix}\"?',\n clearConfirm: \"清除所有项目允许列表条目?内置条目不受影响。\",\n projectAllowlist: \"项目允许列表 · {count}\",\n nothingStored: \"此项目暂无存储的条目。\",\n colNum: \"#\",\n colPrefix: \"前缀\",\n builtinTitle: \"内置 · {count} · 只读\",\n standaloneWarning:\n \"修改操作需要在活跃的 reasonix code 会话内执行 /dashboard — 独立模式的 reasonix dashboard 无法确定要编辑哪个项目的允许列表。\",\n },\n mcp: {\n loading: \"加载 MCP…\",\n servers: \"MCP 服务器 · {count} 个已桥接\",\n all: \"全部\",\n live: \"在线\",\n unbridged: \"未桥接\",\n specPlaceholder: \"规格 — 例如 fs=npx -y @modelcontextprotocol/...\",\n saved: \"已保存\",\n savedRestart: \"已保存 — 重启 reasonix code 以桥接此服务器\",\n removed: \"已移除 — 重启以断开实时桥接\",\n removeConfirm: \"从配置中移除 MCP 规格?\\n\\n{spec}\",\n noServers: \"此会话中无 MCP 服务器。\",\n tools: \"个工具\",\n inConfig: \"在配置中 · 未加载\",\n unbridgedTitle: \"未桥接 · 在配置中\",\n removeBtn: \"移除\",\n spec: \"规格\",\n whyUnbridged: \"为什么未桥接?\",\n whyUnbridgedDesc:\n \"此规格存在于您的 config.json 中,但未桥接到实时会话。MCP 服务器在 reasonix code 启动时连接;仪表盘本身无法生成子进程。\",\n whyUnbridgedHint: \"激活方法:重启 reasonix code,然后刷新此仪表盘。\",\n bridgeFailed: \"桥接失败\",\n bridgeFailedTitle: \"桥接失败 · 在配置中\",\n bridgeFailedHint:\n \"已尝试桥接但失败。常见原因:URL 错误、需要鉴权、上游 404 / 5xx、本地命令缺失。修复后重启 reasonix code 重试。\",\n pickHint: \"选择左侧的 MCP 服务器以检查工具 / 资源 / 提示。\",\n toolsTitle: \"工具 · {count}\",\n resourcesTitle: \"资源 · {count}\",\n promptsTitle: \"提示 · {count}\",\n colName: \"名称\",\n colDesc: \"描述\",\n colUri: \"URI\",\n marketplace: \"市场\",\n marketplaceSearch: \"搜索注册表…\",\n marketplaceLoading: \"加载注册表…\",\n marketplaceMore: \"再加载 5 页\",\n marketplaceMoreLabel: \"再加载 50 条 · 当前 {shown} / {total}\",\n marketplaceMoreHint: \"需要从远端注册表再拉几页\",\n marketplaceMoreCachedHint: \"本地缓存已有更多条目\",\n marketplaceExhausted: \"已加载全部页\",\n marketplaceExhaustedFull: \"已展示全部 {total} 条 — 注册表耗尽\",\n marketplaceCount: \"已载入 {loaded} · 匹配 {matched} · 来源:{source}{cached}\",\n marketplaceCachedSuffix: \" · 缓存中\",\n marketplaceNoMatches: \"无匹配结果。换关键词或加载更多页。\",\n marketplaceInstall: \"安装\",\n marketplacePickHint: \"在左侧选择服务器,然后点安装。\",\n marketplaceInstalled: \"已安装 → {spec}\",\n marketplaceInstalledBridged: \"已安装并桥接 → {spec}\",\n marketplaceAlready: \"已安装过\",\n marketplaceNeedsEnv: \"需设置环境变量:{names}\",\n marketplaceSourceTag: \"[{source}]\",\n marketplaceNoInstall:\n \"Smithery 列表项 — 不暴露安装元数据;请直接 `npx -y @smithery/cli install {name}`\",\n marketplaceFetchOnInstall:\n \"Smithery 列表 — 安装时再拉详情。HTTP 服务映射为 streamable-http 远端;stdio 服务通过 @smithery/cli 运行。\",\n marketplaceInstalledBadge: \"已安装\",\n marketplaceUninstall: \"卸载\",\n marketplaceEnvTitle: \"必需的环境变量\",\n marketplaceEnvHint: \"下次启动 `reasonix code` 之前在 shell 里设好,桥接的服务器才能正常鉴权。\",\n marketplaceRestartHint:\n \"已写入 ~/.reasonix/config.json。重启 `reasonix code` 后服务器才会真正桥接(热重载在路线图上)。\",\n },\n memory: {\n loading: \"加载记忆…\",\n files: \"记忆 · {count} 个文件\",\n exists: \"已存在\",\n create: \"创建\",\n noFiles: \"暂无记忆文件。\",\n pickHint: \"选择左侧的记忆文件。\",\n pickDesc: \"项目 REASONIX.md 可提交;全局笔记存储在 ~/.reasonix/memory/。\",\n chars: \"{count} 个字符\",\n saved: \"已保存 {scope}\",\n reloadHint: \"在下次 /new 或会话重启时重新加载\",\n },\n hooks: {\n loading: \"加载钩子…\",\n resolved: \"已解析\",\n eventMatrix: \"事件矩阵\",\n matrixSub: \"{scripts} 个脚本 × {events} 个事件\",\n noHooks: \"未配置钩子。编辑下方的 JSON 以添加。\",\n colScript: \"脚本\",\n noProject: \"无活跃项目 — 在 reasonix code 中打开 /dashboard 以编辑项目钩子。\",\n saveReload: \"保存并重载\",\n discard: \"放弃更改\",\n savedReloaded: \"已保存并重载 {scope}\",\n recentRuns: \"近期运行\",\n noRuns: \"近期会话日志中无钩子运行记录。\",\n colWhen: \"时间\",\n colPhase: \"阶段\",\n colHook: \"钩子\",\n colOutcome: \"结果\",\n },\n skills: {\n loading: \"加载技能…\",\n filterPlaceholder: \"筛选技能\",\n project: \"项目\",\n custom: \"自定义\",\n global: \"全局\",\n builtin: \"内置\",\n newSkill: \"新技能\",\n noDescription: \"(无描述)\",\n runs7d: \"次运行 · 7 天\",\n pickHint: \"选择左侧的技能,或在上方创建新技能。\",\n readOnlyBuiltin: \"只读 · 内置\",\n readOnlyCustom: \"只读 · 自定义路径\",\n builtinDesc:\n \"内置技能随 Reasonix 一起发布;模型会自动识别。如需自定义,请创建同名的项目或全局技能。\",\n saved: \"已保存 {scope}/{name}\",\n deleteConfirm: \"删除技能 {scope}/{name}?\",\n reloadHint: \"在下次 /new 或会话重启时重新加载\",\n },\n system: {\n loading: \"加载健康状态…\",\n failed: \"健康检查失败:{error}\",\n healthChecks: \"健康检查\",\n version: \"版本\",\n checking: \"检查中\",\n latest: \"● 最新\",\n outOfDate: \"● 需要更新\",\n versionPending: \"版本检查中\",\n upToDate: \"已是最新\",\n latestVer: \"最新:{version}\",\n sessions: \"会话\",\n ok: \"● 正常\",\n memory: \"记忆\",\n semanticIndex: \"语义索引\",\n built: \"● 已构建\",\n none: \"— 无\",\n runIndex: \"运行 reasonix index 以构建\",\n usageLog: \"用量日志\",\n backgroundJobs: \"后台任务\",\n noSession: \"— 无会话\",\n running: \"{count} 个运行中\",\n attachHint: \"连接会话以查看任务\",\n shellSpawn: \"Shell + 生成\",\n paths: \"路径\",\n home: \"主目录\",\n sessionsPath: \"会话\",\n memoryPath: \"记忆\",\n semanticPath: \"语义\",\n usagePath: \"用量\",\n },\n plans: {\n loading: \"加载计划…\",\n failed: \"计划失败:{error}\",\n noPlans: \"暂无归档计划 — 运行调用 submit_plan 和 mark_step_complete 的轮次。\",\n filterPlaceholder: \"筛选计划\",\n active: \"进行中\",\n done: \"已完成\",\n idle: \"未开始\",\n steps: \"步骤\",\n pickHint: \"选择左侧的计划。\",\n noTitle: \"(无标题)\",\n stepTimeline: \"步骤时间线 · {done} / {total}\",\n step: \"步骤 {n}\",\n },\n semantic: {\n codeRequired: \"语义 — 需要代码模式\",\n indexBuilt: \"索引已构建\",\n noIndex: \"尚无索引\",\n ready: \"就绪\",\n setupNeeded: \"需要设置\",\n installOllama: \"安装 Ollama\",\n installOllamaDesc: \"Reasonix 不会为您运行包管理器。请先安装 Ollama,然后返回:\",\n macWindows: \"macOS / Windows:\",\n download: \"从 ollama.com/download 下载\",\n linux: \"Linux:\",\n refreshHint: \"安装后刷新 — 此面板将提供启动守护进程和拉取 {model} 的选项。\",\n daemon: \"守护进程\",\n daemonDesc: \"ollama 在您的 PATH 中,但 HTTP 守护进程不可达。\",\n startDaemon: \"启动守护进程\",\n runsOllama: \"以分离模式运行 ollama serve\",\n model: \"模型\",\n modelMissing: \"{model} 尚未安装。\",\n modelSize: \"首次拉取约 270 MB。\",\n pulling: \"拉取中…\",\n pullModel: \"拉取 {model}\",\n indexStatus: \"索引状态\",\n builtStatus: \"● 已构建\",\n incompatibleStatus: \"● 不兼容\",\n chunks: \"分块\",\n files: \"文件\",\n dim: \"维度\",\n size: \"大小\",\n lastBuild: \"上次构建\",\n builtWith: \"构建来源\",\n currentTarget: \"当前目标\",\n incompatibleHint:\n \"磁盘上的这个索引是为不同的 provider 或 model 构建的。运行\\u201C完全重建\\u201D即可替换。\",\n runIndexHint: \"运行索引以启用 semantic_search。\",\n reIndex: \"重建索引\",\n build: \"构建\",\n rebuild: \"完全重建\",\n stop: \"停止\",\n provider: \"提供方\",\n providerType: \"服务类型\",\n openaiCompat: \"OpenAI-Compatible\",\n apiUrl: \"API URL\",\n apiKey: \"API Key\",\n apiKeyStoredNote: \"API Key 仅保存在本地,不会发送到第三方。\",\n customRequestBody: \"自定义请求体\",\n invalidCustomRequestBody: \"自定义请求体必须是合法 JSON:{error}\",\n customRequestBodyMustBeObject: \"自定义请求体必须是 JSON 对象。\",\n saveBeforeIndex: \"请先保存语义设置,再启动索引。\",\n extraBody: \"扩展请求体\",\n batchSize: \"批次大小\",\n keepExistingKey: \"留空则保留现有 Key\",\n remoteProvider: \"远程向量服务\",\n remoteProviderDesc:\n \"在这里配置 OpenAI-Compatible embeddings 的完整 URL。Reasonix 会严格使用你提供的 URL 发起请求。\",\n ollama: \"Ollama\",\n binary: \"二进制\",\n found: \"已找到\",\n missing: \"缺失\",\n daemonStatus: \"守护进程\",\n up: \"运行中\",\n down: \"已停止\",\n pulled: \"已拉取\",\n indexConfig: \"索引配置\",\n reset: \"重置\",\n excludeDirs: \"排除目录\",\n excludeFiles: \"排除文件\",\n excludeExts: \"排除扩展名\",\n excludePatterns: \"排除模式\",\n glob: \"glob\",\n respectGitignore: \"遵循 .gitignore\",\n maxFileBytes: \"最大文件字节数\",\n skipLarger: \"跳过大于 ~{size} MiB 的文件\",\n preview: \"预览\",\n searchPlaceholder: \"描述要查找的内容 — '哪里处理中止信号'\",\n searching: \"搜索中…\",\n results: \"{count} 个结果 · {ms}ms · {model}\",\n noMatches: \"没有超过分数阈值的匹配。\",\n previewSummary: \"预览 — 将索引 {included} 个文件,跳过 {skipped} 个\",\n nothingSkipped: \"无跳过 — 所有遍历的文件都将被索引。\",\n firstIncluded: \"前 {count} 个包含的文件\",\n job: \"任务\",\n phaseSetup: \"初始化中\",\n phaseScan: \"扫描文件\",\n phaseEmbed: \"嵌入分块\",\n phaseWrite: \"写入索引\",\n phaseDone: \"完成\",\n phaseError: \"错误\",\n phaseCancelled: \"已停止\",\n setupFailed: \"初始化失败\",\n stopping: \"停止中\",\n scanned: \"已扫描 {count}\",\n changed: \"已变更 {count}\",\n skipped: \"已跳过 {count}\",\n chunksProgress: \"{done} / {total}({pct}%)\",\n result: \"结果\",\n added: \"已添加 {count}\",\n removed: \"已移除 {count}\",\n failed: \"失败 {count}\",\n skippedFiles: \"{total} 个文件({details})\",\n rebuildStarted: \"已启动完全重建\",\n incrementalStarted: \"已启动增量索引\",\n stopRequested: \"已请求停止 — 当前分块批次将首先完成\",\n startingDaemon: \"正在启动 ollama 守护进程(15 秒超时)…\",\n daemonUp: \"守护进程已启动\",\n daemonTimeout: \"守护进程未在规定时间内启动 — 请手动检查 ollama serve\",\n pullingModel: \"正在拉取 {model} — 首次安装可能需要几分钟\",\n savedConfig: \"已保存 · {count} 个字段已更新 · 重新运行索引以应用\",\n runningPreview: \"正在对项目根目录执行干运行…\",\n exclude: \"排除\",\n },\n modal: {\n shellTitle: \"Shell 命令\",\n shellBgTitle: \"后台进程\",\n shellSubtitle: \"模型想要运行一条 Shell 命令\",\n shellBgSubtitle: \"长时间运行 — 批准后继续运行\",\n pathTitle: \"沙箱外文件访问\",\n pathSubtitle: \"{intent} · 通过 {tool}\",\n pathRead: \"读取\",\n pathWrite: \"写入\",\n pathSandboxLabel: \"沙箱\",\n pathAllowPrefixLabel: \"允许前缀\",\n runOnce: \"运行一次\",\n alwaysAllow: '始终允许 \"{prefix}\"',\n deny: \"拒绝\",\n choiceTitle: \"模型需要您选择\",\n typeOwn: \"输入自定义回答\",\n typeOwnSummary: \"以上选项都不合适 — 写一个自由格式的回复。\",\n typePlaceholder: \"输入自由格式的回答…\",\n send: \"发送\",\n cancel: \"取消\",\n cancelSummary: \"放弃此问题。模型将询问您实际想要什么。\",\n planTitle: \"计划已提交\",\n planSubtitle: \"模型提出了一项计划;请审阅后选择\",\n approveInstructions: \"可选的最后指示 / 对开放问题的回答(Enter 发送空白)\",\n refinePlaceholder: \"需要更改什么?请具体说明。\",\n approve: \"批准\",\n refine: \"优化\",\n sendRefinement: \"发送优化\",\n editTitle: \"编辑待审阅\",\n editSubtitle: \"{path} · {remaining} / {total} 个块剩余\",\n before: \"修改前\",\n after: \"修改后\",\n workspaceTitle: \"模型想要切换工作区\",\n workspaceSubtitle: \"后续所有文件 / Shell / 记忆工具将针对新根目录解析\",\n switchBtn: \"切换 (Enter)\",\n denyBtn: \"拒绝 (Esc)\",\n stepComplete: \"步骤完成{counter}\",\n continueBtn: \"继续\",\n reviseBtn: \"修订…\",\n stopBtn: \"停止\",\n revisionTitle: \"模型提出了计划修订\",\n sendRevision: \"发送修订\",\n accept: \"接受\",\n reject: \"拒绝\",\n arguments: \"参数\",\n revisePlaceholder: \"下一步之前需要更改什么?留空则直接继续。\",\n pickerFilter: \"过滤…\",\n pickerEmpty: \"暂无内容。\",\n pickerLoadMore: \"加载更多\",\n pickerPick: \"打开\",\n pickerInstall: \"安装\",\n pickerUninstall: \"卸载\",\n pickerRename: \"重命名…\",\n pickerNew: \"新建…\",\n pickerNewPlaceholder: \"名称(留空使用默认)\",\n viewerClose: \"关闭\",\n },\n error: {\n title: \"仪表盘出错了\",\n body: \"TUI 不受影响——只有这个浏览器标签出了问题。通常可以直接关闭并继续使用,不会打断智能体。\",\n copyDetails: \"复制详情\",\n copied: \"已复制 ✓\",\n reportOnGithub: \"在 GitHub 上报告\",\n dismiss: \"关闭 (Esc)\",\n crashing: \"此面板持续崩溃 — {name}\",\n retry: \"重试\",\n recovering: \"恢复中…\",\n },\n fmt: {\n justNow: \"刚刚\",\n minutesAgo: \"{n} 分钟前\",\n hoursAgo: \"{n} 小时前\",\n daysAgo: \"{n} 天前\",\n },\n cards: {\n applied: \"已应用\",\n cacheHit: \"缓存命中\",\n checkpointRewind: \"检查点回退\",\n cost: \"费用\",\n diffApply: \"应用\",\n diffApplyChanges: \"应用更改\",\n diffAwaiting: \"待审阅\",\n diffDiscard: \"丢弃\",\n done: \"完成\",\n elapsed: \"耗时\",\n error: \"错误\",\n errorName: \"错误\",\n failed: \"失败\",\n hits: \"命中\",\n memoryCountSuffix: \"条记忆\",\n memoryName: \"记忆\",\n output: \"输出\",\n planDefaultTitle: \"计划\",\n prompt: \"提示词\",\n compactionMeta: \"{chars} 字符\",\n compactionName: \"已压缩历史\",\n reasoningComplete: \"推理完成\",\n reasoningName: \"推理\",\n result: \"结果\",\n running: \"运行中\",\n searchName: \"搜索\",\n shellAlwaysAllow: \"始终允许\",\n shellAwaiting: \"待审批\",\n shellExecuteHint: \"执行此命令?\",\n shellReject: \"拒绝\",\n shellRun: \"运行\",\n shellRunning: \"运行中\",\n streaming: \"输出中\",\n subagentDone: \"子代理完成\",\n subagentDoneProgress: \"子代理完成 ({pct}%)\",\n subagentFailed: \"子代理失败\",\n subagentRunning: \"子代理运行中\",\n },\n planBadge: {\n blocked: \"已阻塞\",\n done: \"完成\",\n failed: \"失败\",\n pending: \"待处理\",\n running: \"运行中\",\n },\n composer: {\n atHeader: \"提及文件\",\n close: \"关闭\",\n commandPalette: \"命令面板\",\n commands: \"命令\",\n commandsLabel: \"命令\",\n confirm: \"确认\",\n imageFilterName: \"图片\",\n insertFile: \"插入文件\",\n insertImage: \"插入图片\",\n interrupt: \"中断\",\n mentionFiles: \"提及文件\",\n mentionLabel: \"提及\",\n newline: \"换行\",\n noMatches: \"无匹配\",\n placeholder: \"输入提示词…\",\n queue: \"队列\",\n queueCount: \"{count} 个排队\",\n select: \"选择\",\n send: \"发送\",\n slashHeader: \"斜杠命令\",\n switchModel: \"切换模型\",\n switchEffort: \"切换推理强度\",\n workspaceRoot: \"工作区根目录\",\n },\n contextPanel: {\n allow: \"允许\",\n ask: \"询问\",\n autoApproveTitle: \"自动审批\",\n cacheKey: \"缓存\",\n contextTokens: \"上下文 tokens\",\n fileInContext: \"在上下文中\",\n fileModified: \"已修改\",\n filesCount: \"{count} 个文件\",\n filesTab: \"文件\",\n filesTitle: \"文件\",\n freeKey: \"空闲\",\n itemCount: \"{count} 个项目\",\n mcpConfigured: \"已配置\",\n mcpConnecting: \"连接中…\",\n mcpDisabled: \"已禁用\",\n mcpEmpty: \"无 MCP 服务器\",\n mcpFailed: \"失败\",\n mcpReady: \"就绪\",\n mcpReadyAll: \"全部就绪\",\n mcpReadySome: \"部分就绪\",\n mcpTitle: \"MCP\",\n mcpTools: \"工具\",\n memoryTab: \"记忆\",\n memoryTitle: \"记忆\",\n noFilesMsg: \"上下文中无文件\",\n noMemoriesMsg: \"无记忆\",\n reservedKey: \"保留\",\n ruleReadOnly: \"只读\",\n ruleReview: \"审阅\",\n ruleShellAllowlist: \"Shell 允许列表\",\n rulesTab: \"规则\",\n ruleWritesAsk: \"写入需询问\",\n ruleYolo: \"YOLO\",\n scopeGlobal: \"全局\",\n scopeProject: \"项目\",\n toolsTab: \"工具\",\n usedKey: \"已用\",\n },\n dragDrop: {\n overlay: \"拖放文件到此处\",\n },\n extraCards: {\n approve: \"批准\",\n balance: \"余额\",\n cache: \"缓存\",\n cacheHit: \"缓存命中\",\n contextWindow: \"上下文窗口\",\n doctorTitle: \"诊断\",\n output: \"输出\",\n prompt: \"提示词\",\n reasoning: \"推理\",\n reject: \"拒绝\",\n sessionCost: \"会话成本\",\n sessionUsage: \"会话用量\",\n topToolsUsage: \"热门工具\",\n unknownKind: \"未知\",\n memoryUser: \"用户\",\n memoryFeedback: \"反馈\",\n memoryProject: \"项目\",\n memoryReference: \"参考\",\n },\n jobs: {\n empty: \"无后台任务\",\n exited: \"已退出\",\n kbClose: \"关闭\",\n kbToggle: \"切换\",\n running: \"运行中\",\n stop: \"停止\",\n stopAll: \"全部停止\",\n stopAllTip: \"停止所有任务\",\n stopOne: \"停止\",\n title: \"后台任务\",\n },\n live: {\n deliveredWaiting: \"等待下一条消息\",\n reasoning: \"推理\",\n running: \"运行中\",\n secondsAgo: \"{n} 秒前\",\n you: \"你\",\n },\n markdown: {\n copied: \"已复制!\",\n copy: \"复制\",\n externalLinkTitle: \"在新标签中打开\",\n filePillTitle: \"打开文件\",\n localLinkTitle: \"打开链接\",\n },\n palette: {\n abort: \"中止\",\n abortHint: \"中止当前请求\",\n about: \"关于\",\n clearChat: \"清除对话\",\n clearChatHint: \"清除对话\",\n closeTab: \"关闭标签\",\n closeTabHint: \"关闭当前标签\",\n copyConv: \"复制对话\",\n copyConvHint: \"复制对话为 Markdown\",\n copyLast: \"复制上条回复\",\n copyLastHint: \"复制上条助手消息\",\n countSuffix: \"个项目\",\n empty: \"无匹配命令\",\n exportMd: \"导出为 Markdown\",\n exportMdHint: \"导出对话为 Markdown 文件\",\n focusComposer: \"聚焦编辑器\",\n footClose: \"关闭\",\n footMove: \"移动\",\n footRun: \"运行\",\n groupAction: \"操作\",\n groupNav: \"导航\",\n groupSettings: \"设置\",\n groupWorkspace: \"工作区\",\n newChat: \"新建对话\",\n newChatHint: \"开始新对话\",\n newTab: \"新建标签\",\n newTabHint: \"打开新标签\",\n pickWorkspace: \"切换工作区\",\n pickWorkspaceHint: \"更改工作区\",\n searchPlaceholder: \"搜索命令…\",\n settings: \"设置\",\n settingsHint: \"打开设置\",\n },\n panel: {\n renderError: \"面板崩溃\",\n },\n sidebarPanel: {\n approvalRules: \"审批规则\",\n cancel: \"取消\",\n commandPalette: \"命令面板\",\n daysAgo: \"{n} 天前\",\n delete: \"删除\",\n deleteSession: \"删除会话\",\n hoursAgo: \"{n} 小时前\",\n justNow: \"刚刚\",\n loading: \"加载中…\",\n messageCount: \"{count} 条消息\",\n minutesAgo: \"{n} 分钟前\",\n newChat: \"新建对话\",\n noMatches: \"无匹配\",\n noSessions: \"无会话\",\n recent: \"最近\",\n searchSessions: \"搜索会话…\",\n sessionTitle: \"会话\",\n settings: \"设置\",\n weeksAgo: \"{n} 周前\",\n },\n statusbar: {\n balance: \"余额\",\n busy: \"忙碌\",\n cache: \"缓存\",\n cacheHit: \"缓存命中\",\n jobs: \"任务\",\n jobsTip: \"后台任务\",\n offline: \"离线\",\n online: \"在线\",\n switchCurrency: \"切换货币\",\n switchTheme: \"切换主题\",\n switchWorkspace: \"切换工作区\",\n themeDark: \"深色\",\n themeLight: \"浅色\",\n themeStyleGraphite: \"石墨\",\n themeStyleSandstone: \"砂岩\",\n themeStylePorcelain: \"瓷白\",\n themeStyleMidnight: \"午夜\",\n thisTurn: \"本轮\",\n tokens: \"Tokens\",\n },\n thread: {\n activePlan: \"活跃计划\",\n allowRead: \"允许读取\",\n allowWrite: \"允许写入\",\n alwaysAllow: \"始终允许\",\n alwaysAllowPrefix: \"始终允许 {prefix}\",\n approve: \"批准\",\n approveRewrite: \"批准重写\",\n cancel: \"取消\",\n checkpointKind: \"检查点\",\n checkpointSub: \"保存当前状态\",\n checkpointTitle: \"创建检查点\",\n collapse: \"折叠\",\n continue: \"继续\",\n copyMessage: \"复制消息\",\n copyResponse: \"复制回复\",\n execute: \"执行\",\n keepOriginal: \"保留原始\",\n keepSteps: \"保留步骤\",\n optionCount: \"{count} 个选项\",\n pathAccessKind: \"路径访问\",\n planConfirmationKind: \"计划审批\",\n planRevisionKind: \"计划修订\",\n planRunning: \"计划进行中\",\n planStepCount: \"步骤 {done}/{total}\",\n readPathOutsideSandbox: \"沙箱外读取路径\",\n refine: \"优化\",\n reject: \"拒绝\",\n revise: \"修订\",\n revisionMeta: \"修订\",\n rewritePlan: \"重写计划\",\n risk: \"风险评估\",\n riskMedium: \"中等风险\",\n runBackgroundCommand: \"后台运行\",\n runCommand: \"运行命令\",\n shellConfirmationKind: \"Shell 确认\",\n startPlan: \"启动计划\",\n stop: \"停止\",\n subagent: \"子代理\",\n userChoiceKind: \"用户选择\",\n writePathOutsideSandbox: \"沙箱外写入路径\",\n you: \"你\",\n },\n workdir: {\n browse: \"浏览…\",\n cancel: \"取消\",\n empty: \"无工作区\",\n emptyDir: \"无子目录。\",\n go: \"前往\",\n goTip: \"跳转到该路径\",\n loading: \"加载中…\",\n openHere: \"打开此目录\",\n pathPlaceholder: \"绝对路径…\",\n promptWeb: \"输入要打开的工作区绝对路径:\",\n searchPlaceholder: \"搜索工作区…\",\n title: \"工作区\",\n },\n about: {\n close: \"关闭\",\n repo: \"仓库\",\n sidebarLabel: \"关于\",\n tagline: \"AI 驱动的编程助手\",\n version: \"版本\",\n },\n effort: {\n lowDesc: \"最快 — 极少推理\",\n mediumDesc: \"平衡\",\n highDesc: \"默认 — vLLM / Azure 安全\",\n maxDesc: \"DeepSeek 扩展;标准 OpenAI / vLLM 会拒绝\",\n },\n editMode: {\n plan: \"计划\",\n planHint: \"只读模式 · 所有写工具都不会派发\",\n review: \"审阅\",\n reviewHint: \"编辑和非允许列表的 shell 命令都会先询问\",\n auto: \"自动\",\n autoHint: \"编辑自动应用,shell 仍会询问\",\n yolo: \"YOLO\",\n yoloHint: \"编辑和 shell 都自动运行,绕过允许列表\",\n },\n};\n","import { useEffect, useState } from \"react\";\nimport { de } from \"./de\";\nimport { en } from \"./en\";\nimport { zhCN } from \"./zh-CN\";\n\nexport type Lang = \"en\" | \"zh-CN\" | \"de\";\n\nconst SUPPORTED_LANGS: readonly Lang[] = [\"en\", \"zh-CN\", \"de\"];\nconst SUPPORTED: ReadonlySet<Lang> = new Set<Lang>(SUPPORTED_LANGS);\nconst LANG_LABELS: Record<Lang, string> = { en: \"English\", \"zh-CN\": \"简体中文\", de: \"Deutsch\" };\nconst STORAGE_KEY = \"reasonix.lang\";\n\ntype Listener = () => void;\nconst listeners: Listener[] = [];\n\nfunction detectDefault(): Lang {\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored && SUPPORTED.has(stored as Lang)) return stored as Lang;\n } catch {\n /* private mode */\n }\n const nav = typeof navigator !== \"undefined\" ? navigator.language : \"\";\n const lower = nav.toLowerCase();\n if (lower.startsWith(\"zh\")) return \"zh-CN\";\n if (lower.startsWith(\"de\")) return \"de\";\n return \"en\";\n}\n\nlet currentLang: Lang = detectDefault();\n\nfunction syncHtmlLang(lang: Lang): void {\n if (typeof document === \"undefined\") return;\n try {\n document.documentElement.lang = lang;\n } catch {\n /* document not ready */\n }\n}\n\nsyncHtmlLang(currentLang);\n\nexport function getLang(): Lang {\n return currentLang;\n}\n\nexport function getSupportedLangs(): readonly Lang[] {\n return SUPPORTED_LANGS;\n}\n\nexport function getLangLabel(lang: Lang): string {\n return LANG_LABELS[lang];\n}\n\nexport function setLang(lang: Lang): void {\n if (!SUPPORTED.has(lang) || lang === currentLang) return;\n currentLang = lang;\n try {\n localStorage.setItem(STORAGE_KEY, lang);\n } catch {\n /* ignore */\n }\n syncHtmlLang(lang);\n for (const cb of listeners) cb();\n}\n\nexport function useLang(): Lang {\n const [, setTick] = useState(0);\n useEffect(() => {\n const cb = () => setTick((n) => n + 1);\n listeners.push(cb);\n return () => {\n const idx = listeners.indexOf(cb);\n if (idx >= 0) listeners.splice(idx, 1);\n };\n }, []);\n return currentLang;\n}\n\nconst dicts = { en, \"zh-CN\": zhCN, de } as const;\n\ntype Dict = typeof en;\ntype Path<T, K extends keyof T = keyof T> = K extends string\n ? T[K] extends Record<string, unknown>\n ? `${K}.${Path<T[K]>}`\n : K\n : never;\nexport type TKey = Path<Dict>;\n\nfunction resolve(dict: Dict, key: string): string {\n const parts = key.split(\".\");\n let cursor: unknown = dict;\n for (const p of parts) {\n if (cursor && typeof cursor === \"object\" && p in (cursor as Record<string, unknown>)) {\n cursor = (cursor as Record<string, unknown>)[p];\n } else {\n return key;\n }\n }\n return typeof cursor === \"string\" ? cursor : key;\n}\n\nexport function t(key: TKey, params?: Record<string, string | number>): string {\n const raw = resolve(dicts[currentLang], key);\n if (!params) return raw;\n return raw.replace(/\\{(\\w+)\\}/g, (_, k) => (k in params ? String(params[k]) : `{${k}}`));\n}\n","import type { ReactNode } from \"react\";\n\nexport type ShortcutKey = \"mod\" | \"shift\" | \"enter\" | \"tab\" | \"esc\" | \"updown\" | string;\n\nfunction isMacPlatform(): boolean {\n if (typeof document === \"undefined\") return false;\n return document.documentElement.dataset.platform === \"macos\";\n}\n\nfunction keyLabel(key: ShortcutKey, mac: boolean): string {\n switch (key) {\n case \"mod\":\n case \"⌘\":\n return mac ? \"⌘\" : \"Ctrl\";\n case \"shift\":\n case \"⇧\":\n return mac ? \"⇧\" : \"Shift\";\n case \"enter\":\n case \"⏎\":\n return \"Enter\";\n case \"tab\":\n case \"⇥\":\n return \"Tab\";\n case \"esc\":\n return \"Esc\";\n case \"updown\":\n case \"↑↓\":\n return \"↑↓\";\n default:\n return key;\n }\n}\n\nexport function shortcutText(keys: readonly ShortcutKey[]): string {\n const mac = isMacPlatform();\n return keys.map((key) => keyLabel(key, mac)).join(mac ? \"\" : \"+\");\n}\n\nexport function localizeShortcutText(text: string): string {\n return text.replace(/⌘/g, keyLabel(\"mod\", isMacPlatform()));\n}\n\nexport function Shortcut({\n keys,\n className,\n}: {\n keys: readonly ShortcutKey[];\n className?: string;\n}): ReactNode {\n const mac = isMacPlatform();\n return (\n <span className={[\"shortcut\", className].filter(Boolean).join(\" \")}>\n {keys.map((key, index) => (\n <kbd key={`${key}-${index}`} data-key={key}>\n {keyLabel(key, mac)}\n </kbd>\n ))}\n </span>\n );\n}\n","import {\n ClipboardCopy,\n Download,\n FilePlus,\n FocusIcon,\n FolderOpen,\n Info,\n Plus,\n Search,\n Settings,\n SquareX,\n StopCircle,\n Trash2,\n} from \"lucide-react\";\nimport { type ReactNode, useEffect, useMemo, useRef, useState } from \"react\";\nimport { t, useLang } from \"./i18n\";\nimport { Shortcut, type ShortcutKey } from \"./ui/shortcut\";\n\nexport type CommandGroup = \"nav\" | \"action\" | \"workspace\" | \"settings\";\n\nexport type Command = {\n id: string;\n label: string;\n hint?: string;\n icon: ReactNode;\n shortcut?: ShortcutKey[];\n group: CommandGroup;\n run: () => void;\n};\n\nexport function useCommandPalette(active: boolean = true) {\n const [open, setOpen] = useState(false);\n useEffect(() => {\n // Skip in background tabs — each TabRuntime calls this hook, so without the gate Cmd+K toggles every tab's palette at once.\n if (!active) return;\n const onKey = (e: KeyboardEvent) => {\n const mod = e.ctrlKey || e.metaKey;\n if (mod && (e.key === \"k\" || e.key === \"K\")) {\n e.preventDefault();\n setOpen((v) => !v);\n } else if (e.key === \"Escape\") {\n setOpen(false);\n }\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [active]);\n return { open, setOpen };\n}\n\nexport type CommandHandlers = {\n newChat: () => void;\n clearChat: () => void;\n focusComposer: () => void;\n openSettings: () => void;\n about: () => void;\n abort: () => void;\n copyLast: () => void;\n conversationCopy: () => void;\n exportMarkdown: () => void;\n pickWorkspace: () => void;\n newTab: () => void;\n closeTab: () => void;\n busy: boolean;\n canCloseTab: boolean;\n hasMessages: boolean;\n};\n\nexport function buildCommands(handlers: CommandHandlers): Command[] {\n const list: Command[] = [\n {\n id: \"new-chat\",\n group: \"nav\",\n label: t(\"palette.newChat\"),\n hint: t(\"palette.newChatHint\"),\n icon: <FilePlus size={13} />,\n shortcut: [\"mod\", \"N\"],\n run: handlers.newChat,\n },\n {\n id: \"new-tab\",\n group: \"nav\",\n label: t(\"palette.newTab\"),\n hint: t(\"palette.newTabHint\"),\n icon: <Plus size={13} />,\n shortcut: [\"mod\", \"T\"],\n run: handlers.newTab,\n },\n ];\n if (handlers.canCloseTab) {\n list.push({\n id: \"close-tab\",\n group: \"nav\",\n label: t(\"palette.closeTab\"),\n hint: t(\"palette.closeTabHint\"),\n icon: <SquareX size={13} />,\n shortcut: [\"mod\", \"W\"],\n run: handlers.closeTab,\n });\n }\n list.push({\n id: \"focus-composer\",\n group: \"nav\",\n label: t(\"palette.focusComposer\"),\n icon: <FocusIcon size={13} />,\n shortcut: [\"mod\", \"L\"],\n run: handlers.focusComposer,\n });\n if (handlers.busy) {\n list.push({\n id: \"abort\",\n group: \"action\",\n label: t(\"palette.abort\"),\n hint: t(\"palette.abortHint\"),\n icon: <StopCircle size={13} />,\n shortcut: [\"esc\"],\n run: handlers.abort,\n });\n }\n if (handlers.hasMessages) {\n list.push({\n id: \"copy-last\",\n group: \"action\",\n label: t(\"palette.copyLast\"),\n hint: t(\"palette.copyLastHint\"),\n icon: <ClipboardCopy size={13} />,\n run: handlers.copyLast,\n });\n list.push({\n id: \"copy-conv\",\n group: \"action\",\n label: t(\"palette.copyConv\"),\n hint: t(\"palette.copyConvHint\"),\n icon: <ClipboardCopy size={13} />,\n run: handlers.conversationCopy,\n });\n list.push({\n id: \"export-md\",\n group: \"action\",\n label: t(\"palette.exportMd\"),\n hint: t(\"palette.exportMdHint\"),\n icon: <Download size={13} />,\n run: handlers.exportMarkdown,\n });\n list.push({\n id: \"clear-chat\",\n group: \"action\",\n label: t(\"palette.clearChat\"),\n hint: t(\"palette.clearChatHint\"),\n icon: <Trash2 size={13} />,\n run: handlers.clearChat,\n });\n }\n list.push({\n id: \"pick-workspace\",\n group: \"workspace\",\n label: t(\"palette.pickWorkspace\"),\n hint: t(\"palette.pickWorkspaceHint\"),\n icon: <FolderOpen size={13} />,\n run: handlers.pickWorkspace,\n });\n list.push({\n id: \"settings\",\n group: \"settings\",\n label: t(\"palette.settings\"),\n hint: t(\"palette.settingsHint\"),\n icon: <Settings size={13} />,\n run: handlers.openSettings,\n });\n list.push({\n id: \"about\",\n group: \"settings\",\n label: t(\"palette.about\"),\n icon: <Info size={13} />,\n run: handlers.about,\n });\n return list;\n}\n\nconst GROUP_ORDER: CommandGroup[] = [\"nav\", \"action\", \"workspace\", \"settings\"];\n\nfunction groupLabel(g: CommandGroup): string {\n switch (g) {\n case \"nav\": return t(\"palette.groupNav\");\n case \"action\": return t(\"palette.groupAction\");\n case \"workspace\": return t(\"palette.groupWorkspace\");\n case \"settings\": return t(\"palette.groupSettings\");\n }\n}\n\nexport function CommandPalette({\n open,\n onClose,\n commands,\n}: {\n open: boolean;\n onClose: () => void;\n commands: Command[];\n}) {\n useLang();\n const [query, setQuery] = useState(\"\");\n const [active, setActive] = useState(0);\n const inputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n\n const filtered = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return commands;\n return commands.filter((c) =>\n [c.label, c.hint].filter(Boolean).join(\" \").toLowerCase().includes(q),\n );\n }, [query, commands]);\n\n useEffect(() => {\n if (open) {\n setQuery(\"\");\n setActive(0);\n requestAnimationFrame(() => inputRef.current?.focus());\n }\n }, [open]);\n\n useEffect(() => {\n setActive((a) => Math.min(a, Math.max(0, filtered.length - 1)));\n }, [filtered.length]);\n\n useEffect(() => {\n const el = listRef.current?.querySelector<HTMLElement>(`[data-idx=\"${active}\"]`);\n el?.scrollIntoView({ block: \"nearest\" });\n }, [active]);\n\n const grouped = useMemo(() => {\n const byGroup = new Map<CommandGroup, Command[]>();\n for (const c of filtered) {\n const arr = byGroup.get(c.group) ?? [];\n arr.push(c);\n byGroup.set(c.group, arr);\n }\n return GROUP_ORDER\n .map((g) => ({ group: g, items: byGroup.get(g) ?? [] }))\n .filter((s) => s.items.length > 0);\n }, [filtered]);\n\n if (!open) return null;\n\n const run = (cmd: Command) => {\n cmd.run();\n onClose();\n };\n\n return (\n <div className=\"cmdk-mask\" onMouseDown={onClose}>\n <div className=\"cmdk\" onMouseDown={(e) => e.stopPropagation()}>\n <div className=\"cmdk-head\">\n <Search size={14} />\n <input\n ref={inputRef}\n placeholder={t(\"palette.searchPlaceholder\")}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setActive((a) => Math.min(a + 1, filtered.length - 1));\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setActive((a) => Math.max(a - 1, 0));\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n const cmd = filtered[active];\n if (cmd) run(cmd);\n }\n }}\n />\n <span className=\"hint\">\n <Shortcut keys={[\"esc\"]} />\n </span>\n </div>\n <div className=\"cmdk-body\" ref={listRef}>\n {filtered.length === 0 ? (\n <div className=\"cmdk-empty\">{t(\"palette.empty\")}</div>\n ) : null}\n {grouped.map((section) => (\n <div className=\"cmdk-group\" key={section.group}>\n <div className=\"cmdk-gh\">{groupLabel(section.group)}</div>\n {section.items.map((c) => {\n const i = filtered.indexOf(c);\n return (\n <div\n key={c.id}\n data-idx={i}\n className=\"cmdk-row\"\n data-active={i === active}\n onMouseEnter={() => setActive(i)}\n onClick={() => run(c)}\n >\n <span className=\"ic\">{c.icon}</span>\n <span className=\"l\">{c.label}</span>\n <span className=\"g\">{groupLabel(c.group)}</span>\n {c.shortcut ? (\n <span className=\"kb\">\n <Shortcut keys={c.shortcut} />\n </span>\n ) : (\n <span className=\"kb-empty\" />\n )}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n <div className=\"cmdk-foot\">\n <span>\n <Shortcut keys={[\"updown\"]} />\n {t(\"palette.footMove\")}\n </span>\n <span>\n <Shortcut keys={[\"enter\"]} />\n {t(\"palette.footRun\")}\n </span>\n <span>\n <Shortcut keys={[\"esc\"]} />\n {t(\"palette.footClose\")}\n </span>\n <span style={{ marginLeft: \"auto\", color: \"var(--muted)\" }}>\n {filtered.length} {t(\"palette.countSuffix\")}\n </span>\n </div>\n </div>\n </div>\n );\n}\n\nexport function Toast({ message }: { message: { msg: string; yolo?: boolean } | null }) {\n if (!message) return null;\n if (message.yolo) {\n return (\n <div className=\"toast toast-yolo\">\n <span className=\"toast-yolo-badge\">YOLO</span>\n {message.msg}\n </div>\n );\n }\n return <div className=\"toast\">{message.msg}</div>;\n}\n","import { Highlight, type PrismTheme } from \"prism-react-renderer\";\nimport { useEffect, useRef, useState } from \"react\";\n\nconst DARK_THEME: PrismTheme = {\n plain: { color: \"#dde1ea\", backgroundColor: \"transparent\" },\n styles: [\n { types: [\"comment\", \"prolog\", \"doctype\", \"cdata\"], style: { color: \"#6d6e80\", fontStyle: \"italic\" } },\n { types: [\"punctuation\"], style: { color: \"#a8a9b8\" } },\n { types: [\"property\", \"tag\", \"boolean\", \"number\", \"constant\", \"symbol\", \"deleted\"], style: { color: \"#fbbf24\" } },\n { types: [\"selector\", \"attr-name\", \"string\", \"char\", \"builtin\", \"inserted\"], style: { color: \"#86dcb1\" } },\n { types: [\"operator\", \"entity\", \"url\"], style: { color: \"#84b9e8\" } },\n { types: [\"atrule\", \"attr-value\", \"keyword\"], style: { color: \"#b4a8f0\" } },\n { types: [\"function\", \"class-name\", \"maybe-class-name\"], style: { color: \"#84b9e8\", fontWeight: \"500\" } },\n { types: [\"regex\", \"important\", \"variable\"], style: { color: \"#f0c062\" } },\n { types: [\"important\", \"bold\"], style: { fontWeight: \"bold\" } },\n { types: [\"italic\"], style: { fontStyle: \"italic\" } },\n ],\n};\n\nconst LIGHT_THEME: PrismTheme = {\n plain: { color: \"#24292e\", backgroundColor: \"transparent\" },\n styles: [\n { types: [\"comment\", \"prolog\", \"doctype\", \"cdata\"], style: { color: \"#6a737d\", fontStyle: \"italic\" } },\n { types: [\"punctuation\"], style: { color: \"#24292e\" } },\n { types: [\"property\", \"tag\", \"boolean\", \"number\", \"constant\", \"symbol\", \"deleted\"], style: { color: \"#d73a49\" } },\n { types: [\"selector\", \"attr-name\", \"string\", \"char\", \"builtin\", \"inserted\"], style: { color: \"#032f62\" } },\n { types: [\"operator\", \"entity\", \"url\"], style: { color: \"#d73a49\" } },\n { types: [\"atrule\", \"attr-value\", \"keyword\"], style: { color: \"#d73a49\" } },\n { types: [\"function\", \"class-name\", \"maybe-class-name\"], style: { color: \"#6f42c1\", fontWeight: \"500\" } },\n { types: [\"regex\", \"important\", \"variable\"], style: { color: \"#e36209\" } },\n { types: [\"important\", \"bold\"], style: { fontWeight: \"bold\" } },\n { types: [\"italic\"], style: { fontStyle: \"italic\" } },\n ],\n};\n\nfunction usePrismTheme(): PrismTheme {\n const [theme, setTheme] = useState<\"dark\" | \"light\">(() =>\n document.documentElement.dataset.theme === \"light\" ? \"light\" : \"dark\",\n );\n const prevRef = useRef(theme);\n useEffect(() => {\n const el = document.documentElement;\n const cb = () => {\n const t = el.dataset.theme === \"light\" ? \"light\" : \"dark\";\n if (t !== prevRef.current) {\n prevRef.current = t;\n setTheme(t);\n }\n };\n const mo = new MutationObserver(cb);\n mo.observe(el, { attributes: true, attributeFilter: [\"data-theme\"] });\n return () => mo.disconnect();\n }, []);\n return theme === \"dark\" ? DARK_THEME : LIGHT_THEME;\n}\n\nexport const PRISM_THEME = DARK_THEME;\n\nconst EXTS: Record<string, string> = {\n ts: \"typescript\", tsx: \"tsx\", mts: \"typescript\", cts: \"typescript\",\n js: \"javascript\", jsx: \"jsx\", mjs: \"javascript\", cjs: \"javascript\",\n py: \"python\", pyi: \"python\",\n rs: \"rust\",\n go: \"go\",\n json: \"json\", jsonc: \"json\",\n md: \"markdown\", mdx: \"markdown\",\n css: \"css\", scss: \"scss\", less: \"less\",\n html: \"markup\", htm: \"markup\", xml: \"markup\", svg: \"markup\",\n yaml: \"yaml\", yml: \"yaml\",\n toml: \"toml\",\n sh: \"bash\", bash: \"bash\", zsh: \"bash\", fish: \"bash\",\n sql: \"sql\",\n rb: \"ruby\",\n java: \"java\", kt: \"kotlin\",\n swift: \"swift\",\n c: \"c\", h: \"c\",\n cpp: \"cpp\", cc: \"cpp\", cxx: \"cpp\", hpp: \"cpp\", hxx: \"cpp\",\n cs: \"csharp\",\n php: \"php\",\n lua: \"lua\",\n dart: \"dart\",\n ex: \"elixir\", exs: \"elixir\",\n erl: \"erlang\",\n hs: \"haskell\",\n clj: \"clojure\", cljs: \"clojure\",\n zig: \"zig\",\n vue: \"markup\",\n svelte: \"markup\",\n graphql: \"graphql\", gql: \"graphql\",\n proto: \"protobuf\",\n dockerfile: \"docker\",\n};\n\nexport function langFromPath(path: string | null | undefined): string | null {\n if (!path) return null;\n const base = path.split(/[\\\\/]/).pop() ?? \"\";\n if (base.toLowerCase() === \"dockerfile\") return \"docker\";\n if (base.toLowerCase() === \"makefile\") return \"makefile\";\n const m = /\\.([a-z0-9]+)$/i.exec(base);\n if (!m) return null;\n return EXTS[m[1].toLowerCase()] ?? null;\n}\n\nexport function CodeView({\n text,\n lang,\n startLine = 1,\n showLineNumbers = true,\n}: {\n text: string;\n lang: string;\n startLine?: number;\n showLineNumbers?: boolean;\n}) {\n const theme = usePrismTheme();\n return (\n <Highlight theme={theme} code={text} language={lang}>\n {({ className, tokens, getLineProps, getTokenProps }) => (\n <pre className={`codeview ${className}`}>\n {tokens.map((line, i) => (\n <div key={i} {...getLineProps({ line })} className=\"codeview-line\">\n {showLineNumbers && (\n <span className=\"codeview-line-num\">{i + startLine}</span>\n )}\n <span className=\"codeview-line-content\">\n {line.map((token, k) => (\n <span key={k} {...getTokenProps({ token })} />\n ))}\n </span>\n </div>\n ))}\n </pre>\n )}\n </Highlight>\n );\n}\n\nexport function CollapsibleCode({\n text,\n lang,\n startLine = 1,\n maxLines = 20,\n}: {\n text: string;\n lang: string;\n startLine?: number;\n maxLines?: number;\n}) {\n const [open, setOpen] = useState(false);\n const lines = text.split(\"\\n\");\n const tooLong = lines.length > maxLines;\n const shown = open || !tooLong ? text : lines.slice(0, maxLines).join(\"\\n\");\n return (\n <>\n <CodeView text={shown} lang={lang} startLine={startLine} />\n {tooLong && (\n <button type=\"button\" className=\"tool-more\" onClick={() => setOpen((v) => !v)}>\n {open ? \"less\" : `+ ${lines.length - maxLines} more lines`}\n </button>\n )}\n </>\n );\n}\n","import { invoke } from \"@tauri-apps/api/core\";\nimport { openPath, openUrl } from \"@tauri-apps/plugin-opener\";\nimport { Check, Copy, ExternalLink, FileText } from \"lucide-react\";\nimport {\n Children,\n cloneElement,\n createContext,\n isValidElement,\n memo,\n type ReactNode,\n useContext,\n useState,\n} from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport rehypeKatex from \"rehype-katex\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport { CodeView } from \"./CodeView\";\nimport { t, useLang } from \"./i18n\";\n\nasync function openWithEditor(\n editor: string | undefined,\n abs: string,\n line?: number,\n): Promise<void> {\n if (editor && editor.trim()) {\n await invoke(\"open_in_editor\", { command: editor, path: abs, line: line ?? null });\n return;\n }\n await openPath(abs);\n}\n\ntype WorkspaceCtx = { dir?: string; editor?: string };\nconst WorkspaceContext = createContext<WorkspaceCtx>({});\nexport const WorkspaceProvider = WorkspaceContext.Provider;\n\nfunction resolveAgainstWorkspace(rel: string, ws: string | undefined): string {\n if (!ws) return rel;\n if (/^[a-zA-Z]:[\\\\/]/.test(rel) || rel.startsWith(\"/\")) return rel;\n const sep = ws.includes(\"\\\\\") ? \"\\\\\" : \"/\";\n const trimmed = ws.replace(/[\\\\/]$/, \"\");\n return `${trimmed}${sep}${rel.replace(/^\\.[\\\\/]/, \"\")}`;\n}\n\nconst KNOWN_EXTS =\n \"ts|tsx|mts|cts|js|jsx|mjs|cjs|py|pyi|rs|go|json|jsonc|md|mdx|css|scss|less|html|htm|xml|svg|yaml|yml|toml|sh|bash|zsh|fish|sql|rb|java|kt|swift|c|cpp|cc|cxx|h|hpp|hxx|cs|php|lua|dart|ex|exs|erl|hs|clj|cljs|zig|vue|svelte|graphql|gql|proto\";\n// No lookbehind here — Tauri's WKWebView on macOS Monterey (Safari < 16.4)\n// can't parse `(?<=...)` and the whole bundle fails to load with an\n// \"invalid group specifier name\" error. Capture the leading char as\n// group 1 instead and let splitFilePaths skip past it. Issue #1209.\nconst FILE_PATH_RE = new RegExp(\n `(^|[\\\\s\\`'\"(\\\\[])((?:[\\\\w.-]+\\\\/)+[\\\\w.-]+\\\\.(?:${KNOWN_EXTS}))(?::(\\\\d+(?:-\\\\d+)?))?(?=[\\\\s.,;!?\\\\]\\\\)'\"\\`]|$)`,\n \"g\",\n);\n\nfunction FilePill({ path, line }: { path: string; line?: string }) {\n useLang();\n const ctx = useContext(WorkspaceContext);\n const [done, setDone] = useState<\"open\" | \"copy\" | null>(null);\n const display = line ? `${path}:${line}` : path;\n const openInEditor = async () => {\n try {\n const abs = resolveAgainstWorkspace(path, ctx.dir);\n const lineNum = line ? Number.parseInt(line.split(\"-\")[0] ?? line, 10) : undefined;\n await openWithEditor(ctx.editor, abs, Number.isFinite(lineNum) ? lineNum : undefined);\n setDone(\"open\");\n setTimeout(() => setDone(null), 1200);\n } catch {\n try {\n await navigator.clipboard.writeText(display);\n setDone(\"copy\");\n setTimeout(() => setDone(null), 1200);\n } catch {\n /* ignore */\n }\n }\n };\n const copyOnly = async (e: React.MouseEvent) => {\n e.stopPropagation();\n try {\n await navigator.clipboard.writeText(display);\n setDone(\"copy\");\n setTimeout(() => setDone(null), 1200);\n } catch {\n /* ignore */\n }\n };\n return (\n <span\n className={`file-pill ${done ? \"done\" : \"\"}`}\n role=\"button\"\n tabIndex={0}\n onClick={openInEditor}\n onContextMenu={(e) => {\n e.preventDefault();\n void copyOnly(e);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n void openInEditor();\n }\n }}\n title={t(\"markdown.filePillTitle\")}\n >\n <FileText size={10} className=\"file-pill-icon\" />\n <span className=\"file-pill-path\">{path}</span>\n {line && <span className=\"file-pill-line\">:{line}</span>}\n {done && <Check size={10} className=\"file-pill-check\" />}\n </span>\n );\n}\n\nfunction splitFilePaths(text: string): ReactNode[] | string {\n FILE_PATH_RE.lastIndex = 0;\n const out: ReactNode[] = [];\n let last = 0;\n let m: RegExpExecArray | null = FILE_PATH_RE.exec(text);\n while (m !== null) {\n const prefix = m[1] ?? \"\";\n const path = m[2]!;\n const line = m[3];\n const pillStart = m.index + prefix.length;\n if (pillStart > last) out.push(text.slice(last, pillStart));\n out.push(<FilePill key={`fp-${pillStart}`} path={path} line={line} />);\n last = pillStart + path.length + (line ? line.length + 1 : 0);\n m = FILE_PATH_RE.exec(text);\n }\n if (out.length === 0) return text;\n if (last < text.length) out.push(text.slice(last));\n return out;\n}\n\ntype AnyProps = { children?: ReactNode } & Record<string, unknown>;\n\nfunction withFilePills(children: ReactNode): ReactNode {\n return Children.map(children, (child) => {\n if (typeof child === \"string\") return splitFilePaths(child);\n if (isValidElement(child)) {\n const props = child.props as AnyProps;\n if (props.children !== undefined) {\n return cloneElement(child, undefined, withFilePills(props.children));\n }\n }\n return child;\n });\n}\n\nexport const Markdown = memo(function Markdown({ source }: { source: string }) {\n return (\n <div className=\"markdown\">\n <ReactMarkdown\n remarkPlugins={[remarkGfm, remarkBreaks, remarkMath]}\n rehypePlugins={[[rehypeKatex, { throwOnError: false }]]}\n components={{\n pre: ({ children }) => {\n // react-markdown v9 nests children unpredictably — flatten all text.\n const rawText = flattenChildText(children).trimEnd();\n return <CodeBlock lang={extractFencedLang(children)} text={rawText} />;\n },\n code: ({ className, children }) => <code className={className}>{children}</code>,\n a: ({ href, children }) => <SafeLink href={href}>{children}</SafeLink>,\n p: ({ children }) => <p>{withFilePills(children)}</p>,\n li: ({ children }) => <li>{withFilePills(children)}</li>,\n td: ({ children }) => <td>{withFilePills(children)}</td>,\n }}\n >\n {source}\n </ReactMarkdown>\n </div>\n );\n});\n\nfunction SafeLink({ href, children }: { href?: string; children: ReactNode }) {\n useLang();\n const ctx = useContext(WorkspaceContext);\n const [done, setDone] = useState(false);\n const isExternal = !!href && /^https?:\\/\\//i.test(href);\n const onClick = async (e: React.MouseEvent) => {\n e.preventDefault();\n if (!href) return;\n if (isExternal) {\n try {\n await openUrl(href);\n } catch {\n window.open(href, \"_blank\", \"noopener,noreferrer\");\n }\n return;\n }\n try {\n const stripped = href.replace(/^file:\\/\\//, \"\");\n const abs = resolveAgainstWorkspace(stripped, ctx.dir);\n await openWithEditor(ctx.editor, abs);\n } catch {\n try {\n await navigator.clipboard.writeText(href);\n setDone(true);\n setTimeout(() => setDone(false), 1200);\n } catch {\n /* ignore */\n }\n }\n };\n return (\n <a\n href={href ?? \"#\"}\n onClick={onClick}\n className={`md-link ${isExternal ? \"external\" : \"local\"} ${done ? \"done\" : \"\"}`}\n title={\n isExternal\n ? t(\"markdown.externalLinkTitle\", { href: href ?? \"\" })\n : t(\"markdown.localLinkTitle\", { href: href ?? \"\" })\n }\n >\n {children}\n {isExternal ? (\n <ExternalLink size={10} className=\"md-link-icon\" />\n ) : done ? (\n <Check size={10} className=\"md-link-icon\" />\n ) : null}\n </a>\n );\n}\n\nexport function extractFencedLang(children: ReactNode): string {\n for (const kid of Children.toArray(children)) {\n if (isValidElement(kid)) {\n const cls = (kid.props as Record<string, unknown>).className;\n if (typeof cls === \"string\") {\n const m = cls.match(/language-([\\w-]+)/);\n if (m) return m[1]!;\n }\n }\n }\n return \"text\";\n}\n\nfunction flattenChildText(node: ReactNode): string {\n if (typeof node === \"string\" || typeof node === \"number\") return String(node);\n if (Array.isArray(node)) return node.map(flattenChildText).join(\"\");\n if (isValidElement(node))\n return flattenChildText((node.props as { children?: ReactNode }).children);\n return \"\";\n}\n\nfunction CodeBlock({ lang, text }: { lang: string; text: string }): ReactNode {\n useLang();\n const [copied, setCopied] = useState(false);\n const onCopy = async () => {\n try {\n await navigator.clipboard.writeText(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 1400);\n } catch {\n /* ignore */\n }\n };\n return (\n <div className=\"codeblock\">\n <div className=\"codeblock-head\">\n <span className=\"codeblock-lang\">{lang}</span>\n <button type=\"button\" className={`copy-btn ${copied ? \"done\" : \"\"}`} onClick={onCopy}>\n {copied ? <Check size={11} /> : <Copy size={11} />}\n {copied ? t(\"markdown.copied\") : t(\"markdown.copy\")}\n </button>\n </div>\n <CodeView text={text} lang={lang} />\n </div>\n );\n}\n","import type { SVGProps } from \"react\";\n\ntype IconProps = SVGProps<SVGSVGElement> & { size?: number };\n\nfunction Ic({ size = 14, children, ...rest }: IconProps & { children: React.ReactNode }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...rest}\n >\n {children}\n </svg>\n );\n}\n\nexport const I = {\n plus: (p: IconProps) => (<Ic {...p}><path d=\"M12 5v14M5 12h14\" /></Ic>),\n search: (p: IconProps) => (<Ic {...p}><circle cx=\"11\" cy=\"11\" r=\"7\" /><path d=\"m20 20-3.5-3.5\" /></Ic>),\n send: (p: IconProps) => (<Ic {...p}><path d=\"M4 12 20 4l-6 16-3-7-7-1Z\" /></Ic>),\n chev: (p: IconProps) => (<Ic {...p}><path d=\"m6 9 6 6 6-6\" /></Ic>),\n chevR: (p: IconProps) => (<Ic {...p}><path d=\"m9 6 6 6-6 6\" /></Ic>),\n check: (p: IconProps) => (<Ic {...p}><path d=\"m5 12 5 5L20 7\" /></Ic>),\n x: (p: IconProps) => (<Ic {...p}><path d=\"M6 6l12 12M18 6 6 18\" /></Ic>),\n terminal: (p: IconProps) => (<Ic {...p}><rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" /><path d=\"m7 9 3 3-3 3M13 15h4\" /></Ic>),\n brain: (p: IconProps) => (\n <Ic {...p}>\n <path d=\"M9 4a3 3 0 0 0-3 3v0a3 3 0 0 0-2 5 3 3 0 0 0 2 5 3 3 0 0 0 3 3h0a3 3 0 0 0 3-3V4\" />\n <path d=\"M15 4a3 3 0 0 1 3 3 3 3 0 0 1 2 5 3 3 0 0 1-2 5 3 3 0 0 1-3 3\" />\n </Ic>\n ),\n list: (p: IconProps) => (<Ic {...p}><path d=\"M4 6h2M4 12h2M4 18h2M9 6h11M9 12h11M9 18h11\" /></Ic>),\n diff: (p: IconProps) => (<Ic {...p}><path d=\"M7 4v11a3 3 0 0 0 3 3h2M17 20V9a3 3 0 0 0-3-3h-2\" /><circle cx=\"7\" cy=\"20\" r=\"2\" /><circle cx=\"17\" cy=\"4\" r=\"2\" /></Ic>),\n globe: (p: IconProps) => (<Ic {...p}><circle cx=\"12\" cy=\"12\" r=\"9\" /><path d=\"M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18\" /></Ic>),\n link: (p: IconProps) => (<Ic {...p}><path d=\"M10 14a4 4 0 0 1 0-6l3-3a4 4 0 0 1 6 6l-2 2\" /><path d=\"M14 10a4 4 0 0 1 0 6l-3 3a4 4 0 0 1-6-6l2-2\" /></Ic>),\n wrench: (p: IconProps) => (<Ic {...p}><path d=\"M14 7a4 4 0 1 0 4 4l3 3-3 3-3-3a4 4 0 0 1-4-4l-3-3-3 3 3 3a4 4 0 0 0 6 0\" /></Ic>),\n bot: (p: IconProps) => (<Ic {...p}><rect x=\"4\" y=\"7\" width=\"16\" height=\"12\" rx=\"3\" /><path d=\"M12 3v4M8 12h.01M16 12h.01M9 16h6\" /></Ic>),\n archive: (p: IconProps) => (<Ic {...p}><rect x=\"3\" y=\"3\" width=\"18\" height=\"5\" rx=\"1\" /><path d=\"M5 8v11a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V8M10 12h4\" /></Ic>),\n bookmark: (p: IconProps) => (<Ic {...p}><path d=\"M6 3h12v18l-6-4-6 4Z\" /></Ic>),\n warning: (p: IconProps) => (<Ic {...p}><path d=\"M12 3 2 21h20Z\" /><path d=\"M12 10v5M12 18h.01\" /></Ic>),\n zap: (p: IconProps) => (<Ic {...p}><path d=\"M13 3 4 14h7l-1 7 9-11h-7Z\" /></Ic>),\n database: (p: IconProps) => (<Ic {...p}><ellipse cx=\"12\" cy=\"5\" rx=\"8\" ry=\"3\" /><path d=\"M4 5v6c0 1.7 3.6 3 8 3s8-1.3 8-3V5M4 11v6c0 1.7 3.6 3 8 3s8-1.3 8-3v-6\" /></Ic>),\n cpu: (p: IconProps) => (<Ic {...p}><rect x=\"5\" y=\"5\" width=\"14\" height=\"14\" rx=\"2\" /><rect x=\"9\" y=\"9\" width=\"6\" height=\"6\" /><path d=\"M9 2v3M15 2v3M9 19v3M15 19v3M2 9h3M2 15h3M19 9h3M19 15h3\" /></Ic>),\n coin: (p: IconProps) => (<Ic {...p}><circle cx=\"12\" cy=\"12\" r=\"9\" /><path d=\"M12 7v10M9 10h4a2 2 0 0 1 0 4H9\" /></Ic>),\n file: (p: IconProps) => (<Ic {...p}><path d=\"M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9Z\" /><path d=\"M14 3v6h6\" /></Ic>),\n folder: (p: IconProps) => (<Ic {...p}><path d=\"M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z\" /></Ic>),\n image: (p: IconProps) => (<Ic {...p}><rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" /><circle cx=\"9\" cy=\"10\" r=\"2\" /><path d=\"m3 18 5-5 4 4 3-3 6 6\" /></Ic>),\n paperclip: (p: IconProps) => (<Ic {...p}><path d=\"M21 12 12 21a5 5 0 0 1-7-7L14 5a3 3 0 0 1 4 4l-9 9a1 1 0 0 1-2-2l8-8\" /></Ic>),\n mic: (p: IconProps) => (<Ic {...p}><rect x=\"9\" y=\"3\" width=\"6\" height=\"12\" rx=\"3\" /><path d=\"M5 11a7 7 0 0 0 14 0M12 18v3M9 21h6\" /></Ic>),\n sun: (p: IconProps) => (<Ic {...p}><circle cx=\"12\" cy=\"12\" r=\"4\" /><path d=\"M12 2v2M12 20v2M2 12h2M20 12h2M5 5l1.5 1.5M17.5 17.5 19 19M5 19l1.5-1.5M17.5 6.5 19 5\" /></Ic>),\n moon: (p: IconProps) => (<Ic {...p}><path d=\"M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8Z\" /></Ic>),\n panel_l: (p: IconProps) => (<Ic {...p}><rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" /><path d=\"M9 4v16\" /></Ic>),\n panel_r: (p: IconProps) => (<Ic {...p}><rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" /><path d=\"M15 4v16\" /></Ic>),\n cog: (p: IconProps) => (<Ic {...p}><path d=\"M12 3.6 19.2 7.8v8.4L12 20.4 4.8 16.2V7.8Z\" /><circle cx=\"12\" cy=\"12\" r=\"3.7\" /></Ic>),\n stop: (p: IconProps) => (<Ic {...p}><rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\" /></Ic>),\n play: (p: IconProps) => (<Ic {...p}><path d=\"M7 5v14l12-7Z\" /></Ic>),\n more: (p: IconProps) => (<Ic {...p}><circle cx=\"6\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" /><circle cx=\"12\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" /><circle cx=\"18\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" /></Ic>),\n pin: (p: IconProps) => (<Ic {...p}><path d=\"M15 3 9 9l-4 1 9 9 1-4 6-6ZM4 20l5-5\" /></Ic>),\n rotate: (p: IconProps) => (<Ic {...p}><path d=\"M3 12a9 9 0 1 0 3-6.7L3 8\" /><path d=\"M3 3v5h5\" /></Ic>),\n branch: (p: IconProps) => (<Ic {...p}><circle cx=\"6\" cy=\"4\" r=\"2\" /><circle cx=\"6\" cy=\"20\" r=\"2\" /><circle cx=\"18\" cy=\"8\" r=\"2\" /><path d=\"M6 6v12M6 14a6 6 0 0 0 6-6h4\" /></Ic>),\n at: (p: IconProps) => (<Ic {...p}><circle cx=\"12\" cy=\"12\" r=\"4\" /><path d=\"M16 8v6a3 3 0 0 0 5-2 9 9 0 1 0-4 7\" /></Ic>),\n slash: (p: IconProps) => (<Ic {...p}><path d=\"M16 4 8 20\" /></Ic>),\n layers: (p: IconProps) => (<Ic {...p}><path d=\"m12 3 9 5-9 5-9-5Z\" /><path d=\"m3 13 9 5 9-5M3 18l9 5 9-5\" /></Ic>),\n download: (p: IconProps) => (<Ic {...p}><path d=\"M12 4v12M6 12l6 6 6-6M4 20h16\" /></Ic>),\n upload: (p: IconProps) => (<Ic {...p}><path d=\"M12 20V8M6 12l6-6 6 6M4 4h16\" /></Ic>),\n history: (p: IconProps) => (<Ic {...p}><path d=\"M3 12a9 9 0 1 0 3-6.7L3 8M12 7v5l3 2\" /></Ic>),\n shield: (p: IconProps) => (<Ic {...p}><path d=\"M12 3 4 6v6c0 5 3.5 8 8 9 4.5-1 8-4 8-9V6Z\" /><path d=\"m9 12 2 2 4-4\" /></Ic>),\n warn: (p: IconProps) => (<Ic {...p}><path d=\"M12 3 2 21h20Z\" /><path d=\"M12 10v5M12 18h.01\" /></Ic>),\n help: (p: IconProps) => (<Ic {...p}><circle cx=\"12\" cy=\"12\" r=\"9\" /><path d=\"M9.5 9a2.5 2.5 0 0 1 5 0c0 1.5-2.5 2-2.5 4M12 17h.01\" /></Ic>),\n refresh: (p: IconProps) => (<Ic {...p}><path d=\"M3 12a9 9 0 0 1 15-6.7L21 8M21 4v4h-4M21 12a9 9 0 0 1-15 6.7L3 16M3 20v-4h4\" /></Ic>),\n copy: (p: IconProps) => (<Ic {...p}><rect x=\"8\" y=\"8\" width=\"12\" height=\"12\" rx=\"2\" /><path d=\"M4 16V6a2 2 0 0 1 2-2h10\" /></Ic>),\n};\n\nexport type IconKey = keyof typeof I;\n","export const THEME = {\n DARK: \"dark\",\n LIGHT: \"light\",\n} as const;\n\nexport type Theme = (typeof THEME)[keyof typeof THEME];\n\nexport function isTheme(value: unknown): value is Theme {\n return value === THEME.DARK || value === THEME.LIGHT;\n}\n\nexport const THEME_STYLE = {\n GRAPHITE: \"graphite\",\n SANDSTONE: \"sandstone\",\n PORCELAIN: \"porcelain\",\n MIDNIGHT: \"midnight\",\n} as const;\n\nexport type ThemeStyle = (typeof THEME_STYLE)[keyof typeof THEME_STYLE];\n\nexport const DEFAULT_THEME_STYLE: Record<Theme, ThemeStyle> = {\n dark: THEME_STYLE.GRAPHITE,\n light: THEME_STYLE.SANDSTONE,\n};\n\nexport const THEME_STYLE_THEME: Record<ThemeStyle, Theme> = {\n graphite: THEME.DARK,\n sandstone: THEME.LIGHT,\n porcelain: THEME.LIGHT,\n midnight: THEME.DARK,\n};\n\nexport const THEME_STYLES = [\n THEME_STYLE.GRAPHITE,\n THEME_STYLE.SANDSTONE,\n THEME_STYLE.PORCELAIN,\n THEME_STYLE.MIDNIGHT,\n] as const;\n\nexport function isThemeStyle(value: unknown): value is ThemeStyle {\n return (\n value === THEME_STYLE.GRAPHITE ||\n value === THEME_STYLE.SANDSTONE ||\n value === THEME_STYLE.PORCELAIN ||\n value === THEME_STYLE.MIDNIGHT\n );\n}\n\nexport function themeForStyle(style: ThemeStyle): Theme {\n return THEME_STYLE_THEME[style];\n}\n\nexport function defaultStyleForTheme(theme: Theme): ThemeStyle {\n return DEFAULT_THEME_STYLE[theme];\n}\n\nexport const FONT_SCALE = {\n SMALL: \"small\",\n MEDIUM: \"medium\",\n LARGE: \"large\",\n} as const;\n\nexport type FontScale = (typeof FONT_SCALE)[keyof typeof FONT_SCALE];\n\nexport function isFontScale(value: unknown): value is FontScale {\n return value === FONT_SCALE.SMALL || value === FONT_SCALE.MEDIUM || value === FONT_SCALE.LARGE;\n}\n\nexport const FONT_SCALE_ZOOM: Record<FontScale, number> = {\n small: 0.875,\n medium: 1.0,\n large: 1.125,\n};\n\nexport const FONT_FAMILY = {\n SANS: \"sans\",\n SYSTEM: \"system\",\n SERIF: \"serif\",\n} as const;\n\nexport type FontFamily = (typeof FONT_FAMILY)[keyof typeof FONT_FAMILY];\n\nexport function isFontFamily(value: unknown): value is FontFamily {\n return value === FONT_FAMILY.SANS || value === FONT_FAMILY.SYSTEM || value === FONT_FAMILY.SERIF;\n}\n\nexport const FONT_FAMILY_STACK: Record<FontFamily, string> = {\n sans: '\"Geist\", system-ui, sans-serif',\n system: '-apple-system, system-ui, \"Segoe UI\", Roboto, sans-serif',\n serif: 'Georgia, \"Times New Roman\", serif',\n};\n","const SESSION_PARAM = \"session\";\n\nexport function readSessionFromUrl(): string | null {\n if (typeof window === \"undefined\") return null;\n const raw = new URLSearchParams(window.location.search).get(SESSION_PARAM);\n if (!raw) return null;\n const trimmed = raw.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nexport function writeSessionToUrl(name: string | null): void {\n if (typeof window === \"undefined\") return;\n const url = new URL(window.location.href);\n if (name && name.trim().length > 0) {\n url.searchParams.set(SESSION_PARAM, name);\n } else {\n url.searchParams.delete(SESSION_PARAM);\n }\n if (url.href === window.location.href) return;\n window.history.replaceState(null, \"\", url.href);\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { I } from \"../icons\";\nimport { t, useLang } from \"../i18n\";\n\nexport function fmtElapsed(ms: number): string {\n const s = ms / 1000;\n return s < 10 ? `${s.toFixed(1)}s` : `${Math.floor(s)}s`;\n}\n\nexport function useElapsed(active: boolean, startAt?: number): number {\n const [ms, setMs] = useState(0);\n const start = useRef<number | null>(null);\n useEffect(() => {\n if (!active) {\n setMs(0);\n start.current = null;\n return;\n }\n start.current = startAt ?? performance.now();\n const id = setInterval(() => {\n if (start.current !== null) setMs(performance.now() - start.current);\n }, 80);\n return () => clearInterval(id);\n }, [active, startAt]);\n return ms;\n}\n\nexport function ThinkingPill({\n phase = \"thinking\",\n label,\n elapsedMs,\n}: {\n phase?: \"queued\" | \"thinking\" | \"tool\";\n label: string;\n elapsedMs: number;\n}) {\n const color =\n phase === \"queued\"\n ? \"var(--muted)\"\n : phase === \"tool\"\n ? \"var(--warning)\"\n : \"var(--accent)\";\n return (\n <div className=\"thinking\">\n <span className=\"dots\" style={{ color }}>\n <span style={{ background: color }} />\n <span style={{ background: color }} />\n <span style={{ background: color }} />\n </span>\n <span className=\"label\">\n <span className=\"sh\">{label}</span>\n </span>\n <span className=\"timer\">{fmtElapsed(elapsedMs)}</span>\n </div>\n );\n}\n\nexport function LiveReasoning({ lines }: { lines: string[] }) {\n useLang();\n return (\n <div className=\"live-reason\">\n <div className=\"head\">\n <span className=\"dot\" /> {t(\"live.reasoning\")}\n </div>\n {lines.map((line, i) => (\n <div key={i}>\n {line}\n {i === lines.length - 1 ? <span className=\"stream-caret\" /> : null}\n </div>\n ))}\n </div>\n );\n}\n\nexport function ToolRunningCard({\n kind = \"tool\",\n name,\n elapsedMs,\n logLines,\n}: {\n kind?: \"shell\" | \"fetch\" | \"search\" | \"tool\";\n name: string;\n elapsedMs: number;\n logLines?: { text: string; tone?: \"ok\" | \"dim\" }[];\n}) {\n useLang();\n const ic =\n kind === \"shell\" ? <I.terminal size={12} /> : kind === \"fetch\" ? <I.globe size={12} /> : kind === \"search\" ? <I.search size={12} /> : <I.wrench size={12} />;\n return (\n <div className=\"skel-card\">\n <div className=\"h\">\n <span className=\"ico\">{ic}</span>\n <span className=\"kind\">{kind}</span>\n <span style={{ color: \"var(--fg)\", fontWeight: 500 }}>{name}</span>\n <span className=\"grow\" />\n <span className=\"spin-meta\" role=\"img\" aria-label={t(\"live.running\")} title={t(\"live.running\")} />\n <span className=\"timer\">{fmtElapsed(elapsedMs)}</span>\n </div>\n {logLines && logLines.length > 0 ? (\n <div className=\"live-log\">\n {logLines.map((ln, i) => (\n <div\n key={i}\n className={`line ${ln.tone ?? \"\"}`}\n style={{ animationDelay: `${i * 0.25}s` }}\n >\n {ln.text}\n </div>\n ))}\n </div>\n ) : (\n <div className=\"body\">\n <div className=\"skel-line w-90\" />\n <div className=\"skel-line w-70\" />\n <div className=\"skel-line w-60\" />\n </div>\n )}\n </div>\n );\n}\n\nexport function PendingUserMsg({ text, elapsedMs }: { text: string; elapsedMs: number }) {\n useLang();\n return (\n <div className=\"msg user\">\n <div className=\"avatar\">YOU</div>\n <div className=\"body\">\n <div className=\"who\">\n <span className=\"name\">{t(\"live.you\")}</span>\n <span className=\"time\">\n {t(\"live.secondsAgo\", { seconds: (elapsedMs / 1000).toFixed(1) })}\n </span>\n </div>\n <div className=\"msg-text user-pending\">{text}</div>\n <div className=\"user-status\">\n <span className=\"spin\" />\n <span>{t(\"live.deliveredWaiting\")}</span>\n </div>\n </div>\n </div>\n );\n}\n","import {\n type ChangeEvent,\n type KeyboardEvent,\n type RefObject,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type React from \"react\";\nimport { open as openFileDialog } from \"@tauri-apps/plugin-dialog\";\nimport { t, type TKey } from \"../i18n\";\nimport { I } from \"../icons\";\nimport { fmtElapsed } from \"./live\";\nimport { Shortcut } from \"./shortcut\";\n\nexport type ReasoningEffort = \"low\" | \"medium\" | \"high\" | \"max\";\nexport type EditMode = \"review\" | \"auto\" | \"yolo\" | \"plan\";\n\ntype ModeEntry = { k: EditMode; label: TKey; icon: React.ReactNode; hint: TKey };\n\nconst EFFORTS: readonly ReasoningEffort[] = [\"low\", \"medium\", \"high\", \"max\"];\n\nconst MODE_INFO: ModeEntry[] = [\n { k: \"plan\", label: \"editMode.plan\", icon: <I.list size={11} />, hint: \"editMode.planHint\" },\n { k: \"review\", label: \"editMode.review\", icon: <I.shield size={11} />, hint: \"editMode.reviewHint\" },\n { k: \"auto\", label: \"editMode.auto\", icon: <I.zap size={11} />, hint: \"editMode.autoHint\" },\n { k: \"yolo\", label: \"editMode.yolo\", icon: <I.warn size={11} />, hint: \"editMode.yoloHint\" },\n];\n\nexport function ModeSwitch({\n mode,\n onChange,\n}: {\n mode: EditMode;\n onChange: (m: EditMode) => void;\n}) {\n return (\n <div className=\"mode-switch\" data-mode={mode}>\n {MODE_INFO.map((m) => (\n <button\n key={m.k}\n type=\"button\"\n className=\"ms-seg\"\n data-on={mode === m.k}\n data-k={m.k}\n onClick={() => onChange(m.k)}\n title={t(m.hint)}\n >\n {m.icon}\n <span>{t(m.label)}</span>\n </button>\n ))}\n </div>\n );\n}\n\nexport type SlashCmd = {\n cmd: string;\n desc: string;\n run: () => void;\n kb?: string;\n insertOnly?: boolean;\n};\nexport type MentionItem = {\n name: string;\n kind: \"file\" | \"dir\" | \"url\" | \"agent\" | \"clip\";\n desc?: string;\n};\n\nexport type Chip =\n | { kind: \"at\"; label: string }\n | { kind: \"slash\"; label: string };\n\ntype Popup =\n | { kind: \"slash\"; query: string }\n | { kind: \"at\"; query: string; nonce: number }\n | null;\n\nfunction slashIcon(cmd: string) {\n const m: Record<string, React.ReactNode> = {\n \"/clear\": <I.x size={12} />,\n \"/new\": <I.plus size={12} />,\n \"/abort\": <I.stop size={12} />,\n \"/copy\": <I.layers size={12} />,\n \"/export\": <I.download size={12} />,\n \"/model\": <I.cpu size={12} />,\n \"/theme\": <I.sun size={12} />,\n \"/lang\": <I.globe size={12} />,\n };\n return m[cmd] || <I.slash size={12} />;\n}\n\n/** Parent dir of the current @ query, with trailing slash. `null` = no parent to show (at workspace root). */\nfunction parentOfAtQuery(query: string): string | null {\n const normalized = query.replace(/\\\\/g, \"/\");\n const trailingSlash = normalized.endsWith(\"/\");\n const lastSlash = normalized.lastIndexOf(\"/\");\n if (lastSlash < 0) return null;\n const dirContext = trailingSlash ? normalized.slice(0, -1) : normalized.slice(0, lastSlash);\n if (!dirContext) return null;\n const parentIdx = dirContext.lastIndexOf(\"/\");\n return parentIdx >= 0 ? `${dirContext.slice(0, parentIdx)}/` : \"\";\n}\n\nfunction atIcon(k: MentionItem[\"kind\"]) {\n if (k === \"file\") return <I.file size={12} />;\n if (k === \"dir\") return <I.folder size={12} />;\n if (k === \"url\") return <I.globe size={12} />;\n if (k === \"agent\") return <I.bot size={12} />;\n if (k === \"clip\") return <I.layers size={12} />;\n return <I.at size={12} />;\n}\n\nexport function Composer({\n draft,\n setDraft,\n onSend,\n onAbort,\n disabled,\n busy,\n busyLabel,\n busyElapsedMs,\n modelLabel,\n reasoningEffort,\n onModelChange,\n onEffortChange,\n editMode,\n onEditModeChange,\n textareaRef,\n slashCommands,\n onMentionQuery,\n onMentionPreview,\n onMentionPicked,\n mentionResults,\n workspaceDir,\n queuedSends,\n onQueueWhileBusy,\n onDequeueSend,\n}: {\n draft: string;\n setDraft: (s: string) => void;\n onSend: () => void;\n onAbort: () => void;\n disabled?: boolean;\n busy?: boolean;\n /** Replaces the hint-row left side while the agent is running — typically \"Reasoning\" or \"Skill · <name>\". */\n busyLabel?: string;\n busyElapsedMs?: number;\n modelLabel: string;\n reasoningEffort: ReasoningEffort;\n onModelChange: (model: string) => void;\n onEffortChange: (effort: ReasoningEffort) => void;\n editMode: EditMode;\n onEditModeChange: (mode: EditMode) => void;\n textareaRef: RefObject<HTMLTextAreaElement | null>;\n slashCommands: SlashCmd[];\n onMentionQuery?: (q: string, nonce: number) => void;\n onMentionPreview?: (path: string, nonce: number) => void;\n onMentionPicked?: (path: string) => void;\n mentionResults?: { nonce: number; query: string; results: string[] } | null;\n workspaceDir?: string;\n /** Messages typed while busy=true; rendered as removable chips above the textarea and auto-drained FIFO on turn-complete. */\n queuedSends?: string[];\n /** Called when the user presses Enter while busy with a non-empty draft. Owns clearing the draft. */\n onQueueWhileBusy?: (text: string) => void;\n onDequeueSend?: (index: number) => void;\n}) {\n const [chips, setChips] = useState<Chip[]>([]);\n const [popup, setPopup] = useState<Popup>(null);\n const [activeIdx, setActiveIdx] = useState(0);\n const [modelMenuOpen, setModelMenuOpen] = useState(false);\n const nonceRef = useRef(0);\n const modelWrapRef = useRef<HTMLDivElement>(null);\n // macOS Chinese IME fires compositionend before the confirm keydown.\n const composingRef = useRef(false);\n const compositionEndedAtRef = useRef(0);\n\n // Programmatic draft transitions to \"/\" (e.g. /help suggestion in EmptyState, #929) must open the slash popup, since handleChange only fires on actual user input.\n const prevDraftRef = useRef(draft);\n useEffect(() => {\n const prev = prevDraftRef.current;\n prevDraftRef.current = draft;\n if (draft === \"/\" && prev !== \"/\") {\n setPopup({ kind: \"slash\", query: \"\" });\n }\n }, [draft]);\n\n useEffect(() => {\n if (!modelMenuOpen) return;\n const onDown = (e: MouseEvent) => {\n if (\n modelWrapRef.current &&\n !modelWrapRef.current.contains(e.target as Node)\n ) {\n setModelMenuOpen(false);\n }\n };\n window.addEventListener(\"mousedown\", onDown);\n return () => window.removeEventListener(\"mousedown\", onDown);\n }, [modelMenuOpen]);\n\n const attachFile = async (filter?: \"image\") => {\n try {\n const picked = await openFileDialog({\n multiple: false,\n directory: false,\n defaultPath: workspaceDir,\n filters:\n filter === \"image\"\n ? [\n {\n name: t(\"composer.imageFilterName\"),\n extensions: [\"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"svg\"],\n },\n ]\n : undefined,\n });\n if (typeof picked !== \"string\" || !picked) return;\n const rel =\n workspaceDir && picked.startsWith(workspaceDir)\n ? picked.slice(workspaceDir.length).replace(/^[\\\\/]+/, \"\")\n : picked;\n setDraft(draft ? `${draft.replace(/\\s+$/, \"\")} @${rel} ` : `@${rel} `);\n setChips((c) => [...c, { kind: \"at\", label: rel }]);\n onMentionPicked?.(rel);\n textareaRef.current?.focus();\n } catch (err) {\n console.error(\"attach failed\", err);\n }\n };\n\n const slashItems = useMemo(() => {\n if (!popup || popup.kind !== \"slash\") return [];\n const q = popup.query.toLowerCase();\n if (!q) return slashCommands;\n return slashCommands.filter((c) => c.cmd.toLowerCase().includes(q));\n }, [popup, slashCommands]);\n\n const atItems = useMemo<MentionItem[]>(() => {\n if (!popup || popup.kind !== \"at\") return [];\n if (!mentionResults || mentionResults.nonce !== popup.nonce) return [];\n const base: MentionItem[] = mentionResults.results.map((path) => ({\n name: path,\n kind: path.endsWith(\"/\") || path.endsWith(\"\\\\\") ? \"dir\" : \"file\",\n desc: path,\n }));\n // \"../\" entry (#1019): one level up whenever the @ query is inside a subdir.\n const parent = parentOfAtQuery(popup.query);\n if (parent !== null) {\n base.unshift({\n name: \"..\",\n kind: \"dir\",\n desc: parent ? `↑ ${parent}` : `↑ ${t(\"composer.workspaceRoot\")}`,\n });\n }\n return base;\n }, [popup, mentionResults]);\n\n const items =\n popup?.kind === \"slash\" ? slashItems : popup?.kind === \"at\" ? atItems : [];\n\n useEffect(() => {\n setActiveIdx(0);\n }, [items.length, popup?.kind]);\n\n useEffect(() => {\n if (!popup || popup.kind !== \"at\" || !onMentionQuery) return;\n onMentionQuery(popup.query, popup.nonce);\n }, [popup, onMentionQuery]);\n\n const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {\n const v = e.target.value;\n setDraft(v);\n const trail = v.match(/(^|\\s)([/@])([^\\s]*)$/);\n if (trail) {\n const sigil = trail[2];\n const query = trail[3] ?? \"\";\n if (sigil === \"/\") {\n setPopup({ kind: \"slash\", query });\n } else {\n const nonce = ++nonceRef.current;\n setPopup({ kind: \"at\", query, nonce });\n }\n } else if (popup) {\n setPopup(null);\n }\n };\n\n const dismiss = () => setPopup(null);\n\n const pickItem = (idx: number) => {\n const it = items[idx];\n if (!it || !popup) return;\n if (popup.kind === \"slash\") {\n const cmd = (it as SlashCmd).cmd;\n const insertOnly = (it as SlashCmd).insertOnly === true;\n if (insertOnly) {\n const next = draft.replace(/[/@][^\\s]*$/, \"\").trimEnd();\n setDraft(next ? `${next} ${cmd} ` : `${cmd} `);\n setChips((c) => [...c, { kind: \"slash\", label: cmd.replace(/^\\//, \"\") }]);\n } else {\n const next = draft.replace(/[/@][^\\s]*$/, \"\").trimEnd();\n setDraft(next);\n setChips((c) => [...c, { kind: \"slash\", label: cmd.replace(/^\\//, \"\") }]);\n (it as SlashCmd).run();\n }\n } else {\n const mention = it as MentionItem;\n if (mention.name === \"..\") {\n const parent = parentOfAtQuery(popup.query) ?? \"\";\n const next = draft.replace(/[@][^\\s]*$/, `@${parent}`);\n setDraft(next);\n const nonce = ++nonceRef.current;\n setPopup({ kind: \"at\", query: parent, nonce });\n textareaRef.current?.focus();\n return;\n }\n const next = draft.replace(/[/@][^\\s]*$/, \"\").trimEnd();\n setDraft(next ? `${next} @${mention.name} ` : `@${mention.name} `);\n setChips((c) => [...c, { kind: \"at\", label: mention.name }]);\n onMentionPicked?.(mention.name);\n }\n setPopup(null);\n textareaRef.current?.focus();\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (popup) {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setActiveIdx((i) => (items.length ? (i + 1) % items.length : 0));\n return;\n }\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setActiveIdx((i) =>\n items.length ? (i - 1 + items.length) % items.length : 0,\n );\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n dismiss();\n return;\n }\n if (e.key === \"Tab\" && popup.kind === \"at\" && items.length > 0) {\n // Tab on a directory enters it — replaces `@src` with `@src/`\n // and re-queries so the popup shows that directory's children.\n // `..` is the synthetic parent-dir entry (#1019); same shape\n // but rewrites to the parent path.\n const it = items[activeIdx];\n if (it && (it as MentionItem).kind === \"dir\") {\n e.preventDefault();\n const mention = it as MentionItem;\n if (mention.name === \"..\") {\n const parent = parentOfAtQuery(popup.query) ?? \"\";\n const next = draft.replace(/[@][^\\s]*$/, `@${parent}`);\n setDraft(next);\n const nonce = ++nonceRef.current;\n setPopup({ kind: \"at\", query: parent, nonce });\n return;\n }\n const dirPath = mention.name.replace(/\\/+$/, \"\");\n const next = draft.replace(/[@][^\\s]*$/, `@${dirPath}/`);\n setDraft(next);\n const nonce = ++nonceRef.current;\n setPopup({ kind: \"at\", query: `${dirPath}/`, nonce });\n return;\n }\n }\n if (e.key === \"Enter\") {\n if (items.length > 0) {\n e.preventDefault();\n pickItem(activeIdx);\n return;\n }\n dismiss();\n }\n }\n if (composingRef.current || Date.now() - compositionEndedAtRef.current < 50) return;\n if (e.key === \"Enter\" && !e.shiftKey && !popup) {\n e.preventDefault();\n if (busy) {\n const text = draft.trim();\n if (text && onQueueWhileBusy) {\n onQueueWhileBusy(text);\n setChips([]);\n }\n } else if (!disabled && draft.trim()) {\n onSend();\n setChips([]);\n }\n }\n };\n\n return (\n <div className=\"composer-wrap\">\n <div className=\"composer-inner\">\n {queuedSends && queuedSends.length > 0 ? (\n <div className=\"composer-queued\">\n <span className=\"composer-queued-label\">\n {t(\"composer.queueCount\", { count: queuedSends.length })}\n </span>\n {queuedSends.map((text, i) => (\n <span key={i} className=\"composer-queue-chip\" title={text}>\n <span className=\"text\">{text}</span>\n {onDequeueSend ? (\n <span className=\"x\" onClick={() => onDequeueSend(i)}>\n <I.x size={10} />\n </span>\n ) : null}\n </span>\n ))}\n </div>\n ) : null}\n\n <div className=\"hint-row\">\n {busy && busyLabel ? (\n <>\n <span className=\"composer-busy-status\">\n <span className=\"composer-busy-pip\" />\n <span className=\"composer-busy-label\">{busyLabel}</span>\n <span className=\"composer-busy-time\">\n {fmtElapsed(busyElapsedMs ?? 0)}\n </span>\n </span>\n <span className=\"grow\" />\n <ModeSwitch mode={editMode} onChange={onEditModeChange} />\n <span className=\"hint-sep\" />\n <span>\n <Shortcut keys={[\"enter\"]} /> {t(\"composer.queue\")} · {\" \"}\n <Shortcut keys={[\"esc\"]} /> {t(\"composer.interrupt\")}\n </span>\n </>\n ) : (\n <>\n <span>\n <Shortcut keys={[\"/\"]} /> {t(\"composer.commands\")} · {\" \"}\n <Shortcut keys={[\"@\"]} /> {t(\"composer.mentionFiles\")}\n · <Shortcut keys={[\"mod\", \"K\"]} /> {t(\"composer.commandPalette\")}\n </span>\n <span className=\"grow\" />\n <ModeSwitch mode={editMode} onChange={onEditModeChange} />\n <span className=\"hint-sep\" />\n <span>\n <Shortcut keys={[\"enter\"]} /> {t(\"composer.send\")} {\" \"}\n <Shortcut keys={[\"shift\", \"enter\"]} /> {t(\"composer.newline\")}\n </span>\n </>\n )}\n </div>\n\n <div className=\"composer\">\n {chips.length > 0 ? (\n <div className=\"composer-tags\">\n {chips.map((c, i) => (\n <span key={i} className={`chip ${c.kind}`}>\n {c.kind === \"slash\" ? (\n <I.slash size={11} />\n ) : (\n <I.at size={11} />\n )}\n <span>{c.label}</span>\n <span\n className=\"x\"\n onClick={() =>\n setChips((cs) => cs.filter((_, j) => j !== i))\n }\n >\n <I.x size={10} />\n </span>\n </span>\n ))}\n </div>\n ) : null}\n\n <textarea\n ref={textareaRef}\n value={draft}\n placeholder={t(\"composer.placeholder\")}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onCompositionStart={() => {\n composingRef.current = true;\n }}\n onCompositionEnd={() => {\n composingRef.current = false;\n compositionEndedAtRef.current = Date.now();\n }}\n rows={2}\n disabled={disabled}\n />\n\n <div className=\"composer-foot\">\n <button\n type=\"button\"\n className=\"cf-btn\"\n title={t(\"composer.insertFile\")}\n onClick={() => void attachFile()}\n >\n <span className=\"ico\">\n <I.paperclip size={14} />\n </span>\n </button>\n <button\n type=\"button\"\n className=\"cf-btn\"\n title={t(\"composer.insertImage\")}\n onClick={() => void attachFile(\"image\")}\n >\n <span className=\"ico\">\n <I.image size={14} />\n </span>\n </button>\n <button\n type=\"button\"\n className=\"cf-btn\"\n onClick={() => setPopup({ kind: \"slash\", query: \"\" })}\n >\n <span className=\"ico\">\n <I.slash size={14} />\n </span>\n <span className=\"label\">{t(\"composer.commandsLabel\")}</span>\n </button>\n <button\n type=\"button\"\n className=\"cf-btn\"\n onClick={() => {\n const nonce = ++nonceRef.current;\n setPopup({ kind: \"at\", query: \"\", nonce });\n }}\n >\n <span className=\"ico\">\n <I.at size={14} />\n </span>\n <span className=\"label\">{t(\"composer.mentionLabel\")}</span>\n </button>\n\n <span className=\"grow\" />\n\n <div ref={modelWrapRef} style={{ position: \"relative\" }}>\n <button\n type=\"button\"\n className=\"model-pill\"\n onClick={() => setModelMenuOpen((v) => !v)}\n title={t(\"composer.switchModel\")}\n >\n <I.brain size={12} />\n <span>{modelLabel}</span>\n <span className=\"badge\">{reasoningEffort}</span>\n <I.chev size={10} />\n </button>\n {modelMenuOpen ? (\n <ModelEffortMenu\n modelLabel={modelLabel}\n currentEffort={reasoningEffort}\n onPickModel={(m) => {\n onModelChange(m);\n setModelMenuOpen(false);\n }}\n onPickEffort={(e) => {\n onEffortChange(e);\n setModelMenuOpen(false);\n }}\n />\n ) : null}\n </div>\n {busy ? (\n <button\n type=\"button\"\n className=\"send-btn\"\n style={{ background: \"var(--danger)\" }}\n onClick={onAbort}\n title={t(\"composer.interrupt\")}\n >\n <I.stop size={14} />\n </button>\n ) : (\n <button\n type=\"button\"\n className=\"send-btn\"\n disabled={disabled || !draft.trim()}\n onClick={() => {\n if (!disabled && draft.trim()) {\n onSend();\n setChips([]);\n }\n }}\n >\n <I.send size={14} />\n </button>\n )}\n </div>\n\n {popup ? (\n <Popup\n kind={popup.kind}\n items={items}\n activeIdx={activeIdx}\n onPick={(i) => pickItem(i)}\n onClose={dismiss}\n onHover={(i, item) => {\n setActiveIdx(i);\n if (popup.kind === \"at\" && onMentionPreview) {\n const path = (item as MentionItem).name;\n onMentionPreview(path, popup.nonce);\n }\n }}\n />\n ) : null}\n </div>\n </div>\n </div>\n );\n}\n\nfunction Popup({\n kind,\n items,\n activeIdx,\n onPick,\n onClose,\n onHover,\n}: {\n kind: \"slash\" | \"at\";\n items: (SlashCmd | MentionItem)[];\n activeIdx: number;\n onPick: (i: number) => void;\n onClose: () => void;\n onHover: (i: number, item: SlashCmd | MentionItem) => void;\n}) {\n const listRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n requestAnimationFrame(() => {\n const el = listRef.current?.querySelector<HTMLElement>(`[data-active=\"true\"]`);\n el?.scrollIntoView({ block: \"nearest\" });\n });\n }, [activeIdx]);\n\n return (\n <div className=\"popup\" onMouseDown={(e) => e.preventDefault()}>\n <div className=\"ph\">\n <span className=\"tok\">{kind === \"slash\" ? \"/\" : \"@\"}</span>\n <span>\n {kind === \"slash\"\n ? t(\"composer.slashHeader\")\n : t(\"composer.atHeader\")}\n </span>\n <span className=\"grow\" />\n <span style={{ cursor: \"pointer\" }} onClick={onClose}>\n <I.x size={11} />\n </span>\n </div>\n <div className=\"popup-list\" ref={listRef}>\n {items.length === 0 ? (\n <div\n style={{\n padding: \"12px 8px\",\n fontSize: 11.5,\n color: \"var(--muted-2)\",\n fontFamily: \"Geist Mono, monospace\",\n }}\n >\n {t(\"composer.noMatches\")}\n </div>\n ) : null}\n {items.map((it, i) => (\n <div\n key={i}\n className=\"popup-item\"\n data-active={i === activeIdx}\n onClick={() => onPick(i)}\n onMouseEnter={() => onHover(i, it)}\n >\n <span className=\"ico\">\n {kind === \"slash\"\n ? slashIcon((it as SlashCmd).cmd)\n : atIcon((it as MentionItem).kind)}\n </span>\n <div className=\"nm\">\n {kind === \"slash\" ? (\n <>\n <span className=\"cmd\">{(it as SlashCmd).cmd}</span>\n <span className=\"desc\">{(it as SlashCmd).desc}</span>\n </>\n ) : (\n <>\n <span>{(it as MentionItem).name}</span>\n {(it as MentionItem).desc ? (\n <div className=\"desc\">{(it as MentionItem).desc}</div>\n ) : null}\n </>\n )}\n </div>\n <span className=\"kb\">\n {kind === \"slash\" ? ((it as SlashCmd).kb ?? \"\") : \"\"}\n </span>\n </div>\n ))}\n </div>\n <div className=\"popup-foot\">\n <span>\n <Shortcut keys={[\"updown\"]} /> {t(\"composer.select\")}\n </span>\n <span>\n <Shortcut keys={[\"enter\"]} /> {t(\"composer.confirm\")}\n </span>\n <span>\n <Shortcut keys={[\"esc\"]} /> {t(\"composer.close\")}\n </span>\n </div>\n </div>\n );\n}\n\nconst KNOWN_MODELS: readonly string[] = [\"deepseek-v4-flash\", \"deepseek-v4-pro\"];\n\nfunction ModelEffortMenu({\n modelLabel,\n currentEffort,\n onPickModel,\n onPickEffort,\n}: {\n modelLabel: string;\n currentEffort: ReasoningEffort;\n onPickModel: (model: string) => void;\n onPickEffort: (effort: ReasoningEffort) => void;\n}) {\n const [draft, setDraft] = useState(modelLabel);\n return (\n <div\n className=\"popup\"\n style={{\n bottom: \"calc(100% + 6px)\",\n left: \"auto\",\n right: 0,\n width: 280,\n position: \"absolute\",\n }}\n >\n <div className=\"ph\">\n <span className=\"tok\">M</span>\n <span>{t(\"composer.switchModel\")}</span>\n </div>\n <div className=\"popup-list\">\n {KNOWN_MODELS.map((m) => (\n <div\n key={m}\n className=\"popup-item\"\n data-active={m === modelLabel}\n onClick={() => onPickModel(m)}\n >\n <span className=\"ico\">\n <I.brain size={12} />\n </span>\n <div className=\"nm\">\n <span className=\"cmd\">{m}</span>\n </div>\n </div>\n ))}\n <div style={{ padding: \"6px 8px\", display: \"flex\", gap: 6 }}>\n <input\n className=\"field mono\"\n style={{ flex: 1 }}\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n placeholder=\"custom model id\"\n />\n <button\n type=\"button\"\n className=\"btn\"\n disabled={!draft.trim() || draft.trim() === modelLabel}\n onClick={() => onPickModel(draft.trim())}\n >\n {t(\"composer.confirm\")}\n </button>\n </div>\n </div>\n <div className=\"ph\" style={{ marginTop: 4 }}>\n <span className=\"tok\">E</span>\n <span>{t(\"composer.switchEffort\")}</span>\n </div>\n <div className=\"popup-list\">\n {EFFORTS.map((e) => (\n <div\n key={e}\n className=\"popup-item\"\n data-active={e === currentEffort}\n onClick={() => onPickEffort(e)}\n >\n <span className=\"ico\">\n <I.cpu size={12} />\n </span>\n <div className=\"nm\">\n <span className=\"cmd\">{e}</span>\n <div className=\"desc\">{t(`effort.${e}Desc` as TKey)}</div>\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n","import { Component, type ReactNode } from \"react\";\nimport { t } from \"../i18n\";\n\ntype Props = { label: string; children: ReactNode };\ntype State = { error: Error | null };\n\nexport class PanelErrorBoundary extends Component<Props, State> {\n state: State = { error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { error };\n }\n\n componentDidCatch(error: Error, info: { componentStack?: string | null }): void {\n console.error(`[panel:${this.props.label}] render error`, error, info);\n }\n\n render(): ReactNode {\n if (!this.state.error) return this.props.children;\n return (\n <div\n className=\"ctx-empty\"\n style={{\n color: \"var(--danger, #e25555)\",\n padding: 12,\n fontSize: 12,\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n >\n {t(\"panel.renderError\", { panel: this.props.label })}\n {\": \"}\n {this.state.error.message}\n </div>\n );\n }\n}\n","import { useMemo, useState } from \"react\";\nimport type { SessionFile, Settings, UsageStats } from \"../App\";\nimport { t, useLang } from \"../i18n\";\nimport { I } from \"../icons\";\nimport type { McpSpecInfo, MemoryDetail, MemoryEntryInfo } from \"../protocol\";\nimport { PanelErrorBoundary } from \"./error-boundary\";\n\ntype Tab = \"files\" | \"tools\" | \"memory\" | \"rules\";\n\nconst CONTEXT_MAX_TOKENS = 1_000_000;\n\nexport function ContextPanel({\n settings,\n usage,\n mcpSpecs,\n mcpBridged,\n sessionFiles,\n memory,\n memoryDetail,\n onReadMemory,\n}: {\n settings: Settings | null;\n usage: UsageStats;\n mcpSpecs: McpSpecInfo[];\n mcpBridged: boolean;\n sessionFiles: SessionFile[];\n memory: MemoryEntryInfo[];\n memoryDetail: MemoryDetail | null;\n onReadMemory: (path: string) => void;\n}) {\n useLang();\n const [tab, setTab] = useState<Tab>(\"files\");\n const reserved = usage.reservedTokens;\n // After a warm cache turn the API counts the reserved prefix inside cacheHit;\n // subtract to keep the bar segments visually disjoint. Cold cache shows the\n // reserved portion in cacheMiss instead, so do the same for `used`.\n const cached = Math.max(0, usage.cacheHitTokens - reserved);\n const used = Math.max(0, usage.cacheMissTokens - Math.max(0, reserved - usage.cacheHitTokens));\n const reservedPct = Math.min(100, (reserved / CONTEXT_MAX_TOKENS) * 100);\n const usedPct = Math.min(100, (used / CONTEXT_MAX_TOKENS) * 100);\n const cachedPct = Math.min(100, (cached / CONTEXT_MAX_TOKENS) * 100);\n const free = Math.max(0, CONTEXT_MAX_TOKENS - reserved - used - cached);\n return (\n <aside className=\"ctx\">\n <div className=\"ctx-tabs\">\n <div className=\"ctx-tab\" data-active={tab === \"files\"} onClick={() => setTab(\"files\")}>\n {t(\"contextPanel.filesTab\")}\n </div>\n <div className=\"ctx-tab\" data-active={tab === \"tools\"} onClick={() => setTab(\"tools\")}>\n {t(\"contextPanel.toolsTab\")}\n </div>\n <div className=\"ctx-tab\" data-active={tab === \"memory\"} onClick={() => setTab(\"memory\")}>\n {t(\"contextPanel.memoryTab\")}\n </div>\n <div className=\"ctx-tab\" data-active={tab === \"rules\"} onClick={() => setTab(\"rules\")}>\n {t(\"contextPanel.rulesTab\")}\n </div>\n </div>\n\n <div className=\"ctx-body\">\n <div className=\"ctx-block\">\n <div className=\"h\">\n <span>{t(\"contextPanel.contextTokens\")}</span>\n <span className=\"right\">\n {(reserved + used + cached).toLocaleString()} /{\" \"}\n {CONTEXT_MAX_TOKENS.toLocaleString()}\n </span>\n </div>\n <div className=\"meter\">\n <span className=\"rsvd\" style={{ width: `${reservedPct}%` }} />\n <span className=\"cached\" style={{ width: `${cachedPct}%` }} />\n <span className=\"used\" style={{ width: `${usedPct}%` }} />\n </div>\n <div className=\"legend\">\n <span className=\"l\">\n <span className=\"sw r\" />\n {t(\"contextPanel.reservedKey\")} <span className=\"v\">{reserved.toLocaleString()}</span>\n </span>\n <span className=\"l\">\n <span className=\"sw c\" />\n {t(\"contextPanel.cacheKey\")} <span className=\"v\">{cached.toLocaleString()}</span>\n </span>\n <span className=\"l\">\n <span className=\"sw u\" />\n {t(\"contextPanel.usedKey\")} <span className=\"v\">{used.toLocaleString()}</span>\n </span>\n <span className=\"l\">\n {t(\"contextPanel.freeKey\")} <span className=\"v\">{free.toLocaleString()}</span>\n </span>\n </div>\n </div>\n\n <PanelErrorBoundary key={tab} label={tab}>\n {tab === \"files\" && <CtxFiles files={sessionFiles} />}\n {tab === \"tools\" && <CtxTools specs={mcpSpecs} bridged={mcpBridged} />}\n {tab === \"memory\" && (\n <CtxMemory entries={memory} detail={memoryDetail} onRead={onReadMemory} />\n )}\n {tab === \"rules\" && <CtxRules settings={settings} />}\n </PanelErrorBoundary>\n </div>\n </aside>\n );\n}\n\ntype TreeNode =\n | { kind: \"dir\"; depth: number; name: string; key: string }\n | { kind: \"file\"; depth: number; name: string; key: string; status: \"c\" | \"m\" };\n\nfunction buildSessionTree(files: SessionFile[]): TreeNode[] {\n const sorted = [...files].sort((a, b) =>\n a.path.replace(/\\\\/g, \"/\").localeCompare(b.path.replace(/\\\\/g, \"/\")),\n );\n const out: TreeNode[] = [];\n const seenDirs = new Set<string>();\n for (const f of sorted) {\n const parts = f.path.replace(/\\\\/g, \"/\").split(\"/\").filter(Boolean);\n if (parts.length === 0) continue;\n let prefix = \"\";\n for (let i = 0; i < parts.length - 1; i++) {\n const seg = parts[i] ?? \"\";\n prefix = prefix ? `${prefix}/${seg}` : seg;\n if (!seenDirs.has(prefix)) {\n seenDirs.add(prefix);\n out.push({ kind: \"dir\", depth: i, name: seg, key: `d:${prefix}` });\n }\n }\n const leaf = parts[parts.length - 1] ?? \"\";\n out.push({\n kind: \"file\",\n depth: parts.length - 1,\n name: leaf,\n key: `f:${f.path}`,\n status: f.status,\n });\n }\n return out;\n}\n\nfunction CtxFiles({ files }: { files: SessionFile[] }) {\n const tree = useMemo(() => buildSessionTree(files), [files]);\n return (\n <div className=\"ctx-block\">\n <div className=\"h\">\n <span>{t(\"contextPanel.filesTitle\")}</span>\n <span className=\"right\">\n {files.length === 0 ? \"—\" : t(\"contextPanel.filesCount\", { count: files.length })}\n </span>\n </div>\n <div className=\"tree\">\n {files.length === 0 ? (\n <div className=\"ctx-empty\">{t(\"contextPanel.noFilesMsg\")}</div>\n ) : (\n tree.map((n) =>\n n.kind === \"dir\" ? (\n <div className=\"node\" key={n.key} data-d={n.depth} data-kind=\"dir\">\n <span className=\"ico\">\n <I.folder size={12} />\n </span>\n <span className=\"nm\">{n.name}/</span>\n </div>\n ) : (\n <div\n className=\"node\"\n key={n.key}\n data-d={n.depth}\n data-kind=\"file\"\n title={n.name}\n >\n <span className=\"ico\">\n <I.file size={12} />\n </span>\n <span className=\"nm\">{n.name}</span>\n <span\n className=\"dot\"\n data-s={n.status}\n title={n.status === \"m\" ? t(\"contextPanel.fileModified\") : t(\"contextPanel.fileInContext\")}\n />\n </div>\n ),\n )\n )}\n </div>\n </div>\n );\n}\n\nfunction CtxTools({ specs, bridged }: { specs: McpSpecInfo[]; bridged: boolean }) {\n const readyCount = specs.filter((s) => s.status === \"connected\").length;\n return (\n <div className=\"ctx-block\">\n <div className=\"h\">\n <span>{t(\"contextPanel.mcpTitle\")}</span>\n <span className=\"right\">\n {specs.length === 0\n ? \"—\"\n : bridged\n ? t(\"contextPanel.mcpReadyAll\", { count: specs.length })\n : t(\"contextPanel.mcpReadySome\", { ready: readyCount, count: specs.length })}\n </span>\n </div>\n {specs.length === 0 ? (\n <div className=\"ctx-empty\">{t(\"contextPanel.mcpEmpty\")}</div>\n ) : (\n specs.map((s) => {\n const dot =\n s.status === \"connected\"\n ? \"ok\"\n : s.status === \"failed\" || s.parseError\n ? \"off\"\n : \"pending\";\n const suffix = s.statusReason\n ? ` · ${s.statusReason}`\n : s.status === \"connected\"\n ? typeof s.toolCount === \"number\"\n ? ` · ${t(\"contextPanel.mcpTools\", { count: s.toolCount })}`\n : ` · ${t(\"contextPanel.mcpReady\")}`\n : s.status === \"handshake\"\n ? ` · ${t(\"contextPanel.mcpConnecting\")}`\n : s.status === \"disabled\"\n ? ` · ${t(\"contextPanel.mcpDisabled\")}`\n : s.status === \"failed\"\n ? ` · ${t(\"contextPanel.mcpFailed\")}`\n : ` · ${t(\"contextPanel.mcpConfigured\")}`;\n return (\n <div className=\"mcp-row\" key={s.raw}>\n <span className=\"ico\">\n <I.wrench size={12} />\n </span>\n <div className=\"body\">\n <div className=\"n\">{s.name ?? s.summary}</div>\n <div className=\"m\">\n {s.transport}\n {suffix}\n </div>\n </div>\n <span className=\"status\" data-s={dot} />\n </div>\n );\n })\n )}\n </div>\n );\n}\n\nfunction CtxMemory({\n entries,\n detail,\n onRead,\n}: {\n entries: MemoryEntryInfo[];\n detail: MemoryDetail | null;\n onRead: (path: string) => void;\n}) {\n return (\n <div className=\"ctx-block\">\n <div className=\"h\">\n <span>{t(\"contextPanel.memoryTitle\")}</span>\n <span className=\"right\">\n {entries.length === 0 ? \"—\" : t(\"contextPanel.itemCount\", { count: entries.length })}\n </span>\n </div>\n {entries.length === 0 ? (\n <div className=\"ctx-empty\">{t(\"contextPanel.noMemoriesMsg\")}</div>\n ) : (\n <div className=\"mem\">\n {entries.map((m) => (\n <button\n type=\"button\"\n className=\"mem-row\"\n data-active={detail?.path === m.path}\n key={m.path}\n onClick={() => onRead(m.path)}\n >\n <span className=\"scope\" data-s={m.scope}>\n {m.scope === \"project\" ? t(\"contextPanel.scopeProject\") : t(\"contextPanel.scopeGlobal\")}\n </span>\n <span className=\"txt\">{m.description || m.name}</span>\n </button>\n ))}\n {detail ? <pre className=\"mem-detail\">{detail.body}</pre> : null}\n </div>\n )}\n </div>\n );\n}\n\nfunction CtxRules({ settings }: { settings: Settings | null }) {\n const editMode = settings?.editMode ?? \"review\";\n const items: { p: string; allow: boolean; desc: string }[] =\n editMode === \"yolo\"\n ? [{ p: \"*\", allow: true, desc: t(\"contextPanel.ruleYolo\") }]\n : editMode === \"auto\"\n ? [\n { p: \"read_file, list_directory, search_files, *\", allow: true, desc: t(\"contextPanel.ruleReadOnly\") },\n { p: \"run_command (allowlist)\", allow: true, desc: t(\"contextPanel.ruleShellAllowlist\") },\n { p: \"edit_file, write_file, run_command (other)\", allow: false, desc: t(\"contextPanel.ruleWritesAsk\") },\n ]\n : [\n { p: \"*\", allow: false, desc: t(\"contextPanel.ruleReview\") },\n ];\n return (\n <div className=\"ctx-block\">\n <div className=\"h\">\n <span>{t(\"contextPanel.autoApproveTitle\")}</span>\n <span className=\"right\">{editMode}</span>\n </div>\n {items.map((r) => (\n <div className=\"rule\" key={r.p}>\n <div className=\"top\">\n <span className={`pat ${r.allow ? \"\" : \"deny\"}`}>{r.p}</span>\n <span className={`sw ${r.allow ? \"\" : \"deny\"}`}>\n {r.allow ? t(\"contextPanel.allow\") : t(\"contextPanel.ask\")}\n </span>\n </div>\n <div className=\"desc\">{r.desc}</div>\n </div>\n ))}\n </div>\n );\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { I } from \"../icons\";\nimport { t, useLang } from \"../i18n\";\nimport type { JobInfo } from \"../protocol\";\nimport { Shortcut } from \"./shortcut\";\n\nexport function JobsPop({\n open,\n onClose,\n jobs,\n onStop,\n onStopAll,\n}: {\n open: boolean;\n onClose: () => void;\n jobs: JobInfo[];\n onStop: (jobId: number) => void;\n onStopAll: () => void;\n}) {\n useLang();\n const [tick, setTick] = useState(0);\n useEffect(() => {\n if (!open) return;\n const id = window.setInterval(() => setTick((n) => n + 1), 600);\n return () => window.clearInterval(id);\n }, [open]);\n useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onClose();\n }\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [open, onClose]);\n\n const running = useMemo(() => jobs.filter((j) => j.running), [jobs]);\n const exited = useMemo(() => jobs.filter((j) => !j.running), [jobs]);\n\n if (!open) return null;\n\n return (\n <div className=\"jobs-mask\" onClick={onClose}>\n <div className=\"jobs-pop\" onClick={(e) => e.stopPropagation()}>\n <div className=\"jobs-head\">\n <span className=\"ico\">\n <I.cpu size={13} />\n </span>\n <div>\n <div className=\"tt\">{t(\"jobs.title\")}</div>\n <div className=\"ss\">\n <span className=\"b ok\">{running.length}</span> {t(\"jobs.running\")} ·{\" \"}\n <span className=\"b mut\">{exited.length}</span> {t(\"jobs.exited\")}\n </div>\n </div>\n <span className=\"grow\" />\n {running.length > 0 ? (\n <button\n type=\"button\"\n className=\"btn danger sm\"\n onClick={onStopAll}\n title={t(\"jobs.stopAllTip\")}\n >\n <I.stop size={10} /> {t(\"jobs.stopAll\")}\n </button>\n ) : null}\n </div>\n\n <div className=\"jobs-body\">\n {jobs.length === 0 ? (\n <div className=\"jobs-empty\">{t(\"jobs.empty\")}</div>\n ) : (\n <>\n {running.length > 0 ? <div className=\"jobs-grp\">{t(\"jobs.running\")}</div> : null}\n {running.map((j) => (\n <JobRow key={j.id} job={j} tick={tick} onStop={onStop} />\n ))}\n {exited.length > 0 ? <div className=\"jobs-grp\">{t(\"jobs.exited\")}</div> : null}\n {exited.map((j) => (\n <JobRow key={j.id} job={j} tick={tick} onStop={onStop} />\n ))}\n </>\n )}\n </div>\n\n <div className=\"jobs-foot\">\n <div className=\"row\">\n <I.zap size={11} />\n <span>\n {t(\"jobs.running\")} <span className=\"v\">{running.length}</span>\n </span>\n <span>·</span>\n <span>\n {t(\"jobs.exited\")} <span className=\"v\">{exited.length}</span>\n </span>\n <span className=\"grow\" />\n <span>\n <Shortcut keys={[\"mod\", \"J\"]} /> {t(\"jobs.kbToggle\")} ·{\" \"}\n <Shortcut keys={[\"esc\"]} /> {t(\"jobs.kbClose\")}\n </span>\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction formatElapsed(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n const s = ms / 1000;\n if (s < 60) return `${s.toFixed(1)}s`;\n const m = Math.floor(s / 60);\n const r = Math.floor(s % 60);\n return `${m}m${r}s`;\n}\n\nfunction JobRow({\n job,\n tick,\n onStop,\n}: {\n job: JobInfo;\n tick: number;\n onStop: (jobId: number) => void;\n}) {\n const [exp, setExp] = useState(false);\n const elapsedMs = (job.running ? Date.now() : job.startedAt + 0) - job.startedAt;\n const liveMs = job.running ? Date.now() - job.startedAt : elapsedMs;\n // tick is referenced so the row re-renders for the running clock\n void tick;\n return (\n <div className=\"job-row\" data-status={job.running ? \"running\" : \"exited\"}>\n <div className=\"jr-main\" onClick={() => setExp((v) => !v)}>\n <span className=\"jr-state\">\n {job.running ? (\n <span className=\"spin\" />\n ) : (\n <I.history size={11} style={{ color: \"var(--muted-2)\" }} />\n )}\n </span>\n <span className=\"jr-kind\">\n <I.terminal size={11} />\n <span>shell</span>\n </span>\n <div className=\"jr-body\">\n <div className=\"nm\" title={job.command}>\n {job.command}\n </div>\n <div className=\"sub\">\n <span className=\"ses\">{job.sessionLabel}</span>\n {job.spawnError ? <span className=\"rk\">· {job.spawnError}</span> : null}\n {!job.running && job.exitCode !== null && job.exitCode !== 0 ? (\n <span className=\"rk\">· exit {job.exitCode}</span>\n ) : null}\n </div>\n </div>\n <div className=\"jr-time\">{formatElapsed(liveMs)}</div>\n <div className=\"jr-act\">\n {job.running ? (\n <button\n type=\"button\"\n className=\"btn danger sm\"\n title={t(\"jobs.stopOne\")}\n onClick={(e) => {\n e.stopPropagation();\n onStop(job.id);\n }}\n >\n <I.stop size={10} /> {t(\"jobs.stop\")}\n </button>\n ) : (\n <span className=\"jr-exit\" title={`exit ${job.exitCode ?? \"—\"}`}>\n {job.exitCode === 0 ? \"ok\" : `exit ${job.exitCode ?? \"?\"}`}\n </span>\n )}\n </div>\n </div>\n {exp ? (\n <div className=\"jr-detail\">\n <div className=\"kv-grid\">\n <div>\n <span className=\"k\">job_id</span>\n <span className=\"v\">{job.id}</span>\n </div>\n <div>\n <span className=\"k\">pid</span>\n <span className=\"v\">{job.pid ?? \"—\"}</span>\n </div>\n <div>\n <span className=\"k\">elapsed</span>\n <span className=\"v\">{formatElapsed(liveMs)}</span>\n </div>\n </div>\n {job.outputTail ? <pre className=\"jr-log\">{job.outputTail}</pre> : null}\n </div>\n ) : null}\n </div>\n );\n}\n","import { openUrl } from \"@tauri-apps/plugin-opener\";\nimport { t } from \"../i18n\";\nimport { I } from \"../icons\";\n\nconst REPO_URL = \"https://github.com/esengine/DeepSeek-Reasonix\";\n\nexport function AboutModal({ onClose }: { onClose: () => void }) {\n const openGitHub = () => {\n void openUrl(REPO_URL).catch(() => undefined);\n };\n\n return (\n <div className=\"about-mask\" onClick={onClose}>\n <div className=\"about-modal\" onClick={(e) => e.stopPropagation()}>\n <button type=\"button\" className=\"about-close\" onClick={onClose} aria-label={t(\"about.close\")}>\n <I.x size={14} />\n </button>\n <div className=\"about-brand\">\n <div className=\"about-name\">Reasonix</div>\n <div className=\"about-tagline\">{t(\"about.tagline\")}</div>\n </div>\n <div className=\"about-meta\">\n <div className=\"about-row\">\n <span className=\"about-label\">{t(\"about.version\")}</span>\n <code className=\"about-value\">{__APP_VERSION__}</code>\n </div>\n <div className=\"about-row\">\n <span className=\"about-label\">{t(\"about.repo\")}</span>\n <button type=\"button\" className=\"about-link\" onClick={openGitHub}>\n <I.link size={12} />\n <span>esengine/DeepSeek-Reasonix</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import { t } from \"./i18n\";\n\nexport interface QQDesktopSettingsState {\n appId?: string;\n appSecret?: string;\n sandbox: boolean;\n enabled: boolean;\n configured: boolean;\n runtimeState: \"disconnected\" | \"connecting\" | \"connected\" | \"failed\";\n lastError?: string;\n appIdPreview?: string;\n access: string;\n}\n\nexport function maskQQAppId(appId: string | undefined): string | undefined {\n if (!appId) return undefined;\n return appId.length > 6 ? `${appId.slice(0, 6)}...` : appId;\n}\n\nexport function getQQConnectIntent(qq: QQDesktopSettingsState): \"configure\" | \"connect\" {\n return qq.configured ? \"connect\" : \"configure\";\n}\n\nexport function getQQStatusLabel(qq: QQDesktopSettingsState): string {\n switch (qq.runtimeState) {\n case \"connected\":\n return t(\"settings.qqConnected\");\n case \"connecting\":\n return t(\"settings.qqConnecting\");\n case \"failed\":\n return t(\"settings.qqFailed\");\n default:\n return t(\"settings.qqDisconnected\");\n }\n}\n\nexport function describeQQAccessLabel(access: string): string {\n const owner = /^owner (.+?)(?:, allowlist (\\d+))?$/.exec(access);\n if (owner) {\n const openId = owner[1] ?? \"unknown\";\n const count = owner[2];\n if (count) return t(\"settings.qqAccessOwnerWithAllowlist\", { openId, count });\n return t(\"settings.qqAccessOwner\", { openId });\n }\n\n const allowlist = /^allowlist (\\d+)$/.exec(access);\n if (allowlist) return t(\"settings.qqAccessAllowlist\", { count: allowlist[1] ?? \"0\" });\n\n const runtime = /^first-sender \\(runtime only, (.+)\\)$/.exec(access);\n if (runtime) return t(\"settings.qqAccessRuntime\", { openId: runtime[1] ?? \"unknown\" });\n\n return t(\"settings.qqAccessOpen\");\n}\n\nexport function describeQQRowSummary(qq: QQDesktopSettingsState): string {\n if (!qq.configured) return t(\"settings.qqSummaryMissing\");\n const appId = qq.appIdPreview ?? maskQQAppId(qq.appId) ?? \"unknown\";\n return t(\"settings.qqSummaryDetail\", {\n appId: t(\"settings.qqSummaryAppId\", { appId }),\n environment: qq.sandbox ? t(\"settings.qqSandbox\") : t(\"settings.qqProduction\"),\n access: describeQQAccessLabel(qq.access),\n });\n}\n","import { type ReactNode, useEffect, useState } from \"react\";\nimport type { Balance, Settings as SettingsType, UsageStats } from \"../App\";\nimport { getLangLabel, getSupportedLangs, setLang, t, useLang } from \"../i18n\";\nimport { I } from \"../icons\";\nimport type {\n McpSpecInfo,\n MemoryDetail,\n MemoryEntryInfo,\n SettingsPatch,\n SkillInfo,\n} from \"../protocol\";\nimport {\n describeQQRowSummary,\n getQQConnectIntent,\n getQQStatusLabel,\n type QQDesktopSettingsState,\n} from \"../qq-settings\";\nimport {\n FONT_FAMILY,\n FONT_SCALE,\n type FontFamily,\n type FontScale,\n THEME,\n THEME_STYLES,\n type Theme,\n type ThemeStyle,\n themeForStyle,\n} from \"../theme\";\nimport { Shortcut, type ShortcutKey } from \"./shortcut\";\n\nexport type PageId =\n | \"general\"\n | \"models\"\n | \"mcp\"\n | \"skills\"\n | \"memory\"\n | \"rules\"\n | \"billing\"\n | \"shortcuts\";\n\nconst PAGE_META: ReadonlyArray<{ id: PageId; icon: keyof typeof I }> = [\n { id: \"general\", icon: \"cog\" },\n { id: \"models\", icon: \"brain\" },\n { id: \"mcp\", icon: \"wrench\" },\n { id: \"skills\", icon: \"zap\" },\n { id: \"memory\", icon: \"bookmark\" },\n { id: \"rules\", icon: \"shield\" },\n { id: \"billing\", icon: \"coin\" },\n { id: \"shortcuts\", icon: \"cpu\" },\n];\n\nexport function SettingsModal({\n settings,\n balance,\n usage,\n currency,\n theme,\n themeStyle,\n onSetTheme,\n onSetThemeStyle,\n fontScale,\n onSetFontScale,\n fontFamily,\n onSetFontFamily,\n initialPage,\n mcpSpecs,\n mcpBridged,\n skills,\n memory,\n memoryDetail,\n qq,\n onClose,\n onSave,\n onSaveApiKey,\n onLoadQQ,\n onConnectQQ,\n onDisconnectQQ,\n onSaveQQConfig,\n onOpenQQApplyLink,\n onPickWorkspace,\n onAddMcpSpec,\n onRemoveMcpSpec,\n onReadMemory,\n}: {\n settings: SettingsType;\n balance: Balance | null;\n usage: UsageStats;\n currency: \"CNY\" | \"USD\";\n theme: Theme;\n themeStyle: ThemeStyle;\n onSetTheme: (theme: Theme) => void;\n onSetThemeStyle: (style: ThemeStyle) => void;\n fontScale: FontScale;\n onSetFontScale: (scale: FontScale) => void;\n fontFamily: FontFamily;\n onSetFontFamily: (family: FontFamily) => void;\n initialPage?: PageId;\n mcpSpecs: McpSpecInfo[];\n mcpBridged: boolean;\n skills: SkillInfo[];\n memory: MemoryEntryInfo[];\n memoryDetail: MemoryDetail | null;\n qq: QQDesktopSettingsState | null;\n onClose: () => void;\n onSave: (patch: SettingsPatch) => void;\n onSaveApiKey: (key: string) => void;\n onLoadQQ: () => void;\n onConnectQQ: () => void;\n onDisconnectQQ: () => void;\n onSaveQQConfig: (patch: { appId?: string; appSecret?: string; sandbox: boolean }) => void;\n onOpenQQApplyLink: () => void;\n onPickWorkspace: () => void;\n onAddMcpSpec: (spec: string) => void;\n onRemoveMcpSpec: (spec: string) => void;\n onReadMemory: (path: string) => void;\n}) {\n const [page, setPage] = useState<PageId>(initialPage ?? \"general\");\n const [qqConfigureOpen, setQQConfigureOpen] = useState(false);\n const currentMeta = PAGE_META.find((p) => p.id === page) ?? PAGE_META[0]!;\n return (\n <div className=\"settings-mask\" onClick={onClose}>\n <div className=\"settings\" onClick={(e) => e.stopPropagation()}>\n <nav className=\"settings-side\">\n <div className=\"sg\">{t(\"settings.title\")}</div>\n {PAGE_META.map((p) => (\n <div\n key={p.id}\n className=\"row\"\n data-active={page === p.id}\n onClick={() => setPage(p.id)}\n >\n <span className=\"ico\">{I[p.icon]({ size: 13 })}</span>\n <span>{t(`settings.page${p.id[0]!.toUpperCase()}${p.id.slice(1)}Label` as any)}</span>\n </div>\n ))}\n </nav>\n <div className=\"settings-main\">\n <div className=\"settings-head\">\n <div>\n <h2>\n {t(\n `settings.page${currentMeta.id[0]!.toUpperCase()}${currentMeta.id.slice(1)}Label` as any,\n )}\n </h2>\n <div className=\"desc\">\n {t(\n `settings.page${currentMeta.id[0]!.toUpperCase()}${currentMeta.id.slice(1)}Desc` as any,\n )}\n </div>\n </div>\n <span className=\"grow\" />\n <button type=\"button\" className=\"close-btn\" onClick={onClose}>\n <I.x size={14} />\n </button>\n </div>\n <div className=\"settings-body\">\n {page === \"general\" && (\n <PageGeneral\n settings={settings}\n theme={theme}\n themeStyle={themeStyle}\n onSetTheme={onSetTheme}\n onSetThemeStyle={onSetThemeStyle}\n fontScale={fontScale}\n onSetFontScale={onSetFontScale}\n fontFamily={fontFamily}\n onSetFontFamily={onSetFontFamily}\n onSave={onSave}\n onPickWorkspace={onPickWorkspace}\n />\n )}\n {page === \"models\" && <PageModels settings={settings} onSave={onSave} />}\n {page === \"mcp\" && (\n <PageMCP\n specs={mcpSpecs}\n bridged={mcpBridged}\n onAdd={onAddMcpSpec}\n onRemove={onRemoveMcpSpec}\n />\n )}\n {page === \"skills\" && (\n <PageSkills\n skills={skills}\n subagentModels={settings.subagentModels ?? {}}\n onSave={onSave}\n />\n )}\n {page === \"memory\" && (\n <PageMemory entries={memory} detail={memoryDetail} onRead={onReadMemory} />\n )}\n {page === \"rules\" && <PageRules settings={settings} onSave={onSave} />}\n {page === \"billing\" && (\n <PageBilling balance={balance} usage={usage} currency={currency} />\n )}\n {page === \"shortcuts\" && <PageShortcuts />}\n {page === \"general\" ? (\n <>\n <ApiKeySection\n baseUrl={settings.baseUrl}\n apiKeyPrefix={settings.apiKeyPrefix}\n onSave={onSave}\n onSaveApiKey={onSaveApiKey}\n />\n <QQChannelSection\n qq={qq}\n configureOpen={qqConfigureOpen}\n onOpenConfigure={() => {\n onLoadQQ();\n setQQConfigureOpen(true);\n }}\n onCloseConfigure={() => setQQConfigureOpen(false)}\n onConnect={onConnectQQ}\n onDisconnect={onDisconnectQQ}\n onSaveConfig={onSaveQQConfig}\n onSaveAndConnect={(patch) => {\n onSaveQQConfig(patch);\n onConnectQQ();\n }}\n onOpenApplyLink={onOpenQQApplyLink}\n />\n </>\n ) : null}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nexport function QQChannelSection({\n qq,\n configureOpen,\n onOpenConfigure,\n onCloseConfigure,\n onConnect,\n onDisconnect,\n onSaveConfig,\n onSaveAndConnect,\n onOpenApplyLink,\n}: {\n qq: QQDesktopSettingsState | null;\n configureOpen: boolean;\n onOpenConfigure: () => void;\n onCloseConfigure: () => void;\n onConnect: () => void;\n onDisconnect: () => void;\n onSaveConfig: (patch: { appId?: string; appSecret?: string; sandbox: boolean }) => void;\n onSaveAndConnect: (patch: { appId?: string; appSecret?: string; sandbox: boolean }) => void;\n onOpenApplyLink: () => void;\n}) {\n const current = qq ?? {\n appId: undefined,\n appSecret: undefined,\n sandbox: true,\n enabled: false,\n configured: false,\n runtimeState: \"disconnected\",\n access: \"open (unbound)\",\n };\n const [appId, setAppId] = useState(current.appId ?? \"\");\n const [appSecret, setAppSecret] = useState(current.appSecret ?? \"\");\n const [sandbox, setSandbox] = useState(current.sandbox ?? true);\n\n useEffect(() => {\n setAppId(current.appId ?? \"\");\n setAppSecret(current.appSecret ?? \"\");\n setSandbox(current.sandbox ?? true);\n }, [current.appId, current.appSecret, current.sandbox, configureOpen]);\n\n const savePatch = { appId, appSecret, sandbox };\n\n return (\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.qqSection\")}</div>\n {!configureOpen ? (\n <div className=\"setting-row qq-setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.qqTitle\")}</div>\n <div className=\"h\">{describeQQRowSummary(current)}</div>\n </div>\n <div className=\"qq-row-actions\">\n <button\n type=\"button\"\n className={`btn qq-status-btn qq-status-${\n current.runtimeState === \"connected\"\n ? \"on\"\n : current.runtimeState === \"connecting\"\n ? \"connecting\"\n : current.runtimeState === \"failed\"\n ? \"failed\"\n : \"off\"\n }`}\n onClick={() => {\n if (getQQConnectIntent(current) === \"configure\") {\n onOpenConfigure();\n return;\n }\n if (current.runtimeState === \"connected\") {\n onDisconnect();\n return;\n }\n onConnect();\n }}\n >\n {getQQStatusLabel(current)}\n </button>\n <button type=\"button\" className=\"btn\" onClick={onOpenConfigure}>\n {t(\"settings.qqConfigure\")}\n </button>\n </div>\n </div>\n ) : (\n <div className=\"qq-config-card\">\n <div className=\"qq-config-head\">\n <div>\n <div className=\"n\">{t(\"settings.qqConfigureTitle\")}</div>\n <div className=\"h\">{t(\"settings.qqConfigureHint\")}</div>\n </div>\n <button type=\"button\" className=\"btn\" onClick={onCloseConfigure}>\n {t(\"settings.qqBack\")}\n </button>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.qqAppId\")}</div>\n </div>\n <input\n className=\"field mono\"\n value={appId}\n onChange={(e) => setAppId(e.target.value)}\n placeholder=\"QQ Open Platform App ID\"\n />\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.qqAppSecret\")}</div>\n </div>\n <input\n className=\"field mono\"\n type=\"password\"\n value={appSecret}\n onChange={(e) => setAppSecret(e.target.value)}\n placeholder=\"QQ Open Platform App Secret\"\n />\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.qqEnvironment\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n <button type=\"button\" data-on={sandbox} onClick={() => setSandbox(true)}>\n {t(\"settings.qqSandbox\")}\n </button>\n <button type=\"button\" data-on={!sandbox} onClick={() => setSandbox(false)}>\n {t(\"settings.qqProduction\")}\n </button>\n </div>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.qqApplyLabel\")}</div>\n </div>\n <button type=\"button\" className=\"btn\" onClick={onOpenApplyLink}>\n {t(\"settings.qqApplyAction\")}\n </button>\n </div>\n <div className=\"qq-config-actions\">\n <button\n type=\"button\"\n className=\"btn\"\n onClick={() => {\n onSaveConfig(savePatch);\n onCloseConfigure();\n }}\n >\n {t(\"settings.qqSave\")}\n </button>\n <button\n type=\"button\"\n className=\"btn primary\"\n onClick={() => {\n onSaveAndConnect(savePatch);\n onCloseConfigure();\n }}\n >\n {t(\"settings.qqSaveAndConnect\")}\n </button>\n </div>\n </div>\n )}\n </section>\n );\n}\n\nfunction PageGeneral({\n settings,\n theme,\n themeStyle,\n onSetTheme,\n onSetThemeStyle,\n fontScale,\n onSetFontScale,\n fontFamily,\n onSetFontFamily,\n onSave,\n onPickWorkspace,\n}: {\n settings: SettingsType;\n theme: Theme;\n themeStyle: ThemeStyle;\n onSetTheme: (theme: Theme) => void;\n onSetThemeStyle: (style: ThemeStyle) => void;\n fontScale: FontScale;\n onSetFontScale: (scale: FontScale) => void;\n fontFamily: FontFamily;\n onSetFontFamily: (family: FontFamily) => void;\n onSave: (patch: SettingsPatch) => void;\n onPickWorkspace: () => void;\n}) {\n const [editorDraft, setEditorDraft] = useState(settings.editor ?? \"\");\n const lang = useLang();\n return (\n <>\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.appearanceSection\")}</div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.theme\")}</div>\n <div className=\"h\">{t(\"settings.themeHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n <button\n type=\"button\"\n data-on={theme === THEME.DARK}\n onClick={() => onSetTheme(THEME.DARK)}\n >\n {t(\"settings.themeDark\")}\n </button>\n <button\n type=\"button\"\n data-on={theme === THEME.LIGHT}\n onClick={() => onSetTheme(THEME.LIGHT)}\n >\n {t(\"settings.themeLight\")}\n </button>\n </div>\n </div>\n <div className=\"setting-row theme-style-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.themeStyle\")}</div>\n <div className=\"h\">{t(\"settings.themeStyleHint\")}</div>\n </div>\n <div className=\"style-grid\">\n {THEME_STYLES.map((style) => (\n <button\n key={style}\n type=\"button\"\n className=\"style-card\"\n data-on={themeStyle === style}\n data-style={style}\n onClick={() => onSetThemeStyle(style)}\n >\n <span className=\"style-card-head\">\n <span className=\"style-name\">\n {t(`settings.themeStyle${style[0]!.toUpperCase()}${style.slice(1)}` as any)}\n </span>\n <span className=\"style-mode\">\n {themeForStyle(style) === THEME.DARK\n ? t(\"settings.themeDark\")\n : t(\"settings.themeLight\")}\n </span>\n </span>\n <span className=\"style-swatches\" aria-hidden=\"true\">\n <span />\n <span />\n <span />\n </span>\n <span className=\"style-desc\">\n {t(`settings.themeStyle${style[0]!.toUpperCase()}${style.slice(1)}Desc` as any)}\n </span>\n </button>\n ))}\n </div>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.fontScale\")}</div>\n <div className=\"h\">{t(\"settings.fontScaleHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n <button\n type=\"button\"\n data-on={fontScale === FONT_SCALE.SMALL}\n onClick={() => onSetFontScale(FONT_SCALE.SMALL)}\n >\n {t(\"settings.fontScaleSmall\")}\n </button>\n <button\n type=\"button\"\n data-on={fontScale === FONT_SCALE.MEDIUM}\n onClick={() => onSetFontScale(FONT_SCALE.MEDIUM)}\n >\n {t(\"settings.fontScaleMedium\")}\n </button>\n <button\n type=\"button\"\n data-on={fontScale === FONT_SCALE.LARGE}\n onClick={() => onSetFontScale(FONT_SCALE.LARGE)}\n >\n {t(\"settings.fontScaleLarge\")}\n </button>\n </div>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.fontFamily\")}</div>\n <div className=\"h\">{t(\"settings.fontFamilyHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n <button\n type=\"button\"\n data-on={fontFamily === FONT_FAMILY.SANS}\n onClick={() => onSetFontFamily(FONT_FAMILY.SANS)}\n >\n {t(\"settings.fontFamilySans\")}\n </button>\n <button\n type=\"button\"\n data-on={fontFamily === FONT_FAMILY.SYSTEM}\n onClick={() => onSetFontFamily(FONT_FAMILY.SYSTEM)}\n >\n {t(\"settings.fontFamilySystem\")}\n </button>\n <button\n type=\"button\"\n data-on={fontFamily === FONT_FAMILY.SERIF}\n onClick={() => onSetFontFamily(FONT_FAMILY.SERIF)}\n >\n {t(\"settings.fontFamilySerif\")}\n </button>\n </div>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.language\")}</div>\n <div className=\"h\">{t(\"settings.languageHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n {getSupportedLangs().map((code) => (\n <button type=\"button\" key={code} data-on={lang === code} onClick={() => setLang(code)}>\n {getLangLabel(code)}\n </button>\n ))}\n </div>\n </div>\n </section>\n\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.workspaceSection\")}</div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.currentWorkspace\")}</div>\n <div className=\"h\">{settings.workspaceDir || t(\"settings.notSelected\")}</div>\n </div>\n <button type=\"button\" className=\"btn\" onClick={onPickWorkspace}>\n {t(\"settings.workspaceChange\")}\n </button>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.editor\")}</div>\n <div className=\"h\">{t(\"settings.editorHint\")}</div>\n </div>\n <input\n className=\"field mono\"\n value={editorDraft}\n placeholder=\"cursor --goto\"\n onChange={(e) => setEditorDraft(e.target.value)}\n onBlur={() => onSave({ editor: editorDraft || undefined })}\n />\n </div>\n </section>\n\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.behaviorSection\")}</div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.reasoningEffort\")}</div>\n <div className=\"h\">{t(\"settings.reasoningEffortHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n {([\"low\", \"medium\", \"high\", \"max\"] as const).map((e) => (\n <button\n type=\"button\"\n key={e}\n data-on={settings.reasoningEffort === e}\n onClick={() => onSave({ reasoningEffort: e })}\n >\n {e}\n </button>\n ))}\n </div>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.editMode\")}</div>\n <div className=\"h\">{t(\"settings.editModeHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n {([\"plan\", \"review\", \"auto\", \"yolo\"] as const).map((m) => (\n <button\n type=\"button\"\n key={m}\n data-on={settings.editMode === m}\n onClick={() => onSave({ editMode: m })}\n >\n {m}\n </button>\n ))}\n </div>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.showSystemEvents\")}</div>\n <div className=\"h\">{t(\"settings.showSystemEventsHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n <button\n type=\"button\"\n data-on={settings.showSystemEvents !== false}\n onClick={() => onSave({ showSystemEvents: true })}\n >\n {t(\"settings.shown\")}\n </button>\n <button\n type=\"button\"\n data-on={settings.showSystemEvents === false}\n onClick={() => onSave({ showSystemEvents: false })}\n >\n {t(\"settings.hidden\")}\n </button>\n </div>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.budget\")}</div>\n <div className=\"h\">{t(\"settings.budgetHint\")}</div>\n </div>\n <input\n className=\"field\"\n type=\"number\"\n defaultValue={settings.budgetUsd ?? \"\"}\n placeholder={t(\"settings.budgetPlaceholder\")}\n onBlur={(e) => {\n const v = e.target.value.trim();\n onSave({ budgetUsd: v === \"\" ? null : Number(v) });\n }}\n />\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.webSearchEngine\")}</div>\n <div className=\"h\">{t(\"settings.webSearchEngineNote\")}</div>\n </div>\n <select\n className=\"field\"\n value={settings.webSearchEngine ?? \"bing\"}\n onChange={(e) =>\n onSave({\n webSearchEngine: e.target.value as\n | \"bing\"\n | \"searxng\"\n | \"metaso\"\n | \"tavily\"\n | \"perplexity\"\n | \"exa\",\n })\n }\n >\n <option value=\"bing\">{t(\"settings.webSearchEngineBing\")}</option>\n <option value=\"searxng\">{t(\"settings.webSearchEngineSearxng\")}</option>\n <option value=\"metaso\">{t(\"settings.webSearchEngineMetaso\")}</option>\n <option value=\"tavily\">{t(\"settings.webSearchEngineTavily\")}</option>\n <option value=\"perplexity\">{t(\"settings.webSearchEnginePerplexity\")}</option>\n <option value=\"exa\">{t(\"settings.webSearchEngineExa\")}</option>\n </select>\n </div>\n </section>\n </>\n );\n}\n\nfunction ApiKeySection({\n baseUrl,\n apiKeyPrefix,\n onSave,\n onSaveApiKey,\n}: {\n baseUrl?: string;\n apiKeyPrefix?: string;\n onSave: (patch: SettingsPatch) => void;\n onSaveApiKey: (key: string) => void;\n}) {\n const [key, setKey] = useState(\"\");\n const [urlDraft, setUrlDraft] = useState(baseUrl ?? \"\");\n return (\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.apiSection\")}</div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.apiKey\")}</div>\n <div className=\"h\">\n {apiKeyPrefix\n ? t(\"settings.apiKeySet\", { prefix: apiKeyPrefix })\n : t(\"settings.apiKeyNotSet\")}\n </div>\n </div>\n <div style={{ display: \"flex\", gap: 6 }}>\n <input\n className=\"field mono\"\n type=\"password\"\n value={key}\n onChange={(e) => setKey(e.target.value)}\n placeholder=\"sk-…\"\n />\n <button\n type=\"button\"\n className=\"btn primary\"\n disabled={!key}\n onClick={() => {\n if (!key) return;\n onSaveApiKey(key);\n setKey(\"\");\n }}\n >\n {t(\"settings.apiKeySave\")}\n </button>\n </div>\n </div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.baseUrl\")}</div>\n <div className=\"h\">{t(\"settings.baseUrlHint\")}</div>\n </div>\n <input\n className=\"field mono\"\n value={urlDraft}\n onChange={(e) => setUrlDraft(e.target.value)}\n onBlur={() => onSave({ baseUrl: urlDraft.trim() || undefined })}\n />\n </div>\n </section>\n );\n}\n\nconst KNOWN_MODELS = [\"deepseek-v4-flash\", \"deepseek-v4-pro\"] as const;\n\nconst EFFORT_VALUES = [\"low\", \"medium\", \"high\", \"max\"] as const;\ntype EffortValue = (typeof EFFORT_VALUES)[number];\n\nfunction PageModels({\n settings,\n onSave,\n}: {\n settings: SettingsType;\n onSave: (patch: SettingsPatch) => void;\n}) {\n const [draft, setDraft] = useState(settings.model);\n useEffect(() => setDraft(settings.model), [settings.model]);\n const isKnown = (KNOWN_MODELS as readonly string[]).includes(settings.model);\n return (\n <>\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.defaultModelCurrent\", { model: settings.model })}</div>\n <div className=\"model-grid\">\n {KNOWN_MODELS.map((id) => (\n <div\n key={id}\n className=\"mcard\"\n data-on={settings.model === id}\n onClick={() => onSave({ model: id })}\n >\n <div className=\"nm\">{id}</div>\n </div>\n ))}\n </div>\n <div className=\"setting-row\" style={{ marginTop: 12 }}>\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.modelCustom\")}</div>\n <div className=\"h\">{t(\"settings.modelCustomHint\")}</div>\n </div>\n <div style={{ display: \"flex\", gap: 6 }}>\n <input\n className=\"field mono\"\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n placeholder=\"deepseek-v4-flash\"\n />\n <button\n type=\"button\"\n className=\"btn primary\"\n disabled={!draft.trim() || draft.trim() === settings.model}\n onClick={() => onSave({ model: draft.trim() })}\n >\n {t(\"settings.apiKeySave\")}\n </button>\n </div>\n </div>\n {!isKnown ? (\n <div className=\"h\" style={{ marginTop: 6 }}>\n {t(\"settings.modelCustomActive\", { model: settings.model })}\n </div>\n ) : null}\n </section>\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.effortSection\")}</div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.reasoningEffort\")}</div>\n <div className=\"h\">{t(\"settings.reasoningEffortHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n {EFFORT_VALUES.map((e) => (\n <button\n type=\"button\"\n key={e}\n data-on={settings.reasoningEffort === e}\n onClick={() => onSave({ reasoningEffort: e as EffortValue })}\n >\n {e}\n </button>\n ))}\n </div>\n </div>\n </section>\n </>\n );\n}\n\nfunction PageMCP({\n specs,\n bridged,\n onAdd,\n onRemove,\n}: {\n specs: McpSpecInfo[];\n bridged: boolean;\n onAdd: (spec: string) => void;\n onRemove: (spec: string) => void;\n}) {\n const [draft, setDraft] = useState(\"\");\n const submit = () => {\n const v = draft.trim();\n if (!v) return;\n onAdd(v);\n setDraft(\"\");\n };\n return (\n <>\n <section className=\"section\">\n <div className=\"stitle\">\n {t(\"settings.mcpConfigured\", { count: specs.length })}\n {bridged ? (\n <span style={{ color: \"var(--accent)\", marginLeft: 8, fontSize: 11 }}>\n {t(\"settings.mcpBridged\")}\n </span>\n ) : (\n <span style={{ color: \"var(--muted)\", marginLeft: 8, fontSize: 11 }}>\n {t(\"settings.mcpNotBridged\")}\n </span>\n )}\n </div>\n {specs.length === 0 ? (\n <div\n style={{\n padding: 16,\n background: \"var(--card)\",\n border: \"1px solid var(--border)\",\n borderRadius: 10,\n fontSize: 12,\n color: \"var(--muted)\",\n }}\n >\n {t(\"settings.mcpEmpty\")}\n </div>\n ) : (\n specs.map((s) => (\n <div className=\"scard\" key={s.raw}>\n <div className=\"top\">\n <span className=\"ico\">\n <I.wrench size={14} />\n </span>\n <div>\n <div className=\"nm\">{s.name ?? \"(anonymous)\"}</div>\n <div className=\"sub\">{s.summary}</div>\n </div>\n <span className=\"grow\" />\n <button\n type=\"button\"\n className=\"btn ghost\"\n style={{ color: \"var(--danger)\" }}\n onClick={() => onRemove(s.raw)}\n >\n {t(\"settings.mcpRemove\")}\n </button>\n </div>\n {s.parseError ? (\n <div className=\"desc\" style={{ color: \"var(--danger)\" }}>\n {t(\"settings.parseError\", { error: s.parseError })}\n </div>\n ) : null}\n </div>\n ))\n )}\n </section>\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.mcpAddSection\")}</div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.mcpSpecLabel\")}</div>\n <div className=\"h\" dangerouslySetInnerHTML={{ __html: t(\"settings.mcpSpecFormat\") }} />\n </div>\n <div style={{ display: \"flex\", gap: 6 }}>\n <input\n className=\"field mono\"\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n placeholder=\"github=npx -y @smithery/cli ...\"\n onKeyDown={(e) => {\n if (e.key === \"Enter\") submit();\n }}\n />\n <button type=\"button\" className=\"btn primary\" disabled={!draft.trim()} onClick={submit}>\n {t(\"settings.mcpAdd\")}\n </button>\n </div>\n </div>\n </section>\n </>\n );\n}\n\nfunction PageSkills({\n skills,\n subagentModels,\n onSave,\n}: {\n skills: SkillInfo[];\n subagentModels: Record<string, \"flash\" | \"pro\">;\n onSave: (patch: SettingsPatch) => void;\n}) {\n const setSubagentModel = (name: string, value: \"flash\" | \"pro\") => {\n onSave({ subagentModels: { ...subagentModels, [name]: value } });\n };\n return (\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.skillsLoaded\", { count: skills.length })}</div>\n {skills.length === 0 ? (\n <div\n style={{\n padding: 16,\n background: \"var(--card)\",\n border: \"1px solid var(--border)\",\n borderRadius: 10,\n fontSize: 12,\n color: \"var(--muted)\",\n }}\n >\n {t(\"settings.skillsEmpty\")}\n </div>\n ) : (\n skills.map((s) => (\n <div className=\"scard\" key={`${s.scope}:${s.name}`}>\n <div className=\"top\">\n <span className=\"ico\">\n <I.zap size={14} />\n </span>\n <div>\n <div className=\"nm\">\n <span\n style={{\n fontFamily: \"Geist Mono, monospace\",\n color: \"var(--accent)\",\n }}\n >\n /{s.name}\n </span>\n </div>\n <div className=\"sub\">\n {s.scope} · {s.runAs}\n {s.model ? ` · ${s.model}` : \"\"}\n </div>\n </div>\n {s.runAs === \"subagent\" ? (\n <select\n className=\"field\"\n style={{ marginLeft: \"auto\", minWidth: 96 }}\n value={subagentModels[s.name] ?? \"flash\"}\n onChange={(e) =>\n setSubagentModel(s.name, e.target.value as \"flash\" | \"pro\")\n }\n title={t(\"settings.subagentModelHint\")}\n >\n <option value=\"flash\">{t(\"settings.subagentModelFlash\")}</option>\n <option value=\"pro\">{t(\"settings.subagentModelPro\")}</option>\n </select>\n ) : null}\n </div>\n <div className=\"desc\">{s.description}</div>\n <div\n style={{\n fontFamily: \"Geist Mono, monospace\",\n fontSize: 10.5,\n color: \"var(--muted-2)\",\n marginTop: 4,\n }}\n >\n {s.path}\n </div>\n </div>\n ))\n )}\n </section>\n );\n}\n\nfunction PageMemory({\n entries,\n detail,\n onRead,\n}: {\n entries: MemoryEntryInfo[];\n detail: MemoryDetail | null;\n onRead: (path: string) => void;\n}) {\n return (\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.memorySection\")}</div>\n {entries.length === 0 ? (\n <div className=\"muted-card\">{t(\"settings.memoryDesc\")}</div>\n ) : (\n <div className=\"memory-browser\">\n <div className=\"memory-list\">\n {entries.map((m) => (\n <button\n type=\"button\"\n className=\"memory-item\"\n data-active={detail?.path === m.path}\n key={m.path}\n onClick={() => onRead(m.path)}\n >\n <span className=\"memory-kind\">{m.kind.replace(\"_\", \" \")}</span>\n <span className=\"memory-name\">{m.description || m.name}</span>\n <span className=\"memory-path\">{m.path}</span>\n </button>\n ))}\n </div>\n <pre className=\"memory-detail\">\n {detail ? detail.body : t(\"settings.memoryDesc\")}\n </pre>\n </div>\n )}\n </section>\n );\n}\n\nfunction PageRules({\n settings,\n onSave,\n}: {\n settings: SettingsType;\n onSave: (patch: SettingsPatch) => void;\n}) {\n return (\n <>\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.editMode\")}</div>\n <div className=\"setting-row\">\n <div className=\"l\">\n <div className=\"n\">{t(\"settings.appMode\")}</div>\n <div className=\"h\">{t(\"settings.editModeHint\")}</div>\n </div>\n <div className=\"seg-ctrl\">\n {([\"plan\", \"review\", \"auto\", \"yolo\"] as const).map((m) => (\n <button\n type=\"button\"\n key={m}\n data-on={settings.editMode === m}\n onClick={() => onSave({ editMode: m })}\n >\n {m}\n </button>\n ))}\n </div>\n </div>\n </section>\n <section className=\"section\">\n <div className=\"stitle\">{t(\"settings.ruleAutoApprovalSection\")}</div>\n <div\n style={{\n padding: 12,\n background: \"var(--card)\",\n border: \"1px solid var(--border)\",\n borderRadius: 10,\n fontSize: 12,\n color: \"var(--muted)\",\n }}\n >\n {t(\"settings.ruleAutoApprovalHint\")}\n </div>\n </section>\n </>\n );\n}\n\nfunction PageBilling({\n balance,\n usage,\n currency,\n}: {\n balance: Balance | null;\n usage: UsageStats;\n currency: \"CNY\" | \"USD\";\n}) {\n const symbol = currency === \"CNY\" ? \"¥\" : \"$\";\n const sessionCost = currency === \"CNY\" ? usage.totalCostUsd * 7.2 : usage.totalCostUsd;\n const totalTokens = usage.cacheHitTokens + usage.cacheMissTokens;\n const hitPct = totalTokens > 0 ? Math.round((usage.cacheHitTokens / totalTokens) * 100) : 0;\n return (\n <>\n <div className=\"bill-grid\">\n <div className=\"bill-card\">\n <div className=\"l\">{t(\"settings.balanceLabel\")}</div>\n <div className=\"v ok\">\n {balance\n ? `${balance.currency === \"USD\" ? \"$\" : \"¥\"} ${balance.total.toFixed(2)}`\n : \"—\"}\n </div>\n <div className=\"sub\">\n {balance && !balance.isAvailable\n ? t(\"settings.balanceLow\")\n : t(\"settings.balanceAvailable\")}\n </div>\n </div>\n <div className=\"bill-card\">\n <div className=\"l\">{t(\"settings.sessionCost\")}</div>\n <div className=\"v\">\n {symbol} {sessionCost.toFixed(4)}\n </div>\n <div className=\"sub\">prompt {usage.totalPromptTokens.toLocaleString()} t</div>\n </div>\n <div className=\"bill-card\">\n <div className=\"l\">{t(\"settings.cacheHitRate\")}</div>\n <div className=\"v acc\">{hitPct}%</div>\n <div className=\"sub\">\n hit {usage.cacheHitTokens.toLocaleString()} / miss{\" \"}\n {usage.cacheMissTokens.toLocaleString()}\n </div>\n </div>\n </div>\n </>\n );\n}\n\nfunction PageShortcuts() {\n const rows: { nm: string; keys: ShortcutKey[] }[] = [\n { nm: t(\"settings.shortcutNewChat\"), keys: [\"mod\", \"N\"] },\n { nm: t(\"settings.shortcutNewTab\"), keys: [\"mod\", \"T\"] },\n { nm: t(\"settings.shortcutCloseTab\"), keys: [\"mod\", \"W\"] },\n { nm: t(\"settings.shortcutCommandPalette\"), keys: [\"mod\", \"K\"] },\n { nm: t(\"settings.shortcutFocusComposer\"), keys: [\"mod\", \"L\"] },\n { nm: t(\"settings.shortcutSwitchTab\"), keys: [\"mod\", \"tab\"] },\n { nm: t(\"settings.shortcutAbort\"), keys: [\"esc\"] },\n { nm: t(\"settings.shortcutSettings\"), keys: [\"mod\", \",\"] },\n ];\n return (\n <section className=\"section\">\n <div className=\"kbd-grid\">\n {rows.map((s, i) => (\n <SectionRow key={i} nm={s.nm} keys={s.keys} />\n ))}\n </div>\n </section>\n );\n}\n\nfunction SectionRow({ nm, keys }: { nm: string; keys: ShortcutKey[] }): ReactNode {\n return (\n <>\n <div className=\"nm\">{nm}</div>\n <div className=\"keys\">\n <Shortcut keys={keys} />\n </div>\n </>\n );\n}\n","import { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport type { SessionInfo } from \"../App\";\nimport { t, useLang } from \"../i18n\";\nimport { I } from \"../icons\";\nimport { Shortcut } from \"./shortcut\";\n\ntype PendingDelete = {\n name: string;\n pretty: string;\n x: number;\n y: number;\n};\n\nfunction prettyName(s: SessionInfo): string {\n if (s.summary && s.summary.trim()) return s.summary.trim();\n const m = s.name.match(/^desktop-(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(?:-(\\d+))?$/);\n if (m) {\n const [, , month, day, hh, mm, tab] = m;\n return `${t(\"sidebarPanel.sessionTitle\", {\n month,\n day,\n hour: hh,\n minute: mm,\n })}${tab && tab !== \"1\" ? ` · #${tab}` : \"\"}`;\n }\n return s.name.replace(/^desktop-/, \"\").replace(/[-_]+/g, \" \");\n}\n\nfunction relative(ms: number): string {\n const min = ms / 60_000;\n if (min < 1) return t(\"sidebarPanel.justNow\");\n if (min < 60) return t(\"sidebarPanel.minutesAgo\", { n: Math.floor(min) });\n const hr = min / 60;\n if (hr < 24) return t(\"sidebarPanel.hoursAgo\", { n: Math.floor(hr) });\n const d = hr / 24;\n if (d < 7) return t(\"sidebarPanel.daysAgo\", { n: Math.floor(d) });\n return t(\"sidebarPanel.weeksAgo\", { n: Math.floor(d / 7) });\n}\n\nexport function Sidebar({\n sessions,\n activeName,\n loadingName,\n onNewChat,\n onLoadSession,\n onDeleteSession,\n onOpenSettings,\n onOpenRules,\n onOpenCommands,\n onOpenAbout,\n}: {\n sessions: SessionInfo[];\n activeName?: string;\n /** Name of the session currently being loaded — drives the per-row spinner. */\n loadingName?: string | null;\n onNewChat: () => void;\n onLoadSession: (name: string) => void;\n onDeleteSession: (name: string) => void;\n onOpenSettings: () => void;\n onOpenRules: () => void;\n onOpenCommands: () => void;\n onOpenAbout: () => void;\n}) {\n useLang();\n const [query, setQuery] = useState(\"\");\n const [pendingDelete, setPendingDelete] = useState<PendingDelete | null>(null);\n const filtered = query\n ? sessions.filter((s) => {\n const q = query.toLowerCase();\n return (\n prettyName(s).toLowerCase().includes(q) || s.name.toLowerCase().includes(q)\n );\n })\n : sessions;\n\n useEffect(() => {\n if (!pendingDelete) return;\n const onMouseDown = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null;\n if (!target?.closest(\".session-delete-popover\")) setPendingDelete(null);\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setPendingDelete(null);\n };\n window.addEventListener(\"mousedown\", onMouseDown);\n window.addEventListener(\"keydown\", onKey);\n return () => {\n window.removeEventListener(\"mousedown\", onMouseDown);\n window.removeEventListener(\"keydown\", onKey);\n };\n }, [pendingDelete]);\n\n return (\n <aside className=\"sidebar\">\n <div className=\"side-head\">\n <button type=\"button\" className=\"new-btn\" onClick={onNewChat}>\n <I.plus size={14} />\n <span>{t(\"sidebarPanel.newChat\")}</span>\n <Shortcut keys={[\"mod\", \"N\"]} />\n </button>\n <button\n type=\"button\"\n className=\"icon-btn\"\n title={t(\"sidebarPanel.commandPalette\")}\n onClick={onOpenCommands}\n >\n <I.history size={14} />\n </button>\n </div>\n\n <div className=\"search-row\">\n <div className=\"input\">\n <I.search size={13} />\n <input\n placeholder={t(\"sidebarPanel.searchSessions\")}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n />\n <Shortcut keys={[\"mod\", \"K\"]} />\n </div>\n </div>\n\n <div className=\"session-list\">\n <div className=\"side-section\">\n <div className=\"label\">\n <span>{t(\"sidebarPanel.recent\")}</span>\n <span className=\"count\">{filtered.length}</span>\n </div>\n {sessions.length === 0 ? (\n <div\n style={{\n padding: \"12px 8px\",\n fontSize: 11,\n color: \"var(--muted-2)\",\n fontFamily: \"Geist Mono, monospace\",\n }}\n >\n {t(\"sidebarPanel.noSessions\")}\n </div>\n ) : filtered.length === 0 ? (\n <div\n style={{\n padding: \"12px 8px\",\n fontSize: 11,\n color: \"var(--muted-2)\",\n fontFamily: \"Geist Mono, monospace\",\n }}\n >\n {t(\"sidebarPanel.noMatches\")}\n </div>\n ) : null}\n {filtered.map((s) => {\n const active = s.name === activeName;\n const loading = s.name === loadingName;\n const mtime = Date.parse(s.mtime);\n const updated = Number.isFinite(mtime) ? relative(Date.now() - mtime) : s.mtime;\n return (\n <div\n key={s.name}\n className=\"session-item\"\n data-active={active}\n data-loading={loading || undefined}\n style={loadingName && !loading ? { opacity: 0.5, pointerEvents: \"none\" } : undefined}\n onClick={() => onLoadSession(s.name)}\n role=\"button\"\n tabIndex={0}\n title={s.name}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") onLoadSession(s.name);\n }}\n >\n <span\n className=\"state\"\n style={{\n background: loading\n ? \"var(--accent)\"\n : active\n ? \"var(--accent)\"\n : \"var(--border-strong)\",\n animation: loading ? \"session-pulse 0.9s ease-in-out infinite\" : undefined,\n }}\n />\n <div className=\"body\">\n <span className=\"title\">{prettyName(s)}</span>\n <span className=\"meta\">\n {loading ? (\n <span>{t(\"sidebarPanel.loading\")}</span>\n ) : (\n <>\n <span>{t(\"sidebarPanel.messageCount\", { count: s.messageCount })}</span>\n <span className=\"sep\">·</span>\n <span>{updated}</span>\n </>\n )}\n </span>\n </div>\n <button\n type=\"button\"\n className=\"delete-btn\"\n title={t(\"sidebarPanel.deleteSession\")}\n aria-label={t(\"sidebarPanel.deleteSession\")}\n onClick={(e) => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n setPendingDelete({\n name: s.name,\n pretty: prettyName(s),\n x: rect.right,\n y: rect.bottom,\n });\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") e.stopPropagation();\n }}\n >\n <I.x size={12} />\n </button>\n </div>\n );\n })}\n </div>\n </div>\n\n <div className=\"side-foot\">\n <div className=\"row\" onClick={onOpenRules}>\n <span className=\"ico\">\n <I.shield size={13} />\n </span>\n <span>{t(\"sidebarPanel.approvalRules\")}</span>\n </div>\n <div className=\"row\" onClick={onOpenAbout}>\n <span className=\"ico\">\n <I.help size={13} />\n </span>\n <span>{t(\"about.sidebarLabel\")}</span>\n </div>\n <div className=\"row\" onClick={onOpenSettings}>\n <span className=\"ico\">\n <I.cog size={13} />\n </span>\n <span>{t(\"sidebarPanel.settings\")}</span>\n <span className=\"right\">\n <Shortcut keys={[\"mod\", \",\"]} />\n </span>\n </div>\n </div>\n\n {pendingDelete ? (\n <SessionDeletePopover\n target={pendingDelete}\n onCancel={() => setPendingDelete(null)}\n onConfirm={() => {\n onDeleteSession(pendingDelete.name);\n setPendingDelete(null);\n }}\n />\n ) : null}\n </aside>\n );\n}\n\nfunction SessionDeletePopover({\n target,\n onCancel,\n onConfirm,\n}: {\n target: PendingDelete;\n onCancel: () => void;\n onConfirm: () => void;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const cancelRef = useRef<HTMLButtonElement>(null);\n const [pos, setPos] = useState<{ left: number; top: number }>({\n left: target.x,\n top: target.y,\n });\n\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n const pad = 8;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n let left = target.x;\n let top = target.y;\n if (left + rect.width + pad > vw) left = Math.max(pad, vw - rect.width - pad);\n if (top + rect.height + pad > vh) top = Math.max(pad, vh - rect.height - pad);\n if (left !== pos.left || top !== pos.top) setPos({ left, top });\n cancelRef.current?.focus();\n }, [target.x, target.y, pos.left, pos.top]);\n\n return (\n <div\n ref={ref}\n className=\"session-delete-popover\"\n role=\"dialog\"\n aria-modal=\"true\"\n style={{ left: pos.left, top: pos.top }}\n >\n <div className=\"msg\">\n {t(\"sidebarPanel.deleteSession\")}\n <span className=\"name\">{target.pretty}</span>\n </div>\n <div className=\"actions\">\n <button ref={cancelRef} type=\"button\" className=\"cancel\" onClick={onCancel}>\n {t(\"sidebarPanel.cancel\")}\n </button>\n <button type=\"button\" className=\"confirm\" onClick={onConfirm}>\n <I.x size={11} />\n {t(\"sidebarPanel.delete\")}\n </button>\n </div>\n </div>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { t } from \"../i18n\";\n\nconst SPLASH_FLAG = \"reasonix.splash.shown\";\n\nexport function shouldShowSplash(): boolean {\n try {\n return sessionStorage.getItem(SPLASH_FLAG) !== \"1\";\n } catch {\n return true;\n }\n}\n\nfunction markSplashShown() {\n try {\n sessionStorage.setItem(SPLASH_FLAG, \"1\");\n } catch {\n /* sessionStorage unavailable */\n }\n}\n\nexport function Splash({ onDone }: { onDone: () => void }) {\n const [leaving, setLeaving] = useState(false);\n const onDoneRef = useRef(onDone);\n onDoneRef.current = onDone;\n\n useEffect(() => {\n const t1 = window.setTimeout(() => setLeaving(true), 1350);\n const t2 = window.setTimeout(() => {\n markSplashShown();\n onDoneRef.current();\n }, 1800);\n return () => {\n window.clearTimeout(t1);\n window.clearTimeout(t2);\n };\n }, []);\n\n useEffect(() => {\n const skip = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\" && e.key !== \"Enter\" && e.key !== \" \") return;\n markSplashShown();\n onDoneRef.current();\n };\n window.addEventListener(\"keydown\", skip);\n return () => window.removeEventListener(\"keydown\", skip);\n }, []);\n\n const skipClick = () => {\n markSplashShown();\n onDone();\n };\n\n return (\n <div className=\"splash\" data-leaving={leaving} onClick={skipClick}>\n <div className=\"splash-card\">\n <div className=\"splash-mark\" />\n <div className=\"splash-name\">Reasonix</div>\n <div className=\"splash-sub\">{t(\"app.splashSubtitle\")}</div>\n <div className=\"splash-dots\">\n <span />\n <span />\n <span />\n </div>\n </div>\n </div>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { I } from \"../icons\";\nimport { t } from \"../i18n\";\nimport type { Balance, Settings, UsageStats } from \"../App\";\nimport type { JobInfo } from \"../protocol\";\nimport { THEME, THEME_STYLES, type Theme, type ThemeStyle, themeForStyle } from \"../theme\";\nimport { localizeShortcutText } from \"./shortcut\";\n\nconst USD_TO_CNY = 7.2;\n\nfunction formatMoney(amountUsd: number, currency: \"CNY\" | \"USD\"): string {\n const symbol = currency === \"CNY\" ? \"¥\" : \"$\";\n const amount = currency === \"CNY\" ? amountUsd * USD_TO_CNY : amountUsd;\n return `${symbol} ${amount.toFixed(4)}`;\n}\n\nfunction tokenLabel(n: number): string {\n if (n >= 1000) return `${(n / 1000).toFixed(1)}k`;\n return `${n}`;\n}\n\nexport function StatusBar({\n settings,\n balance,\n usage,\n busy,\n ready,\n currency,\n theme,\n themeStyle,\n jobs,\n jobsOpen,\n onToggleJobs,\n onSetThemeStyle,\n onToggleCurrency,\n onOpenSettings,\n onOpenWorkdir,\n}: {\n settings: Settings | null;\n balance: Balance | null;\n usage: UsageStats;\n busy: boolean;\n ready: boolean;\n currency: \"CNY\" | \"USD\";\n theme: Theme;\n themeStyle: ThemeStyle;\n jobs: JobInfo[];\n jobsOpen: boolean;\n onToggleJobs: () => void;\n onSetThemeStyle: (style: ThemeStyle) => void;\n onToggleCurrency: () => void;\n onOpenSettings: () => void;\n onOpenWorkdir?: (anchor: { bottom: number; left: number }) => void;\n}) {\n const totalTokens = usage.cacheHitTokens + usage.cacheMissTokens;\n const cacheHitPct = totalTokens > 0 ? Math.round((usage.cacheHitTokens / totalTokens) * 100) : 0;\n const runningJobs = jobs.filter((j) => j.running).length;\n const spent = formatMoney(usage.totalCostUsd, currency);\n const balanceLabel = balance\n ? `${balance.currency === \"USD\" ? \"$\" : \"¥\"} ${balance.total.toFixed(2)}`\n : \"—\";\n const connState = !ready ? \"off\" : busy ? \"running\" : \"online\";\n const [themeOpen, setThemeOpen] = useState(false);\n const themePopRef = useRef<HTMLDivElement | null>(null);\n const themeButtonRef = useRef<HTMLSpanElement | null>(null);\n\n useEffect(() => {\n if (!themeOpen) return;\n const onPointerDown = (event: PointerEvent) => {\n const target = event.target as Node;\n if (themePopRef.current?.contains(target) || themeButtonRef.current?.contains(target)) return;\n setThemeOpen(false);\n };\n window.addEventListener(\"pointerdown\", onPointerDown);\n return () => window.removeEventListener(\"pointerdown\", onPointerDown);\n }, [themeOpen]);\n\n return (\n <footer className=\"statusbar\">\n <span className=\"seg\" title={`API · ${settings?.baseUrl ?? \"api.deepseek.com\"}`}>\n <span\n className={connState === \"off\" ? \"sw warn\" : \"sw\"}\n style={connState === \"off\" ? { background: \"var(--danger)\" } : undefined}\n />\n <span>{settings?.baseUrl?.replace(/^https?:\\/\\//, \"\") ?? \"api.deepseek.com\"}</span>\n <span className=\"v\">{!ready ? t(\"statusbar.offline\") : busy ? t(\"statusbar.busy\") : t(\"statusbar.online\")}</span>\n </span>\n <span className=\"seg\" title={t(\"statusbar.cacheHit\")}>\n <I.zap size={11} style={{ color: \"var(--accent)\" }} />\n <span>{t(\"statusbar.cache\")}</span>\n <span className=\"v acc\">{cacheHitPct}%</span>\n </span>\n <span className=\"seg\">\n <I.cpu size={11} />\n <span>{t(\"statusbar.tokens\")}</span>\n <span className=\"v\">{tokenLabel(totalTokens)}</span>\n </span>\n <span className=\"seg\">\n <I.coin size={11} />\n <span>{t(\"statusbar.thisTurn\")}</span>\n <span className=\"v ok\">{spent}</span>\n </span>\n\n <span className=\"grow\" />\n\n <span\n className={`seg jobs ${jobsOpen ? \"active\" : \"\"}`}\n onClick={onToggleJobs}\n title={localizeShortcutText(t(\"statusbar.jobsTip\"))}\n >\n <I.cpu size={11} />\n <span>{t(\"statusbar.jobs\")}</span>\n <span className={runningJobs > 0 ? \"v acc\" : \"v\"}>{runningJobs}</span>\n </span>\n\n {settings?.workspaceDir ? (\n <span\n className=\"seg\"\n title={t(\"statusbar.switchWorkspace\", { workspace: settings.workspaceDir })}\n style={onOpenWorkdir ? { cursor: \"pointer\" } : undefined}\n onClick={(e) => {\n if (!onOpenWorkdir) return;\n const r = (e.currentTarget as HTMLElement).getBoundingClientRect();\n onOpenWorkdir({ bottom: window.innerHeight - r.top + 6, left: r.left });\n }}\n >\n <I.folder size={11} />\n <span className=\"v\">{settings.workspaceDir.split(/[\\\\/]/).pop() || \"ws\"}</span>\n </span>\n ) : null}\n <span\n className=\"seg\"\n title={`model · effort ${settings?.reasoningEffort ?? \"high\"}`}\n onClick={onOpenSettings}\n >\n <I.brain size={11} style={{ color: \"var(--violet)\" }} />\n <span className=\"v vio\">{settings?.model ?? \"—\"}</span>\n <span className=\"v\">{settings?.reasoningEffort ?? \"high\"}</span>\n </span>\n <span className=\"seg\" title={t(\"statusbar.switchCurrency\")} onClick={onToggleCurrency}>\n <I.coin size={11} />\n <span>{t(\"statusbar.balance\")}</span>\n <span className=\"v ok\">{balanceLabel}</span>\n </span>\n <span\n ref={themeButtonRef}\n className={`seg theme-trigger ${themeOpen ? \"active\" : \"\"}`}\n title={t(\"statusbar.switchTheme\")}\n onClick={() => setThemeOpen((open) => !open)}\n >\n {theme === THEME.DARK ? <I.moon size={11} /> : <I.sun size={11} />}\n <span className=\"v\">\n {t(`statusbar.themeStyle${themeStyle[0]!.toUpperCase()}${themeStyle.slice(1)}` as any)}\n </span>\n </span>\n {themeOpen ? (\n <div ref={themePopRef} className=\"theme-pop\" role=\"menu\" aria-label={t(\"settings.themeStyle\")}>\n <div className=\"theme-pop-head\">\n <div className=\"tt\">{t(\"settings.themeStyle\")}</div>\n <div className=\"ss\">{t(\"statusbar.switchTheme\")}</div>\n </div>\n <div className=\"theme-pop-list\">\n {THEME_STYLES.map((style) => (\n <button\n key={style}\n type=\"button\"\n className=\"theme-pop-item\"\n data-on={themeStyle === style}\n data-style={style}\n onClick={() => {\n onSetThemeStyle(style);\n setThemeOpen(false);\n }}\n >\n <span className=\"style-swatches\" aria-hidden=\"true\">\n <span />\n <span />\n <span />\n </span>\n <span className=\"txt\">\n <span className=\"nm\">\n {t(`statusbar.themeStyle${style[0]!.toUpperCase()}${style.slice(1)}` as any)}\n </span>\n <span className=\"md\">\n {themeForStyle(style) === THEME.DARK\n ? t(\"statusbar.themeDark\")\n : t(\"statusbar.themeLight\")}\n </span>\n </span>\n {themeStyle === style ? <I.check size={13} /> : null}\n </button>\n ))}\n </div>\n </div>\n ) : null}\n </footer>\n );\n}\n","/** Prefix the context-manager prepends when fold replaces older turns with a synthesized recap.\n * Single-sourced here so the agent producer (src/context-manager) and the three UI surfaces\n * (TUI, Desktop, Dashboard) all agree on the wire string. */\nexport const COMPACTION_SUMMARY_MARKER =\n \"[CONVERSATION HISTORY SUMMARY — earlier turns folded for context efficiency]\\n\\n\";\n\nexport function isCompactionSummary(text: string | null | undefined): boolean {\n return typeof text === \"string\" && text.startsWith(COMPACTION_SUMMARY_MARKER);\n}\n\nexport function stripCompactionMarker(text: string): string {\n return text.startsWith(COMPACTION_SUMMARY_MARKER)\n ? text.slice(COMPACTION_SUMMARY_MARKER.length)\n : text;\n}\n","/** First two tokens for known wrappers (`npm install`, `git commit`, …); else first token only.\n * Used by the \"always allow\" permission gate so that `npm test` and `npm run build`\n * share one prefix, while `cargo` and `ls` stay single-token.\n *\n * This function is duplicated in ≥2 build targets (CLI + Desktop), so it lives\n * in `@reasonix/core-utils` to prevent drift like issue #1180. */\nexport function derivePrefix(command: string): string {\n const tokens = command.trim().split(/\\s+/).filter(Boolean);\n if (tokens.length === 0) return \"\";\n if (tokens.length === 1) return tokens[0]!;\n const first = tokens[0]!;\n const TWO_TOKEN_WRAPPERS = new Set([\n \"npm\",\n \"npx\",\n \"pnpm\",\n \"yarn\",\n \"bun\",\n \"git\",\n \"cargo\",\n \"go\",\n \"docker\",\n \"kubectl\",\n \"python\",\n \"python3\",\n \"deno\",\n \"pip\",\n \"pip3\",\n \"make\",\n \"rake\",\n \"bundle\",\n \"gem\",\n ]);\n return TWO_TOKEN_WRAPPERS.has(first) ? `${first} ${tokens[1]}` : first;\n}\n","import { memo, useState, type ReactNode } from \"react\";\nimport { I } from \"../icons\";\nimport { Markdown } from \"../Markdown\";\nimport { t, useLang } from \"../i18n\";\nimport { Shortcut } from \"./shortcut\";\n\ntype Tone = \"default\" | \"success\" | \"warning\" | \"danger\" | \"accent\" | \"violet\";\n\nexport function Card({\n tone = \"default\",\n icon,\n kind,\n name,\n meta,\n defaultOpen = true,\n compact = false,\n children,\n headRight,\n}: {\n tone?: Tone;\n icon: ReactNode;\n kind: string;\n name?: ReactNode;\n meta?: ReactNode;\n defaultOpen?: boolean;\n /** Slimmer header — used for thinking / tool-call process cards so they\n * read as background detail rather than primary content. */\n compact?: boolean;\n children: ReactNode;\n headRight?: ReactNode;\n}) {\n const [open, setOpen] = useState(defaultOpen);\n return (\n <div className={compact ? \"card is-compact\" : \"card\"} data-tone={tone} data-open={open}>\n <button\n type=\"button\"\n className=\"card-head\"\n onClick={() => setOpen((v) => !v)}\n style={{\n width: \"100%\",\n background: \"none\",\n border: \"none\",\n textAlign: \"left\",\n font: \"inherit\",\n color: \"inherit\",\n }}\n >\n <span className=\"ico\">{icon}</span>\n <span className=\"kind\">{kind}</span>\n {name ? <span className=\"name\">{name}</span> : null}\n <span className=\"grow\" />\n {meta ? <span className=\"meta\">{meta}</span> : null}\n {headRight}\n <span className=\"chev\">\n <I.chev size={12} />\n </span>\n </button>\n {open ? <div className=\"card-body\">{children}</div> : null}\n </div>\n );\n}\n\n// ---- Plan ----\n\nexport type PlanItem = {\n id: string | number;\n status: \"todo\" | \"active\" | \"done\" | \"failed\" | \"blocked\" | \"skipped\";\n text: string;\n tool?: string;\n note?: string;\n};\n\nfunction derivePlanBadge(items: PlanItem[]): { state: \"running\" | \"done\" | \"failed\" | \"waiting\" | \"blocked\"; label: string } {\n if (items.some((x) => x.status === \"failed\")) return { state: \"failed\", label: t(\"planBadge.failed\") };\n if (items.some((x) => x.status === \"blocked\")) return { state: \"blocked\", label: t(\"planBadge.blocked\") };\n if (items.some((x) => x.status === \"active\")) return { state: \"running\", label: t(\"planBadge.running\") };\n if (items.length > 0 && items.every((x) => x.status === \"done\")) return { state: \"done\", label: t(\"planBadge.done\") };\n return { state: \"waiting\", label: t(\"planBadge.pending\") };\n}\n\nfunction StatusIcon({ state, label }: { state: \"running\" | \"done\" | \"failed\" | \"waiting\" | \"blocked\"; label: string }) {\n switch (state) {\n case \"running\":\n return <span className=\"spin-meta\" role=\"img\" aria-label={label} title={label} />;\n case \"done\":\n return <I.check size={10} style={{ color: \"var(--success)\" }} aria-label={label} />;\n case \"failed\":\n return <I.x size={10} style={{ color: \"var(--danger)\" }} aria-label={label} />;\n case \"waiting\":\n return <span className=\"status-dot warn\" role=\"img\" aria-label={label} title={label} />;\n case \"blocked\":\n return <I.slash size={10} style={{ color: \"var(--warning)\" }} aria-label={label} />;\n }\n}\n\nexport function PlanCardView({ items, title }: { items: PlanItem[]; title?: string }) {\n useLang();\n const resolvedTitle = title ?? t(\"cards.planDefaultTitle\");\n const done = items.filter((x) => x.status === \"done\").length;\n const badge = derivePlanBadge(items);\n return (\n <Card\n tone=\"accent\"\n icon={<I.list size={12} />}\n kind=\"plan\"\n name={resolvedTitle}\n meta={\n <>\n <span>\n {done}/{items.length}\n </span>\n <StatusIcon state={badge.state} label={badge.label} />\n <span className=\"meta-label\">{badge.label}</span>\n </>\n }\n >\n <ul className=\"plan-list\" style={{ listStyle: \"none\", margin: 0, padding: \"8px 12px 12px\" }}>\n {items.map((it) => (\n <li key={it.id} className=\"plan-item\" data-status={it.status}>\n <span className=\"ck\">{it.status === \"done\" ? <I.check size={12} /> : null}</span>\n <div>\n <div className=\"text\">{it.text}</div>\n {it.tool || it.note ? (\n <div className=\"sub\">\n {it.tool ? <span className=\"tool\">{it.tool}</span> : null}\n {it.note ? <span>{it.note}</span> : null}\n </div>\n ) : null}\n </div>\n <span className=\"stat\">{it.status === \"active\" ? <span className=\"spin\" /> : null}</span>\n </li>\n ))}\n </ul>\n </Card>\n );\n}\n\n// ---- Reasoning ----\n\nexport function ReasoningCard({\n text,\n streaming,\n tokens,\n elapsed,\n model,\n}: {\n text: string;\n streaming: boolean;\n tokens?: number;\n elapsed?: string;\n model?: string;\n}) {\n useLang();\n return (\n <Card\n tone=\"violet\"\n icon={<I.brain size={12} />}\n kind=\"reasoning\"\n name={t(\"cards.reasoningName\")}\n meta={\n <>\n {elapsed || tokens ? (\n <span>\n {elapsed ?? \"\"}\n {elapsed && tokens ? \" · \" : \"\"}\n {tokens ? `${tokens.toLocaleString()} t` : \"\"}\n </span>\n ) : null}\n {streaming ? (\n <StatusIcon state=\"running\" label={t(\"cards.streaming\")} />\n ) : (\n <StatusIcon state=\"done\" label={t(\"cards.reasoningComplete\")} />\n )}\n </>\n }\n defaultOpen={streaming}\n compact\n >\n <div className=\"reason\">\n <div className=\"stream\">\n {text.split(/\\n\\n+/).map((para, i) => (\n <p\n key={i}\n dangerouslySetInnerHTML={{\n __html: para\n .replace(/`([^`]+)`/g, '<span class=\"hl\">$1</span>')\n .replace(/\\*\\*([^*]+)\\*\\*/g, \"<strong>$1</strong>\"),\n }}\n />\n ))}\n </div>\n {model || tokens !== undefined ? (\n <div className=\"meta\">\n {model ? (\n <span>\n <span className=\"k\">{t(\"settings.model\")}</span> {model}\n </span>\n ) : null}\n {tokens !== undefined ? (\n <span>\n <span className=\"k\">{t(\"statusbar.tokens\")}</span> {tokens.toLocaleString()}\n </span>\n ) : null}\n </div>\n ) : null}\n </div>\n </Card>\n );\n}\n\n// ---- Shell ----\n\nexport function ShellCard({\n command,\n output,\n state,\n durationMs,\n onApprove,\n onReject,\n onAlwaysAllow,\n}: {\n command: string;\n output?: string;\n state: \"await\" | \"running\" | \"done\" | \"failed\";\n durationMs?: number;\n onApprove?: () => void;\n onReject?: () => void;\n onAlwaysAllow?: () => void;\n}) {\n useLang();\n const tone: Tone = state === \"failed\" ? \"danger\" : state === \"done\" ? \"success\" : \"warning\";\n return (\n <Card\n tone={tone}\n icon={<I.terminal size={12} />}\n kind=\"shell\"\n name=\"shell\"\n compact\n meta={\n <>\n {state === \"await\" ? (\n <StatusIcon state=\"waiting\" label={t(\"cards.shellAwaiting\")} />\n ) : state === \"running\" ? (\n <StatusIcon state=\"running\" label={t(\"cards.shellRunning\")} />\n ) : state === \"failed\" ? (\n <StatusIcon state=\"failed\" label={t(\"cards.failed\")} />\n ) : (\n <StatusIcon state=\"done\" label={t(\"cards.done\")} />\n )}\n {(state === \"done\" || state === \"failed\") && durationMs ? (\n <span className=\"meta-dur\">{(durationMs / 1000).toFixed(2)}s</span>\n ) : null}\n </>\n }\n >\n <div className=\"shell\">\n <div className=\"cmd\">\n <span className=\"prompt\">$</span>\n <span className=\"text\">{command}</span>\n </div>\n {output ? (\n <pre className=\"out\">\n {output.split(\"\\n\").map((ln, i) => {\n if (ln.startsWith(\" ✓\") || ln.startsWith(\"✓\"))\n return (\n <div key={i}>\n <span className=\"ok\">{ln}</span>\n </div>\n );\n if (ln.startsWith(\" ✗\") || ln.startsWith(\"✗\") || /error/i.test(ln))\n return (\n <div key={i}>\n <span className=\"err\">{ln}</span>\n </div>\n );\n return <div key={i}>{ln}</div>;\n })}\n </pre>\n ) : null}\n {state === \"await\" && onApprove ? (\n <div className=\"approve-row\">\n <div className=\"why\">\n <b>{t(\"cards.shellAwaiting\")}</b> — {t(\"cards.shellExecuteHint\")}\n </div>\n <div className=\"actions\">\n {onAlwaysAllow ? (\n <button type=\"button\" className=\"btn ghost\" onClick={onAlwaysAllow}>\n {t(\"cards.shellAlwaysAllow\")}\n </button>\n ) : null}\n {onReject ? (\n <button type=\"button\" className=\"btn\" onClick={onReject}>\n {t(\"cards.shellReject\")} <Shortcut keys={[\"mod\", \".\"]} />\n </button>\n ) : null}\n <button type=\"button\" className=\"btn primary\" onClick={onApprove}>\n {t(\"cards.shellRun\")} <Shortcut keys={[\"mod\", \"enter\"]} />\n </button>\n </div>\n </div>\n ) : null}\n </div>\n </Card>\n );\n}\n\n// ---- Compaction ----\n\nexport function CompactionCard({ summary }: { summary: string }) {\n useLang();\n const charCount = summary.length;\n return (\n <Card\n tone=\"default\"\n icon={<I.archive size={12} />}\n kind=\"compaction\"\n name={t(\"cards.compactionName\")}\n meta={<span>{t(\"cards.compactionMeta\", { chars: charCount.toLocaleString() })}</span>}\n defaultOpen={false}\n compact\n >\n <div className=\"compaction-body\">\n <Markdown source={summary} />\n </div>\n </Card>\n );\n}\n\n// ---- Generic Tool ----\n\nexport function ToolCard({\n name,\n args,\n result,\n ok,\n durationMs,\n}: {\n name: string;\n args?: string;\n result?: string;\n ok?: boolean;\n durationMs?: number;\n}) {\n useLang();\n const running = result === undefined;\n const tone: Tone = running ? \"default\" : ok === false ? \"danger\" : \"success\";\n return (\n <Card\n tone={tone}\n icon={<I.wrench size={12} />}\n kind=\"tool\"\n name={name}\n defaultOpen={false}\n compact\n meta={\n <>\n {running ? (\n <StatusIcon state=\"running\" label={t(\"cards.running\")} />\n ) : ok === false ? (\n <StatusIcon state=\"failed\" label={t(\"cards.error\")} />\n ) : (\n <StatusIcon state=\"done\" label={t(\"cards.done\")} />\n )}\n {!running && durationMs !== undefined ? (\n <span className=\"meta-dur\">{durationMs} ms</span>\n ) : null}\n </>\n }\n >\n <div className=\"tool-call\">\n {args ? (\n <div className=\"row\">\n <span className=\"k\">args</span>\n <span className=\"v\">\n <span className=\"str\">{args.length > 600 ? `${args.slice(0, 600)}…` : args}</span>\n </span>\n </div>\n ) : null}\n {result !== undefined ? (\n <div className=\"row\">\n <span className=\"k\">{ok === false ? t(\"cards.error\") : t(\"cards.result\")}</span>\n <span className=\"v\">\n <span className={ok === false ? \"num\" : \"str\"}>\n {result.length > 1200 ? `${result.slice(0, 1200)}…` : result}\n </span>\n </span>\n </div>\n ) : null}\n </div>\n </Card>\n );\n}\n\n// ---- Diff ----\n\nexport type DiffLine =\n | { t: \"hunk\"; s: string }\n | { t: \"ctx\"; l?: number; r?: number; s: string }\n | { t: \"add\"; r: number; s: string }\n | { t: \"rm\"; l: number; s: string };\n\nexport function DiffCard({\n filename,\n lines,\n applied,\n onApply,\n onDiscard,\n}: {\n filename: string;\n lines: DiffLine[];\n applied?: boolean;\n onApply?: () => void;\n onDiscard?: () => void;\n}) {\n useLang();\n const adds = lines.filter((x) => x.t === \"add\").length;\n const rms = lines.filter((x) => x.t === \"rm\").length;\n return (\n <Card\n tone={applied ? \"success\" : \"accent\"}\n icon={<I.diff size={12} />}\n kind=\"edit\"\n name={filename}\n meta={\n <>\n <span style={{ color: \"var(--success)\" }}>+{adds}</span>\n <span style={{ color: \"var(--danger)\" }}>−{rms}</span>\n {applied ? (\n <StatusIcon state=\"done\" label={t(\"cards.applied\")} />\n ) : (\n <StatusIcon state=\"waiting\" label={t(\"cards.diffAwaiting\")} />\n )}\n </>\n }\n >\n <div className=\"diff\">\n <div className=\"lines\">\n {lines.map((ln, i) => {\n if (ln.t === \"hunk\")\n return (\n <div key={i} className=\"ln hunk\">\n <span className=\"code\">{ln.s}</span>\n </div>\n );\n const cls = ln.t === \"add\" ? \"add\" : ln.t === \"rm\" ? \"rm\" : \"\";\n const l = ln.t === \"ctx\" ? ln.l : ln.t === \"rm\" ? ln.l : undefined;\n const r = ln.t === \"ctx\" ? ln.r : ln.t === \"add\" ? ln.r : undefined;\n return (\n <div key={i} className={`ln ${cls}`}>\n <span className=\"num\">{l ?? \"\"}</span>\n <span className=\"num\">{r ?? \"\"}</span>\n <span className=\"code\">\n {ln.t === \"add\" ? \"+ \" : ln.t === \"rm\" ? \"− \" : \" \"}\n {ln.s}\n </span>\n </div>\n );\n })}\n </div>\n {!applied && (onApply || onDiscard) ? (\n <div className=\"approve-row\">\n <div className=\"why\">\n <b>{t(\"cards.diffApplyChanges\")}</b> · +{adds} / −{rms}\n </div>\n <div className=\"actions\">\n {onDiscard ? (\n <button type=\"button\" className=\"btn\" onClick={onDiscard}>\n {t(\"cards.diffDiscard\")}\n </button>\n ) : null}\n {onApply ? (\n <button type=\"button\" className=\"btn primary\" onClick={onApply}>\n {t(\"cards.diffApply\")} <Shortcut keys={[\"mod\", \"enter\"]} />\n </button>\n ) : null}\n </div>\n </div>\n ) : null}\n </div>\n </Card>\n );\n}\n\n// ---- Error ----\n\nexport function ErrorCard({ message, hint, code }: { message: string; hint?: ReactNode; code?: string }) {\n useLang();\n return (\n <Card\n tone=\"danger\"\n icon={<I.warning size={12} />}\n kind=\"error\"\n name={t(\"cards.errorName\")}\n meta={code ? <span className=\"pill-tag err\">{code}</span> : null}\n >\n <div className=\"error-body\">\n <div className=\"msg-err\">{message}</div>\n {hint ? <div className=\"hint\">{hint}</div> : null}\n </div>\n </Card>\n );\n}\n\n// ---- Search results ----\n\nexport type SearchHit = { url: string; title: string; snippet: string };\n\nexport function WebSearchCard({ query, results }: { query: string; results: SearchHit[] }) {\n useLang();\n return (\n <Card\n tone=\"default\"\n icon={<I.globe size={12} />}\n kind=\"web_search\"\n name={t(\"cards.searchName\")}\n meta={\n <>\n <span>\"{query}\"</span>\n <span className=\"pill-tag ok\">{results.length} {t(\"cards.hits\")}</span>\n </>\n }\n >\n <div className=\"search-results\">\n {results.map((r, i) => (\n <div className=\"search-result\" key={i}>\n <div className=\"url\">\n <span className=\"favicon\" />\n <span>{r.url}</span>\n </div>\n <div className=\"title\">{r.title}</div>\n <div className=\"snippet\">{r.snippet}</div>\n </div>\n ))}\n </div>\n </Card>\n );\n}\n\n// ---- Subagent ----\n\nexport type SubAgentChild = {\n avatar: string;\n what: string;\n role: string;\n status: \"done\" | \"running\" | \"queued\";\n};\n\nexport function SubagentCard({\n name,\n children,\n status,\n}: {\n name: string;\n children: SubAgentChild[];\n status: \"running\" | \"done\" | \"failed\";\n}) {\n useLang();\n const done = children.filter((c) => c.status === \"done\").length;\n return (\n <Card\n tone=\"violet\"\n icon={<I.bot size={12} />}\n kind=\"subagent\"\n name={name}\n meta={\n <>\n <span>\n {done} / {children.length} {t(\"cards.subagentDoneProgress\")}\n </span>\n {status === \"done\" ? (\n <StatusIcon state=\"done\" label={t(\"cards.subagentDone\")} />\n ) : status === \"failed\" ? (\n <StatusIcon state=\"failed\" label={t(\"cards.subagentFailed\")} />\n ) : (\n <StatusIcon state=\"running\" label={t(\"cards.subagentRunning\")} />\n )}\n </>\n }\n >\n <div className=\"sub-card\">\n {children.map((c, i) => (\n <div className=\"sub-row\" key={i}>\n <span className=\"av\">{c.avatar}</span>\n <div className=\"what\">\n <div>{c.what}</div>\n <div className=\"role\">{c.role}</div>\n </div>\n <span className=\"prog\">\n {c.status === \"done\" ? (\n <I.check size={12} style={{ color: \"var(--success)\" }} />\n ) : c.status === \"running\" ? (\n <span className=\"spin\" />\n ) : null}\n </span>\n </div>\n ))}\n </div>\n </Card>\n );\n}\n\n// ---- Memory rows ----\n\nexport type MemRow = { scope: string; txt: string };\n\nexport function MemoryCard({ rows }: { rows: MemRow[] }) {\n useLang();\n return (\n <Card\n tone=\"violet\"\n icon={<I.bookmark size={12} />}\n kind=\"memory\"\n name={t(\"cards.memoryName\")}\n meta={<span>+ {rows.length} {t(\"cards.memoryCountSuffix\")}</span>}\n >\n <div className=\"mem\">\n {rows.map((m, i) => (\n <div className=\"mem-row\" key={i}>\n <span className=\"scope\">{m.scope}</span>\n <span className=\"txt\">{m.txt}</span>\n </div>\n ))}\n </div>\n </Card>\n );\n}\n\n// ---- Image attachment ----\n\nexport function AttachCard({\n filename,\n meta,\n preview,\n}: {\n filename: string;\n meta: string;\n preview?: string;\n}) {\n useLang();\n return (\n <Card\n tone=\"default\"\n icon={<I.image size={12} />}\n kind=\"image\"\n name={filename}\n meta={<span>{meta}</span>}\n >\n <div className=\"attach-card\">\n <div className=\"ph\">{preview ?? \"PNG\"}</div>\n <div className=\"info\">\n <div className=\"n\">{filename}</div>\n <div className=\"m\">{meta}</div>\n </div>\n <button type=\"button\" className=\"btn ghost\">\n <I.download size={12} />\n </button>\n </div>\n </Card>\n );\n}\n\n// ---- Metric strip (inline) ----\n\nexport function MetricStrip({\n cacheHit,\n promptTokens,\n outputTokens,\n costLabel,\n elapsed,\n}: {\n cacheHit?: number;\n promptTokens?: number;\n outputTokens?: number;\n costLabel?: string;\n elapsed?: string;\n}) {\n return (\n <div className=\"metric-strip\">\n {cacheHit !== undefined ? (\n <span className=\"item\">\n <I.zap size={11} style={{ color: \"var(--accent)\" }} />\n <span>{t(\"cards.cacheHit\")}</span>\n <span className=\"v acc\">{cacheHit}%</span>\n </span>\n ) : null}\n {promptTokens !== undefined ? (\n <span className=\"item\">\n <span>{t(\"cards.prompt\")}</span>\n <span className=\"v\">{promptTokens.toLocaleString()} t</span>\n </span>\n ) : null}\n {outputTokens !== undefined ? (\n <span className=\"item\">\n <span>{t(\"cards.output\")}</span>\n <span className=\"v\">{outputTokens.toLocaleString()} t</span>\n </span>\n ) : null}\n {costLabel ? (\n <span className=\"item\">\n <I.coin size={11} />\n <span>{t(\"cards.cost\")}</span>\n <span className=\"v ok\">{costLabel}</span>\n </span>\n ) : null}\n {elapsed ? (\n <span className=\"item\">\n <span>{t(\"cards.elapsed\")}</span>\n <span className=\"v\">{elapsed}</span>\n </span>\n ) : null}\n </div>\n );\n}\n\n// ---- Checkpoint marker (inline) ----\n\nexport function Checkpoint({\n hash,\n label,\n onRewind,\n}: {\n hash: string;\n label: string;\n onRewind?: () => void;\n}) {\n useLang();\n return (\n <div className=\"checkpoint\">\n <I.history size={12} />\n <span className=\"hash\">{hash}</span>\n <span>·</span>\n <span>{label}</span>\n {onRewind ? (\n <button type=\"button\" onClick={onRewind}>\n {t(\"cards.checkpointRewind\")}\n </button>\n ) : null}\n </div>\n );\n}\n\n// ---- Plain text block (assistant content via markdown) ----\n\nexport const AssistantText = memo(function AssistantText({ text }: { text: string }) {\n return (\n <div className=\"msg-text\">\n <Markdown source={text} />\n </div>\n );\n});\n","import type { ReactNode } from \"react\";\nimport { I } from \"../icons\";\nimport { t, useLang } from \"../i18n\";\n\nexport type ApprovalTone = \"ok\" | \"warn\" | \"danger\" | \"info\" | \"brand\" | \"ghost\";\n\nexport function ApprovalCard({\n kind,\n tone = \"info\",\n title,\n sub,\n body,\n preview,\n meta,\n primaryLabel,\n secondaryLabel,\n tertiaryLabel,\n onPrimary,\n onSecondary,\n onTertiary,\n}: {\n kind: string;\n tone?: ApprovalTone;\n title: string;\n sub?: string;\n body?: ReactNode;\n preview?: ReactNode;\n meta?: ReactNode;\n primaryLabel?: string;\n secondaryLabel?: string;\n tertiaryLabel?: string;\n onPrimary?: () => void;\n onSecondary?: () => void;\n onTertiary?: () => void;\n}) {\n useLang();\n return (\n <div className=\"approval\" data-tone={tone}>\n <div className=\"ap-head\">\n <span className=\"ap-ico\">\n <I.shield size={13} />\n </span>\n <div>\n <div className=\"ap-kind\">{kind}</div>\n <div className=\"ap-title\">{title}</div>\n {sub ? <div className=\"ap-sub\">{sub}</div> : null}\n </div>\n </div>\n {body ? <div className=\"ap-body\">{body}</div> : null}\n {preview ? <div className=\"ap-preview\">{preview}</div> : null}\n <div className=\"ap-foot\">\n {onPrimary ? (\n <button type=\"button\" className=\"btn primary\" onClick={onPrimary}>\n {primaryLabel ?? t(\"extraCards.approve\")}\n </button>\n ) : null}\n {onSecondary ? (\n <button type=\"button\" className=\"btn ghost\" onClick={onSecondary}>\n {secondaryLabel ?? t(\"extraCards.reject\")}\n </button>\n ) : null}\n {onTertiary && tertiaryLabel ? (\n <button type=\"button\" className=\"btn ghost\" onClick={onTertiary}>\n {tertiaryLabel}\n </button>\n ) : null}\n <span className=\"grow\" />\n {meta ? <span className=\"meta\">{meta}</span> : null}\n </div>\n </div>\n );\n}\n\n// ---- Task Card (multi-step execution from active plan) ----\n\nexport type TaskStepView = {\n n: string;\n state: \"queued\" | \"running\" | \"done\" | \"failed\" | \"blocked\" | \"skipped\";\n label: string;\n hint?: string;\n durationLabel?: string;\n};\n\nexport function TaskCard({\n title,\n subtitle,\n steps,\n}: {\n title: string;\n subtitle?: string;\n steps: TaskStepView[];\n}) {\n useLang();\n const done = steps.filter((x) => x.state === \"done\").length;\n const pct = steps.length ? (done / steps.length) * 100 : 0;\n return (\n <div className=\"task-card\">\n <div className=\"th\">\n <span className=\"ico\">\n <I.list size={13} />\n </span>\n <div>\n <div className=\"tt\">{title}</div>\n {subtitle ? <div className=\"ss\">{subtitle}</div> : null}\n </div>\n <span className=\"grow\" />\n <span className=\"ss\">\n {done}/{steps.length}\n </span>\n <div className=\"meter\">\n <span style={{ width: `${pct}%` }} />\n </div>\n </div>\n <div className=\"tb\">\n {steps.map((st) => (\n <div className=\"task-step\" key={st.n} data-state={st.state}>\n <span className=\"nx\">step.{st.n}</span>\n <span className=\"st\" />\n <div className=\"l\">\n {st.label}\n {st.hint ? <div className=\"h\">{st.hint}</div> : null}\n </div>\n <span className=\"t\">{st.durationLabel ?? \"—\"}</span>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\n// ---- Warn / Tip / Doctor ----\n\nexport function WarnCard({ title, body }: { title: string; body: ReactNode }) {\n return (\n <div className=\"warn-card\">\n <span className=\"ico\">\n <I.warn size={16} />\n </span>\n <div>\n <div className=\"tt\">{title}</div>\n <div className=\"ds\">{body}</div>\n </div>\n </div>\n );\n}\n\nexport type TipSection = { title: string; rows: ReactNode[] };\n\nexport function TipCard({\n topic,\n command,\n sections,\n footer,\n}: {\n topic: string;\n command?: string;\n sections: TipSection[];\n footer?: ReactNode;\n}) {\n return (\n <div className=\"tip-card\">\n <div className=\"head\">\n <span className=\"ico\">\n <I.help size={12} />\n </span>\n <span className=\"topic\">{topic}</span>\n <span className=\"grow\" />\n {command ? <span className=\"pill\">{command}</span> : null}\n </div>\n {sections.map((sec, i) => (\n <div className=\"sec\" key={i}>\n <div className=\"stt\">{sec.title}</div>\n {sec.rows.map((r, j) => (\n <div className=\"row\" key={j}>\n {r}\n </div>\n ))}\n </div>\n ))}\n {footer ? <div className=\"foot\">{footer}</div> : null}\n </div>\n );\n}\n\nexport type DoctorRow = { s: \"ok\" | \"warn\" | \"fail\"; nm: string; sub: string; v: string };\n\nexport function DoctorCard({ rows, headerSubtitle }: { rows: DoctorRow[]; headerSubtitle?: string }) {\n useLang();\n const c = { ok: 0, warn: 0, fail: 0 };\n for (const r of rows) c[r.s]++;\n return (\n <div className=\"doctor-card\">\n <div className=\"dh\">\n <span className=\"ico\">\n <I.shield size={13} />\n </span>\n <div>\n <div className=\"tt\">{t(\"extraCards.doctorTitle\")}</div>\n {headerSubtitle ? (\n <div\n className=\"ss\"\n style={{\n fontFamily: \"Geist Mono, monospace\",\n fontSize: 10.5,\n color: \"var(--muted)\",\n }}\n >\n {headerSubtitle}\n </div>\n ) : null}\n </div>\n <span className=\"grow\" />\n <div className=\"summary\">\n <span>\n <span className=\"b ok\">{c.ok}</span> ok\n </span>\n <span>\n <span className=\"b warn\">{c.warn}</span> warn\n </span>\n <span>\n <span className=\"b err\">{c.fail}</span> fail\n </span>\n </div>\n </div>\n {rows.map((r, i) => (\n <div className=\"doctor-row\" key={i} data-s={r.s}>\n <span className=\"ic\" data-mark={r.s === \"ok\" ? \"✓\" : r.s === \"warn\" ? \"!\" : \"✕\"} />\n <div className=\"body\">\n <div className=\"nm\">{r.nm}</div>\n <div className=\"sub\">{r.sub}</div>\n </div>\n <span className=\"v\">{r.v}</span>\n </div>\n ))}\n </div>\n );\n}\n\n// ---- Usage (full) ----\n\nexport function UsageFull({\n promptTokens,\n reasoningTokens,\n outputTokens,\n cacheHitTokens,\n costLabel,\n balanceLabel,\n range,\n}: {\n promptTokens: number;\n reasoningTokens: number;\n outputTokens: number;\n cacheHitTokens: number;\n costLabel: string;\n balanceLabel?: string;\n range?: string;\n}) {\n useLang();\n const fmt = (n: number) => (n >= 1000 ? `${(n / 1000).toFixed(1)}k` : `${n}`);\n const total = promptTokens + reasoningTokens + outputTokens + cacheHitTokens || 1;\n const pct = (n: number) => Math.round((n / total) * 100);\n return (\n <div className=\"usage-full\">\n <div className=\"uh\">\n <div>\n <div className=\"tt\">{t(\"extraCards.sessionUsage\")}</div>\n {range ? <div className=\"ss\">{range}</div> : null}\n </div>\n <span className=\"grow\" />\n </div>\n <div className=\"ub\">\n <div className=\"ucol\">\n <div className=\"l\">{t(\"extraCards.prompt\")}</div>\n <div className=\"v acc\">{fmt(promptTokens)}</div>\n <div className=\"pct\">{pct(promptTokens)}%</div>\n </div>\n <div className=\"ucol\">\n <div className=\"l\">{t(\"extraCards.reasoning\")}</div>\n <div className=\"v vio\">{fmt(reasoningTokens)}</div>\n <div className=\"pct\">{pct(reasoningTokens)}%</div>\n </div>\n <div className=\"ucol\">\n <div className=\"l\">{t(\"extraCards.output\")}</div>\n <div className=\"v ok\">{fmt(outputTokens)}</div>\n <div className=\"pct\">{pct(outputTokens)}%</div>\n </div>\n <div className=\"ucol\">\n <div className=\"l\">{t(\"extraCards.cacheHit\")}</div>\n <div className=\"v\">{fmt(cacheHitTokens)}</div>\n <div className=\"pct\">{pct(cacheHitTokens)}%</div>\n </div>\n </div>\n <div className=\"stack\">\n <span className=\"s1\" style={{ width: `${pct(promptTokens)}%` }} />\n <span className=\"s2\" style={{ width: `${pct(reasoningTokens)}%` }} />\n <span className=\"s3\" style={{ width: `${pct(outputTokens)}%` }} />\n <span className=\"s4\" style={{ width: `${pct(cacheHitTokens)}%` }} />\n </div>\n <div className=\"uf\">\n <span className=\"x\">\n <span className=\"sw\" style={{ background: \"var(--accent)\" }} />\n {t(\"extraCards.prompt\")}\n </span>\n <span className=\"x\">\n <span className=\"sw\" style={{ background: \"var(--violet)\" }} />\n {t(\"extraCards.reasoning\")}\n </span>\n <span className=\"x\">\n <span className=\"sw\" style={{ background: \"var(--tone-ok)\" }} />\n {t(\"extraCards.output\")}\n </span>\n <span className=\"x\">\n <span className=\"sw\" style={{ background: \"var(--border-strong)\" }} />\n {t(\"extraCards.cache\")}\n </span>\n <span style={{ marginLeft: \"auto\" }}>\n {t(\"extraCards.sessionCost\", { costLabel })}\n {balanceLabel ? ` · ${t(\"extraCards.balance\", { balanceLabel })}` : \"\"}\n </span>\n </div>\n </div>\n );\n}\n\n// ---- Context window breakdown ----\n\nexport type CtxPart = { k: \"system\" | \"tools\" | \"log\" | \"input\"; label: string; value: string; widthPct: number };\nexport type CtxTopRow = { name: string; widthPct: number; value: string };\n\nexport function CtxCard({\n totalLabel,\n parts,\n topTools,\n}: {\n totalLabel: string;\n parts: CtxPart[];\n topTools: CtxTopRow[];\n}) {\n useLang();\n return (\n <div className=\"ctx-card\">\n <div className=\"h\">\n <span className=\"tt\">{t(\"extraCards.contextWindow\")}</span>\n <span className=\"grow\" />\n <span className=\"v\">{totalLabel}</span>\n </div>\n <div className=\"bar\">\n {parts.map((p) => (\n <span key={p.k} className={p.k} style={{ width: `${p.widthPct}%` }} />\n ))}\n </div>\n <div className=\"legend\">\n {parts.map((p) => {\n const color =\n p.k === \"system\"\n ? \"var(--accent)\"\n : p.k === \"tools\"\n ? \"var(--violet)\"\n : p.k === \"log\"\n ? \"var(--tone-ok)\"\n : \"var(--tone-warn)\";\n return (\n <div key={p.k}>\n <span className=\"sw\" style={{ background: color }} />\n <span className=\"l\">{p.label}</span>\n <span className=\"v\">{p.value}</span>\n </div>\n );\n })}\n </div>\n {topTools.length > 0 ? (\n <div className=\"ttop\">\n <div className=\"stt\">{t(\"extraCards.topToolsUsage\")}</div>\n {topTools.map((t, i) => (\n <div className=\"row\" key={i}>\n <span className=\"n\">{t.name}</span>\n <div className=\"bbar\">\n <span style={{ width: `${t.widthPct}%` }} />\n </div>\n <span className=\"v\">{t.value}</span>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n );\n}\n\n// ---- Memory groups ----\n\nexport type MemGroupKey = \"user\" | \"feedback\" | \"project\" | \"reference\";\nexport type MemEntry = { text: string; meta?: string };\nexport type MemGroups = Partial<Record<MemGroupKey, MemEntry[]>>;\n\nconst GROUP_LABELS: Record<MemGroupKey, Parameters<typeof t>[0]> = {\n user: \"extraCards.memoryUser\",\n feedback: \"extraCards.memoryFeedback\",\n project: \"extraCards.memoryProject\",\n reference: \"extraCards.memoryReference\",\n};\n\nexport function MemoryGroups({ data }: { data: MemGroups }) {\n useLang();\n const keys: MemGroupKey[] = [\"user\", \"feedback\", \"project\", \"reference\"];\n return (\n <div className=\"mem-groups\">\n {keys.map((g) => {\n const rows = data[g] ?? [];\n if (rows.length === 0) return null;\n return (\n <div key={g}>\n <div className=\"gh\" data-g={g}>\n <span className=\"sw\" />\n <span>{t(GROUP_LABELS[g])}</span>\n <span className=\"grow\" />\n <span className=\"cnt\">{rows.length}</span>\n </div>\n {rows.map((r, i) => (\n <div className=\"mrow\" key={i}>\n <span className=\"b\">·</span>\n <div className=\"t\">{r.text}</div>\n {r.meta ? <span className=\"meta\">{r.meta}</span> : null}\n </div>\n ))}\n </div>\n );\n })}\n </div>\n );\n}\n\n// ---- Fallback ----\n\nexport function FallbackCard({ kindLabel, payload }: { kindLabel: string; payload: Record<string, string> }) {\n useLang();\n return (\n <div className=\"fallback-card\">\n <div className=\"hd\">{t(\"extraCards.unknownKind\")}</div>\n <div className=\"kv\">\n <span className=\"k\">kind</span>\n <span className=\"v\">\"{kindLabel}\"</span>\n {Object.entries(payload).map(([k, v]) => (\n <span key={k} style={{ display: \"contents\" }}>\n <span className=\"k\">{k}</span>\n <span className=\"v\">{v}</span>\n </span>\n ))}\n </div>\n </div>\n );\n}\n\n// ---- LiveCard (pill variants) ----\n\nexport type LiveVariant =\n | \"thinking\"\n | \"undo\"\n | \"ctxPressure\"\n | \"aborted\"\n | \"retry\"\n | \"checkpoint\"\n | \"stepProgress\"\n | \"mcpEvent\"\n | \"sessionOp\";\n\nexport function LiveCard({\n variant,\n icon,\n body,\n action,\n onAction,\n}: {\n variant: LiveVariant;\n icon: ReactNode;\n body: ReactNode;\n action?: string;\n onAction?: () => void;\n}) {\n return (\n <span className={`live-card ${variant === \"stepProgress\" ? \"step\" : \"\"}`} data-v={variant}>\n <span className=\"lc-ico\">{icon}</span>\n <span className=\"lc-body\">{body}</span>\n {action ? (\n <button type=\"button\" className=\"lc-act\" onClick={onAction}>\n {action}\n </button>\n ) : null}\n </span>\n );\n}\n","import { isCompactionSummary, stripCompactionMarker } from \"@reasonix/core-utils/compaction\";\nimport { derivePrefix } from \"@reasonix/core-utils/derive-prefix\";\nimport { memo, useState, type ReactNode } from \"react\";\nimport { Copy } from \"lucide-react\";\nimport { I } from \"../icons\";\nimport { t, useLang } from \"../i18n\";\nimport type { AssistantSegment, ActivePlan, PendingPlan, PendingCheckpoint, PendingRevision, PendingConfirm, PendingChoice, SkillOrigin } from \"../App\";\nimport { AssistantText, CompactionCard, PlanCardView, ReasoningCard, ShellCard, ToolCard, type PlanItem } from \"./cards\";\nimport { ApprovalCard, TaskCard, type TaskStepView } from \"./extra-cards\";\n\nexport function TurnDivider({ label }: { label: string }) {\n return (\n <div className=\"turn-divider\">\n <span>{label}</span>\n <span className=\"line\" />\n </div>\n );\n}\n\nexport const UserMsg = memo(function UserMsg({\n text,\n time,\n skill,\n}: {\n text: string;\n time?: string;\n skill?: SkillOrigin;\n}) {\n useLang();\n const [copied, setCopied] = useState(false);\n const onCopy = async () => {\n try {\n await navigator.clipboard.writeText(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n } catch {\n /* ignore */\n }\n };\n return (\n <div className=\"msg user\">\n <div className=\"avatar\">YOU</div>\n <div className=\"body\">\n <div className=\"who\">\n <span className=\"name\">{t(\"thread.you\")}</span>\n {skill ? (\n <span className=\"skill-chip\" title={`skill · ${skill.runAs}`}>\n <I.zap size={10} /> /{skill.name}\n {skill.runAs === \"subagent\" ? <span className=\"sub\">{t(\"thread.subagent\")}</span> : null}\n </span>\n ) : null}\n {time ? <span className=\"time\">{time}</span> : null}\n </div>\n <div className=\"msg-text\">{text}</div>\n <div className=\"msg-actions\">\n <button\n type=\"button\"\n className={`copy-btn ${copied ? \"done\" : \"\"}`}\n onClick={onCopy}\n title={t(\"thread.copyMessage\")}\n >\n <Copy size={11} />\n {copied ? t(\"markdown.copied\") : null}\n </button>\n </div>\n </div>\n </div>\n );\n});\n\nexport const AssistantMsg = memo(function AssistantMsg({\n segments,\n pending,\n model,\n time,\n onApproveConfirm,\n onRejectConfirm,\n onAlwaysAllowConfirm,\n pendingConfirms,\n}: {\n segments: AssistantSegment[];\n pending: boolean;\n model?: string;\n time?: string;\n onApproveConfirm: (id: number) => void;\n onRejectConfirm: (id: number) => void;\n onAlwaysAllowConfirm: (id: number, prefix: string) => void;\n pendingConfirms: PendingConfirm[];\n}) {\n const [copied, setCopied] = useState(false);\n const content = segments\n .filter((s): s is AssistantSegment & { kind: \"text\" } => s.kind === \"text\")\n .map((s) => s.text)\n .join(\"\\n\\n\");\n const onCopy = async () => {\n try {\n await navigator.clipboard.writeText(content);\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n } catch {\n /* ignore */\n }\n };\n return (\n <div className=\"msg assistant\">\n <div className=\"avatar\">DS</div>\n <div className=\"body\">\n <div className=\"who\">\n <span className=\"name\">Reasonix</span>\n {model ? <span className=\"model\">{model}</span> : null}\n {time ? <span className=\"time\">{time}</span> : null}\n </div>\n {segments.map((s, i) => {\n if (s.kind === \"text\") {\n if (!s.text.trim()) return null;\n if (isCompactionSummary(s.text)) {\n return <CompactionCard key={i} summary={stripCompactionMarker(s.text)} />;\n }\n return <AssistantText key={i} text={s.text} />;\n }\n if (s.kind === \"reasoning\") {\n return (\n <ReasoningCard\n key={i}\n text={s.text}\n streaming={pending && i === segments.length - 1}\n />\n );\n }\n // tool segment\n const pendingConfirm =\n (s.name === \"run_command\" || s.name === \"run_background\") && s.result === undefined\n ? pendingConfirms.find((c) => c.command === extractCommand(s.args))\n : undefined;\n if (s.name === \"run_command\" || s.name === \"run_background\") {\n const cmd = extractCommand(s.args) ?? s.args;\n const state: \"await\" | \"running\" | \"done\" | \"failed\" =\n s.result === undefined\n ? pendingConfirm\n ? \"await\"\n : \"running\"\n : s.ok === false\n ? \"failed\"\n : \"done\";\n return (\n <ShellCard\n key={i}\n command={cmd}\n output={s.result}\n state={state}\n durationMs={s.durationMs}\n onApprove={pendingConfirm ? () => onApproveConfirm(pendingConfirm.id) : undefined}\n onReject={pendingConfirm ? () => onRejectConfirm(pendingConfirm.id) : undefined}\n onAlwaysAllow={\n pendingConfirm\n ? () => {\n onAlwaysAllowConfirm(pendingConfirm.id, derivePrefix(cmd));\n }\n : undefined\n }\n />\n );\n }\n return (\n <ToolCard\n key={i}\n name={s.name}\n args={s.args}\n result={s.result}\n ok={s.ok}\n durationMs={s.durationMs}\n />\n );\n })}\n {content ? (\n <div className=\"msg-actions\">\n <button\n type=\"button\"\n className={`copy-btn ${copied ? \"done\" : \"\"}`}\n onClick={onCopy}\n title={t(\"thread.copyResponse\")}\n >\n <Copy size={11} />\n {copied ? t(\"markdown.copied\") : null}\n </button>\n </div>\n ) : null}\n </div>\n </div>\n );\n});\n\nfunction extractCommand(args: string): string | undefined {\n if (!args) return undefined;\n try {\n const v = JSON.parse(args);\n if (v && typeof v === \"object\" && typeof v.command === \"string\") return v.command;\n } catch {\n // ignore\n }\n return undefined;\n}\n\nexport function PlanBanner({\n plan,\n onDismiss,\n}: {\n plan: ActivePlan;\n onDismiss?: () => void;\n}) {\n useLang();\n const total = plan.steps.length || 1;\n const done = plan.completedStepIds.length;\n const pct = (done / total) * 100;\n const current = plan.steps.find((s) => !plan.completedStepIds.includes(s.id));\n return (\n <div className=\"plan-banner\">\n <span className=\"ico\">\n <I.list size={14} />\n </span>\n <div className=\"body\">\n <div className=\"t\">\n {t(\"thread.planRunning\", { step: Math.min(done + 1, total), total })}\n {current ? ` — ${current.title}` : \"\"}\n </div>\n <div className=\"s\">{plan.plan}</div>\n </div>\n <div className=\"prog\">\n <div className=\"meter-mini\">\n <span style={{ width: `${pct}%` }} />\n </div>\n {onDismiss ? (\n <button type=\"button\" onClick={onDismiss}>\n {t(\"thread.collapse\")}\n </button>\n ) : null}\n </div>\n </div>\n );\n}\n\nexport function ActivePlanCard({ plan }: { plan: ActivePlan }) {\n useLang();\n const done = new Set(plan.completedStepIds);\n const items: PlanItem[] = plan.steps.map((s) => {\n let status: PlanItem[\"status\"];\n if (done.has(s.id)) status = \"done\";\n else if (s === plan.steps.find((x) => !done.has(x.id))) status = \"active\";\n else status = \"todo\";\n return {\n id: s.id,\n status,\n text: s.title,\n tool: s.action,\n note: s.risk ? `${t(\"thread.risk\")}: ${s.risk}` : undefined,\n };\n });\n return <PlanCardView items={items} title={t(\"thread.activePlan\")} />;\n}\n\n// ---- Approval bindings ----\n\nexport function PlanApprovalCard({\n p,\n onApprove,\n onRefine,\n onCancel,\n}: {\n p: PendingPlan;\n onApprove: () => void;\n onRefine: () => void;\n onCancel: () => void;\n}) {\n useLang();\n const stepCount = p.steps?.length ?? 0;\n const sub = stepCount > 0 ? t(\"thread.planStepCount\", { count: stepCount }) : undefined;\n return (\n <ApprovalCard\n kind={t(\"thread.planConfirmationKind\")}\n tone=\"info\"\n title={t(\"thread.startPlan\")}\n sub={sub}\n body={\n <>\n {p.summary ? <div style={{ marginBottom: 6 }}>{p.summary}</div> : null}\n <div style={{ whiteSpace: \"pre-wrap\" }}>{p.plan}</div>\n </>\n }\n meta={`plan/#${p.id}`}\n primaryLabel={t(\"thread.approve\")}\n secondaryLabel={t(\"thread.cancel\")}\n tertiaryLabel={t(\"thread.refine\")}\n onPrimary={onApprove}\n onSecondary={onCancel}\n onTertiary={onRefine}\n />\n );\n}\n\nexport function CheckpointApprovalCard({\n c,\n onContinue,\n onRevise,\n onStop,\n}: {\n c: PendingCheckpoint;\n onContinue: () => void;\n onRevise: () => void;\n onStop: () => void;\n}) {\n useLang();\n return (\n <ApprovalCard\n kind={t(\"thread.checkpointKind\")}\n tone=\"brand\"\n title={c.title ?? t(\"thread.checkpointTitle\", { completed: c.completed, total: c.total })}\n sub={t(\"thread.checkpointSub\", { completed: c.completed, total: c.total })}\n body={\n <>\n <div style={{ whiteSpace: \"pre-wrap\" }}>{c.result}</div>\n {c.notes ? (\n <div style={{ marginTop: 8, fontSize: 11.5, color: \"var(--muted)\" }}>{c.notes}</div>\n ) : null}\n </>\n }\n meta={`checkpoint · ${c.stepId}`}\n primaryLabel={t(\"thread.continue\")}\n secondaryLabel={t(\"thread.stop\")}\n tertiaryLabel={t(\"thread.revise\")}\n onPrimary={onContinue}\n onSecondary={onStop}\n onTertiary={onRevise}\n />\n );\n}\n\nexport function RevisionApprovalCard({\n r,\n onAccept,\n onReject,\n}: {\n r: PendingRevision;\n onAccept: () => void;\n onReject: () => void;\n}) {\n useLang();\n return (\n <ApprovalCard\n kind={t(\"thread.planRevisionKind\")}\n tone=\"warn\"\n title={t(\"thread.rewritePlan\")}\n sub={t(\"thread.keepSteps\", { n: r.remainingSteps.length })}\n body={\n <>\n <div style={{ marginBottom: 8 }}>{r.reason}</div>\n {r.summary ? (\n <div style={{ fontSize: 11.5, color: \"var(--muted)\", marginBottom: 8 }}>{r.summary}</div>\n ) : null}\n <ul style={{ margin: 0, paddingLeft: 18 }}>\n {r.remainingSteps.map((s) => (\n <li key={s.id} style={{ fontSize: 12, marginBottom: 2 }}>\n {s.title}\n {s.risk ? (\n <span\n style={{\n marginLeft: 6,\n fontSize: 10,\n color:\n s.risk === \"high\"\n ? \"var(--tone-err)\"\n : s.risk === \"med\"\n ? \"var(--tone-warn)\"\n : \"var(--muted)\",\n }}\n >\n [{s.risk}]\n </span>\n ) : null}\n </li>\n ))}\n </ul>\n </>\n }\n meta={t(\"thread.revisionMeta\")}\n primaryLabel={t(\"thread.approveRewrite\")}\n secondaryLabel={t(\"thread.keepOriginal\")}\n onPrimary={onAccept}\n onSecondary={onReject}\n />\n );\n}\n\nexport function ConfirmApprovalCard({\n c,\n onAllow,\n onAlwaysAllow,\n onDeny,\n}: {\n c: PendingConfirm;\n onAllow: () => void;\n onAlwaysAllow: (prefix: string) => void;\n onDeny: () => void;\n}) {\n useLang();\n const isBackground = c.kind === \"run_background\";\n const prefix = derivePrefix(c.command);\n return (\n <ApprovalCard\n kind={t(\"thread.shellConfirmationKind\")}\n tone=\"warn\"\n title={isBackground ? t(\"thread.runBackgroundCommand\") : t(\"thread.runCommand\")}\n sub={c.command.length > 80 ? `${c.command.slice(0, 80)}…` : c.command}\n preview={\n <>\n <span style={{ color: \"var(--accent)\" }}>$</span> {c.command}\n </>\n }\n meta={t(\"thread.riskMedium\", { kind: c.kind })}\n primaryLabel={t(\"thread.execute\")}\n secondaryLabel={t(\"thread.reject\")}\n tertiaryLabel={t(\"thread.alwaysAllow\", { prefix })}\n onPrimary={onAllow}\n onSecondary={onDeny}\n onTertiary={() => onAlwaysAllow(prefix)}\n />\n );\n}\n\nexport function PathAccessApprovalCard({\n p,\n onAllow,\n onAlwaysAllow,\n onDeny,\n}: {\n p: {\n id: number;\n path: string;\n intent: \"read\" | \"write\";\n toolName: string;\n sandboxRoot: string;\n allowPrefix: string;\n };\n onAllow: () => void;\n onAlwaysAllow: (prefix: string) => void;\n onDeny: () => void;\n}) {\n useLang();\n const isWrite = p.intent === \"write\";\n return (\n <ApprovalCard\n kind={t(\"thread.pathAccessKind\")}\n tone=\"warn\"\n title={isWrite ? t(\"thread.writePathOutsideSandbox\") : t(\"thread.readPathOutsideSandbox\")}\n sub={p.path}\n preview={\n <>\n <div>{p.toolName} → {p.path}</div>\n <div style={{ color: \"var(--muted)\", marginTop: 4 }}>\n workspace: {p.sandboxRoot}\n </div>\n </>\n }\n meta={t(\"thread.riskMedium\", { kind: p.intent })}\n primaryLabel={isWrite ? t(\"thread.allowWrite\") : t(\"thread.allowRead\")}\n secondaryLabel={t(\"thread.reject\")}\n tertiaryLabel={t(\"thread.alwaysAllowPrefix\", { prefix: p.allowPrefix })}\n onPrimary={onAllow}\n onSecondary={onDeny}\n onTertiary={() => onAlwaysAllow(p.allowPrefix)}\n />\n );\n}\n\nexport function ChoiceApprovalCard({\n c,\n onPick,\n onCancel,\n}: {\n c: PendingChoice;\n onPick: (optionId: string) => void;\n onCancel: () => void;\n}) {\n useLang();\n return (\n <ApprovalCard\n kind={t(\"thread.userChoiceKind\")}\n tone=\"info\"\n title={c.question}\n sub={t(\"thread.optionCount\", { count: c.options.length })}\n body={\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n {c.options.map((o) => (\n <button\n key={o.id}\n type=\"button\"\n className=\"btn\"\n style={{ justifyContent: \"flex-start\", textAlign: \"left\" }}\n onClick={() => onPick(o.id)}\n >\n <div>\n <div style={{ fontWeight: 600 }}>{o.title}</div>\n {o.summary ? (\n <div style={{ fontSize: 11, color: \"var(--muted)\", marginTop: 2 }}>\n {o.summary}\n </div>\n ) : null}\n </div>\n </button>\n ))}\n </div>\n }\n primaryLabel={t(\"thread.cancel\")}\n onPrimary={onCancel}\n />\n );\n}\n\nexport function activePlanToTaskSteps(plan: ActivePlan): TaskStepView[] {\n const done = new Set(plan.completedStepIds);\n return plan.steps.map((s, i) => ({\n n: String(i + 1),\n state: done.has(s.id) ? \"done\" : i === plan.completedStepIds.length ? \"running\" : \"queued\",\n label: s.title,\n hint: s.action,\n durationLabel: undefined,\n }));\n}\n\nexport function ActivePlanTaskCard({ plan }: { plan: ActivePlan }) {\n useLang();\n return (\n <TaskCard\n title={t(\"thread.activePlan\")}\n subtitle={plan.summary}\n steps={activePlanToTaskSteps(plan)}\n />\n );\n}\n\nexport function HeaderHint({ children }: { children: ReactNode }) {\n return <div className=\"msg-text\">{children}</div>;\n}\n","import { useEffect, useMemo, useRef, useState } from \"react\";\nimport { I } from \"../icons\";\nimport { t, useLang } from \"../i18n\";\nimport { Shortcut } from \"./shortcut\";\n\ntype Anchor = { top?: number; bottom?: number; left: number };\n\nexport function WorkdirPop({\n open,\n onClose,\n recent,\n current,\n anchor,\n onPick,\n onBrowse,\n}: {\n open: boolean;\n onClose: () => void;\n recent: string[];\n current?: string;\n anchor?: Anchor;\n onPick: (path: string) => void;\n onBrowse: () => void;\n}) {\n useLang();\n const [query, setQuery] = useState(\"\");\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (!open) return;\n setQuery(\"\");\n const id = window.setTimeout(() => inputRef.current?.focus(), 40);\n return () => window.clearTimeout(id);\n }, [open]);\n\n const items = useMemo(() => {\n const list = recent.length > 0 ? recent : current ? [current] : [];\n const q = query.trim().toLowerCase();\n if (!q) return list;\n return list.filter((p) => p.toLowerCase().includes(q));\n }, [recent, current, query]);\n\n if (!open) return null;\n\n const left = anchor?.left ?? 240;\n const positionStyle =\n anchor?.bottom !== undefined\n ? { bottom: anchor.bottom, left }\n : { top: anchor?.top ?? 56, left };\n\n return (\n <div className=\"wd-mask\" onMouseDown={onClose}>\n <div className=\"wd-pop\" style={positionStyle} onMouseDown={(e) => e.stopPropagation()}>\n <div className=\"wd-head\">\n <I.folder size={12} />\n <span>{t(\"workdir.title\")}</span>\n <span\n style={{\n marginLeft: \"auto\",\n fontFamily: \"Geist Mono, monospace\",\n fontSize: 10,\n color: \"var(--muted)\",\n }}\n >\n <Shortcut keys={[\"mod\", \"O\"]} />\n </span>\n </div>\n <input\n ref={inputRef}\n className=\"wd-search\"\n placeholder={t(\"workdir.searchPlaceholder\")}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onClose();\n } else if (e.key === \"Enter\" && items[0]) {\n e.preventDefault();\n onPick(items[0]);\n onClose();\n }\n }}\n />\n <div className=\"wd-list\">\n {items.length === 0 ? (\n <div\n style={{\n padding: \"16px 12px\",\n fontSize: 11.5,\n color: \"var(--muted)\",\n fontFamily: \"Geist Mono, monospace\",\n }}\n >\n {t(\"workdir.empty\")}\n </div>\n ) : null}\n {items.map((p) => {\n const isCurrent = p === current;\n const name = p.split(/[\\\\/]/).filter(Boolean).pop() ?? p;\n return (\n <div\n key={p}\n className=\"wd-row\"\n onClick={() => {\n if (!isCurrent) onPick(p);\n onClose();\n }}\n title={p}\n >\n <span className=\"ic\">\n <I.folder size={12} />\n </span>\n <div className=\"b\">\n <div className=\"p\">{name}</div>\n <div className=\"br\">{p}</div>\n </div>\n {isCurrent ? (\n <span className=\"pin\">\n <I.check size={11} />\n </span>\n ) : null}\n </div>\n );\n })}\n </div>\n <div className=\"wd-foot\">\n <button\n type=\"button\"\n className=\"btn ghost\"\n onClick={() => {\n onBrowse();\n onClose();\n }}\n >\n <I.plus size={11} /> {t(\"workdir.browse\")}\n </button>\n </div>\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { I } from \"../icons\";\nimport { t, useLang } from \"../i18n\";\n\ninterface BrowseEntry {\n name: string;\n full: string;\n}\n\ninterface BrowseResult {\n path: string;\n parent: string | null;\n entries: BrowseEntry[];\n}\n\nasync function fetchBrowse(path: string): Promise<BrowseResult> {\n const token = document\n .querySelector('meta[name=\"reasonix-token\"]')\n ?.getAttribute(\"content\") ?? \"\";\n const params = new URLSearchParams();\n if (path) params.set(\"path\", path);\n if (token && token !== \"__REASONIX_TOKEN__\") params.set(\"token\", token);\n const res = await fetch(`/api/browse?${params.toString()}`);\n if (!res.ok) {\n const text = await res.text();\n throw new Error(text || `browse failed (${res.status})`);\n }\n return (await res.json()) as BrowseResult;\n}\n\nexport function WorkdirInputModal({\n open,\n initialPath,\n onCancel,\n onConfirm,\n}: {\n open: boolean;\n initialPath?: string;\n onCancel: () => void;\n onConfirm: (path: string) => void;\n}) {\n useLang();\n const [typed, setTyped] = useState<string>(initialPath ?? \"\");\n const [browse, setBrowse] = useState<BrowseResult | null>(null);\n const [error, setError] = useState<string>(\"\");\n const [loading, setLoading] = useState(false);\n const seededRef = useRef(false);\n\n const navigate = useCallback(async (path: string) => {\n setLoading(true);\n setError(\"\");\n try {\n const result = await fetchBrowse(path);\n setBrowse(result);\n setTyped(result.path);\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n if (!open) {\n seededRef.current = false;\n return;\n }\n if (seededRef.current) return;\n seededRef.current = true;\n void navigate(initialPath ?? \"\");\n }, [open, initialPath, navigate]);\n\n if (!open) return null;\n\n const trimmedTyped = typed.trim();\n const canConfirm = trimmedTyped.length > 0 && !loading;\n const sameAsCurrent = browse !== null && trimmedTyped === browse.path;\n\n const handleConfirm = () => {\n if (!canConfirm) return;\n onConfirm(trimmedTyped);\n };\n\n const handleTypedKey = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onCancel();\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n if (sameAsCurrent) {\n handleConfirm();\n } else {\n void navigate(trimmedTyped);\n }\n }\n };\n\n return (\n <div className=\"settings-mask\" onMouseDown={onCancel}>\n <div\n className=\"workdir-input\"\n onMouseDown={(e) => e.stopPropagation()}\n >\n <div className=\"workdir-input-head\">\n <I.folder size={14} />\n <span>{t(\"workdir.title\")}</span>\n <button\n type=\"button\"\n className=\"close-btn\"\n onClick={onCancel}\n title={t(\"workdir.cancel\")}\n >\n <I.x size={13} />\n </button>\n </div>\n <div className=\"workdir-input-pathrow\">\n <input\n autoFocus\n className=\"workdir-input-path\"\n value={typed}\n placeholder={t(\"workdir.pathPlaceholder\")}\n onChange={(e) => setTyped(e.target.value)}\n onKeyDown={handleTypedKey}\n spellCheck={false}\n />\n <button\n type=\"button\"\n className=\"btn ghost\"\n onClick={() => void navigate(trimmedTyped)}\n disabled={loading || trimmedTyped.length === 0}\n title={t(\"workdir.goTip\")}\n >\n {t(\"workdir.go\")}\n </button>\n </div>\n {error ? <div className=\"workdir-input-error\">{error}</div> : null}\n <div className=\"workdir-input-list\">\n {browse?.parent ? (\n <div\n className=\"workdir-input-row up\"\n onClick={() => void navigate(browse.parent!)}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") void navigate(browse.parent!);\n }}\n >\n <span className=\"ic\">↑</span>\n <span>..</span>\n </div>\n ) : null}\n {browse?.entries.length === 0 && !loading ? (\n <div className=\"workdir-input-empty\">{t(\"workdir.emptyDir\")}</div>\n ) : null}\n {browse?.entries.map((e) => (\n <div\n key={e.full}\n className=\"workdir-input-row\"\n onClick={() => void navigate(e.full)}\n onDoubleClick={() => onConfirm(e.full)}\n role=\"button\"\n tabIndex={0}\n title={e.full}\n onKeyDown={(ev) => {\n if (ev.key === \"Enter\") void navigate(e.full);\n }}\n >\n <span className=\"ic\"><I.folder size={12} /></span>\n <span className=\"n\">{e.name}</span>\n </div>\n ))}\n {loading ? <div className=\"workdir-input-empty\">{t(\"workdir.loading\")}</div> : null}\n </div>\n <div className=\"workdir-input-foot\">\n <button type=\"button\" className=\"btn ghost\" onClick={onCancel}>\n {t(\"workdir.cancel\")}\n </button>\n <button\n type=\"button\"\n className=\"btn primary\"\n onClick={handleConfirm}\n disabled={!canConfirm}\n >\n {t(\"workdir.openHere\")}\n </button>\n </div>\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\n\nconst PIN_THRESHOLD = 80; // px from bottom to consider \"pinned\"\n\n// Auto-scrolls while content grows; un-pins only on real user gestures.\n// Scroll events are avoided because smooth scrollTo can fire them mid-flight.\nexport function useAutoScroll(\n containerRef: React.RefObject<HTMLDivElement | null>,\n contentRef: React.RefObject<HTMLDivElement | null>,\n busy: boolean,\n /** Optional boot-time restore: the offset the transcript should open at. */\n getRestoreScrollTop?: () => number | null,\n) {\n const [showJumpButton, setShowJumpButton] = useState(false);\n const isPinnedRef = useRef(true);\n const wasBusyRef = useRef(busy);\n const rafIdRef = useRef<number>(0);\n\n const isAtBottom = useCallback(() => {\n const el = containerRef.current;\n if (!el) return true;\n return el.scrollTop + el.clientHeight >= el.scrollHeight - PIN_THRESHOLD;\n }, [containerRef]);\n\n const refreshJumpButton = useCallback(() => {\n const el = containerRef.current;\n if (!el) return;\n setShowJumpButton(\n !isPinnedRef.current && el.scrollHeight > el.clientHeight + PIN_THRESHOLD,\n );\n }, [containerRef]);\n\n const scrollToBottom = useCallback(\n (smooth = true) => {\n const el = containerRef.current;\n if (!el) return;\n isPinnedRef.current = true;\n setShowJumpButton(false);\n el.scrollTo({\n top: el.scrollHeight,\n behavior: smooth ? \"smooth\" : \"instant\",\n });\n },\n [containerRef],\n );\n\n // User-intent detection: only these gestures un-pin. Scroll events are\n // intentionally NOT listened to — they can't tell user gestures from our\n // own scrollTo.\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n\n // rAF lets the gesture's scroll delta land before we measure.\n let pendingFrame = 0;\n const onUserGesture = () => {\n if (pendingFrame) cancelAnimationFrame(pendingFrame);\n pendingFrame = requestAnimationFrame(() => {\n pendingFrame = 0;\n isPinnedRef.current = isAtBottom();\n refreshJumpButton();\n });\n };\n\n el.addEventListener(\"wheel\", onUserGesture, { passive: true });\n el.addEventListener(\"touchmove\", onUserGesture, { passive: true });\n el.addEventListener(\"keydown\", onUserGesture);\n // pointerdown on the scrollbar gutter starts a drag-scroll. The\n // drag itself fires no wheel/touch, but pointerdown's followup\n // scroll arrives within a frame; one rAF measure catches it.\n el.addEventListener(\"pointerdown\", onUserGesture);\n\n return () => {\n if (pendingFrame) cancelAnimationFrame(pendingFrame);\n el.removeEventListener(\"wheel\", onUserGesture);\n el.removeEventListener(\"touchmove\", onUserGesture);\n el.removeEventListener(\"keydown\", onUserGesture);\n el.removeEventListener(\"pointerdown\", onUserGesture);\n };\n }, [containerRef, isAtBottom, refreshJumpButton]);\n\n // Both busy edges re-pin: turn start = user just sent and expects to\n // see the reply; turn end = settle on the final answer (issue #1182).\n useEffect(() => {\n if (wasBusyRef.current !== busy) {\n scrollToBottom(true);\n }\n wasBusyRef.current = busy;\n }, [busy, scrollToBottom]);\n\n // Watch content size changes (streaming text, tool results, new\n // messages) and follow the bottom while pinned.\n useEffect(() => {\n const content = contentRef.current;\n if (!content) return;\n\n const ro = new ResizeObserver(() => {\n if (rafIdRef.current) cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = requestAnimationFrame(() => {\n rafIdRef.current = 0;\n const el = containerRef.current;\n if (!el) return;\n if (isPinnedRef.current) {\n el.scrollTo({ top: el.scrollHeight, behavior: \"instant\" });\n } else {\n refreshJumpButton();\n }\n });\n });\n\n ro.observe(content);\n return () => {\n ro.disconnect();\n if (rafIdRef.current) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = 0;\n }\n };\n }, [containerRef, contentRef, refreshJumpButton]);\n\n // Initial scroll when the hook mounts (e.g. session loaded). Restores the\n // saved offset if there is one (#1244), otherwise pins to the bottom.\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n const id = setTimeout(() => {\n const restore = getRestoreScrollTop?.() ?? null;\n if (restore != null && restore > PIN_THRESHOLD) {\n // Mid-transcript restore: stay un-pinned so content growth and the\n // ResizeObserver don't yank the view back to the bottom.\n isPinnedRef.current = false;\n el.scrollTop = restore;\n refreshJumpButton();\n } else {\n isPinnedRef.current = true;\n setShowJumpButton(false);\n el.scrollTo({ top: el.scrollHeight, behavior: \"instant\" });\n }\n }, 60);\n return () => clearTimeout(id);\n }, [containerRef, getRestoreScrollTop, refreshJumpButton]);\n\n return { showJumpButton, scrollToBottom };\n}\n","import { useEffect } from \"react\";\n\nconst TEXT_INPUT_SELECTOR =\n 'input, textarea, [contenteditable=\"\"], [contenteditable=\"true\"], [contenteditable=\"plaintext-only\"]';\n\nfunction getTextAssistAttrs() {\n return {\n autoCorrect: \"off\" as const,\n autoCapitalize: \"off\" as const,\n spellCheck: false as const,\n };\n}\n\nfunction isMacPlatform() {\n if (typeof document === \"undefined\") return false;\n return document.documentElement.dataset.platform === \"macos\";\n}\n\nfunction applyTextAssistAttrs(element: Element) {\n if (!(element instanceof HTMLElement)) return;\n if (\n !(element instanceof HTMLInputElement) &&\n !(element instanceof HTMLTextAreaElement) &&\n !element.isContentEditable\n ) {\n return;\n }\n\n const attrs = getTextAssistAttrs();\n element.setAttribute(\"autocorrect\", attrs.autoCorrect);\n element.setAttribute(\"autocapitalize\", attrs.autoCapitalize);\n element.setAttribute(\"spellcheck\", String(attrs.spellCheck));\n element.spellcheck = attrs.spellCheck;\n}\n\nfunction applyWithin(root: ParentNode) {\n if (root instanceof Element) {\n applyTextAssistAttrs(root);\n }\n root.querySelectorAll(TEXT_INPUT_SELECTOR).forEach(applyTextAssistAttrs);\n}\n\nexport function useDisableTextAssist() {\n useEffect(() => {\n if (typeof document === \"undefined\" || !isMacPlatform()) return;\n\n const root = document.body;\n if (!root) return;\n\n applyWithin(root);\n\n const handleFocusIn = (event: FocusEvent) => {\n if (event.target instanceof Element) {\n applyTextAssistAttrs(event.target);\n }\n };\n\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n mutation.addedNodes.forEach((node) => {\n if (node instanceof Element) {\n applyWithin(node);\n }\n });\n }\n });\n\n document.addEventListener(\"focusin\", handleFocusIn, true);\n observer.observe(root, { childList: true, subtree: true });\n\n return () => {\n document.removeEventListener(\"focusin\", handleFocusIn, true);\n observer.disconnect();\n };\n }, []);\n}\n","import { invoke } from \"@tauri-apps/api/core\";\nimport { listen } from \"@tauri-apps/api/event\";\nimport { getCurrentWindow } from \"@tauri-apps/api/window\";\nimport { open as openDialog, save as saveDialog } from \"@tauri-apps/plugin-dialog\";\nimport { isWebRuntime } from \"./lib/tauri-bridge\";\nimport { useCallback, useEffect, useReducer, useRef, useState } from \"react\";\nimport { CommandPalette, Toast, buildCommands, useCommandPalette } from \"./CommandPalette\";\nimport { WorkspaceProvider } from \"./Markdown\";\nimport { getLang, getLangLabel, getSupportedLangs, setLang, t, useLang } from \"./i18n\";\nimport { I } from \"./icons\";\nimport {\n FONT_FAMILY,\n FONT_FAMILY_STACK,\n FONT_SCALE,\n FONT_SCALE_ZOOM,\n type FontFamily,\n type FontScale,\n THEME,\n type Theme,\n type ThemeStyle,\n defaultStyleForTheme,\n isFontFamily,\n isFontScale,\n isTheme,\n isThemeStyle,\n themeForStyle,\n} from \"./theme\";\nimport type {\n CheckpointVerdict,\n ChoiceVerdict,\n ConfirmationChoice,\n IncomingEvent,\n JobInfo,\n McpSpecInfo,\n MemoryDetail,\n MemoryEntryInfo,\n OutgoingCommand,\n PlanVerdict,\n RevisionVerdict,\n SettingsPatch,\n SkillInfo,\n} from \"./protocol\";\nimport { readSessionFromUrl, writeSessionToUrl } from \"./lib/session-url\";\nimport { type QQDesktopSettingsState } from \"./qq-settings\";\nimport { Composer, type SlashCmd } from \"./ui/composer\";\nimport { ContextPanel } from \"./ui/context-panel\";\nimport { JobsPop } from \"./ui/jobs-pop\";\nimport { useElapsed } from \"./ui/live\";\nimport { AboutModal } from \"./ui/about\";\nimport { SettingsModal, type PageId as SettingsPageId } from \"./ui/settings\";\nimport { Sidebar } from \"./ui/sidebar\";\nimport { Shortcut, localizeShortcutText, shortcutText } from \"./ui/shortcut\";\nimport { Splash, shouldShowSplash } from \"./ui/splash\";\nimport { StatusBar } from \"./ui/statusbar\";\nimport {\n ActivePlanTaskCard,\n AssistantMsg,\n CheckpointApprovalCard,\n ChoiceApprovalCard,\n ConfirmApprovalCard,\n PathAccessApprovalCard,\n PlanApprovalCard,\n PlanBanner,\n RevisionApprovalCard,\n TurnDivider,\n UserMsg,\n} from \"./ui/thread\";\nimport { WorkdirPop } from \"./ui/workdir-pop\";\nimport { WorkdirInputModal } from \"./ui/workdir-input-modal\";\nimport { useAutoScroll } from \"./ui/useAutoScroll\";\nimport { useDisableTextAssist } from \"./ui/useDisableTextAssist\";\nimport { openUrl } from \"@tauri-apps/plugin-opener\";\n\nexport type AssistantSegment =\n | { kind: \"text\"; text: string }\n | { kind: \"reasoning\"; text: string }\n | {\n kind: \"tool\";\n callId: string;\n name: string;\n args: string;\n startedAt: number;\n result?: string;\n ok?: boolean;\n durationMs?: number;\n };\n\nexport type SkillOrigin = {\n name: string;\n runAs: \"inline\" | \"subagent\";\n};\n\nexport type ChatMessage =\n | { kind: \"user\"; text: string; clientId: string; turn: number; skill?: SkillOrigin }\n | {\n kind: \"assistant\";\n turn: number;\n segments: AssistantSegment[];\n pending: boolean;\n }\n | { kind: \"status\"; text: string }\n | { kind: \"warning\"; id: string; text: string; severity: \"low\" | \"high\" }\n | { kind: \"error\"; message: string };\n\nexport type PendingConfirm = {\n id: number;\n kind: \"run_command\" | \"run_background\";\n command: string;\n};\n\nexport type PendingPathAccess = {\n id: number;\n path: string;\n intent: \"read\" | \"write\";\n toolName: string;\n sandboxRoot: string;\n allowPrefix: string;\n};\n\nexport type PendingChoice = {\n id: number;\n question: string;\n options: { id: string; title: string; summary?: string }[];\n allowCustom: boolean;\n};\n\nexport type PendingPlan = {\n id: number;\n plan: string;\n summary?: string;\n steps?: PlanStep[];\n};\n\nexport type PlanStep = {\n id: string;\n title: string;\n action: string;\n risk?: \"low\" | \"med\" | \"high\";\n};\n\nexport type ActivePlan = {\n plan: string;\n summary?: string;\n steps: PlanStep[];\n completedStepIds: string[];\n stepResults: Record<string, string>;\n};\n\nexport type PendingCheckpoint = {\n id: number;\n stepId: string;\n title?: string;\n result: string;\n notes?: string;\n completed: number;\n total: number;\n};\n\nexport type PendingRevision = {\n id: number;\n reason: string;\n remainingSteps: PlanStep[];\n summary?: string;\n};\n\nexport type UsageStats = {\n totalCostUsd: number;\n totalPromptTokens: number;\n totalCompletionTokens: number;\n cacheHitTokens: number;\n cacheMissTokens: number;\n lastCallCacheHit: number | null;\n lastCallCacheMiss: number | null;\n /** System prompt + tool specs — constant for the session, sent on tab open. */\n reservedTokens: number;\n};\n\nexport type SessionInfo = {\n name: string;\n messageCount: number;\n mtime: string;\n summary?: string;\n workspaceStatus?: \"matched\" | \"legacy_missing_meta\";\n};\n\nexport type Settings = {\n reasoningEffort: \"low\" | \"medium\" | \"high\" | \"max\";\n editMode: \"review\" | \"auto\" | \"yolo\" | \"plan\";\n budgetUsd: number | null;\n baseUrl?: string;\n apiKeyPrefix?: string;\n workspaceDir: string;\n recentWorkspaces: string[];\n model: string;\n editor?: string;\n webSearchEngine?: \"bing\" | \"searxng\" | \"metaso\" | \"tavily\" | \"perplexity\" | \"exa\";\n subagentModels?: Record<string, \"flash\" | \"pro\">;\n showSystemEvents?: boolean;\n version: string;\n};\n\nexport type Balance = {\n currency: string;\n total: number;\n isAvailable: boolean;\n};\n\ntype MentionResults = { nonce: number; query: string; results: string[] };\ntype MentionPreviewState = {\n nonce: number;\n path: string;\n head: string;\n totalLines: number;\n};\n\ntype State = {\n ready: boolean;\n needsSetup: boolean;\n busy: boolean;\n model?: string;\n currentSession?: string;\n messages: ChatMessage[];\n pendingConfirms: PendingConfirm[];\n pendingPathAccess: PendingPathAccess[];\n pendingChoices: PendingChoice[];\n pendingPlans: PendingPlan[];\n pendingCheckpoints: PendingCheckpoint[];\n pendingRevisions: PendingRevision[];\n activePlan: ActivePlan | null;\n usage: UsageStats;\n sessions: SessionInfo[];\n settings: Settings | null;\n qq: QQDesktopSettingsState | null;\n balance: Balance | null;\n mentionResults: MentionResults | null;\n mentionPreview: MentionPreviewState | null;\n mcpSpecs: McpSpecInfo[];\n mcpBridged: boolean;\n skills: SkillInfo[];\n /** Files the agent has read or modified this session — paths as the tool args provided them. */\n sessionFiles: SessionFile[];\n memory: MemoryEntryInfo[];\n memoryDetail: MemoryDetail | null;\n jobs: JobInfo[];\n /** Live \"skill running\" indicator — set when a `skill_run` RPC dispatches, cleared on `$turn_complete`. */\n activeSkill: SkillOrigin | null;\n /** Messages typed while busy=true — auto-sent FIFO once the current turn completes. Cleared on `clear`, `rpc_exit`, `session_loaded`. */\n queuedSends: string[];\n /** Populated by $retry_result — component useEffect reads and sets composer draft. */\n retryText?: string;\n retryNonce: number;\n};\n\nexport type SessionFile = {\n path: string;\n /** \"c\": pulled into context (read_file). \"m\": modified by the agent (edit_file / write_file / multi_edit). */\n status: \"c\" | \"m\";\n};\n\ntype DeltaBatchItem = {\n turn: number;\n channel: \"content\" | \"reasoning\";\n text: string;\n};\n\ntype Action =\n | { t: \"send_user\"; text: string; clientId: string }\n | { t: \"start_skill\"; skill: SkillOrigin; args?: string; clientId: string }\n | { t: \"incoming\"; event: IncomingEvent }\n | { t: \"batch_delta\"; items: DeltaBatchItem[] }\n | { t: \"rpc_exit\"; code: number | null }\n | { t: \"clear\" }\n | { t: \"resolve_confirm\"; id: number }\n | { t: \"resolve_path_access\"; id: number }\n | { t: \"resolve_choice\"; id: number }\n | { t: \"resolve_plan\"; id: number; verdict: PlanVerdict }\n | { t: \"resolve_checkpoint\"; id: number; verdict: CheckpointVerdict }\n | { t: \"resolve_revision\"; id: number; verdict: RevisionVerdict }\n | { t: \"dismiss_plan\" }\n | { t: \"mention_results\"; results: MentionResults }\n | { t: \"mention_preview\"; preview: MentionPreviewState }\n | { t: \"enqueue_send\"; text: string }\n | { t: \"dequeue_send\"; index: number }\n | { t: \"shift_queued_send\" };\n\nfunction fallbackSkillDesc(skill: SkillInfo): string {\n const scope =\n skill.scope === \"builtin\"\n ? t(\"app.skill.scope.builtin\")\n : skill.scope === \"global\"\n ? t(\"app.skill.scope.global\")\n : t(\"app.skill.scope.project\");\n const runAs =\n skill.runAs === \"subagent\"\n ? t(\"app.skill.runAs.subagent\")\n : t(\"app.skill.runAs.inline\");\n return t(\"app.skill.generic\", { scope, runAs });\n}\n\nfunction nextMessageTurn(messages: ChatMessage[]): number {\n const lastTurn = messages.reduce((max, m) => {\n if (m.kind === \"user\" || m.kind === \"assistant\") return Math.max(max, m.turn);\n return max;\n }, 0);\n return lastTurn + 1;\n}\n\nfunction reduce(state: State, action: Action): State {\n switch (action.t) {\n case \"send_user\": {\n return {\n ...state,\n busy: true,\n messages: [\n ...state.messages,\n { kind: \"user\", text: action.text, clientId: action.clientId, turn: nextMessageTurn(state.messages) },\n ],\n };\n }\n case \"start_skill\": {\n const argsLine = action.args ? ` ${action.args}` : \"\";\n return {\n ...state,\n busy: true,\n activeSkill: action.skill,\n messages: [\n ...state.messages,\n {\n kind: \"user\",\n text: `/${action.skill.name}${argsLine}`,\n clientId: action.clientId,\n turn: nextMessageTurn(state.messages),\n skill: action.skill,\n },\n ],\n };\n }\n case \"rpc_exit\":\n return {\n ...state,\n ready: false,\n busy: false,\n activeSkill: null,\n queuedSends: [],\n messages: [\n ...state.messages,\n { kind: \"error\", message: `reasonix exited (code ${action.code ?? \"?\"})` },\n ],\n };\n case \"incoming\":\n return applyIncoming(state, action.event);\n case \"batch_delta\": {\n const collapsed: DeltaBatchItem[] = [];\n for (const item of action.items) {\n const last = collapsed[collapsed.length - 1];\n if (last && last.turn === item.turn && last.channel === item.channel) {\n last.text += item.text;\n } else {\n collapsed.push({ ...item });\n }\n }\n return {\n ...state,\n messages: state.messages.map((m) => {\n if (m.kind !== \"assistant\") return m;\n const relevant = collapsed.filter((it) => it.turn === m.turn);\n if (relevant.length === 0) return m;\n let segments = m.segments;\n for (const it of relevant) {\n segments = appendTextSegment(\n segments,\n it.channel === \"content\" ? \"text\" : \"reasoning\",\n it.text,\n );\n }\n return { ...m, segments };\n }),\n };\n }\n case \"clear\":\n return {\n ...state,\n busy: false,\n currentSession: undefined,\n messages: [],\n pendingConfirms: [],\n pendingPathAccess: [],\n pendingChoices: [],\n pendingPlans: [],\n pendingCheckpoints: [],\n pendingRevisions: [],\n activePlan: null,\n usage: zeroUsage(),\n sessionFiles: [],\n activeSkill: null,\n queuedSends: [],\n retryNonce: 0,\n };\n case \"resolve_confirm\":\n return {\n ...state,\n pendingConfirms: state.pendingConfirms.filter((c) => c.id !== action.id),\n };\n case \"resolve_path_access\":\n return {\n ...state,\n pendingPathAccess: state.pendingPathAccess.filter((p) => p.id !== action.id),\n };\n case \"resolve_choice\":\n return {\n ...state,\n pendingChoices: state.pendingChoices.filter((c) => c.id !== action.id),\n };\n case \"resolve_plan\": {\n const removed = state.pendingPlans.find((p) => p.id === action.id);\n let activePlan = state.activePlan;\n if (removed && action.verdict.type === \"approve\") {\n const pendingSteps = (removed as PendingPlan & { steps?: PlanStep[] }).steps;\n activePlan = {\n plan: removed.plan,\n summary: removed.summary,\n steps: pendingSteps ?? [],\n completedStepIds: [],\n stepResults: {},\n };\n }\n return {\n ...state,\n pendingPlans: state.pendingPlans.filter((p) => p.id !== action.id),\n activePlan,\n };\n }\n case \"resolve_checkpoint\":\n return {\n ...state,\n pendingCheckpoints: state.pendingCheckpoints.filter((c) => c.id !== action.id),\n };\n case \"resolve_revision\": {\n const removed = state.pendingRevisions.find((r) => r.id === action.id);\n let activePlan = state.activePlan;\n if (removed && action.verdict.type === \"accepted\" && activePlan) {\n const doneIds = new Set(activePlan.completedStepIds);\n const keptDone = activePlan.steps.filter((s) => doneIds.has(s.id));\n activePlan = {\n ...activePlan,\n steps: [...keptDone, ...removed.remainingSteps],\n };\n }\n return {\n ...state,\n pendingRevisions: state.pendingRevisions.filter((r) => r.id !== action.id),\n activePlan,\n };\n }\n case \"dismiss_plan\":\n return { ...state, activePlan: null };\n case \"mention_results\":\n return { ...state, mentionResults: action.results };\n case \"mention_preview\":\n return { ...state, mentionPreview: action.preview };\n case \"enqueue_send\":\n return { ...state, queuedSends: [...state.queuedSends, action.text] };\n case \"dequeue_send\":\n return {\n ...state,\n queuedSends: state.queuedSends.filter((_, i) => i !== action.index),\n };\n case \"shift_queued_send\":\n return { ...state, queuedSends: state.queuedSends.slice(1) };\n }\n}\n\nconst READING_TOOLS = new Set([\"read_file\"]);\nconst MODIFYING_TOOLS = new Set([\"edit_file\", \"write_file\"]);\n\nfunction extractToolFiles(name: string, args: string): SessionFile[] {\n try {\n const parsed = JSON.parse(args) as { path?: unknown; edits?: unknown };\n if (READING_TOOLS.has(name) && typeof parsed?.path === \"string\") {\n return [{ path: parsed.path, status: \"c\" }];\n }\n if (MODIFYING_TOOLS.has(name) && typeof parsed?.path === \"string\") {\n return [{ path: parsed.path, status: \"m\" }];\n }\n if (name === \"multi_edit\" && Array.isArray(parsed?.edits)) {\n const out: SessionFile[] = [];\n const seen = new Set<string>();\n for (const e of parsed.edits as Array<{ path?: unknown }>) {\n if (typeof e?.path === \"string\" && !seen.has(e.path)) {\n seen.add(e.path);\n out.push({ path: e.path, status: \"m\" });\n }\n }\n return out;\n }\n } catch {\n // malformed args — skip; tool will error on the real side anyway\n }\n return [];\n}\n\nfunction mergeSessionFiles(existing: SessionFile[], adds: SessionFile[]): SessionFile[] {\n if (adds.length === 0) return existing;\n const next = [...existing];\n const indexByPath = new Map<string, number>();\n next.forEach((f, i) => indexByPath.set(f.path, i));\n let changed = false;\n for (const add of adds) {\n const idx = indexByPath.get(add.path);\n if (idx === undefined) {\n indexByPath.set(add.path, next.length);\n next.push(add);\n changed = true;\n continue;\n }\n const prev = next[idx];\n if (!prev || prev.status === \"m\") continue; // never downgrade m → c\n if (prev.status === add.status) continue;\n next[idx] = add;\n changed = true;\n }\n return changed ? next : existing;\n}\n\nfunction zeroUsage(): UsageStats {\n return {\n totalCostUsd: 0,\n totalPromptTokens: 0,\n totalCompletionTokens: 0,\n cacheHitTokens: 0,\n cacheMissTokens: 0,\n lastCallCacheHit: null,\n lastCallCacheMiss: null,\n reservedTokens: 0,\n };\n}\n\nfunction appendTextSegment(\n segments: AssistantSegment[],\n kind: \"text\" | \"reasoning\",\n text: string,\n): AssistantSegment[] {\n const last = segments[segments.length - 1];\n if (last && last.kind === kind) {\n return [...segments.slice(0, -1), { ...last, text: last.text + text }];\n }\n return [...segments, { kind, text }];\n}\n\nexport function applyIncoming(state: State, ev: IncomingEvent): State {\n switch (ev.type) {\n case \"user.message\": {\n const last = state.messages[state.messages.length - 1];\n if (state.busy && last?.kind === \"user\" && last.text === ev.text) {\n return state;\n }\n return {\n ...state,\n busy: true,\n messages: [\n ...state.messages,\n {\n kind: \"user\",\n text: ev.text,\n clientId: `remote-${ev.id}`,\n turn: ev.turn > 0 ? ev.turn : nextMessageTurn(state.messages),\n },\n ],\n };\n }\n case \"$ready\":\n return { ...state, ready: true, needsSetup: false };\n case \"$needs_setup\":\n return { ...state, needsSetup: true, ready: false };\n case \"$turn_complete\":\n return { ...state, busy: false, activeSkill: null };\n case \"$confirm_required\":\n return {\n ...state,\n pendingConfirms: [\n ...state.pendingConfirms,\n { id: ev.id, kind: ev.kind, command: ev.command },\n ],\n };\n case \"$path_access_required\":\n return {\n ...state,\n pendingPathAccess: [\n ...state.pendingPathAccess,\n {\n id: ev.id,\n path: ev.path,\n intent: ev.intent,\n toolName: ev.toolName,\n sandboxRoot: ev.sandboxRoot,\n allowPrefix: ev.allowPrefix,\n },\n ],\n };\n case \"$choice_required\":\n return {\n ...state,\n pendingChoices: [\n ...state.pendingChoices,\n {\n id: ev.id,\n question: ev.question,\n options: ev.options,\n allowCustom: ev.allowCustom,\n },\n ],\n };\n case \"$plan_required\": {\n const steps = Array.isArray(ev.steps) ? (ev.steps as PlanStep[]) : undefined;\n return {\n ...state,\n pendingPlans: [\n ...state.pendingPlans,\n { id: ev.id, plan: ev.plan, summary: ev.summary, ...(steps ? { steps } : {}) },\n ],\n };\n }\n case \"$checkpoint_required\":\n return {\n ...state,\n pendingCheckpoints: [\n ...state.pendingCheckpoints,\n {\n id: ev.id,\n stepId: ev.stepId,\n title: ev.title,\n result: ev.result,\n notes: ev.notes,\n completed: ev.completed,\n total: ev.total,\n },\n ],\n };\n case \"$revision_required\":\n return {\n ...state,\n pendingRevisions: [\n ...state.pendingRevisions,\n {\n id: ev.id,\n reason: ev.reason,\n remainingSteps: ev.remainingSteps,\n summary: ev.summary,\n },\n ],\n };\n case \"$step_completed\": {\n if (!state.activePlan) return state;\n const stepIds = new Set(state.activePlan.completedStepIds);\n stepIds.add(ev.stepId);\n return {\n ...state,\n activePlan: {\n ...state.activePlan,\n completedStepIds: [...stepIds],\n stepResults: { ...state.activePlan.stepResults, [ev.stepId]: ev.result },\n },\n };\n }\n case \"$plan_cleared\":\n return {\n ...state,\n activePlan: null,\n pendingCheckpoints: [],\n pendingRevisions: [],\n };\n case \"$sessions\":\n return { ...state, sessions: ev.items };\n case \"$mcp_specs\":\n return {\n ...state,\n mcpSpecs: Array.isArray(ev.specs) ? ev.specs : [],\n mcpBridged: Boolean(ev.bridged),\n };\n case \"$skills\":\n return { ...state, skills: ev.items };\n case \"$ctx_breakdown\":\n return { ...state, usage: { ...state.usage, reservedTokens: ev.reservedTokens } };\n case \"$memory\":\n return {\n ...state,\n memory: ev.entries,\n memoryDetail:\n state.memoryDetail && ev.entries.some((entry) => entry.path === state.memoryDetail?.path)\n ? state.memoryDetail\n : null,\n };\n case \"$memory_detail\":\n return { ...state, memoryDetail: ev.detail };\n case \"$jobs\":\n return { ...state, jobs: ev.items };\n case \"$balance\":\n return {\n ...state,\n balance: {\n currency: ev.currency,\n total: ev.total,\n isAvailable: ev.isAvailable,\n },\n };\n case \"$qq_settings\":\n return {\n ...state,\n qq: {\n appId: ev.appId,\n appSecret: ev.appSecret,\n sandbox: ev.sandbox,\n enabled: ev.enabled,\n configured: ev.configured,\n runtimeState: ev.runtimeState,\n lastError: ev.lastError,\n appIdPreview: ev.appIdPreview,\n access: ev.access,\n },\n };\n case \"$settings\": {\n const prevWs = state.settings?.workspaceDir;\n const wsChanged = prevWs !== undefined && prevWs !== ev.workspaceDir;\n return {\n ...state,\n busy: wsChanged ? false : state.busy,\n messages: wsChanged ? [] : state.messages,\n pendingConfirms: wsChanged ? [] : state.pendingConfirms,\n pendingPathAccess: wsChanged ? [] : state.pendingPathAccess,\n pendingChoices: wsChanged ? [] : state.pendingChoices,\n pendingPlans: wsChanged ? [] : state.pendingPlans,\n pendingCheckpoints: wsChanged ? [] : state.pendingCheckpoints,\n pendingRevisions: wsChanged ? [] : state.pendingRevisions,\n activePlan: wsChanged ? null : state.activePlan,\n usage: wsChanged ? zeroUsage() : state.usage,\n sessionFiles: wsChanged ? [] : state.sessionFiles,\n retryNonce: wsChanged ? 0 : state.retryNonce,\n settings: {\n reasoningEffort: ev.reasoningEffort,\n editMode: ev.editMode,\n budgetUsd: ev.budgetUsd,\n baseUrl: ev.baseUrl,\n apiKeyPrefix: ev.apiKeyPrefix,\n workspaceDir: ev.workspaceDir,\n recentWorkspaces: ev.recentWorkspaces,\n model: ev.model,\n editor: ev.editor,\n webSearchEngine: ev.webSearchEngine,\n subagentModels: ev.subagentModels,\n showSystemEvents: ev.showSystemEvents,\n version: ev.version,\n },\n };\n }\n case \"$session_loaded\": {\n const sessionName = ev.name;\n const loaded: ChatMessage[] = ev.messages.map((m, i) => {\n if (m.kind === \"user\") {\n return { kind: \"user\", text: m.text, clientId: `c-loaded-${i}`, turn: i + 1 };\n }\n const segments: AssistantSegment[] = m.segments.map((s) => {\n if (s.kind === \"tool\") {\n return {\n kind: \"tool\",\n callId: s.callId,\n name: s.name,\n args: s.args,\n startedAt: 0,\n result: s.result,\n ok: s.ok,\n durationMs: 0,\n };\n }\n return s;\n });\n return { kind: \"assistant\", turn: m.turn, segments, pending: false };\n });\n let sessionFiles: SessionFile[] = [];\n for (const m of loaded) {\n if (m.kind !== \"assistant\") continue;\n for (const s of m.segments) {\n if (s.kind !== \"tool\") continue;\n // For replayed sessions we don't have tool.result ok-status here, but\n // segments only survive into history if the call completed. Trust it.\n sessionFiles = mergeSessionFiles(sessionFiles, extractToolFiles(s.name, s.args));\n }\n }\n return {\n ...state,\n busy: false,\n currentSession: sessionName,\n messages: loaded,\n pendingConfirms: [],\n pendingPathAccess: [],\n pendingChoices: [],\n pendingPlans: [],\n pendingCheckpoints: [],\n pendingRevisions: [],\n activePlan: null,\n usage: {\n ...zeroUsage(),\n totalCostUsd: ev.carryover.totalCostUsd,\n totalPromptTokens: ev.carryover.cacheHitTokens + ev.carryover.cacheMissTokens,\n cacheHitTokens: ev.carryover.cacheHitTokens,\n cacheMissTokens: ev.carryover.cacheMissTokens,\n },\n sessionFiles,\n activeSkill: null,\n queuedSends: [],\n retryNonce: 0,\n };\n }\n case \"$session_empty\": {\n // The sidecar successfully ran loadSessionMessages but the jsonl is\n // empty / all-malformed. Without this, the click looks like a no-op\n // because the chat just re-renders empty. Issue #1179.\n const sizeNote = ev.sizeBytes === 0 ? \"0 bytes\" : `${ev.sizeBytes} bytes, no valid entries`;\n return {\n ...state,\n messages: [\n ...state.messages,\n {\n kind: \"error\",\n message:\n `Session \"${ev.name}\" loaded with no messages (${sizeNote}). ` +\n `The file ~/.reasonix/sessions/${ev.name}.jsonl exists but couldn't be parsed — ` +\n `start a new chat or restore from .jsonl.bak if you have one.`,\n },\n ],\n };\n }\n case \"$error\":\n case \"error\":\n return {\n ...state,\n busy: false,\n activeSkill: null,\n messages: [...state.messages, { kind: \"error\", message: ev.message }],\n };\n case \"model.turn.started\":\n if (state.messages.some((m) => m.kind === \"assistant\" && m.turn === ev.turn)) {\n return { ...state, model: ev.model };\n }\n return {\n ...state,\n model: ev.model,\n messages: [\n ...state.messages,\n { kind: \"assistant\", turn: ev.turn, segments: [], pending: true },\n ],\n };\n case \"model.delta\":\n return {\n ...state,\n messages: state.messages.map((m) => {\n if (m.kind !== \"assistant\" || m.turn !== ev.turn) return m;\n if (ev.channel === \"content\") {\n return { ...m, segments: appendTextSegment(m.segments, \"text\", ev.text) };\n }\n if (ev.channel === \"reasoning\") {\n return { ...m, segments: appendTextSegment(m.segments, \"reasoning\", ev.text) };\n }\n return m;\n }),\n };\n case \"model.final\": {\n const u = ev.usage;\n const callHit = u?.prompt_cache_hit_tokens ?? 0;\n const callMiss = u?.prompt_cache_miss_tokens ?? 0;\n const hasCall = callHit > 0 || callMiss > 0;\n const usage: UsageStats = {\n totalCostUsd: state.usage.totalCostUsd + (ev.costUsd ?? 0),\n totalPromptTokens: state.usage.totalPromptTokens + (u?.prompt_tokens ?? 0),\n totalCompletionTokens: state.usage.totalCompletionTokens + (u?.completion_tokens ?? 0),\n cacheHitTokens: state.usage.cacheHitTokens + callHit,\n cacheMissTokens: state.usage.cacheMissTokens + callMiss,\n lastCallCacheHit: hasCall ? callHit : state.usage.lastCallCacheHit,\n lastCallCacheMiss: hasCall ? callMiss : state.usage.lastCallCacheMiss,\n reservedTokens: state.usage.reservedTokens,\n };\n return {\n ...state,\n usage,\n messages: state.messages.map((m) => {\n if (m.kind !== \"assistant\" || m.turn !== ev.turn) return m;\n return { ...m, pending: false };\n }),\n };\n }\n case \"tool.preparing\":\n return {\n ...state,\n messages: state.messages.map((m) => {\n if (m.kind !== \"assistant\" || m.turn !== ev.turn) return m;\n if (m.segments.some((s) => s.kind === \"tool\" && s.callId === ev.callId)) return m;\n return {\n ...m,\n segments: [\n ...m.segments,\n {\n kind: \"tool\",\n callId: ev.callId,\n name: ev.name,\n args: \"\",\n startedAt: Date.now(),\n },\n ],\n };\n }),\n };\n case \"tool.intent\": {\n const adds = extractToolFiles(ev.name, ev.args);\n return {\n ...state,\n sessionFiles: mergeSessionFiles(state.sessionFiles, adds),\n messages: state.messages.map((m) => {\n if (m.kind !== \"assistant\" || m.turn !== ev.turn) return m;\n const idx = m.segments.findIndex((s) => s.kind === \"tool\" && s.callId === ev.callId);\n if (idx >= 0) {\n const segs = [...m.segments];\n const seg = segs[idx];\n if (seg?.kind === \"tool\") {\n segs[idx] = { ...seg, args: ev.args };\n }\n return { ...m, segments: segs };\n }\n return {\n ...m,\n segments: [\n ...m.segments,\n {\n kind: \"tool\",\n callId: ev.callId,\n name: ev.name,\n args: ev.args,\n startedAt: Date.now(),\n },\n ],\n };\n }),\n };\n }\n case \"tool.result\":\n return {\n ...state,\n messages: state.messages.map((m) => {\n if (m.kind !== \"assistant\") return m;\n let mutated = false;\n const segs = m.segments.map((s) => {\n if (s.kind === \"tool\" && s.callId === ev.callId) {\n mutated = true;\n return {\n ...s,\n result: ev.output,\n ok: ev.ok,\n durationMs: Date.now() - s.startedAt,\n };\n }\n return s;\n });\n return mutated ? { ...m, segments: segs } : m;\n }),\n };\n case \"$retry_result\":\n return { ...state, retryText: ev.text, retryNonce: state.retryNonce + 1 };\n case \"$btw_result\":\n return {\n ...state,\n messages: [\n ...state.messages,\n { kind: \"status\", text: `≫ btw\\n${ev.answer}` },\n ],\n };\n case \"status\":\n return state;\n case \"warning\":\n // High-severity only — eventize already drops \"low\". Render as a quiet\n // inline divider so users see compaction / abort / rate-limit events\n // without confusing them for errors.\n if (ev.severity !== \"high\") return state;\n return {\n ...state,\n messages: [\n ...state.messages,\n {\n kind: \"warning\",\n id: `w-${ev.id}`,\n text: ev.text,\n severity: ev.severity,\n },\n ],\n };\n default:\n return state;\n }\n}\n\nfunction formatConversationMarkdown(messages: ChatMessage[], userLabel: string): string {\n return messages\n .map((m) => {\n if (m.kind === \"user\") return `### ${userLabel}\\n\\n${m.text}`;\n if (m.kind === \"assistant\") {\n const body = m.segments\n .map((s) => {\n if (s.kind === \"text\") return s.text;\n if (s.kind === \"reasoning\")\n return `<details>\\n<summary>${t(\"app.exportReasoningSummary\")}</summary>\\n\\n${s.text}\\n\\n</details>`;\n if (s.kind === \"tool\") {\n const arg = s.args ? `\\n\\n\\`\\`\\`json\\n${s.args}\\n\\`\\`\\`` : \"\";\n const res = s.result ? `\\n\\n\\`\\`\\`\\n${s.result}\\n\\`\\`\\`` : \"\";\n return `> **${t(\"app.exportToolLabel\")} · \\`${s.name}\\`**${arg}${res}`;\n }\n return \"\";\n })\n .filter(Boolean)\n .join(\"\\n\\n\");\n return `### Reasonix\\n\\n${body}`;\n }\n if (m.kind === \"error\") return `### Error\\n\\n${m.message}`;\n return \"\";\n })\n .filter(Boolean)\n .join(\"\\n\\n---\\n\\n\");\n}\n\nfunction sanitizeFilename(name: string): string {\n return name.replace(/[<>:\"/\\\\|?*\\x00-\\x1f]/g, \"_\").replace(/^\\.+/, \"\").slice(0, 200) || \"session\";\n}\n\nfunction defaultExportFilename(session: string): string {\n const safe = sanitizeFilename(session);\n return `${safe}.md`;\n}\n\ntype TabAction = Action;\ntype TabDispatcher = (action: TabAction) => void;\n\ninterface TabRuntimeProps {\n tabId: string;\n active: boolean;\n currency: \"CNY\" | \"USD\";\n registerDispatch: (tabId: string, d: TabDispatcher | null) => void;\n onNewTab: () => void;\n onCloseTab: () => void;\n canCloseTab: boolean;\n theme: Theme;\n themeStyle: ThemeStyle;\n onSetTheme: (theme: Theme) => void;\n onSetThemeStyle: (style: ThemeStyle) => void;\n onToggleTheme: () => void;\n fontScale: FontScale;\n onSetFontScale: (scale: FontScale) => void;\n fontFamily: FontFamily;\n onSetFontFamily: (family: FontFamily) => void;\n sideCollapsed: boolean;\n ctxCollapsed: boolean;\n onToggleSide: () => void;\n onToggleCtx: () => void;\n onToggleCurrency: () => void;\n tabsList: { id: string; workspaceDir?: string }[];\n activeTabId: string;\n setActiveTabId: (id: string) => void;\n /** 移动端专用:当前侧边栏抽屉是否展开 */\n mobileSideOpen: boolean;\n onToggleMobileSide: () => void;\n}\n\nfunction TabRuntime({\n tabId,\n active,\n currency,\n registerDispatch,\n onNewTab,\n onCloseTab,\n canCloseTab,\n theme,\n themeStyle,\n onSetTheme,\n onSetThemeStyle,\n onToggleTheme,\n fontScale,\n onSetFontScale,\n fontFamily,\n onSetFontFamily,\n sideCollapsed,\n ctxCollapsed,\n onToggleSide,\n onToggleCtx,\n onToggleCurrency,\n tabsList,\n activeTabId,\n setActiveTabId,\n mobileSideOpen,\n onToggleMobileSide,\n}: TabRuntimeProps) {\n const [state, dispatch] = useReducer(reduce, {\n ready: false,\n needsSetup: false,\n busy: false,\n messages: [],\n pendingConfirms: [],\n pendingPathAccess: [],\n pendingChoices: [],\n pendingPlans: [],\n pendingCheckpoints: [],\n pendingRevisions: [],\n activePlan: null,\n usage: zeroUsage(),\n sessions: [],\n settings: null,\n qq: null,\n balance: null,\n mentionResults: null,\n mentionPreview: null,\n mcpSpecs: [],\n mcpBridged: false,\n skills: [],\n sessionFiles: [],\n memory: [],\n memoryDetail: null,\n jobs: [],\n activeSkill: null,\n queuedSends: [],\n retryNonce: 0,\n });\n useLang();\n useDisableTextAssist();\n const [draft, setDraft] = useState(\"\");\n const [toast, setToast] = useState<{ msg: string; yolo?: boolean } | null>(null);\n const [splashOn, setSplashOn] = useState<boolean>(() => shouldShowSplash());\n const [wdOpen, setWdOpen] = useState(false);\n const [wdAnchor, setWdAnchor] = useState<\n { top?: number; bottom?: number; left: number } | undefined\n >(undefined);\n const composerRef = useRef<HTMLTextAreaElement>(null);\n const threadRef = useRef<HTMLDivElement>(null);\n const threadInnerRef = useRef<HTMLDivElement>(null);\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [settingsPage, setSettingsPage] = useState<SettingsPageId>(\"general\");\n const [jobsOpen, setJobsOpen] = useState(false);\n const [aboutOpen, setAboutOpen] = useState(false);\n // Pending session swap — set on sidebar click, cleared once the bridge's\n // $session_loaded lands (via the effect below). Big sessions take a beat to\n // pull off disk; without this the click looks dead.\n const [loadingSession, setLoadingSession] = useState<string | null>(null);\n const [workdirModalOpen, setWorkdirModalOpen] = useState(false);\n useEffect(() => {\n if (loadingSession && state.currentSession === loadingSession) {\n setLoadingSession(null);\n }\n }, [loadingSession, state.currentSession]);\n const openSettingsAt = useCallback((page: SettingsPageId = \"general\") => {\n setSettingsPage(page);\n setSettingsOpen(true);\n }, []);\n const palette = useCommandPalette(active);\n\n useEffect(() => {\n registerDispatch(tabId, dispatch);\n return () => registerDispatch(tabId, null);\n }, [tabId, registerDispatch]);\n\n const sendRpc = useCallback(\n (cmd: OutgoingCommand) => {\n const payload = { tabId, ...cmd };\n invoke(\"rpc_send\", { line: JSON.stringify(payload) }).catch((err) =>\n console.error(`${cmd.cmd} failed`, err),\n );\n },\n [tabId],\n );\n\n const queryMentions = useCallback(\n (query: string, nonce: number) => sendRpc({ cmd: \"mention_query\", query, nonce }),\n [sendRpc],\n );\n const previewMention = useCallback(\n (path: string, nonce: number) => sendRpc({ cmd: \"mention_preview\", path, nonce }),\n [sendRpc],\n );\n const markMentionPicked = useCallback(\n (path: string) => sendRpc({ cmd: \"mention_picked\", path }),\n [sendRpc],\n );\n const saveSettings = useCallback(\n (patch: SettingsPatch) => sendRpc({ cmd: \"settings_save\", ...patch }),\n [sendRpc],\n );\n const loadQQSettings = useCallback(() => sendRpc({ cmd: \"qq_status_get\" }), [sendRpc]);\n const connectQQ = useCallback(() => sendRpc({ cmd: \"qq_connect\" }), [sendRpc]);\n const disconnectQQ = useCallback(() => sendRpc({ cmd: \"qq_disconnect\" }), [sendRpc]);\n const saveQQConfig = useCallback(\n (patch: { appId?: string; appSecret?: string; sandbox: boolean }) =>\n sendRpc({ cmd: \"qq_config_save\", ...patch }),\n [sendRpc],\n );\n const saveApiKey = useCallback(\n (key: string) => sendRpc({ cmd: \"setup_save_key\", key }),\n [sendRpc],\n );\n const addMcpSpec = useCallback(\n (spec: string) => sendRpc({ cmd: \"mcp_specs_add\", spec }),\n [sendRpc],\n );\n const removeMcpSpec = useCallback(\n (spec: string) => sendRpc({ cmd: \"mcp_specs_remove\", spec }),\n [sendRpc],\n );\n const newChat = useCallback(() => {\n sendRpc({ cmd: \"new_chat\" });\n dispatch({ t: \"clear\" });\n }, [sendRpc]);\n\n const pickWorkspace = useCallback(async () => {\n // Browsers can't expose absolute filesystem paths (webkitdirectory only\n // hands back relative + File handles), so the web runtime opens a custom\n // server-backed directory browser instead of the native dialog. Desktop\n // (Tauri) still gets the OS picker for free.\n if (isWebRuntime) {\n setWorkdirModalOpen(true);\n return;\n }\n try {\n const picked = await openDialog({\n directory: true,\n multiple: false,\n title: t(\"workdir.title\"),\n defaultPath: state.settings?.workspaceDir,\n });\n if (typeof picked === \"string\" && picked.length > 0) {\n saveSettings({ workspaceDir: picked });\n }\n } catch (err) {\n console.error(\"pickWorkspace failed\", err);\n }\n }, [saveSettings, state.settings?.workspaceDir]);\n\n const flashToast = useCallback(\n (msg: string, opts?: { yolo?: boolean; duration?: number }) => {\n setToast({ msg, yolo: opts?.yolo });\n window.setTimeout(() => setToast(null), opts?.duration ?? 1600);\n },\n [],\n );\n\n // Drag-and-drop: dropping files/folders onto the window inserts them\n // as @-mentions in the draft (relative to workspaceDir when inside it).\n // activeRef gates the handler — without it, a single drop hits every\n // mounted tab's draft (issue #1027, exposed once #1063 restored tabs).\n const dropActiveRef = useRef(active);\n useEffect(() => {\n dropActiveRef.current = active;\n }, [active]);\n useEffect(() => {\n const ws = state.settings?.workspaceDir;\n let unlisten: (() => void) | null = null;\n let cancelled = false;\n void (async () => {\n try {\n const mod = await import(\"@tauri-apps/api/webview\");\n const webview = mod.getCurrentWebview();\n const handle = await webview.onDragDropEvent((event: any) => {\n if (!dropActiveRef.current) return;\n if (event.payload.type === \"enter\") {\n document.body.style.setProperty(\n \"--drop-overlay-label\",\n `\"${t(\"dragDrop.overlay\")}\"`,\n );\n document.body.dataset.dragOver = \"1\";\n return;\n }\n if (event.payload.type === \"leave\") {\n delete document.body.dataset.dragOver;\n return;\n }\n if (event.payload.type !== \"drop\") return;\n delete document.body.dataset.dragOver;\n const paths = event.payload.paths ?? [];\n if (paths.length === 0) return;\n const mentions = paths.map((p: string) => {\n const norm = p.replace(/\\\\/g, \"/\");\n if (ws) {\n const wsNorm = ws.replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\");\n if (norm === wsNorm || norm.startsWith(`${wsNorm}/`)) {\n return norm.slice(wsNorm.length).replace(/^\\/+/, \"\") || \".\";\n }\n }\n return norm;\n });\n setDraft((d) => {\n const prefix = d.trim() ? `${d.replace(/\\s+$/, \"\")} ` : \"\";\n return `${prefix}${mentions.map((m: string) => `@${m}`).join(\" \")} `;\n });\n for (const m of mentions) markMentionPicked(m as string);\n composerRef.current?.focus();\n });\n if (cancelled) handle();\n else unlisten = handle;\n } catch (err) {\n console.error(\"drag-drop listen failed\", err);\n }\n })();\n return () => {\n cancelled = true;\n unlisten?.();\n delete document.body.dataset.dragOver;\n };\n }, [state.settings?.workspaceDir, markMentionPicked]);\n\n const send = useCallback(\n (override?: string) => {\n const text = (override ?? draft).trim();\n if (!text || !state.ready || state.busy) return;\n\n // /btw <question> — route to side-question RPC instead of user_input\n const btwMatch = /^\\/btw(?:\\s+([\\s\\S]+))?$/.exec(text);\n if (btwMatch) {\n const question = btwMatch[1]?.trim() ?? \"\";\n if (!question) return;\n sendRpc({ cmd: \"btw\", text: question });\n if (!override) setDraft(\"\");\n return;\n }\n\n const skillMatch = text.match(/^\\/([a-zA-Z0-9_-]+)(\\s+.*)?$/);\n if (skillMatch) {\n const [, name, args] = skillMatch;\n const skill = state.skills.find((s) => s.name === name);\n if (skill) {\n const clientId = `skill-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n const trimmedArgs = args?.trim() ?? \"\";\n dispatch({ t: \"start_skill\", skill: { name: skill.name, runAs: skill.runAs }, args: trimmedArgs, clientId });\n sendRpc({ cmd: \"skill_run\", name: skill.name, args: trimmedArgs || undefined });\n if (!override) setDraft(\"\");\n return;\n }\n }\n const clientId = `c-${Date.now()}`;\n dispatch({ t: \"send_user\", text, clientId });\n sendRpc({ cmd: \"user_input\", text });\n if (!override) setDraft(\"\");\n },\n [draft, state.ready, state.busy, state.skills, sendRpc],\n );\n\n const abort = useCallback(() => sendRpc({ cmd: \"abort\" }), [sendRpc]);\n\n // When /retry returns the last user text, set it as the composer draft\n useEffect(() => {\n if (state.retryNonce > 0 && state.retryText) {\n setDraft(state.retryText);\n composerRef.current?.focus();\n }\n // Only fire when retryNonce changes — retryText alone would re-fire on re-renders\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [state.retryNonce]);\n\n useEffect(() => {\n if (state.busy || !state.ready || state.queuedSends.length === 0) return;\n const next = state.queuedSends[0];\n if (!next) return;\n dispatch({ t: \"shift_queued_send\" });\n send(next);\n }, [state.busy, state.ready, state.queuedSends, send]);\n\n const resolveConfirm = useCallback(\n (id: number, response: ConfirmationChoice) => {\n sendRpc({ cmd: \"confirm_response\", id, response });\n dispatch({ t: \"resolve_confirm\", id });\n },\n [sendRpc],\n );\n const onApproveConfirm = useCallback(\n (id: number) => resolveConfirm(id, { type: \"run_once\" }),\n [resolveConfirm],\n );\n const onRejectConfirm = useCallback(\n (id: number) => resolveConfirm(id, { type: \"deny\" }),\n [resolveConfirm],\n );\n const onAlwaysAllowConfirm = useCallback(\n (id: number, prefix: string) => resolveConfirm(id, { type: \"always_allow\", prefix }),\n [resolveConfirm],\n );\n const resolvePathAccess = useCallback(\n (id: number, response: ConfirmationChoice) => {\n sendRpc({ cmd: \"confirm_response\", id, response });\n dispatch({ t: \"resolve_path_access\", id });\n },\n [sendRpc],\n );\n const resolveChoice = useCallback(\n (id: number, response: ChoiceVerdict) => {\n sendRpc({ cmd: \"choice_response\", id, response });\n dispatch({ t: \"resolve_choice\", id });\n },\n [sendRpc],\n );\n const resolvePlan = useCallback(\n (id: number, response: PlanVerdict) => {\n sendRpc({ cmd: \"plan_response\", id, response });\n dispatch({ t: \"resolve_plan\", id, verdict: response });\n },\n [sendRpc],\n );\n const resolveCheckpoint = useCallback(\n (id: number, response: CheckpointVerdict) => {\n sendRpc({ cmd: \"checkpoint_response\", id, response });\n dispatch({ t: \"resolve_checkpoint\", id, verdict: response });\n },\n [sendRpc],\n );\n const resolveRevision = useCallback(\n (id: number, response: RevisionVerdict) => {\n sendRpc({ cmd: \"revision_response\", id, response });\n dispatch({ t: \"resolve_revision\", id, verdict: response });\n },\n [sendRpc],\n );\n\n // Read the latest session inside the stable restore callback below.\n const currentSessionRef = useRef(state.currentSession);\n currentSessionRef.current = state.currentSession;\n const restoreScrollTop = useCallback(() => {\n const session = currentSessionRef.current;\n if (!session) return null;\n const raw = localStorage.getItem(`reasonix.scroll.${session}`);\n const n = raw ? Number(raw) : Number.NaN;\n return Number.isFinite(n) ? n : null;\n }, []);\n\n const { showJumpButton, scrollToBottom } = useAutoScroll(\n threadRef,\n threadInnerRef,\n state.busy,\n restoreScrollTop,\n );\n\n // Persist the transcript scroll offset per session so a restart reopens\n // the conversation where the user left it (#1244).\n useEffect(() => {\n const el = threadRef.current;\n const session = state.currentSession;\n if (!el || !session) return;\n const key = `reasonix.scroll.${session}`;\n let timer: ReturnType<typeof setTimeout>;\n const onScroll = () => {\n clearTimeout(timer);\n timer = setTimeout(() => {\n const atBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - 80;\n if (atBottom) localStorage.removeItem(key);\n else localStorage.setItem(key, String(Math.round(el.scrollTop)));\n }, 250);\n };\n el.addEventListener(\"scroll\", onScroll, { passive: true });\n return () => {\n el.removeEventListener(\"scroll\", onScroll);\n clearTimeout(timer);\n };\n }, [state.currentSession]);\n\n useEffect(() => {\n if (!active) return;\n if (!jobsOpen) return;\n sendRpc({ cmd: \"jobs_list\" });\n const id = window.setInterval(() => sendRpc({ cmd: \"jobs_list\" }), 1500);\n return () => window.clearInterval(id);\n }, [active, jobsOpen, sendRpc]);\n\n useEffect(() => {\n if (!active) return;\n if (state.busy) return;\n sendRpc({ cmd: \"jobs_list\" });\n }, [active, state.busy, sendRpc]);\n\n useEffect(() => {\n if (!active) return;\n loadQQSettings();\n }, [active, loadQQSettings]);\n\n const initialUrlSession = useRef<string | null>(readSessionFromUrl());\n const urlSessionDispatched = useRef(false);\n useEffect(() => {\n if (!active) return;\n if (urlSessionDispatched.current) return;\n if (!state.ready) return;\n if (state.sessions.length === 0) return;\n urlSessionDispatched.current = true;\n const target = initialUrlSession.current;\n if (!target) return;\n if (target === state.currentSession) return;\n if (!state.sessions.some((s) => s.name === target)) {\n writeSessionToUrl(null);\n return;\n }\n sendRpc({ cmd: \"session_load\", name: target });\n }, [active, state.ready, state.sessions, state.currentSession, sendRpc]);\n\n useEffect(() => {\n // Every TabRuntime stays mounted (display:none on inactive), so each registers its own keydown — without this gate Cmd+N would fire newChat() in every tab and wipe the inactive ones' sessions.\n if (!active) return;\n const onKey = (e: KeyboardEvent) => {\n const mod = e.ctrlKey || e.metaKey;\n if (mod && (e.key === \"a\" || e.key === \"A\")) {\n const tag = (e.target as HTMLElement)?.tagName;\n if (tag !== \"INPUT\" && tag !== \"TEXTAREA\") e.preventDefault();\n return;\n }\n if (mod && (e.key === \"l\" || e.key === \"L\")) {\n e.preventDefault();\n composerRef.current?.focus();\n } else if (mod && (e.key === \"n\" || e.key === \"N\")) {\n e.preventDefault();\n newChat();\n } else if (mod && (e.key === \"o\" || e.key === \"O\")) {\n e.preventDefault();\n setWdAnchor(undefined);\n setWdOpen((v) => !v);\n } else if (mod && e.key === \",\") {\n e.preventDefault();\n if (settingsOpen) setSettingsOpen(false);\n else openSettingsAt(\"general\");\n } else if (mod && (e.key === \"j\" || e.key === \"J\")) {\n e.preventDefault();\n setJobsOpen((v) => !v);\n } else if (e.key === \"Escape\" && state.busy) {\n const target = e.target as HTMLElement | null;\n if (target?.tagName === \"INPUT\" || target?.tagName === \"TEXTAREA\") return;\n e.preventDefault();\n abort();\n }\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [active, state.busy, abort, newChat, settingsOpen, openSettingsAt]);\n\n const commands = buildCommands({\n newChat: () => {\n newChat();\n flashToast(t(\"app.toast.newSession\"));\n },\n clearChat: () => {\n dispatch({ t: \"clear\" });\n flashToast(t(\"app.toast.cleared\"));\n },\n focusComposer: () => composerRef.current?.focus(),\n openSettings: () => openSettingsAt(\"general\"),\n about: () => setAboutOpen(true),\n abort,\n copyLast: () => {\n const last = [...state.messages].reverse().find((m) => m.kind === \"assistant\");\n if (!last || last.kind !== \"assistant\") return;\n const text = last.segments\n .filter((s): s is { kind: \"text\"; text: string } => s.kind === \"text\")\n .map((s) => s.text)\n .join(\"\\n\\n\")\n .trim();\n if (text) {\n void navigator.clipboard.writeText(text);\n flashToast(t(\"app.toast.copied\"));\n }\n },\n conversationCopy: () => {\n conversationCopy();\n },\n exportMarkdown: () => {\n exportConversation();\n },\n pickWorkspace,\n newTab: onNewTab,\n closeTab: onCloseTab,\n busy: state.busy,\n canCloseTab,\n hasMessages: state.messages.length > 0,\n });\n\n const slashCommands: SlashCmd[] = [\n {\n cmd: \"/help\",\n desc: t(\"app.cmd.help\"),\n run: () => {\n setDraft(\"/\");\n composerRef.current?.focus();\n },\n },\n { cmd: \"/new\", desc: t(\"app.cmd.newSession\"), run: () => newChat(), kb: shortcutText([\"mod\", \"N\"]) },\n { cmd: \"/clear\", desc: t(\"app.cmd.clearChat\"), run: () => dispatch({ t: \"clear\" }) },\n { cmd: \"/abort\", desc: t(\"app.cmd.abort\"), run: () => abort(), kb: \"esc\" },\n {\n cmd: \"/copy\",\n desc: t(\"app.cmd.copyLast\"),\n run: () => {\n const last = [...state.messages].reverse().find((m) => m.kind === \"assistant\");\n if (last?.kind === \"assistant\") {\n const text = last.segments\n .filter((s): s is { kind: \"text\"; text: string } => s.kind === \"text\")\n .map((s) => s.text)\n .join(\"\\n\\n\");\n if (text) {\n void navigator.clipboard.writeText(text);\n flashToast(t(\"app.toast.copied\"));\n }\n }\n },\n },\n { cmd: \"/model\", desc: t(\"app.cmd.switchModel\"), run: () => openSettingsAt(\"models\") },\n { cmd: \"/theme\", desc: t(\"app.cmd.toggleTheme\"), run: onToggleTheme },\n {\n cmd: \"/currency\",\n desc: t(\"app.cmd.toggleCurrency\"),\n run: onToggleCurrency,\n },\n {\n cmd: \"/lang\",\n desc: t(\"app.cmd.toggleLang\"),\n run: () => {\n const langs = getSupportedLangs();\n const next = langs[(langs.indexOf(getLang()) + 1) % langs.length] ?? \"en\";\n setLang(next);\n const langName = getLangLabel(next);\n flashToast(t(\"app.toast.langSwitched\", { lang: langName }));\n },\n },\n {\n cmd: \"/export\",\n desc: t(\"app.cmd.exportMd\"),\n run: () => exportConversation(),\n },\n {\n cmd: \"/feedback\",\n desc: t(\"app.cmd.feedback\"),\n run: () => {\n void openUrl(\"https://github.com/esengine/DeepSeek-Reasonix/issues/new/choose\").catch(\n () => undefined,\n );\n },\n },\n {\n cmd: \"/compact\",\n desc: t(\"app.cmd.compact\"),\n run: () => sendRpc({ cmd: \"compact_history\" }),\n },\n {\n cmd: \"/retry\",\n desc: t(\"app.cmd.retry\"),\n run: () => sendRpc({ cmd: \"retry\" }),\n },\n {\n cmd: \"/btw\",\n desc: t(\"app.cmd.btw\"),\n run: () => {\n // Sets the draft to /btw so the user can type their question.\n // The send() handler detects the /btw prefix and routes to the btw RPC.\n setDraft(\"/btw \");\n composerRef.current?.focus();\n },\n },\n ...state.skills.map((s) => ({\n cmd: `/${s.name}`,\n desc: s.description?.trim() || fallbackSkillDesc(s),\n insertOnly: true,\n run: () => {\n dispatch({\n t: \"start_skill\",\n skill: { name: s.name, runAs: s.runAs },\n clientId: `skill-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n });\n sendRpc({ cmd: \"skill_run\", name: s.name });\n },\n })),\n ];\n\n const elapsed = useElapsed(state.busy);\n const workspaceLabel = state.settings?.workspaceDir\n ? state.settings.workspaceDir.split(/[\\\\/]/).pop() || \"workspace\"\n : \"Reasonix\";\n const session = (() => {\n const firstUser = state.messages.find((m) => m.kind === \"user\");\n if (firstUser && firstUser.kind === \"user\") {\n const cleaned = firstUser.text.replace(/\\s+/g, \" \").trim();\n if (cleaned) return cleaned.length > 60 ? `${cleaned.slice(0, 60)}…` : cleaned;\n }\n if (state.currentSession) {\n const s = state.sessions.find((x) => x.name === state.currentSession);\n if (s?.summary?.trim()) return s.summary.trim();\n const m = state.currentSession.match(/^desktop-(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})/);\n if (m)\n return t(\"app.session.format\", {\n month: m[2],\n day: m[3],\n hour: m[4],\n minute: m[5],\n });\n }\n return state.messages.length === 0\n ? t(\"app.session.new\", { workspace: workspaceLabel })\n : workspaceLabel;\n })();\n\n const exportConversation = useCallback(async () => {\n const userLabel = t(\"app.exportUserLabel\");\n const md = formatConversationMarkdown(state.messages, userLabel);\n if (!md) {\n flashToast(t(\"app.toast.emptySession\"));\n return;\n }\n try {\n const filename = defaultExportFilename(session);\n const path = await saveDialog({\n defaultPath: filename,\n filters: [{ name: \"Markdown\", extensions: [\"md\"] }],\n title: t(\"app.toast.exportDialogTitle\"),\n });\n if (!path) return;\n await invoke(\"write_text_file\", { path, content: md });\n flashToast(t(\"app.toast.exportedMd\"));\n } catch (err) {\n console.error(\"export failed\", err);\n flashToast(t(\"app.toast.exportFailed\", { error: String(err) }));\n }\n }, [state.messages, session, flashToast]);\n\n const conversationCopy = useCallback(() => {\n const userLabel = t(\"app.exportUserLabel\");\n const md = formatConversationMarkdown(state.messages, userLabel);\n if (!md) {\n flashToast(t(\"app.toast.emptySession\"));\n return;\n }\n void navigator.clipboard.writeText(md);\n flashToast(t(\"app.toast.copiedMd\"));\n }, [state.messages, flashToast]);\n\n return (\n <WorkspaceProvider\n value={{ dir: state.settings?.workspaceDir, editor: state.settings?.editor }}\n >\n <div\n className=\"app\"\n data-theme={theme}\n data-theme-style={themeStyle}\n data-side-collapsed={sideCollapsed}\n data-ctx-collapsed={ctxCollapsed}\n data-mobile-side-open={mobileSideOpen}\n style={{ display: active ? undefined : \"none\" }}\n >\n {/* 移动端遮罩层:点击关闭侧边栏抽屉 */}\n <div\n className=\"mobile-overlay\"\n aria-hidden=\"true\"\n onClick={onToggleMobileSide}\n />\n\n <TitleBar\n session={session}\n model={state.settings?.model}\n sideOn={!sideCollapsed}\n ctxOn={!ctxCollapsed}\n onToggleSide={onToggleSide}\n onToggleCtx={onToggleCtx}\n onOpenCommands={() => palette.setOpen(true)}\n onOpenSettings={() => openSettingsAt(\"general\")}\n onCopy={conversationCopy}\n onExport={exportConversation}\n onClear={() => dispatch({ t: \"clear\" })}\n hasMessages={state.messages.length > 0}\n mobileSideOpen={mobileSideOpen}\n onToggleMobileSide={onToggleMobileSide}\n />\n\n <TabBar\n tabs={tabsList}\n activeId={activeTabId}\n setActive={setActiveTabId}\n onClose={(id) => {\n if (tabsList.length <= 1) return;\n invoke(\"rpc_send\", {\n line: JSON.stringify({ cmd: \"tab_close\", tabId: id }),\n }).catch((err) => console.error(\"tab_close failed\", err));\n }}\n onNew={onNewTab}\n singleTab={tabsList.length <= 1}\n />\n\n <Sidebar\n sessions={state.sessions}\n activeName={state.currentSession}\n loadingName={loadingSession}\n onNewChat={() => { newChat(); onToggleMobileSide && mobileSideOpen && onToggleMobileSide(); }}\n onLoadSession={(name) => {\n if (name === state.currentSession || name === loadingSession) return;\n setLoadingSession(name);\n sendRpc({ cmd: \"session_load\", name });\n // 移动端选择会话后自动收起抽屉\n if (mobileSideOpen) onToggleMobileSide();\n }}\n onDeleteSession={(name) => sendRpc({ cmd: \"session_delete\", name })}\n onOpenSettings={() => { openSettingsAt(\"general\"); if (mobileSideOpen) onToggleMobileSide(); }}\n onOpenRules={() => { openSettingsAt(\"rules\"); if (mobileSideOpen) onToggleMobileSide(); }}\n onOpenCommands={() => { palette.setOpen(true); if (mobileSideOpen) onToggleMobileSide(); }}\n onOpenAbout={() => { setAboutOpen(true); if (mobileSideOpen) onToggleMobileSide(); }}\n />\n\n <main className=\"main\" style={{ position: \"relative\" }}>\n {state.needsSetup ? (\n <NeedsSetupView\n workspaceDir={state.settings?.workspaceDir}\n onPickWorkspace={pickWorkspace}\n onSubmit={(key) => sendRpc({ cmd: \"setup_save_key\", key })}\n />\n ) : (\n <>\n <MainHead\n session={session}\n model={state.settings?.model}\n workspaceDir={state.settings?.workspaceDir}\n busy={state.busy}\n hasMessages={state.messages.length > 0}\n onAbort={abort}\n onNewChat={newChat}\n onCopy={conversationCopy}\n onExport={exportConversation}\n onOpenWorkdir={(anchor) => {\n setWdAnchor(anchor);\n setWdOpen(true);\n }}\n />\n <div className=\"thread\" ref={threadRef} style={{ position: \"relative\" }}>\n {loadingSession ? (\n <div className=\"thread-loading-overlay\">\n {t(\"sidebarPanel.loading\")} {loadingSession}\n </div>\n ) : null}\n <div className=\"thread-inner\" ref={threadInnerRef}>\n {state.activePlan ? (\n <>\n <PlanBanner\n plan={state.activePlan}\n onDismiss={state.busy ? undefined : () => dispatch({ t: \"dismiss_plan\" })}\n />\n <ActivePlanTaskCard plan={state.activePlan} />\n </>\n ) : null}\n\n {state.messages.length === 0 ? (\n <EmptyState\n onPick={(text) => {\n const trimmed = text.trim();\n if (trimmed.startsWith(\"/\")) {\n const cmd = trimmed.split(/\\s+/)[0] ?? \"\";\n const match = slashCommands.find((s) => s.cmd === cmd);\n if (match) {\n match.run();\n return;\n }\n }\n send(text);\n }}\n workspaceDir={state.settings?.workspaceDir}\n />\n ) : null}\n\n {state.messages.map((m, i) => {\n if (m.kind === \"user\") {\n const dividerLabel = `turn ${m.turn}`;\n const prev = state.messages[i - 1];\n const needsDivider = !prev || prev.kind === \"user\";\n return (\n <div key={`u-${i}`}>\n {needsDivider ? <TurnDivider label={dividerLabel} /> : null}\n <UserMsg text={m.text} skill={m.skill} />\n </div>\n );\n }\n if (m.kind === \"assistant\") {\n return (\n <AssistantMsg\n // Index, not turn — replayed transcripts arrive with turn=0\n // for every assistant row (the server doesn't reconstruct\n // turn numbers from JSONL), so a turn-keyed list collapsed\n // every assistant into one slot and switching sessions left\n // the same stale row visible.\n key={`a-${i}`}\n segments={m.segments}\n pending={m.pending}\n model={state.model}\n onApproveConfirm={onApproveConfirm}\n onRejectConfirm={onRejectConfirm}\n onAlwaysAllowConfirm={onAlwaysAllowConfirm}\n pendingConfirms={state.pendingConfirms}\n />\n );\n }\n if (m.kind === \"error\") {\n return (\n <div\n key={`e-${i}`}\n className=\"warn-card\"\n style={{\n borderColor: \"var(--tone-err)\",\n background: \"var(--danger-soft)\",\n }}\n >\n <span className=\"ico\" style={{ color: \"var(--tone-err)\" }}>\n <I.warning size={16} />\n </span>\n <div>\n <div className=\"tt\">{t(\"app.errorLabel\")}</div>\n <div className=\"ds\">{m.message}</div>\n </div>\n </div>\n );\n }\n if (m.kind === \"warning\") {\n if (state.settings?.showSystemEvents === false) return null;\n return (\n <div key={m.id} className=\"sys-event-row\" title={m.text}>\n <span className=\"line\" />\n <span className=\"label\">{m.text}</span>\n <span className=\"line\" />\n </div>\n );\n }\n return null;\n })}\n\n {/* Pending approvals */}\n {state.pendingPlans.map((p) => (\n <PlanApprovalCard\n key={`pp-${p.id}`}\n p={p}\n onApprove={() => resolvePlan(p.id, { type: \"approve\" })}\n onRefine={() => resolvePlan(p.id, { type: \"refine\" })}\n onCancel={() => resolvePlan(p.id, { type: \"cancel\" })}\n />\n ))}\n {state.pendingCheckpoints.map((c) => (\n <CheckpointApprovalCard\n key={`cp-${c.id}`}\n c={c}\n onContinue={() => resolveCheckpoint(c.id, { type: \"continue\" })}\n onRevise={() => resolveCheckpoint(c.id, { type: \"revise\" })}\n onStop={() => resolveCheckpoint(c.id, { type: \"stop\" })}\n />\n ))}\n {state.pendingRevisions.map((r) => (\n <RevisionApprovalCard\n key={`rv-${r.id}`}\n r={r}\n onAccept={() => resolveRevision(r.id, { type: \"accepted\" })}\n onReject={() => resolveRevision(r.id, { type: \"rejected\" })}\n />\n ))}\n {state.pendingConfirms.map((c) => (\n <ConfirmApprovalCard\n key={`cc-${c.id}`}\n c={c}\n onAllow={() => resolveConfirm(c.id, { type: \"run_once\" })}\n onAlwaysAllow={(prefix) =>\n resolveConfirm(c.id, { type: \"always_allow\", prefix })\n }\n onDeny={() => resolveConfirm(c.id, { type: \"deny\" })}\n />\n ))}\n {state.pendingPathAccess.map((p) => (\n <PathAccessApprovalCard\n key={`pa-${p.id}`}\n p={p}\n onAllow={() => resolvePathAccess(p.id, { type: \"run_once\" })}\n onAlwaysAllow={(prefix) =>\n resolvePathAccess(p.id, { type: \"always_allow\", prefix })\n }\n onDeny={() => resolvePathAccess(p.id, { type: \"deny\" })}\n />\n ))}\n {state.pendingChoices.map((c) => (\n <ChoiceApprovalCard\n key={`ch-${c.id}`}\n c={c}\n onPick={(optionId) => resolveChoice(c.id, { type: \"pick\", optionId })}\n onCancel={() => resolveChoice(c.id, { type: \"cancel\" })}\n />\n ))}\n\n {!state.ready ? (\n <div\n style={{\n padding: 12,\n color: \"var(--muted)\",\n fontFamily: \"Geist Mono, monospace\",\n fontSize: 11,\n }}\n >\n {t(\"app.connecting\")}\n </div>\n ) : null}\n </div>\n {showJumpButton ? (\n <button\n className=\"thread-jump-bottom\"\n onClick={() => scrollToBottom(true)}\n title={t(\"app.jumpToBottom\") ?? \"Jump to bottom\"}\n aria-label={t(\"app.jumpToBottom\") ?? \"Jump to bottom\"}\n >\n <I.chev size={16} />\n </button>\n ) : null}\n </div>\n\n <Composer\n draft={draft}\n setDraft={setDraft}\n onSend={() => send()}\n onAbort={abort}\n disabled={!state.ready}\n busy={state.busy}\n busyLabel={\n state.busy\n ? state.activeSkill\n ? `Skill · ${state.activeSkill.name}`\n : \"Reasoning\"\n : undefined\n }\n busyElapsedMs={elapsed}\n textareaRef={composerRef}\n modelLabel={state.settings?.model ?? \"deepseek-v4-flash\"}\n reasoningEffort={state.settings?.reasoningEffort ?? \"high\"}\n onModelChange={(model) => {\n saveSettings({ model });\n flashToast(t(\"app.toast.modelSwitched\", { model }));\n }}\n onEffortChange={(reasoningEffort) => {\n saveSettings({ reasoningEffort });\n flashToast(t(\"app.toast.effortSwitched\", { effort: reasoningEffort }));\n }}\n editMode={state.settings?.editMode ?? \"review\"}\n onEditModeChange={(mode) => {\n saveSettings({ editMode: mode });\n if (mode === \"yolo\") {\n flashToast(t(\"app.yolo.toast\"), { yolo: true, duration: 3000 });\n } else {\n flashToast(t(\"app.toast.modeSwitched\", { mode: mode.toUpperCase() }));\n }\n }}\n workspaceDir={state.settings?.workspaceDir}\n slashCommands={slashCommands}\n onMentionQuery={queryMentions}\n onMentionPreview={previewMention}\n onMentionPicked={markMentionPicked}\n mentionResults={state.mentionResults}\n queuedSends={state.queuedSends}\n onQueueWhileBusy={(text) => {\n dispatch({ t: \"enqueue_send\", text });\n setDraft(\"\");\n }}\n onDequeueSend={(index) => dispatch({ t: \"dequeue_send\", index })}\n />\n </>\n )}\n </main>\n\n <ContextPanel\n settings={state.settings}\n usage={state.usage}\n mcpSpecs={state.mcpSpecs}\n mcpBridged={state.mcpBridged}\n sessionFiles={state.sessionFiles}\n memory={state.memory}\n memoryDetail={state.memoryDetail}\n onReadMemory={(path) => sendRpc({ cmd: \"memory_read\", path })}\n />\n\n <StatusBar\n settings={state.settings}\n balance={state.balance}\n usage={state.usage}\n busy={state.busy}\n ready={state.ready}\n currency={currency}\n theme={theme}\n themeStyle={themeStyle}\n jobs={state.jobs}\n jobsOpen={jobsOpen}\n onToggleJobs={() => setJobsOpen((v) => !v)}\n onSetThemeStyle={onSetThemeStyle}\n onToggleCurrency={onToggleCurrency}\n onOpenSettings={() => openSettingsAt(\"general\")}\n onOpenWorkdir={(anchor) => {\n setWdAnchor(anchor);\n setWdOpen(true);\n }}\n />\n\n <CommandPalette\n open={palette.open}\n onClose={() => palette.setOpen(false)}\n commands={commands}\n />\n\n <WorkdirPop\n open={wdOpen}\n onClose={() => setWdOpen(false)}\n recent={state.settings?.recentWorkspaces ?? []}\n current={state.settings?.workspaceDir}\n anchor={wdAnchor}\n onPick={(path) => saveSettings({ workspaceDir: path })}\n onBrowse={pickWorkspace}\n />\n\n <WorkdirInputModal\n open={workdirModalOpen}\n initialPath={state.settings?.workspaceDir}\n onCancel={() => setWorkdirModalOpen(false)}\n onConfirm={(path) => {\n saveSettings({ workspaceDir: path });\n setWorkdirModalOpen(false);\n }}\n />\n\n {aboutOpen ? <AboutModal onClose={() => setAboutOpen(false)} /> : null}\n\n {settingsOpen && state.settings ? (\n <SettingsModal\n settings={state.settings}\n balance={state.balance}\n usage={state.usage}\n currency={currency}\n theme={theme}\n themeStyle={themeStyle}\n onSetTheme={onSetTheme}\n onSetThemeStyle={onSetThemeStyle}\n fontScale={fontScale}\n onSetFontScale={onSetFontScale}\n fontFamily={fontFamily}\n onSetFontFamily={onSetFontFamily}\n initialPage={settingsPage}\n mcpSpecs={state.mcpSpecs}\n mcpBridged={state.mcpBridged}\n skills={state.skills}\n memory={state.memory}\n memoryDetail={state.memoryDetail}\n qq={state.qq}\n onClose={() => setSettingsOpen(false)}\n onSave={saveSettings}\n onSaveApiKey={saveApiKey}\n onLoadQQ={loadQQSettings}\n onConnectQQ={connectQQ}\n onDisconnectQQ={disconnectQQ}\n onSaveQQConfig={saveQQConfig}\n onOpenQQApplyLink={() =>\n openUrl(\"https://q.qq.com/qqbot/openclaw/login.html\").catch(() => undefined)\n }\n onPickWorkspace={pickWorkspace}\n onAddMcpSpec={addMcpSpec}\n onRemoveMcpSpec={removeMcpSpec}\n onReadMemory={(path) => sendRpc({ cmd: \"memory_read\", path })}\n />\n ) : null}\n\n <JobsPop\n open={jobsOpen}\n onClose={() => setJobsOpen(false)}\n jobs={state.jobs}\n onStop={(jobId) => sendRpc({ cmd: \"jobs_stop\", jobId })}\n onStopAll={() => sendRpc({ cmd: \"jobs_stop_all\" })}\n />\n\n <Toast message={toast} />\n\n {splashOn ? <Splash onDone={() => setSplashOn(false)} /> : null}\n </div>\n </WorkspaceProvider>\n );\n}\n\nfunction WinMinimize() {\n return (\n <svg width=\"10\" height=\"1\" viewBox=\"0 0 10 1\" aria-hidden>\n <rect width=\"10\" height=\"1\" fill=\"currentColor\" />\n </svg>\n );\n}\nfunction WinMaximize() {\n return (\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden>\n <rect x=\"0.5\" y=\"0.5\" width=\"9\" height=\"9\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1\" />\n </svg>\n );\n}\nfunction WinRestore() {\n return (\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden>\n <rect x=\"2.5\" y=\"0.5\" width=\"7\" height=\"7\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1\" />\n <rect x=\"0.5\" y=\"2.5\" width=\"7\" height=\"7\" fill=\"var(--bg-2, #eee)\" stroke=\"currentColor\" strokeWidth=\"1\" />\n </svg>\n );\n}\nfunction WinClose() {\n return (\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" aria-hidden>\n <line x1=\"0.5\" y1=\"0.5\" x2=\"9.5\" y2=\"9.5\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\" />\n <line x1=\"9.5\" y1=\"0.5\" x2=\"0.5\" y2=\"9.5\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\" />\n </svg>\n );\n}\n\nfunction TitleBar({\n session,\n model,\n sideOn,\n ctxOn,\n onToggleSide,\n onToggleCtx,\n onOpenCommands,\n onOpenSettings,\n onCopy,\n onExport,\n onClear,\n hasMessages,\n mobileSideOpen,\n onToggleMobileSide,\n}: {\n session: string;\n model?: string;\n sideOn: boolean;\n ctxOn: boolean;\n onToggleSide: () => void;\n onToggleCtx: () => void;\n onOpenCommands: () => void;\n onOpenSettings: () => void;\n onCopy: () => void;\n onExport: () => void;\n onClear: () => void;\n hasMessages: boolean;\n /** 移动端:汉堡菜单状态 */\n mobileSideOpen: boolean;\n onToggleMobileSide: () => void;\n}) {\n useLang();\n const [menuOpen, setMenuOpen] = useState(false);\n const [isMaximized, setIsMaximized] = useState(false);\n const moreWrapRef = useRef<HTMLDivElement>(null);\n const isMac = document.documentElement.dataset.platform === \"macos\";\n // Web 模式下隐藏原生窗口控件\n const isWeb = document.documentElement.dataset.web === \"true\";\n\n useEffect(() => {\n const win = getCurrentWindow();\n win.isMaximized().then(setIsMaximized);\n let unlisten: (() => void) | undefined;\n win.listen(\"tauri://resize\", async () => {\n setIsMaximized(await win.isMaximized());\n }).then((fn: (() => void) | undefined) => { unlisten = fn; });\n return () => unlisten?.();\n }, []);\n\n useEffect(() => {\n if (!menuOpen) return;\n const onDown = (e: MouseEvent) => {\n if (moreWrapRef.current && !moreWrapRef.current.contains(e.target as Node))\n setMenuOpen(false);\n };\n window.addEventListener(\"mousedown\", onDown);\n return () => window.removeEventListener(\"mousedown\", onDown);\n }, [menuOpen]);\n\n const win = getCurrentWindow();\n\n return (\n <header className=\"titlebar\">\n {/* left: sidebar toggle + brand */}\n <div className=\"tb-left\">\n {isMac && !isWeb ? (\n <div className=\"mac-controls\" aria-label={t(\"app.titlebar.windowControls\")}>\n <button\n type=\"button\"\n className=\"mac-ctrl close\"\n title={t(\"app.titlebar.close\")}\n aria-label={t(\"app.titlebar.close\")}\n onMouseDown={(e) => {\n e.stopPropagation();\n win.close();\n }}\n >\n <WinClose />\n </button>\n <button\n type=\"button\"\n className=\"mac-ctrl minimize\"\n title={t(\"app.titlebar.minimize\")}\n aria-label={t(\"app.titlebar.minimize\")}\n onMouseDown={(e) => {\n e.stopPropagation();\n win.minimize();\n }}\n >\n <WinMinimize />\n </button>\n <button\n type=\"button\"\n className=\"mac-ctrl zoom\"\n title={isMaximized ? t(\"app.titlebar.restore\") : t(\"app.titlebar.maximize\")}\n aria-label={isMaximized ? t(\"app.titlebar.restore\") : t(\"app.titlebar.maximize\")}\n onMouseDown={(e) => {\n e.stopPropagation();\n win.toggleMaximize();\n }}\n >\n {isMaximized ? <WinRestore /> : <WinMaximize />}\n </button>\n </div>\n ) : null}\n {/* 移动端汉堡菜单按钮(仅在 xs 断点可见,通过 CSS 控制) */}\n <button\n type=\"button\"\n className=\"tb-mobile-menu\"\n aria-label=\"打开会话列表\"\n aria-expanded={mobileSideOpen}\n onClick={onToggleMobileSide}\n >\n {mobileSideOpen ? <I.x size={18} /> : <I.panel_l size={18} />}\n </button>\n {/* 桌面端侧边栏切换按钮 */}\n <button\n type=\"button\"\n className=\"iconbtn tb-desktop-side-btn\"\n data-on={sideOn}\n title={localizeShortcutText(t(\"app.titlebar.sidebar\"))}\n onClick={onToggleSide}\n >\n <I.panel_l size={14} />\n </button>\n <div className=\"tb-meta\" data-tauri-drag-region>\n <div className=\"brand\" data-tauri-drag-region>\n <span className=\"mark\" />\n <span className=\"brand-name\">Reasonix</span>\n </div>\n {session && (\n <div className=\"crumbs\" data-tauri-drag-region>\n <span className=\"sep\">/</span>\n <span className=\"cur\">{model ?? \"—\"}</span>\n </div>\n )}\n </div>\n </div>\n\n {/* center: drag region */}\n <span className=\"grow\" data-tauri-drag-region />\n\n {/* right: panel toggles + more + window controls */}\n <div className=\"tb-right\">\n <button\n type=\"button\"\n className=\"iconbtn\"\n data-on={ctxOn}\n title={t(\"app.titlebar.contextPanel\")}\n onClick={onToggleCtx}\n >\n <I.panel_r size={14} />\n </button>\n\n <div ref={moreWrapRef} style={{ position: \"relative\" }}>\n <button\n type=\"button\"\n className=\"iconbtn\"\n title={t(\"app.titlebar.more\")}\n onClick={() => setMenuOpen((v) => !v)}\n >\n <I.more size={14} />\n </button>\n {menuOpen ? (\n <div\n className=\"popup\"\n style={{ top: \"calc(100% + 6px)\", right: 0, left: \"auto\", bottom: \"auto\", width: 220 }}\n >\n <div className=\"popup-list\">\n <div className=\"popup-item\" onClick={() => { onOpenCommands(); setMenuOpen(false); }}>\n <span className=\"ico\"><I.search size={12} /></span>\n <div className=\"nm\"><span>{t(\"app.titlebar.commandPalette\")}</span></div>\n <span className=\"kb\">\n <Shortcut keys={[\"mod\", \"K\"]} />\n </span>\n </div>\n <div\n className=\"popup-item\"\n onClick={() => { if (hasMessages) onCopy(); setMenuOpen(false); }}\n style={{ opacity: hasMessages ? 1 : 0.5 }}\n >\n <span className=\"ico\"><I.copy size={12} /></span>\n <div className=\"nm\"><span>{t(\"app.titlebar.copyMd\")}</span></div>\n </div>\n <div\n className=\"popup-item\"\n onClick={() => { if (hasMessages) onExport(); setMenuOpen(false); }}\n style={{ opacity: hasMessages ? 1 : 0.5 }}\n >\n <span className=\"ico\"><I.download size={12} /></span>\n <div className=\"nm\"><span>{t(\"app.titlebar.exportMd\")}</span></div>\n </div>\n <div className=\"popup-item\" onClick={() => { onClear(); setMenuOpen(false); }}>\n <span className=\"ico\"><I.x size={12} /></span>\n <div className=\"nm\"><span>{t(\"app.titlebar.clearChat\")}</span></div>\n </div>\n <div className=\"popup-item\" onClick={() => { onOpenSettings(); setMenuOpen(false); }}>\n <span className=\"ico\"><I.cog size={12} /></span>\n <div className=\"nm\"><span>{t(\"app.titlebar.settings\")}</span></div>\n <span className=\"kb\">\n <Shortcut keys={[\"mod\", \",\"]} />\n </span>\n </div>\n </div>\n </div>\n ) : null}\n </div>\n\n {/* window controls — 仅在非 Web 的原生 Tauri 窗口环境下渲染 */}\n {!isMac && !isWeb ? (\n <div className=\"win-controls\">\n <button\n type=\"button\"\n className=\"win-ctrl\"\n title={t(\"app.titlebar.minimize\")}\n onMouseDown={(e) => { e.stopPropagation(); win.minimize(); }}\n >\n <WinMinimize />\n </button>\n <button\n type=\"button\"\n className=\"win-ctrl\"\n title={isMaximized ? t(\"app.titlebar.restore\") : t(\"app.titlebar.maximize\")}\n onMouseDown={(e) => { e.stopPropagation(); win.toggleMaximize(); }}\n >\n {isMaximized ? <WinRestore /> : <WinMaximize />}\n </button>\n <button\n type=\"button\"\n className=\"win-ctrl close\"\n title={t(\"app.titlebar.close\")}\n onMouseDown={(e) => { e.stopPropagation(); win.close(); }}\n >\n <WinClose />\n </button>\n </div>\n ) : null}\n </div>\n </header>\n );\n}\n\nfunction TabBar({\n tabs,\n activeId,\n setActive,\n onClose,\n onNew,\n singleTab,\n}: {\n tabs: { id: string; workspaceDir?: string }[];\n activeId: string;\n setActive: (id: string) => void;\n onClose: (id: string) => void;\n onNew: () => void;\n singleTab?: boolean;\n}) {\n useLang();\n return (\n <div className=\"tabbar\">\n {tabs.map((t) => {\n const ws = t.workspaceDir ?? \"\";\n const label =\n ws\n .replace(/[\\\\/]$/, \"\")\n .split(/[\\\\/]/)\n .pop() || \"workspace\";\n return (\n <div\n key={t.id}\n className=\"tab\"\n data-active={t.id === activeId}\n onClick={() => setActive(t.id)}\n title={ws || label}\n >\n <span className=\"dot\" data-state=\"running\" />\n <span className=\"label\">{label}</span>\n {!singleTab ? (\n <span\n className=\"close\"\n onClick={(e) => {\n e.stopPropagation();\n onClose(t.id);\n }}\n >\n <I.x size={11} />\n </span>\n ) : null}\n </div>\n );\n })}\n </div>\n );\n}\n\nfunction MainHead({\n session,\n model,\n workspaceDir,\n busy,\n hasMessages,\n onAbort,\n onNewChat,\n onCopy,\n onExport,\n onOpenWorkdir,\n}: {\n session: string;\n model?: string;\n workspaceDir?: string;\n busy: boolean;\n hasMessages: boolean;\n onAbort: () => void;\n onNewChat: () => void;\n onCopy: () => void;\n onExport: () => void;\n onOpenWorkdir: (anchor: { top?: number; bottom?: number; left: number }) => void;\n}) {\n useLang();\n const wsLabel = workspaceDir\n ? workspaceDir.split(/[\\\\/]/).pop() || \"workspace\"\n : t(\"app.header.noWorkspace\");\n return (\n <div className=\"main-head\">\n <div className=\"title-wrap\">\n <h1>\n <span className=\"editable\">{session}</span>\n {busy ? (\n <span className=\"pill\" style={{ color: \"var(--accent)\" }}>\n <span className=\"dot\" />\n <span className=\"shimmer\">{t(\"app.header.running\")}</span>\n </span>\n ) : null}\n </h1>\n <div className=\"sub\">\n <span\n className=\"ws-crumb\"\n onClick={(e) => {\n const r = (e.currentTarget as HTMLElement).getBoundingClientRect();\n onOpenWorkdir({ top: r.bottom + 6, left: r.left });\n }}\n style={{ cursor: \"pointer\" }}\n title={workspaceDir ?? t(\"app.header.clickToSelect\")}\n >\n <I.folder size={10} /> {wsLabel}\n </span>\n {model ? (\n <span className=\"pill\">\n <I.brain size={10} /> {model}\n </span>\n ) : null}\n </div>\n </div>\n <span className=\"grow\" />\n <button\n type=\"button\"\n className=\"h-btn\"\n onClick={onCopy}\n disabled={!hasMessages}\n title={t(\"app.header.copyMd\")}\n >\n <I.copy size={12} /> {t(\"app.header.copy\")}\n </button>\n <button\n type=\"button\"\n className=\"h-btn\"\n onClick={onExport}\n disabled={!hasMessages}\n title={t(\"app.header.exportMd\")}\n >\n <I.download size={12} /> {t(\"app.header.export\")}\n </button>\n <button type=\"button\" className=\"h-btn\" onClick={onNewChat}>\n <I.plus size={12} /> {t(\"app.header.newChat\")}\n </button>\n {busy ? (\n <button type=\"button\" className=\"h-btn primary\" onClick={onAbort}>\n <I.stop size={12} /> {t(\"app.header.abort\")}\n </button>\n ) : null}\n </div>\n );\n}\n\nfunction EmptyState({\n onPick,\n workspaceDir,\n}: {\n onPick: (text: string) => void;\n workspaceDir?: string;\n}) {\n useLang();\n const suggestions = [\n t(\"app.empty.suggestion0\"),\n t(\"app.empty.suggestion1\"),\n t(\"app.empty.suggestion2\"),\n t(\"app.empty.suggestion3\"),\n \"/help\",\n ];\n const wsLabel = workspaceDir ? workspaceDir.split(/[\\\\/]/).pop() : null;\n return (\n <div\n style={{\n padding: \"48px 16px 24px\",\n textAlign: \"center\",\n color: \"var(--muted)\",\n fontFamily: \"var(--font-sans, 'Geist', sans-serif)\",\n }}\n >\n <div\n style={{\n width: 56,\n height: 56,\n borderRadius: 12,\n margin: \"0 auto 14px\",\n background: \"linear-gradient(135deg, var(--accent), var(--violet))\",\n position: \"relative\",\n }}\n >\n <span\n style={{\n position: \"absolute\",\n inset: 8,\n borderRadius: 6,\n background: \"var(--bg)\",\n }}\n />\n </div>\n <div style={{ fontSize: 18, fontWeight: 600, color: \"var(--fg)\", marginBottom: 4 }}>\n {t(\"app.empty.welcome\")}\n </div>\n <div style={{ fontSize: 12, marginBottom: 18 }}>\n {wsLabel ? (\n <>\n {t(\"app.empty.currentWorkspace\")}\n <code style={{ fontFamily: \"Geist Mono, monospace\" }}>{wsLabel}</code>\n </>\n ) : (\n t(\"app.empty.selectWorkspace\")\n )}\n </div>\n <div\n style={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: 8,\n justifyContent: \"center\",\n maxWidth: 540,\n margin: \"0 auto\",\n }}\n >\n {suggestions.map((s) => (\n <button\n key={s}\n type=\"button\"\n className=\"btn\"\n style={{ fontSize: 11.5 }}\n onClick={() => onPick(s)}\n >\n {s}\n </button>\n ))}\n </div>\n </div>\n );\n}\n\nfunction NeedsSetupView({\n workspaceDir,\n onPickWorkspace,\n onSubmit,\n}: {\n workspaceDir?: string;\n onPickWorkspace: () => void;\n onSubmit: (key: string) => void;\n}) {\n useLang();\n const [key, setKey] = useState(\"\");\n return (\n <div\n style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 24,\n gap: 18,\n }}\n >\n <div style={{ fontSize: 18, fontWeight: 600 }}>{t(\"app.setup.welcome\")}</div>\n <div style={{ fontSize: 12.5, color: \"var(--muted)\", maxWidth: 400, textAlign: \"center\" }}>\n {t(\"app.setup.description\")}\n </div>\n <div\n style={{\n width: \"min(420px, 100%)\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 10,\n }}\n >\n <div className=\"setting-row\" style={{ borderBottom: \"none\" }}>\n <div className=\"l\">\n <div className=\"n\">{t(\"app.setup.workspace\")}</div>\n <div className=\"h\">{workspaceDir || t(\"app.setup.notSelected\")}</div>\n </div>\n <button type=\"button\" className=\"btn\" onClick={onPickWorkspace}>\n {t(\"app.setup.choose\")}\n </button>\n </div>\n <input\n className=\"field mono\"\n type=\"password\"\n value={key}\n onChange={(e) => setKey(e.target.value)}\n placeholder=\"sk-…\"\n style={{ width: \"100%\" }}\n />\n <button\n type=\"button\"\n className=\"btn primary\"\n disabled={!key.trim()}\n onClick={() => onSubmit(key.trim())}\n >\n {t(\"app.setup.saveAndStart\")}\n </button>\n </div>\n </div>\n );\n}\n\nfunction formatBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n if (n < 1024 * 1024 * 1024) return `${(n / (1024 * 1024)).toFixed(1)} MB`;\n return `${(n / (1024 * 1024 * 1024)).toFixed(2)} GB`;\n}\n\ntype TabMeta = { id: string; workspaceDir?: string; busy?: boolean };\n\nexport function App() {\n const [tabs, setTabs] = useState<TabMeta[]>([]);\n const [activeTabId, setActiveTabId] = useState<string>(\"\");\n const dispatchersRef = useRef<Map<string, TabDispatcher>>(new Map());\n const pendingEventsRef = useRef<Map<string, TabAction[]>>(new Map());\n const pendingDeltasRef = useRef<Map<string, DeltaBatchItem[]>>(new Map());\n const rafScheduledRef = useRef(false);\n const tabsRef = useRef<TabMeta[]>([]);\n useEffect(() => {\n tabsRef.current = tabs;\n }, [tabs]);\n\n const [currency, setCurrency] = useState<\"CNY\" | \"USD\">(() => {\n const v = localStorage.getItem(\"reasonix.currency\");\n return v === \"USD\" ? \"USD\" : \"CNY\";\n });\n const [theme, setTheme] = useState<Theme>(() => {\n const v = localStorage.getItem(\"reasonix.theme\");\n const style = localStorage.getItem(\"reasonix.themeStyle\");\n if (isThemeStyle(style)) return themeForStyle(style);\n return isTheme(v) ? v : THEME.DARK;\n });\n const [themeStyle, setThemeStyle] = useState<ThemeStyle>(() => {\n const style = localStorage.getItem(\"reasonix.themeStyle\");\n if (isThemeStyle(style)) return style;\n const storedTheme = localStorage.getItem(\"reasonix.theme\");\n return defaultStyleForTheme(isTheme(storedTheme) ? storedTheme : THEME.DARK);\n });\n const [fontScale, setFontScale] = useState<FontScale>(() => {\n const v = localStorage.getItem(\"reasonix.fontScale\");\n return isFontScale(v) ? v : FONT_SCALE.MEDIUM;\n });\n const [fontFamily, setFontFamily] = useState<FontFamily>(() => {\n const v = localStorage.getItem(\"reasonix.fontFamily\");\n return isFontFamily(v) ? v : FONT_FAMILY.SANS;\n });\n const [sideCollapsed, setSideCollapsed] = useState(\n () => localStorage.getItem(\"reasonix.sideCollapsed\") === \"1\",\n );\n const [ctxCollapsed, setCtxCollapsed] = useState(\n () => localStorage.getItem(\"reasonix.ctxCollapsed\") === \"1\",\n );\n\n useEffect(() => {\n document.documentElement.dataset.theme = theme;\n document.documentElement.dataset.themeStyle = themeStyle;\n localStorage.setItem(\"reasonix.theme\", theme);\n localStorage.setItem(\"reasonix.themeStyle\", themeStyle);\n }, [theme, themeStyle]);\n\n useEffect(() => {\n localStorage.setItem(\"reasonix.sideCollapsed\", sideCollapsed ? \"1\" : \"0\");\n }, [sideCollapsed]);\n\n useEffect(() => {\n localStorage.setItem(\"reasonix.ctxCollapsed\", ctxCollapsed ? \"1\" : \"0\");\n }, [ctxCollapsed]);\n\n useEffect(() => {\n // Chromium webview supports `zoom`; scales every px-based size without touching CSS rules.\n document.documentElement.style.setProperty(\"zoom\", String(FONT_SCALE_ZOOM[fontScale]));\n localStorage.setItem(\"reasonix.fontScale\", fontScale);\n }, [fontScale]);\n\n useEffect(() => {\n // CSS rules use var(--font-sans); changing it here re-styles every sans surface in one shot. Mono stays put because code/transcripts hardcode \"Geist Mono\".\n document.documentElement.style.setProperty(\"--font-sans\", FONT_FAMILY_STACK[fontFamily]);\n localStorage.setItem(\"reasonix.fontFamily\", fontFamily);\n }, [fontFamily]);\n\n useEffect(() => {\n const onCur = (e: Event) => {\n const detail = (e as CustomEvent).detail;\n if (detail === \"CNY\" || detail === \"USD\") setCurrency(detail);\n };\n window.addEventListener(\"reasonix:currency\", onCur);\n return () => window.removeEventListener(\"reasonix:currency\", onCur);\n }, []);\n\n const deliverToTab = useCallback((tabId: string, action: TabAction) => {\n const dispatch = dispatchersRef.current.get(tabId);\n if (dispatch) {\n dispatch(action);\n } else {\n const buf = pendingEventsRef.current.get(tabId) ?? [];\n buf.push(action);\n pendingEventsRef.current.set(tabId, buf);\n }\n }, []);\n\n const registerDispatch = useCallback((tabId: string, d: TabDispatcher | null) => {\n if (d) {\n dispatchersRef.current.set(tabId, d);\n const buf = pendingEventsRef.current.get(tabId);\n if (buf && buf.length > 0) {\n for (const action of buf) d(action);\n pendingEventsRef.current.delete(tabId);\n }\n } else {\n dispatchersRef.current.delete(tabId);\n }\n }, []);\n\n useEffect(() => {\n let cancelled = false;\n const cleanups: Array<() => void> = [];\n\n const flushDeltas = () => {\n rafScheduledRef.current = false;\n for (const [tabId, items] of pendingDeltasRef.current) {\n if (items.length === 0) continue;\n deliverToTab(tabId, { t: \"batch_delta\", items });\n pendingDeltasRef.current.set(tabId, []);\n }\n };\n const scheduleFlush = () => {\n if (rafScheduledRef.current || cancelled) return;\n rafScheduledRef.current = true;\n requestAnimationFrame(flushDeltas);\n };\n const flushTabDeltas = (tabId: string) => {\n const bucket = pendingDeltasRef.current.get(tabId);\n if (bucket && bucket.length > 0) {\n deliverToTab(tabId, { t: \"batch_delta\", items: bucket });\n pendingDeltasRef.current.set(tabId, []);\n }\n };\n\n const setup = async () => {\n const subs = await Promise.all([\n listen<{ data: string }>(\"rpc:event\", (e) => {\n try {\n const ev = JSON.parse(e.payload.data) as IncomingEvent;\n const tabId = ev.tabId;\n\n if (ev.type === \"$tab_opened\" && tabId) {\n setTabs((prev) =>\n prev.some((t) => t.id === tabId)\n ? prev\n : [...prev, { id: tabId, workspaceDir: ev.workspaceDir }],\n );\n // Focus the tab the backend marked active (user-opened, or the\n // restored focused tab); otherwise keep focus, but make sure\n // *some* tab is active during a multi-tab restore.\n setActiveTabId((prev) => (ev.active || !prev ? tabId : prev));\n return;\n }\n if (ev.type === \"$tab_closed\" && tabId) {\n setTabs((prev) => prev.filter((t) => t.id !== tabId));\n setActiveTabId((prev) => {\n if (prev !== tabId) return prev;\n const remaining = tabsRef.current.filter((t) => t.id !== tabId);\n return remaining[0]?.id ?? \"\";\n });\n dispatchersRef.current.delete(tabId);\n pendingEventsRef.current.delete(tabId);\n pendingDeltasRef.current.delete(tabId);\n return;\n }\n\n if (ev.type === \"model.delta\" && tabId) {\n if (ev.channel === \"content\" || ev.channel === \"reasoning\") {\n const bucket = pendingDeltasRef.current.get(tabId) ?? [];\n bucket.push({ turn: ev.turn, channel: ev.channel, text: ev.text });\n pendingDeltasRef.current.set(tabId, bucket);\n scheduleFlush();\n return;\n }\n }\n\n if (ev.type === \"$settings\" && tabId) {\n setTabs((prev) =>\n prev.map((t) => (t.id === tabId ? { ...t, workspaceDir: ev.workspaceDir } : t)),\n );\n }\n\n if (ev.type === \"$jobs\") {\n for (const id of dispatchersRef.current.keys()) {\n deliverToTab(id, { t: \"incoming\", event: ev });\n }\n return;\n }\n\n const target = tabId;\n if (target) {\n flushTabDeltas(target);\n if (ev.type === \"$mention_results\") {\n deliverToTab(target, {\n t: \"mention_results\",\n results: { nonce: ev.nonce, query: ev.query, results: ev.results },\n });\n return;\n }\n if (ev.type === \"$mention_preview\") {\n deliverToTab(target, {\n t: \"mention_preview\",\n preview: {\n nonce: ev.nonce,\n path: ev.path,\n head: ev.head,\n totalLines: ev.totalLines,\n },\n });\n return;\n }\n deliverToTab(target, { t: \"incoming\", event: ev });\n }\n } catch {\n console.error(\"bad rpc:event line\", e.payload.data);\n }\n }),\n listen<{ data: string }>(\"rpc:stderr\", (e) => {\n console.warn(\"[reasonix stderr]\", e.payload.data);\n }),\n listen<{ code: number | null }>(\"rpc:exit\", (e) => {\n for (const tabId of dispatchersRef.current.keys()) flushTabDeltas(tabId);\n for (const dispatch of dispatchersRef.current.values()) {\n dispatch({ t: \"rpc_exit\", code: e.payload.code });\n }\n }),\n ]);\n if (cancelled) {\n for (const u of subs) u();\n return;\n }\n cleanups.push(...subs);\n try {\n await invoke(\"rpc_spawn\");\n } catch (err) {\n if (!cancelled) console.error(\"rpc_spawn failed\", err);\n }\n };\n void setup();\n return () => {\n cancelled = true;\n for (const c of cleanups) c();\n };\n }, [deliverToTab]);\n\n // Tell the backend which tab is focused so a restart can reopen on it (#1244).\n useEffect(() => {\n if (!activeTabId) return;\n invoke(\"rpc_send\", {\n line: JSON.stringify({ cmd: \"tab_activate\", tabId: activeTabId }),\n }).catch(() => {});\n }, [activeTabId]);\n\n const openTab = useCallback(() => {\n invoke(\"rpc_send\", { line: JSON.stringify({ cmd: \"tab_open\" }) }).catch((err) =>\n console.error(\"tab_open failed\", err),\n );\n }, []);\n\n const closeTab = useCallback(\n (id: string) => {\n if (tabs.length <= 1) return;\n invoke(\"rpc_send\", { line: JSON.stringify({ cmd: \"tab_close\", tabId: id }) }).catch((err) =>\n console.error(\"tab_close failed\", err),\n );\n },\n [tabs.length],\n );\n\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n const mod = e.ctrlKey || e.metaKey;\n if (mod && (e.key === \"t\" || e.key === \"T\")) {\n e.preventDefault();\n openTab();\n } else if (mod && (e.key === \"w\" || e.key === \"W\") && activeTabId && tabs.length > 1) {\n e.preventDefault();\n closeTab(activeTabId);\n } else if (mod && e.key === \"Tab\") {\n if (tabs.length <= 1) return;\n e.preventDefault();\n const idx = tabs.findIndex((t) => t.id === activeTabId);\n const next = e.shiftKey ? (idx - 1 + tabs.length) % tabs.length : (idx + 1) % tabs.length;\n const target = tabs[next];\n if (target) setActiveTabId(target.id);\n } else if (mod && (e.key === \"b\" || e.key === \"B\")) {\n if (e.altKey) {\n e.preventDefault();\n setCtxCollapsed((v) => !v);\n } else {\n e.preventDefault();\n setSideCollapsed((v) => !v);\n }\n }\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [openTab, closeTab, activeTabId, tabs]);\n\n const onSetTheme = useCallback((nextTheme: Theme) => {\n setTheme(nextTheme);\n setThemeStyle(defaultStyleForTheme(nextTheme));\n }, []);\n\n const onSetThemeStyle = useCallback((nextStyle: ThemeStyle) => {\n setThemeStyle(nextStyle);\n setTheme(themeForStyle(nextStyle));\n }, []);\n\n const onToggleTheme = useCallback(() => {\n onSetTheme(theme === THEME.DARK ? THEME.LIGHT : THEME.DARK);\n }, [onSetTheme, theme]);\n\n const [mobileSideOpen, setMobileSideOpen] = useState(false);\n const onToggleMobileSide = useCallback(() => setMobileSideOpen((v) => !v), []);\n\n const onToggleCurrency = useCallback(() => {\n setCurrency((c) => {\n const next = c === \"CNY\" ? \"USD\" : \"CNY\";\n localStorage.setItem(\"reasonix.currency\", next);\n window.dispatchEvent(new CustomEvent(\"reasonix:currency\", { detail: next }));\n return next;\n });\n }, []);\n\n return (\n <>\n {tabs.map((t) => (\n <TabRuntime\n key={t.id}\n tabId={t.id}\n active={t.id === activeTabId}\n currency={currency}\n registerDispatch={registerDispatch}\n onNewTab={openTab}\n onCloseTab={() => closeTab(t.id)}\n canCloseTab={tabs.length > 1}\n theme={theme}\n themeStyle={themeStyle}\n onSetTheme={onSetTheme}\n onSetThemeStyle={onSetThemeStyle}\n onToggleTheme={onToggleTheme}\n fontScale={fontScale}\n onSetFontScale={setFontScale}\n fontFamily={fontFamily}\n onSetFontFamily={setFontFamily}\n sideCollapsed={sideCollapsed}\n ctxCollapsed={ctxCollapsed}\n onToggleSide={() => setSideCollapsed((v) => !v)}\n onToggleCtx={() => setCtxCollapsed((v) => !v)}\n onToggleCurrency={onToggleCurrency}\n mobileSideOpen={mobileSideOpen}\n onToggleMobileSide={onToggleMobileSide}\n tabsList={tabs}\n activeTabId={activeTabId}\n setActiveTabId={setActiveTabId}\n />\n ))}\n </>\n );\n}\n","import \"@fontsource/geist/400.css\";\nimport \"@fontsource/geist/500.css\";\nimport \"@fontsource/geist/600.css\";\nimport \"@fontsource/geist/700.css\";\nimport \"@fontsource/geist-mono/400.css\";\nimport \"@fontsource/geist-mono/500.css\";\nimport \"@fontsource/geist-mono/600.css\";\nimport \"@fontsource/inter/400.css\";\nimport \"@fontsource/inter/500.css\";\nimport \"@fontsource/inter/600.css\";\nimport \"@fontsource/inter/700.css\";\nimport \"./styles.css\";\nimport \"katex/dist/katex.min.css\";\nimport { createRoot } from \"react-dom/client\";\nimport { App } from \"./App\";\nimport {\n defaultStyleForTheme,\n isTheme,\n isThemeStyle,\n themeForStyle,\n} from \"./theme\";\n\nconst stored = localStorage.getItem(\"reasonix.theme\");\nconst storedStyle = localStorage.getItem(\"reasonix.themeStyle\");\nif (isThemeStyle(storedStyle)) {\n document.documentElement.dataset.themeStyle = storedStyle;\n document.documentElement.dataset.theme = themeForStyle(storedStyle);\n} else if (isTheme(stored)) {\n document.documentElement.dataset.theme = stored;\n document.documentElement.dataset.themeStyle = defaultStyleForTheme(stored);\n}\n\nconst platform = /Mac|macOS/i.test(navigator.userAgent)\n ? \"macos\"\n : /Windows/i.test(navigator.userAgent)\n ? \"windows\"\n : \"default\";\ndocument.documentElement.dataset.platform = platform;\ndocument.body.dataset.platform = platform;\n\nconst host = document.getElementById(\"root\");\nif (!host) throw new Error(\"#root missing\");\n\ncreateRoot(host).render(<App />);\n"],"file":"app.js"}
|