@forsion/extend 0.4.0 → 0.5.1
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/CHANGELOG.md +36 -0
- package/README.md +35 -15
- package/SIGNATURE +8 -7
- package/dist/THIRD_PARTY_NOTICES.md +144 -0
- package/dist/desktop.mjs +8 -8
- package/dist/main.js +179 -1
- package/manifest.json +3 -3
- package/package.json +6 -2
package/dist/desktop.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
function Tn(
|
|
2
|
-
`,"utf8")}catch{}}function Nn(
|
|
1
|
+
function Tn(t,e){if(typeof e!="string"||!e.startsWith("/"))return null;let n=String(t||"").replace(/\/+$/,"").replace(/\/api$/,"");if(!n)return null;let s,r;try{s=new URL(n),r=new URL(n+"/api"+e)}catch{return null}return s.protocol!=="http:"&&s.protocol!=="https:"||r.origin!==s.origin||!r.pathname.startsWith("/api/")?null:r.toString()}async function de(t,e,n,s,r=6e4){let o=await fetch(t.base+n,{method:e,headers:{"Content-Type":"application/json","X-Project-Source":"connect",...t.token?{Authorization:`Bearer ${t.token}`}:{}},body:s===void 0?void 0:JSON.stringify(s),signal:AbortSignal.timeout(r)}),a=await o.json().catch(()=>({}));return{status:o.status,json:a}}import{readdirSync as Gr,lstatSync as Yr,readFileSync as Ft,writeFileSync as Jr,realpathSync as Rn}from"node:fs";import{join as Lt,extname as Kr,sep as Xr}from"node:path";var Ot=300,In=5*1024*1024,An=20*1024*1024,Qr=50*1024*1024,Zr=new Set(["node_modules"]),es=new Set([".ts",".tsx",".jsx",".mts",".cts"]);function Pn(t,e){let n=[],s=0,r=(o,a)=>{for(let c of Gr(o)){if(c.startsWith("."))continue;let l=Lt(o,c),m;try{m=Yr(l)}catch{continue}if(m.isSymbolicLink())continue;let d=a?`${a}/${c}`:c;if(m.isDirectory()){Zr.has(c)||r(l,d);continue}if(!m.isFile()||c.endsWith(".d.ts"))continue;if(n.length>=Ot)throw new Error(`\u6587\u4EF6\u6570\u8D85\u8FC7 ${Ot}\uFF0C\u8BF7\u7CBE\u7B80\u9879\u76EE\uFF08node_modules \u4E0E\u9690\u85CF\u6587\u4EF6\u5DF2\u81EA\u52A8\u8DF3\u8FC7\uFF09`);let f=Kr(c).toLowerCase(),u,y=e.mimeOf(f)??"application/octet-stream";if(es.has(f)){let _=e.transpile(Ft(l,"utf8"),f,d);u=Buffer.from(_??"","utf8"),y="text/javascript"}else u=Ft(l);if(u.length>In)throw new Error(`\u5355\u6587\u4EF6\u8D85\u8FC7 5MB\uFF1A${d}`);if(s+=u.length,s>An)throw new Error("\u9879\u76EE\u603B\u5927\u5C0F\u8D85\u8FC7 20MB\uFF0C\u65E0\u6CD5\u53D1\u5E03");n.push({path:d,content_b64:u.toString("base64"),content_type:y,size:u.length})}};if(r(t,""),!n.length)throw new Error("\u9879\u76EE\u4E3A\u7A7A\uFF0C\u6CA1\u6709\u53EF\u53D1\u5E03\u7684\u6587\u4EF6");return{files:n,totalBytes:s}}var Dn=".forsion-connect.json";function $n(t){try{return JSON.parse(Ft(Lt(t,Dn),"utf8"))}catch{return{}}}function Mn(t,e){try{Jr(Lt(t,Dn),JSON.stringify(e,null,2)+`
|
|
2
|
+
`,"utf8")}catch{}}function Nn(t){let e={"/__forsion/chat":{method:"POST",path:"/api/chat/completions",auth:!0},"/__forsion/images":{method:"POST",path:"/api/images/generations",auth:!0},"/__forsion/user":{method:"GET",path:"/api/brain/users/me",auth:!0},"/__forsion/models":{method:"GET",path:"/api/models",auth:!1},"/__forsion/config":{method:"GET",path:"/api/connect/config",auth:!1},"/__forsion/agent":{method:"POST",path:"/api/agent/runs",auth:!0,agentRun:!0}};function n(s){if(e[s])return e[s];let r="/__forsion/agent-events/";if(s.startsWith(r)){let o=s.slice(r.length);if(/^[A-Za-z0-9-]{1,64}$/.test(o))return{method:"GET",path:`/api/agent/runs/${o}/events`,auth:!0,timeoutMs:9e5}}}return async(s,r)=>{let[o,a]=(s.url||"").split("?"),c=(_,T)=>{r.headersSent||(r.statusCode=_,r.setHeader("Content-Type","application/json")),r.end(JSON.stringify({detail:T}))},l=n(o);if(!l)return c(404,"unknown connect endpoint");if((s.method||"GET")!==l.method)return c(405,"method not allowed");let m="",d="";try{({base:m,token:d}=await t())}catch{}if(!m)return c(502,"\u672A\u914D\u7F6E Forsion \u4E91\u7AEF\u5730\u5740");if(l.auth&&!d)return c(401,"\u8BF7\u5148\u5728 Forsion Desktop \u4E2D\u767B\u5F55 Forsion \u8D26\u53F7");let f;if(l.method==="POST"){let _=[],T=0;try{for await(let v of s){if(T+=v.length,T>Qr)return s.destroy(),c(413,"\u8BF7\u6C42\u4F53\u8FC7\u5927");_.push(v)}}catch(v){return c(400,`\u8BF7\u6C42\u4F53\u8BFB\u53D6\u5931\u8D25\uFF1A${v?.message||String(v)}`)}f=Buffer.concat(_)}if(l.agentRun){let _;try{_=JSON.parse((f||Buffer.alloc(0)).toString("utf8")||"{}")}catch{return c(400,"agent \u8BF7\u6C42\u4F53\u5FC5\u987B\u662F JSON")}f=Buffer.from(JSON.stringify({session_id:typeof _.session_id=="string"?_.session_id:"",message:typeof _.message=="string"?_.message:"",app_id:"connect",agent_config:{}}))}let u=new AbortController,y=setTimeout(()=>u.abort(new Error("proxy timeout")),l.timeoutMs??3e5);s.on("close",()=>u.abort());try{let _=await fetch(m+l.path+(a?`?${a}`:""),{method:l.method,headers:{"Content-Type":"application/json","X-Project-Source":"connect",...d?{Authorization:`Bearer ${d}`}:{}},body:f&&f.length?new Uint8Array(f):void 0,signal:u.signal});if(r.statusCode=_.status,r.setHeader("Content-Type",_.headers.get("content-type")||"application/json"),r.setHeader("Cache-Control","no-store"),_.body)for await(let T of _.body)r.write(T);r.end()}catch(_){let T=`\u4E91\u7AEF\u8BF7\u6C42\u4E2D\u65AD\uFF1A${_?.message||String(_)}`;if(r.headersSent){try{r.write(`data: ${JSON.stringify({error:T})}
|
|
3
3
|
|
|
4
|
-
`)}catch{}r.end()}else c(502,
|
|
4
|
+
`)}catch{}r.end()}else c(502,T)}finally{clearTimeout(y)}}}var Fn=`
|
|
5
5
|
(function () {
|
|
6
6
|
'use strict';
|
|
7
7
|
if (window.forsion) return;
|
|
@@ -190,13 +190,13 @@ function Tn(n,e){if(typeof e!="string"||!e.startsWith("/"))return null;let t=Str
|
|
|
190
190
|
ai: { chat: chat, agent: agentRun, generateImage: generateImage }
|
|
191
191
|
};
|
|
192
192
|
})();
|
|
193
|
-
`,es=n=>({transpile:(e,t,s)=>n.transpileForServe(e,t,s),mimeOf:e=>n.mimeOf(e)});function jt(n){let e=n;return typeof e.projectsRoot=="function"&&typeof e.transpileForServe=="function"&&typeof e.mimeOf=="function"&&typeof e.setPreviewHooks=="function"}function Ut(n){n.setPreviewHooks({sdkJs:Fn,proxy:Nn(()=>n.getCloud())}),n.handle("connect:meta",(e,t)=>typeof t=="string"&&t?$n(t):{}),n.handle("connect:list",async()=>{let e=await n.getCloud();if(!e.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:t,json:s}=await me(e,"GET","/api/connect/apps");return t===401||t===403?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:t!==200?{ok:!1,code:"error",detail:s?.detail||`HTTP ${t}`}:{ok:!0,base:e.base,...s}}catch(t){return{ok:!1,code:"error",detail:t?.message||String(t)}}}),n.handle("connect:publish",async(e,t)=>{if(!t||typeof t.dir!="string"||!t.dir||!t.name||!t.slug||!t.entry)return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let s;try{let o=Rn(n.projectsRoot());if(s=Rn(t.dir),s!==o&&!s.startsWith(o+Kr))return{ok:!1,code:"error",detail:"\u53EA\u80FD\u53D1\u5E03 Coding Space \u9879\u76EE\u76EE\u5F55"}}catch{return{ok:!1,code:"error",detail:"\u9879\u76EE\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6CD5\u8BBF\u95EE"}}let r=await n.getCloud();if(!r.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{files:o,totalBytes:a}=Pn(s,es(n));if(!o.some(h=>h.path===t.entry))return{ok:!1,code:"error",detail:`\u5165\u53E3\u6587\u4EF6\u4E0D\u5B58\u5728:${t.entry}`};let{status:c,json:l}=await me(r,"POST","/api/connect/apps",{slug:t.slug,name:t.name,entry:t.entry,files:o},3e5);return c===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:c!==200?{ok:!1,code:l?.code||"error",detail:l?.detail||`HTTP ${c}`,used:l?.used,limit:l?.limit}:(Mn(s,{slug:String(l.slug)}),{ok:!0,slug:l.slug,handle:l.handle,url:`${r.base}${l.url}`,totalBytes:a})}catch(o){return{ok:!1,code:"error",detail:o?.message||String(o)}}}),n.handle("connect:unpublish",async(e,t)=>{if(!t||typeof t!="string")return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let s=await n.getCloud();if(!s.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:r,json:o}=await me(s,"DELETE",`/api/connect/apps/${encodeURIComponent(t)}`);return r===401||r===403?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:r!==200&&r!==404?{ok:!1,code:"error",detail:o?.detail||`HTTP ${r}`}:{ok:!0}}catch(r){return{ok:!1,code:"error",detail:r?.message||String(r)}}}),n.handle("connect:listingApply",async(e,t)=>{if(!t||typeof t.slug!="string"||!t.slug||typeof t.summary!="string"||!t.summary.trim())return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let s=await n.getCloud();if(!s.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:r,json:o}=await me(s,"PUT",`/api/connect/apps/${encodeURIComponent(t.slug)}/listing`,{summary:t.summary});return r===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:r!==200?{ok:!1,code:o?.code||"error",detail:o?.detail||`HTTP ${r}`}:{ok:!0,status:o.status}}catch(r){return{ok:!1,code:"error",detail:r?.message||String(r)}}}),n.handle("connect:listingWithdraw",async(e,t)=>{if(!t||typeof t!="string")return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let s=await n.getCloud();if(!s.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:r,json:o}=await me(s,"DELETE",`/api/connect/apps/${encodeURIComponent(t)}/listing`);return r===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:r!==200&&r!==404?{ok:!1,code:"error",detail:o?.detail||`HTTP ${r}`}:{ok:!0}}catch(r){return{ok:!1,code:"error",detail:r?.message||String(r)}}}),n.handle("connect:store",async()=>{let e=await n.getCloud();try{let{status:t,json:s}=await me(e,"GET","/api/connect/store");return t!==200?{ok:!1,detail:s?.detail||`HTTP ${t}`}:{ok:!0,base:e.base,items:Array.isArray(s.items)?s.items:[]}}catch(t){return{ok:!1,detail:t?.message||String(t)}}}),n.log("[forsion-extend] connect handlers registered")}import{createHash as ts}from"node:crypto";async function nt(n,e){if(!n||!e)return{status:"offline"};let t=n.replace(/\/+$/,"");try{let s=await fetch(`${t}/api/brain/users/me`,{headers:{Authorization:`Bearer ${e}`},signal:AbortSignal.timeout(5e3)});if(s.status===401||s.status===403)return{status:(s.headers.get("content-type")||"").includes("application/json")?"expired":"offline"};if(!s.ok)return{status:"offline"};let r=await s.json();if(!r)return{status:"offline"};let o=r.avatar||r.avatarUrl||r.avatar_url||void 0;return o&&/^\/(?!\/)/.test(o)&&(o=t+o),{status:"ok",user:{username:r.username||r.nickname||void 0,nickname:r.nickname||void 0,avatar:o,membershipTier:r.membershipTier||r.membership_tier||void 0}}}catch{return{status:"offline"}}}var On=n=>`${n.seq}:${n.hash}`,ns=n=>ts("sha256").update(n).digest("hex");function Ht(n){if(n===null)return{baseSeq:0,baseHash:null};if(typeof n!="string")return;let e=n.indexOf(":"),t=Number(e===-1?n:n.slice(0,e));if(!Number.isInteger(t)||t<=0)return;let s=e===-1?"":n.slice(e+1);return{baseSeq:t,baseHash:/^[0-9a-f]{64}$/.test(s)?s:null}}function jn(n){let e=n.baseUrl.replace(/\/+$/,""),t=r=>`${e}/api/remotesync/vaults/${encodeURIComponent(n.vault)}${r}`,s=async(r,o)=>{let a=n.getToken();if(!a)throw new Error("penzor-not-logged-in");let c=await fetch(r,{...o,headers:{...o.headers,Authorization:`Bearer ${a}`}});if(c.status===409){let l=await c.json().catch(()=>({}));throw new Error(`cas-conflict ${String(l.code??"")}: seq=${String(l.seq??"?")}`)}if(!c.ok){let l=await c.text().catch(()=>"");throw new Error(`penzor ${o.method??"GET"} ${c.status}: ${l.slice(0,200)}`)}return c};return{kind:"penzor",async walk(r){let o=await s(t("/manifest"),{method:"GET",signal:r}),{files:a}=await o.json();return a.map(c=>({key:c.path,size:c.size,mtimeMs:c.mtimeMs,id:On(c)}))},async readFile(r,o){let c=await(await s(t(`/file?path=${encodeURIComponent(r)}`),{method:"GET",signal:o})).json(),l=await fetch(c.url,{signal:o});if(!l.ok)throw new Error(`penzor blob GET ${l.status}: ${r}`);let h=Buffer.from(await l.arrayBuffer());if(ns(h)!==c.hash)throw new Error(`penzor hash mismatch: ${r}`);return h},async writeFile(r,o,a,c,l){let h=Ht(l),f=new URLSearchParams({path:r,mtimeMs:String(Math.floor(a)||0)});h&&(f.set("baseSeq",String(h.baseSeq)),h.baseHash&&f.set("baseHash",h.baseHash));let u=await(await s(t(`/file?${f.toString()}`),{method:"PUT",body:new Uint8Array(o),headers:{"Content-Type":"application/octet-stream"},signal:c})).json();return{key:r,size:u.size,mtimeMs:u.mtimeMs,id:On(u)}},async rm(r,o,a){let c=Ht(a),l=new URLSearchParams({path:r});c&&c.baseSeq>0&&(l.set("baseSeq",String(c.baseSeq)),c.baseHash&&l.set("baseHash",c.baseHash)),await s(t(`/file?${l.toString()}`),{method:"DELETE",signal:o})},async check(){try{return await s(t("/manifest"),{method:"GET"}),{ok:!0}}catch(r){return{ok:!1,error:String(r?.message||r)}}}}}var Un=50*1024*1024,Ln=new Map;async function rs(n,e){let t=Ln.get(e);if(t)return{id:t};let s=await nt(n,e);if(s.status==="offline")return{error:"penzor-offline"};if(s.status!=="ok")return{error:"penzor-not-logged-in"};let r=s.user?.username?.trim();return r?(Ln.set(e,r),{id:r}):{error:"penzor-auth-unverified"}}var zt=n=>typeof n.registerRemoteSyncBackend=="function"&&typeof n.readCreds=="function";function qt(n){n.registerRemoteSyncBackend("penzor",async e=>{let t=n.readCreds();if(!t.token||!t.cloudUrl)return{error:"penzor-not-logged-in"};let s=e?.vault,r=(typeof s=="string"?s:"default").trim()||"default";if(!/^[A-Za-z0-9_-]{1,64}$/.test(r))return{error:"penzor-bad-vault"};let o=await rs(t.cloudUrl,t.token);if("error"in o)return o;let a=t.token;return{remote:jn({baseUrl:t.cloudUrl,vault:r,getToken:()=>a}),fingerprint:`penzor:${t.cloudUrl.replace(/\/+$/,"")}|u:${o.id}|${r}`,maxFileBytes:Un}}),n.log('[forsion-extend] remote-sync backend "penzor" registered')}import{readFileSync as ss,writeFileSync as os,mkdirSync as is,chmodSync as as,renameSync as ls}from"node:fs";import{join as cs}from"node:path";function Se(n,e){try{let t=new URL(n);if(t.protocol!=="https:"&&t.protocol!=="http:")return null;let s=e.split(".")[1];if(!s)return null;let r=s.replace(/-/g,"+").replace(/_/g,"/"),o=Uint8Array.from(atob(r),l=>l.charCodeAt(0)),a=JSON.parse(new TextDecoder().decode(o)),c=a.userId??a.sub;return typeof c!="string"&&typeof c!="number"||!String(c).trim()?null:`${t.origin}${t.pathname.replace(/\/+$/,"")}::${String(c)}`}catch{return null}}function Wt(n){try{let e=n.split(".")[1];if(!e)return null;let t=JSON.parse(Buffer.from(e,"base64url").toString("utf8"));return t&&typeof t=="object"?t:null}catch{return null}}function zn(n,e=Date.now()){let t=Wt(n)?.iat;return typeof t=="number"?e-t*1e3:1/0}function us(n,e=Date.now()){let t=Wt(n)?.exp;return typeof t=="number"?t*1e3-e:1/0}var ds=36e5;function qn(n,e=Date.now()){return!!n&&zn(n,e)>=ds}async function Wn(n,e,t=8e3,s){if(!n||!e)return null;let r=n.replace(/\/+$/,"");try{let o=await fetch(`${r}/api/auth/refresh`,{method:"POST",headers:{Authorization:`Bearer ${e}`,...s?{"X-Forsion-Client":s}:{}},signal:AbortSignal.timeout(t)});if(!o.ok)return null;let a=await o.json().catch(()=>null),c=typeof a?.token=="string"?a.token:"";return c&&c!==e?c:null}catch{return null}}var bt=(n,e)=>`${n.replace(/\/+$/,"")}\0${e}`,fs=(n,e)=>new Promise((t,s)=>{let r=()=>{clearTimeout(o),s(new Error("Sign-in cancelled."))},o=setTimeout(()=>{e.removeEventListener("abort",r),t()},n);e.aborted?r():e.addEventListener("abort",r,{once:!0})});function Bn(n){let e=()=>cs(n.homeDir(),"auth-accounts.json"),t=(m,u)=>{is(n.homeDir(),{recursive:!0});let w=`${m}.tmp`;os(w,JSON.stringify(u,null,2),{encoding:"utf8",mode:384}),as(w,384),ls(w,m)},s=()=>{try{let m=JSON.parse(ss(e(),"utf8"));return Array.isArray(m.accounts)?m.accounts.filter(u=>u&&typeof u.token=="string"&&u.id===Se(u.cloudUrl,u.token)):[]}catch{return[]}},r=(m,u)=>{let w=Se(m.cloudUrl||"",m.token||"");if(!w||!m.token||!m.cloudUrl)return;let v=s(),R=v.find(j=>j.id===w),_=Wt(m.token),L={...R,id:w,cloudUrl:m.cloudUrl.replace(/\/+$/,""),token:m.token,username:u?.username||R?.username||_?.username,nickname:u?.nickname||R?.nickname};JSON.stringify(R)!==JSON.stringify(L)&&t(e(),{version:1,accounts:[...v.filter(j=>j.id!==w),L]})},o=()=>{let m=n.readCreds();r(m);let u=Se(m.cloudUrl,m.token);return s().map(({token:w,...v})=>({...v,active:v.id===u}))},a=m=>{let u=s().find(w=>w.id===m);if(!u)throw new Error("Account is no longer signed in. Sign in again.");return{cloudUrl:u.cloudUrl,token:u.token}},c=m=>{let u=Se(m.cloudUrl||"",m.token||"");u&&t(e(),{version:1,accounts:s().filter(w=>w.id!==u)})},l=null;return{rememberForsionAccount:r,forsionAccounts:o,savedForsionAccount:a,forgetForsionAccount:c,cancelForsionLogin:()=>{l?.abort(),l=null},forsionDeviceLogin:async(m,u,w)=>{if(l)throw new Error("A sign-in is already in progress.");if(!m)throw new Error("\u8BF7\u5148\u586B\u5199 Forsion \u4E91\u7AEF\u5730\u5740(\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF TANGU_CLOUD_URL)");let v=new AbortController;l=v;let R=()=>{if(v.signal.aborted||l!==v)throw new Error("Sign-in cancelled.")};try{let _=m.replace(/\/+$/,""),L;try{L=await fetch(`${_}/api/auth/cli/start`,{method:"POST",headers:{"Content-Type":"application/json"},body:"{}",signal:AbortSignal.any([v.signal,AbortSignal.timeout(15e3)])}).then(Y=>Y.json())}catch(Y){throw new Error(`\u65E0\u6CD5\u8FDE\u63A5 ${_}:${Y?.message||Y}`)}if(R(),!L?.device_code)throw new Error("\u4E91\u7AEF\u4E0D\u652F\u6301 CLI \u767B\u5F55(/api/auth/cli/start \u8FD4\u56DE\u5F02\u5E38)");let j=L.verification_uri_complete||`${L.verification_uri}?code=${L.user_code}`,te=new URL(`${_}/auth`);te.searchParams.set("logout","1"),te.searchParams.set("app","forsion-desktop"),te.searchParams.set("redirect",j);let G=te.toString();u?.({url:G,userCode:String(L.user_code||"")}),n.openExternal(G);let B=Date.now()+(L.expires_in||600)*1e3,X=(L.interval||2)*1e3;for(;Date.now()<B;){await fs(X,v.signal),R();let Y=null;try{Y=await fetch(`${_}/api/auth/cli/poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({device_code:L.device_code}),signal:AbortSignal.any([v.signal,AbortSignal.timeout(15e3)])})}catch{R();continue}if(R(),Y.status===410)throw new Error("\u767B\u5F55\u7801\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u53D1\u8D77\u767B\u5F55");let ne=await Y.json().catch(()=>({status:"pending"}));if(R(),ne.status==="approved"&&ne.token){let ue={cloudUrl:_,token:ne.token};return await w(ue,R),R(),{token:ne.token,cloudUrl:_}}}throw new Error("\u767B\u5F55\u8D85\u65F6,\u8BF7\u91CD\u8BD5")}finally{l===v&&(l=null)}},readAccounts:s}}var Vn=["homeDir","appVersion","broadcast","accountBackendState","accountTransition","accountCommit","accountClear","writeCreds","onExternalCredsChange","setTokenRefresher","readCreds"],Bt=n=>Vn.every(e=>typeof n[e]=="function");function Vt(n){let e=Bn(n),t=0,s=()=>{let o=n.readCreds();return bt(o.cloudUrl,o.token)},r=null;n.handle("auth:status",async()=>{let o=t,a=s(),{base:c}=await n.getCloud(),l=n.readCreds().token,h=l?await nt(c,l):null,f=await n.accountBackendState(),{base:m}=await n.getCloud(),u=n.readCreds(),w=bt(m,u.token)!==bt(c,l),v=bt(c,l);!w&&h?.status==="ok"&&h.user&&(r={key:v,user:h.user},e.rememberForsionAccount({...u,cloudUrl:c},h.user));let R=w?void 0:h?.status==="ok"?h.user:h?.status==="offline"&&r?.key===v?r.user:void 0;if(w)return{loggedIn:!!u.token,tokenValid:null,cloudUrl:m,accountId:Se(m,u.token),username:null,nickname:null,avatar:null,membershipTier:null,tokenSource:u.token?"tangu-login":null,backendState:f};if(h?.status==="expired"){await n.accountTransition(async()=>{if(o!==t||s()!==a)return;let L=()=>{if(o!==t||s()!==a)throw Hn};try{await n.accountClear(L,()=>{n.log("[auth] token \u5DF2\u5931\u6548(\u670D\u52A1\u7AEF 401/403),\u81EA\u52A8\u767B\u51FA"),++t,e.cancelForsionLogin(),e.forgetForsionAccount(n.readCreds()),r=null})}catch(j){if(j!==Hn)throw j}});let _=n.readCreds();return{loggedIn:!!_.token,tokenValid:null,cloudUrl:_.cloudUrl||c,accountId:Se(_.cloudUrl||c,_.token),username:null,nickname:null,avatar:null,membershipTier:null,tokenSource:_.token?"tangu-login":null,backendState:f}}return{loggedIn:!!l,tokenValid:h&&h.status==="ok"?!0:null,cloudUrl:c,accountId:Se(c,l),username:R?.username||null,nickname:R?.nickname||null,avatar:R?.avatar||null,membershipTier:R?.membershipTier||null,tokenSource:l?"tangu-login":null,backendState:f}}),n.handle("auth:accounts",()=>e.forsionAccounts()),n.handle("auth:switchAccount",async(o,a)=>{if(typeof a!="string")throw new Error("Invalid account.");let c=++t;return e.cancelForsionLogin(),n.accountTransition(async()=>{let l=e.savedForsionAccount(a);return await n.accountCommit(l,()=>{if(c!==t)throw new Error("Account switch cancelled.")},()=>{e.rememberForsionAccount(l),r=null}),{ok:!0,cloudUrl:l.cloudUrl||""}})}),n.handle("auth:forsionLogin",async(o,a)=>{let c=++t;e.cancelForsionLogin();let{base:l}=await n.getCloud();if(c!==t)throw new Error("Sign-in cancelled.");let h=(a||l||"").trim();return{ok:!0,cloudUrl:(await e.forsionDeviceLogin(h,m=>n.broadcast("auth:device",m),(m,u)=>n.accountTransition(()=>n.accountCommit(m,()=>{if(u(),c!==t)throw new Error("Sign-in cancelled.")},()=>{e.rememberForsionAccount(m),r=null})))).cloudUrl}}),n.handle("auth:logout",async()=>(++t,e.cancelForsionLogin(),n.accountTransition(async()=>{let{base:o}=await n.getCloud(),a=n.readCreds();return await n.accountClear(void 0,()=>{e.forgetForsionAccount(a),r=null,o&&a.token&&fetch(`${o}/api/auth/logout`,{method:"POST",headers:{Authorization:`Bearer ${a.token}`},signal:AbortSignal.timeout(5e3)}).catch(()=>{})}),{ok:!0}}))),n.onExternalCredsChange(({previous:o,current:a})=>{++t,e.cancelForsionLogin(),o.token&&!a.token&&e.forgetForsionAccount(o),r=null,e.rememberForsionAccount(a)}),n.setTokenRefresher(async o=>{let a=t,c=s(),l=n.readCreds().token;if(!qn(l))return;let{base:h}=await n.getCloud(),f=await Wn(h,l,o,`desktop/${n.appVersion()}`);if(!f){n.log("[auth] \u6ED1\u52A8\u7EED\u671F\u672A\u6210\u529F(\u79BB\u7EBF/\u8001\u7248\u672C server/\u8FD9\u679A\u5DF2\u5931\u6548),\u7EE7\u7EED\u7528\u65E7 token");return}a!==t||s()!==c||(e.rememberForsionAccount({cloudUrl:h,token:f}),n.writeCreds({cloudUrl:h,token:f}),n.log("[auth] \u767B\u5F55\u6001\u5DF2\u6ED1\u52A8\u7EED\u671F(\u6709\u6548\u671F\u91CD\u65B0\u8BA1\u6EE1 2 \u5468)"))}),n.log("[forsion-extend] account core registered")}var Hn=Symbol("stale-auth-intent");import{promises as Xe}from"node:fs";import je from"node:path";import{createHash as hs}from"node:crypto";var Gt=null;function Gn(n){Gt=n}function de(){if(!Gt)throw new Error("amadeus sync env not set (registerAmadeus factory has not run)");return Gt}var fe=()=>de().accountId();function rt(n=fe()){return n?hs("sha256").update(n).digest("hex"):"signed-out"}var Ee=(n=fe())=>de().readConfig(n),Ae=(n,e=fe())=>de().writeConfig(n,e),qe=(n,e=fe())=>de().updateConfig(n,e),De=(n=fe())=>de().cloudVaultDir(n),St=n=>de().isManagedCloudVault(n);import{createHash as wo}from"node:crypto";import{promises as ee,existsSync as Cr}from"node:fs";import se from"node:path";import{EventEmitter as zs}from"node:events";import{stat as qs}from"node:fs";import{readdir as Ws,stat as Bs}from"node:fs/promises";import*as z from"node:path";import{lstat as Yn,readdir as ms,realpath as ps,stat as gs}from"node:fs/promises";import{join as ys,resolve as ws,sep as Jn}from"node:path";import{Readable as bs}from"node:stream";var pe={FILE_TYPE:"files",DIR_TYPE:"directories",FILE_DIR_TYPE:"files_directories",EVERYTHING_TYPE:"all"},We={root:".",fileFilter:n=>!0,directoryFilter:n=>!0,type:pe.FILE_TYPE,lstat:!1,depth:2147483648,alwaysStat:!1,highWaterMark:256};Object.freeze(We);var Zn="READDIRP_RECURSIVE_ERROR",Ss=new Set(["ENOENT","EPERM","EACCES","ELOOP",Zn]),Kn=[pe.DIR_TYPE,pe.EVERYTHING_TYPE,pe.FILE_DIR_TYPE,pe.FILE_TYPE],Es=new Set([pe.DIR_TYPE,pe.EVERYTHING_TYPE,pe.FILE_DIR_TYPE]),vs=new Set([pe.EVERYTHING_TYPE,pe.FILE_DIR_TYPE,pe.FILE_TYPE]),_s=n=>Ss.has(n.code),ks=process.platform==="win32",Xn=n=>!0,Qn=n=>{if(n===void 0)return Xn;if(typeof n=="function")return n;if(typeof n=="string"){let e=n.trim();return t=>t.basename===e}if(Array.isArray(n)){let e=n.map(t=>t.trim());return t=>e.some(s=>t.basename===s)}return Xn},Yt=class extends bs{parents;reading;parent;_stat;_maxDepth;_wantsDir;_wantsFile;_wantsEverything;_root;_isDirent;_statsProp;_rdOptions;_fileFilter;_directoryFilter;_relStart;constructor(e={}){super({objectMode:!0,autoDestroy:!0,highWaterMark:e.highWaterMark??We.highWaterMark});let t={...We,...e},s=t.root??We.root,r=t.type??We.type;this._fileFilter=Qn(t.fileFilter),this._directoryFilter=Qn(t.directoryFilter);let o=t.lstat?Yn:gs;ks?this._stat=c=>o(c,{bigint:!0}):this._stat=o,this._maxDepth=t.depth!=null&&Number.isSafeInteger(t.depth)?t.depth:We.depth,this._wantsDir=Es.has(r),this._wantsFile=vs.has(r),this._wantsEverything=r===pe.EVERYTHING_TYPE,this._root=ws(s),this._relStart=this._root.endsWith(Jn)?this._root.length:this._root.length+1,this._isDirent=!t.alwaysStat,this._statsProp=this._isDirent?"dirent":"stats",this._rdOptions={encoding:"utf8",withFileTypes:this._isDirent};let a={path:this._root,depth:1};a.pending=this._exploreDir(this._root,1),this.parents=[a],this.reading=!1,this.parent=void 0}async _read(e){if(!this.reading){this.reading=!0;try{for(;!this.destroyed&&e>0;){let t=this.parent,s=t&&t.files;if(s&&s.length>0){let{path:r,depth:o}=t,a=s.splice(0,e).map(l=>this._formatEntry(l,r)),c=this._isDirent?a:await Promise.all(a);for(let l of c){if(!l)continue;if(this.destroyed)return;let h=this._getEntryType(l);typeof h!="string"&&(h=await h),h==="directory"&&this._directoryFilter(l)?(o<=this._maxDepth&&this.parents.push({path:l.fullPath,depth:o+1}),this._wantsDir&&(this.push(l),e--)):(h==="file"||this._includeAsFile(l))&&this._fileFilter(l)&&this._wantsFile&&(this.push(l),e--)}}else{let r=this.parents.pop();if(!r){this.push(null);break}let o=r.pending??this._exploreDir(r.path,r.depth),a=this.parents[this.parents.length-1];if(a&&!a.pending&&(a.pending=this._exploreDir(a.path,a.depth)),this.parent=await o,this.destroyed)return}}}catch(t){this.destroy(t)}finally{this.reading=!1}}}async _exploreDir(e,t){let s;try{s=await ms(e,this._rdOptions)}catch(r){this._onError(r)}return{files:s,depth:t,path:e}}_formatEntry(e,t){let s=this._isDirent?e.name:e,r=ys(t,s),o={path:r.slice(this._relStart),fullPath:r,basename:s};return this._isDirent?(o.dirent=e,o):this._stat(r).then(a=>(o.stats=a,o),a=>{this._onError(a)})}_onError(e){_s(e)&&!this.destroyed?this.emit("warn",e):this.destroy(e)}_getEntryType(e){if(!e||!(this._statsProp in e))return"";let t=e[this._statsProp];return t.isFile()?"file":t.isDirectory()?"directory":t.isSymbolicLink()?this._getSymlinkEntryType(e):""}async _getSymlinkEntryType(e){let t=e.fullPath;try{let s=await ps(t),r=await Yn(s);if(r.isFile())return"file";if(r.isDirectory()){let o=s.length;if(t.startsWith(s)&&t[o]===Jn){let a=new Error(`Circular symlink detected: "${t}" points to "${s}"`);return a.code=Zn,this._onError(a),""}return"directory"}}catch(s){this._onError(s)}return""}_includeAsFile(e){let t=e&&e[this._statsProp];return t&&this._wantsEverything&&!t.isDirectory()}};function er(n,e={}){let t=e.entryType||e.type;if(t==="both"&&(t=pe.FILE_DIR_TYPE),n){if(typeof n!="string")throw new TypeError("readdirp: root argument must be a string. Usage: readdirp(root, options)");if(t&&!Kn.includes(t))throw new Error(`readdirp: Invalid type passed. Use one of ${Kn.join(", ")}`)}else throw new Error("readdirp: root argument is required. Usage: readdirp(root, options)");let s={...e,root:n};return t&&(s.type=t),new Yt(s)}import{watch as Cs,unwatchFile as tr,watchFile as xs}from"node:fs";import{realpath as Jt,lstat as Ts,open as Rs,stat as rr}from"node:fs/promises";import{type as Is}from"node:os";import*as K from"node:path";var As="data",Qt="end",sr="close",Ct=()=>{};var xt=process.platform,Zt=xt==="win32",Ps=xt==="darwin",Ds=xt==="linux",$s=xt==="freebsd",or=Is()==="OS400",Z={ALL:"all",READY:"ready",ADD:"add",CHANGE:"change",ADD_DIR:"addDir",UNLINK:"unlink",UNLINK_DIR:"unlinkDir",RAW:"raw",ERROR:"error"},ve=Z,Ms="watch",Ns={lstat:Ts,stat:rr},Le="listeners",Et="errHandlers",Be="rawEmitters",Fs=[Le,Et,Be],Os=new Set(["3dm","3ds","3g2","3gp","7z","a","aac","adp","afdesign","afphoto","afpub","ai","aif","aiff","alz","ape","apk","appimage","ar","arj","asf","au","avi","bak","baml","bh","bin","bk","bmp","btif","bz2","bzip2","cab","caf","cgm","class","cmx","cpio","cr2","cur","dat","dcm","deb","dex","djvu","dll","dmg","dng","doc","docm","docx","dot","dotm","dra","DS_Store","dsk","dts","dtshd","dvb","dwg","dxf","ecelp4800","ecelp7470","ecelp9600","egg","eol","eot","epub","exe","f4v","fbs","fh","fla","flac","flatpak","fli","flv","fpx","fst","fvt","g3","gh","gif","graffle","gz","gzip","h261","h263","h264","icns","ico","ief","img","ipa","iso","jar","jpeg","jpg","jpgv","jpm","jxr","key","ktx","lha","lib","lvp","lz","lzh","lzma","lzo","m3u","m4a","m4v","mar","mdi","mht","mid","midi","mj2","mka","mkv","mmr","mng","mobi","mov","movie","mp3","mp4","mp4a","mpeg","mpg","mpga","mxu","nef","npx","numbers","nupkg","o","odp","ods","odt","oga","ogg","ogv","otf","ott","pages","pbm","pcx","pdb","pdf","pea","pgm","pic","png","pnm","pot","potm","potx","ppa","ppam","ppm","pps","ppsm","ppsx","ppt","pptm","pptx","psd","pya","pyc","pyo","pyv","qt","rar","ras","raw","resources","rgb","rip","rlc","rmf","rmvb","rpm","rtf","rz","s3m","s7z","scpt","sgi","shar","snap","sil","sketch","slk","smv","snk","so","stl","suo","sub","swf","tar","tbz","tbz2","tga","tgz","thmx","tif","tiff","tlz","ttc","ttf","txz","udf","uvh","uvi","uvm","uvp","uvs","uvu","viv","vob","war","wav","wax","wbmp","wdp","weba","webm","webp","whl","wim","wm","wma","wmv","wmx","woff","woff2","wrm","wvx","xbm","xif","xla","xlam","xls","xlsb","xlsm","xlsx","xlt","xltm","xltx","xm","xmind","xpi","xpm","xwd","xz","z","zip","zipx"]),Ls=n=>Os.has(K.extname(n).slice(1).toLowerCase()),Xt=(n,e)=>{n instanceof Set?n.forEach(e):e(n)},st=(n,e,t)=>{let s=n[e];s instanceof Set||(n[e]=s=new Set([s])),s.add(t)},js=n=>e=>{let t=n[e];t instanceof Set?t.clear():delete n[e]},ot=(n,e,t)=>{let s=n[e];s instanceof Set?s.delete(t):s===t&&delete n[e]},ir=n=>n instanceof Set?n.size===0:!n,vt=new Map;function nr(n,e,t,s,r){let o=(a,c)=>{t(n),r(a,c,{watchedPath:n}),c&&n!==c&&_t(K.resolve(n,c),Le,K.join(n,c))};try{return Cs(n,{persistent:e.persistent},o)}catch(a){s(a);return}}var _t=(n,e,t,s,r)=>{let o=vt.get(n);o&&Xt(o[e],a=>{a(t,s,r)})},Us=(n,e,t,s)=>{let{listener:r,errHandler:o,rawEmitter:a}=s,c=vt.get(e),l;if(!t.persistent)return l=nr(n,t,r,o,a),l?l.close.bind(l):void 0;if(c)st(c,Le,r),st(c,Et,o),st(c,Be,a);else{if(l=nr(n,t,_t.bind(null,e,Le),o,_t.bind(null,e,Be)),!l)return;l.on(ve.ERROR,async h=>{let f=_t.bind(null,e,Et);if(c&&(c.watcherUnusable=!0),Zt&&h.code==="EPERM")try{await(await Rs(n,"r")).close(),f(h)}catch{}else f(h)}),c={listeners:r,errHandlers:o,rawEmitters:a,watcher:l},vt.set(e,c)}return()=>{ot(c,Le,r),ot(c,Et,o),ot(c,Be,a),ir(c.listeners)&&(c.watcher.close(),vt.delete(e),Fs.forEach(js(c)),c.watcher=void 0,Object.freeze(c))}},Kt=new Map,Hs=(n,e,t,s)=>{let{listener:r,rawEmitter:o}=s,a=Kt.get(e),c=a&&a.options;return c&&(c.persistent<t.persistent||c.interval>t.interval)&&(tr(e),a=void 0),a?(st(a,Le,r),st(a,Be,o)):(a={listeners:r,rawEmitters:o,options:t,watcher:xs(e,t,(l,h)=>{Xt(a.rawEmitters,m=>{m(ve.CHANGE,e,{curr:l,prev:h})});let f=l.mtimeMs;(l.size!==h.size||f>h.mtimeMs||f===0)&&Xt(a.listeners,m=>m(n,l))})},Kt.set(e,a)),()=>{ot(a,Le,r),ot(a,Be,o),ir(a.listeners)&&(Kt.delete(e),tr(e),a.options=a.watcher=void 0,Object.freeze(a))}},kt=class{fsw;_boundHandleError;constructor(e){this.fsw=e,this._boundHandleError=t=>e._handleError(t)}_watchWithNodeFs(e,t){let s=this.fsw.options,r=K.dirname(e),o=K.basename(e);this.fsw._getWatchedDir(r).add(o);let c=K.resolve(e),l={persistent:s.persistent};t||(t=Ct);let h;if(s.usePolling){let f=s.interval!==s.binaryInterval;l.interval=f&&Ls(o)?s.binaryInterval:s.interval,h=Hs(e,c,l,{listener:t,rawEmitter:this.fsw._emitRaw})}else h=Us(e,c,l,{listener:t,errHandler:this._boundHandleError,rawEmitter:this.fsw._emitRaw});return h}_handleFile(e,t,s){if(this.fsw.closed)return;let r=K.dirname(e),o=K.basename(e),a=this.fsw._getWatchedDir(r),c=t;if(a.has(o))return;let l=async(f,m)=>{if(this.fsw._throttle(Ms,e,5)){if(!m||m.mtimeMs===0)try{let u=await rr(e);if(this.fsw.closed)return;let w=u.atimeMs,v=u.mtimeMs;if((!w||w<=v||v!==c.mtimeMs)&&this.fsw._emit(ve.CHANGE,e,u),(Ps||Ds||$s)&&c.ino!==u.ino){this.fsw._closeFile(f),c=u;let R=this._watchWithNodeFs(e,l);R&&this.fsw._addPathCloser(f,R)}else c=u}catch{this.fsw._remove(r,o)}else if(a.has(o)){let u=m.atimeMs,w=m.mtimeMs;(!u||u<=w||w!==c.mtimeMs)&&this.fsw._emit(ve.CHANGE,e,m),c=m}}},h=this._watchWithNodeFs(e,l);if(!(s&&this.fsw.options.ignoreInitial)&&this.fsw._isntIgnored(e)){if(!this.fsw._throttle(ve.ADD,e,0))return;this.fsw._emit(ve.ADD,e,t)}return h}async _handleSymlink(e,t,s,r){if(this.fsw.closed)return;let o=e.fullPath,a=this.fsw._getWatchedDir(t);if(!this.fsw.options.followSymlinks){this.fsw._incrReadyCount();let c;try{c=await Jt(s)}catch{return this.fsw._emitReady(),!0}return this.fsw.closed?void 0:(a.has(r)?this.fsw._symlinkPaths.get(o)!==c&&(this.fsw._symlinkPaths.set(o,c),this.fsw._emit(ve.CHANGE,s,e.stats)):(a.add(r),this.fsw._symlinkPaths.set(o,c),this.fsw._emit(ve.ADD,s,e.stats)),this.fsw._emitReady(),!0)}if(this.fsw._symlinkPaths.has(o))return!0;this.fsw._symlinkPaths.set(o,!0)}_handleRead(e,t,s,r,o,a,c){e=K.join(e,"");let l=r?`${e}:${r}`:e;if(c=this.fsw._throttle("readdir",l,1e3),!c)return;let h=this.fsw._getWatchedDir(s.path),f=new Set,m=this.fsw._readdirp(e,{fileFilter:u=>s.filterPath(u),directoryFilter:u=>s.filterDir(u)});if(m)return m.on(As,async u=>{if(this.fsw.closed){m=void 0;return}let w=u.path,v=K.join(e,w);if(f.add(w),!(u.stats.isSymbolicLink()&&await this._handleSymlink(u,e,v,w))){if(this.fsw.closed){m=void 0;return}(w===r||!r&&!h.has(w))&&(this.fsw._incrReadyCount(),v=K.join(o,K.relative(o,v)),this._addToNodeFs(v,t,s,a+1))}}).on(ve.ERROR,this._boundHandleError),new Promise((u,w)=>{if(!m)return w();m.once(Qt,()=>{if(this.fsw.closed){m=void 0;return}let v=c?c.clear():!1;u(void 0),h.getChildren().filter(R=>R!==e&&!f.has(R)).forEach(R=>{this.fsw._remove(e,R)}),m=void 0,v&&this._handleRead(e,!1,s,r,o,a,c)})})}async _handleDir(e,t,s,r,o,a,c){let l=this.fsw._getWatchedDir(K.dirname(e)),h=l.has(K.basename(e));!(s&&this.fsw.options.ignoreInitial)&&!o&&!h&&this.fsw._emit(ve.ADD_DIR,e,t),l.add(K.basename(e)),this.fsw._getWatchedDir(e);let f,m,u=this.fsw.options.depth;if((u==null||r<=u)&&!this.fsw._symlinkPaths.has(c)){if(!o&&(await this._handleRead(e,s,a,o,e,r,f),this.fsw.closed))return;m=this._watchWithNodeFs(e,(w,v)=>{v&&v.mtimeMs===0||this._handleRead(w,!1,a,o,e,r,f)})}return m}async _addToNodeFs(e,t,s,r,o){let a=this.fsw._emitReady;if(this.fsw._isIgnored(e)||this.fsw.closed)return a(),!1;let c=this.fsw._getWatchHelpers(e);s&&(c.filterPath=l=>s.filterPath(l),c.filterDir=l=>s.filterDir(l));try{let l=await Ns[c.statMethod](c.watchPath);if(this.fsw.closed)return;if(this.fsw._isIgnored(c.watchPath,l))return a(),!1;let h=this.fsw.options.followSymlinks,f;if(l.isDirectory()){let m=K.resolve(e),u=h?await Jt(e):e;if(this.fsw.closed||(f=await this._handleDir(c.watchPath,l,t,r,o,c,u),this.fsw.closed))return;m!==u&&u!==void 0&&this.fsw._symlinkPaths.set(m,u)}else if(l.isSymbolicLink()){let m=h?await Jt(e):e;if(this.fsw.closed)return;let u=K.dirname(c.watchPath);if(this.fsw._getWatchedDir(u).add(c.watchPath),this.fsw._emit(ve.ADD,c.watchPath,l),f=await this._handleDir(u,l,t,r,e,c,m),this.fsw.closed)return;m!==void 0&&this.fsw._symlinkPaths.set(K.resolve(e),m)}else f=this._handleFile(c.watchPath,l,t);return a(),f&&this.fsw._addPathCloser(e,f),!1}catch(l){if(this.fsw._handleError(l))return a(),e}}};var en="/",Vs="//",dr=".",Gs="..",Ys="string",Js=/\\/g,fr=/\/\//g,Ks=/\..*\.(sw[px])$|~$|\.subl.*\.tmp/,Xs=/^\.[/\\]/;function Tt(n){return Array.isArray(n)?n:[n]}var tn=n=>typeof n=="object"&&n!==null&&!(n instanceof RegExp);function Qs(n){return typeof n=="function"?n:typeof n=="string"?e=>n===e:n instanceof RegExp?e=>n.test(e):typeof n=="object"&&n!==null?e=>{if(n.path===e)return!0;if(n.recursive){let t=z.relative(n.path,e);return t?!t.startsWith("..")&&!z.isAbsolute(t):!1}return!1}:()=>!1}function Zs(n){if(typeof n!="string")throw new Error("string expected");n=z.normalize(n),n=n.replace(/\\/g,"/");let e=!1;return n.startsWith("//")&&(e=!0),n=n.replace(fr,"/"),e&&(n="/"+n),n}function ar(n,e,t){let s=Zs(e);for(let r=0;r<n.length;r++){let o=n[r];if(o(s,t))return!0}return!1}function eo(n,e){if(n==null)throw new TypeError("anymatch: specify first argument");let s=Tt(n).map(r=>Qs(r));return e==null?(r,o)=>ar(s,r,o):ar(s,e)}var lr=n=>{let e=Tt(n).flat();if(!e.every(t=>typeof t===Ys))throw new TypeError(`Non-string provided as watch path: ${e}`);return e.map(hr)},cr=n=>{let e=n.replace(Js,en),t=!1;return e.startsWith(Vs)&&(t=!0),e=e.replace(fr,en),t&&(e=en+e),e},hr=n=>cr(z.normalize(cr(n))),ur=(n="")=>e=>typeof e=="string"?hr(z.isAbsolute(e)?e:z.join(n,e)):e,to=(n,e)=>z.isAbsolute(n)?n:z.join(e,n),no=Object.freeze(new Set),nn=class{path;_removeWatcher;items;constructor(e,t){this.path=e,this._removeWatcher=t,this.items=new Set}add(e){let{items:t}=this;t&&e!==dr&&e!==Gs&&t.add(e)}async remove(e){let{items:t}=this;if(!t||(t.delete(e),t.size>0))return;let s=this.path;try{await Ws(s)}catch{this._removeWatcher&&this._removeWatcher(z.dirname(s),z.basename(s))}}has(e){let{items:t}=this;if(t)return t.has(e)}getChildren(){let{items:e}=this;return e?[...e.values()]:[]}dispose(){this.items.clear(),this.path="",this._removeWatcher=Ct,this.items=no,Object.freeze(this)}},ro="stat",so="lstat",rn=class{fsw;path;watchPath;fullWatchPath;dirParts;followSymlinks;statMethod;constructor(e,t,s){this.fsw=s;let r=e;this.path=e=e.replace(Xs,""),this.watchPath=r,this.fullWatchPath=z.resolve(r),this.dirParts=[],this.dirParts.forEach(o=>{o.length>1&&o.pop()}),this.followSymlinks=t,this.statMethod=t?ro:so}entryPath(e){return z.join(this.watchPath,z.relative(this.watchPath,e.fullPath))}filterPath(e){let{stats:t}=e;if(t&&t.isSymbolicLink())return this.filterDir(e);let s=this.entryPath(e);return this.fsw._isntIgnored(s,t)&&this.fsw._hasReadPermissions(t)}filterDir(e){return this.fsw._isntIgnored(this.entryPath(e),e.stats)}},Rt=class extends zs{closed;options;_closers;_ignoredPaths;_throttled;_streams;_symlinkPaths;_watched;_pendingWrites;_pendingUnlinks;_readyCount;_emitReady;_closePromise;_userIgnored;_readyEmitted;_emitRaw;_boundRemove;_nodeFsHandler;constructor(e={}){super(),this.closed=!1,this._closers=new Map,this._ignoredPaths=new Set,this._throttled=new Map,this._streams=new Set,this._symlinkPaths=new Map,this._watched=new Map,this._pendingWrites=new Map,this._pendingUnlinks=new Map,this._readyCount=0,this._readyEmitted=!1;let t=e.awaitWriteFinish,s={stabilityThreshold:2e3,pollInterval:100},r={persistent:!0,ignoreInitial:!1,ignorePermissionErrors:!1,interval:100,binaryInterval:300,followSymlinks:!0,usePolling:!1,atomic:!0,...e,ignored:e.ignored?Tt(e.ignored):Tt([]),awaitWriteFinish:t===!0?s:typeof t=="object"?{...s,...t}:!1};or&&(r.usePolling=!0),r.atomic===void 0&&(r.atomic=!r.usePolling);let o=process.env.CHOKIDAR_USEPOLLING;if(o!==void 0){let l=o.toLowerCase();l==="false"||l==="0"?r.usePolling=!1:l==="true"||l==="1"?r.usePolling=!0:r.usePolling=!!l}let a=process.env.CHOKIDAR_INTERVAL;a&&(r.interval=Number.parseInt(a,10));let c=0;this._emitReady=()=>{c++,c>=this._readyCount&&(this._emitReady=Ct,this._readyEmitted=!0,process.nextTick(()=>this.emit(Z.READY)))},this._emitRaw=(...l)=>this.emit(Z.RAW,...l),this._boundRemove=this._remove.bind(this),this.options=r,this._nodeFsHandler=new kt(this),Object.freeze(r)}_addIgnoredPath(e){if(tn(e)){for(let t of this._ignoredPaths)if(tn(t)&&t.path===e.path&&t.recursive===e.recursive)return}this._ignoredPaths.add(e)}_removeIgnoredPath(e){if(this._ignoredPaths.delete(e),typeof e=="string")for(let t of this._ignoredPaths)tn(t)&&t.path===e&&this._ignoredPaths.delete(t)}add(e,t,s){let{cwd:r}=this.options;this.closed=!1,this._closePromise=void 0;let o=lr(e);return r&&(o=o.map(a=>to(a,r))),o.forEach(a=>{this._removeIgnoredPath(a)}),this._userIgnored=void 0,this._readyCount||(this._readyCount=0),this._readyCount+=o.length,Promise.all(o.map(async a=>{let c=await this._nodeFsHandler._addToNodeFs(a,!s,void 0,0,t);return c&&this._emitReady(),c})).then(a=>{this.closed||a.forEach(c=>{c&&this.add(z.dirname(c),z.basename(t||c))})}),this}unwatch(e){if(this.closed)return this;let t=lr(e),{cwd:s}=this.options;return t.forEach(r=>{!z.isAbsolute(r)&&!this._closers.has(r)&&(s&&(r=z.join(s,r)),r=z.resolve(r)),this._closePath(r),this._addIgnoredPath(r),this._watched.has(r)&&this._addIgnoredPath({path:r,recursive:!0}),this._userIgnored=void 0}),this}close(){if(this._closePromise)return this._closePromise;this.closed=!0,this.removeAllListeners();let e=[];return this._closers.forEach(t=>t.forEach(s=>{let r=s();r instanceof Promise&&e.push(r)})),this._streams.forEach(t=>t.destroy()),this._userIgnored=void 0,this._readyCount=0,this._readyEmitted=!1,this._watched.forEach(t=>t.dispose()),this._closers.clear(),this._watched.clear(),this._streams.clear(),this._symlinkPaths.clear(),this._throttled.clear(),this._closePromise=e.length?Promise.all(e).then(()=>{}):Promise.resolve(),this._closePromise}getWatched(){let e={};return this._watched.forEach((t,s)=>{let o=(this.options.cwd?z.relative(this.options.cwd,s):s)||dr;e[o]=t.getChildren().sort()}),e}emitWithAll(e,t){this.emit(e,...t),e!==Z.ERROR&&this.emit(Z.ALL,e,...t)}async _emit(e,t,s){if(this.closed)return;let r=this.options;Zt&&(t=z.normalize(t)),r.cwd&&(t=z.relative(r.cwd,t));let o=[t];s!=null&&o.push(s);let a=r.awaitWriteFinish,c;if(a&&(c=this._pendingWrites.get(t)))return c.lastChange=new Date,this;if(r.atomic){if(e===Z.UNLINK)return this._pendingUnlinks.set(t,[e,...o]),setTimeout(()=>{this._pendingUnlinks.forEach((l,h)=>{this.emit(...l),this.emit(Z.ALL,...l),this._pendingUnlinks.delete(h)})},typeof r.atomic=="number"?r.atomic:100),this;e===Z.ADD&&this._pendingUnlinks.has(t)&&(e=Z.CHANGE,this._pendingUnlinks.delete(t))}if(a&&(e===Z.ADD||e===Z.CHANGE)&&this._readyEmitted){let l=(h,f)=>{h?(e=Z.ERROR,o[0]=h,this.emitWithAll(e,o)):f&&(o.length>1?o[1]=f:o.push(f),this.emitWithAll(e,o))};return this._awaitWriteFinish(t,a.stabilityThreshold,e,l),this}if(e===Z.CHANGE&&!this._throttle(Z.CHANGE,t,50))return this;if(r.alwaysStat&&s===void 0&&(e===Z.ADD||e===Z.ADD_DIR||e===Z.CHANGE)){let l=r.cwd?z.join(r.cwd,t):t,h;try{h=await Bs(l)}catch{}if(!h||this.closed)return;o.push(h)}return this.emitWithAll(e,o),this}_handleError(e){let t=e&&e.code;return e&&t!=="ENOENT"&&t!=="ENOTDIR"&&(!this.options.ignorePermissionErrors||t!=="EPERM"&&t!=="EACCES")&&this.emit(Z.ERROR,e),e||this.closed}_throttle(e,t,s){this._throttled.has(e)||this._throttled.set(e,new Map);let r=this._throttled.get(e);if(!r)throw new Error("invalid throttle");let o=r.get(t);if(o)return o.count++,!1;let a,c=()=>{let h=r.get(t),f=h?h.count:0;return r.delete(t),clearTimeout(a),h&&clearTimeout(h.timeoutObject),f};a=setTimeout(c,s);let l={timeoutObject:a,clear:c,count:0};return r.set(t,l),l}_incrReadyCount(){return this._readyCount++}_awaitWriteFinish(e,t,s,r){let o=this.options.awaitWriteFinish;if(typeof o!="object")return;let a=o.pollInterval,c,l=e;this.options.cwd&&!z.isAbsolute(e)&&(l=z.join(this.options.cwd,e));let h=new Date,f=this._pendingWrites;function m(u){qs(l,(w,v)=>{if(w||!f.has(e)){w&&w.code!=="ENOENT"&&r(w);return}let R=Number(new Date);u&&v.size!==u.size&&(f.get(e).lastChange=R);let _=f.get(e);R-_.lastChange>=t?(f.delete(e),r(void 0,v)):c=setTimeout(m,a,v)})}f.has(e)||(f.set(e,{lastChange:h,cancelWait:()=>(f.delete(e),clearTimeout(c),s)}),c=setTimeout(m,a))}_isIgnored(e,t){if(this.options.atomic&&Ks.test(e))return!0;if(!this._userIgnored){let{cwd:s}=this.options,o=(this.options.ignored||[]).map(ur(s)),c=[...[...this._ignoredPaths].map(ur(s)),...o];this._userIgnored=eo(c,void 0)}return this._userIgnored(e,t)}_isntIgnored(e,t){return!this._isIgnored(e,t)}_getWatchHelpers(e){return new rn(e,this.options.followSymlinks,this)}_getWatchedDir(e){let t=z.resolve(e);return this._watched.has(t)||this._watched.set(t,new nn(t,this._boundRemove)),this._watched.get(t)}_hasReadPermissions(e){return this.options.ignorePermissionErrors?!0:!!(Number(e.mode)&256)}_remove(e,t,s){let r=z.join(e,t),o=z.resolve(r);if(s=s??(this._watched.has(r)||this._watched.has(o)),!this._throttle("remove",r,100))return;!s&&this._watched.size===1&&this.add(e,t,!0),this._getWatchedDir(r).getChildren().forEach(u=>this._remove(r,u));let l=this._getWatchedDir(e),h=l.has(t);l.remove(t),this._symlinkPaths.has(o)&&this._symlinkPaths.delete(o);let f=r;if(this.options.cwd&&(f=z.relative(this.options.cwd,r)),this.options.awaitWriteFinish&&this._pendingWrites.has(f)&&this._pendingWrites.get(f).cancelWait()===Z.ADD)return;this._watched.delete(r),this._watched.delete(o);let m=s?Z.UNLINK_DIR:Z.UNLINK;h&&!this._isIgnored(r)&&this._emit(m,r),this._closePath(r)}_closePath(e){this._closeFile(e);let t=z.dirname(e);this._getWatchedDir(t).remove(z.basename(e))}_closeFile(e){let t=this._closers.get(e);t&&(t.forEach(s=>s()),this._closers.delete(e))}_addPathCloser(e,t){if(!t)return;let s=this._closers.get(e);s||(s=[],this._closers.set(e,s)),s.push(t)}_readdirp(e,t){if(this.closed)return;let s={type:Z.ALL,alwaysStat:!0,lstat:!0,...t,depth:0},r=er(e,s);return this._streams.add(r),r.once(sr,()=>{r=void 0}),r.once(Qt,()=>{r&&(this._streams.delete(r),r=void 0)}),r}};function oo(n,e={}){let t=new Rt(e);return t.add(n),t}var mr={watch:oo,FSWatcher:Rt};function io(n,e){let t=Object.create(null);for(let o=0;o<e.length;o++){let a=e[o];t[a]?t[a].push(o):t[a]=[o]}let r=[{buffer1index:-1,buffer2index:-1,chain:null}];for(let o=0;o<n.length;o++){let a=n[o],c=t[a]||[],l=0,h=r[0];for(let f of c){let m;for(m=l;m<r.length&&!(r[m].buffer2index<f&&(m===r.length-1||r[m+1].buffer2index>f));m++);if(m<r.length){let u={buffer1index:o,buffer2index:f,chain:r[m]};if(l===r.length?r.push(h):r[l]=h,l=m+1,h=u,l===r.length)break}}r[l]=h}return r[r.length-1]}function pr(n,e){let t=io(n,e),s=[],r=n.length,o=e.length;for(let a=t;a!==null;a=a.chain){let c=r-a.buffer1index-1,l=o-a.buffer2index-1;r=a.buffer1index,o=a.buffer2index,(c||l)&&s.push({buffer1:[r+1,c],buffer1Content:n.slice(r+1,r+1+c),buffer2:[o+1,l],buffer2Content:e.slice(o+1,o+1+l)})}return s.reverse(),s}function ao(n,e,t){let s=[];function r(l,h){s.push({ab:h,oStart:l.buffer1[0],oLength:l.buffer1[1],abStart:l.buffer2[0],abLength:l.buffer2[1]})}pr(e,n).forEach(l=>r(l,"a")),pr(e,t).forEach(l=>r(l,"b")),s.sort((l,h)=>l.oStart-h.oStart);let o=[],a=0;function c(l){l>a&&(o.push({stable:!0,buffer:"o",bufferStart:a,bufferLength:l-a,bufferContent:e.slice(a,l)}),a=l)}for(;s.length;){let l=s.shift(),h=l.oStart,f=l.oStart+l.oLength,m=[l];for(c(h);s.length;){let u=s[0],w=u.oStart;if(w>f)break;f=Math.max(f,w+u.oLength),m.push(s.shift())}if(m.length===1){if(l.abLength>0){let u=l.ab==="a"?n:t;o.push({stable:!0,buffer:l.ab,bufferStart:l.abStart,bufferLength:l.abLength,bufferContent:u.slice(l.abStart,l.abStart+l.abLength)})}}else{let u={a:[n.length,-1,e.length,-1],b:[t.length,-1,e.length,-1]};for(;m.length;){l=m.shift();let j=l.oStart,te=j+l.oLength,G=l.abStart,B=G+l.abLength,X=u[l.ab];X[0]=Math.min(G,X[0]),X[1]=Math.max(B,X[1]),X[2]=Math.min(j,X[2]),X[3]=Math.max(te,X[3])}let w=u.a[0]+(h-u.a[2]),v=u.a[1]+(f-u.a[3]),R=u.b[0]+(h-u.b[2]),_=u.b[1]+(f-u.b[3]),L={stable:!1,aStart:w,aLength:v-w,aContent:n.slice(w,v),oStart:h,oLength:f-h,oContent:e.slice(h,f),bStart:R,bLength:_-R,bContent:t.slice(R,_)};o.push(L)}a=f}return c(e.length),o}function gr(n,e,t,s){s=Object.assign({excludeFalseConflicts:!0,stringSeparator:/\s+/},s),typeof n=="string"&&(n=n.split(s.stringSeparator)),typeof e=="string"&&(e=e.split(s.stringSeparator)),typeof t=="string"&&(t=t.split(s.stringSeparator));let o=[],a=ao(n,e,t),c=[];function l(){c.length&&o.push({ok:c}),c=[]}function h(f,m){if(f.length!==m.length)return!1;for(let u=0;u<f.length;u++)if(f[u]!==m[u])return!1;return!0}return a.forEach(f=>{f.stable?c.push(...f.bufferContent):s.excludeFalseConflicts&&h(f.aContent,f.bContent)?c.push(...f.aContent):(l(),o.push({conflict:{a:f.aContent,aIndex:f.aStart,o:f.oContent,oIndex:f.oStart,b:f.bContent,bIndex:f.bStart}}))}),l(),o}function It(n,e){let t=n.lastIndexOf("/"),s=t<0?"":n.slice(0,t+1),r=t<0?n:n.slice(t+1),o=r.lastIndexOf("."),a=o>0?r.slice(0,o):r,c=o>0?r.slice(o):"",l=f=>String(f).padStart(2,"0"),h=`${e.getFullYear()}-${l(e.getMonth()+1)}-${l(e.getDate())} ${l(e.getHours())}${l(e.getMinutes())}`;return`${s}${a} (conflict ${h})${c}`}function lo(n,e){if(e<2)return n;let t=n.lastIndexOf("."),s=t>n.lastIndexOf("/")&&t>n.lastIndexOf(")"),r=s?n.slice(0,t):n,o=s?n.slice(t):"";return`${r}-${e}${o}`}function co(n){let e=3735928559,t=1103547991;for(let r=0;r<n.length;r++){let o=n.charCodeAt(r);e=Math.imul(e^o,2654435761),t=Math.imul(t^o,1597334677)}e=Math.imul(e^e>>>16,2246822507)^Math.imul(t^t>>>13,3266489909),t=Math.imul(t^t>>>16,2246822507)^Math.imul(e^e>>>13,3266489909);let s=4294967296*(2097151&t)+(e>>>0);return`${n.length.toString(36)}-${s.toString(36)}`}function At(n,e,t){if(n===null&&e===null&&t===null)return{kind:"none"};if(t===null)return n===null?e?{kind:"dropShadow"}:{kind:"none"}:e?n===e.hash?{kind:"deleteLocal"}:{kind:"pushCreate"}:{kind:"pushCreate"};if(n===null)return e?t.seq===e.seq?{kind:"pushDelete"}:{kind:"pull"}:{kind:"pull"};if(!e)return n===t.hash?{kind:"adopt"}:{kind:"conflict"};let s=n!==e.hash,r=t.seq!==e.seq;return!s&&!r?{kind:"none"}:s?r?n===t.hash?{kind:"adopt"}:t.hash===e.hash?{kind:"push",baseSeq:t.seq}:{kind:"conflict"}:{kind:"push",baseSeq:e.seq}:{kind:"pull"}}function yr(n,e,t){let s=gr(n.split(`
|
|
193
|
+
`,ts=t=>({transpile:(e,n,s)=>t.transpileForServe(e,n,s),mimeOf:e=>t.mimeOf(e)});function jt(t){let e=t;return typeof e.projectsRoot=="function"&&typeof e.transpileForServe=="function"&&typeof e.mimeOf=="function"&&typeof e.setPreviewHooks=="function"}function Ut(t){t.setPreviewHooks({sdkJs:Fn,proxy:Nn(()=>t.getCloud())}),t.handle("connect:meta",(e,n)=>typeof n=="string"&&n?$n(n):{}),t.handle("connect:list",async()=>{let e=await t.getCloud();if(!e.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:n,json:s}=await de(e,"GET","/api/connect/apps");return n===401||n===403?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:n!==200?{ok:!1,code:"error",detail:s?.detail||`HTTP ${n}`}:{ok:!0,base:e.base,...s}}catch(n){return{ok:!1,code:"error",detail:n?.message||String(n)}}}),t.handle("connect:publish",async(e,n)=>{if(!n||typeof n.dir!="string"||!n.dir||!n.name||!n.slug||!n.entry)return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let s;try{let o=Rn(t.projectsRoot());if(s=Rn(n.dir),s!==o&&!s.startsWith(o+Xr))return{ok:!1,code:"error",detail:"\u53EA\u80FD\u53D1\u5E03 Coding Space \u9879\u76EE\u76EE\u5F55"}}catch{return{ok:!1,code:"error",detail:"\u9879\u76EE\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6CD5\u8BBF\u95EE"}}let r=await t.getCloud();if(!r.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{files:o,totalBytes:a}=Pn(s,ts(t));if(!o.some(m=>m.path===n.entry))return{ok:!1,code:"error",detail:`\u5165\u53E3\u6587\u4EF6\u4E0D\u5B58\u5728:${n.entry}`};let{status:c,json:l}=await de(r,"POST","/api/connect/apps",{slug:n.slug,name:n.name,entry:n.entry,files:o},3e5);return c===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:c!==200?{ok:!1,code:l?.code||"error",detail:l?.detail||`HTTP ${c}`,used:l?.used,limit:l?.limit}:(Mn(s,{slug:String(l.slug)}),{ok:!0,slug:l.slug,handle:l.handle,url:`${r.base}${l.url}`,totalBytes:a})}catch(o){return{ok:!1,code:"error",detail:o?.message||String(o)}}}),t.handle("connect:unpublish",async(e,n)=>{if(!n||typeof n!="string")return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let s=await t.getCloud();if(!s.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:r,json:o}=await de(s,"DELETE",`/api/connect/apps/${encodeURIComponent(n)}`);return r===401||r===403?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:r!==200&&r!==404?{ok:!1,code:"error",detail:o?.detail||`HTTP ${r}`}:{ok:!0}}catch(r){return{ok:!1,code:"error",detail:r?.message||String(r)}}}),t.handle("connect:listingApply",async(e,n)=>{if(!n||typeof n.slug!="string"||!n.slug||typeof n.summary!="string"||!n.summary.trim())return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let s=await t.getCloud();if(!s.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:r,json:o}=await de(s,"PUT",`/api/connect/apps/${encodeURIComponent(n.slug)}/listing`,{summary:n.summary});return r===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:r!==200?{ok:!1,code:o?.code||"error",detail:o?.detail||`HTTP ${r}`}:{ok:!0,status:o.status}}catch(r){return{ok:!1,code:"error",detail:r?.message||String(r)}}}),t.handle("connect:listingWithdraw",async(e,n)=>{if(!n||typeof n!="string")return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let s=await t.getCloud();if(!s.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:r,json:o}=await de(s,"DELETE",`/api/connect/apps/${encodeURIComponent(n)}/listing`);return r===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:r!==200&&r!==404?{ok:!1,code:"error",detail:o?.detail||`HTTP ${r}`}:{ok:!0}}catch(r){return{ok:!1,code:"error",detail:r?.message||String(r)}}}),t.handle("connect:store",async()=>{let e=await t.getCloud();try{let{status:n,json:s}=await de(e,"GET","/api/connect/store");return n!==200?{ok:!1,detail:s?.detail||`HTTP ${n}`}:{ok:!0,base:e.base,items:Array.isArray(s.items)?s.items:[]}}catch(n){return{ok:!1,detail:n?.message||String(n)}}}),t.log("[forsion-extend] connect handlers registered")}import{createHash as ns}from"node:crypto";async function nt(t,e){if(!t||!e)return{status:"offline"};let n=t.replace(/\/+$/,"");try{let s=await fetch(`${n}/api/brain/users/me`,{headers:{Authorization:`Bearer ${e}`},signal:AbortSignal.timeout(5e3)});if(s.status===401||s.status===403)return{status:(s.headers.get("content-type")||"").includes("application/json")?"expired":"offline"};if(!s.ok)return{status:"offline"};let r=await s.json();if(!r)return{status:"offline"};let o=r.avatar||r.avatarUrl||r.avatar_url||void 0;return o&&/^\/(?!\/)/.test(o)&&(o=n+o),{status:"ok",user:{username:r.username||r.nickname||void 0,nickname:r.nickname||void 0,avatar:o,membershipTier:r.membershipTier||r.membership_tier||void 0}}}catch{return{status:"offline"}}}var On=t=>`${t.seq}:${t.hash}`,rs=t=>ns("sha256").update(t).digest("hex");function Ht(t){if(t===null)return{baseSeq:0,baseHash:null};if(typeof t!="string")return;let e=t.indexOf(":"),n=Number(e===-1?t:t.slice(0,e));if(!Number.isInteger(n)||n<=0)return;let s=e===-1?"":t.slice(e+1);return{baseSeq:n,baseHash:/^[0-9a-f]{64}$/.test(s)?s:null}}function jn(t){let e=t.baseUrl.replace(/\/+$/,""),n=r=>`${e}/api/remotesync/vaults/${encodeURIComponent(t.vault)}${r}`,s=async(r,o)=>{let a=t.getToken();if(!a)throw new Error("penzor-not-logged-in");let c=await fetch(r,{...o,headers:{...o.headers,Authorization:`Bearer ${a}`}});if(c.status===409){let l=await c.json().catch(()=>({}));throw new Error(`cas-conflict ${String(l.code??"")}: seq=${String(l.seq??"?")}`)}if(!c.ok){let l=await c.text().catch(()=>"");throw new Error(`penzor ${o.method??"GET"} ${c.status}: ${l.slice(0,200)}`)}return c};return{kind:"penzor",async walk(r){let o=await s(n("/manifest"),{method:"GET",signal:r}),{files:a}=await o.json();return a.map(c=>({key:c.path,size:c.size,mtimeMs:c.mtimeMs,id:On(c)}))},async readFile(r,o){let c=await(await s(n(`/file?path=${encodeURIComponent(r)}`),{method:"GET",signal:o})).json(),l=await fetch(c.url,{signal:o});if(!l.ok)throw new Error(`penzor blob GET ${l.status}: ${r}`);let m=Buffer.from(await l.arrayBuffer());if(rs(m)!==c.hash)throw new Error(`penzor hash mismatch: ${r}`);return m},async writeFile(r,o,a,c,l){let m=Ht(l),d=new URLSearchParams({path:r,mtimeMs:String(Math.floor(a)||0)});m&&(d.set("baseSeq",String(m.baseSeq)),m.baseHash&&d.set("baseHash",m.baseHash));let u=await(await s(n(`/file?${d.toString()}`),{method:"PUT",body:new Uint8Array(o),headers:{"Content-Type":"application/octet-stream"},signal:c})).json();return{key:r,size:u.size,mtimeMs:u.mtimeMs,id:On(u)}},async rm(r,o,a){let c=Ht(a),l=new URLSearchParams({path:r});c&&c.baseSeq>0&&(l.set("baseSeq",String(c.baseSeq)),c.baseHash&&l.set("baseHash",c.baseHash)),await s(n(`/file?${l.toString()}`),{method:"DELETE",signal:o})},async check(){try{return await s(n("/manifest"),{method:"GET"}),{ok:!0}}catch(r){return{ok:!1,error:String(r?.message||r)}}}}}var Un=50*1024*1024,Ln=new Map;async function ss(t,e){let n=Ln.get(e);if(n)return{id:n};let s=await nt(t,e);if(s.status==="offline")return{error:"penzor-offline"};if(s.status!=="ok")return{error:"penzor-not-logged-in"};let r=s.user?.username?.trim();return r?(Ln.set(e,r),{id:r}):{error:"penzor-auth-unverified"}}var zt=t=>typeof t.registerRemoteSyncBackend=="function"&&typeof t.readCreds=="function";function qt(t){t.registerRemoteSyncBackend("penzor",async e=>{let n=t.readCreds();if(!n.token||!n.cloudUrl)return{error:"penzor-not-logged-in"};let s=e?.vault,r=(typeof s=="string"?s:"default").trim()||"default";if(!/^[A-Za-z0-9_-]{1,64}$/.test(r))return{error:"penzor-bad-vault"};let o=await ss(n.cloudUrl,n.token);if("error"in o)return o;let a=n.token;return{remote:jn({baseUrl:n.cloudUrl,vault:r,getToken:()=>a}),fingerprint:`penzor:${n.cloudUrl.replace(/\/+$/,"")}|u:${o.id}|${r}`,maxFileBytes:Un}}),t.log('[forsion-extend] remote-sync backend "penzor" registered')}import{readFileSync as os,writeFileSync as is,mkdirSync as as,chmodSync as ls,renameSync as cs}from"node:fs";import{join as us}from"node:path";function Se(t,e){try{let n=new URL(t);if(n.protocol!=="https:"&&n.protocol!=="http:")return null;let s=e.split(".")[1];if(!s)return null;let r=s.replace(/-/g,"+").replace(/_/g,"/"),o=Uint8Array.from(atob(r),l=>l.charCodeAt(0)),a=JSON.parse(new TextDecoder().decode(o)),c=a.userId??a.sub;return typeof c!="string"&&typeof c!="number"||!String(c).trim()?null:`${n.origin}${n.pathname.replace(/\/+$/,"")}::${String(c)}`}catch{return null}}function Wt(t){try{let e=t.split(".")[1];if(!e)return null;let n=JSON.parse(Buffer.from(e,"base64url").toString("utf8"));return n&&typeof n=="object"?n:null}catch{return null}}function zn(t,e=Date.now()){let n=Wt(t)?.iat;return typeof n=="number"?e-n*1e3:1/0}function ds(t,e=Date.now()){let n=Wt(t)?.exp;return typeof n=="number"?n*1e3-e:1/0}var fs=36e5;function qn(t,e=Date.now()){return!!t&&zn(t,e)>=fs}async function Wn(t,e,n=8e3,s){if(!t||!e)return null;let r=t.replace(/\/+$/,"");try{let o=await fetch(`${r}/api/auth/refresh`,{method:"POST",headers:{Authorization:`Bearer ${e}`,...s?{"X-Forsion-Client":s}:{}},signal:AbortSignal.timeout(n)});if(!o.ok)return null;let a=await o.json().catch(()=>null),c=typeof a?.token=="string"?a.token:"";return c&&c!==e?c:null}catch{return null}}var bt=(t,e)=>`${t.replace(/\/+$/,"")}\0${e}`,hs=(t,e)=>new Promise((n,s)=>{let r=()=>{clearTimeout(o),s(new Error("Sign-in cancelled."))},o=setTimeout(()=>{e.removeEventListener("abort",r),n()},t);e.aborted?r():e.addEventListener("abort",r,{once:!0})});function Bn(t){let e=()=>us(t.homeDir(),"auth-accounts.json"),n=(f,u)=>{as(t.homeDir(),{recursive:!0});let y=`${f}.tmp`;is(y,JSON.stringify(u,null,2),{encoding:"utf8",mode:384}),ls(y,384),cs(y,f)},s=()=>{try{let f=JSON.parse(os(e(),"utf8"));return Array.isArray(f.accounts)?f.accounts.filter(u=>u&&typeof u.token=="string"&&u.id===Se(u.cloudUrl,u.token)):[]}catch{return[]}},r=(f,u)=>{let y=Se(f.cloudUrl||"",f.token||"");if(!y||!f.token||!f.cloudUrl)return;let _=s(),T=_.find(N=>N.id===y),v=Wt(f.token),O={...T,id:y,cloudUrl:f.cloudUrl.replace(/\/+$/,""),token:f.token,username:u?.username||T?.username||v?.username,nickname:u?.nickname||T?.nickname};JSON.stringify(T)!==JSON.stringify(O)&&n(e(),{version:1,accounts:[..._.filter(N=>N.id!==y),O]})},o=()=>{let f=t.readCreds();r(f);let u=Se(f.cloudUrl,f.token);return s().map(({token:y,..._})=>({..._,active:_.id===u}))},a=f=>{let u=s().find(y=>y.id===f);if(!u)throw new Error("Account is no longer signed in. Sign in again.");return{cloudUrl:u.cloudUrl,token:u.token}},c=f=>{let u=Se(f.cloudUrl||"",f.token||"");u&&n(e(),{version:1,accounts:s().filter(y=>y.id!==u)})},l=null;return{rememberForsionAccount:r,forsionAccounts:o,savedForsionAccount:a,forgetForsionAccount:c,cancelForsionLogin:()=>{l?.abort(),l=null},forsionDeviceLogin:async(f,u,y)=>{if(l)throw new Error("A sign-in is already in progress.");if(!f)throw new Error("\u8BF7\u5148\u586B\u5199 Forsion \u4E91\u7AEF\u5730\u5740(\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF TANGU_CLOUD_URL)");let _=new AbortController;l=_;let T=()=>{if(_.signal.aborted||l!==_)throw new Error("Sign-in cancelled.")};try{let v=f.replace(/\/+$/,""),O;try{O=await fetch(`${v}/api/auth/cli/start`,{method:"POST",headers:{"Content-Type":"application/json"},body:"{}",signal:AbortSignal.any([_.signal,AbortSignal.timeout(15e3)])}).then(J=>J.json())}catch(J){throw new Error(`\u65E0\u6CD5\u8FDE\u63A5 ${v}:${J?.message||J}`)}if(T(),!O?.device_code)throw new Error("\u4E91\u7AEF\u4E0D\u652F\u6301 CLI \u767B\u5F55(/api/auth/cli/start \u8FD4\u56DE\u5F02\u5E38)");let N=O.verification_uri_complete||`${O.verification_uri}?code=${O.user_code}`,Y=new URL(`${v}/auth`);Y.searchParams.set("logout","1"),Y.searchParams.set("app","forsion-desktop"),Y.searchParams.set("redirect",N);let G=Y.toString();u?.({url:G,userCode:String(O.user_code||"")}),t.openExternal(G);let W=Date.now()+(O.expires_in||600)*1e3,Q=(O.interval||2)*1e3;for(;Date.now()<W;){await hs(Q,_.signal),T();let J=null;try{J=await fetch(`${v}/api/auth/cli/poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({device_code:O.device_code}),signal:AbortSignal.any([_.signal,AbortSignal.timeout(15e3)])})}catch{T();continue}if(T(),J.status===410)throw new Error("\u767B\u5F55\u7801\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u53D1\u8D77\u767B\u5F55");let ne=await J.json().catch(()=>({status:"pending"}));if(T(),ne.status==="approved"&&ne.token){let ue={cloudUrl:v,token:ne.token};return await y(ue,T),T(),{token:ne.token,cloudUrl:v}}}throw new Error("\u767B\u5F55\u8D85\u65F6,\u8BF7\u91CD\u8BD5")}finally{l===_&&(l=null)}},readAccounts:s}}var Vn=["homeDir","appVersion","broadcast","accountBackendState","accountTransition","accountCommit","accountClear","writeCreds","onExternalCredsChange","setTokenRefresher","readCreds"],Bt=t=>Vn.every(e=>typeof t[e]=="function");function Vt(t){let e={ok:!1,error:"untrusted"},n={loggedIn:!1,error:"untrusted"},s=Bn(t),r=0,o=()=>{let c=t.readCreds();return bt(c.cloudUrl,c.token)},a=null;t.handle("auth:status",async c=>{if(!t.isTrustedSender(c))return n;let l=r,m=o(),{base:d}=await t.getCloud(),f=t.readCreds().token,u=f?await nt(d,f):null,y=await t.accountBackendState(),{base:_}=await t.getCloud(),T=t.readCreds(),v=bt(_,T.token)!==bt(d,f),O=bt(d,f);!v&&u?.status==="ok"&&u.user&&(a={key:O,user:u.user},s.rememberForsionAccount({...T,cloudUrl:d},u.user));let N=v?void 0:u?.status==="ok"?u.user:u?.status==="offline"&&a?.key===O?a.user:void 0;if(v)return{loggedIn:!!T.token,tokenValid:null,cloudUrl:_,accountId:Se(_,T.token),username:null,nickname:null,avatar:null,membershipTier:null,tokenSource:T.token?"tangu-login":null,backendState:y};if(u?.status==="expired"){await t.accountTransition(async()=>{if(l!==r||o()!==m)return;let G=()=>{if(l!==r||o()!==m)throw Hn};try{await t.accountClear(G,()=>{t.log("[auth] token \u5DF2\u5931\u6548(\u670D\u52A1\u7AEF 401/403),\u81EA\u52A8\u767B\u51FA"),++r,s.cancelForsionLogin(),s.forgetForsionAccount(t.readCreds()),a=null})}catch(W){if(W!==Hn)throw W}});let Y=t.readCreds();return{loggedIn:!!Y.token,tokenValid:null,cloudUrl:Y.cloudUrl||d,accountId:Se(Y.cloudUrl||d,Y.token),username:null,nickname:null,avatar:null,membershipTier:null,tokenSource:Y.token?"tangu-login":null,backendState:y}}return{loggedIn:!!f,tokenValid:u&&u.status==="ok"?!0:null,cloudUrl:d,accountId:Se(d,f),username:N?.username||null,nickname:N?.nickname||null,avatar:N?.avatar||null,membershipTier:N?.membershipTier||null,tokenSource:f?"tangu-login":null,backendState:y}}),t.handle("auth:accounts",c=>t.isTrustedSender(c)?s.forsionAccounts():[]),t.handle("auth:switchAccount",async(c,l)=>{if(!t.isTrustedSender(c))return e;if(typeof l!="string")throw new Error("Invalid account.");let m=++r;return s.cancelForsionLogin(),t.accountTransition(async()=>{let d=s.savedForsionAccount(l);return await t.accountCommit(d,()=>{if(m!==r)throw new Error("Account switch cancelled.")},()=>{s.rememberForsionAccount(d),a=null}),{ok:!0,cloudUrl:d.cloudUrl||""}})}),t.handle("auth:forsionLogin",async(c,l)=>{if(!t.isTrustedSender(c))return e;let m=++r;s.cancelForsionLogin();let{base:d}=await t.getCloud();if(m!==r)throw new Error("Sign-in cancelled.");let f=(l||d||"").trim();return{ok:!0,cloudUrl:(await s.forsionDeviceLogin(f,y=>t.broadcast("auth:device",y),(y,_)=>t.accountTransition(()=>t.accountCommit(y,()=>{if(_(),m!==r)throw new Error("Sign-in cancelled.")},()=>{s.rememberForsionAccount(y),a=null})))).cloudUrl}}),t.handle("auth:logout",async c=>t.isTrustedSender(c)?(++r,s.cancelForsionLogin(),t.accountTransition(async()=>{let{base:l}=await t.getCloud(),m=t.readCreds();return await t.accountClear(void 0,()=>{s.forgetForsionAccount(m),a=null,l&&m.token&&fetch(`${l}/api/auth/logout`,{method:"POST",headers:{Authorization:`Bearer ${m.token}`},signal:AbortSignal.timeout(5e3)}).catch(()=>{})}),{ok:!0}})):e),t.onExternalCredsChange(({previous:c,current:l})=>{++r,s.cancelForsionLogin(),c.token&&!l.token&&s.forgetForsionAccount(c),a=null,s.rememberForsionAccount(l)}),t.setTokenRefresher(async c=>{let l=r,m=o(),d=t.readCreds().token;if(!qn(d))return;let{base:f}=await t.getCloud(),u=await Wn(f,d,c,`desktop/${t.appVersion()}`);if(!u){t.log("[auth] \u6ED1\u52A8\u7EED\u671F\u672A\u6210\u529F(\u79BB\u7EBF/\u8001\u7248\u672C server/\u8FD9\u679A\u5DF2\u5931\u6548),\u7EE7\u7EED\u7528\u65E7 token");return}l!==r||o()!==m||(s.rememberForsionAccount({cloudUrl:f,token:u}),t.writeCreds({cloudUrl:f,token:u}),t.log("[auth] \u767B\u5F55\u6001\u5DF2\u6ED1\u52A8\u7EED\u671F(\u6709\u6548\u671F\u91CD\u65B0\u8BA1\u6EE1 2 \u5468)"))}),t.log("[forsion-extend] account core registered")}var Hn=Symbol("stale-auth-intent");import{promises as Xe}from"node:fs";import je from"node:path";import{createHash as ms}from"node:crypto";var Gt=null;function Gn(t){Gt=t}function fe(){if(!Gt)throw new Error("amadeus sync env not set (registerAmadeus factory has not run)");return Gt}var he=()=>fe().accountId();function rt(t=he()){return t?ms("sha256").update(t).digest("hex"):"signed-out"}var Ee=(t=he())=>fe().readConfig(t),Ae=(t,e=he())=>fe().writeConfig(t,e),qe=(t,e=he())=>fe().updateConfig(t,e),De=(t=he())=>fe().cloudVaultDir(t),St=t=>fe().isManagedCloudVault(t);import{createHash as bo}from"node:crypto";import{promises as te,existsSync as Cr}from"node:fs";import se from"node:path";import{EventEmitter as qs}from"node:events";import{stat as Ws}from"node:fs";import{readdir as Bs,stat as Vs}from"node:fs/promises";import*as z from"node:path";import{lstat as Yn,readdir as ps,realpath as gs,stat as ys}from"node:fs/promises";import{join as ws,resolve as bs,sep as Jn}from"node:path";import{Readable as Ss}from"node:stream";var pe={FILE_TYPE:"files",DIR_TYPE:"directories",FILE_DIR_TYPE:"files_directories",EVERYTHING_TYPE:"all"},We={root:".",fileFilter:t=>!0,directoryFilter:t=>!0,type:pe.FILE_TYPE,lstat:!1,depth:2147483648,alwaysStat:!1,highWaterMark:256};Object.freeze(We);var Zn="READDIRP_RECURSIVE_ERROR",Es=new Set(["ENOENT","EPERM","EACCES","ELOOP",Zn]),Kn=[pe.DIR_TYPE,pe.EVERYTHING_TYPE,pe.FILE_DIR_TYPE,pe.FILE_TYPE],vs=new Set([pe.DIR_TYPE,pe.EVERYTHING_TYPE,pe.FILE_DIR_TYPE]),_s=new Set([pe.EVERYTHING_TYPE,pe.FILE_DIR_TYPE,pe.FILE_TYPE]),ks=t=>Es.has(t.code),Cs=process.platform==="win32",Xn=t=>!0,Qn=t=>{if(t===void 0)return Xn;if(typeof t=="function")return t;if(typeof t=="string"){let e=t.trim();return n=>n.basename===e}if(Array.isArray(t)){let e=t.map(n=>n.trim());return n=>e.some(s=>n.basename===s)}return Xn},Yt=class extends Ss{parents;reading;parent;_stat;_maxDepth;_wantsDir;_wantsFile;_wantsEverything;_root;_isDirent;_statsProp;_rdOptions;_fileFilter;_directoryFilter;_relStart;constructor(e={}){super({objectMode:!0,autoDestroy:!0,highWaterMark:e.highWaterMark??We.highWaterMark});let n={...We,...e},s=n.root??We.root,r=n.type??We.type;this._fileFilter=Qn(n.fileFilter),this._directoryFilter=Qn(n.directoryFilter);let o=n.lstat?Yn:ys;Cs?this._stat=c=>o(c,{bigint:!0}):this._stat=o,this._maxDepth=n.depth!=null&&Number.isSafeInteger(n.depth)?n.depth:We.depth,this._wantsDir=vs.has(r),this._wantsFile=_s.has(r),this._wantsEverything=r===pe.EVERYTHING_TYPE,this._root=bs(s),this._relStart=this._root.endsWith(Jn)?this._root.length:this._root.length+1,this._isDirent=!n.alwaysStat,this._statsProp=this._isDirent?"dirent":"stats",this._rdOptions={encoding:"utf8",withFileTypes:this._isDirent};let a={path:this._root,depth:1};a.pending=this._exploreDir(this._root,1),this.parents=[a],this.reading=!1,this.parent=void 0}async _read(e){if(!this.reading){this.reading=!0;try{for(;!this.destroyed&&e>0;){let n=this.parent,s=n&&n.files;if(s&&s.length>0){let{path:r,depth:o}=n,a=s.splice(0,e).map(l=>this._formatEntry(l,r)),c=this._isDirent?a:await Promise.all(a);for(let l of c){if(!l)continue;if(this.destroyed)return;let m=this._getEntryType(l);typeof m!="string"&&(m=await m),m==="directory"&&this._directoryFilter(l)?(o<=this._maxDepth&&this.parents.push({path:l.fullPath,depth:o+1}),this._wantsDir&&(this.push(l),e--)):(m==="file"||this._includeAsFile(l))&&this._fileFilter(l)&&this._wantsFile&&(this.push(l),e--)}}else{let r=this.parents.pop();if(!r){this.push(null);break}let o=r.pending??this._exploreDir(r.path,r.depth),a=this.parents[this.parents.length-1];if(a&&!a.pending&&(a.pending=this._exploreDir(a.path,a.depth)),this.parent=await o,this.destroyed)return}}}catch(n){this.destroy(n)}finally{this.reading=!1}}}async _exploreDir(e,n){let s;try{s=await ps(e,this._rdOptions)}catch(r){this._onError(r)}return{files:s,depth:n,path:e}}_formatEntry(e,n){let s=this._isDirent?e.name:e,r=ws(n,s),o={path:r.slice(this._relStart),fullPath:r,basename:s};return this._isDirent?(o.dirent=e,o):this._stat(r).then(a=>(o.stats=a,o),a=>{this._onError(a)})}_onError(e){ks(e)&&!this.destroyed?this.emit("warn",e):this.destroy(e)}_getEntryType(e){if(!e||!(this._statsProp in e))return"";let n=e[this._statsProp];return n.isFile()?"file":n.isDirectory()?"directory":n.isSymbolicLink()?this._getSymlinkEntryType(e):""}async _getSymlinkEntryType(e){let n=e.fullPath;try{let s=await gs(n),r=await Yn(s);if(r.isFile())return"file";if(r.isDirectory()){let o=s.length;if(n.startsWith(s)&&n[o]===Jn){let a=new Error(`Circular symlink detected: "${n}" points to "${s}"`);return a.code=Zn,this._onError(a),""}return"directory"}}catch(s){this._onError(s)}return""}_includeAsFile(e){let n=e&&e[this._statsProp];return n&&this._wantsEverything&&!n.isDirectory()}};function er(t,e={}){let n=e.entryType||e.type;if(n==="both"&&(n=pe.FILE_DIR_TYPE),t){if(typeof t!="string")throw new TypeError("readdirp: root argument must be a string. Usage: readdirp(root, options)");if(n&&!Kn.includes(n))throw new Error(`readdirp: Invalid type passed. Use one of ${Kn.join(", ")}`)}else throw new Error("readdirp: root argument is required. Usage: readdirp(root, options)");let s={...e,root:t};return n&&(s.type=n),new Yt(s)}import{watch as xs,unwatchFile as tr,watchFile as Ts}from"node:fs";import{realpath as Jt,lstat as Rs,open as Is,stat as rr}from"node:fs/promises";import{type as As}from"node:os";import*as X from"node:path";var Ps="data",Qt="end",sr="close",Ct=()=>{};var xt=process.platform,Zt=xt==="win32",Ds=xt==="darwin",$s=xt==="linux",Ms=xt==="freebsd",or=As()==="OS400",ee={ALL:"all",READY:"ready",ADD:"add",CHANGE:"change",ADD_DIR:"addDir",UNLINK:"unlink",UNLINK_DIR:"unlinkDir",RAW:"raw",ERROR:"error"},ve=ee,Ns="watch",Fs={lstat:Rs,stat:rr},Le="listeners",Et="errHandlers",Be="rawEmitters",Os=[Le,Et,Be],Ls=new Set(["3dm","3ds","3g2","3gp","7z","a","aac","adp","afdesign","afphoto","afpub","ai","aif","aiff","alz","ape","apk","appimage","ar","arj","asf","au","avi","bak","baml","bh","bin","bk","bmp","btif","bz2","bzip2","cab","caf","cgm","class","cmx","cpio","cr2","cur","dat","dcm","deb","dex","djvu","dll","dmg","dng","doc","docm","docx","dot","dotm","dra","DS_Store","dsk","dts","dtshd","dvb","dwg","dxf","ecelp4800","ecelp7470","ecelp9600","egg","eol","eot","epub","exe","f4v","fbs","fh","fla","flac","flatpak","fli","flv","fpx","fst","fvt","g3","gh","gif","graffle","gz","gzip","h261","h263","h264","icns","ico","ief","img","ipa","iso","jar","jpeg","jpg","jpgv","jpm","jxr","key","ktx","lha","lib","lvp","lz","lzh","lzma","lzo","m3u","m4a","m4v","mar","mdi","mht","mid","midi","mj2","mka","mkv","mmr","mng","mobi","mov","movie","mp3","mp4","mp4a","mpeg","mpg","mpga","mxu","nef","npx","numbers","nupkg","o","odp","ods","odt","oga","ogg","ogv","otf","ott","pages","pbm","pcx","pdb","pdf","pea","pgm","pic","png","pnm","pot","potm","potx","ppa","ppam","ppm","pps","ppsm","ppsx","ppt","pptm","pptx","psd","pya","pyc","pyo","pyv","qt","rar","ras","raw","resources","rgb","rip","rlc","rmf","rmvb","rpm","rtf","rz","s3m","s7z","scpt","sgi","shar","snap","sil","sketch","slk","smv","snk","so","stl","suo","sub","swf","tar","tbz","tbz2","tga","tgz","thmx","tif","tiff","tlz","ttc","ttf","txz","udf","uvh","uvi","uvm","uvp","uvs","uvu","viv","vob","war","wav","wax","wbmp","wdp","weba","webm","webp","whl","wim","wm","wma","wmv","wmx","woff","woff2","wrm","wvx","xbm","xif","xla","xlam","xls","xlsb","xlsm","xlsx","xlt","xltm","xltx","xm","xmind","xpi","xpm","xwd","xz","z","zip","zipx"]),js=t=>Ls.has(X.extname(t).slice(1).toLowerCase()),Xt=(t,e)=>{t instanceof Set?t.forEach(e):e(t)},st=(t,e,n)=>{let s=t[e];s instanceof Set||(t[e]=s=new Set([s])),s.add(n)},Us=t=>e=>{let n=t[e];n instanceof Set?n.clear():delete t[e]},ot=(t,e,n)=>{let s=t[e];s instanceof Set?s.delete(n):s===n&&delete t[e]},ir=t=>t instanceof Set?t.size===0:!t,vt=new Map;function nr(t,e,n,s,r){let o=(a,c)=>{n(t),r(a,c,{watchedPath:t}),c&&t!==c&&_t(X.resolve(t,c),Le,X.join(t,c))};try{return xs(t,{persistent:e.persistent},o)}catch(a){s(a);return}}var _t=(t,e,n,s,r)=>{let o=vt.get(t);o&&Xt(o[e],a=>{a(n,s,r)})},Hs=(t,e,n,s)=>{let{listener:r,errHandler:o,rawEmitter:a}=s,c=vt.get(e),l;if(!n.persistent)return l=nr(t,n,r,o,a),l?l.close.bind(l):void 0;if(c)st(c,Le,r),st(c,Et,o),st(c,Be,a);else{if(l=nr(t,n,_t.bind(null,e,Le),o,_t.bind(null,e,Be)),!l)return;l.on(ve.ERROR,async m=>{let d=_t.bind(null,e,Et);if(c&&(c.watcherUnusable=!0),Zt&&m.code==="EPERM")try{await(await Is(t,"r")).close(),d(m)}catch{}else d(m)}),c={listeners:r,errHandlers:o,rawEmitters:a,watcher:l},vt.set(e,c)}return()=>{ot(c,Le,r),ot(c,Et,o),ot(c,Be,a),ir(c.listeners)&&(c.watcher.close(),vt.delete(e),Os.forEach(Us(c)),c.watcher=void 0,Object.freeze(c))}},Kt=new Map,zs=(t,e,n,s)=>{let{listener:r,rawEmitter:o}=s,a=Kt.get(e),c=a&&a.options;return c&&(c.persistent<n.persistent||c.interval>n.interval)&&(tr(e),a=void 0),a?(st(a,Le,r),st(a,Be,o)):(a={listeners:r,rawEmitters:o,options:n,watcher:Ts(e,n,(l,m)=>{Xt(a.rawEmitters,f=>{f(ve.CHANGE,e,{curr:l,prev:m})});let d=l.mtimeMs;(l.size!==m.size||d>m.mtimeMs||d===0)&&Xt(a.listeners,f=>f(t,l))})},Kt.set(e,a)),()=>{ot(a,Le,r),ot(a,Be,o),ir(a.listeners)&&(Kt.delete(e),tr(e),a.options=a.watcher=void 0,Object.freeze(a))}},kt=class{fsw;_boundHandleError;constructor(e){this.fsw=e,this._boundHandleError=n=>e._handleError(n)}_watchWithNodeFs(e,n){let s=this.fsw.options,r=X.dirname(e),o=X.basename(e);this.fsw._getWatchedDir(r).add(o);let c=X.resolve(e),l={persistent:s.persistent};n||(n=Ct);let m;if(s.usePolling){let d=s.interval!==s.binaryInterval;l.interval=d&&js(o)?s.binaryInterval:s.interval,m=zs(e,c,l,{listener:n,rawEmitter:this.fsw._emitRaw})}else m=Hs(e,c,l,{listener:n,errHandler:this._boundHandleError,rawEmitter:this.fsw._emitRaw});return m}_handleFile(e,n,s){if(this.fsw.closed)return;let r=X.dirname(e),o=X.basename(e),a=this.fsw._getWatchedDir(r),c=n;if(a.has(o))return;let l=async(d,f)=>{if(this.fsw._throttle(Ns,e,5)){if(!f||f.mtimeMs===0)try{let u=await rr(e);if(this.fsw.closed)return;let y=u.atimeMs,_=u.mtimeMs;if((!y||y<=_||_!==c.mtimeMs)&&this.fsw._emit(ve.CHANGE,e,u),(Ds||$s||Ms)&&c.ino!==u.ino){this.fsw._closeFile(d),c=u;let T=this._watchWithNodeFs(e,l);T&&this.fsw._addPathCloser(d,T)}else c=u}catch{this.fsw._remove(r,o)}else if(a.has(o)){let u=f.atimeMs,y=f.mtimeMs;(!u||u<=y||y!==c.mtimeMs)&&this.fsw._emit(ve.CHANGE,e,f),c=f}}},m=this._watchWithNodeFs(e,l);if(!(s&&this.fsw.options.ignoreInitial)&&this.fsw._isntIgnored(e)){if(!this.fsw._throttle(ve.ADD,e,0))return;this.fsw._emit(ve.ADD,e,n)}return m}async _handleSymlink(e,n,s,r){if(this.fsw.closed)return;let o=e.fullPath,a=this.fsw._getWatchedDir(n);if(!this.fsw.options.followSymlinks){this.fsw._incrReadyCount();let c;try{c=await Jt(s)}catch{return this.fsw._emitReady(),!0}return this.fsw.closed?void 0:(a.has(r)?this.fsw._symlinkPaths.get(o)!==c&&(this.fsw._symlinkPaths.set(o,c),this.fsw._emit(ve.CHANGE,s,e.stats)):(a.add(r),this.fsw._symlinkPaths.set(o,c),this.fsw._emit(ve.ADD,s,e.stats)),this.fsw._emitReady(),!0)}if(this.fsw._symlinkPaths.has(o))return!0;this.fsw._symlinkPaths.set(o,!0)}_handleRead(e,n,s,r,o,a,c){e=X.join(e,"");let l=r?`${e}:${r}`:e;if(c=this.fsw._throttle("readdir",l,1e3),!c)return;let m=this.fsw._getWatchedDir(s.path),d=new Set,f=this.fsw._readdirp(e,{fileFilter:u=>s.filterPath(u),directoryFilter:u=>s.filterDir(u)});if(f)return f.on(Ps,async u=>{if(this.fsw.closed){f=void 0;return}let y=u.path,_=X.join(e,y);if(d.add(y),!(u.stats.isSymbolicLink()&&await this._handleSymlink(u,e,_,y))){if(this.fsw.closed){f=void 0;return}(y===r||!r&&!m.has(y))&&(this.fsw._incrReadyCount(),_=X.join(o,X.relative(o,_)),this._addToNodeFs(_,n,s,a+1))}}).on(ve.ERROR,this._boundHandleError),new Promise((u,y)=>{if(!f)return y();f.once(Qt,()=>{if(this.fsw.closed){f=void 0;return}let _=c?c.clear():!1;u(void 0),m.getChildren().filter(T=>T!==e&&!d.has(T)).forEach(T=>{this.fsw._remove(e,T)}),f=void 0,_&&this._handleRead(e,!1,s,r,o,a,c)})})}async _handleDir(e,n,s,r,o,a,c){let l=this.fsw._getWatchedDir(X.dirname(e)),m=l.has(X.basename(e));!(s&&this.fsw.options.ignoreInitial)&&!o&&!m&&this.fsw._emit(ve.ADD_DIR,e,n),l.add(X.basename(e)),this.fsw._getWatchedDir(e);let d,f,u=this.fsw.options.depth;if((u==null||r<=u)&&!this.fsw._symlinkPaths.has(c)){if(!o&&(await this._handleRead(e,s,a,o,e,r,d),this.fsw.closed))return;f=this._watchWithNodeFs(e,(y,_)=>{_&&_.mtimeMs===0||this._handleRead(y,!1,a,o,e,r,d)})}return f}async _addToNodeFs(e,n,s,r,o){let a=this.fsw._emitReady;if(this.fsw._isIgnored(e)||this.fsw.closed)return a(),!1;let c=this.fsw._getWatchHelpers(e);s&&(c.filterPath=l=>s.filterPath(l),c.filterDir=l=>s.filterDir(l));try{let l=await Fs[c.statMethod](c.watchPath);if(this.fsw.closed)return;if(this.fsw._isIgnored(c.watchPath,l))return a(),!1;let m=this.fsw.options.followSymlinks,d;if(l.isDirectory()){let f=X.resolve(e),u=m?await Jt(e):e;if(this.fsw.closed||(d=await this._handleDir(c.watchPath,l,n,r,o,c,u),this.fsw.closed))return;f!==u&&u!==void 0&&this.fsw._symlinkPaths.set(f,u)}else if(l.isSymbolicLink()){let f=m?await Jt(e):e;if(this.fsw.closed)return;let u=X.dirname(c.watchPath);if(this.fsw._getWatchedDir(u).add(c.watchPath),this.fsw._emit(ve.ADD,c.watchPath,l),d=await this._handleDir(u,l,n,r,e,c,f),this.fsw.closed)return;f!==void 0&&this.fsw._symlinkPaths.set(X.resolve(e),f)}else d=this._handleFile(c.watchPath,l,n);return a(),d&&this.fsw._addPathCloser(e,d),!1}catch(l){if(this.fsw._handleError(l))return a(),e}}};var en="/",Gs="//",dr=".",Ys="..",Js="string",Ks=/\\/g,fr=/\/\//g,Xs=/\..*\.(sw[px])$|~$|\.subl.*\.tmp/,Qs=/^\.[/\\]/;function Tt(t){return Array.isArray(t)?t:[t]}var tn=t=>typeof t=="object"&&t!==null&&!(t instanceof RegExp);function Zs(t){return typeof t=="function"?t:typeof t=="string"?e=>t===e:t instanceof RegExp?e=>t.test(e):typeof t=="object"&&t!==null?e=>{if(t.path===e)return!0;if(t.recursive){let n=z.relative(t.path,e);return n?!n.startsWith("..")&&!z.isAbsolute(n):!1}return!1}:()=>!1}function eo(t){if(typeof t!="string")throw new Error("string expected");t=z.normalize(t),t=t.replace(/\\/g,"/");let e=!1;return t.startsWith("//")&&(e=!0),t=t.replace(fr,"/"),e&&(t="/"+t),t}function ar(t,e,n){let s=eo(e);for(let r=0;r<t.length;r++){let o=t[r];if(o(s,n))return!0}return!1}function to(t,e){if(t==null)throw new TypeError("anymatch: specify first argument");let s=Tt(t).map(r=>Zs(r));return e==null?(r,o)=>ar(s,r,o):ar(s,e)}var lr=t=>{let e=Tt(t).flat();if(!e.every(n=>typeof n===Js))throw new TypeError(`Non-string provided as watch path: ${e}`);return e.map(hr)},cr=t=>{let e=t.replace(Ks,en),n=!1;return e.startsWith(Gs)&&(n=!0),e=e.replace(fr,en),n&&(e=en+e),e},hr=t=>cr(z.normalize(cr(t))),ur=(t="")=>e=>typeof e=="string"?hr(z.isAbsolute(e)?e:z.join(t,e)):e,no=(t,e)=>z.isAbsolute(t)?t:z.join(e,t),ro=Object.freeze(new Set),nn=class{path;_removeWatcher;items;constructor(e,n){this.path=e,this._removeWatcher=n,this.items=new Set}add(e){let{items:n}=this;n&&e!==dr&&e!==Ys&&n.add(e)}async remove(e){let{items:n}=this;if(!n||(n.delete(e),n.size>0))return;let s=this.path;try{await Bs(s)}catch{this._removeWatcher&&this._removeWatcher(z.dirname(s),z.basename(s))}}has(e){let{items:n}=this;if(n)return n.has(e)}getChildren(){let{items:e}=this;return e?[...e.values()]:[]}dispose(){this.items.clear(),this.path="",this._removeWatcher=Ct,this.items=ro,Object.freeze(this)}},so="stat",oo="lstat",rn=class{fsw;path;watchPath;fullWatchPath;dirParts;followSymlinks;statMethod;constructor(e,n,s){this.fsw=s;let r=e;this.path=e=e.replace(Qs,""),this.watchPath=r,this.fullWatchPath=z.resolve(r),this.dirParts=[],this.dirParts.forEach(o=>{o.length>1&&o.pop()}),this.followSymlinks=n,this.statMethod=n?so:oo}entryPath(e){return z.join(this.watchPath,z.relative(this.watchPath,e.fullPath))}filterPath(e){let{stats:n}=e;if(n&&n.isSymbolicLink())return this.filterDir(e);let s=this.entryPath(e);return this.fsw._isntIgnored(s,n)&&this.fsw._hasReadPermissions(n)}filterDir(e){return this.fsw._isntIgnored(this.entryPath(e),e.stats)}},Rt=class extends qs{closed;options;_closers;_ignoredPaths;_throttled;_streams;_symlinkPaths;_watched;_pendingWrites;_pendingUnlinks;_readyCount;_emitReady;_closePromise;_userIgnored;_readyEmitted;_emitRaw;_boundRemove;_nodeFsHandler;constructor(e={}){super(),this.closed=!1,this._closers=new Map,this._ignoredPaths=new Set,this._throttled=new Map,this._streams=new Set,this._symlinkPaths=new Map,this._watched=new Map,this._pendingWrites=new Map,this._pendingUnlinks=new Map,this._readyCount=0,this._readyEmitted=!1;let n=e.awaitWriteFinish,s={stabilityThreshold:2e3,pollInterval:100},r={persistent:!0,ignoreInitial:!1,ignorePermissionErrors:!1,interval:100,binaryInterval:300,followSymlinks:!0,usePolling:!1,atomic:!0,...e,ignored:e.ignored?Tt(e.ignored):Tt([]),awaitWriteFinish:n===!0?s:typeof n=="object"?{...s,...n}:!1};or&&(r.usePolling=!0),r.atomic===void 0&&(r.atomic=!r.usePolling);let o=process.env.CHOKIDAR_USEPOLLING;if(o!==void 0){let l=o.toLowerCase();l==="false"||l==="0"?r.usePolling=!1:l==="true"||l==="1"?r.usePolling=!0:r.usePolling=!!l}let a=process.env.CHOKIDAR_INTERVAL;a&&(r.interval=Number.parseInt(a,10));let c=0;this._emitReady=()=>{c++,c>=this._readyCount&&(this._emitReady=Ct,this._readyEmitted=!0,process.nextTick(()=>this.emit(ee.READY)))},this._emitRaw=(...l)=>this.emit(ee.RAW,...l),this._boundRemove=this._remove.bind(this),this.options=r,this._nodeFsHandler=new kt(this),Object.freeze(r)}_addIgnoredPath(e){if(tn(e)){for(let n of this._ignoredPaths)if(tn(n)&&n.path===e.path&&n.recursive===e.recursive)return}this._ignoredPaths.add(e)}_removeIgnoredPath(e){if(this._ignoredPaths.delete(e),typeof e=="string")for(let n of this._ignoredPaths)tn(n)&&n.path===e&&this._ignoredPaths.delete(n)}add(e,n,s){let{cwd:r}=this.options;this.closed=!1,this._closePromise=void 0;let o=lr(e);return r&&(o=o.map(a=>no(a,r))),o.forEach(a=>{this._removeIgnoredPath(a)}),this._userIgnored=void 0,this._readyCount||(this._readyCount=0),this._readyCount+=o.length,Promise.all(o.map(async a=>{let c=await this._nodeFsHandler._addToNodeFs(a,!s,void 0,0,n);return c&&this._emitReady(),c})).then(a=>{this.closed||a.forEach(c=>{c&&this.add(z.dirname(c),z.basename(n||c))})}),this}unwatch(e){if(this.closed)return this;let n=lr(e),{cwd:s}=this.options;return n.forEach(r=>{!z.isAbsolute(r)&&!this._closers.has(r)&&(s&&(r=z.join(s,r)),r=z.resolve(r)),this._closePath(r),this._addIgnoredPath(r),this._watched.has(r)&&this._addIgnoredPath({path:r,recursive:!0}),this._userIgnored=void 0}),this}close(){if(this._closePromise)return this._closePromise;this.closed=!0,this.removeAllListeners();let e=[];return this._closers.forEach(n=>n.forEach(s=>{let r=s();r instanceof Promise&&e.push(r)})),this._streams.forEach(n=>n.destroy()),this._userIgnored=void 0,this._readyCount=0,this._readyEmitted=!1,this._watched.forEach(n=>n.dispose()),this._closers.clear(),this._watched.clear(),this._streams.clear(),this._symlinkPaths.clear(),this._throttled.clear(),this._closePromise=e.length?Promise.all(e).then(()=>{}):Promise.resolve(),this._closePromise}getWatched(){let e={};return this._watched.forEach((n,s)=>{let o=(this.options.cwd?z.relative(this.options.cwd,s):s)||dr;e[o]=n.getChildren().sort()}),e}emitWithAll(e,n){this.emit(e,...n),e!==ee.ERROR&&this.emit(ee.ALL,e,...n)}async _emit(e,n,s){if(this.closed)return;let r=this.options;Zt&&(n=z.normalize(n)),r.cwd&&(n=z.relative(r.cwd,n));let o=[n];s!=null&&o.push(s);let a=r.awaitWriteFinish,c;if(a&&(c=this._pendingWrites.get(n)))return c.lastChange=new Date,this;if(r.atomic){if(e===ee.UNLINK)return this._pendingUnlinks.set(n,[e,...o]),setTimeout(()=>{this._pendingUnlinks.forEach((l,m)=>{this.emit(...l),this.emit(ee.ALL,...l),this._pendingUnlinks.delete(m)})},typeof r.atomic=="number"?r.atomic:100),this;e===ee.ADD&&this._pendingUnlinks.has(n)&&(e=ee.CHANGE,this._pendingUnlinks.delete(n))}if(a&&(e===ee.ADD||e===ee.CHANGE)&&this._readyEmitted){let l=(m,d)=>{m?(e=ee.ERROR,o[0]=m,this.emitWithAll(e,o)):d&&(o.length>1?o[1]=d:o.push(d),this.emitWithAll(e,o))};return this._awaitWriteFinish(n,a.stabilityThreshold,e,l),this}if(e===ee.CHANGE&&!this._throttle(ee.CHANGE,n,50))return this;if(r.alwaysStat&&s===void 0&&(e===ee.ADD||e===ee.ADD_DIR||e===ee.CHANGE)){let l=r.cwd?z.join(r.cwd,n):n,m;try{m=await Vs(l)}catch{}if(!m||this.closed)return;o.push(m)}return this.emitWithAll(e,o),this}_handleError(e){let n=e&&e.code;return e&&n!=="ENOENT"&&n!=="ENOTDIR"&&(!this.options.ignorePermissionErrors||n!=="EPERM"&&n!=="EACCES")&&this.emit(ee.ERROR,e),e||this.closed}_throttle(e,n,s){this._throttled.has(e)||this._throttled.set(e,new Map);let r=this._throttled.get(e);if(!r)throw new Error("invalid throttle");let o=r.get(n);if(o)return o.count++,!1;let a,c=()=>{let m=r.get(n),d=m?m.count:0;return r.delete(n),clearTimeout(a),m&&clearTimeout(m.timeoutObject),d};a=setTimeout(c,s);let l={timeoutObject:a,clear:c,count:0};return r.set(n,l),l}_incrReadyCount(){return this._readyCount++}_awaitWriteFinish(e,n,s,r){let o=this.options.awaitWriteFinish;if(typeof o!="object")return;let a=o.pollInterval,c,l=e;this.options.cwd&&!z.isAbsolute(e)&&(l=z.join(this.options.cwd,e));let m=new Date,d=this._pendingWrites;function f(u){Ws(l,(y,_)=>{if(y||!d.has(e)){y&&y.code!=="ENOENT"&&r(y);return}let T=Number(new Date);u&&_.size!==u.size&&(d.get(e).lastChange=T);let v=d.get(e);T-v.lastChange>=n?(d.delete(e),r(void 0,_)):c=setTimeout(f,a,_)})}d.has(e)||(d.set(e,{lastChange:m,cancelWait:()=>(d.delete(e),clearTimeout(c),s)}),c=setTimeout(f,a))}_isIgnored(e,n){if(this.options.atomic&&Xs.test(e))return!0;if(!this._userIgnored){let{cwd:s}=this.options,o=(this.options.ignored||[]).map(ur(s)),c=[...[...this._ignoredPaths].map(ur(s)),...o];this._userIgnored=to(c,void 0)}return this._userIgnored(e,n)}_isntIgnored(e,n){return!this._isIgnored(e,n)}_getWatchHelpers(e){return new rn(e,this.options.followSymlinks,this)}_getWatchedDir(e){let n=z.resolve(e);return this._watched.has(n)||this._watched.set(n,new nn(n,this._boundRemove)),this._watched.get(n)}_hasReadPermissions(e){return this.options.ignorePermissionErrors?!0:!!(Number(e.mode)&256)}_remove(e,n,s){let r=z.join(e,n),o=z.resolve(r);if(s=s??(this._watched.has(r)||this._watched.has(o)),!this._throttle("remove",r,100))return;!s&&this._watched.size===1&&this.add(e,n,!0),this._getWatchedDir(r).getChildren().forEach(u=>this._remove(r,u));let l=this._getWatchedDir(e),m=l.has(n);l.remove(n),this._symlinkPaths.has(o)&&this._symlinkPaths.delete(o);let d=r;if(this.options.cwd&&(d=z.relative(this.options.cwd,r)),this.options.awaitWriteFinish&&this._pendingWrites.has(d)&&this._pendingWrites.get(d).cancelWait()===ee.ADD)return;this._watched.delete(r),this._watched.delete(o);let f=s?ee.UNLINK_DIR:ee.UNLINK;m&&!this._isIgnored(r)&&this._emit(f,r),this._closePath(r)}_closePath(e){this._closeFile(e);let n=z.dirname(e);this._getWatchedDir(n).remove(z.basename(e))}_closeFile(e){let n=this._closers.get(e);n&&(n.forEach(s=>s()),this._closers.delete(e))}_addPathCloser(e,n){if(!n)return;let s=this._closers.get(e);s||(s=[],this._closers.set(e,s)),s.push(n)}_readdirp(e,n){if(this.closed)return;let s={type:ee.ALL,alwaysStat:!0,lstat:!0,...n,depth:0},r=er(e,s);return this._streams.add(r),r.once(sr,()=>{r=void 0}),r.once(Qt,()=>{r&&(this._streams.delete(r),r=void 0)}),r}};function io(t,e={}){let n=new Rt(e);return n.add(t),n}var mr={watch:io,FSWatcher:Rt};function ao(t,e){let n=Object.create(null);for(let o=0;o<e.length;o++){let a=e[o];n[a]?n[a].push(o):n[a]=[o]}let r=[{buffer1index:-1,buffer2index:-1,chain:null}];for(let o=0;o<t.length;o++){let a=t[o],c=n[a]||[],l=0,m=r[0];for(let d of c){let f;for(f=l;f<r.length&&!(r[f].buffer2index<d&&(f===r.length-1||r[f+1].buffer2index>d));f++);if(f<r.length){let u={buffer1index:o,buffer2index:d,chain:r[f]};if(l===r.length?r.push(m):r[l]=m,l=f+1,m=u,l===r.length)break}}r[l]=m}return r[r.length-1]}function pr(t,e){let n=ao(t,e),s=[],r=t.length,o=e.length;for(let a=n;a!==null;a=a.chain){let c=r-a.buffer1index-1,l=o-a.buffer2index-1;r=a.buffer1index,o=a.buffer2index,(c||l)&&s.push({buffer1:[r+1,c],buffer1Content:t.slice(r+1,r+1+c),buffer2:[o+1,l],buffer2Content:e.slice(o+1,o+1+l)})}return s.reverse(),s}function lo(t,e,n){let s=[];function r(l,m){s.push({ab:m,oStart:l.buffer1[0],oLength:l.buffer1[1],abStart:l.buffer2[0],abLength:l.buffer2[1]})}pr(e,t).forEach(l=>r(l,"a")),pr(e,n).forEach(l=>r(l,"b")),s.sort((l,m)=>l.oStart-m.oStart);let o=[],a=0;function c(l){l>a&&(o.push({stable:!0,buffer:"o",bufferStart:a,bufferLength:l-a,bufferContent:e.slice(a,l)}),a=l)}for(;s.length;){let l=s.shift(),m=l.oStart,d=l.oStart+l.oLength,f=[l];for(c(m);s.length;){let u=s[0],y=u.oStart;if(y>d)break;d=Math.max(d,y+u.oLength),f.push(s.shift())}if(f.length===1){if(l.abLength>0){let u=l.ab==="a"?t:n;o.push({stable:!0,buffer:l.ab,bufferStart:l.abStart,bufferLength:l.abLength,bufferContent:u.slice(l.abStart,l.abStart+l.abLength)})}}else{let u={a:[t.length,-1,e.length,-1],b:[n.length,-1,e.length,-1]};for(;f.length;){l=f.shift();let N=l.oStart,Y=N+l.oLength,G=l.abStart,W=G+l.abLength,Q=u[l.ab];Q[0]=Math.min(G,Q[0]),Q[1]=Math.max(W,Q[1]),Q[2]=Math.min(N,Q[2]),Q[3]=Math.max(Y,Q[3])}let y=u.a[0]+(m-u.a[2]),_=u.a[1]+(d-u.a[3]),T=u.b[0]+(m-u.b[2]),v=u.b[1]+(d-u.b[3]),O={stable:!1,aStart:y,aLength:_-y,aContent:t.slice(y,_),oStart:m,oLength:d-m,oContent:e.slice(m,d),bStart:T,bLength:v-T,bContent:n.slice(T,v)};o.push(O)}a=d}return c(e.length),o}function gr(t,e,n,s){s=Object.assign({excludeFalseConflicts:!0,stringSeparator:/\s+/},s),typeof t=="string"&&(t=t.split(s.stringSeparator)),typeof e=="string"&&(e=e.split(s.stringSeparator)),typeof n=="string"&&(n=n.split(s.stringSeparator));let o=[],a=lo(t,e,n),c=[];function l(){c.length&&o.push({ok:c}),c=[]}function m(d,f){if(d.length!==f.length)return!1;for(let u=0;u<d.length;u++)if(d[u]!==f[u])return!1;return!0}return a.forEach(d=>{d.stable?c.push(...d.bufferContent):s.excludeFalseConflicts&&m(d.aContent,d.bContent)?c.push(...d.aContent):(l(),o.push({conflict:{a:d.aContent,aIndex:d.aStart,o:d.oContent,oIndex:d.oStart,b:d.bContent,bIndex:d.bStart}}))}),l(),o}function It(t,e){let n=t.lastIndexOf("/"),s=n<0?"":t.slice(0,n+1),r=n<0?t:t.slice(n+1),o=r.lastIndexOf("."),a=o>0?r.slice(0,o):r,c=o>0?r.slice(o):"",l=d=>String(d).padStart(2,"0"),m=`${e.getFullYear()}-${l(e.getMonth()+1)}-${l(e.getDate())} ${l(e.getHours())}${l(e.getMinutes())}`;return`${s}${a} (conflict ${m})${c}`}function co(t,e){if(e<2)return t;let n=t.lastIndexOf("."),s=n>t.lastIndexOf("/")&&n>t.lastIndexOf(")"),r=s?t.slice(0,n):t,o=s?t.slice(n):"";return`${r}-${e}${o}`}function uo(t){let e=3735928559,n=1103547991;for(let r=0;r<t.length;r++){let o=t.charCodeAt(r);e=Math.imul(e^o,2654435761),n=Math.imul(n^o,1597334677)}e=Math.imul(e^e>>>16,2246822507)^Math.imul(n^n>>>13,3266489909),n=Math.imul(n^n>>>16,2246822507)^Math.imul(e^e>>>13,3266489909);let s=4294967296*(2097151&n)+(e>>>0);return`${t.length.toString(36)}-${s.toString(36)}`}function At(t,e,n){if(t===null&&e===null&&n===null)return{kind:"none"};if(n===null)return t===null?e?{kind:"dropShadow"}:{kind:"none"}:e?t===e.hash?{kind:"deleteLocal"}:{kind:"pushCreate"}:{kind:"pushCreate"};if(t===null)return e?n.seq===e.seq?{kind:"pushDelete"}:{kind:"pull"}:{kind:"pull"};if(!e)return t===n.hash?{kind:"adopt"}:{kind:"conflict"};let s=t!==e.hash,r=n.seq!==e.seq;return!s&&!r?{kind:"none"}:s?r?t===n.hash?{kind:"adopt"}:n.hash===e.hash?{kind:"push",baseSeq:n.seq}:{kind:"conflict"}:{kind:"push",baseSeq:e.seq}:{kind:"pull"}}function yr(t,e,n){let s=gr(t.split(`
|
|
194
194
|
`),e.split(`
|
|
195
|
-
`),
|
|
195
|
+
`),n.split(`
|
|
196
196
|
`),{excludeFalseConflicts:!0}),r=[];for(let o of s){if(o.conflict)return null;o.ok&&r.push(...o.ok)}return r.join(`
|
|
197
|
-
`)}function sn(
|
|
198
|
-
`),
|
|
199
|
-
`);if(j<0)break;let te=u.slice(0,j).replace(/\r$/,"");if(u=u.slice(j+1),te==="")R();else{if(te.startsWith(":"))continue;te.startsWith("event:")?w=te.slice(6).trim():te.startsWith("data:")&&v.push(te.slice(5).replace(/^ /,""))}}}}catch(_){t||c(_);return}c(new Error("sse stream ended"))};return l(),{stop:()=>{t=!0,o&&clearTimeout(o),r?.abort()}}}import{constants as go,promises as Ye}from"node:fs";import yo from"node:path";var Ge=n=>yo.join(de().userDataDir(),de().isDevMode()?`${n}.dev.json`:`${n}.json`);async function an(n){try{let e=JSON.parse(await Ye.readFile(Ge(n),"utf8"));return!e||typeof e.vaultRoot!="string"||typeof e.vaultId!="string"?null:(e.files=e.files??{},e.cursor=Number(e.cursor??0),e.lastSyncAt=e.lastSyncAt??null,e)}catch{return null}}function vr(n){let e=null,t=null,s=Promise.resolve(),r=null,o=()=>{if(!e)return s;let a=e,c=JSON.stringify(e);return e=null,s=s.then(async()=>{try{let l=Ge(n),h=`${l}.tmp-${process.pid}-${Date.now()}-0`;await Ye.writeFile(h,c,"utf8"),await Ye.rename(h,l),r=null}catch(l){e??=a,r=l}}),s};return{save(a){e=a,!t&&(t=setTimeout(()=>{t=null,o()},500))},async flush(a=!1){if(t&&(clearTimeout(t),t=null),await o(),a&&r)throw r}}}async function _r(n){try{await Ye.unlink(Ge(n))}catch{}}async function kr(n,e){try{await Ye.copyFile(Ge(n),Ge(e),go.COPYFILE_EXCL)}catch(t){let s=t?.code;if(s==="EEXIST"||s==="ENOENT")return!1;throw t}return await Ye.unlink(Ge(n)).catch(()=>{}),!0}var bo=5*1024*1024,So=5*1024*1024,Eo=3e4,vo=2500,_o=3e3,ko=5,Co=256*1024,xo=5,xr=1024*1024,Tr=200,To=6e4,Ro=50,Io=".sync-trash",Je=n=>wo("sha256").update(n).digest("hex");function at(n,e={localRoot:De(),shadowName:`amadeus-sync-${rt()}`,vaultId:"first",serverDir:"",excludePrefixes:["\u4E0E\u6211\u5171\u4EAB/"]}){let t=i=>{let d=on(i,"");if(!d)return null;for(let p of e.excludePrefixes??[])if(d===p.replace(/\/$/,"")||d.startsWith(p))return null;if(e.ignoreNames?.length&&d.split("/").some(p=>e.ignoreNames.includes(p)))return null;let g=e.serverDir?`${e.serverDir}/${d}`:d;return e.inScope&&!e.inScope(g,Ce(g))?null:g},s=i=>{let d;if(e.serverDir){if(!i.startsWith(`${e.serverDir}/`))return null;d=i.slice(e.serverDir.length+1)}else{for(let g of e.excludePrefixes??[])if(i.startsWith(g))return null;d=i}return d.split("/").some(g=>it(g)||!!e.ignoreNames?.includes(g))?null:d},r=(i,d)=>!e.inScope||e.inScope(i,d),o=e.accountId??fe(),a=!1,c=0,l=Promise.resolve(),h=new Set,f="disabled",m=null,u=null,w=null,v=null,R=null,_=null,L=0,j=new Map,te=null,G=vr(e.shadowName),B=new Map,X=!1,Y=!1,ne=[],ue=()=>{u&&(u.pending=B.size?Object.fromEntries(B):void 0,G.save(u))},ut=()=>{Y=!1,ne.length=0},Qe=()=>{if(Y)return!0;let i=Date.now();for(;ne.length&&i-ne[0]>To;)ne.shift();return ne.length>=Ro?(Y=!0,!0):!1},xe=[],Ne=new Set,Ze=!1,E=null,C=null,y=null,b=()=>{!a||y||(y=setTimeout(()=>{y=null,n.onStatus(Oe())},200))},A=(i,d)=>{f=i,d!==void 0&&(m=d),b()},S=(i,d=!1)=>{if(a){if(i.key){if(Ne.has(i.key))return;Ne.add(i.key)}d?xe.unshift(i):xe.push(i),V()}},x=new Map,D=i=>{if(!a)return;let d=(u?.files[i]?.size??0)>Co,g=(e.pushQuietMs??_o)*(d?xo:1),p=Date.now(),k=x.get(i);k&&clearTimeout(k.timer);let I=k?.since??p,$=Math.max(0,Math.min(g,I+g*ko-p)),T=setTimeout(()=>{x.delete(i),S({key:i,run:()=>ae(i,!0)})},$);x.set(i,{timer:T,since:I}),b()},U=()=>{for(let{timer:i}of x.values())clearTimeout(i);x.clear()},N=i=>!(i instanceof le)||i.status>=500||i.status===0,F=i=>i instanceof le&&(i.status===401||i.status===403),V=async()=>{if(!Ze){Ze=!0;try{for(;xe.length;){(f==="idle"||f==="starting")&&A("syncing");let i=xe.shift();i.key&&Ne.delete(i.key);try{await i.run()}catch(d){if(!a)return;if(F(d)){xe.length=0,Ne.clear(),gt(),A("auth-required","login-expired");return}if(N(d)){S(i,!0),gt(),A("offline",d?.message||"network error"),W();return}let g=i.key??"(op)";j.set(g,d?.body?.code||`http ${d?.status}`),b()}}a&&f==="syncing"&&(u&&(u.lastSyncAt=Date.now(),G.save(u)),A("idle",null))}finally{Ze=!1;for(let i of h)i();h.clear()}}},W=()=>{!a||E||(E=setTimeout(()=>{E=null,tt()},Eo))},q=i=>{if(!_||!u)throw new Error("engine not bound");let d=s(i);if(d===null)throw new Error("path outside binding: "+i);let g=se.resolve(_,wr(d,u.folder)),p=se.relative(_,g);if(p.startsWith("..")||se.isAbsolute(p))throw new Error("path escapes vault: "+i);return g},Q=i=>({size:i,mtimeMs:-1}),J=async i=>{try{let d=await ee.stat(i);return d.isFile()?{size:d.size,mtimeMs:Math.floor(d.mtimeMs)}:null}catch{return null}},we=0,Fe=async(i,d,g=()=>!0)=>{await ee.mkdir(se.dirname(i),{recursive:!0});let p=`${i}.tmp-${process.pid}-${Date.now()}-${we++}`;await ee.writeFile(p,d);let k=await J(p)??Q(Buffer.byteLength(d));return g()?(await ee.rename(p,i),k):(await ee.rm(p,{force:!0}),null)},Ue=async i=>{let d;try{d=await ee.readdir(i,{withFileTypes:!0})}catch{return}for(let g of d)g.isDirectory()&&await Ue(se.join(i,g.name));try{await ee.rmdir(i)}catch{}},oe=async i=>{let d=q(i),g=await J(d),p;try{p=await ee.readFile(d)}catch{return null}return{hash:$e(Ce(i))?Je(p.toString("utf8")):Je(p),size:g?.size??p.length,mtimeMs:g?.mtimeMs??-1,buf:p}},_e=async(i,d,g,p)=>{u&&(u.files[i]={seq:d,hash:g,size:p.size,mtimeMs:p.mtimeMs},G.save(u))},ye=i=>{u&&i in u.files&&(delete u.files[i],G.save(u))},Te=async(i,d)=>{if(!w||!u||be(i))return;let g=re,p=Ce(i),k,I,$;if($e(p)){let O;try{O=await w.getFile(u.vaultId,i)}catch(H){if(H instanceof le&&H.status===404){await $t(i);return}throw H}k=O.content,I=O.seq,$=O.hash??Je(O.content)}else{let O;try{O=await w.getAsset(u.vaultId,i)}catch(H){if(H instanceof le&&H.status===404){j.set(i,"ASSET_404"),b();return}throw H}k=O,I=d??0,$=Je(O)}let T=await oe(i);if(g!==re||be(i))return;if(T&&T.hash===$){await _e(i,I,$,T);return}let M=u.files[i];if(T&&M&&$===M.hash&&T.hash!==M.hash){await _e(i,I,$,Q(M.size)),S({key:i,run:()=>ae(i)});return}if(T&&(!M||T.hash!==M.hash)){if(M&&p==="page"&&typeof k=="string"&&await Or(i,M,T,k,I,$,()=>g===re&&!be(i))||g!==re||be(i))return;await Lr(i)}let P=await Fe(q(i),k,()=>g===re&&!be(i));P&&await _e(i,I,$,P)},Or=async(i,d,g,p,k,I,$)=>{try{if(!w||!u||g.buf.length>xr||p.length>xr)return!1;let M=(await w.listVersions(u.vaultId,i)).find(H=>H.seq===d.seq);if(!M)return!1;let P=await w.getVersion(u.vaultId,M.id);if(Je(P)!==d.hash)return!1;let O=yr(g.buf.toString("utf8"),P,p);return O===null?!1:(await Fe(q(i),O,$)&&(await _e(i,k,I,Q(Buffer.byteLength(O))),S({key:i,run:()=>ae(i)})),!0)}catch{return!1}},Lr=async i=>{let d=Ve(It(i,new Date));if(!d)return;let g=d.lastIndexOf("."),p=g>d.lastIndexOf("/"),k=p?d.slice(0,g):d,I=p?d.slice(g):"",$=d;for(let T=2;Cr(q($));T++)$=`${k}-${T}${I}`;try{await ee.rename(q(i),q($))}catch(T){if(T?.code==="ENOENT")return;throw T}L++,S({key:$,run:()=>ae($)}),b()},yn=async i=>{if(!_)return;let d=q(i),g=s(i)??i,p=se.join(_,Io,new Date().toISOString().slice(0,10),...g.split("/")),k=Cr(p)?`${p}.${Date.now()}`:p;try{await ee.mkdir(se.dirname(k),{recursive:!0}),await ee.rename(d,k)}catch(I){if(I?.code==="ENOENT")return;throw new Error(`\u8F6F\u5220\u5931\u8D25,\u4FDD\u7559\u672C\u5730\u6587\u4EF6 ${d}: ${I?.message??String(I)}`)}},$t=async i=>{if(!u)return;let d=await oe(i);if(be(i))return;let g=u.files[i]??null,p=At(d?.hash??null,g,null);if(p.kind==="deleteLocal"){if(!X&&Qe()){B.set(i,"local"),ue(),b();return}ne.push(Date.now()),await yn(i),ye(i)}else p.kind==="pushCreate"?(ye(i),S({key:i,run:()=>ae(i)})):ye(i)},wn=(i,d)=>{if(u){for(let g of Object.keys(u.files))if(g===i||g.startsWith(`${i}/`)){let p=d+g.slice(i.length);u.files[p]=u.files[g],delete u.files[g]}G.save(u)}},bn=async i=>{if(!w||!u||i.seq<=u.cursor||!await ht())return;if(i.origin.client&&w.clientId===i.origin.client){u.cursor=i.seq,G.save(u);return}let d=i.type==="structure"?"folder":i.type,g=k=>s(k)!==null&&r(k,d);if(!g(i.path)&&!(i.newPath&&g(i.newPath))){u.cursor=i.seq,G.save(u);return}let p=i.path;switch(i.op){case"write":await Te(p,i.fileSeq);break;case"delete":await $t(p);break;case"move":{let k=i.newPath;if(!k)break;let I=u.files[p];if(await oe(p)&&I)try{await ee.mkdir(se.dirname(q(k)),{recursive:!0}),await ee.rename(q(p),q(k)),u.files[k]={...I,seq:i.fileSeq??I.seq},delete u.files[p],G.save(u)}catch{await Te(k,i.fileSeq)}else ye(p),await Te(k,i.fileSeq);break}case"mkdir":await ee.mkdir(q(p),{recursive:!0});break;case"rename-folder":case"move-folder":{let k=i.newPath;if(!k)break;try{await ee.mkdir(se.dirname(q(k)),{recursive:!0}),await ee.rename(q(p),q(k))}catch{}wn(p,k);break}case"delete-folder":{let k=`${p}/`;for(let I of Object.keys(u.files))(I===p||I.startsWith(k))&&await $t(I);await Ue(q(p));break}}if(u.cursor=i.seq,G.save(u),i.op==="move"||i.op==="rename-folder"||i.op==="move-folder"||i.op==="delete"||i.op==="delete-folder")try{await n.onRemoteApplied?.(i)}catch{}},jr=async(i,d,g)=>{let p=Number(d?.seq??0),k=d?.content??null;if(k!==null&&Je(k)===g.hash){await _e(i,p,g.hash,g);return}if(k===null&&p===0){if(!u?.files[i]){j.set(i,d?.code||"EXISTS"),b();return}ye(i),S({key:i,run:()=>ae(i)});return}await Te(i,p)},dt=async(i,d)=>{if(!w||!u)return;let g=await oe(i);if(!g){S({key:i,run:()=>ae(i)});return}if(g.size>bo){j.set(i,"TOO_LARGE"),b();return}let p=g.buf.toString("utf8");try{let k=await w.putFile(u.vaultId,i,p,d);j.delete(i),await _e(i,k.seq,k.hash??g.hash,g)}catch(k){if(k instanceof le&&k.status===409){await jr(i,k.body,g);return}throw k}},ft=async(i,d)=>{if(!w||!u)return;let g=await oe(i);if(!g){S({key:i,run:()=>ae(i)});return}if(g.size>(te??So)){j.set(i,"TOO_LARGE"),b();return}try{let p=await w.putBinary(u.vaultId,i,g.buf,{baseSeq:d});j.delete(i),await _e(i,p.seq,g.hash,g)}catch(p){if(p instanceof le&&p.status===409){let k=Number(p.body?.seq??0),I=p.body?.hash??null;if(I!==null&&I===g.hash){await _e(i,k,g.hash,g);return}if(k===0){if(!u.files[i]){j.set(i,p.body?.code||"EXISTS"),b();return}ye(i),S({key:i,run:()=>ae(i)});return}await Te(i,k);return}throw p}},Sn=async i=>{if(!w||!u||be(i))return;let d=re,g=u.files[i];if(g){if($e(Ce(i)))try{let p=await w.getFile(u.vaultId,i);if(p.seq!==g.seq){await Te(i,p.seq);return}}catch(p){if(p instanceof le&&p.status===404){ye(i);return}throw p}if(!(d!==re||be(i))){try{await w.deleteFile(u.vaultId,i,g.seq,{confirmed:X})}catch(p){if(p instanceof le&&p.status===409){await Te(i,Number(p.body?.seq??0)||null);return}if(p instanceof le&&p.status===429&&p.body?.code==="MASS_DELETE_BLOCKED"){B.set(i,"remote"),Y=!0,ue(),b();return}throw p}ye(i)}}},ht=async()=>_?await ee.stat(_).then(d=>d.isDirectory()).catch(()=>!1)||!e.requireRootExists&&!Object.keys(u?.files??{}).length?!0:(A("error",`vault-missing: ${_}`),W(),!1):!1,re=0,mt=new Set,pt=new Map,he=i=>JSON.stringify([i.from,i.to]),Pe=(i,d)=>i===d||i.startsWith(`${d}/`),be=i=>[...u?.moves??[],...mt].some(d=>Pe(i,d.from)||Pe(i,d.to)),Re=()=>!!(u?.moves?.length||mt.size),Mt=async i=>{if(!w||!u)return;let{from:d,to:g,kind:p}=i;if(s(d)===null||s(g)===null)throw new Error("Invalid queued cloud move");i.hashes??=Object.fromEntries(Object.entries(u.files).filter(([T])=>Pe(T,d)).map(([T,M])=>[T.slice(d.length),M.hash])),G.save(u),await G.flush(!0);let k,I=!1;try{if(p==="folder"){let T=se.posix.dirname(d)==="."?"":se.posix.dirname(d),M=se.posix.dirname(g)==="."?"":se.posix.dirname(g);T===M?await w.renameFolder(u.vaultId,d,se.posix.basename(g)):await w.moveFolder(u.vaultId,d,M)}else{let T=await w.move(u.vaultId,d,g);k=Number(T.seq)}}catch(T){if(!(T instanceof le)||T.status!==404)throw T;let M=await w.tree(u.vaultId);if(M.entries.some(H=>Pe(H.path,d))||M.folders.some(H=>Pe(H,d)))throw T;let O=M.entries.find(H=>H.path===g);if(k=O?.seq,I=!O&&!M.entries.some(H=>Pe(H.path,g))&&!M.folders.some(H=>Pe(H,g)),!I){let H=Object.entries(i.hashes);if(!(H.length>0&&H.every(([ke,He])=>M.entries.some(ze=>ze.path===g+ke&&ze.hash===He))))throw new le(409,{code:"MOVE_DESTINATION_CHANGED"},"local-move")}}if(I)for(let T of Object.keys(u.files))Pe(T,d)&&delete u.files[T];else wn(d,g),k!==void 0&&u.files[g]&&(u.files[g].seq=k);u.moves=(u.moves??[]).filter(T=>he(T)!==he(i)),G.save(u);try{await G.flush(!0)}catch(T){throw u.moves.unshift(i),G.save(u),T}let $=pt.get(he(i));pt.delete(he(i)),$?.(),be(g)||(p==="folder"?await Nt():await ae(g))},ae=async(i,d=!1)=>{if(!u||be(i))return;if(!r(i,Ce(i))){ye(i);return}if(!await ht())return;let g=await oe(i);if(be(i))return;let p=u.files[i]??null,k=At(g?.hash??null,p,p?{seq:p.seq,hash:p.hash}:null);switch(k.kind){case"push":$e(Ce(i))?await dt(i,k.baseSeq):await ft(i,k.baseSeq);break;case"pushCreate":$e(Ce(i))?await dt(i,0):await ft(i,0);break;case"pushDelete":if(d){wt();break}if(!X&&(B.has(i)||Qe())){B.set(i,"remote"),ue(),b();break}ne.push(Date.now()),await Sn(i);break;case"dropShadow":ye(i);break;default:g&&p&&g.hash===p.hash&&g.mtimeMs>=0&&(p.size!==g.size||p.mtimeMs!==g.mtimeMs)&&await _e(i,p.seq,p.hash,g);break}},En=async()=>{let i=new Map;if(!_||!u)return i;let d=_,g=null,p=async k=>{if(g)return;let I;try{I=await ee.readdir(k,{withFileTypes:!0})}catch($){g=`${k}: ${$?.message??String($)}`;return}for(let $ of I){if(it($.name)||$.isDirectory()&&e.ignoreNames?.includes($.name))continue;let T=se.join(k,$.name);if($.isDirectory())await p(T);else if($.isFile()){let M=se.relative(d,T).split(se.sep).join("/"),P=t(M);if(!P)continue;try{let O=await ee.stat(T);if(!O.isFile())continue;i.set(P,{size:O.size,mtimeMs:Math.floor(O.mtimeMs)})}catch(O){if(O?.code==="ENOENT")continue;g=`${T}: ${O?.message??String(O)}`;return}}}};return await p(d),g?(A("error",`scan-failed: ${g}`),W(),null):i},Nt=async()=>{let i=re;if(Re()||i!==re||!u||!await ht())return;let d=await En();if(!d||Re()||i!==re)return;let g=!1;for(let[I,$]of[...B])($==="remote"&&d.has(I)||$==="local"&&!d.has(I))&&(B.delete(I),g=!0);B.size||ut();for(let[I,$]of d){let T=u.files[I];T&&T.size===$.size&&T.mtimeMs===$.mtimeMs||S({key:I,run:()=>ae(I)})}let p=Object.keys(u.files),k=p.filter(I=>!d.has(I));if(k.length&&!X&&(Y||sn(k.length,p.length,Tr))){Y=!0;for(let I of k)B.set(I,"remote");ue(),b();return}g&&(ue(),b());for(let I of k)B.has(I)||S({key:I,run:()=>ae(I)})},et=async()=>{let i=re;if(Re()||i!==re||!w||!u||!_||!await ht())return;let d=await w.tree(u.vaultId);if(d.maxFileBytes!==void 0&&d.maxFileBytes!==te&&(te=d.maxFileBytes,b()),Re()||i!==re)return;let g=new Map;for(let P of d.entries)s(P.path)===null||!r(P.path,P.kind)||g.set(P.path,P);let p=await En();if(!p||Re()||i!==re)return;let k=new Set([...g.keys(),...p.keys(),...Object.keys(u.files)]),I=Object.keys(u.files).length,$=[];for(let P of k){if(Re()||i!==re)return;let O=u.files[P]??null,H=g.get(P)??null,ce=p.get(P)??null,ke=null,He=Q(ce?.size??0);if(ce)if(O&&O.size===ce.size&&O.mtimeMs===ce.mtimeMs)ke=O.hash,He=ce;else{let ze=await oe(P);ze&&(ke=ze.hash,He=ze)}$.push({sp:P,d:At(ke,O,H?{seq:H.seq,hash:H.hash}:null),rSeq:H?.seq??null,localHash:ke,localStat:He})}if(Re()||i!==re)return;let T=$.filter(P=>P.d.kind==="deleteLocal"||P.d.kind==="pushDelete").length,M=!X&&(Y||sn(T,I,Tr));M&&T&&(Y=!0),B.clear();for(let{sp:P,d:O,rSeq:H,localHash:ce,localStat:ke}of $){if(Re()||i!==re)return;if(M&&(O.kind==="deleteLocal"||O.kind==="pushDelete")){B.set(P,O.kind==="deleteLocal"?"local":"remote");continue}if((O.kind==="deleteLocal"||O.kind==="pushDelete")&&((await oe(P))?.hash??null)!==ce){S({key:P,run:()=>ae(P)});continue}if(Re()||i!==re)return;switch(O.kind){case"adopt":await _e(P,H,ce,ke);break;case"pull":await Te(P,H);break;case"push":$e(Ce(P))?await dt(P,O.baseSeq):await ft(P,O.baseSeq);break;case"pushCreate":$e(Ce(P))?await dt(P,0):await ft(P,0);break;case"pushDelete":await Sn(P);break;case"deleteLocal":await yn(P),ye(P);break;case"conflict":await Te(P,H);break;case"dropShadow":ye(P);break;case"none":break}}X&&(X=!1,ne.length=0),B.size||ut(),ue(),M&&b();for(let P of d.folders)if(!(s(P)===null||!r(P,"folder")))try{await ee.mkdir(q(P),{recursive:!0})}catch{}u.cursor=d.seq,u.lastSyncAt=Date.now(),G.save(u)},Ur=async()=>{if(!w||!u)return;let i=u.cursor,d=await w.changes(u.vaultId,i);if(d.changes.length===0&&d.seq>i||d.changes.length>0&&d.changes[0].seq!==i+1){await et();return}for(let p of d.changes)await bn(p)},Ie=null,vn=[],_n=()=>{Ie&&vn.push(Ie.close()),Ie=null},Hr=()=>{if(!a||Ie||!_)return;Ie=mr.watch(_,{ignoreInitial:!0,depth:12,ignored:d=>{let g=se.basename(d);return it(g)||!!e.ignoreNames?.includes(g)}});let i=d=>{if(!_)return;let g=se.relative(_,d);if(!g||g.startsWith(".."))return;let p=t(g);p&&D(p)};Ie.on("change",i),Ie.on("add",i),Ie.on("unlink",()=>wt()),Ie.on("unlinkDir",()=>wt())},gt=()=>{v?.stop(),v=null},zr=()=>{if(!a||!w||!u||v)return;let i=R;i&&(v=Er({baseUrl:i.cloudUrl,vaultId:u.vaultId,token:i.token},{getSince:()=>u?.cursor??0,onHello:d=>{u&&d>u.cursor&&S({run:Ur})},onChange:d=>{S({run:()=>bn(d)})},onReset:()=>{S({run:et})},onOpen:()=>{(f==="offline"||f==="starting")&&A("idle",null),S({run:Nt})},onDown:()=>{(f==="idle"||f==="syncing")&&A("offline")},onPresence:d=>n.onPresence?.(u?.vaultId??"",d),onPresenceRoster:d=>n.onPresenceRoster?.(u?.vaultId??"",d)}))},qr=async()=>{let i=await Ee(o);if(i.cloudSync?.deviceId)return i.cloudSync.deviceId;let d=`desk-${Math.random().toString(36).slice(2,10)}${Date.now().toString(36)}`;return await Ae({cloudSync:{...i.cloudSync??{},deviceId:d}},o),d},Wr=async i=>{gt(),_n(),xe.length=0,Ne.clear(),B.clear(),X=!1,Y=!1,ne.length=0;let d=await Ee(o);if(i!==c)return;let g=d.cloudSync;if(g?.enabled===!1){_=null,w=null,A("disabled",null);return}if(!o||o!==fe()){A("auth-required","not-logged-in");return}if(_=e.localRoot,e.requireRootExists){let $=await ee.stat(_).then(T=>T.isDirectory()).catch(()=>!1);if(i!==c)return;if(!$){A("error",`vault-missing: ${_}`),W();return}}if(i!==c)return;let p=n.loadCreds();if(!p.cloudUrl||!p.token){w=null,A("auth-required","not-logged-in");return}A("starting",null);let k=g?.deviceId??await qr();if(i!==c)return;let I=e.clientIdSuffix?`${k}#${e.clientIdSuffix}`:k;R={cloudUrl:p.cloudUrl,token:p.token},w=Sr({baseUrl:p.cloudUrl,token:p.token,clientId:I});try{let $=e.vaultId==="first"?g?.vaultId:e.vaultId;if(!$){let M=await w.listVaults();if(i!==c)return;if(!M.length)throw new Error("\u4E91\u7AEF\u65E0\u53EF\u7528 vault");$=M[0].id,await Ae({cloudSync:{...g??{},vaultId:$}},o)}if(i!==c)return;let T=await an(e.shadowName);if(i!==c||(u=T&&T.vaultRoot===_&&T.vaultId===$&&T.folder===""?T:{vaultRoot:_,folder:"",vaultId:$,cursor:0,lastSyncAt:null,files:{}},i!==c))return;for(let[M,P]of Object.entries(u.pending??{}))B.set(M,P);if(B.size&&(Y=!0),!e.requireRootExists){let M=await ee.stat(_).then(P=>P.isDirectory()).catch(()=>!1);if(i!==c)return;if(!M){if(Object.keys(u.files).length){A("error",`mirror-missing: ${_}`),W();return}if(await ee.mkdir(_,{recursive:!0}),i!==c)return}}Hr();for(let M of u.moves??[])S({key:`move:${he(M)}`,run:()=>Mt(M)});S({run:et}),S({run:async()=>{zr()}})}catch($){if(i!==c)return;F($)?A("auth-required","login-expired"):(A("offline",$?.message||String($)),W())}},kn=()=>{a=!1,gt(),_n(),xe.length=0,Ne.clear(),U();for(let i of[E,C,y])i&&clearTimeout(i);E=C=y=null},Cn=async()=>{Ze&&await new Promise(i=>h.add(i)),await Promise.all(vn.splice(0)),await G.flush(),u=null,w=null,R=null,_=null,L=0,j.clear(),te=null,B.clear(),X=!1,Y=!1,ne.length=0,f="disabled",m=null},Br=()=>{xn()},yt=null,tt=()=>{yt?.(),yt=de().onBeforeQuit(Br);let i=++c;kn();let d=l.catch(()=>{}).then(async()=>{await Cn(),i===c&&(a=!0,await Wr(i))});return l=d,d},xn=()=>{yt?.(),yt=null,++c,kn();let i=l.catch(()=>{}).then(Cn);return l=i,i},Oe=()=>({enabled:f!=="disabled",state:f==="idle"&&x.size?"syncing":f,lastSyncAt:u?.lastSyncAt??null,pending:xe.length+x.size,conflicts:L,skipped:[...j].map(([i,d])=>({path:i,reason:d})),error:m,pendingDeletions:B.size,maxFileBytes:te});return{getStatus:Oe,start(){tt()},notifyLocal(i,d,g){if(!u||f==="disabled"||f==="auth-required")return;let p=t(i),k=g?t(g):null;if(d==="write"&&p){it(p.split("/").pop()||"")||D(p);return}if(d==="remove"){if(!p)return;let I=`${p}/`,$=!1;for(let T of Object.keys(u.files))(T===p||T.startsWith(I))&&($=!0,S({key:T,run:()=>ae(T)}));!$&&p&&S({key:p,run:()=>ae(p)})}},holdLocalMove(i,d){let g=k=>e.serverDir?`${e.serverDir}/${k.replace(/\\/g,"/").normalize("NFC")}`:k.replace(/\\/g,"/").normalize("NFC"),p={from:g(i),to:g(d)};return++re,mt.add(p),()=>{mt.delete(p)}},async notifyLocalMove(i,d,g,p){let k=t(i),I=t(d),$=u??await an(e.shadowName),T=on(i,""),M=T&&(e.serverDir?`${e.serverDir}/${T}`:T);if(!k&&I&&M&&$&&Object.keys($.files).some(P=>P===M||P.startsWith(`${M}/`))&&(k=M),!k&&!I){g?.();return}if(k&&I){let P=u??$;if(!P){g?.();return}let O=p??(Object.keys(P.files).some(ce=>ce.startsWith(`${k}/`))?"folder":"file"),H={from:k,to:I,kind:O};P.moves??=[],P.moves.some(ce=>he(ce)===he(H))||(P.moves.push(H),++re),g&&pt.set(he(H),g),G.save(P);try{await G.flush(!0)}catch(ce){throw P.moves=P.moves.filter(ke=>he(ke)!==he(H)),pt.delete(he(H)),G.save(P),ce}u===P&&a&&f!=="disabled"&&f!=="auth-required"&&S({key:`move:${he(H)}`,run:()=>Mt(H)});return}k&&this.notifyLocal(i,"remove"),I&&(S({key:I,run:()=>ae(I)}),wt()),g?.()},async setEnabled(i){let d=await Ee(o);return await Ae({cloudSync:{...d.cloudSync??{},enabled:i}},o),await tt(),Oe()},async restart(){return await tt(),Oe()},async syncNow(){if(j.clear(),f==="disabled"||f==="auth-required"||!w)await tt();else{for(let i of u?.moves??[])S({key:`move:${he(i)}`,run:()=>Mt(i)});S({run:et})}return Oe()},confirmMassDeletions(){return B.size&&(X=!0,Y=!1,B.clear(),ne.length=0,ue(),S({run:et})),Oe()},stop:xn};function wt(){a&&(C&&clearTimeout(C),C=setTimeout(()=>{C=null,S({run:Nt})},vo))}}import{createHash as Ao}from"node:crypto";function Rr(n){let e=n.replace(/\.md$/i,""),t=n.lastIndexOf("/"),s=t<0?"":n.slice(0,t);return{root:n,fdPrefix:`${e}.fd/`,assetPrefix:s?`${s}/.amadeus/`:".amadeus/"}}function Ir(n,e,t){return!!(e===n.root||e.startsWith(n.fdPrefix)||`${e}/`===n.fdPrefix||t==="binary"&&e.startsWith(n.assetPrefix)||t==="folder"&&(`${e}/`===n.assetPrefix||e.startsWith(n.assetPrefix)))}var Po=n=>Ao("sha256").update(n).digest("hex").slice(0,8),Do=n=>n.replace(/[\\/:*?"<>|]/g," ").trim().slice(0,40)||"shared",Pt="\u4E0E\u6211\u5171\u4EAB";function ln(n){let e=Po(`${n.vaultId}:${n.path}`),t=Rr(n.path),s=n.path.includes("/")?n.path.slice(0,n.path.lastIndexOf("/")):"";return{key:e,vaultId:n.vaultId,rootPath:n.path,title:n.title,localRelDir:`${Pt}/${Do(n.title)}-${e}`,serverDir:s,inScope:(r,o)=>Ir(t,r,o)}}function cn(){let n=de().readCreds(),e=Se(n.cloudUrl??"",n.token??""),t=new AbortController,s=()=>{let m=de().readCreds();if(t.signal.aborted||!e||Se(m.cloudUrl??"",m.token??"")!==e)throw Object.assign(new Error("Cloud account changed; retry from the current account"),{status:401});return m},r=()=>{let m=s();if(!m.cloudUrl||!m.token)throw Object.assign(new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7"),{status:401});return m.cloudUrl.replace(/\/+$/,"")},o=async(m,u,w)=>{let v=s();if(!v.cloudUrl||!v.token)throw Object.assign(new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7"),{status:401});let R=await fetch(`${v.cloudUrl.replace(/\/+$/,"")}/api/amadeus${u}`,{method:m,headers:{Authorization:`Bearer ${v.token}`,...w!==void 0?{"Content-Type":"application/json"}:{}},body:w!==void 0?JSON.stringify(w):void 0,signal:AbortSignal.any([t.signal,AbortSignal.timeout(2e4)])});if(!R.ok){let L=null;try{L=await R.json()}catch{}throw Object.assign(new Error(L?.detail||`http ${R.status}`),{status:R.status,code:L?.code})}let _=await R.json();return s(),_},a=null,c=async()=>(s(),a||(a=(await o("GET","/vaults")).vaults[0]?.id??"default",a)),l=()=>{try{let m=(s().token??"").split(".")[1],u=JSON.parse(Buffer.from(m.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString());return typeof u.userId=="string"?u.userId:null}catch{return null}},h=async()=>(await o("GET","/shared-with-me")).items.map(u=>{let w=ln(u),v=u.path.split("/").pop()??u.path;return{...u,localPath:`${w.localRelDir}/${v}`}}),f=null;return{stop:()=>t.abort(),call:o,ensureOwnVault:c,myUserId:l,sharedWithMe:h,linkBase:async()=>{if(s(),f)return f;try{f=((await o("GET","/collab/link-base")).webOrigin??"").trim().replace(/\/+$/,"")||r()}catch{f=r()}return f},async heartbeat(m,u){let w=(m??"").replace(/\\/g,"/"),v,R=null,_=u.find(L=>w.startsWith(`${L.localRelDir}/`));_?(v=_.vaultId,R=_.serverDir?`${_.serverDir}/${w.slice(_.localRelDir.length+1)}`:w.slice(_.localRelDir.length+1)):(v=await c(),R=w||null),await o("POST",`/vaults/${encodeURIComponent(v)}/presence`,{page:R})}}}import{promises as Ar}from"node:fs";import $o from"node:path";var un=".forsion-vault.md",dn=n=>`${n}/${un}`;var ge=n=>n.replace(/\\/g,"/").normalize("NFC");function fn(n){let e=ge(n.path);return e?n.kind==="folder"?`${e}/`:n.kind==="page"?`${e.replace(/\.md$/i,"")}.fd/`:null:null}function Ke(n,e,t){let s=ge(t);if(!s)return!1;if(n.some(r=>ge(r.path)===s))return!0;for(let r of e??[]){let o=ge(r);if(!o)continue;let a=`${o.replace(/\.md$/i,"")}.fd`;if(s===o||s.startsWith(`${o}/`)||s===a||s.startsWith(`${a}/`))return!1}return n.some(r=>{let o=fn(r);return!!o&&s.startsWith(o)})}function hn(n,e,t){let s=ge(n),r=ge(e);return s===r?ge(t):s.startsWith(`${r}/`)?ge(t)+s.slice(r.length):null}function lt(n,e,t){let s=!1,r=n.map(o=>{let a=hn(o,e,t);return a===null?o:(s=!0,a)});return{changed:s,next:r}}async function Pr(n){let e=await Ar.readdir(n,{withFileTypes:!0}).catch(()=>[]),t=[];for(let s of e)!s.isDirectory()||s.name.startsWith(".")||await Ar.access($o.join(n,s.name,un)).then(()=>!0,()=>!1)&&t.push(s.name);return t.sort()}var ie={get:"amadeus:sync:get",setEnabled:"amadeus:sync:set-enabled",syncNow:"amadeus:sync:now",confirmDeletions:"amadeus:sync:confirm-deletions",status:"amadeus:sync:status",switchSide:"amadeus:sync:switch-side",collabCall:"amadeus:collab:call",presence:"amadeus:collab:presence",entryGet:"amadeus:entry-sync:get",entryEnable:"amadeus:entry-sync:enable",entryDisable:"amadeus:entry-sync:disable",entryClosure:"amadeus:entry-sync:closure",entryChange:"amadeus:entry-sync:change",otherSideDbs:"amadeus:entry-sync:other-side-dbs"};import{createHash as Mo}from"node:crypto";var Dt=n=>Mo("sha256").update(n).digest("hex").slice(0,8);function Dr(n){return n.replace(/ \(conflict \d{4}-\d{2}-\d{2} \d{4}\)(?=(?:\.[^./]+)?$)/,"")}function Me(n,e=[]){let t=[],s=[];for(let r of n){let o=ge(r.path);if(!o)continue;s.push(o);let a=fn(r);a&&t.push(a)}return{entries:n,exclude:e,prefixes:t,paths:s}}function $r(n,e){let t=Dr(ge(e));if(!t)return!1;if(Ke(n.entries,n.exclude,t))return!0;let s=`${t}/`;for(let r of n.paths)if(r.startsWith(s))return!0;for(let r of n.prefixes)if(r.startsWith(s))return!0;return!1}function ct(n,e,t){let s=!1,r=n.map(o=>{let a=hn(o.path,e,t);return a===null?o:(s=!0,{...o,path:a})});return{changed:s,next:r}}function Mr(n,e,t,s){if(e==="delete"||e==="delete-folder"){let r=ge(t),o=n.filter(a=>{let c=ge(a.path);return!(c===r||e==="delete-folder"&&c.startsWith(`${r}/`))});return{changed:o.length!==n.length,next:o}}return s?ct(n,t,s):{changed:!1,next:n}}function mn(n,e){let t=Ve(n);return!t||t!==n.normalize("NFC").trim()?"\u540D\u79F0\u4E0D\u5408\u6CD5":t.includes("/")?"\u540D\u79F0\u4E0D\u80FD\u5305\u542B /":t===Pt?`\u300C${Pt}\u300D\u662F\u4FDD\u7559\u540D\u79F0`:e.includes(t)?"\u8BE5\u540D\u79F0\u5DF2\u88AB\u5176\u4ED6\u667A\u5E93\u7684\u4E91\u540C\u6B65\u5360\u7528":null}var Nr=["setAmadeusSyncFactory","readCreds","accountId","homeDir"],pn=n=>Nr.every(e=>typeof n[e]=="function"),No=()=>({enabled:!1,state:"disabled",lastSyncAt:null,pending:0,conflicts:0,skipped:[],error:null,pendingDeletions:0,maxFileBytes:null,side:"local"});function gn(n){let e=null,t=()=>{if(!e)throw new Error("Cloud sync is not ready");return e};n.handle(ie.get,()=>e?e.get():No()),n.handle(ie.setEnabled,(s,r)=>t().setEnabled(r)),n.handle(ie.syncNow,()=>t().syncNow()),n.handle(ie.confirmDeletions,()=>t().confirmDeletions()),n.handle(ie.entryGet,()=>t().entryGet()),n.handle(ie.otherSideDbs,()=>t().otherSideDbs()),n.handle(ie.entryEnable,(s,r)=>t().entryEnable(r)),n.handle(ie.entryDisable,(s,r)=>t().entryDisable(r)),n.handle(ie.entryClosure,(s,r,o)=>t().entryClosure(r,o)),n.handle(ie.collabCall,(s,r,o)=>t().collabCall(r,o)),n.handle(ie.switchSide,(s,r)=>t().switchSide(s.sender.id,r)),n.setAmadeusSyncFactory(s=>{Gn(s);let r=Fr(s);return e=r.handlers,r.instance}),n.log("[forsion-extend] amadeus cloud sync registered")}function Fr(n){let e=n.notifyAll,t=()=>n.vaultRoot(),s=0,r=!1,o=cn(),a=new Map,c=()=>{let E=Date.now();for(let[C,y]of a)E-y.at>7e4&&a.delete(C);e(ie.presence,[...a.values()])},l={loadCreds:()=>n.readCreds(),onStatus:E=>e(ie.status,{...E,pendingDeletions:ne(),side:v()?"cloud":"local"}),onPresence:(E,C)=>{let y=C;y?.userId&&(a.set(y.userId,{userId:y.userId,username:String(y.username??"user"),page:y.page??null,at:Number(y.at)||Date.now()}),c())},onPresenceRoster:(E,C)=>{if(Array.isArray(C)){for(let y of C){let b=y;b?.userId&&a.set(b.userId,{userId:b.userId,username:String(b.username??"user"),page:b.page??null,at:Number(b.at)||Date.now()})}c()}}},h=()=>{let E=s;return{...l,onStatus:C=>{E===s&&l.onStatus(C)},onPresence:(C,y)=>{E===s&&l.onPresence(C,y)},onPresenceRoster:(C,y)=>{E===s&&l.onPresenceRoster(C,y)}}},f=at(h()),m=new Map,u=[],w=async()=>{if(!r||!fe())return;let E=s,C=o,y;try{y=await C.sharedWithMe()}catch{return}if(E!==s||!r)return;let b=y.map(S=>ln(S));u=b;let A=new Set(b.map(S=>S.key));for(let[S,x]of m)if(!A.has(S)){if(await x.engine.stop(),E!==s)return;m.delete(S)}for(let S of b){if(m.has(S.key))continue;let x=at(h(),{localRoot:je.join(De(),...S.localRelDir.split("/")),shadowName:`amadeus-sync-${rt()}-share-${S.key}`,vaultId:S.vaultId,serverDir:S.serverDir,inScope:S.inScope});m.set(S.key,{engine:x,plan:S}),x.start()}},v=()=>t()===De(),R=(E,C=E.base)=>{E.base=C;let y=[C,...E.pendingMoves];E.scope.current=Me(y.flatMap(b=>b.entries),y.flatMap(b=>b.exclude))},_=new Map,L=new Set,j=()=>{e(ie.entryChange)},te=async(E,C)=>{let y=_.get(E);if(!y)return;let b=x=>x&&x.startsWith(`${y.cloudName}/`)?x.slice(y.cloudName.length+1):null,A=b(C.path);if(!A)return;let S=!1;await qe(x=>{if(_.get(E)!==y)return!1;let D=(x.entrySync??[]).find(W=>W.vaultRoot===E);if(!D)return!1;let U=C.op,N=b(C.newPath),F=Mr(D.entries,U,A,N),V=N?lt(D.exclude??[],A,N):{changed:!1,next:D.exclude??[]};if(!F.changed&&!V.changed)return!1;S=!0,D.entries=F.next,V.changed&&(D.exclude=V.next),R(y,Me(D.entries,D.exclude??[]))}),S&&_.get(E)===y&&j()},G=E=>{let C=s;return{...h(),onStatus:y=>{C===s&&e(ie.status,{...y,pendingDeletions:ne(),side:"local",binding:E})},onRemoteApplied:async y=>{C===s&&await te(E,y)}}},B=async()=>{let E=fe();if(!r||!E)return;let C=s,y=o,b=rt(E);await n.adoptLegacyCloudState(E,kr);let A=await Ee(E),S=A.entrySync??[];if(C!==s||!r||E!==fe())return;let x=new Map(S.map(D=>[D.vaultRoot,D]));for(let[D,U]of _){let N=x.get(D);if(!(N&&N.cloudName===U.cloudName)&&(await U.engine.stop(),C!==s||(_.delete(D),N&&await _r(`amadeus-sync-${b}-entry-${Dt(D)}`),C!==s)))return}for(let D of S){let U=_.get(D.vaultRoot);if(U){R(U,Me(D.entries,D.exclude??[]));continue}let N={current:Me(D.entries,D.exclude??[])},F=D.cloudName,V=at(G(D.vaultRoot),{accountId:E,localRoot:D.vaultRoot,shadowName:`amadeus-sync-${b}-entry-${Dt(D.vaultRoot)}`,vaultId:"first",serverDir:F,clientIdSuffix:`entry-${Dt(D.vaultRoot)}`,requireRootExists:!0,ignoreNames:[".git","node_modules",".trash"],inScope:W=>W===F?!0:W.startsWith(`${F}/`)?$r(N.current,W.slice(F.length+1)):!1});_.set(D.vaultRoot,{engine:V,scope:N,cloudName:F,base:N.current,pendingMoves:new Set}),V.start()}if(A.cloudSync?.enabled!==!1)for(let D of S)L.has(D.cloudName)||(async()=>{try{let U=await y.ensureOwnVault();await y.call("PUT",`/vaults/${encodeURIComponent(U)}/file`,{path:dn(D.cloudName),content:"",baseSeq:0}),C===s&&L.add(D.cloudName)}catch(U){U?.status===409&&C===s&&L.add(D.cloudName)}})()},X=async(E,C,y,b,A)=>{let S=C.replace(/\\/g,"/").normalize("NFC"),x=y.replace(/\\/g,"/").normalize("NFC"),D=!1,U,N,F,V=A??"file";try{await qe(async W=>{if(_.get(E)!==b)return!1;let q=(W.entrySync??[]).find(oe=>oe.vaultRoot===E);if(!q)return!1;let Q=ct(q.entries,S,x),J=lt(q.exclude??[],S,x),we=Ke(q.entries,q.exclude,S);!A&&await Xe.stat(je.join(E,...x.split("/"))).then(oe=>oe.isDirectory(),()=>!1)&&(V="folder");let Fe=V==="folder"?"folder":/\.md$/i.test(x)?"page":"asset";we&&!Ke(Q.next,J.next,x)&&(Q.next.push({path:x,kind:Fe}),Q.changed=!0),D=Q.changed||J.changed;let Ue=q.entries.filter(oe=>ct([oe],S,x).changed);return we&&!Ue.some(oe=>oe.path===S)&&Ue.push({path:S,kind:Fe}),U=Me(Ue,(q.exclude??[]).filter(oe=>lt([oe],S,x).changed)),N=b.base,b.pendingMoves.add(U),q.entries=Q.next,q.exclude=J.next,F=Me(q.entries,q.exclude),R(b,F),D})}catch(W){throw U&&b.pendingMoves.delete(U),R(b,b.base===F&&N?N:b.base),W}try{U&&await b.engine.notifyLocalMove(S,x,()=>{b.pendingMoves.delete(U),R(b)},V)}catch(W){throw U&&b.pendingMoves.delete(U),await qe(q=>{let Q=q.entrySync?.find(J=>J.vaultRoot===E);if(!Q)return!1;Q.entries=ct(Q.entries,x,S).next,Q.exclude=lt(Q.exclude??[],x,S).next,R(b,Me(Q.entries,Q.exclude))}),W}D&&_.get(E)===b&&j()},Y=E=>{let C=E.replace(/\\/g,"/");for(let{engine:y,plan:b}of m.values())if(C.startsWith(`${b.localRelDir}/`))return{engine:y,rel:C.slice(b.localRelDir.length+1)};return{engine:f,rel:C}};n.setMutationHooks((E,C)=>{if(v()){let y=Y(E);y.engine.notifyLocal(y.rel,C);return}_.get(t()??"")?.engine.notifyLocal(E,C)},(E,C,y)=>{if(v()){let S=Y(E),x=Y(C);if(S.engine===x.engine)return S.engine.notifyLocalMove(S.rel,x.rel,void 0,y);S.engine.notifyLocal(S.rel,"remove"),x.engine.notifyLocal(x.rel,"write");return}let b=t()??"",A=_.get(b);if(A)return X(b,E,C,A,y)},(E,C)=>{if(v()){let y=Y(E),b=Y(C),A=[y.engine.holdLocalMove(y.rel,b.rel)];return y.engine!==b.engine&&A.push(b.engine.holdLocalMove(y.rel,b.rel)),()=>{for(let S of A)S()}}return _.get(t()??"")?.engine.holdLocalMove(E,C)});let ne=()=>{let E=f.getStatus().pendingDeletions;for(let{engine:C}of m.values())E+=C.getStatus().pendingDeletions;for(let{engine:C}of _.values())E+=C.getStatus().pendingDeletions;return E},ue=E=>({...E,pendingDeletions:ne(),side:v()?"cloud":"local"}),ut=()=>{if(!r)return Promise.resolve(f.getStatus());w();for(let{engine:E}of m.values())E.syncNow();for(let{engine:E}of _.values())E.syncNow();return f.syncNow()},Qe=async()=>{++s,r=!1,o.stop();let E=[f.stop(),...[...m.values()].map(({engine:y})=>y.stop()),...[..._.values()].map(({engine:y})=>y.stop())];m.clear(),_.clear(),u=[],L.clear(),a.clear(),c(),await Promise.all(E),await n.awaitPendingVaultWrites();let C=t();if(C&&St(C)){let y=await Ee(),b=y.localVault&&!St(y.localVault)?y.localVault:je.join(n.workspaceDir(),"Amadeus");await Xe.mkdir(b,{recursive:!0}),await Ae({lastVault:b,localVault:b,lastPage:void 0}),await n.activateRoot(b,!1)}j()};return{handlers:{get:()=>ue(f.getStatus()),setEnabled:async E=>{if(!r)throw new Error("Cloud account is changing");let C=s;return await f.setEnabled(E),C!==s?f.getStatus():(await Promise.all([...m.values(),..._.values()].map(({engine:y})=>y.restart())),ue(f.getStatus()))},syncNow:()=>ut(),confirmDeletions:()=>{for(let{engine:E}of m.values())E.confirmMassDeletions();for(let{engine:E}of _.values())E.confirmMassDeletions();return ue(f.confirmMassDeletions())},entryGet:async()=>{let E=await Ee(),C=De();return{vaults:E.entrySync??[],activeRoot:t(),cloudRoot:C,mirrorVaults:await Pr(C)}},otherSideDbs:async()=>{let E=t();if(!E)return null;let C=De(),y=await Ee(),b=E===C?y.localVault&&y.localVault!==C?y.localVault:null:C;if(!b)return null;let A=[],S=500,x=async(D,U)=>{if(A.length>=S)return;let N;try{N=await Xe.readdir(D,{withFileTypes:!0})}catch{return}for(let F of N){if(A.length>=S)break;if(F.name.startsWith(".")||F.isSymbolicLink())continue;let V=U?`${U}/${F.name}`:F.name;if(F.isDirectory())await x(je.join(D,F.name),V);else if(F.isFile()&&/\.db$/i.test(F.name))try{A.push({rel:V,source:await Xe.readFile(je.join(D,F.name),"utf8")})}catch{}}};return await x(b,""),{root:b,vaultName:b===C?"\u4E91\u7AEF":je.basename(b),dbs:A}},entryEnable:async E=>{let C=s,y=o;if(!r||!fe())return{error:"Sign in to enable cloud sync"};let b=t();if(!b||v())return{error:"\u4EC5\u672C\u5730 vault \u53EF\u5F00\u542F\u4E91\u540C\u6B65"};let A=await Ee(),S=A.entrySync??[],x=S.find(D=>D.vaultRoot===b);if(!x){let D=(E.cloudName??je.basename(b)).normalize("NFC").trim(),U=mn(D,S.map(N=>N.cloudName));if(U)return{error:U};if(!E.merge)try{let N=await y.ensureOwnVault(),F=await y.call("GET",`/vaults/${encodeURIComponent(N)}/tree`);if((F.folders??[]).some(W=>W===D||W.startsWith(`${D}/`))||(F.entries??[]).some(W=>W.path===D||W.path.startsWith(`${D}/`)))return{conflict:D}}catch(N){return{error:N?.message||"\u65E0\u6CD5\u8FDE\u63A5\u4E91\u7AEF(\u9996\u6B21\u5F00\u542F\u9700\u8981\u5728\u7EBF)"}}x={vaultRoot:b,cloudName:D,entries:[]},S.push(x),(async()=>{try{let N=await y.ensureOwnVault();await y.call("PUT",`/vaults/${encodeURIComponent(N)}/file`,{path:dn(x.cloudName),content:"",baseSeq:0})}catch{}})()}return C!==s||!r?{error:"Cloud account changed; retry from the current account"}:(await qe(D=>{if(C!==s||!r)return!1;let U=D.entrySync??[],N=U.find(J=>J.vaultRoot===b);if(!N){let J=mn(x.cloudName,U.map(we=>we.cloudName));if(J)throw new Error(J);N={vaultRoot:b,cloudName:x.cloudName,entries:[]},U.push(N)}let F=J=>String(J??"").replace(/\\/g,"/").normalize("NFC"),V=new Set;for(let J of E.entries??[]){let we=F(J.path);we&&(V.add(we),!N.entries.some(Fe=>Fe.path===we)&&N.entries.push({path:we,kind:J.kind==="folder"||J.kind==="asset"?J.kind:"page"}))}let W=(E.exclude??[]).map(F).filter(Boolean),q=new Set([...V,...(E.include??[]).map(F).filter(Boolean)]);N.exclude=[...new Set([...(N.exclude??[]).filter(J=>!q.has(J)),...W])];let Q=new Set(W);N.entries=N.entries.filter(J=>!Q.has(J.path)),D.entrySync=U,x=N},A.cloudAccountId),C!==s?{error:"Cloud account changed; retry from the current account"}:(await B(),_.get(b)?.engine.syncNow(),j(),{ok:!0,cloudName:x.cloudName}))},entryDisable:async E=>{let C=t(),y=!1,b=s;return await qe(A=>{if(b!==s||!r)return!1;let S=(A.entrySync??[]).find(U=>U.vaultRoot===C);if(!C||!S)return!1;let x=String(E??"").replace(/\\/g,"/").normalize("NFC"),D=S.entries.length;if(S.entries=S.entries.filter(U=>U.path!==x),Ke(S.entries,S.exclude,x))S.exclude=[...new Set([...S.exclude??[],x])];else if(S.entries.length===D)return!1;y=!0}),!y||b!==s?{ok:!1}:(await B(),j(),{ok:!0})},entryClosure:(E,C)=>n.relatedClosure(String(E??""),C==="folder"?"folder":"page"),collabCall:async(E,C)=>{let y=o,b=async()=>y.ensureOwnVault(),A=x=>String((C??[])[x]??""),S=x=>(C??[])[x]??{};switch(E){case"listVaults":return(await y.call("GET","/vaults")).vaults;case"activeVaultId":return b();case"pageShare":return y.call("GET",`/vaults/${encodeURIComponent(await b())}/page-shares?path=${encodeURIComponent(A(0))}`);case"createPageShare":return y.call("POST",`/vaults/${encodeURIComponent(await b())}/page-shares`,{path:A(0),...S(1)});case"updatePageShare":return y.call("PATCH",`/vaults/${encodeURIComponent(await b())}/page-shares/${encodeURIComponent(A(0))}`,S(1));case"revokePageShare":return y.call("DELETE",`/vaults/${encodeURIComponent(await b())}/page-shares/${encodeURIComponent(A(0))}`);case"setParticipantRole":return y.call("PATCH",`/vaults/${encodeURIComponent(await b())}/page-shares/${encodeURIComponent(A(0))}/members/${encodeURIComponent(A(1))}`,{role:A(2)});case"removeParticipant":return y.call("DELETE",`/vaults/${encodeURIComponent(await b())}/page-shares/${encodeURIComponent(A(0))}/members/${encodeURIComponent(A(1))}`);case"sharedWithMe":{let x=await y.sharedWithMe();return w(),x}case"leaveShare":{let x=y.myUserId();if(!x)throw new Error("\u672A\u767B\u5F55");return y.call("DELETE",`/vaults/${encodeURIComponent(await b())}/page-shares/${encodeURIComponent(A(0))}/members/${encodeURIComponent(x)}`)}case"publishes":return y.call("GET",`/vaults/${encodeURIComponent(await b())}/shares`);case"listAllShares":{let x=(await y.call("GET","/vaults")).vaults||[],D=y.myUserId(),U=[],N=[];for(let F of x){try{let V=await y.call("GET",`/vaults/${encodeURIComponent(F.id)}/shares`);for(let W of V.shares||[])U.push({...W,vaultId:F.id,vaultName:F.name||""})}catch(V){n.log(`[connect] listAllShares publishes vault ${F.id} failed: ${V?.message}`)}try{let V=await y.call("GET",`/vaults/${encodeURIComponent(F.id)}/page-shares`),W=V?.shares||V?.pageShares||(Array.isArray(V)?V:[]);for(let q of W){let Q=q.created_by??q.createdBy;(!D||!Q||Q===D)&&N.push({...q,vaultId:F.id,vaultName:F.name||""})}}catch(V){n.log(`[connect] listAllShares pageShares vault ${F.id} failed: ${V?.message}`)}}return{publishes:U,pageShares:N,linkBase:await y.linkBase()}}case"createPublish":{let x=await y.call("POST",`/vaults/${encodeURIComponent(await b())}/shares`,{mode:A(0),path:A(1)});return{...x,url:`${await y.linkBase()}/share/${x.token}`}}case"revokePublish":return y.call("DELETE",`/vaults/${encodeURIComponent(await b())}/shares/${encodeURIComponent(A(0))}`);case"revokePublishIn":return y.call("DELETE",`/vaults/${encodeURIComponent(A(0))}/shares/${encodeURIComponent(A(1))}`);case"revokePageShareIn":return y.call("DELETE",`/vaults/${encodeURIComponent(A(0))}/page-shares/${encodeURIComponent(A(1))}`);case"myUserId":return y.myUserId();case"linkBase":return y.linkBase();case"heartbeat":return y.heartbeat((C??[])[0]??null,u);default:throw new Error(`unknown collab fn: ${E}`)}},switchSide:async(E,C)=>{let y=await Ee();if(C==="cloud"){if(!r||!fe())throw new Error("Sign in to open cloud notes");let S=De();await Xe.mkdir(S,{recursive:!0}),y.lastVault&&!St(y.lastVault)&&await Ae({localVault:y.lastVault}),await Ae({lastVault:S});let x=await n.activateRoot(S,!1);return n.bindRenderer(E,S),{...x,side:"cloud"}}let b=y.localVault&&await Xe.stat(y.localVault).then(S=>S.isDirectory()).catch(()=>!1)?y.localVault:null;if(!b){let S=await n.ensureDefaultVault();return n.bindRenderer(E,S.root),{...S,side:"local"}}await Ae({lastVault:b});let A=await n.activateRoot(b,!1);return n.bindRenderer(E,b),{...A,side:"local"}}},instance:{start:()=>{r=!0,f.start(),w(),B()},stopAllSync:Qe,restartAllSync:async()=>{await Qe(),o=cn(),f=at(h()),r=!0,await Promise.all([f.restart(),w(),B()]),j(),e(ie.status,ue(f.getStatus()))}}}}function Ea(n){n.handle("auth:openAccountCenter",async(t,s)=>{let{base:r,token:o}=await n.getCloud();if(!r)return{ok:!1};let a=s&&/^[a-z0-9-]+$/i.test(s)?`#${s}`:"",c=`${r}/account${o?`?token=${encodeURIComponent(o)}`:""}${a}`;return await n.openExternal(c),{ok:!0}}),n.handle("auth:openPayCenter",async()=>{let{base:t,token:s}=await n.getCloud();if(!t)return{ok:!1};let r=`${t}/pay?tab=membership${s?`&token=${encodeURIComponent(s)}`:""}&redirect=${encodeURIComponent(`${t}/account`)}`;return await n.openExternal(r),{ok:!0}});let e=()=>n.getCloud();n.handle("account:quota",async()=>{let t=await e();if(!t.token)return{status:401,json:null};try{return await me(t,"GET","/api/token-quota/my",void 0,15e3)}catch(s){return{status:0,json:{detail:String(s?.message||s)}}}}),n.handle("account:useResetCard",async(t,s)=>{let r=await e();if(!r.token)return{status:401,json:null};if(s!==void 0&&s!=="both"&&s!=="weekly")return{status:400,json:{error:"invalid_type",detail:`invalid reset card type: ${s}`}};let o=s??"both";try{return await me(r,"POST","/api/token-quota/reset-card/use",{type:o},15e3)}catch(a){return{status:0,json:{detail:String(a?.message||a)}}}}),n.handle("account:bgConvert",async(t,s)=>{let r=await e();if(!r.token)return{status:401,json:null};if(!Number.isInteger(s)||s<1||s>100)return{status:400,json:{error:"invalid_percent"}};try{return await me(r,"POST","/api/token-quota/background/convert",{percent:s},15e3)}catch(o){return{status:0,json:{detail:String(o?.message||o)}}}}),n.handle("account:bgAutoMain",async(t,s)=>{let r=await e();if(!r.token)return{status:401,json:null};if(typeof s!="boolean")return{status:400,json:{error:"invalid_request"}};try{return await me(r,"POST","/api/token-quota/background/auto-main",{enabled:s},15e3)}catch(o){return{status:0,json:{detail:String(o?.message||o)}}}}),n.handle("feedback:submit",async(t,s)=>{let{base:r,token:o}=await n.getCloud();if(!r||!o)return{ok:!1,error:"not-logged-in"};let a=(s?.description||"").trim();if(!a)return{ok:!1,error:"empty"};if(a.length>1e4)return{ok:!1,error:"description-too-long"};let c=[],l=!1;if(s?.sessionLogJson){let h=Buffer.from(s.sessionLogJson,"utf8");if(h.length>5*1024*1024)return{ok:!1,error:"attachment-too-large"};c.push({filename:s.sessionLogName||"tangu-session.json",mime_type:"application/json",size:h.length,data_base64:h.toString("base64")})}try{let h=await fetch(`${r}/api/feedback`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`},body:JSON.stringify({description:a,attachments:c}),signal:AbortSignal.timeout(2e4)});if(!h.ok){let m=`HTTP ${h.status}`;try{m=(await h.json())?.detail||m}catch{}return{ok:!1,error:m}}return{ok:!0,id:(await h.json().catch(()=>({})))?.id??null,attachmentSkipped:l}}catch(h){return{ok:!1,error:h?.message||String(h)}}}),n.handle("cloud:fetch",async(t,s)=>{if(!n.isTrustedSender(t))return{status:0,error:"untrusted"};let r=s??{},o=typeof r.path=="string"?r.path:"",a=Math.min(12e4,Math.max(1e3,Number(r.timeoutMs)||15e3)),c=typeof r.method=="string"?r.method.toUpperCase():"GET";if(!/^(GET|POST|PUT|PATCH|DELETE)$/.test(c))return{status:0,error:"bad_method"};if(!o.startsWith("/"))return{status:0,error:"bad_path"};let{base:l,token:h}=await n.getCloud();if(!String(l||""))return{status:0,error:"no_cloud_url"};let f=Tn(l,o);if(!f)return{status:0,error:"bad_path"};if(!h)return{status:401,error:"not_signed_in"};let m=r.body!==void 0&&c!=="GET"&&c!=="DELETE",u=new AbortController,w=setTimeout(()=>u.abort(),a);try{let v=await fetch(f,{method:c,headers:{Authorization:`Bearer ${h}`,...m?{"Content-Type":"application/json"}:{}},body:m?JSON.stringify(r.body):void 0,signal:u.signal});return{status:v.status,json:await v.json().catch(()=>null)}}catch(v){return{status:0,error:String(v?.message||v)}}finally{clearTimeout(w)}}),n.log("[forsion-extend] cloud account handlers registered"),jt(n)?Ut(n):n.log("[forsion-extend] host has no Connect seam (projectsRoot / transpileForServe / mimeOf / setPreviewHooks); Connect stays with the host"),zt(n)?qt(n):n.log("[forsion-extend] host has no remote-sync seam (registerRemoteSyncBackend / readCreds); penzor stays with the host"),Bt(n)?Vt(n):n.log("[forsion-extend] host has no account seam (accountCommit / accountClear / \u2026); account core stays with the host"),pn(n)?gn(n):n.log("[forsion-extend] host has no amadeus seam (setAmadeusSyncFactory); cloud sync stays with the host")}export{Vn as ACCOUNT_SEAM,Nr as AMADEUS_SEAM,Ot as CONNECT_MAX_FILES,In as CONNECT_MAX_FILE_BYTES,An as CONNECT_MAX_TOTAL_BYTES,Fn as FORSION_CONNECT_LOCAL_SDK,Un as PENZOR_MAX_FILE,ie as SYNC_IPC,me as cloudJson,Pn as collectProjectFiles,It as conflictCopyPath,lo as conflictCopyVariant,Bn as createAccountCloud,Fr as createAmadeusCloud,jn as createPenzorRemote,Ht as expectedPartsOf,Se as forsionAccountId,Wn as forsionRefreshToken,nt as forsionWhoami,Bt as hasAccountHost,pn as hasAmadeusHost,jt as hasConnectHost,zt as hasRemoteSyncHost,Nn as makePreviewProxy,$n as readConnectMeta,Vt as registerAccount,gn as registerAmadeus,Ea as registerCloud,Ut as registerConnect,qt as registerPenzor,qn as shouldRefreshToken,Dr as stripConflictSuffix,co as textFingerprint,zn as tokenAgeMs,us as tokenRemainingMs,Mn as writeConnectMeta};
|
|
197
|
+
`)}function sn(t,e,n=200){return t>=n||e>=5&&t>=Math.max(5,Math.ceil(e/2))}var fo=/[\u0000-\u001f\u007f]/;function Ve(t){let e=t.replace(/\\/g,"/").normalize("NFC").trim();if(e=e.replace(/\/+$/,""),!e||e.length>512||e.startsWith("/")||fo.test(e))return null;let n=e.split("/");for(let s of n)if(!s||s==="."||s==="..")return null;return n.join("/")}function on(t,e){let n=t.replace(/\\/g,"/").normalize("NFC");return e===""?Ve(n):n.startsWith(`${e}/`)?Ve(n.slice(e.length+1)):null}function wr(t,e){return e===""?t:`${e}/${t}`}function it(t){return!!(t===".DS_Store"||t==="Icon\r"||t===".sync-trash"||/\.tmp-\d+-\d+-\d+$/.test(t)||/^\..+\.lock$/.test(t))}function Ce(t){return/\.md$/i.test(t)?"page":/\.db$/i.test(t)?"db":"binary"}var $e=t=>t==="page"||t==="db";import{gzip as ho}from"node:zlib";import{promisify as mo}from"node:util";var po=mo(ho),go=1024,le=class extends Error{status;body;constructor(e,n,s){super(`cloud http ${e} on ${s}`),this.status=e,this.body=n}},br=t=>12e4+Math.ceil(t/256);function Sr(t){let e=`${t.baseUrl.replace(/\/+$/,"")}/api/amadeus`,n=async(r,o,a)=>{let c={Authorization:`Bearer ${t.token}`,...a?.headers};r!=="GET"&&(c["X-Amadeus-Client"]=t.clientId);let l;a?.json!==void 0?(c["Content-Type"]="application/json",l=JSON.stringify(a.json),l.length>=go&&(c["Content-Encoding"]="gzip",l=await po(l))):a?.form&&(l=a.form);let m=await fetch(o,{method:r,headers:c,body:l,signal:AbortSignal.timeout(a?.timeoutMs??3e4)});if(!m.ok){let d=null;try{d=await m.json()}catch{}throw new le(m.status,d,o)}return m.json()},s=r=>new URLSearchParams(r).toString();return{clientId:t.clientId,async listVaults(){return((await n("GET",`${e}/vaults`)).vaults??[]).map(o=>({id:String(o.id),name:String(o.name),lastChangeSeq:Number(o.lastChangeSeq??0)}))},async tree(r){let o=await n("GET",`${e}/vaults/${r}/tree`);if(!Array.isArray(o.entries))throw new Error("server too old: tree has no entries[] (deploy the amadeus microserver update)");return{folders:o.folders??[],seq:Number(o.seq??0),maxFileBytes:Number.isInteger(o.maxFileBytes)&&o.maxFileBytes>0?o.maxFileBytes:void 0,entries:o.entries.map(a=>({path:String(a.path),kind:a.kind,seq:Number(a.seq??0),hash:a.hash??null,size:Number(a.size??0)}))}},async getFile(r,o){let a=await n("GET",`${e}/vaults/${r}/file?${s({path:o})}`);return{content:String(a.content??""),seq:Number(a.seq??0),hash:a.hash??null}},putFile(r,o,a,c,l=!1){return n("PUT",`${e}/vaults/${r}/file`,{json:{path:o,content:a,baseSeq:c,...l?{force:!0}:{}}})},async deleteFile(r,o,a,c){let l={path:o};a!==void 0&&(l.baseSeq=String(a)),await n("DELETE",`${e}/vaults/${r}/file?${s(l)}`,c?.confirmed?{headers:{"X-Amadeus-Delete-Confirmed":"1"}}:void 0)},move(r,o,a){return n("POST",`${e}/vaults/${r}/move`,{json:{from:o,to:a}})},renameFolder(r,o,a){return n("POST",`${e}/vaults/${r}/folders/rename`,{json:{path:o,newName:a}})},moveFolder(r,o,a){return n("POST",`${e}/vaults/${r}/folders/move`,{json:{path:o,dest:a}})},async deleteFolder(r,o){await n("DELETE",`${e}/vaults/${r}/folders?${s({path:o})}`)},putBinary(r,o,a,c){let l=new FormData;return l.set("path",o),c?.ifAbsent&&l.set("ifAbsent","true"),c?.baseSeq!==void 0&&l.set("baseSeq",String(c.baseSeq)),l.set("file",new Blob([new Uint8Array(a)]),o.split("/").pop()||"file"),n("POST",`${e}/vaults/${r}/binary`,{form:l,timeoutMs:br(a.length)})},async listVersions(r,o){return((await n("GET",`${e}/vaults/${r}/file/versions?${s({path:o})}`)).versions??[]).map(c=>({id:String(c.id),seq:Number(c.seq??0)}))},async getVersion(r,o){let a=await n("GET",`${e}/vaults/${r}/file/versions/${o}`);return String(a.content??"")},async getAsset(r,o){let a=new AbortController,c=setTimeout(()=>a.abort(),12e4);try{let l=await fetch(`${e}/vaults/${r}/asset?${s({ref:o})}`,{headers:{Authorization:`Bearer ${t.token}`},signal:a.signal});if(!l.ok)throw new le(l.status,null,"asset:"+o);return clearTimeout(c),c=setTimeout(()=>a.abort(),br(Number(l.headers.get("content-length"))||0)),Buffer.from(await l.arrayBuffer())}finally{clearTimeout(c)}},async changes(r,o){let a=await n("GET",`${e}/vaults/${r}/changes?${s({since:String(o)})}`);return{changes:a.changes??[],seq:Number(a.seq??0)}}}}function Er(t,e){let n=!1,s=0,r=null,o=null,a=()=>`${t.baseUrl.replace(/\/+$/,"")}/api/amadeus/vaults/${t.vaultId}/events?since=${e.getSince()}`,c=m=>{if(n)return;e.onDown(m);let d=Math.min(3e4,1e3*2**s)*(.7+Math.random()*.6);s++,o=setTimeout(()=>void l(),d)},l=async()=>{if(n)return;r=new AbortController;let m;try{m=await fetch(a(),{headers:{Authorization:`Bearer ${t.token}`,Accept:"text/event-stream"},signal:r.signal})}catch(v){c(v);return}if(!m.ok||!m.body){c(new Error(`sse http ${m.status}`));return}s=0,e.onOpen();let d=m.body.getReader(),f=new TextDecoder,u="",y="",_=[],T=()=>{if(!_.length&&!y)return;let v=_.join(`
|
|
198
|
+
`),O=y||"message";y="",_=[];let N=null;try{N=v?JSON.parse(v):null}catch{return}O==="hello"?e.onHello(Number(N?.seq??0)):O==="change"?e.onChange(N):O==="reset"?e.onReset():O==="presence"?e.onPresence?.(N):O==="presence-roster"&&e.onPresenceRoster?.(N)};try{for(;;){let{done:v,value:O}=await d.read();if(v)break;for(u+=f.decode(O,{stream:!0});;){let N=u.indexOf(`
|
|
199
|
+
`);if(N<0)break;let Y=u.slice(0,N).replace(/\r$/,"");if(u=u.slice(N+1),Y==="")T();else{if(Y.startsWith(":"))continue;Y.startsWith("event:")?y=Y.slice(6).trim():Y.startsWith("data:")&&_.push(Y.slice(5).replace(/^ /,""))}}}}catch(v){n||c(v);return}c(new Error("sse stream ended"))};return l(),{stop:()=>{n=!0,o&&clearTimeout(o),r?.abort()}}}import{constants as yo,promises as Ye}from"node:fs";import wo from"node:path";var Ge=t=>wo.join(fe().userDataDir(),fe().isDevMode()?`${t}.dev.json`:`${t}.json`);async function an(t){try{let e=JSON.parse(await Ye.readFile(Ge(t),"utf8"));return!e||typeof e.vaultRoot!="string"||typeof e.vaultId!="string"?null:(e.files=e.files??{},e.cursor=Number(e.cursor??0),e.lastSyncAt=e.lastSyncAt??null,e)}catch{return null}}function vr(t){let e=null,n=null,s=Promise.resolve(),r=null,o=()=>{if(!e)return s;let a=e,c=JSON.stringify(e);return e=null,s=s.then(async()=>{try{let l=Ge(t),m=`${l}.tmp-${process.pid}-${Date.now()}-0`;await Ye.writeFile(m,c,"utf8"),await Ye.rename(m,l),r=null}catch(l){e??=a,r=l}}),s};return{save(a){e=a,!n&&(n=setTimeout(()=>{n=null,o()},500))},async flush(a=!1){if(n&&(clearTimeout(n),n=null),await o(),a&&r)throw r}}}async function _r(t){try{await Ye.unlink(Ge(t))}catch{}}async function kr(t,e){try{await Ye.copyFile(Ge(t),Ge(e),yo.COPYFILE_EXCL)}catch(n){let s=n?.code;if(s==="EEXIST"||s==="ENOENT")return!1;throw n}return await Ye.unlink(Ge(t)).catch(()=>{}),!0}var So=5*1024*1024,Eo=5*1024*1024,vo=3e4,_o=2500,ko=3e3,Co=5,xo=256*1024,To=5,xr=1024*1024,Tr=200,Ro=6e4,Io=50,Ao=".sync-trash",Je=t=>bo("sha256").update(t).digest("hex");function at(t,e={localRoot:De(),shadowName:`amadeus-sync-${rt()}`,vaultId:"first",serverDir:"",excludePrefixes:["\u4E0E\u6211\u5171\u4EAB/"]}){let n=i=>{let h=on(i,"");if(!h)return null;for(let p of e.excludePrefixes??[])if(h===p.replace(/\/$/,"")||h.startsWith(p))return null;if(e.ignoreNames?.length&&h.split("/").some(p=>e.ignoreNames.includes(p)))return null;let g=e.serverDir?`${e.serverDir}/${h}`:h;return e.inScope&&!e.inScope(g,Ce(g))?null:g},s=i=>{let h;if(e.serverDir){if(!i.startsWith(`${e.serverDir}/`))return null;h=i.slice(e.serverDir.length+1)}else{for(let g of e.excludePrefixes??[])if(i.startsWith(g))return null;h=i}return h.split("/").some(g=>it(g)||!!e.ignoreNames?.includes(g))?null:h},r=(i,h)=>!e.inScope||e.inScope(i,h),o=e.accountId??he(),a=!1,c=0,l=Promise.resolve(),m=new Set,d="disabled",f=null,u=null,y=null,_=null,T=null,v=null,O=0,N=new Map,Y=null,G=vr(e.shadowName),W=new Map,Q=!1,J=!1,ne=[],ue=()=>{u&&(u.pending=W.size?Object.fromEntries(W):void 0,G.save(u))},ut=()=>{J=!1,ne.length=0},Qe=()=>{if(J)return!0;let i=Date.now();for(;ne.length&&i-ne[0]>Ro;)ne.shift();return ne.length>=Io?(J=!0,!0):!1},xe=[],Ne=new Set,Ze=!1,E=null,C=null,w=null,b=()=>{!a||w||(w=setTimeout(()=>{w=null,t.onStatus(Oe())},200))},A=(i,h)=>{d=i,h!==void 0&&(f=h),b()},S=(i,h=!1)=>{if(a){if(i.key){if(Ne.has(i.key))return;Ne.add(i.key)}h?xe.unshift(i):xe.push(i),V()}},x=new Map,D=i=>{if(!a)return;let h=(u?.files[i]?.size??0)>xo,g=(e.pushQuietMs??ko)*(h?To:1),p=Date.now(),k=x.get(i);k&&clearTimeout(k.timer);let I=k?.since??p,$=Math.max(0,Math.min(g,I+g*Co-p)),R=setTimeout(()=>{x.delete(i),S({key:i,run:()=>ae(i,!0)})},$);x.set(i,{timer:R,since:I}),b()},U=()=>{for(let{timer:i}of x.values())clearTimeout(i);x.clear()},F=i=>!(i instanceof le)||i.status>=500||i.status===0,L=i=>i instanceof le&&(i.status===401||i.status===403),V=async()=>{if(!Ze){Ze=!0;try{for(;xe.length;){(d==="idle"||d==="starting")&&A("syncing");let i=xe.shift();i.key&&Ne.delete(i.key);try{await i.run()}catch(h){if(!a)return;if(L(h)){xe.length=0,Ne.clear(),gt(),A("auth-required","login-expired");return}if(F(h)){S(i,!0),gt(),A("offline",h?.message||"network error"),B();return}let g=i.key??"(op)";N.set(g,h?.body?.code||`http ${h?.status}`),b()}}a&&d==="syncing"&&(u&&(u.lastSyncAt=Date.now(),G.save(u)),A("idle",null))}finally{Ze=!1;for(let i of m)i();m.clear()}}},B=()=>{!a||E||(E=setTimeout(()=>{E=null,tt()},vo))},q=i=>{if(!v||!u)throw new Error("engine not bound");let h=s(i);if(h===null)throw new Error("path outside binding: "+i);let g=se.resolve(v,wr(h,u.folder)),p=se.relative(v,g);if(p.startsWith("..")||se.isAbsolute(p))throw new Error("path escapes vault: "+i);return g},Z=i=>({size:i,mtimeMs:-1}),K=async i=>{try{let h=await te.stat(i);return h.isFile()?{size:h.size,mtimeMs:Math.floor(h.mtimeMs)}:null}catch{return null}},we=0,Fe=async(i,h,g=()=>!0)=>{await te.mkdir(se.dirname(i),{recursive:!0});let p=`${i}.tmp-${process.pid}-${Date.now()}-${we++}`;await te.writeFile(p,h);let k=await K(p)??Z(Buffer.byteLength(h));return g()?(await te.rename(p,i),k):(await te.rm(p,{force:!0}),null)},Ue=async i=>{let h;try{h=await te.readdir(i,{withFileTypes:!0})}catch{return}for(let g of h)g.isDirectory()&&await Ue(se.join(i,g.name));try{await te.rmdir(i)}catch{}},oe=async i=>{let h=q(i),g=await K(h),p;try{p=await te.readFile(h)}catch{return null}return{hash:$e(Ce(i))?Je(p.toString("utf8")):Je(p),size:g?.size??p.length,mtimeMs:g?.mtimeMs??-1,buf:p}},_e=async(i,h,g,p)=>{u&&(u.files[i]={seq:h,hash:g,size:p.size,mtimeMs:p.mtimeMs},G.save(u))},ye=i=>{u&&i in u.files&&(delete u.files[i],G.save(u))},Te=async(i,h)=>{if(!y||!u||be(i))return;let g=re,p=Ce(i),k,I,$;if($e(p)){let j;try{j=await y.getFile(u.vaultId,i)}catch(H){if(H instanceof le&&H.status===404){await $t(i);return}throw H}k=j.content,I=j.seq,$=j.hash??Je(j.content)}else{let j;try{j=await y.getAsset(u.vaultId,i)}catch(H){if(H instanceof le&&H.status===404){N.set(i,"ASSET_404"),b();return}throw H}k=j,I=h??0,$=Je(j)}let R=await oe(i);if(g!==re||be(i))return;if(R&&R.hash===$){await _e(i,I,$,R);return}let M=u.files[i];if(R&&M&&$===M.hash&&R.hash!==M.hash){await _e(i,I,$,Z(M.size)),S({key:i,run:()=>ae(i)});return}if(R&&(!M||R.hash!==M.hash)){if(M&&p==="page"&&typeof k=="string"&&await Lr(i,M,R,k,I,$,()=>g===re&&!be(i))||g!==re||be(i))return;await jr(i)}let P=await Fe(q(i),k,()=>g===re&&!be(i));P&&await _e(i,I,$,P)},Lr=async(i,h,g,p,k,I,$)=>{try{if(!y||!u||g.buf.length>xr||p.length>xr)return!1;let M=(await y.listVersions(u.vaultId,i)).find(H=>H.seq===h.seq);if(!M)return!1;let P=await y.getVersion(u.vaultId,M.id);if(Je(P)!==h.hash)return!1;let j=yr(g.buf.toString("utf8"),P,p);return j===null?!1:(await Fe(q(i),j,$)&&(await _e(i,k,I,Z(Buffer.byteLength(j))),S({key:i,run:()=>ae(i)})),!0)}catch{return!1}},jr=async i=>{let h=Ve(It(i,new Date));if(!h)return;let g=h.lastIndexOf("."),p=g>h.lastIndexOf("/"),k=p?h.slice(0,g):h,I=p?h.slice(g):"",$=h;for(let R=2;Cr(q($));R++)$=`${k}-${R}${I}`;try{await te.rename(q(i),q($))}catch(R){if(R?.code==="ENOENT")return;throw R}O++,S({key:$,run:()=>ae($)}),b()},yn=async i=>{if(!v)return;let h=q(i),g=s(i)??i,p=se.join(v,Ao,new Date().toISOString().slice(0,10),...g.split("/")),k=Cr(p)?`${p}.${Date.now()}`:p;try{await te.mkdir(se.dirname(k),{recursive:!0}),await te.rename(h,k)}catch(I){if(I?.code==="ENOENT")return;throw new Error(`\u8F6F\u5220\u5931\u8D25,\u4FDD\u7559\u672C\u5730\u6587\u4EF6 ${h}: ${I?.message??String(I)}`)}},$t=async i=>{if(!u)return;let h=await oe(i);if(be(i))return;let g=u.files[i]??null,p=At(h?.hash??null,g,null);if(p.kind==="deleteLocal"){if(!Q&&Qe()){W.set(i,"local"),ue(),b();return}ne.push(Date.now()),await yn(i),ye(i)}else p.kind==="pushCreate"?(ye(i),S({key:i,run:()=>ae(i)})):ye(i)},wn=(i,h)=>{if(u){for(let g of Object.keys(u.files))if(g===i||g.startsWith(`${i}/`)){let p=h+g.slice(i.length);u.files[p]=u.files[g],delete u.files[g]}G.save(u)}},bn=async i=>{if(!y||!u||i.seq<=u.cursor||!await ht())return;if(i.origin.client&&y.clientId===i.origin.client){u.cursor=i.seq,G.save(u);return}let h=i.type==="structure"?"folder":i.type,g=k=>s(k)!==null&&r(k,h);if(!g(i.path)&&!(i.newPath&&g(i.newPath))){u.cursor=i.seq,G.save(u);return}let p=i.path;switch(i.op){case"write":await Te(p,i.fileSeq);break;case"delete":await $t(p);break;case"move":{let k=i.newPath;if(!k)break;let I=u.files[p];if(await oe(p)&&I)try{await te.mkdir(se.dirname(q(k)),{recursive:!0}),await te.rename(q(p),q(k)),u.files[k]={...I,seq:i.fileSeq??I.seq},delete u.files[p],G.save(u)}catch{await Te(k,i.fileSeq)}else ye(p),await Te(k,i.fileSeq);break}case"mkdir":await te.mkdir(q(p),{recursive:!0});break;case"rename-folder":case"move-folder":{let k=i.newPath;if(!k)break;try{await te.mkdir(se.dirname(q(k)),{recursive:!0}),await te.rename(q(p),q(k))}catch{}wn(p,k);break}case"delete-folder":{let k=`${p}/`;for(let I of Object.keys(u.files))(I===p||I.startsWith(k))&&await $t(I);await Ue(q(p));break}}if(u.cursor=i.seq,G.save(u),i.op==="move"||i.op==="rename-folder"||i.op==="move-folder"||i.op==="delete"||i.op==="delete-folder")try{await t.onRemoteApplied?.(i)}catch{}},Ur=async(i,h,g)=>{let p=Number(h?.seq??0),k=h?.content??null;if(k!==null&&Je(k)===g.hash){await _e(i,p,g.hash,g);return}if(k===null&&p===0){if(!u?.files[i]){N.set(i,h?.code||"EXISTS"),b();return}ye(i),S({key:i,run:()=>ae(i)});return}await Te(i,p)},dt=async(i,h)=>{if(!y||!u)return;let g=await oe(i);if(!g){S({key:i,run:()=>ae(i)});return}if(g.size>So){N.set(i,"TOO_LARGE"),b();return}let p=g.buf.toString("utf8");try{let k=await y.putFile(u.vaultId,i,p,h);N.delete(i),await _e(i,k.seq,k.hash??g.hash,g)}catch(k){if(k instanceof le&&k.status===409){await Ur(i,k.body,g);return}throw k}},ft=async(i,h)=>{if(!y||!u)return;let g=await oe(i);if(!g){S({key:i,run:()=>ae(i)});return}if(g.size>(Y??Eo)){N.set(i,"TOO_LARGE"),b();return}try{let p=await y.putBinary(u.vaultId,i,g.buf,{baseSeq:h});N.delete(i),await _e(i,p.seq,g.hash,g)}catch(p){if(p instanceof le&&p.status===409){let k=Number(p.body?.seq??0),I=p.body?.hash??null;if(I!==null&&I===g.hash){await _e(i,k,g.hash,g);return}if(k===0){if(!u.files[i]){N.set(i,p.body?.code||"EXISTS"),b();return}ye(i),S({key:i,run:()=>ae(i)});return}await Te(i,k);return}throw p}},Sn=async i=>{if(!y||!u||be(i))return;let h=re,g=u.files[i];if(g){if($e(Ce(i)))try{let p=await y.getFile(u.vaultId,i);if(p.seq!==g.seq){await Te(i,p.seq);return}}catch(p){if(p instanceof le&&p.status===404){ye(i);return}throw p}if(!(h!==re||be(i))){try{await y.deleteFile(u.vaultId,i,g.seq,{confirmed:Q})}catch(p){if(p instanceof le&&p.status===409){await Te(i,Number(p.body?.seq??0)||null);return}if(p instanceof le&&p.status===429&&p.body?.code==="MASS_DELETE_BLOCKED"){W.set(i,"remote"),J=!0,ue(),b();return}throw p}ye(i)}}},ht=async()=>v?await te.stat(v).then(h=>h.isDirectory()).catch(()=>!1)||!e.requireRootExists&&!Object.keys(u?.files??{}).length?!0:(A("error",`vault-missing: ${v}`),B(),!1):!1,re=0,mt=new Set,pt=new Map,me=i=>JSON.stringify([i.from,i.to]),Pe=(i,h)=>i===h||i.startsWith(`${h}/`),be=i=>[...u?.moves??[],...mt].some(h=>Pe(i,h.from)||Pe(i,h.to)),Re=()=>!!(u?.moves?.length||mt.size),Mt=async i=>{if(!y||!u)return;let{from:h,to:g,kind:p}=i;if(s(h)===null||s(g)===null)throw new Error("Invalid queued cloud move");i.hashes??=Object.fromEntries(Object.entries(u.files).filter(([R])=>Pe(R,h)).map(([R,M])=>[R.slice(h.length),M.hash])),G.save(u),await G.flush(!0);let k,I=!1;try{if(p==="folder"){let R=se.posix.dirname(h)==="."?"":se.posix.dirname(h),M=se.posix.dirname(g)==="."?"":se.posix.dirname(g);R===M?await y.renameFolder(u.vaultId,h,se.posix.basename(g)):await y.moveFolder(u.vaultId,h,M)}else{let R=await y.move(u.vaultId,h,g);k=Number(R.seq)}}catch(R){if(!(R instanceof le)||R.status!==404)throw R;let M=await y.tree(u.vaultId);if(M.entries.some(H=>Pe(H.path,h))||M.folders.some(H=>Pe(H,h)))throw R;let j=M.entries.find(H=>H.path===g);if(k=j?.seq,I=!j&&!M.entries.some(H=>Pe(H.path,g))&&!M.folders.some(H=>Pe(H,g)),!I){let H=Object.entries(i.hashes);if(!(H.length>0&&H.every(([ke,He])=>M.entries.some(ze=>ze.path===g+ke&&ze.hash===He))))throw new le(409,{code:"MOVE_DESTINATION_CHANGED"},"local-move")}}if(I)for(let R of Object.keys(u.files))Pe(R,h)&&delete u.files[R];else wn(h,g),k!==void 0&&u.files[g]&&(u.files[g].seq=k);u.moves=(u.moves??[]).filter(R=>me(R)!==me(i)),G.save(u);try{await G.flush(!0)}catch(R){throw u.moves.unshift(i),G.save(u),R}let $=pt.get(me(i));pt.delete(me(i)),$?.(),be(g)||(p==="folder"?await Nt():await ae(g))},ae=async(i,h=!1)=>{if(!u||be(i))return;if(!r(i,Ce(i))){ye(i);return}if(!await ht())return;let g=await oe(i);if(be(i))return;let p=u.files[i]??null,k=At(g?.hash??null,p,p?{seq:p.seq,hash:p.hash}:null);switch(k.kind){case"push":$e(Ce(i))?await dt(i,k.baseSeq):await ft(i,k.baseSeq);break;case"pushCreate":$e(Ce(i))?await dt(i,0):await ft(i,0);break;case"pushDelete":if(h){wt();break}if(!Q&&(W.has(i)||Qe())){W.set(i,"remote"),ue(),b();break}ne.push(Date.now()),await Sn(i);break;case"dropShadow":ye(i);break;default:g&&p&&g.hash===p.hash&&g.mtimeMs>=0&&(p.size!==g.size||p.mtimeMs!==g.mtimeMs)&&await _e(i,p.seq,p.hash,g);break}},En=async()=>{let i=new Map;if(!v||!u)return i;let h=v,g=null,p=async k=>{if(g)return;let I;try{I=await te.readdir(k,{withFileTypes:!0})}catch($){g=`${k}: ${$?.message??String($)}`;return}for(let $ of I){if(it($.name)||$.isDirectory()&&e.ignoreNames?.includes($.name))continue;let R=se.join(k,$.name);if($.isDirectory())await p(R);else if($.isFile()){let M=se.relative(h,R).split(se.sep).join("/"),P=n(M);if(!P)continue;try{let j=await te.stat(R);if(!j.isFile())continue;i.set(P,{size:j.size,mtimeMs:Math.floor(j.mtimeMs)})}catch(j){if(j?.code==="ENOENT")continue;g=`${R}: ${j?.message??String(j)}`;return}}}};return await p(h),g?(A("error",`scan-failed: ${g}`),B(),null):i},Nt=async()=>{let i=re;if(Re()||i!==re||!u||!await ht())return;let h=await En();if(!h||Re()||i!==re)return;let g=!1;for(let[I,$]of[...W])($==="remote"&&h.has(I)||$==="local"&&!h.has(I))&&(W.delete(I),g=!0);W.size||ut();for(let[I,$]of h){let R=u.files[I];R&&R.size===$.size&&R.mtimeMs===$.mtimeMs||S({key:I,run:()=>ae(I)})}let p=Object.keys(u.files),k=p.filter(I=>!h.has(I));if(k.length&&!Q&&(J||sn(k.length,p.length,Tr))){J=!0;for(let I of k)W.set(I,"remote");ue(),b();return}g&&(ue(),b());for(let I of k)W.has(I)||S({key:I,run:()=>ae(I)})},et=async()=>{let i=re;if(Re()||i!==re||!y||!u||!v||!await ht())return;let h=await y.tree(u.vaultId);if(h.maxFileBytes!==void 0&&h.maxFileBytes!==Y&&(Y=h.maxFileBytes,b()),Re()||i!==re)return;let g=new Map;for(let P of h.entries)s(P.path)===null||!r(P.path,P.kind)||g.set(P.path,P);let p=await En();if(!p||Re()||i!==re)return;let k=new Set([...g.keys(),...p.keys(),...Object.keys(u.files)]),I=Object.keys(u.files).length,$=[];for(let P of k){if(Re()||i!==re)return;let j=u.files[P]??null,H=g.get(P)??null,ce=p.get(P)??null,ke=null,He=Z(ce?.size??0);if(ce)if(j&&j.size===ce.size&&j.mtimeMs===ce.mtimeMs)ke=j.hash,He=ce;else{let ze=await oe(P);ze&&(ke=ze.hash,He=ze)}$.push({sp:P,d:At(ke,j,H?{seq:H.seq,hash:H.hash}:null),rSeq:H?.seq??null,localHash:ke,localStat:He})}if(Re()||i!==re)return;let R=$.filter(P=>P.d.kind==="deleteLocal"||P.d.kind==="pushDelete").length,M=!Q&&(J||sn(R,I,Tr));M&&R&&(J=!0),W.clear();for(let{sp:P,d:j,rSeq:H,localHash:ce,localStat:ke}of $){if(Re()||i!==re)return;if(M&&(j.kind==="deleteLocal"||j.kind==="pushDelete")){W.set(P,j.kind==="deleteLocal"?"local":"remote");continue}if((j.kind==="deleteLocal"||j.kind==="pushDelete")&&((await oe(P))?.hash??null)!==ce){S({key:P,run:()=>ae(P)});continue}if(Re()||i!==re)return;switch(j.kind){case"adopt":await _e(P,H,ce,ke);break;case"pull":await Te(P,H);break;case"push":$e(Ce(P))?await dt(P,j.baseSeq):await ft(P,j.baseSeq);break;case"pushCreate":$e(Ce(P))?await dt(P,0):await ft(P,0);break;case"pushDelete":await Sn(P);break;case"deleteLocal":await yn(P),ye(P);break;case"conflict":await Te(P,H);break;case"dropShadow":ye(P);break;case"none":break}}Q&&(Q=!1,ne.length=0),W.size||ut(),ue(),M&&b();for(let P of h.folders)if(!(s(P)===null||!r(P,"folder")))try{await te.mkdir(q(P),{recursive:!0})}catch{}u.cursor=h.seq,u.lastSyncAt=Date.now(),G.save(u)},Hr=async()=>{if(!y||!u)return;let i=u.cursor,h=await y.changes(u.vaultId,i);if(h.changes.length===0&&h.seq>i||h.changes.length>0&&h.changes[0].seq!==i+1){await et();return}for(let p of h.changes)await bn(p)},Ie=null,vn=[],_n=()=>{Ie&&vn.push(Ie.close()),Ie=null},zr=()=>{if(!a||Ie||!v)return;Ie=mr.watch(v,{ignoreInitial:!0,depth:12,ignored:h=>{let g=se.basename(h);return it(g)||!!e.ignoreNames?.includes(g)}});let i=h=>{if(!v)return;let g=se.relative(v,h);if(!g||g.startsWith(".."))return;let p=n(g);p&&D(p)};Ie.on("change",i),Ie.on("add",i),Ie.on("unlink",()=>wt()),Ie.on("unlinkDir",()=>wt())},gt=()=>{_?.stop(),_=null},qr=()=>{if(!a||!y||!u||_)return;let i=T;i&&(_=Er({baseUrl:i.cloudUrl,vaultId:u.vaultId,token:i.token},{getSince:()=>u?.cursor??0,onHello:h=>{u&&h>u.cursor&&S({run:Hr})},onChange:h=>{S({run:()=>bn(h)})},onReset:()=>{S({run:et})},onOpen:()=>{(d==="offline"||d==="starting")&&A("idle",null),S({run:Nt})},onDown:()=>{(d==="idle"||d==="syncing")&&A("offline")},onPresence:h=>t.onPresence?.(u?.vaultId??"",h),onPresenceRoster:h=>t.onPresenceRoster?.(u?.vaultId??"",h)}))},Wr=async()=>{let i=await Ee(o);if(i.cloudSync?.deviceId)return i.cloudSync.deviceId;let h=`desk-${Math.random().toString(36).slice(2,10)}${Date.now().toString(36)}`;return await Ae({cloudSync:{...i.cloudSync??{},deviceId:h}},o),h},Br=async i=>{gt(),_n(),xe.length=0,Ne.clear(),W.clear(),Q=!1,J=!1,ne.length=0;let h=await Ee(o);if(i!==c)return;let g=h.cloudSync;if(g?.enabled===!1){v=null,y=null,A("disabled",null);return}if(!o||o!==he()){A("auth-required","not-logged-in");return}if(v=e.localRoot,e.requireRootExists){let $=await te.stat(v).then(R=>R.isDirectory()).catch(()=>!1);if(i!==c)return;if(!$){A("error",`vault-missing: ${v}`),B();return}}if(i!==c)return;let p=t.loadCreds();if(!p.cloudUrl||!p.token){y=null,A("auth-required","not-logged-in");return}A("starting",null);let k=g?.deviceId??await Wr();if(i!==c)return;let I=e.clientIdSuffix?`${k}#${e.clientIdSuffix}`:k;T={cloudUrl:p.cloudUrl,token:p.token},y=Sr({baseUrl:p.cloudUrl,token:p.token,clientId:I});try{let $=e.vaultId==="first"?g?.vaultId:e.vaultId;if(!$){let M=await y.listVaults();if(i!==c)return;if(!M.length)throw new Error("\u4E91\u7AEF\u65E0\u53EF\u7528 vault");$=M[0].id,await Ae({cloudSync:{...g??{},vaultId:$}},o)}if(i!==c)return;let R=await an(e.shadowName);if(i!==c||(u=R&&R.vaultRoot===v&&R.vaultId===$&&R.folder===""?R:{vaultRoot:v,folder:"",vaultId:$,cursor:0,lastSyncAt:null,files:{}},i!==c))return;for(let[M,P]of Object.entries(u.pending??{}))W.set(M,P);if(W.size&&(J=!0),!e.requireRootExists){let M=await te.stat(v).then(P=>P.isDirectory()).catch(()=>!1);if(i!==c)return;if(!M){if(Object.keys(u.files).length){A("error",`mirror-missing: ${v}`),B();return}if(await te.mkdir(v,{recursive:!0}),i!==c)return}}zr();for(let M of u.moves??[])S({key:`move:${me(M)}`,run:()=>Mt(M)});S({run:et}),S({run:async()=>{qr()}})}catch($){if(i!==c)return;L($)?A("auth-required","login-expired"):(A("offline",$?.message||String($)),B())}},kn=()=>{a=!1,gt(),_n(),xe.length=0,Ne.clear(),U();for(let i of[E,C,w])i&&clearTimeout(i);E=C=w=null},Cn=async()=>{Ze&&await new Promise(i=>m.add(i)),await Promise.all(vn.splice(0)),await G.flush(),u=null,y=null,T=null,v=null,O=0,N.clear(),Y=null,W.clear(),Q=!1,J=!1,ne.length=0,d="disabled",f=null},Vr=()=>{xn()},yt=null,tt=()=>{yt?.(),yt=fe().onBeforeQuit(Vr);let i=++c;kn();let h=l.catch(()=>{}).then(async()=>{await Cn(),i===c&&(a=!0,await Br(i))});return l=h,h},xn=()=>{yt?.(),yt=null,++c,kn();let i=l.catch(()=>{}).then(Cn);return l=i,i},Oe=()=>({enabled:d!=="disabled",state:d==="idle"&&x.size?"syncing":d,lastSyncAt:u?.lastSyncAt??null,pending:xe.length+x.size,conflicts:O,skipped:[...N].map(([i,h])=>({path:i,reason:h})),error:f,pendingDeletions:W.size,maxFileBytes:Y});return{getStatus:Oe,start(){tt()},notifyLocal(i,h,g){if(!u||d==="disabled"||d==="auth-required")return;let p=n(i),k=g?n(g):null;if(h==="write"&&p){it(p.split("/").pop()||"")||D(p);return}if(h==="remove"){if(!p)return;let I=`${p}/`,$=!1;for(let R of Object.keys(u.files))(R===p||R.startsWith(I))&&($=!0,S({key:R,run:()=>ae(R)}));!$&&p&&S({key:p,run:()=>ae(p)})}},holdLocalMove(i,h){let g=k=>e.serverDir?`${e.serverDir}/${k.replace(/\\/g,"/").normalize("NFC")}`:k.replace(/\\/g,"/").normalize("NFC"),p={from:g(i),to:g(h)};return++re,mt.add(p),()=>{mt.delete(p)}},async notifyLocalMove(i,h,g,p){let k=n(i),I=n(h),$=u??await an(e.shadowName),R=on(i,""),M=R&&(e.serverDir?`${e.serverDir}/${R}`:R);if(!k&&I&&M&&$&&Object.keys($.files).some(P=>P===M||P.startsWith(`${M}/`))&&(k=M),!k&&!I){g?.();return}if(k&&I){let P=u??$;if(!P){g?.();return}let j=p??(Object.keys(P.files).some(ce=>ce.startsWith(`${k}/`))?"folder":"file"),H={from:k,to:I,kind:j};P.moves??=[],P.moves.some(ce=>me(ce)===me(H))||(P.moves.push(H),++re),g&&pt.set(me(H),g),G.save(P);try{await G.flush(!0)}catch(ce){throw P.moves=P.moves.filter(ke=>me(ke)!==me(H)),pt.delete(me(H)),G.save(P),ce}u===P&&a&&d!=="disabled"&&d!=="auth-required"&&S({key:`move:${me(H)}`,run:()=>Mt(H)});return}k&&this.notifyLocal(i,"remove"),I&&(S({key:I,run:()=>ae(I)}),wt()),g?.()},async setEnabled(i){let h=await Ee(o);return await Ae({cloudSync:{...h.cloudSync??{},enabled:i}},o),await tt(),Oe()},async restart(){return await tt(),Oe()},async syncNow(){if(N.clear(),d==="disabled"||d==="auth-required"||!y)await tt();else{for(let i of u?.moves??[])S({key:`move:${me(i)}`,run:()=>Mt(i)});S({run:et})}return Oe()},confirmMassDeletions(){return W.size&&(Q=!0,J=!1,W.clear(),ne.length=0,ue(),S({run:et})),Oe()},stop:xn};function wt(){a&&(C&&clearTimeout(C),C=setTimeout(()=>{C=null,S({run:Nt})},_o))}}import{createHash as Po}from"node:crypto";function Rr(t){let e=t.replace(/\.md$/i,""),n=t.lastIndexOf("/"),s=n<0?"":t.slice(0,n);return{root:t,fdPrefix:`${e}.fd/`,assetPrefix:s?`${s}/.amadeus/`:".amadeus/"}}function Ir(t,e,n){return!!(e===t.root||e.startsWith(t.fdPrefix)||`${e}/`===t.fdPrefix||n==="binary"&&e.startsWith(t.assetPrefix)||n==="folder"&&(`${e}/`===t.assetPrefix||e.startsWith(t.assetPrefix)))}var Do=t=>Po("sha256").update(t).digest("hex").slice(0,8),$o=t=>t.replace(/[\\/:*?"<>|]/g," ").trim().slice(0,40)||"shared",Pt="\u4E0E\u6211\u5171\u4EAB";function ln(t){let e=Do(`${t.vaultId}:${t.path}`),n=Rr(t.path),s=t.path.includes("/")?t.path.slice(0,t.path.lastIndexOf("/")):"";return{key:e,vaultId:t.vaultId,rootPath:t.path,title:t.title,localRelDir:`${Pt}/${$o(t.title)}-${e}`,serverDir:s,inScope:(r,o)=>Ir(n,r,o)}}function cn(){let t=fe().readCreds(),e=Se(t.cloudUrl??"",t.token??""),n=new AbortController,s=()=>{let f=fe().readCreds();if(n.signal.aborted||!e||Se(f.cloudUrl??"",f.token??"")!==e)throw Object.assign(new Error("Cloud account changed; retry from the current account"),{status:401});return f},r=()=>{let f=s();if(!f.cloudUrl||!f.token)throw Object.assign(new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7"),{status:401});return f.cloudUrl.replace(/\/+$/,"")},o=async(f,u,y)=>{let _=s();if(!_.cloudUrl||!_.token)throw Object.assign(new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7"),{status:401});let T=await fetch(`${_.cloudUrl.replace(/\/+$/,"")}/api/amadeus${u}`,{method:f,headers:{Authorization:`Bearer ${_.token}`,...y!==void 0?{"Content-Type":"application/json"}:{}},body:y!==void 0?JSON.stringify(y):void 0,signal:AbortSignal.any([n.signal,AbortSignal.timeout(2e4)])});if(!T.ok){let O=null;try{O=await T.json()}catch{}throw Object.assign(new Error(O?.detail||`http ${T.status}`),{status:T.status,code:O?.code})}let v=await T.json();return s(),v},a=null,c=async()=>(s(),a||(a=(await o("GET","/vaults")).vaults[0]?.id??"default",a)),l=()=>{try{let f=(s().token??"").split(".")[1],u=JSON.parse(Buffer.from(f.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString());return typeof u.userId=="string"?u.userId:null}catch{return null}},m=async()=>(await o("GET","/shared-with-me")).items.map(u=>{let y=ln(u),_=u.path.split("/").pop()??u.path;return{...u,localPath:`${y.localRelDir}/${_}`}}),d=null;return{stop:()=>n.abort(),call:o,ensureOwnVault:c,myUserId:l,sharedWithMe:m,linkBase:async()=>{if(s(),d)return d;try{d=((await o("GET","/collab/link-base")).webOrigin??"").trim().replace(/\/+$/,"")||r()}catch{d=r()}return d},async heartbeat(f,u){let y=(f??"").replace(/\\/g,"/"),_,T=null,v=u.find(O=>y.startsWith(`${O.localRelDir}/`));v?(_=v.vaultId,T=v.serverDir?`${v.serverDir}/${y.slice(v.localRelDir.length+1)}`:y.slice(v.localRelDir.length+1)):(_=await c(),T=y||null),await o("POST",`/vaults/${encodeURIComponent(_)}/presence`,{page:T})}}}import{promises as Ar}from"node:fs";import Mo from"node:path";var un=".forsion-vault.md",dn=t=>`${t}/${un}`;var ge=t=>t.replace(/\\/g,"/").normalize("NFC");function fn(t){let e=ge(t.path);return e?t.kind==="folder"?`${e}/`:t.kind==="page"?`${e.replace(/\.md$/i,"")}.fd/`:null:null}function Ke(t,e,n){let s=ge(n);if(!s)return!1;if(t.some(r=>ge(r.path)===s))return!0;for(let r of e??[]){let o=ge(r);if(!o)continue;let a=`${o.replace(/\.md$/i,"")}.fd`;if(s===o||s.startsWith(`${o}/`)||s===a||s.startsWith(`${a}/`))return!1}return t.some(r=>{let o=fn(r);return!!o&&s.startsWith(o)})}function hn(t,e,n){let s=ge(t),r=ge(e);return s===r?ge(n):s.startsWith(`${r}/`)?ge(n)+s.slice(r.length):null}function lt(t,e,n){let s=!1,r=t.map(o=>{let a=hn(o,e,n);return a===null?o:(s=!0,a)});return{changed:s,next:r}}async function Pr(t){let e=await Ar.readdir(t,{withFileTypes:!0}).catch(()=>[]),n=[];for(let s of e)!s.isDirectory()||s.name.startsWith(".")||await Ar.access(Mo.join(t,s.name,un)).then(()=>!0,()=>!1)&&n.push(s.name);return n.sort()}var ie={get:"amadeus:sync:get",setEnabled:"amadeus:sync:set-enabled",syncNow:"amadeus:sync:now",confirmDeletions:"amadeus:sync:confirm-deletions",status:"amadeus:sync:status",switchSide:"amadeus:sync:switch-side",collabCall:"amadeus:collab:call",presence:"amadeus:collab:presence",entryGet:"amadeus:entry-sync:get",entryEnable:"amadeus:entry-sync:enable",entryDisable:"amadeus:entry-sync:disable",entryClosure:"amadeus:entry-sync:closure",entryChange:"amadeus:entry-sync:change",otherSideDbs:"amadeus:entry-sync:other-side-dbs"};import{createHash as No}from"node:crypto";var Dt=t=>No("sha256").update(t).digest("hex").slice(0,8);function Dr(t){return t.replace(/ \(conflict \d{4}-\d{2}-\d{2} \d{4}\)(?=(?:\.[^./]+)?$)/,"")}function Me(t,e=[]){let n=[],s=[];for(let r of t){let o=ge(r.path);if(!o)continue;s.push(o);let a=fn(r);a&&n.push(a)}return{entries:t,exclude:e,prefixes:n,paths:s}}function $r(t,e){let n=Dr(ge(e));if(!n)return!1;if(Ke(t.entries,t.exclude,n))return!0;let s=`${n}/`;for(let r of t.paths)if(r.startsWith(s))return!0;for(let r of t.prefixes)if(r.startsWith(s))return!0;return!1}function ct(t,e,n){let s=!1,r=t.map(o=>{let a=hn(o.path,e,n);return a===null?o:(s=!0,{...o,path:a})});return{changed:s,next:r}}function Mr(t,e,n,s){if(e==="delete"||e==="delete-folder"){let r=ge(n),o=t.filter(a=>{let c=ge(a.path);return!(c===r||e==="delete-folder"&&c.startsWith(`${r}/`))});return{changed:o.length!==t.length,next:o}}return s?ct(t,n,s):{changed:!1,next:t}}function mn(t,e){let n=Ve(t);return!n||n!==t.normalize("NFC").trim()?"\u540D\u79F0\u4E0D\u5408\u6CD5":n.includes("/")?"\u540D\u79F0\u4E0D\u80FD\u5305\u542B /":n===Pt?`\u300C${Pt}\u300D\u662F\u4FDD\u7559\u540D\u79F0`:e.includes(n)?"\u8BE5\u540D\u79F0\u5DF2\u88AB\u5176\u4ED6\u667A\u5E93\u7684\u4E91\u540C\u6B65\u5360\u7528":null}var Nr=["setAmadeusSyncFactory","readCreds","accountId","homeDir"],pn=t=>Nr.every(e=>typeof t[e]=="function"),Fo=()=>({enabled:!1,state:"disabled",lastSyncAt:null,pending:0,conflicts:0,skipped:[],error:null,pendingDeletions:0,maxFileBytes:null,side:"local"});function gn(t){let e=null,n=()=>{if(!e)throw new Error("Cloud sync is not ready");return e};t.handle(ie.get,()=>e?e.get():Fo()),t.handle(ie.setEnabled,(s,r)=>n().setEnabled(r)),t.handle(ie.syncNow,()=>n().syncNow()),t.handle(ie.confirmDeletions,()=>n().confirmDeletions()),t.handle(ie.entryGet,()=>n().entryGet()),t.handle(ie.otherSideDbs,()=>n().otherSideDbs()),t.handle(ie.entryEnable,(s,r)=>n().entryEnable(r)),t.handle(ie.entryDisable,(s,r)=>n().entryDisable(r)),t.handle(ie.entryClosure,(s,r,o)=>n().entryClosure(r,o)),t.handle(ie.collabCall,(s,r,o)=>n().collabCall(r,o)),t.handle(ie.switchSide,(s,r)=>n().switchSide(s.sender.id,r)),t.setAmadeusSyncFactory(s=>{Gn(s);let r=Fr(s);return e=r.handlers,r.instance}),t.log("[forsion-extend] amadeus cloud sync registered")}function Fr(t){let e=t.notifyAll,n=()=>t.vaultRoot(),s=0,r=!1,o=cn(),a=new Map,c=()=>{let E=Date.now();for(let[C,w]of a)E-w.at>7e4&&a.delete(C);e(ie.presence,[...a.values()])},l={loadCreds:()=>t.readCreds(),onStatus:E=>e(ie.status,{...E,pendingDeletions:ne(),side:_()?"cloud":"local"}),onPresence:(E,C)=>{let w=C;w?.userId&&(a.set(w.userId,{userId:w.userId,username:String(w.username??"user"),page:w.page??null,at:Number(w.at)||Date.now()}),c())},onPresenceRoster:(E,C)=>{if(Array.isArray(C)){for(let w of C){let b=w;b?.userId&&a.set(b.userId,{userId:b.userId,username:String(b.username??"user"),page:b.page??null,at:Number(b.at)||Date.now()})}c()}}},m=()=>{let E=s;return{...l,onStatus:C=>{E===s&&l.onStatus(C)},onPresence:(C,w)=>{E===s&&l.onPresence(C,w)},onPresenceRoster:(C,w)=>{E===s&&l.onPresenceRoster(C,w)}}},d=at(m()),f=new Map,u=[],y=async()=>{if(!r||!he())return;let E=s,C=o,w;try{w=await C.sharedWithMe()}catch{return}if(E!==s||!r)return;let b=w.map(S=>ln(S));u=b;let A=new Set(b.map(S=>S.key));for(let[S,x]of f)if(!A.has(S)){if(await x.engine.stop(),E!==s)return;f.delete(S)}for(let S of b){if(f.has(S.key))continue;let x=at(m(),{localRoot:je.join(De(),...S.localRelDir.split("/")),shadowName:`amadeus-sync-${rt()}-share-${S.key}`,vaultId:S.vaultId,serverDir:S.serverDir,inScope:S.inScope});f.set(S.key,{engine:x,plan:S}),x.start()}},_=()=>n()===De(),T=(E,C=E.base)=>{E.base=C;let w=[C,...E.pendingMoves];E.scope.current=Me(w.flatMap(b=>b.entries),w.flatMap(b=>b.exclude))},v=new Map,O=new Set,N=()=>{e(ie.entryChange)},Y=async(E,C)=>{let w=v.get(E);if(!w)return;let b=x=>x&&x.startsWith(`${w.cloudName}/`)?x.slice(w.cloudName.length+1):null,A=b(C.path);if(!A)return;let S=!1;await qe(x=>{if(v.get(E)!==w)return!1;let D=(x.entrySync??[]).find(B=>B.vaultRoot===E);if(!D)return!1;let U=C.op,F=b(C.newPath),L=Mr(D.entries,U,A,F),V=F?lt(D.exclude??[],A,F):{changed:!1,next:D.exclude??[]};if(!L.changed&&!V.changed)return!1;S=!0,D.entries=L.next,V.changed&&(D.exclude=V.next),T(w,Me(D.entries,D.exclude??[]))}),S&&v.get(E)===w&&N()},G=E=>{let C=s;return{...m(),onStatus:w=>{C===s&&e(ie.status,{...w,pendingDeletions:ne(),side:"local",binding:E})},onRemoteApplied:async w=>{C===s&&await Y(E,w)}}},W=async()=>{let E=he();if(!r||!E)return;let C=s,w=o,b=rt(E);await t.adoptLegacyCloudState(E,kr);let A=await Ee(E),S=A.entrySync??[];if(C!==s||!r||E!==he())return;let x=new Map(S.map(D=>[D.vaultRoot,D]));for(let[D,U]of v){let F=x.get(D);if(!(F&&F.cloudName===U.cloudName)&&(await U.engine.stop(),C!==s||(v.delete(D),F&&await _r(`amadeus-sync-${b}-entry-${Dt(D)}`),C!==s)))return}for(let D of S){let U=v.get(D.vaultRoot);if(U){T(U,Me(D.entries,D.exclude??[]));continue}let F={current:Me(D.entries,D.exclude??[])},L=D.cloudName,V=at(G(D.vaultRoot),{accountId:E,localRoot:D.vaultRoot,shadowName:`amadeus-sync-${b}-entry-${Dt(D.vaultRoot)}`,vaultId:"first",serverDir:L,clientIdSuffix:`entry-${Dt(D.vaultRoot)}`,requireRootExists:!0,ignoreNames:[".git","node_modules",".trash"],inScope:B=>B===L?!0:B.startsWith(`${L}/`)?$r(F.current,B.slice(L.length+1)):!1});v.set(D.vaultRoot,{engine:V,scope:F,cloudName:L,base:F.current,pendingMoves:new Set}),V.start()}if(A.cloudSync?.enabled!==!1)for(let D of S)O.has(D.cloudName)||(async()=>{try{let U=await w.ensureOwnVault();await w.call("PUT",`/vaults/${encodeURIComponent(U)}/file`,{path:dn(D.cloudName),content:"",baseSeq:0}),C===s&&O.add(D.cloudName)}catch(U){U?.status===409&&C===s&&O.add(D.cloudName)}})()},Q=async(E,C,w,b,A)=>{let S=C.replace(/\\/g,"/").normalize("NFC"),x=w.replace(/\\/g,"/").normalize("NFC"),D=!1,U,F,L,V=A??"file";try{await qe(async B=>{if(v.get(E)!==b)return!1;let q=(B.entrySync??[]).find(oe=>oe.vaultRoot===E);if(!q)return!1;let Z=ct(q.entries,S,x),K=lt(q.exclude??[],S,x),we=Ke(q.entries,q.exclude,S);!A&&await Xe.stat(je.join(E,...x.split("/"))).then(oe=>oe.isDirectory(),()=>!1)&&(V="folder");let Fe=V==="folder"?"folder":/\.md$/i.test(x)?"page":"asset";we&&!Ke(Z.next,K.next,x)&&(Z.next.push({path:x,kind:Fe}),Z.changed=!0),D=Z.changed||K.changed;let Ue=q.entries.filter(oe=>ct([oe],S,x).changed);return we&&!Ue.some(oe=>oe.path===S)&&Ue.push({path:S,kind:Fe}),U=Me(Ue,(q.exclude??[]).filter(oe=>lt([oe],S,x).changed)),F=b.base,b.pendingMoves.add(U),q.entries=Z.next,q.exclude=K.next,L=Me(q.entries,q.exclude),T(b,L),D})}catch(B){throw U&&b.pendingMoves.delete(U),T(b,b.base===L&&F?F:b.base),B}try{U&&await b.engine.notifyLocalMove(S,x,()=>{b.pendingMoves.delete(U),T(b)},V)}catch(B){throw U&&b.pendingMoves.delete(U),await qe(q=>{let Z=q.entrySync?.find(K=>K.vaultRoot===E);if(!Z)return!1;Z.entries=ct(Z.entries,x,S).next,Z.exclude=lt(Z.exclude??[],x,S).next,T(b,Me(Z.entries,Z.exclude))}),B}D&&v.get(E)===b&&N()},J=E=>{let C=E.replace(/\\/g,"/");for(let{engine:w,plan:b}of f.values())if(C.startsWith(`${b.localRelDir}/`))return{engine:w,rel:C.slice(b.localRelDir.length+1)};return{engine:d,rel:C}};t.setMutationHooks((E,C)=>{if(_()){let w=J(E);w.engine.notifyLocal(w.rel,C);return}v.get(n()??"")?.engine.notifyLocal(E,C)},(E,C,w)=>{if(_()){let S=J(E),x=J(C);if(S.engine===x.engine)return S.engine.notifyLocalMove(S.rel,x.rel,void 0,w);S.engine.notifyLocal(S.rel,"remove"),x.engine.notifyLocal(x.rel,"write");return}let b=n()??"",A=v.get(b);if(A)return Q(b,E,C,A,w)},(E,C)=>{if(_()){let w=J(E),b=J(C),A=[w.engine.holdLocalMove(w.rel,b.rel)];return w.engine!==b.engine&&A.push(b.engine.holdLocalMove(w.rel,b.rel)),()=>{for(let S of A)S()}}return v.get(n()??"")?.engine.holdLocalMove(E,C)});let ne=()=>{let E=d.getStatus().pendingDeletions;for(let{engine:C}of f.values())E+=C.getStatus().pendingDeletions;for(let{engine:C}of v.values())E+=C.getStatus().pendingDeletions;return E},ue=E=>({...E,pendingDeletions:ne(),side:_()?"cloud":"local"}),ut=()=>{if(!r)return Promise.resolve(d.getStatus());y();for(let{engine:E}of f.values())E.syncNow();for(let{engine:E}of v.values())E.syncNow();return d.syncNow()},Qe=async()=>{++s,r=!1,o.stop();let E=[d.stop(),...[...f.values()].map(({engine:w})=>w.stop()),...[...v.values()].map(({engine:w})=>w.stop())];f.clear(),v.clear(),u=[],O.clear(),a.clear(),c(),await Promise.all(E),await t.awaitPendingVaultWrites();let C=n();if(C&&St(C)){let w=await Ee(),b=w.localVault&&!St(w.localVault)?w.localVault:je.join(t.workspaceDir(),"Amadeus");await Xe.mkdir(b,{recursive:!0}),await Ae({lastVault:b,localVault:b,lastPage:void 0}),await t.activateRoot(b,!1)}N()};return{handlers:{get:()=>ue(d.getStatus()),setEnabled:async E=>{if(!r)throw new Error("Cloud account is changing");let C=s;return await d.setEnabled(E),C!==s?d.getStatus():(await Promise.all([...f.values(),...v.values()].map(({engine:w})=>w.restart())),ue(d.getStatus()))},syncNow:()=>ut(),confirmDeletions:()=>{for(let{engine:E}of f.values())E.confirmMassDeletions();for(let{engine:E}of v.values())E.confirmMassDeletions();return ue(d.confirmMassDeletions())},entryGet:async()=>{let E=await Ee(),C=De();return{vaults:E.entrySync??[],activeRoot:n(),cloudRoot:C,mirrorVaults:await Pr(C)}},otherSideDbs:async()=>{let E=n();if(!E)return null;let C=De(),w=await Ee(),b=E===C?w.localVault&&w.localVault!==C?w.localVault:null:C;if(!b)return null;let A=[],S=500,x=async(D,U)=>{if(A.length>=S)return;let F;try{F=await Xe.readdir(D,{withFileTypes:!0})}catch{return}for(let L of F){if(A.length>=S)break;if(L.name.startsWith(".")||L.isSymbolicLink())continue;let V=U?`${U}/${L.name}`:L.name;if(L.isDirectory())await x(je.join(D,L.name),V);else if(L.isFile()&&/\.db$/i.test(L.name))try{A.push({rel:V,source:await Xe.readFile(je.join(D,L.name),"utf8")})}catch{}}};return await x(b,""),{root:b,vaultName:b===C?"\u4E91\u7AEF":je.basename(b),dbs:A}},entryEnable:async E=>{let C=s,w=o;if(!r||!he())return{error:"Sign in to enable cloud sync"};let b=n();if(!b||_())return{error:"\u4EC5\u672C\u5730 vault \u53EF\u5F00\u542F\u4E91\u540C\u6B65"};let A=await Ee(),S=A.entrySync??[],x=S.find(D=>D.vaultRoot===b);if(!x){let D=(E.cloudName??je.basename(b)).normalize("NFC").trim(),U=mn(D,S.map(F=>F.cloudName));if(U)return{error:U};if(!E.merge)try{let F=await w.ensureOwnVault(),L=await w.call("GET",`/vaults/${encodeURIComponent(F)}/tree`);if((L.folders??[]).some(B=>B===D||B.startsWith(`${D}/`))||(L.entries??[]).some(B=>B.path===D||B.path.startsWith(`${D}/`)))return{conflict:D}}catch(F){return{error:F?.message||"\u65E0\u6CD5\u8FDE\u63A5\u4E91\u7AEF(\u9996\u6B21\u5F00\u542F\u9700\u8981\u5728\u7EBF)"}}x={vaultRoot:b,cloudName:D,entries:[]},S.push(x),(async()=>{try{let F=await w.ensureOwnVault();await w.call("PUT",`/vaults/${encodeURIComponent(F)}/file`,{path:dn(x.cloudName),content:"",baseSeq:0})}catch{}})()}return C!==s||!r?{error:"Cloud account changed; retry from the current account"}:(await qe(D=>{if(C!==s||!r)return!1;let U=D.entrySync??[],F=U.find(K=>K.vaultRoot===b);if(!F){let K=mn(x.cloudName,U.map(we=>we.cloudName));if(K)throw new Error(K);F={vaultRoot:b,cloudName:x.cloudName,entries:[]},U.push(F)}let L=K=>String(K??"").replace(/\\/g,"/").normalize("NFC"),V=new Set;for(let K of E.entries??[]){let we=L(K.path);we&&(V.add(we),!F.entries.some(Fe=>Fe.path===we)&&F.entries.push({path:we,kind:K.kind==="folder"||K.kind==="asset"?K.kind:"page"}))}let B=(E.exclude??[]).map(L).filter(Boolean),q=new Set([...V,...(E.include??[]).map(L).filter(Boolean)]);F.exclude=[...new Set([...(F.exclude??[]).filter(K=>!q.has(K)),...B])];let Z=new Set(B);F.entries=F.entries.filter(K=>!Z.has(K.path)),D.entrySync=U,x=F},A.cloudAccountId),C!==s?{error:"Cloud account changed; retry from the current account"}:(await W(),v.get(b)?.engine.syncNow(),N(),{ok:!0,cloudName:x.cloudName}))},entryDisable:async E=>{let C=n(),w=!1,b=s;return await qe(A=>{if(b!==s||!r)return!1;let S=(A.entrySync??[]).find(U=>U.vaultRoot===C);if(!C||!S)return!1;let x=String(E??"").replace(/\\/g,"/").normalize("NFC"),D=S.entries.length;if(S.entries=S.entries.filter(U=>U.path!==x),Ke(S.entries,S.exclude,x))S.exclude=[...new Set([...S.exclude??[],x])];else if(S.entries.length===D)return!1;w=!0}),!w||b!==s?{ok:!1}:(await W(),N(),{ok:!0})},entryClosure:(E,C)=>t.relatedClosure(String(E??""),C==="folder"?"folder":"page"),collabCall:async(E,C)=>{let w=o,b=async()=>w.ensureOwnVault(),A=x=>String((C??[])[x]??""),S=x=>(C??[])[x]??{};switch(E){case"listVaults":return(await w.call("GET","/vaults")).vaults;case"activeVaultId":return b();case"pageShare":return w.call("GET",`/vaults/${encodeURIComponent(await b())}/page-shares?path=${encodeURIComponent(A(0))}`);case"createPageShare":return w.call("POST",`/vaults/${encodeURIComponent(await b())}/page-shares`,{path:A(0),...S(1)});case"updatePageShare":return w.call("PATCH",`/vaults/${encodeURIComponent(await b())}/page-shares/${encodeURIComponent(A(0))}`,S(1));case"revokePageShare":return w.call("DELETE",`/vaults/${encodeURIComponent(await b())}/page-shares/${encodeURIComponent(A(0))}`);case"setParticipantRole":return w.call("PATCH",`/vaults/${encodeURIComponent(await b())}/page-shares/${encodeURIComponent(A(0))}/members/${encodeURIComponent(A(1))}`,{role:A(2)});case"removeParticipant":return w.call("DELETE",`/vaults/${encodeURIComponent(await b())}/page-shares/${encodeURIComponent(A(0))}/members/${encodeURIComponent(A(1))}`);case"sharedWithMe":{let x=await w.sharedWithMe();return y(),x}case"leaveShare":{let x=w.myUserId();if(!x)throw new Error("\u672A\u767B\u5F55");return w.call("DELETE",`/vaults/${encodeURIComponent(await b())}/page-shares/${encodeURIComponent(A(0))}/members/${encodeURIComponent(x)}`)}case"publishes":return w.call("GET",`/vaults/${encodeURIComponent(await b())}/shares`);case"listAllShares":{let x=(await w.call("GET","/vaults")).vaults||[],D=w.myUserId(),U=[],F=[];for(let L of x){try{let V=await w.call("GET",`/vaults/${encodeURIComponent(L.id)}/shares`);for(let B of V.shares||[])U.push({...B,vaultId:L.id,vaultName:L.name||""})}catch(V){t.log(`[connect] listAllShares publishes vault ${L.id} failed: ${V?.message}`)}try{let V=await w.call("GET",`/vaults/${encodeURIComponent(L.id)}/page-shares`),B=V?.shares||V?.pageShares||(Array.isArray(V)?V:[]);for(let q of B){let Z=q.created_by??q.createdBy;(!D||!Z||Z===D)&&F.push({...q,vaultId:L.id,vaultName:L.name||""})}}catch(V){t.log(`[connect] listAllShares pageShares vault ${L.id} failed: ${V?.message}`)}}return{publishes:U,pageShares:F,linkBase:await w.linkBase()}}case"createPublish":{let x=await w.call("POST",`/vaults/${encodeURIComponent(await b())}/shares`,{mode:A(0),path:A(1)});return{...x,url:`${await w.linkBase()}/share/${x.token}`}}case"revokePublish":return w.call("DELETE",`/vaults/${encodeURIComponent(await b())}/shares/${encodeURIComponent(A(0))}`);case"revokePublishIn":return w.call("DELETE",`/vaults/${encodeURIComponent(A(0))}/shares/${encodeURIComponent(A(1))}`);case"revokePageShareIn":return w.call("DELETE",`/vaults/${encodeURIComponent(A(0))}/page-shares/${encodeURIComponent(A(1))}`);case"myUserId":return w.myUserId();case"linkBase":return w.linkBase();case"heartbeat":return w.heartbeat((C??[])[0]??null,u);default:throw new Error(`unknown collab fn: ${E}`)}},switchSide:async(E,C)=>{let w=await Ee();if(C==="cloud"){if(!r||!he())throw new Error("Sign in to open cloud notes");let S=De();await Xe.mkdir(S,{recursive:!0}),w.lastVault&&!St(w.lastVault)&&await Ae({localVault:w.lastVault}),await Ae({lastVault:S});let x=await t.activateRoot(S,!1);return t.bindRenderer(E,S),{...x,side:"cloud"}}let b=w.localVault&&await Xe.stat(w.localVault).then(S=>S.isDirectory()).catch(()=>!1)?w.localVault:null;if(!b){let S=await t.ensureDefaultVault();return t.bindRenderer(E,S.root),{...S,side:"local"}}await Ae({lastVault:b});let A=await t.activateRoot(b,!1);return t.bindRenderer(E,b),{...A,side:"local"}}},instance:{start:()=>{r=!0,d.start(),y(),W()},stopAllSync:Qe,restartAllSync:async()=>{await Qe(),o=cn(),d=at(m()),r=!0,await Promise.all([d.restart(),y(),W()]),N(),e(ie.status,ue(d.getStatus()))}}}}async function Or(t,e){if(!e)return"";try{let n=await de({base:t,token:e},"POST","/api/auth/handoff",{},5e3);if(n.status===200&&typeof n.json?.code=="string"&&n.json.code)return`code=${encodeURIComponent(n.json.code)}`;if(n.status===404||n.status===405)return`token=${encodeURIComponent(e)}`}catch{}return""}var Oo=["membership","credits"];function _a(t){let e={status:0,error:"untrusted"},n={ok:!1,error:"untrusted"};t.handle("auth:openAccountCenter",async(r,o)=>{if(!t.isTrustedSender(r))return n;let{base:a,token:c}=await t.getCloud();if(!a)return{ok:!1};let l=o&&/^[a-z0-9-]+$/i.test(o)?`#${o}`:"",m=await Or(a,c),d=`${a}/account${m?`?${m}`:""}${l}`;return await t.openExternal(d),{ok:!0}}),t.handle("auth:openPayCenter",async(r,o)=>{if(!t.isTrustedSender(r))return n;if(o!==void 0&&!Oo.includes(o))return{ok:!1,error:"invalid_tab"};let{base:a,token:c}=await t.getCloud();if(!a)return{ok:!1};let l=await Or(a,c),m=`${a}/pay?tab=${o??"membership"}${l?`&${l}`:""}&redirect=${encodeURIComponent(`${a}/account`)}`;return await t.openExternal(m),{ok:!0}});let s=()=>t.getCloud();t.handle("account:quota",async r=>{if(!t.isTrustedSender(r))return e;let o=await s();if(!o.token)return{status:401,json:null};try{return await de(o,"GET","/api/token-quota/my",void 0,15e3)}catch(a){return{status:0,json:{detail:String(a?.message||a)}}}}),t.handle("account:useResetCard",async(r,o)=>{if(!t.isTrustedSender(r))return e;let a=await s();if(!a.token)return{status:401,json:null};if(o!==void 0&&o!=="both")return{status:400,json:{error:"invalid_type",detail:`invalid reset card type: ${o}`}};let c=o??"both";try{return await de(a,"POST","/api/token-quota/reset-card/use",{type:c},15e3)}catch(l){return{status:0,json:{detail:String(l?.message||l)}}}}),t.handle("account:bgConvert",async(r,o)=>{if(!t.isTrustedSender(r))return e;let a=await s();if(!a.token)return{status:401,json:null};if(!Number.isInteger(o)||o<1||o>100)return{status:400,json:{error:"invalid_percent"}};try{return await de(a,"POST","/api/token-quota/background/convert",{percent:o},15e3)}catch(c){return{status:0,json:{detail:String(c?.message||c)}}}}),t.handle("account:bgAutoMain",async(r,o)=>{if(!t.isTrustedSender(r))return e;let a=await s();if(!a.token)return{status:401,json:null};if(typeof o!="boolean")return{status:400,json:{error:"invalid_request"}};try{return await de(a,"POST","/api/token-quota/background/auto-main",{enabled:o},15e3)}catch(c){return{status:0,json:{detail:String(c?.message||c)}}}}),t.handle("feedback:submit",async(r,o)=>{if(!t.isTrustedSender(r))return n;let{base:a,token:c}=await t.getCloud();if(!a||!c)return{ok:!1,error:"not-logged-in"};let l=(o?.description||"").trim();if(!l)return{ok:!1,error:"empty"};if(l.length>1e4)return{ok:!1,error:"description-too-long"};let m=[],d=!1;if(o?.sessionLogJson){let f=Buffer.from(o.sessionLogJson,"utf8");if(f.length>5*1024*1024)return{ok:!1,error:"attachment-too-large"};m.push({filename:o.sessionLogName||"tangu-session.json",mime_type:"application/json",size:f.length,data_base64:f.toString("base64")})}try{let f=await fetch(`${a}/api/feedback`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${c}`},body:JSON.stringify({description:l,attachments:m}),signal:AbortSignal.timeout(2e4)});if(!f.ok){let y=`HTTP ${f.status}`;try{y=(await f.json())?.detail||y}catch{}return{ok:!1,error:y}}return{ok:!0,id:(await f.json().catch(()=>({})))?.id??null,attachmentSkipped:d}}catch(f){return{ok:!1,error:f?.message||String(f)}}}),t.handle("cloud:fetch",async(r,o)=>{if(!t.isTrustedSender(r))return{status:0,error:"untrusted"};let a=o??{},c=typeof a.path=="string"?a.path:"",l=Math.min(12e4,Math.max(1e3,Number(a.timeoutMs)||15e3)),m=typeof a.method=="string"?a.method.toUpperCase():"GET";if(!/^(GET|POST|PUT|PATCH|DELETE)$/.test(m))return{status:0,error:"bad_method"};if(!c.startsWith("/"))return{status:0,error:"bad_path"};let{base:d,token:f}=await t.getCloud();if(!String(d||""))return{status:0,error:"no_cloud_url"};let u=Tn(d,c);if(!u)return{status:0,error:"bad_path"};if(!f)return{status:401,error:"not_signed_in"};let y=a.body!==void 0&&m!=="GET"&&m!=="DELETE",_=new AbortController,T=setTimeout(()=>_.abort(),l);try{let v=await fetch(u,{method:m,headers:{Authorization:`Bearer ${f}`,...y?{"Content-Type":"application/json"}:{}},body:y?JSON.stringify(a.body):void 0,signal:_.signal});return{status:v.status,json:await v.json().catch(()=>null)}}catch(v){return{status:0,error:String(v?.message||v)}}finally{clearTimeout(T)}}),t.log("[forsion-extend] cloud account handlers registered"),jt(t)?Ut(t):t.log("[forsion-extend] host has no Connect seam (projectsRoot / transpileForServe / mimeOf / setPreviewHooks); Connect stays with the host"),zt(t)?qt(t):t.log("[forsion-extend] host has no remote-sync seam (registerRemoteSyncBackend / readCreds); penzor stays with the host"),Bt(t)?Vt(t):t.log("[forsion-extend] host has no account seam (accountCommit / accountClear / \u2026); account core stays with the host"),pn(t)?gn(t):t.log("[forsion-extend] host has no amadeus seam (setAmadeusSyncFactory); cloud sync stays with the host")}export{Vn as ACCOUNT_SEAM,Nr as AMADEUS_SEAM,Ot as CONNECT_MAX_FILES,In as CONNECT_MAX_FILE_BYTES,An as CONNECT_MAX_TOTAL_BYTES,Fn as FORSION_CONNECT_LOCAL_SDK,Oo as PAY_TABS,Un as PENZOR_MAX_FILE,ie as SYNC_IPC,de as cloudJson,Pn as collectProjectFiles,It as conflictCopyPath,co as conflictCopyVariant,Bn as createAccountCloud,Fr as createAmadeusCloud,jn as createPenzorRemote,Ht as expectedPartsOf,Se as forsionAccountId,Wn as forsionRefreshToken,nt as forsionWhoami,Bt as hasAccountHost,pn as hasAmadeusHost,jt as hasConnectHost,zt as hasRemoteSyncHost,Nn as makePreviewProxy,$n as readConnectMeta,Vt as registerAccount,gn as registerAmadeus,_a as registerCloud,Ut as registerConnect,qt as registerPenzor,qn as shouldRefreshToken,Dr as stripConflictSuffix,uo as textFingerprint,zn as tokenAgeMs,ds as tokenRemainingMs,Mn as writeConnectMeta};
|
|
200
200
|
/*! Bundled license information:
|
|
201
201
|
|
|
202
202
|
chokidar/index.js:
|