obsidian-headless 0.0.2 → 0.0.4

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.
Files changed (2) hide show
  1. package/cli.js +12 -12
  2. package/package.json +2 -3
package/cli.js CHANGED
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
- var wi=Object.create;var pt=Object.defineProperty;var vi=Object.getOwnPropertyDescriptor;var Ei=Object.getOwnPropertyNames;var Si=Object.getPrototypeOf,Di=Object.prototype.hasOwnProperty;var Pi=(s,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Ei(e))!Di.call(s,r)&&r!==t&&pt(s,r,{get:()=>e[r],enumerable:!(i=vi(e,r))||i.enumerable});return s};var M=(s,e,t)=>(t=s!=null?wi(Si(s)):{},Pi(e||!s||!s.__esModule?pt(t,"default",{value:s,enumerable:!0}):t,s));var N=M(require("keytar")),$="obsidian-headless",gt="OBSIDIAN_AUTH_TOKEN",I={async getToken(){if(process.env[gt])return process.env[gt];try{return await N.getPassword($,"token")}catch(s){return console.error("Failed to get token from keychain:",s),null}},async setToken(s){try{await N.setPassword($,"token",s)}catch(e){throw new Error(`Failed to store token in keychain: ${e}`)}},async deleteToken(){try{await N.deletePassword($,"token")}catch{}},async getKey(s){let e;try{e=await N.getPassword($,`${s}:key`)}catch{}if(!e)return null;try{return JSON.parse(e)}catch{return null}},async setKey(s,e){try{await N.setPassword($,`${s}:key`,JSON.stringify(e))}catch(t){throw new Error(`Failed to store key in keychain: ${t}`)}},async deleteKey(s){try{await N.deletePassword($,`${s}:key`)}catch{}}};var dt=M(require("node:crypto")),P=M(require("node:fs")),B=M(require("node:os")),D=M(require("node:path")),ke=M(require("node:url"));global.nodeCrypto=dt.default;var ge=null;try{let s=D.default.join(__dirname,"btime",process.platform+"-"+process.arch);ge=require(D.default.join(s,"btime.node")).btime}catch{}function mt(){return ge!==null}function yt(s,e){if(!ge)return;let t=Buffer.alloc(Buffer.byteLength(s,"utf-8")+1);t.write(s,0,t.length-1,"utf-8"),t[t.length-1]=0,ge(t,e)}var Me=["image","audio","video","pdf","unsupported"],G=["image","audio","pdf","video"],Be=["app","appearance","appearance-data","hotkey","core-plugin","core-plugin-data","community-plugin","community-plugin-data"],z=["app","appearance","appearance-data","hotkey","core-plugin","core-plugin-data"];var Ft="obsidian-headless",bt=B.default.platform()==="linux"?D.default.join(process.env.XDG_CONFIG_HOME||D.default.join(B.default.homedir(),".config"),Ft):D.default.join(B.default.homedir(),"."+Ft);function ee(s){return D.default.join(bt,"sync",s)}function wt(s){return D.default.join(ee(s),"state.db")}function vt(s){return D.default.join(ee(s),"sync.log")}function Et(s){return D.default.join(ee(s),"config.json")}function Ue(s){let e=ee(s);return P.default.existsSync(e)||P.default.mkdirSync(e,{recursive:!0,mode:448}),e}function Ve(s){let e=Et(s);if(!P.default.existsSync(e))return null;try{let t=P.default.readFileSync(e,"utf-8");return JSON.parse(t)}catch{return null}}function je(s,e){Ue(s);let t=Et(s);P.default.writeFileSync(t,JSON.stringify(e,null,2),{mode:384})}function St(s,e){return D.default.join(s,e,".sync.lock")}function Dt(s){let e=ee(s);P.default.existsSync(e)&&P.default.rmSync(e,{recursive:!0,force:!0})}function qe(){let s=D.default.join(bt,"sync");if(!P.default.existsSync(s))return[];let e=P.default.readdirSync(s,{withFileTypes:!0}),t=[];for(let i of e)if(i.isDirectory()){let r=D.default.join(s,i.name,"config.json");P.default.existsSync(r)&&t.push(i.name)}return t}function te(s){let e=D.default.resolve(s),t=qe();for(let i of t){let r=Ve(i);if(r&&D.default.resolve(r.vaultPath)===e)return r}return null}function Pt(s){let e=s.split(",").map(t=>t.trim().toLowerCase());for(let t of e)if(!Me.includes(t))throw new Error(`Invalid file type: "${t}". Valid values: ${Me.join(", ")}`);return e}function At(s){let e=s.split(",").map(t=>t.trim().toLowerCase());for(let t of e)if(!Be.includes(t))throw new Error(`Invalid config: "${t}". Valid values: ${Be.join(", ")}`);return e}function Ke(s){if(s){if(!s.startsWith(".")||s.includes("/")||s.includes("\\"))throw new Error(`Invalid config directory: "${s}". Must be a dotfolder name (e.g. .obsidian).`);return s}}function We(){let s=B.default.hostname(),e=B.default.platform();return`${s} (${e==="darwin"?"macOS":e==="win32"?"Windows":e==="linux"?"Linux":e})`}function _t(s){let e=D.default.dirname(s);P.default.existsSync(e)||P.default.mkdirSync(e,{recursive:!0});let t=P.default.createWriteStream(s,{flags:"a"}),i=console.log,r=console.warn,n=console.error,o=console.debug;function a(...l){let c=new Date().toISOString(),u=l.map(p=>typeof p=="object"?JSON.stringify(p):String(p)).join(" ");t.write(`[${c}] ${u}
3
- `)}return console.log=(...l)=>{i(...l),a(...l)},console.warn=(...l)=>{r(...l),a(...l)},console.error=(...l)=>{n(...l),a(...l)},console.debug=(...l)=>{o(...l),a(...l)},()=>{console.log=i,console.warn=r,console.error=n,console.debug=o,t.end()}}var Tt=M(require("better-sqlite3"));var Ai=1,de=class{constructor(e){let t=D.default.dirname(e);P.default.existsSync(t)||P.default.mkdirSync(t,{recursive:!0}),this.db=new Tt.default(e),this.db.pragma("journal_mode = WAL"),this.db.exec("CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT );"),this.db.exec("CREATE TABLE IF NOT EXISTS local_files (path TEXT PRIMARY KEY, data TEXT NOT NULL);"),this.db.exec("CREATE TABLE IF NOT EXISTS server_files (path TEXT PRIMARY KEY, data TEXT NOT NULL);"),this.db.exec("CREATE TABLE IF NOT EXISTS pending_files (uid INTEGER PRIMARY KEY, path TEXT, data TEXT NOT NULL)"),this.stmts={getMeta:this.db.prepare("SELECT value FROM meta WHERE key = ?"),setMeta:this.db.prepare("INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)"),getLocalFile:this.db.prepare("SELECT data FROM local_files WHERE path = ?"),setLocalFile:this.db.prepare("INSERT OR REPLACE INTO local_files (path, data) VALUES (?, ?)"),deleteLocalFile:this.db.prepare("DELETE FROM local_files WHERE path = ?"),getAllLocalFiles:this.db.prepare("SELECT path, data FROM local_files"),getServerFile:this.db.prepare("SELECT data FROM server_files WHERE path = ?"),setServerFile:this.db.prepare("INSERT OR REPLACE INTO server_files (path, data) VALUES (?, ?)"),deleteServerFile:this.db.prepare("DELETE FROM server_files WHERE path = ?"),getAllServerFiles:this.db.prepare("SELECT path, data FROM server_files"),addPendingFile:this.db.prepare("INSERT OR REPLACE INTO pending_files (uid, path, data) VALUES (?, ?, ?)"),deletePendingFile:this.db.prepare("DELETE FROM pending_files WHERE path = ?"),getPendingFiles:this.db.prepare("SELECT data FROM pending_files ORDER BY uid")},this.getMetaValue("schema_version")===null&&this.setMetaValue("schema_version",String(Ai))}getMetaValue(e){let t=this.stmts.getMeta.get(e);return t?t.value:null}setMetaValue(e,t){this.stmts.setMeta.run(e,t)}getVersion(){let e=this.getMetaValue("version");return e?parseInt(e,10):0}setVersion(e){this.setMetaValue("version",String(e))}isInitial(){return this.getMetaValue("initial")!=="false"}setInitial(e){this.setMetaValue("initial",e?"true":"false")}getLocalFile(e){let t=this.stmts.getLocalFile.get(e);if(!t)return null;try{return JSON.parse(t.data)}catch{return null}}setLocalFile(e){this.stmts.setLocalFile.run(e.path,JSON.stringify(e))}deleteLocalFile(e){this.stmts.deleteLocalFile.run(e)}getAllLocalFiles(){let e=this.stmts.getAllLocalFiles.all(),t={};for(let i of e)try{t[i.path]=JSON.parse(i.data)}catch{}return t}getServerFile(e){let t=this.stmts.getServerFile.get(e);if(!t)return null;try{return JSON.parse(t.data)}catch{return null}}setServerFile(e){this.stmts.setServerFile.run(e.path,JSON.stringify(e))}deleteServerFile(e){this.stmts.deleteServerFile.run(e)}getAllServerFiles(){let e=this.stmts.getAllServerFiles.all(),t={};for(let i of e)try{t[i.path]=JSON.parse(i.data)}catch{}return t}addPendingFile(e){this.stmts.addPendingFile.run(e.uid,e.path,JSON.stringify(e))}deletePendingFile(e){this.stmts.deletePendingFile.run(e)}getPendingFiles(){let e=this.stmts.getPendingFiles.all(),t=[];for(let i of e)try{t.push(JSON.parse(i.data))}catch{}return t}close(){this.db.close()}};var ie=()=>typeof activeWindow<"u"?activeWindow:global;function xt(s,e=0,t=!1){let i=null,r=null,n=null,o=0,a=0,l=ie(),c=function(){let d=r,F=n;return r=null,n=null,s.apply(d,F)},u=function(){if(o){let d=Date.now();if(d<o){l=ie(),i=l.setTimeout(u,o-d),o=0;return}}a=0,i=null,c()},p=function(...d){r=this,n=d;let F=Date.now();return i?t?o=a=F+e:l!==ie()&&a<=F&&(l.clearTimeout(i),l=ie(),i=l.setTimeout(u,0)):(l=ie(),a=F+e,i=l.setTimeout(u,e)),p};return p.cancel=function(){return i&&(l.clearTimeout(i),i=null),p},p.run=function(){if(i)return l.clearTimeout(i),i=null,c()},p}var _i=/\u00A0|\u202F/g;function He(s){return s.replace(_i," ")}function O(s){let e=s.lastIndexOf("/");return e===-1?s:s.slice(e+1)}function U(s){let e=s.lastIndexOf("/");return e===-1?"":s.slice(0,e)}function $e(s){for(;s;){if(O(s).startsWith("."))return!0;s=U(s)}return!1}function It(s){let e=O(s),t=e.lastIndexOf(".");return t===-1||t===e.length-1||t===0?e:e.substr(0,t)}function Lt(s){let e=s.lastIndexOf(".");return e===-1||e===s.length-1||e===0?s:s.substr(0,e)}function T(s){let e=s.lastIndexOf(".");return e===-1||e===s.length-1||e===0?"":s.substr(e+1).toLowerCase()}function Q(s){return He(X(s)).normalize("NFC")}function X(s){return s=s.replace(/([\\/])+/g,"/").replace(/(^\/+|\/+$)/g,""),s===""&&(s="/"),s}function re(s){return s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength)}function Ge(s){return Buffer.from(s)}var Ti=5;function xi(s,e){if(e.isFile())return{type:"file",realpath:s,ctime:Math.round(e.birthtimeMs),mtime:Math.round(e.mtimeMs),size:e.size};if(e.isDirectory())return{type:"folder",realpath:s}}function Qe(s){return{ctime:Math.round(s.birthtimeMs),mtime:Math.round(s.mtimeMs),size:s.size}}var Ct=typeof process<"u"?process:null,Ot=Ct?Ct.platform:"",Rt=Ot==="darwin",Nt=Ot==="win32",me=Rt||Nt,ye=class{constructor(e,t,i,r,n,o,a){this.thingsHappening=xt(this.kill.bind(this),60*1e3,!0);this.resourcePathPrefix=o,this.basePath=a,this.fs=e,this.fsPromises=e.promises,this.path=t,this.url=i,this.trash=r,this.files={},this.promise=Promise.resolve(),this.watchers={},this.handler=null,this.btime=n,this.insensitive=Rt||Nt;try{this.testInsensitive()}catch(l){console.error(l)}}testInsensitive(){let{fs:e,path:t,basePath:i}=this,r=t.join(i,".OBSIDIANTEST"),n=t.join(i,".OBSIDIANTEST".toLowerCase());e.existsSync(r)&&e.unlinkSync(r),e.writeFileSync(r,"","utf8"),this.insensitive=e.existsSync(n),e.unlinkSync(r)}getName(){return this.path.basename(this.basePath)}getBasePath(){return this.basePath}async listAll(){this.files={},this.files["/"]={type:"folder",realpath:"/"},await this.listRecursive("")}async listRecursive(e){let t=this.getFullRealPath(e),i=await this.fsPromises.readdir(t);this.thingsHappening();let r=[];for(let n of i)r.push(this.listRecursiveChild(e,n));await Promise.all(r)}async listRecursiveChild(e,t){let i=X(e===""?t:e+"/"+t),r=Q(i);if(this.trigger("raw",r),$e(r))return await this.reconcileDeletion(i,r);try{await this.reconcileFileInternal(i,r)}catch(n){if(n.code==="ENOENT")await this.reconcileDeletion(i,r,!0);else throw n}}mkdir(e){return this.queue(async()=>{let t=this.getFullPath(e);await this.fsPromises.mkdir(t,{recursive:!0}),await this.reconcileInternalFile(e)})}trashSystem(e){return this.queue(async()=>{let t=this.getFullPath(e);return this.trash(t)?(await this.reconcileInternalFile(e),!0):!1})}trashLocal(e){return this.queue(async()=>{let t=this.getFullPath(e),i=this.getFullPath(".trash");await this.fsPromises.mkdir(i,{recursive:!0});let r=this.path.extname(t),n=this.path.basename(t,r),o=this.path.join(i,n+r),a=1;for(;await this._exists(o);)a++,o=this.path.join(i,n+" "+a+r);await this.fsPromises.rename(t,o),await this.reconcileInternalFile(e)})}rmdir(e,t){return this.queue(async()=>{let i=this.getFullPath(e);await this.fsPromises.rm(i,{maxRetries:Ti,recursive:t}),await this.reconcileInternalFile(e)})}read(e){return this.queue(async()=>{let t=this.getFullPath(e);try{return this.fsPromises.readFile(t,"utf8")}catch(i){throw this.queue(()=>this.reconcileInternalFile(e)),i}})}readBinary(e){return this.queue(async()=>{let t=this.getFullPath(e);try{let i=await this.fsPromises.readFile(t);return re(i)}catch(i){throw this.queue(()=>this.reconcileInternalFile(e)),i}})}write(e,t,i){return this.queue(async()=>{let r=this.getFullPath(e);try{await this.fsPromises.writeFile(r,t,"utf8"),await this.applyWriteOptions(r,i)}finally{await this.reconcileInternalFile(e)}})}writeBinary(e,t,i){return this.queue(async()=>{let r=this.getFullPath(e),n=Ge(t);try{await this.fsPromises.writeFile(r,n),await this.applyWriteOptions(r,i)}finally{await this.reconcileInternalFile(e)}})}append(e,t,i){return this.queue(async()=>{let r=this.getFullPath(e);try{await this.fsPromises.appendFile(r,t,"utf8"),await this.applyWriteOptions(r,i)}finally{await this.reconcileInternalFile(e)}})}appendBinary(e,t,i){return this.queue(async()=>{let r=this.getFullPath(e),n=Ge(t);try{await this.fsPromises.appendFile(r,n),await this.applyWriteOptions(r,i)}finally{await this.reconcileInternalFile(e)}})}process(e,t,i){return this.queue(async()=>{let r=this.getFullPath(e),n=await this.fsPromises.readFile(r,"utf8"),o=t(n);if(o===n)return n;try{await this.fsPromises.writeFile(r,o,"utf8"),await this.applyWriteOptions(r,i)}finally{await this.reconcileInternalFile(e)}return o})}async applyWriteOptions(e,t){if(!t)return;let{ctime:i,mtime:r,immediate:n}=t;i&&this.btime(e,i),r&&await this.fsPromises.utimes(e,r/1e3,r/1e3),n&&n()}getResourcePath(e){let t=this.getFullPath(e),i=0,r=this.files[e];r&&r.type==="file"&&(i=r.mtime),i||(i=Date.now());let n=this.url.pathToFileURL(t).href;return n.startsWith("file:///")?n=n.substring(8):n.startsWith("file://")&&(n="%5C%5C"+n.substring(7)),this.resourcePathPrefix+n+"?"+i}getFilePath(e){let t=this.getFullPath(e);return this.url.pathToFileURL(t).toString()}remove(e){return this.queue(async()=>{let t=this.getFullPath(e);await this.fsPromises.unlink(t),await this.reconcileInternalFile(e)})}update(e){return this.queue(async()=>{await this.reconcileInternalFile(e)})}async rename(e,t){e!==t&&await this.queue(async()=>{let i=this.getFullPath(e),r=this.getFullPath(t);if(await this._exists(r,!1)&&!(this.insensitive&&e.toLowerCase()===t.toLowerCase()))throw new Error("Destination file already exists!");let n=this.files[e],o=n?n.realpath:null;if(await this.fsPromises.rename(i,r),!n)return;delete this.files[e];let a=this.getRealPath(t);if(n.realpath=a,this.files[t]=n,this.trigger("renamed",t,e),n.type==="folder"&&this.watchers.hasOwnProperty(e)&&(this.stopWatchPath(e),await this.startWatchPath(t)),n.type==="folder"){for(let c in this.files)if(this.files.hasOwnProperty(c)&&c.startsWith(e+"/")){let u=c.slice(e.length),p=t+u,d=this.files[c];delete this.files[c];let F=d.realpath.slice(o.length);d.realpath=a+F,this.files[p]=d,this.trigger("renamed",p,c)}}})}async copyRecursive(e,t){let i=await this.fsPromises.stat(e);if(i.isFile()&&await this.fsPromises.copyFile(e,t,this.fs.constants.COPYFILE_EXCL),i.isDirectory()){await this.fsPromises.mkdir(t,{recursive:!0});let r=await this.fsPromises.readdir(e);for(let n of r){let o=this.path.join(e,n),a=this.path.join(t,n);await this.copyRecursive(o,a)}}}async copy(e,t){await this.queue(async()=>{let i=this.getFullPath(e),r=this.getFullPath(t);await this.copyRecursive(i,r),await this.reconcileInternalFile(t)})}async exists(e,t){return this.queue(()=>{let i=this.getFullPath(e);return this._exists(i,t)})}async _exists(e,t){try{await this.fsPromises.access(e)}catch{return!1}if(t&&this.insensitive){let i=this.path.dirname(e),r=this.path.basename(e);if((await this.fsPromises.readdir(i)).indexOf(r)===-1)return!1}return!0}async stat(e){return this.queue(async()=>{let t=this.getFullPath(e);try{let i=await this.fsPromises.stat(t);if(i.isFile())return{type:"file",...Qe(i)};if(i.isDirectory())return{type:"folder",...Qe(i)}}catch(i){if(i.code!=="ENOENT")throw i}return null})}async list(e){return this.queue(async()=>{let t=this.getFullPath(e),i=await this.fsPromises.readdir(t),r={folders:[],files:[]};for(let n of i){let o=X(e===""?n:e+"/"+n),a=Q(o),l=await this.fsPromises.stat(this.getFullRealPath(o));l.isFile()&&r.files.push(a),l.isDirectory()&&r.folders.push(a)}return r})}async watch(e){return this.stopWatch(),this.handler=e,await this.startWatchPath("/"),this.queue(()=>this.listAll())}async watchHiddenRecursive(e){if(!me)try{let t=this.getFullRealPath(e),i=await this.fsPromises.readdir(t);await this.startWatchPath(e);for(let r of i)try{let n=X(e===""?r:e+"/"+r),o=this.getFullRealPath(n);(await this.fsPromises.lstat(o)).isDirectory()&&await this.watchHiddenRecursive(n)}catch{}}catch{}}stopWatch(){for(let e in this.watchers)this.watchers.hasOwnProperty(e)&&this.stopWatchPath(e);this.handler=null}async startWatchPath(e){let t=this.getRealPath(e);if(this.watchers[e])return;let i=this.getFullPath(e),r=i;try{r=await this.fsPromises.realpath(i)}catch(o){o.code!=="ENOENT"&&console.error(o)}let n=this.fs.watch(i,{persistent:!1,encoding:"utf8",recursive:me});n.on("change",(o,a)=>{let l=t==="/"?a:t+"/"+a;this.onFileChange(l)}),n.on("error",()=>{this.onFileChange(t)}),this.watchers[e]={watcher:n,resolvedPath:r}}stopWatchPath(e){let t=this.watchers[e];t&&(t.watcher.close(),delete this.watchers[e])}onFileChange(e){e&&(e=X(e),setTimeout(()=>{let t=Q(e);this.queue(()=>this.reconcileFile(e,t,!1))},0))}async reconcileInternalFile(e){return this.reconcileFile(this.getRealPath(e),e)}async reconcileFile(e,t,i=!0){if(this.trigger("raw",t),$e(t))return await this.reconcileDeletion(e,t,i);let r=U(t);r&&r!=="/"&&(this.files[t]||await this.reconcileFile(U(e),r,i));try{let n=this.getFullRealPath(e);if(this.insensitive){let o=this.path.dirname(n),a=this.path.basename(t),l=await this.fsPromises.readdir(o);if(l=l.map(c=>He(c).normalize("NFC")),l.indexOf(a)===-1)return await this.reconcileDeletion(e,t,i)}await this.reconcileFileInternal(e,t)}catch(n){n.code==="ENOENT"?await this.reconcileDeletion(e,t,i):console.error(n)}}async reconcileFileInternal(e,t){let i=this.getFullRealPath(e),r=await this.fsPromises.lstat(i);r.isFile()?await this.reconcileFileCreation(e,t,r):r.isDirectory()?await this.reconcileFolderCreation(e,t):r.isSymbolicLink()&&await this.reconcileSymbolicLinkCreation(e,t)}async reconcileFileCreation(e,t,i){let r=Qe(i),n=this.files[t];if(n)if(n.realpath=e,n.type==="file"){(n.mtime!==Math.round(i.mtimeMs)||n.size!==i.size)&&(n.mtime=Math.round(i.mtimeMs),n.size=i.size,this.trigger("raw",t,t,r),this.trigger("modified",t,t,r));return}else this.removeFile(t);this.files[t]=xi(e,i),this.trigger("file-created",t,t,r)}async reconcileFolderCreation(e,t){this.files.hasOwnProperty(t)?this.files[t].realpath=e:(this.files[t]={type:"folder",realpath:e},this.trigger("folder-created",t),me||await this.startWatchPath(t),await this.listRecursive(e))}async reconcileSymbolicLinkCreation(e,t){let i=this.getFullRealPath(e),r;try{r=await this.fsPromises.realpath(i)}catch{return}let n=this.path.sep,o=this.watchers;if(o.hasOwnProperty(t))o[t].resolvedPath=r;else for(let l in o)if(o.hasOwnProperty(l)&&l!==t){let c=o[l].resolvedPath;if(r===c||c.startsWith(r+n)||r.startsWith(c+n))return}let a=await this.fsPromises.stat(i);a.isFile()?await this.reconcileFileCreation(e,t,a):a.isDirectory()&&(me&&await this.startWatchPath(t),await this.reconcileFolderCreation(e,t))}async reconcileDeletion(e,t,i=!0){if(t==="/"){this.trigger("closed",t);return}this.stopWatchPath(t);let r=this.files[t];if(r){if(!i){setTimeout(()=>{this.queue(()=>this.reconcileFile(e,t))},100);return}if(r.type==="folder")for(let n in this.files)this.files.hasOwnProperty(n)&&n.startsWith(t+"/")&&this.removeFile(n);this.removeFile(t)}}trigger(e,t,i,r){this.handler&&this.handler(e,t,i,r)}getRealPath(e){let t=e;for(;t;){if(this.files.hasOwnProperty(t)){let i=e.substr(t.length);return this.files[t].realpath+i}t=U(t)}return e}getFullPath(e){let t=this.getRealPath(e);return this.getFullRealPath(t)}getFullRealPath(e){return this.path.join(this.basePath,e)}kill(){this.killLastAction&&(this.killLastAction(new Error("File system operation timed out.")),this.killLastAction=null)}queue(e){let t=()=>{let r=new Promise((n,o)=>this.killLastAction=o);return this.thingsHappening(),Promise.race([r,e()])},i=this.promise.then(t,t);return this.promise=i,i}removeFile(e){let t=this.files[e];delete this.files[e],t&&(t.type==="file"?this.trigger("file-removed",e):t.type==="folder"&&this.trigger("folder-removed",e))}static async readLocalFile(e){let t=require;if(t){let i=t("fs");return re(await i.promises.readFile(e))}return null}static async mkdir(e){let t=require;return t?await t("fs").promises.mkdir(e,{recursive:!0}):null}};var kt=/[^a-zA-Z0-9]/,Mt=/\s/,Bt=/[\r\n]/,Ii=/\n\r?\n$/,Li=/^\r?\n\r?\n/;function V(s,e){return s<e?s:e}function j(s,e){return s>e?s:e}var Ci=/\W/;function Oi(s,e){let t=s.length;for(let i=e;i<t;i+=1)if(Ci.test(s[i]))return i;return-1}function Ri(s,e){let t=0,i=-1;for(;i<s.length-1;)if(i=Oi(s,t),i!==-1){if(t!==i){let n=s.substring(t,i);e(n)}let r=s[i];e(r),t=i+1}else{let r=s.substring(t,s.length);e(r),i=s.length;break}}var Fe=class{constructor(){this.diffTimeout=1;this.diffEditCost=4;this.matchThreshold=.5;this.matchDistance=1e3;this.patchDeleteThreshold=.5;this.patchMargin=4;this.matchMaxBits=32}diff_main(e,t,i,r){typeof r>"u"&&(this.diffTimeout<=0?r=Number.MAX_VALUE:r=Date.now()+this.diffTimeout*1e3);let n=r;if(e==null||t==null)throw new Error("Null input. (diff_main)");if(e===t)return e?[[0,e]]:[];typeof i>"u"&&(i=!0);let o=i,a=this.diff_commonPrefix(e,t),l=e.substring(0,a);e=e.substring(a),t=t.substring(a),a=this.diff_commonSuffix(e,t);let c=e.substring(e.length-a);e=e.substring(0,e.length-a),t=t.substring(0,t.length-a);let u=this.diff_compute_(e,t,o,n);return l&&u.unshift([0,l]),c&&u.push([0,c]),this.diff_cleanupMerge(u),u}diff_lineMode(e,t){let{chars1:i,chars2:r,lineArray:n}=this.diff_linesToChars_(e,t),o=this.diff_main(i,r,!1);return this.diff_charsToLines_(o,n),o}diff_wordMode(e,t){let{chars1:i,chars2:r,lineArray:n}=this.diff_wordsToChars_(e,t),o=this.diff_main(i,r,!1);return this.diff_charsToLines_(o,n),o}diff_wordsToChars_(e,t){let i=[],r={};i[0]="";let n=l=>{let c="",u=i.length;return Ri(l,p=>{(r.hasOwnProperty?r.hasOwnProperty(p):r[p]!==void 0)?c+=String.fromCharCode(r[p]):(c+=String.fromCharCode(u),r[p]=u,i[u++]=p)}),c},o=n(e),a=n(t);return{chars1:o,chars2:a,lineArray:i}}diff_commonPrefix(e,t){if(!e||!t||e.charAt(0)!==t.charAt(0))return 0;let i=0,r=V(e.length,t.length),n=r,o=0;for(;i<n;)e.substring(o,n)===t.substring(o,n)?(i=n,o=i):r=n,n=Math.floor((r-i)/2+i);return n}diff_commonSuffix(e,t){if(!e||!t||e.charAt(e.length-1)!==t.charAt(t.length-1))return 0;let i=0,r=V(e.length,t.length),n=r,o=0;for(;i<n;)e.substring(e.length-n,e.length-o)===t.substring(t.length-n,t.length-o)?(i=n,o=i):r=n,n=Math.floor((r-i)/2+i);return n}diff_cleanupSemantic(e){let t=!1,i=[],r=0,n=null,o=0,a=0,l=0,c=0,u=0;for(;o<e.length;)e[o][0]===0?(i[r++]=o,a=c,l=u,c=0,u=0,n=e[o][1]):(e[o][0]===1?c+=e[o][1].length:u+=e[o][1].length,n&&n.length<=j(a,l)&&n.length<=j(c,u)&&(e.splice(i[r-1],0,[-1,n]),e[i[r-1]+1][0]=1,r--,r--,o=r>0?i[r-1]:-1,a=0,l=0,c=0,u=0,n=null,t=!0)),o++;for(t&&this.diff_cleanupMerge(e),this.diff_cleanupSemanticLossless(e),o=1;o<e.length;){if(e[o-1][0]===-1&&e[o][0]===1){let p=e[o-1][1],d=e[o][1],F=this.diff_commonOverlap_(p,d),b=this.diff_commonOverlap_(d,p);F>=b?(F>=p.length/2||F>=d.length/2)&&(e.splice(o,0,[0,d.substring(0,F)]),e[o-1][1]=p.substring(0,p.length-F),e[o+1][1]=d.substring(F),o++):(b>=p.length/2||b>=d.length/2)&&(e.splice(o,0,[0,p.substring(0,b)]),e[o-1][0]=1,e[o-1][1]=d.substring(0,d.length-b),e[o+1][0]=-1,e[o+1][1]=p.substring(b),o++),o++}o++}}diff_cleanupSemanticLossless(e){let t=1;for(;t<e.length-1;){if(e[t-1][0]===0&&e[t+1][0]===0){let i=e[t-1][1],r=e[t][1],n=e[t+1][1],o=this.diff_commonSuffix(i,r);if(o){let p=r.substring(r.length-o);i=i.substring(0,i.length-o),r=p+r.substring(0,r.length-o),n=p+n}let a=i,l=r,c=n,u=this.diff_cleanupSemanticScore_(i,r)+this.diff_cleanupSemanticScore_(r,n);for(;r.charAt(0)===n.charAt(0);){i+=r.charAt(0),r=r.substring(1)+n.charAt(0),n=n.substring(1);let p=this.diff_cleanupSemanticScore_(i,r)+this.diff_cleanupSemanticScore_(r,n);p>=u&&(u=p,a=i,l=r,c=n)}e[t-1][1]!==a&&(a?e[t-1][1]=a:(e.splice(t-1,1),t--),e[t][1]=l,c?e[t+1][1]=c:(e.splice(t+1,1),t--))}t++}}diff_cleanupEfficiency(e){let t=!1,i=[],r=0,n=null,o=0,a=!1,l=!1,c=!1,u=!1;for(;o<e.length;)e[o][0]===0?(e[o][1].length<this.diffEditCost&&(c||u)?(i[r++]=o,a=c,l=u,n=e[o][1]):(r=0,n=null),c=u=!1):(e[o][0]===-1?u=!0:c=!0,n&&(a&&l&&c&&u||n.length<this.diffEditCost/2&&Number(a)+Number(l)+Number(c)+Number(u)===3)&&(e.splice(i[r-1],0,[-1,n]),e[i[r-1]+1][0]=1,r--,n=null,a&&l?(c=u=!0,r=0):(r--,o=r>0?i[r-1]:-1,c=u=!1),t=!0)),o++;t&&this.diff_cleanupMerge(e)}diff_cleanupMerge(e){e.push([0,""]);let t=0,i=0,r=0,n="",o="",a;for(;t<e.length;)switch(e[t][0]){case 1:r++,o+=e[t][1],t++;break;case-1:i++,n+=e[t][1],t++;break;case 0:i+r>1?(i!==0&&r!==0&&(a=this.diff_commonPrefix(o,n),a!==0&&(t-i-r>0&&e[t-i-r-1][0]===0?e[t-i-r-1][1]+=o.substring(0,a):(e.splice(0,0,[0,o.substring(0,a)]),t++),o=o.substring(a),n=n.substring(a)),a=this.diff_commonSuffix(o,n),a!==0&&(e[t][1]=o.substring(o.length-a)+e[t][1],o=o.substring(0,o.length-a),n=n.substring(0,n.length-a))),t-=i+r,e.splice(t,i+r),n.length&&(e.splice(t,0,[-1,n]),t++),o.length&&(e.splice(t,0,[1,o]),t++),t++):t!==0&&e[t-1][0]===0?(e[t-1][1]+=e[t][1],e.splice(t,1)):t++,r=0,i=0,n="",o="";break}e[e.length-1][1]===""&&e.pop();let l=!1;for(t=1;t<e.length-1;)e[t-1][0]===0&&e[t+1][0]===0&&(e[t][1].substring(e[t][1].length-e[t-1][1].length)===e[t-1][1]?(e[t][1]=e[t-1][1]+e[t][1].substring(0,e[t][1].length-e[t-1][1].length),e[t+1][1]=e[t-1][1]+e[t+1][1],e.splice(t-1,1),l=!0):e[t][1].substring(0,e[t+1][1].length)===e[t+1][1]&&(e[t-1][1]+=e[t+1][1],e[t][1]=e[t][1].substring(e[t+1][1].length)+e[t+1][1],e.splice(t+1,1),l=!0)),t++;l&&this.diff_cleanupMerge(e)}diff_xIndex(e,t){let i=0,r=0,n=0,o=0,a;for(a=0;a<e.length&&(e[a][0]!==1&&(i+=e[a][1].length),e[a][0]!==-1&&(r+=e[a][1].length),!(i>t));a++)n=i,o=r;return e.length!==a&&e[a][0]===-1?o:o+(t-n)}diff_prettyHtml(e){let t=[],i=/&/g,r=/</g,n=/>/g,o=/\n/g;for(let a=0;a<e.length;a++){let l=e[a][0],u=e[a][1].replace(i,"&amp;").replace(r,"&lt;").replace(n,"&gt;").replace(o,"&para;<br>");switch(l){case 1:t[a]='<ins style="background:#e6ffe6;">'+u+"</ins>";break;case-1:t[a]='<del style="background:#ffe6e6;">'+u+"</del>";break;case 0:t[a]="<span>"+u+"</span>";break}}return t.join("")}diff_text1(e){let t=[];for(let i=0;i<e.length;i++)e[i][0]!==1&&(t[i]=e[i][1]);return t.join("")}diff_text2(e){let t=[];for(let i=0;i<e.length;i++)e[i][0]!==-1&&(t[i]=e[i][1]);return t.join("")}diff_levenshtein(e){let t=0,i=0,r=0;for(let n=0;n<e.length;n++){let o=e[n][0],a=e[n][1];switch(o){case 1:i+=a.length;break;case-1:r+=a.length;break;case 0:t+=j(i,r),i=0,r=0;break}}return t+=j(i,r),t}diff_toDelta(e){let t=[];for(let i=0;i<e.length;i++)switch(e[i][0]){case 1:t[i]="+"+encodeURI(e[i][1]);break;case-1:t[i]="-"+e[i][1].length;break;case 0:t[i]="="+e[i][1].length;break}return t.join(" ").replace(/%20/g," ")}diff_fromDelta(e,t){let i=[],r=0,n=0,o=t.split(/\t/g);for(let a=0;a<o.length;a++){let l=o[a].substring(1);switch(o[a].charAt(0)){case"+":try{i[r++]=[1,decodeURI(l)]}catch{throw new Error("Illegal escape in diff_fromDelta: "+l)}break;case"-":case"=":let c=parseInt(l,10);if(isNaN(c)||c<0)throw new Error("Invalid number in diff_fromDelta: "+l);let u=e.substring(n,n+=c);o[a].charAt(0)==="="?i[r++]=[0,u]:i[r++]=[-1,u];break;default:if(o[a])throw new Error("Invalid diff operation in diff_fromDelta: "+o[a])}}if(n!==e.length)throw new Error("Delta length ("+n+") does not equal source text length ("+e.length+")");return i}match_main(e,t,i){if(e==null||t==null||i==null)throw new Error("Null input. (match_main)");return i=j(0,V(i,e.length)),e===t?0:e.length?e.substring(i,i+t.length)===t?i:this.match_bitap_(e,t,i):-1}patch_make(e,t,i){let r,n;if(typeof e=="string"&&typeof t=="string"&&typeof i>"u")r=e,n=this.diff_main(r,t,!0),n.length>2&&(this.diff_cleanupSemantic(n),this.diff_cleanupEfficiency(n));else if(e&&typeof e=="object"&&typeof t>"u"&&typeof i>"u")n=e,r=this.diff_text1(n);else if(typeof e=="string"&&t&&typeof t=="object"&&typeof i>"u")r=e,n=t;else if(typeof e=="string"&&typeof t=="string"&&i&&typeof i=="object")r=e,n=i;else throw new Error("Unknown call format to patch_make");if(n.length===0)return[];let o=[],a=new q,l=0,c=0,u=0,p=r,d=r;for(let F=0;F<n.length;F++){let b=n[F][0],y=n[F][1];switch(!l&&b!==0&&(a.start1=c,a.start2=u),b){case 1:a.diffs[l++]=n[F],a.length2+=y.length,d=d.substring(0,u)+y+d.substring(u);break;case-1:a.length1+=y.length,a.diffs[l++]=n[F],d=d.substring(0,u)+d.substring(u+y.length);break;case 0:y.length<=2*this.patchMargin&&l&&n.length!==F+1?(a.diffs[l++]=n[F],a.length1+=y.length,a.length2+=y.length):y.length>=2*this.patchMargin&&l&&(this.patch_addContext_(a,p),o.push(a),a=new q,l=0,p=d,c=u);break}b!==1&&(c+=y.length),b!==-1&&(u+=y.length)}return l&&(this.patch_addContext_(a,p),o.push(a)),o}patch_deepCopy(e){let t=[];for(let i=0;i<e.length;i++){let r=e[i],n=new q;for(let o=0;o<r.diffs.length;o++)n.diffs[o]=[r.diffs[o][0],r.diffs[o][1]];n.start1=r.start1,n.start2=r.start2,n.length1=r.length1,n.length2=r.length2,t[i]=n}return t}patch_apply(e,t){if(e.length===0)return[t,[]];e=this.patch_deepCopy(e);let i=this.patch_addPadding(e);t=i+t+i,this.patch_splitMax(e);let r=0,n=[];for(let o=0;o<e.length;o++){let a=e[o].start2+r,l=this.diff_text1(e[o].diffs),c,u=-1;if(l.length>this.matchMaxBits?(c=this.match_main(t,l.substring(0,this.matchMaxBits),a),c!==-1&&(u=this.match_main(t,l.substring(l.length-this.matchMaxBits),a+l.length-this.matchMaxBits),(u===-1||c>=u)&&(c=-1))):c=this.match_main(t,l,a),c===-1)n[o]=!1,r-=e[o].length2-e[o].length1;else{n[o]=!0,r=c-a;let p;if(u===-1?p=t.substring(c,c+l.length):p=t.substring(c,u+this.matchMaxBits),l===p)t=t.substring(0,c)+this.diff_text2(e[o].diffs)+t.substring(c+l.length);else{let d=this.diff_main(l,p,!1);if(l.length>this.matchMaxBits&&this.diff_levenshtein(d)/l.length>this.patchDeleteThreshold)n[o]=!1;else{this.diff_cleanupSemanticLossless(d);let F=0,b=0;for(let y=0;y<e[o].diffs.length;y++){let g=e[o].diffs[y];g[0]!==0&&(b=this.diff_xIndex(d,F)),g[0]===1?t=t.substring(0,c+b)+g[1]+t.substring(c+b):g[0]===-1&&(t=t.substring(0,c+b)+t.substring(c+this.diff_xIndex(d,F+g[1].length))),g[0]!==-1&&(F+=g[1].length)}}}}}return t=t.substring(i.length,t.length-i.length),[t,n]}patch_addPadding(e){let t=this.patchMargin,i="";for(let o=1;o<=t;o++)i+=String.fromCharCode(o);for(let o=0;o<e.length;o++)e[o].start1+=t,e[o].start2+=t;let r=e[0],n=r.diffs;if(n.length===0||n[0][0]!==0)n.unshift([0,i]),r.start1-=t,r.start2-=t,r.length1+=t,r.length2+=t;else if(t>n[0][1].length){let o=t-n[0][1].length;n[0][1]=i.substring(n[0][1].length)+n[0][1],r.start1-=o,r.start2-=o,r.length1+=o,r.length2+=o}if(r=e[e.length-1],n=r.diffs,n.length===0||n[n.length-1][0]!==0)n.push([0,i]),r.length1+=t,r.length2+=t;else if(t>n[n.length-1][1].length){let o=t-n[n.length-1][1].length;n[n.length-1][1]+=i.substring(0,o),r.length1+=o,r.length2+=o}return i}patch_splitMax(e){let t=this.matchMaxBits;for(let i=0;i<e.length;i++){if(e[i].length1<=t)continue;let r=e[i];e.splice(i--,1);let n=r.start1,o=r.start2,a="";for(;r.diffs.length!==0;){let l=new q,c=!0;for(l.start1=n-a.length,l.start2=o-a.length,a!==""&&(l.length1=l.length2=a.length,l.diffs.push([0,a]));r.diffs.length!==0&&l.length1<t-this.patchMargin;){let p=r.diffs[0][0],d=r.diffs[0][1];p===1?(l.length2+=d.length,o+=d.length,l.diffs.push(r.diffs.shift()),c=!1):p===-1&&l.diffs.length===1&&l.diffs[0][0]===0&&d.length>2*t?(l.length1+=d.length,n+=d.length,c=!1,l.diffs.push([p,d]),r.diffs.shift()):(d=d.substring(0,t-l.length1-this.patchMargin),l.length1+=d.length,n+=d.length,p===0?(l.length2+=d.length,o+=d.length):c=!1,l.diffs.push([p,d]),d===r.diffs[0][1]?r.diffs.shift():r.diffs[0][1]=r.diffs[0][1].substring(d.length))}a=this.diff_text2(l.diffs),a=a.substring(a.length-this.patchMargin);let u=this.diff_text1(r.diffs).substring(0,this.patchMargin);u!==""&&(l.length1+=u.length,l.length2+=u.length,l.diffs.length!==0&&l.diffs[l.diffs.length-1][0]===0?l.diffs[l.diffs.length-1][1]+=u:l.diffs.push([0,u])),c||e.splice(++i,0,l)}}}patch_toText(e){let t=[];for(let i=0;i<e.length;i++)t[i]=e[i];return t.join("")}patch_fromText(e){let t=[];if(!e)return t;let i=e.split(`
4
- `),r=0,n=/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;for(;r<i.length;){let o=i[r].match(n);if(!o)throw new Error("Invalid patch string: "+i[r]);let a=new q;t.push(a),a.start1=parseInt(o[1],10),o[2]===""?(a.start1--,a.length1=1):o[2]==="0"?a.length1=0:(a.start1--,a.length1=parseInt(o[2],10)),a.start2=parseInt(o[3],10),o[4]===""?(a.start2--,a.length2=1):o[4]==="0"?a.length2=0:(a.start2--,a.length2=parseInt(o[4],10)),r++;let l,c,u;for(;r<i.length;){l=i[r].charAt(0),u=i[r].substring(1);try{c=decodeURI(u)}catch{throw new Error("Illegal escape in patch_fromText: "+u)}if(l==="-")a.diffs.push([-1,c]);else if(l==="+")a.diffs.push([1,c]);else if(l===" ")a.diffs.push([0,c]);else{if(l==="@")break;if(l!=="")throw new Error('Invalid patch mode "'+l+'" in: '+c)}r++}}return t}diff_compute_(e,t,i,r){let n;if(!e)return[[1,t]];if(!t)return[[-1,e]];let o=e.length>t.length?e:t,a=e.length>t.length?t:e,l=o.indexOf(a);if(l!==-1)return n=[[1,o.substring(0,l)],[0,a],[1,o.substring(l+a.length)]],e.length>t.length&&(n[0][0]=-1,n[2][0]=-1),n;if(a.length===1)return[[-1,e],[1,t]];let c=this.diff_halfMatch_(e,t);if(c){let u=c[0],p=c[1],d=c[2],F=c[3],b=c[4],y=this.diff_main(u,d,i,r),g=this.diff_main(p,F,i,r);return y.concat([[0,b]],g)}return i&&e.length>100&&t.length>100?this.diff_lineMode_(e,t,r):this.diff_bisect_(e,t,r)}diff_lineMode_(e,t,i){let r=this.diff_linesToChars_(e,t);e=r.chars1,t=r.chars2;let n=r.lineArray,o=this.diff_main(e,t,!1,i);this.diff_charsToLines_(o,n),this.diff_cleanupSemantic(o),o.push([0,""]);let a=0,l=0,c=0,u="",p="";for(;a<o.length;){switch(o[a][0]){case 1:c++,p+=o[a][1];break;case-1:l++,u+=o[a][1];break;case 0:if(l>=1&&c>=1){o.splice(a-l-c,l+c),a=a-l-c;let d=this.diff_main(u,p,!1,i);for(let F=d.length-1;F>=0;F--)o.splice(a,0,d[F]);a=a+d.length}c=0,l=0,u="",p="";break}a++}return o.pop(),o}diff_bisect_(e,t,i){let r=e.length,n=t.length,o=Math.ceil((r+n)/2),a=o,l=2*o,c=new Array(l),u=new Array(l);for(let h=0;h<l;h++)c[h]=-1,u[h]=-1;c[a+1]=0,u[a+1]=0;let p=r-n,d=p%2!==0,F=0,b=0,y=0,g=0;for(let h=0;h<o&&!(Date.now()>i);h++){for(let f=-h+F;f<=h-b;f+=2){let w=a+f,m;f===-h||f!==h&&c[w-1]<c[w+1]?m=c[w+1]:m=c[w-1]+1;let v=m-f;for(;m<r&&v<n&&e.charAt(m)===t.charAt(v);)m++,v++;if(c[w]=m,m>r)b+=2;else if(v>n)F+=2;else if(d){let E=a+p-f;if(E>=0&&E<l&&u[E]!==-1){let S=r-u[E];if(m>=S)return this.diff_bisectSplit_(e,t,m,v,i)}}}for(let f=-h+y;f<=h-g;f+=2){let w=a+f,m;f===-h||f!==h&&u[w-1]<u[w+1]?m=u[w+1]:m=u[w-1]+1;let v=m-f;for(;m<r&&v<n&&e.charAt(r-m-1)===t.charAt(n-v-1);)m++,v++;if(u[w]=m,m>r)g+=2;else if(v>n)y+=2;else if(!d){let E=a+p-f;if(E>=0&&E<l&&c[E]!==-1){let S=c[E],_=a+S-E;if(m=r-m,S>=m)return this.diff_bisectSplit_(e,t,S,_,i)}}}}return[[-1,e],[1,t]]}diff_bisectSplit_(e,t,i,r,n){let o=e.substring(0,i),a=t.substring(0,r),l=e.substring(i),c=t.substring(r),u=this.diff_main(o,a,!1,n),p=this.diff_main(l,c,!1,n);return u.concat(p)}diff_linesToChars_(e,t){let i=[],r={};i[0]="";let n=this.diff_linesToCharsMunge_(e,i,r,4e4),o=this.diff_linesToCharsMunge_(t,i,r,65535);return{chars1:n,chars2:o,lineArray:i}}diff_linesToCharsMunge_(e,t,i,r){let n="",o=0,a=-1,l=t.length;for(;a<e.length-1;){a=e.indexOf(`
5
- `,o),a===-1&&(a=e.length-1);let c=e.substring(o,a+1);(i.hasOwnProperty?i.hasOwnProperty(c):i[c]!==void 0)?n+=String.fromCharCode(i[c]):(l===r&&(c=e.substring(o),a=e.length),n+=String.fromCharCode(l),i[c]=l,t[l++]=c),o=a+1}return n}diff_charsToLines_(e,t){for(let i=0;i<e.length;i++){let r=e[i][1],n=[];for(let o=0;o<r.length;o++)n[o]=t[r.charCodeAt(o)];e[i][1]=n.join("")}}diff_commonOverlap_(e,t){let i=e.length,r=t.length;if(i===0||r===0)return 0;i>r?e=e.substring(i-r):i<r&&(t=t.substring(0,i));let n=V(i,r);if(e===t)return n;let o=0,a=1;for(;;){let l=e.substring(n-a),c=t.indexOf(l);if(c===-1)return o;a+=c,(c===0||e.substring(n-a)===t.substring(0,a))&&(o=a,a++)}}diff_halfMatch_(e,t){if(this.diffTimeout<=0)return null;let i=e.length>t.length?e:t,r=e.length>t.length?t:e;if(i.length<4||r.length*2<i.length)return null;let n=this.diff_halfMatchI_(i,r,Math.ceil(i.length/4)),o=this.diff_halfMatchI_(i,r,Math.ceil(i.length/2)),a;if(!n&&!o)return null;o?n?a=n[4].length>o[4].length?n:o:a=o:a=n;let l,c,u,p,d=a[4];return e.length>t.length?(l=a[0],c=a[1],u=a[2],p=a[3]):(u=a[0],p=a[1],l=a[2],c=a[3]),[l,c,u,p,d]}diff_halfMatchI_(e,t,i){let r=e.substring(i,i+Math.floor(e.length/4)),n="",o,a,l,c,u=t.indexOf(r,0);for(;u!==-1;){let p=this.diff_commonPrefix(e.substring(i),t.substring(u)),d=this.diff_commonSuffix(e.substring(0,i),t.substring(0,u));n.length<d+p&&(n=t.substring(u-d,u)+t.substring(u,u+p),o=e.substring(0,i-d),a=e.substring(i+p),l=t.substring(0,u-d),c=t.substring(u+p)),u=t.indexOf(r,u+1)}return n.length*2>=e.length?[o,a,l,c,n]:null}diff_cleanupSemanticScore_(e,t){if(!e||!t)return 6;let i=e.charAt(e.length-1),r=t.charAt(0),n=i.match(kt),o=r.match(kt),a=n&&i.match(Mt),l=o&&r.match(Mt),c=a&&i.match(Bt),u=l&&r.match(Bt),p=c&&e.match(Ii),d=u&&t.match(Li);return p||d?5:c||u?4:n&&!a&&l?3:a||l?2:n||o?1:0}match_bitap_(e,t,i){if(t.length>this.matchMaxBits)throw new Error("Pattern too long for this browser");let r=this.match_alphabet_(t),n=this.matchThreshold,o=e.indexOf(t,i);o!==-1&&(n=V(this.match_bitapScore_(0,o,t,i),n),o=e.lastIndexOf(t,i+t.length),o!==-1&&(n=V(this.match_bitapScore_(0,o,t,i),n)));let a=1<<t.length-1;o=-1;let l,c,u=t.length+e.length,p;for(let d=0;d<t.length;d++){for(l=0,c=u;l<c;)this.match_bitapScore_(d,i+c,t,i)<=n?l=c:u=c,c=Math.floor((u-l)/2+l);u=c;let F=j(1,i-c+1),b=V(i+c,e.length)+t.length,y=Array(b+2);y[b+1]=(1<<d)-1;for(let g=b;g>=F;g--){let h=r[e.charAt(g-1)];if(d===0?y[g]=(y[g+1]<<1|1)&h:y[g]=(y[g+1]<<1|1)&h|((p[g+1]|p[g])<<1|1)|p[g+1],y[g]&a){let f=this.match_bitapScore_(d,g-1,t,i);if(f<=n)if(n=f,o=g-1,o>i)F=j(1,2*i-o);else break}}if(this.match_bitapScore_(d+1,i,t,i)>n)break;p=y}return o}match_bitapScore_(e,t,i,r){let n=e/i.length,o=Math.abs(r-t);return this.matchDistance?n+o/this.matchDistance:o?1:n}match_alphabet_(e){let t={};for(let i=0;i<e.length;i++)t[e.charAt(i)]=0;for(let i=0;i<e.length;i++)t[e.charAt(i)]|=1<<e.length-i-1;return t}patch_addContext_(e,t){if(t.length===0)return;if(e.start2==null)throw Error("patch not initialized");let i=t.substring(e.start2,e.start2+e.length1),r=0;for(;t.indexOf(i)!==t.lastIndexOf(i)&&i.length<this.matchMaxBits-this.patchMargin-this.patchMargin;)r+=this.patchMargin,i=t.substring(e.start2-r,e.start2+e.length1+r);r+=this.patchMargin;let n=t.substring(e.start2-r,e.start2);n&&e.diffs.unshift([0,n]);let o=t.substring(e.start2+e.length1,e.start2+e.length1+r);o&&e.diffs.push([0,o]),e.start1-=n.length,e.start2-=n.length,e.length1+=n.length+o.length,e.length2+=n.length+o.length}},q=class{constructor(){this.diffs=[];this.start1=0;this.start2=0;this.length1=0;this.length2=0}toString(){let e,t;this.length1===0?e=this.start1+",0":this.length1===1?e=this.start1+1:e=this.start1+1+","+this.length1,this.length2===0?t=this.start2+",0":this.length2===1?t=this.start2+1:t=this.start2+1+","+this.length2;let i=["@@ -"+e+" +"+t+` @@
2
+ var wi=Object.create;var gt=Object.defineProperty;var vi=Object.getOwnPropertyDescriptor;var Si=Object.getOwnPropertyNames;var Ei=Object.getPrototypeOf,Di=Object.prototype.hasOwnProperty;var Pi=(s,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Si(e))!Di.call(s,r)&&r!==t&&gt(s,r,{get:()=>e[r],enumerable:!(i=vi(e,r))||i.enumerable});return s};var W=(s,e,t)=>(t=s!=null?wi(Ei(s)):{},Pi(e||!s||!s.__esModule?gt(t,"default",{value:s,enumerable:!0}):t,s));var dt=W(require("node:crypto")),E=W(require("node:fs")),N=W(require("node:os")),D=W(require("node:path")),Re=W(require("node:url"));global.nodeCrypto=dt.default;var he=null;try{let s=D.default.join(__dirname,"btime",process.platform+"-"+process.arch);he=require(D.default.join(s,"btime.node")).btime}catch{}function mt(){return he!==null}function yt(s,e){if(!he)return;let t=Buffer.alloc(Buffer.byteLength(s,"utf-8")+1);t.write(s,0,t.length-1,"utf-8"),t[t.length-1]=0,he(t,e)}var Ne=["image","audio","video","pdf","unsupported"],K=["image","audio","pdf","video"],ke=["app","appearance","appearance-data","hotkey","core-plugin","core-plugin-data","community-plugin","community-plugin-data"],Me=["app","appearance","appearance-data","hotkey","core-plugin","core-plugin-data"];var Ft="obsidian-headless",Y=N.default.platform()==="linux"?D.default.join(process.env.XDG_CONFIG_HOME||D.default.join(N.default.homedir(),".config"),Ft):D.default.join(N.default.homedir(),"."+Ft),bt="OBSIDIAN_AUTH_TOKEN",Be=D.default.join(Y,"auth_token");function J(){if(process.env[bt])return process.env[bt];try{return E.default.readFileSync(Be,"utf8")}catch{return null}}function wt(s){E.default.existsSync(Y)||E.default.mkdirSync(Y,{recursive:!0,mode:448}),E.default.writeFileSync(Be,s,{mode:384})}function Ue(){E.default.rmSync(Be,{force:!0})}function Z(s){return D.default.join(Y,"sync",s)}function vt(s){return D.default.join(Z(s),"state.db")}function St(s){return D.default.join(Z(s),"sync.log")}function Et(s){return D.default.join(Z(s),"config.json")}function Ve(s){let e=Z(s);return E.default.existsSync(e)||E.default.mkdirSync(e,{recursive:!0,mode:448}),e}function je(s){let e=Et(s);if(!E.default.existsSync(e))return null;try{let t=E.default.readFileSync(e,"utf-8");return JSON.parse(t)}catch{return null}}function qe(s,e){Ve(s);let t=Et(s);E.default.writeFileSync(t,JSON.stringify(e,null,2),{mode:384})}function Dt(s,e){return D.default.join(s,e,".sync.lock")}function Pt(s){let e=Z(s);E.default.existsSync(e)&&E.default.rmSync(e,{recursive:!0,force:!0})}function We(){let s=D.default.join(Y,"sync");if(!E.default.existsSync(s))return[];let e=E.default.readdirSync(s,{withFileTypes:!0}),t=[];for(let i of e)if(i.isDirectory()){let r=D.default.join(s,i.name,"config.json");E.default.existsSync(r)&&t.push(i.name)}return t}function z(s){let e=D.default.resolve(s),t=We();for(let i of t){let r=je(i);if(r&&D.default.resolve(r.vaultPath)===e)return r}return null}function At(s){let e=s.split(",").map(t=>t.trim().toLowerCase());for(let t of e)if(!Ne.includes(t))throw new Error(`Invalid file type: "${t}". Valid values: ${Ne.join(", ")}`);return e}function _t(s){let e=s.split(",").map(t=>t.trim().toLowerCase());for(let t of e)if(!ke.includes(t))throw new Error(`Invalid config: "${t}". Valid values: ${ke.join(", ")}`);return e}function Ke(s){if(s){if(!s.startsWith(".")||s.includes("/")||s.includes("\\"))throw new Error(`Invalid config directory: "${s}". Must be a dotfolder name (e.g. .obsidian).`);return s}}function He(){let s=N.default.hostname(),e=N.default.platform();return`${s} (${e==="darwin"?"macOS":e==="win32"?"Windows":e==="linux"?"Linux":e})`}function Tt(s){let e=D.default.dirname(s);E.default.existsSync(e)||E.default.mkdirSync(e,{recursive:!0});let t=E.default.createWriteStream(s,{flags:"a"}),i=console.log,r=console.warn,n=console.error,o=console.debug;function a(...l){let u=new Date().toISOString(),c=l.map(p=>typeof p=="object"?JSON.stringify(p):String(p)).join(" ");t.write(`[${u}] ${c}
3
+ `)}return console.log=(...l)=>{i(...l),a(...l)},console.warn=(...l)=>{r(...l),a(...l)},console.error=(...l)=>{n(...l),a(...l)},console.debug=(...l)=>{o(...l),a(...l)},()=>{console.log=i,console.warn=r,console.error=n,console.debug=o,t.end()}}var ee=()=>typeof activeWindow<"u"?activeWindow:global;function xt(s,e=0,t=!1){let i=null,r=null,n=null,o=0,a=0,l=ee(),u=function(){let d=r,F=n;return r=null,n=null,s.apply(d,F)},c=function(){if(o){let d=Date.now();if(d<o){l=ee(),i=l.setTimeout(c,o-d),o=0;return}}a=0,i=null,u()},p=function(...d){r=this,n=d;let F=Date.now();return i?t?o=a=F+e:l!==ee()&&a<=F&&(l.clearTimeout(i),l=ee(),i=l.setTimeout(c,0)):(l=ee(),a=F+e,i=l.setTimeout(c,e)),p};return p.cancel=function(){return i&&(l.clearTimeout(i),i=null),p},p.run=function(){if(i)return l.clearTimeout(i),i=null,u()},p}var Ai=/\u00A0|\u202F/g;function Ge(s){return s.replace(Ai," ")}function C(s){let e=s.lastIndexOf("/");return e===-1?s:s.slice(e+1)}function k(s){let e=s.lastIndexOf("/");return e===-1?"":s.slice(0,e)}function $e(s){for(;s;){if(C(s).startsWith("."))return!0;s=k(s)}return!1}function It(s){let e=C(s),t=e.lastIndexOf(".");return t===-1||t===e.length-1||t===0?e:e.substr(0,t)}function Lt(s){let e=s.lastIndexOf(".");return e===-1||e===s.length-1||e===0?s:s.substr(0,e)}function T(s){let e=s.lastIndexOf(".");return e===-1||e===s.length-1||e===0?"":s.substr(e+1).toLowerCase()}function H(s){return Ge(G(s)).normalize("NFC")}function G(s){return s=s.replace(/([\\/])+/g,"/").replace(/(^\/+|\/+$)/g,""),s===""&&(s="/"),s}function te(s){return s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength)}function Qe(s){return Buffer.from(s)}var _i=5;function Ti(s,e){if(e.isFile())return{type:"file",realpath:s,ctime:Math.round(e.birthtimeMs),mtime:Math.round(e.mtimeMs),size:e.size};if(e.isDirectory())return{type:"folder",realpath:s}}function Xe(s){return{ctime:Math.round(s.birthtimeMs),mtime:Math.round(s.mtimeMs),size:s.size}}var Ct=typeof process<"u"?process:null,Ot=Ct?Ct.platform:"",Rt=Ot==="darwin",Nt=Ot==="win32",pe=Rt||Nt,ge=class{constructor(e,t,i,r,n,o,a){this.thingsHappening=xt(this.kill.bind(this),60*1e3,!0);this.resourcePathPrefix=o,this.basePath=a,this.fs=e,this.fsPromises=e.promises,this.path=t,this.url=i,this.trash=r,this.files={},this.promise=Promise.resolve(),this.watchers={},this.handler=null,this.btime=n,this.insensitive=Rt||Nt;try{this.testInsensitive()}catch(l){console.error(l)}}testInsensitive(){let{fs:e,path:t,basePath:i}=this,r=t.join(i,".OBSIDIANTEST"),n=t.join(i,".OBSIDIANTEST".toLowerCase());e.existsSync(r)&&e.unlinkSync(r),e.writeFileSync(r,"","utf8"),this.insensitive=e.existsSync(n),e.unlinkSync(r)}getName(){return this.path.basename(this.basePath)}getBasePath(){return this.basePath}async listAll(){this.files={},this.files["/"]={type:"folder",realpath:"/"},await this.listRecursive("")}async listRecursive(e){let t=this.getFullRealPath(e),i=await this.fsPromises.readdir(t);this.thingsHappening();let r=[];for(let n of i)r.push(this.listRecursiveChild(e,n));await Promise.all(r)}async listRecursiveChild(e,t){let i=G(e===""?t:e+"/"+t),r=H(i);if(this.trigger("raw",r),$e(r))return await this.reconcileDeletion(i,r);try{await this.reconcileFileInternal(i,r)}catch(n){if(n.code==="ENOENT")await this.reconcileDeletion(i,r,!0);else throw n}}mkdir(e){return this.queue(async()=>{let t=this.getFullPath(e);await this.fsPromises.mkdir(t,{recursive:!0}),await this.reconcileInternalFile(e)})}trashSystem(e){return this.queue(async()=>{let t=this.getFullPath(e);return this.trash(t)?(await this.reconcileInternalFile(e),!0):!1})}trashLocal(e){return this.queue(async()=>{let t=this.getFullPath(e),i=this.getFullPath(".trash");await this.fsPromises.mkdir(i,{recursive:!0});let r=this.path.extname(t),n=this.path.basename(t,r),o=this.path.join(i,n+r),a=1;for(;await this._exists(o);)a++,o=this.path.join(i,n+" "+a+r);await this.fsPromises.rename(t,o),await this.reconcileInternalFile(e)})}rmdir(e,t){return this.queue(async()=>{let i=this.getFullPath(e);await this.fsPromises.rm(i,{maxRetries:_i,recursive:t}),await this.reconcileInternalFile(e)})}read(e){return this.queue(async()=>{let t=this.getFullPath(e);try{return this.fsPromises.readFile(t,"utf8")}catch(i){throw this.queue(()=>this.reconcileInternalFile(e)),i}})}readBinary(e){return this.queue(async()=>{let t=this.getFullPath(e);try{let i=await this.fsPromises.readFile(t);return te(i)}catch(i){throw this.queue(()=>this.reconcileInternalFile(e)),i}})}write(e,t,i){return this.queue(async()=>{let r=this.getFullPath(e);try{await this.fsPromises.writeFile(r,t,"utf8"),await this.applyWriteOptions(r,i)}finally{await this.reconcileInternalFile(e)}})}writeBinary(e,t,i){return this.queue(async()=>{let r=this.getFullPath(e),n=Qe(t);try{await this.fsPromises.writeFile(r,n),await this.applyWriteOptions(r,i)}finally{await this.reconcileInternalFile(e)}})}append(e,t,i){return this.queue(async()=>{let r=this.getFullPath(e);try{await this.fsPromises.appendFile(r,t,"utf8"),await this.applyWriteOptions(r,i)}finally{await this.reconcileInternalFile(e)}})}appendBinary(e,t,i){return this.queue(async()=>{let r=this.getFullPath(e),n=Qe(t);try{await this.fsPromises.appendFile(r,n),await this.applyWriteOptions(r,i)}finally{await this.reconcileInternalFile(e)}})}process(e,t,i){return this.queue(async()=>{let r=this.getFullPath(e),n=await this.fsPromises.readFile(r,"utf8"),o=t(n);if(o===n)return n;try{await this.fsPromises.writeFile(r,o,"utf8"),await this.applyWriteOptions(r,i)}finally{await this.reconcileInternalFile(e)}return o})}async applyWriteOptions(e,t){if(!t)return;let{ctime:i,mtime:r,immediate:n}=t;i&&this.btime(e,i),r&&await this.fsPromises.utimes(e,r/1e3,r/1e3),n&&n()}getResourcePath(e){let t=this.getFullPath(e),i=0,r=this.files[e];r&&r.type==="file"&&(i=r.mtime),i||(i=Date.now());let n=this.url.pathToFileURL(t).href;return n.startsWith("file:///")?n=n.substring(8):n.startsWith("file://")&&(n="%5C%5C"+n.substring(7)),this.resourcePathPrefix+n+"?"+i}getFilePath(e){let t=this.getFullPath(e);return this.url.pathToFileURL(t).toString()}remove(e){return this.queue(async()=>{let t=this.getFullPath(e);await this.fsPromises.unlink(t),await this.reconcileInternalFile(e)})}update(e){return this.queue(async()=>{await this.reconcileInternalFile(e)})}async rename(e,t){e!==t&&await this.queue(async()=>{let i=this.getFullPath(e),r=this.getFullPath(t);if(await this._exists(r,!1)&&!(this.insensitive&&e.toLowerCase()===t.toLowerCase()))throw new Error("Destination file already exists!");let n=this.files[e],o=n?n.realpath:null;if(await this.fsPromises.rename(i,r),!n)return;delete this.files[e];let a=this.getRealPath(t);if(n.realpath=a,this.files[t]=n,this.trigger("renamed",t,e),n.type==="folder"&&this.watchers.hasOwnProperty(e)&&(this.stopWatchPath(e),await this.startWatchPath(t)),n.type==="folder"){for(let u in this.files)if(this.files.hasOwnProperty(u)&&u.startsWith(e+"/")){let c=u.slice(e.length),p=t+c,d=this.files[u];delete this.files[u];let F=d.realpath.slice(o.length);d.realpath=a+F,this.files[p]=d,this.trigger("renamed",p,u)}}})}async copyRecursive(e,t){let i=await this.fsPromises.stat(e);if(i.isFile()&&await this.fsPromises.copyFile(e,t,this.fs.constants.COPYFILE_EXCL),i.isDirectory()){await this.fsPromises.mkdir(t,{recursive:!0});let r=await this.fsPromises.readdir(e);for(let n of r){let o=this.path.join(e,n),a=this.path.join(t,n);await this.copyRecursive(o,a)}}}async copy(e,t){await this.queue(async()=>{let i=this.getFullPath(e),r=this.getFullPath(t);await this.copyRecursive(i,r),await this.reconcileInternalFile(t)})}async exists(e,t){return this.queue(()=>{let i=this.getFullPath(e);return this._exists(i,t)})}async _exists(e,t){try{await this.fsPromises.access(e)}catch{return!1}if(t&&this.insensitive){let i=this.path.dirname(e),r=this.path.basename(e);if((await this.fsPromises.readdir(i)).indexOf(r)===-1)return!1}return!0}async stat(e){return this.queue(async()=>{let t=this.getFullPath(e);try{let i=await this.fsPromises.stat(t);if(i.isFile())return{type:"file",...Xe(i)};if(i.isDirectory())return{type:"folder",...Xe(i)}}catch(i){if(i.code!=="ENOENT")throw i}return null})}async list(e){return this.queue(async()=>{let t=this.getFullPath(e),i=await this.fsPromises.readdir(t),r={folders:[],files:[]};for(let n of i){let o=G(e===""?n:e+"/"+n),a=H(o),l=await this.fsPromises.stat(this.getFullRealPath(o));l.isFile()&&r.files.push(a),l.isDirectory()&&r.folders.push(a)}return r})}async watch(e){return this.stopWatch(),this.handler=e,await this.startWatchPath("/"),this.queue(()=>this.listAll())}async watchHiddenRecursive(e){if(!pe)try{let t=this.getFullRealPath(e),i=await this.fsPromises.readdir(t);await this.startWatchPath(e);for(let r of i)try{let n=G(e===""?r:e+"/"+r),o=this.getFullRealPath(n);(await this.fsPromises.lstat(o)).isDirectory()&&await this.watchHiddenRecursive(n)}catch{}}catch{}}stopWatch(){for(let e in this.watchers)this.watchers.hasOwnProperty(e)&&this.stopWatchPath(e);this.handler=null}async startWatchPath(e){let t=this.getRealPath(e);if(this.watchers[e])return;let i=this.getFullPath(e),r=i;try{r=await this.fsPromises.realpath(i)}catch(o){o.code!=="ENOENT"&&console.error(o)}let n=this.fs.watch(i,{persistent:!1,encoding:"utf8",recursive:pe});n.on("change",(o,a)=>{let l=t==="/"?a:t+"/"+a;this.onFileChange(l)}),n.on("error",()=>{this.onFileChange(t)}),this.watchers[e]={watcher:n,resolvedPath:r}}stopWatchPath(e){let t=this.watchers[e];t&&(t.watcher.close(),delete this.watchers[e])}onFileChange(e){e&&(e=G(e),setTimeout(()=>{let t=H(e);this.queue(()=>this.reconcileFile(e,t,!1))},0))}async reconcileInternalFile(e){return this.reconcileFile(this.getRealPath(e),e)}async reconcileFile(e,t,i=!0){if(this.trigger("raw",t),$e(t))return await this.reconcileDeletion(e,t,i);let r=k(t);r&&r!=="/"&&(this.files[t]||await this.reconcileFile(k(e),r,i));try{let n=this.getFullRealPath(e);if(this.insensitive){let o=this.path.dirname(n),a=this.path.basename(t),l=await this.fsPromises.readdir(o);if(l=l.map(u=>Ge(u).normalize("NFC")),l.indexOf(a)===-1)return await this.reconcileDeletion(e,t,i)}await this.reconcileFileInternal(e,t)}catch(n){n.code==="ENOENT"?await this.reconcileDeletion(e,t,i):console.error(n)}}async reconcileFileInternal(e,t){let i=this.getFullRealPath(e),r=await this.fsPromises.lstat(i);r.isFile()?await this.reconcileFileCreation(e,t,r):r.isDirectory()?await this.reconcileFolderCreation(e,t):r.isSymbolicLink()&&await this.reconcileSymbolicLinkCreation(e,t)}async reconcileFileCreation(e,t,i){let r=Xe(i),n=this.files[t];if(n)if(n.realpath=e,n.type==="file"){(n.mtime!==Math.round(i.mtimeMs)||n.size!==i.size)&&(n.mtime=Math.round(i.mtimeMs),n.size=i.size,this.trigger("raw",t,t,r),this.trigger("modified",t,t,r));return}else this.removeFile(t);this.files[t]=Ti(e,i),this.trigger("file-created",t,t,r)}async reconcileFolderCreation(e,t){this.files.hasOwnProperty(t)?this.files[t].realpath=e:(this.files[t]={type:"folder",realpath:e},this.trigger("folder-created",t),pe||await this.startWatchPath(t),await this.listRecursive(e))}async reconcileSymbolicLinkCreation(e,t){let i=this.getFullRealPath(e),r;try{r=await this.fsPromises.realpath(i)}catch{return}let n=this.path.sep,o=this.watchers;if(o.hasOwnProperty(t))o[t].resolvedPath=r;else for(let l in o)if(o.hasOwnProperty(l)&&l!==t){let u=o[l].resolvedPath;if(r===u||u.startsWith(r+n)||r.startsWith(u+n))return}let a=await this.fsPromises.stat(i);a.isFile()?await this.reconcileFileCreation(e,t,a):a.isDirectory()&&(pe&&await this.startWatchPath(t),await this.reconcileFolderCreation(e,t))}async reconcileDeletion(e,t,i=!0){if(t==="/"){this.trigger("closed",t);return}this.stopWatchPath(t);let r=this.files[t];if(r){if(!i){setTimeout(()=>{this.queue(()=>this.reconcileFile(e,t))},100);return}if(r.type==="folder")for(let n in this.files)this.files.hasOwnProperty(n)&&n.startsWith(t+"/")&&this.removeFile(n);this.removeFile(t)}}trigger(e,t,i,r){this.handler&&this.handler(e,t,i,r)}getRealPath(e){let t=e;for(;t;){if(this.files.hasOwnProperty(t)){let i=e.substr(t.length);return this.files[t].realpath+i}t=k(t)}return e}getFullPath(e){let t=this.getRealPath(e);return this.getFullRealPath(t)}getFullRealPath(e){return this.path.join(this.basePath,e)}kill(){this.killLastAction&&(this.killLastAction(new Error("File system operation timed out.")),this.killLastAction=null)}queue(e){let t=()=>{let r=new Promise((n,o)=>this.killLastAction=o);return this.thingsHappening(),Promise.race([r,e()])},i=this.promise.then(t,t);return this.promise=i,i}removeFile(e){let t=this.files[e];delete this.files[e],t&&(t.type==="file"?this.trigger("file-removed",e):t.type==="folder"&&this.trigger("folder-removed",e))}static async readLocalFile(e){let t=require;if(t){let i=t("fs");return te(await i.promises.readFile(e))}return null}static async mkdir(e){let t=require;return t?await t("fs").promises.mkdir(e,{recursive:!0}):null}};var kt=W(require("better-sqlite3"));var xi=1,de=class{constructor(e){let t=D.default.dirname(e);E.default.existsSync(t)||E.default.mkdirSync(t,{recursive:!0}),this.db=new kt.default(e),this.db.pragma("journal_mode = WAL"),this.db.exec("CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT );"),this.db.exec("CREATE TABLE IF NOT EXISTS local_files (path TEXT PRIMARY KEY, data TEXT NOT NULL);"),this.db.exec("CREATE TABLE IF NOT EXISTS server_files (path TEXT PRIMARY KEY, data TEXT NOT NULL);"),this.db.exec("CREATE TABLE IF NOT EXISTS pending_files (uid INTEGER PRIMARY KEY, path TEXT, data TEXT NOT NULL)"),this.stmts={getMeta:this.db.prepare("SELECT value FROM meta WHERE key = ?"),setMeta:this.db.prepare("INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)"),getLocalFile:this.db.prepare("SELECT data FROM local_files WHERE path = ?"),setLocalFile:this.db.prepare("INSERT OR REPLACE INTO local_files (path, data) VALUES (?, ?)"),deleteLocalFile:this.db.prepare("DELETE FROM local_files WHERE path = ?"),getAllLocalFiles:this.db.prepare("SELECT path, data FROM local_files"),getServerFile:this.db.prepare("SELECT data FROM server_files WHERE path = ?"),setServerFile:this.db.prepare("INSERT OR REPLACE INTO server_files (path, data) VALUES (?, ?)"),deleteServerFile:this.db.prepare("DELETE FROM server_files WHERE path = ?"),getAllServerFiles:this.db.prepare("SELECT path, data FROM server_files"),addPendingFile:this.db.prepare("INSERT OR REPLACE INTO pending_files (uid, path, data) VALUES (?, ?, ?)"),deletePendingFile:this.db.prepare("DELETE FROM pending_files WHERE path = ?"),getPendingFiles:this.db.prepare("SELECT data FROM pending_files ORDER BY uid")},this.getMetaValue("schema_version")===null&&this.setMetaValue("schema_version",String(xi))}getMetaValue(e){let t=this.stmts.getMeta.get(e);return t?t.value:null}setMetaValue(e,t){this.stmts.setMeta.run(e,t)}getVersion(){let e=this.getMetaValue("version"),t=e?parseInt(e,10):0;return isNaN(t)&&(t=0),t}setVersion(e){this.setMetaValue("version",String(e))}isInitial(){return this.getMetaValue("initial")!=="false"}setInitial(e){this.setMetaValue("initial",e?"true":"false")}getLocalFile(e){let t=this.stmts.getLocalFile.get(e);if(!t)return null;try{return JSON.parse(t.data)}catch{return null}}setLocalFile(e){this.stmts.setLocalFile.run(e.path,JSON.stringify(e))}deleteLocalFile(e){this.stmts.deleteLocalFile.run(e)}getAllLocalFiles(){let e=this.stmts.getAllLocalFiles.all(),t={};for(let i of e)try{t[i.path]=JSON.parse(i.data)}catch{}return t}getServerFile(e){let t=this.stmts.getServerFile.get(e);if(!t)return null;try{return JSON.parse(t.data)}catch{return null}}setServerFile(e){this.stmts.setServerFile.run(e.path,JSON.stringify(e))}deleteServerFile(e){this.stmts.deleteServerFile.run(e)}getAllServerFiles(){let e=this.stmts.getAllServerFiles.all(),t={};for(let i of e)try{t[i.path]=JSON.parse(i.data)}catch{}return t}addPendingFile(e){this.stmts.addPendingFile.run(e.uid,e.path,JSON.stringify(e))}deletePendingFile(e){this.stmts.deletePendingFile.run(e)}getPendingFiles(){let e=this.stmts.getPendingFiles.all(),t=[];for(let i of e)try{t.push(JSON.parse(i.data))}catch{}return t}close(){this.db.open&&this.db.close()}};var Mt=/[^a-zA-Z0-9]/,Bt=/\s/,Ut=/[\r\n]/,Ii=/\n\r?\n$/,Li=/^\r?\n\r?\n/;function M(s,e){return s<e?s:e}function B(s,e){return s>e?s:e}var Ci=/\W/;function Oi(s,e){let t=s.length;for(let i=e;i<t;i+=1)if(Ci.test(s[i]))return i;return-1}function Ri(s,e){let t=0,i=-1;for(;i<s.length-1;)if(i=Oi(s,t),i!==-1){if(t!==i){let n=s.substring(t,i);e(n)}let r=s[i];e(r),t=i+1}else{let r=s.substring(t,s.length);e(r),i=s.length;break}}var me=class{constructor(){this.diffTimeout=1;this.diffEditCost=4;this.matchThreshold=.5;this.matchDistance=1e3;this.patchDeleteThreshold=.5;this.patchMargin=4;this.matchMaxBits=32}diff_main(e,t,i,r){typeof r>"u"&&(this.diffTimeout<=0?r=Number.MAX_VALUE:r=Date.now()+this.diffTimeout*1e3);let n=r;if(e==null||t==null)throw new Error("Null input. (diff_main)");if(e===t)return e?[[0,e]]:[];typeof i>"u"&&(i=!0);let o=i,a=this.diff_commonPrefix(e,t),l=e.substring(0,a);e=e.substring(a),t=t.substring(a),a=this.diff_commonSuffix(e,t);let u=e.substring(e.length-a);e=e.substring(0,e.length-a),t=t.substring(0,t.length-a);let c=this.diff_compute_(e,t,o,n);return l&&c.unshift([0,l]),u&&c.push([0,u]),this.diff_cleanupMerge(c),c}diff_lineMode(e,t){let{chars1:i,chars2:r,lineArray:n}=this.diff_linesToChars_(e,t),o=this.diff_main(i,r,!1);return this.diff_charsToLines_(o,n),o}diff_wordMode(e,t){let{chars1:i,chars2:r,lineArray:n}=this.diff_wordsToChars_(e,t),o=this.diff_main(i,r,!1);return this.diff_charsToLines_(o,n),o}diff_wordsToChars_(e,t){let i=[],r={};i[0]="";let n=l=>{let u="",c=i.length;return Ri(l,p=>{(r.hasOwnProperty?r.hasOwnProperty(p):r[p]!==void 0)?u+=String.fromCharCode(r[p]):(u+=String.fromCharCode(c),r[p]=c,i[c++]=p)}),u},o=n(e),a=n(t);return{chars1:o,chars2:a,lineArray:i}}diff_commonPrefix(e,t){if(!e||!t||e.charAt(0)!==t.charAt(0))return 0;let i=0,r=M(e.length,t.length),n=r,o=0;for(;i<n;)e.substring(o,n)===t.substring(o,n)?(i=n,o=i):r=n,n=Math.floor((r-i)/2+i);return n}diff_commonSuffix(e,t){if(!e||!t||e.charAt(e.length-1)!==t.charAt(t.length-1))return 0;let i=0,r=M(e.length,t.length),n=r,o=0;for(;i<n;)e.substring(e.length-n,e.length-o)===t.substring(t.length-n,t.length-o)?(i=n,o=i):r=n,n=Math.floor((r-i)/2+i);return n}diff_cleanupSemantic(e){let t=!1,i=[],r=0,n=null,o=0,a=0,l=0,u=0,c=0;for(;o<e.length;)e[o][0]===0?(i[r++]=o,a=u,l=c,u=0,c=0,n=e[o][1]):(e[o][0]===1?u+=e[o][1].length:c+=e[o][1].length,n&&n.length<=B(a,l)&&n.length<=B(u,c)&&(e.splice(i[r-1],0,[-1,n]),e[i[r-1]+1][0]=1,r--,r--,o=r>0?i[r-1]:-1,a=0,l=0,u=0,c=0,n=null,t=!0)),o++;for(t&&this.diff_cleanupMerge(e),this.diff_cleanupSemanticLossless(e),o=1;o<e.length;){if(e[o-1][0]===-1&&e[o][0]===1){let p=e[o-1][1],d=e[o][1],F=this.diff_commonOverlap_(p,d),b=this.diff_commonOverlap_(d,p);F>=b?(F>=p.length/2||F>=d.length/2)&&(e.splice(o,0,[0,d.substring(0,F)]),e[o-1][1]=p.substring(0,p.length-F),e[o+1][1]=d.substring(F),o++):(b>=p.length/2||b>=d.length/2)&&(e.splice(o,0,[0,p.substring(0,b)]),e[o-1][0]=1,e[o-1][1]=d.substring(0,d.length-b),e[o+1][0]=-1,e[o+1][1]=p.substring(b),o++),o++}o++}}diff_cleanupSemanticLossless(e){let t=1;for(;t<e.length-1;){if(e[t-1][0]===0&&e[t+1][0]===0){let i=e[t-1][1],r=e[t][1],n=e[t+1][1],o=this.diff_commonSuffix(i,r);if(o){let p=r.substring(r.length-o);i=i.substring(0,i.length-o),r=p+r.substring(0,r.length-o),n=p+n}let a=i,l=r,u=n,c=this.diff_cleanupSemanticScore_(i,r)+this.diff_cleanupSemanticScore_(r,n);for(;r.charAt(0)===n.charAt(0);){i+=r.charAt(0),r=r.substring(1)+n.charAt(0),n=n.substring(1);let p=this.diff_cleanupSemanticScore_(i,r)+this.diff_cleanupSemanticScore_(r,n);p>=c&&(c=p,a=i,l=r,u=n)}e[t-1][1]!==a&&(a?e[t-1][1]=a:(e.splice(t-1,1),t--),e[t][1]=l,u?e[t+1][1]=u:(e.splice(t+1,1),t--))}t++}}diff_cleanupEfficiency(e){let t=!1,i=[],r=0,n=null,o=0,a=!1,l=!1,u=!1,c=!1;for(;o<e.length;)e[o][0]===0?(e[o][1].length<this.diffEditCost&&(u||c)?(i[r++]=o,a=u,l=c,n=e[o][1]):(r=0,n=null),u=c=!1):(e[o][0]===-1?c=!0:u=!0,n&&(a&&l&&u&&c||n.length<this.diffEditCost/2&&Number(a)+Number(l)+Number(u)+Number(c)===3)&&(e.splice(i[r-1],0,[-1,n]),e[i[r-1]+1][0]=1,r--,n=null,a&&l?(u=c=!0,r=0):(r--,o=r>0?i[r-1]:-1,u=c=!1),t=!0)),o++;t&&this.diff_cleanupMerge(e)}diff_cleanupMerge(e){e.push([0,""]);let t=0,i=0,r=0,n="",o="",a;for(;t<e.length;)switch(e[t][0]){case 1:r++,o+=e[t][1],t++;break;case-1:i++,n+=e[t][1],t++;break;case 0:i+r>1?(i!==0&&r!==0&&(a=this.diff_commonPrefix(o,n),a!==0&&(t-i-r>0&&e[t-i-r-1][0]===0?e[t-i-r-1][1]+=o.substring(0,a):(e.splice(0,0,[0,o.substring(0,a)]),t++),o=o.substring(a),n=n.substring(a)),a=this.diff_commonSuffix(o,n),a!==0&&(e[t][1]=o.substring(o.length-a)+e[t][1],o=o.substring(0,o.length-a),n=n.substring(0,n.length-a))),t-=i+r,e.splice(t,i+r),n.length&&(e.splice(t,0,[-1,n]),t++),o.length&&(e.splice(t,0,[1,o]),t++),t++):t!==0&&e[t-1][0]===0?(e[t-1][1]+=e[t][1],e.splice(t,1)):t++,r=0,i=0,n="",o="";break}e[e.length-1][1]===""&&e.pop();let l=!1;for(t=1;t<e.length-1;)e[t-1][0]===0&&e[t+1][0]===0&&(e[t][1].substring(e[t][1].length-e[t-1][1].length)===e[t-1][1]?(e[t][1]=e[t-1][1]+e[t][1].substring(0,e[t][1].length-e[t-1][1].length),e[t+1][1]=e[t-1][1]+e[t+1][1],e.splice(t-1,1),l=!0):e[t][1].substring(0,e[t+1][1].length)===e[t+1][1]&&(e[t-1][1]+=e[t+1][1],e[t][1]=e[t][1].substring(e[t+1][1].length)+e[t+1][1],e.splice(t+1,1),l=!0)),t++;l&&this.diff_cleanupMerge(e)}diff_xIndex(e,t){let i=0,r=0,n=0,o=0,a;for(a=0;a<e.length&&(e[a][0]!==1&&(i+=e[a][1].length),e[a][0]!==-1&&(r+=e[a][1].length),!(i>t));a++)n=i,o=r;return e.length!==a&&e[a][0]===-1?o:o+(t-n)}diff_prettyHtml(e){let t=[],i=/&/g,r=/</g,n=/>/g,o=/\n/g;for(let a=0;a<e.length;a++){let l=e[a][0],c=e[a][1].replace(i,"&amp;").replace(r,"&lt;").replace(n,"&gt;").replace(o,"&para;<br>");switch(l){case 1:t[a]='<ins style="background:#e6ffe6;">'+c+"</ins>";break;case-1:t[a]='<del style="background:#ffe6e6;">'+c+"</del>";break;case 0:t[a]="<span>"+c+"</span>";break}}return t.join("")}diff_text1(e){let t=[];for(let i=0;i<e.length;i++)e[i][0]!==1&&(t[i]=e[i][1]);return t.join("")}diff_text2(e){let t=[];for(let i=0;i<e.length;i++)e[i][0]!==-1&&(t[i]=e[i][1]);return t.join("")}diff_levenshtein(e){let t=0,i=0,r=0;for(let n=0;n<e.length;n++){let o=e[n][0],a=e[n][1];switch(o){case 1:i+=a.length;break;case-1:r+=a.length;break;case 0:t+=B(i,r),i=0,r=0;break}}return t+=B(i,r),t}diff_toDelta(e){let t=[];for(let i=0;i<e.length;i++)switch(e[i][0]){case 1:t[i]="+"+encodeURI(e[i][1]);break;case-1:t[i]="-"+e[i][1].length;break;case 0:t[i]="="+e[i][1].length;break}return t.join(" ").replace(/%20/g," ")}diff_fromDelta(e,t){let i=[],r=0,n=0,o=t.split(/\t/g);for(let a=0;a<o.length;a++){let l=o[a].substring(1);switch(o[a].charAt(0)){case"+":try{i[r++]=[1,decodeURI(l)]}catch{throw new Error("Illegal escape in diff_fromDelta: "+l)}break;case"-":case"=":let u=parseInt(l,10);if(isNaN(u)||u<0)throw new Error("Invalid number in diff_fromDelta: "+l);let c=e.substring(n,n+=u);o[a].charAt(0)==="="?i[r++]=[0,c]:i[r++]=[-1,c];break;default:if(o[a])throw new Error("Invalid diff operation in diff_fromDelta: "+o[a])}}if(n!==e.length)throw new Error("Delta length ("+n+") does not equal source text length ("+e.length+")");return i}match_main(e,t,i){if(e==null||t==null||i==null)throw new Error("Null input. (match_main)");return i=B(0,M(i,e.length)),e===t?0:e.length?e.substring(i,i+t.length)===t?i:this.match_bitap_(e,t,i):-1}patch_make(e,t,i){let r,n;if(typeof e=="string"&&typeof t=="string"&&typeof i>"u")r=e,n=this.diff_main(r,t,!0),n.length>2&&(this.diff_cleanupSemantic(n),this.diff_cleanupEfficiency(n));else if(e&&typeof e=="object"&&typeof t>"u"&&typeof i>"u")n=e,r=this.diff_text1(n);else if(typeof e=="string"&&t&&typeof t=="object"&&typeof i>"u")r=e,n=t;else if(typeof e=="string"&&typeof t=="string"&&i&&typeof i=="object")r=e,n=i;else throw new Error("Unknown call format to patch_make");if(n.length===0)return[];let o=[],a=new U,l=0,u=0,c=0,p=r,d=r;for(let F=0;F<n.length;F++){let b=n[F][0],y=n[F][1];switch(!l&&b!==0&&(a.start1=u,a.start2=c),b){case 1:a.diffs[l++]=n[F],a.length2+=y.length,d=d.substring(0,c)+y+d.substring(c);break;case-1:a.length1+=y.length,a.diffs[l++]=n[F],d=d.substring(0,c)+d.substring(c+y.length);break;case 0:y.length<=2*this.patchMargin&&l&&n.length!==F+1?(a.diffs[l++]=n[F],a.length1+=y.length,a.length2+=y.length):y.length>=2*this.patchMargin&&l&&(this.patch_addContext_(a,p),o.push(a),a=new U,l=0,p=d,u=c);break}b!==1&&(u+=y.length),b!==-1&&(c+=y.length)}return l&&(this.patch_addContext_(a,p),o.push(a)),o}patch_deepCopy(e){let t=[];for(let i=0;i<e.length;i++){let r=e[i],n=new U;for(let o=0;o<r.diffs.length;o++)n.diffs[o]=[r.diffs[o][0],r.diffs[o][1]];n.start1=r.start1,n.start2=r.start2,n.length1=r.length1,n.length2=r.length2,t[i]=n}return t}patch_apply(e,t){if(e.length===0)return[t,[]];e=this.patch_deepCopy(e);let i=this.patch_addPadding(e);t=i+t+i,this.patch_splitMax(e);let r=0,n=[];for(let o=0;o<e.length;o++){let a=e[o].start2+r,l=this.diff_text1(e[o].diffs),u,c=-1;if(l.length>this.matchMaxBits?(u=this.match_main(t,l.substring(0,this.matchMaxBits),a),u!==-1&&(c=this.match_main(t,l.substring(l.length-this.matchMaxBits),a+l.length-this.matchMaxBits),(c===-1||u>=c)&&(u=-1))):u=this.match_main(t,l,a),u===-1)n[o]=!1,r-=e[o].length2-e[o].length1;else{n[o]=!0,r=u-a;let p;if(c===-1?p=t.substring(u,u+l.length):p=t.substring(u,c+this.matchMaxBits),l===p)t=t.substring(0,u)+this.diff_text2(e[o].diffs)+t.substring(u+l.length);else{let d=this.diff_main(l,p,!1);if(l.length>this.matchMaxBits&&this.diff_levenshtein(d)/l.length>this.patchDeleteThreshold)n[o]=!1;else{this.diff_cleanupSemanticLossless(d);let F=0,b=0;for(let y=0;y<e[o].diffs.length;y++){let g=e[o].diffs[y];g[0]!==0&&(b=this.diff_xIndex(d,F)),g[0]===1?t=t.substring(0,u+b)+g[1]+t.substring(u+b):g[0]===-1&&(t=t.substring(0,u+b)+t.substring(u+this.diff_xIndex(d,F+g[1].length))),g[0]!==-1&&(F+=g[1].length)}}}}}return t=t.substring(i.length,t.length-i.length),[t,n]}patch_addPadding(e){let t=this.patchMargin,i="";for(let o=1;o<=t;o++)i+=String.fromCharCode(o);for(let o=0;o<e.length;o++)e[o].start1+=t,e[o].start2+=t;let r=e[0],n=r.diffs;if(n.length===0||n[0][0]!==0)n.unshift([0,i]),r.start1-=t,r.start2-=t,r.length1+=t,r.length2+=t;else if(t>n[0][1].length){let o=t-n[0][1].length;n[0][1]=i.substring(n[0][1].length)+n[0][1],r.start1-=o,r.start2-=o,r.length1+=o,r.length2+=o}if(r=e[e.length-1],n=r.diffs,n.length===0||n[n.length-1][0]!==0)n.push([0,i]),r.length1+=t,r.length2+=t;else if(t>n[n.length-1][1].length){let o=t-n[n.length-1][1].length;n[n.length-1][1]+=i.substring(0,o),r.length1+=o,r.length2+=o}return i}patch_splitMax(e){let t=this.matchMaxBits;for(let i=0;i<e.length;i++){if(e[i].length1<=t)continue;let r=e[i];e.splice(i--,1);let n=r.start1,o=r.start2,a="";for(;r.diffs.length!==0;){let l=new U,u=!0;for(l.start1=n-a.length,l.start2=o-a.length,a!==""&&(l.length1=l.length2=a.length,l.diffs.push([0,a]));r.diffs.length!==0&&l.length1<t-this.patchMargin;){let p=r.diffs[0][0],d=r.diffs[0][1];p===1?(l.length2+=d.length,o+=d.length,l.diffs.push(r.diffs.shift()),u=!1):p===-1&&l.diffs.length===1&&l.diffs[0][0]===0&&d.length>2*t?(l.length1+=d.length,n+=d.length,u=!1,l.diffs.push([p,d]),r.diffs.shift()):(d=d.substring(0,t-l.length1-this.patchMargin),l.length1+=d.length,n+=d.length,p===0?(l.length2+=d.length,o+=d.length):u=!1,l.diffs.push([p,d]),d===r.diffs[0][1]?r.diffs.shift():r.diffs[0][1]=r.diffs[0][1].substring(d.length))}a=this.diff_text2(l.diffs),a=a.substring(a.length-this.patchMargin);let c=this.diff_text1(r.diffs).substring(0,this.patchMargin);c!==""&&(l.length1+=c.length,l.length2+=c.length,l.diffs.length!==0&&l.diffs[l.diffs.length-1][0]===0?l.diffs[l.diffs.length-1][1]+=c:l.diffs.push([0,c])),u||e.splice(++i,0,l)}}}patch_toText(e){let t=[];for(let i=0;i<e.length;i++)t[i]=e[i];return t.join("")}patch_fromText(e){let t=[];if(!e)return t;let i=e.split(`
4
+ `),r=0,n=/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;for(;r<i.length;){let o=i[r].match(n);if(!o)throw new Error("Invalid patch string: "+i[r]);let a=new U;t.push(a),a.start1=parseInt(o[1],10),o[2]===""?(a.start1--,a.length1=1):o[2]==="0"?a.length1=0:(a.start1--,a.length1=parseInt(o[2],10)),a.start2=parseInt(o[3],10),o[4]===""?(a.start2--,a.length2=1):o[4]==="0"?a.length2=0:(a.start2--,a.length2=parseInt(o[4],10)),r++;let l,u,c;for(;r<i.length;){l=i[r].charAt(0),c=i[r].substring(1);try{u=decodeURI(c)}catch{throw new Error("Illegal escape in patch_fromText: "+c)}if(l==="-")a.diffs.push([-1,u]);else if(l==="+")a.diffs.push([1,u]);else if(l===" ")a.diffs.push([0,u]);else{if(l==="@")break;if(l!=="")throw new Error('Invalid patch mode "'+l+'" in: '+u)}r++}}return t}diff_compute_(e,t,i,r){let n;if(!e)return[[1,t]];if(!t)return[[-1,e]];let o=e.length>t.length?e:t,a=e.length>t.length?t:e,l=o.indexOf(a);if(l!==-1)return n=[[1,o.substring(0,l)],[0,a],[1,o.substring(l+a.length)]],e.length>t.length&&(n[0][0]=-1,n[2][0]=-1),n;if(a.length===1)return[[-1,e],[1,t]];let u=this.diff_halfMatch_(e,t);if(u){let c=u[0],p=u[1],d=u[2],F=u[3],b=u[4],y=this.diff_main(c,d,i,r),g=this.diff_main(p,F,i,r);return y.concat([[0,b]],g)}return i&&e.length>100&&t.length>100?this.diff_lineMode_(e,t,r):this.diff_bisect_(e,t,r)}diff_lineMode_(e,t,i){let r=this.diff_linesToChars_(e,t);e=r.chars1,t=r.chars2;let n=r.lineArray,o=this.diff_main(e,t,!1,i);this.diff_charsToLines_(o,n),this.diff_cleanupSemantic(o),o.push([0,""]);let a=0,l=0,u=0,c="",p="";for(;a<o.length;){switch(o[a][0]){case 1:u++,p+=o[a][1];break;case-1:l++,c+=o[a][1];break;case 0:if(l>=1&&u>=1){o.splice(a-l-u,l+u),a=a-l-u;let d=this.diff_main(c,p,!1,i);for(let F=d.length-1;F>=0;F--)o.splice(a,0,d[F]);a=a+d.length}u=0,l=0,c="",p="";break}a++}return o.pop(),o}diff_bisect_(e,t,i){let r=e.length,n=t.length,o=Math.ceil((r+n)/2),a=o,l=2*o,u=new Array(l),c=new Array(l);for(let h=0;h<l;h++)u[h]=-1,c[h]=-1;u[a+1]=0,c[a+1]=0;let p=r-n,d=p%2!==0,F=0,b=0,y=0,g=0;for(let h=0;h<o&&!(Date.now()>i);h++){for(let f=-h+F;f<=h-b;f+=2){let v=a+f,m;f===-h||f!==h&&u[v-1]<u[v+1]?m=u[v+1]:m=u[v-1]+1;let S=m-f;for(;m<r&&S<n&&e.charAt(m)===t.charAt(S);)m++,S++;if(u[v]=m,m>r)b+=2;else if(S>n)F+=2;else if(d){let w=a+p-f;if(w>=0&&w<l&&c[w]!==-1){let P=r-c[w];if(m>=P)return this.diff_bisectSplit_(e,t,m,S,i)}}}for(let f=-h+y;f<=h-g;f+=2){let v=a+f,m;f===-h||f!==h&&c[v-1]<c[v+1]?m=c[v+1]:m=c[v-1]+1;let S=m-f;for(;m<r&&S<n&&e.charAt(r-m-1)===t.charAt(n-S-1);)m++,S++;if(c[v]=m,m>r)g+=2;else if(S>n)y+=2;else if(!d){let w=a+p-f;if(w>=0&&w<l&&u[w]!==-1){let P=u[w],_=a+P-w;if(m=r-m,P>=m)return this.diff_bisectSplit_(e,t,P,_,i)}}}}return[[-1,e],[1,t]]}diff_bisectSplit_(e,t,i,r,n){let o=e.substring(0,i),a=t.substring(0,r),l=e.substring(i),u=t.substring(r),c=this.diff_main(o,a,!1,n),p=this.diff_main(l,u,!1,n);return c.concat(p)}diff_linesToChars_(e,t){let i=[],r={};i[0]="";let n=this.diff_linesToCharsMunge_(e,i,r,4e4),o=this.diff_linesToCharsMunge_(t,i,r,65535);return{chars1:n,chars2:o,lineArray:i}}diff_linesToCharsMunge_(e,t,i,r){let n="",o=0,a=-1,l=t.length;for(;a<e.length-1;){a=e.indexOf(`
5
+ `,o),a===-1&&(a=e.length-1);let u=e.substring(o,a+1);(i.hasOwnProperty?i.hasOwnProperty(u):i[u]!==void 0)?n+=String.fromCharCode(i[u]):(l===r&&(u=e.substring(o),a=e.length),n+=String.fromCharCode(l),i[u]=l,t[l++]=u),o=a+1}return n}diff_charsToLines_(e,t){for(let i=0;i<e.length;i++){let r=e[i][1],n=[];for(let o=0;o<r.length;o++)n[o]=t[r.charCodeAt(o)];e[i][1]=n.join("")}}diff_commonOverlap_(e,t){let i=e.length,r=t.length;if(i===0||r===0)return 0;i>r?e=e.substring(i-r):i<r&&(t=t.substring(0,i));let n=M(i,r);if(e===t)return n;let o=0,a=1;for(;;){let l=e.substring(n-a),u=t.indexOf(l);if(u===-1)return o;a+=u,(u===0||e.substring(n-a)===t.substring(0,a))&&(o=a,a++)}}diff_halfMatch_(e,t){if(this.diffTimeout<=0)return null;let i=e.length>t.length?e:t,r=e.length>t.length?t:e;if(i.length<4||r.length*2<i.length)return null;let n=this.diff_halfMatchI_(i,r,Math.ceil(i.length/4)),o=this.diff_halfMatchI_(i,r,Math.ceil(i.length/2)),a;if(!n&&!o)return null;o?n?a=n[4].length>o[4].length?n:o:a=o:a=n;let l,u,c,p,d=a[4];return e.length>t.length?(l=a[0],u=a[1],c=a[2],p=a[3]):(c=a[0],p=a[1],l=a[2],u=a[3]),[l,u,c,p,d]}diff_halfMatchI_(e,t,i){let r=e.substring(i,i+Math.floor(e.length/4)),n="",o,a,l,u,c=t.indexOf(r,0);for(;c!==-1;){let p=this.diff_commonPrefix(e.substring(i),t.substring(c)),d=this.diff_commonSuffix(e.substring(0,i),t.substring(0,c));n.length<d+p&&(n=t.substring(c-d,c)+t.substring(c,c+p),o=e.substring(0,i-d),a=e.substring(i+p),l=t.substring(0,c-d),u=t.substring(c+p)),c=t.indexOf(r,c+1)}return n.length*2>=e.length?[o,a,l,u,n]:null}diff_cleanupSemanticScore_(e,t){if(!e||!t)return 6;let i=e.charAt(e.length-1),r=t.charAt(0),n=i.match(Mt),o=r.match(Mt),a=n&&i.match(Bt),l=o&&r.match(Bt),u=a&&i.match(Ut),c=l&&r.match(Ut),p=u&&e.match(Ii),d=c&&t.match(Li);return p||d?5:u||c?4:n&&!a&&l?3:a||l?2:n||o?1:0}match_bitap_(e,t,i){if(t.length>this.matchMaxBits)throw new Error("Pattern too long for this browser");let r=this.match_alphabet_(t),n=this.matchThreshold,o=e.indexOf(t,i);o!==-1&&(n=M(this.match_bitapScore_(0,o,t,i),n),o=e.lastIndexOf(t,i+t.length),o!==-1&&(n=M(this.match_bitapScore_(0,o,t,i),n)));let a=1<<t.length-1;o=-1;let l,u,c=t.length+e.length,p;for(let d=0;d<t.length;d++){for(l=0,u=c;l<u;)this.match_bitapScore_(d,i+u,t,i)<=n?l=u:c=u,u=Math.floor((c-l)/2+l);c=u;let F=B(1,i-u+1),b=M(i+u,e.length)+t.length,y=Array(b+2);y[b+1]=(1<<d)-1;for(let g=b;g>=F;g--){let h=r[e.charAt(g-1)];if(d===0?y[g]=(y[g+1]<<1|1)&h:y[g]=(y[g+1]<<1|1)&h|((p[g+1]|p[g])<<1|1)|p[g+1],y[g]&a){let f=this.match_bitapScore_(d,g-1,t,i);if(f<=n)if(n=f,o=g-1,o>i)F=B(1,2*i-o);else break}}if(this.match_bitapScore_(d+1,i,t,i)>n)break;p=y}return o}match_bitapScore_(e,t,i,r){let n=e/i.length,o=Math.abs(r-t);return this.matchDistance?n+o/this.matchDistance:o?1:n}match_alphabet_(e){let t={};for(let i=0;i<e.length;i++)t[e.charAt(i)]=0;for(let i=0;i<e.length;i++)t[e.charAt(i)]|=1<<e.length-i-1;return t}patch_addContext_(e,t){if(t.length===0)return;if(e.start2==null)throw Error("patch not initialized");let i=t.substring(e.start2,e.start2+e.length1),r=0;for(;t.indexOf(i)!==t.lastIndexOf(i)&&i.length<this.matchMaxBits-this.patchMargin-this.patchMargin;)r+=this.patchMargin,i=t.substring(e.start2-r,e.start2+e.length1+r);r+=this.patchMargin;let n=t.substring(e.start2-r,e.start2);n&&e.diffs.unshift([0,n]);let o=t.substring(e.start2+e.length1,e.start2+e.length1+r);o&&e.diffs.push([0,o]),e.start1-=n.length,e.start2-=n.length,e.length1+=n.length+o.length,e.length2+=n.length+o.length}},U=class{constructor(){this.diffs=[];this.start1=0;this.start2=0;this.length1=0;this.length2=0}toString(){let e,t;this.length1===0?e=this.start1+",0":this.length1===1?e=this.start1+1:e=this.start1+1+","+this.length1,this.length2===0?t=this.start2+",0":this.length2===1?t=this.start2+1:t=this.start2+1+","+this.length2;let i=["@@ -"+e+" +"+t+` @@
6
6
  `],r;for(let n=0;n<this.diffs.length;n++){switch(this.diffs[n][0]){case 1:r="+";break;case-1:r="-";break;case 0:r=" ";break}i[n+1]=r+encodeURI(this.diffs[n][1])+`
7
- `}return i.join("").replace(/%20/g," ")}};function Ut(s,e,t){let i=new Fe,r=i.diff_main(s,e,!0,0);r.length>2&&(i.diff_cleanupSemantic(r),i.diff_cleanupEfficiency(r));let n=i.patch_make(s,r);return i.patch_apply(n,t)[0]}var be=["bmp","png","jpg","jpeg","gif","svg","webp","avif"],we=["mp3","wav","m4a","3gp","flac","ogg","oga","opus"],ve=["mp4","webm","ogv","mov","mkv"],Ee=["pdf"],Vt=["md"],Xe=["canvas"],jt=["base"];var Pr=Vt.concat(Xe,jt),Ar=[].concat(be,we,ve,Ee,Vt,Xe);var _r=[...be,...we,...ve,...Ee,...jt,...Xe];var Se=class{constructor(e){this.allowTypes=new Set(G);this.allowSpecialFiles=new Set(z);this.ignoreFolders=[];this.filterCache={};this.configDir=e}init(e,t,i){this.filterCache={},this.allowTypes=new Set(e||G),this.allowSpecialFiles=new Set(t||[]),this.ignoreFolders=i||[]}clear(){this.filterCache={},this.allowTypes=new Set(G),this.allowSpecialFiles=new Set(z),this.ignoreFolders=[]}clearCache(){this.filterCache={}}allowSyncFile(e,t){let{filterCache:i}=this;return Object.hasOwn(i,e)?i[e]:i[e]=this._allowSyncFile(e,t)}_allowSyncFile(e,t){for(let n of this.ignoreFolders)if(t&&e===n||e.startsWith(n+"/"))return!1;if(!t&&e.startsWith(this.configDir+"/")){let n=e.substring((this.configDir+"/").length),o=n.split("/");if(o.some(u=>u==="node_modules"||u.startsWith(".")))return!1;let a=O(n),l=T(a),c=null;return n==="workspace.json"||n==="workspace-mobile.json"?!1:(n==="app.json"||n==="types.json"?c="app":n==="appearance.json"?c="appearance":n==="hotkeys.json"?c="hotkey":n==="core-plugins.json"||n==="core-plugins-migration.json"?c="core-plugin":n==="community-plugins.json"?c="community-plugin":o[0]==="themes"&&o.length===3&&(a==="theme.css"||a==="manifest.json")||o[0]==="snippets"&&o.length===2&&l==="css"?c="appearance-data":o.length===1&&l==="json"?c="core-plugin-data":o[0]==="plugins"&&o.length===3&&this.isPluginFile(a)&&(c="community-plugin-data"),c&&this.allowSpecialFiles.has(c))}if(e.startsWith("."))return!1;if(t)return!0;if(e.startsWith("."))return!1;let i=T(O(e));if(i==="md"||i==="canvas"||i==="base")return!0;let{allowTypes:r}=this;return be.includes(i)?r.has("image"):i==="webm"?r.has("audio")||r.has("video"):we.includes(i)?r.has("audio"):ve.includes(i)?r.has("video"):Ee.includes(i)?r.has("pdf"):!!r.has("unsupported")}isPluginFile(e){return e==="manifest.json"||e==="main.js"||e==="styles.css"||e==="data.json"}};var ne=class{constructor(){this.promise=Promise.resolve()}queue(e){let t=this.promise.then(e,e);return this.promise=t,t}};function De(){let s={promise:null,resolve:null,reject:null};return s.promise=new Promise((e,t)=>{s.resolve=e,s.reject=t}),s}var Ye=WebSocket,Kt=URL,Ni=Object.getOwnPropertyDescriptor(Kt.prototype,"hostname").get,ki=String.prototype.endsWith,qt={1e3:"Disconnected",1001:"Going Away",1002:"Protocol Error",1003:"Unsupported Data",1004:"(For future)",1005:"No Status Received",1006:"Disconnected",1007:"Invalid frame payload data",1008:"Policy Violation",1009:"Message too big",1010:"Missing Extension",1011:"Internal Error",1012:"Service Restart",1013:"Try Again Later",1014:"Bad Gateway",1015:"TLS Handshake"};function Mi(s){if(s>=0&&s<=999)return"(Unused)";if(s>=1016){if(s<=1999)return"(For WebSocket standard)";if(s<=2999)return"(For WebSocket extensions)";if(s<=3999)return"(For libraries and frameworks)";if(s<=4999)return"(For applications)"}return qt.hasOwnProperty(s)?qt[s]:"(Unknown)"}var Bi=20*1e3,Ui=10*1e3,Vi=2*60*1e3,Pe=class{constructor(e){this.socket=null;this.queue=new ne;this.notifyQueue=new ne;this.onDisconnect=null;this.perFileMax=199*1024*1024;this.userId=-1;this.justPushed=null;this.encryptionProvider=e}isConnecting(){let{socket:e}=this;return e&&e.readyState===Ye.CONNECTING}isConnected(){let{socket:e}=this;return e&&e.readyState===Ye.OPEN}hasConnection(){let{socket:e}=this;return!!e}async connect(e,t,i,r,n,o,a,l){if(this.hasConnection())return;this.onReady=a,this.onPush=l;let c=this.encryptionProvider.keyHash;return new Promise((u,p)=>{let d=new Kt(e),F=Ni.call(d);if(!ki.call(F,".obsidian.md")&&F!=="127.0.0.1")return p(new Error("Unable to connect to server."));let b=!1,y=h=>{b||(b=!0,this.disconnect(),p(h))},g=this.socket=new Ye(d);g.binaryType="arraybuffer",g.onclose=h=>{h.code===1006?y(new Error("Unable to connect to server.")):y(new Error("Disconnected. Code: "+h.code+" "+Mi(h.code)))},g.onopen=()=>{this.lastMessageTs=Date.now(),this.heartbeat=setInterval(()=>{let h=Date.now()-this.lastMessageTs;if(h>Vi){this.disconnect();return}h>Ui&&this.send({op:"ping"})},Bi),this.send({op:"init",token:t,id:i,keyhash:c,version:r,initial:n,device:o,encryption_version:this.encryptionProvider.encryptionVersion})},g.onmessage=h=>{let f=h.data;if(typeof f!="string")return y(new Error("Server returned binary"));let w;try{w=JSON.parse(f)}catch(m){return console.error(m),y(new Error("Server JSON failed to parse: "+f))}if(w.op!=="pong"){if(w.status==="err"||w.res==="err")return y(new Error("Failed to authenticate: "+w.msg));if(w.res!=="ok")return y(new Error("Did not respond to login request: "+f));if(w.hasOwnProperty("perFileMax")){let m=w.perFileMax;if(!Number.isInteger(m)||isNaN(m)||m<0)return y(new Error("Unexpected value from server for max file size"));this.perFileMax=m}w.userId&&(this.userId=w.userId),u(),b=!0,g.onmessage=this.onMessage.bind(this),g.onclose=this.disconnect.bind(this),g.onerror=this.disconnect.bind(this)}}})}disconnect(){let e=!1;this.socket&&(this.socket.close(),this.socket=null,e=!0),this.heartbeat&&(clearInterval(this.heartbeat),this.heartbeat=null),this.responsePromise&&(this.responsePromise.reject(new Error("Disconnected")),this.responsePromise=null),this.dataPromise&&(this.dataPromise.reject(new Error("Disconnected")),this.dataPromise=null),e&&this.onDisconnect&&this.onDisconnect()}async pull(e){return this.queue.queue(async()=>{this.lastNetworkRequestTs=Date.now();let t=await this.request({op:"pull",uid:e});if(!t.deleted){let i=t.size,r=t.pieces,n=new ArrayBuffer(i),o=0;for(let a=0;a<r;a++){let l=await this.dataResponse();new Uint8Array(n,o,l.byteLength).set(new Uint8Array(l)),o+=l.byteLength}return n.byteLength>0&&(n=await this.encryptionProvider.decrypt(n)),n}return null})}async push(e,t,i,r,n,o,a,l){return this.queue.queue(async()=>{this.lastNetworkRequestTs=Date.now();let c=await this.encryptionProvider.deterministicEncodeStr(e),u=t?await this.encryptionProvider.deterministicEncodeStr(t):null,p=i?"":T(O(e));if(i||r){this.justPushed={path:c,folder:i,deleted:r,mtime:0,hash:""},await this.request({op:"push",path:c,relatedpath:u,extension:p,hash:"",ctime:0,mtime:0,folder:i,deleted:r});return}l.byteLength>0&&(l=await this.encryptionProvider.encrypt(l)),a&&(a=await this.encryptionProvider.deterministicEncodeStr(a));let d=l.byteLength,F=2*1024*1024,b=Math.ceil(d/F);if(this.justPushed={path:c,folder:i,deleted:r,mtime:o,hash:a},(await this.request({op:"push",path:c,relatedpath:u,extension:p,hash:a,ctime:n,mtime:o,folder:i,deleted:r,size:d,pieces:b})).res==="ok"){this.justPushed=null;return}for(let g=0;g<b;g++){let h=g*F,f=Math.min(F,d-h);this.sendBinary(new Uint8Array(l,h,f)),await this.response()}this.justPushed=null})}async listDeleted(){return this.queue.queue(async()=>{let t=(await this.request({op:"deleted",suppressrenames:!0})).items;for(let i of t)i.path=await this.encryptionProvider.deterministicDecodeStr(i.path);return t})}async listHistory(e,t){return this.queue.queue(async()=>{let i=await this.encryptionProvider.deterministicEncodeStr(e),r=await this.request({op:"history",path:i,last:t}),n=r.items;for(let o of n)o.path=await this.encryptionProvider.deterministicDecodeStr(o.path),o.relatedpath=o.relatedpath&&await this.encryptionProvider.deterministicDecodeStr(o.relatedpath);return r})}async restore(e){return this.queue.queue(async()=>this.request({op:"restore",uid:e}))}async getUsernames(){return this.queue.queue(()=>this.request({op:"usernames"}))}async purge(){return this.queue.queue(()=>this.request({op:"purge"}))}async size(){return this.queue.queue(()=>this.request({op:"size"}))}onServerPush(e){let{justPushed:t}=this;t&&t.path===e.path&&t.folder===e.folder&&t.deleted===e.deleted&&t.mtime===e.mtime&&t.hash===e.hash&&(this.justPushed=null,e.wasJustPushed=!0),this.notifyQueue.queue(async()=>{e.path=await this.encryptionProvider.deterministicDecodeStr(e.path),e.hash&&(e.hash=await this.encryptionProvider.deterministicDecodeStr(e.hash)),this.onPush(e)})}response(){return(this.responsePromise=De()).promise}dataResponse(){return(this.dataPromise=De()).promise}async request(e,t=6e4){let i=this.responsePromise=De();this.send(e);let r=new Error("Timeout"),n=setTimeout(()=>i.reject(r),t),o;try{o=await i.promise,clearTimeout(n)}catch(a){throw a===r&&this.disconnect(),a}if(o.err)throw new Error(o.err);return o}onMessage(e){if(this.lastMessageTs=Date.now(),typeof e.data=="string"){let t;try{t=JSON.parse(e.data)}catch{console.log(e.data),this.disconnect();return}let i=t.op;if(i==="pong")return;if(i==="ready"){this.notifyQueue.queue(async()=>{this.onReady(t.version)});return}if(i==="push"){this.onServerPush(t);return}let r=this.responsePromise;r&&(this.responsePromise=null,r.resolve(t))}else{let t=this.dataPromise;t&&(this.dataPromise=null,t.resolve(e.data))}}send(e){this.socket.send(JSON.stringify(e))}sendBinary(e){this.socket.send(e)}};var Ae=class{constructor(e,t,i,r){this.min=e||0,this.max=t||Number.MAX_VALUE,this.base=i||1e3,this.jitter=r||!0,this.count=0,this.nextTs=Date.now()}success(){this.count=0,this.nextTs=Date.now()+this.getTimeout()}fail(){this.count++,this.nextTs=Date.now()+this.getTimeout()}getTimeout(){if(this.count===0)return this.min;let e=this.count-1,t=this.base*Math.pow(2,e);if(this.jitter){let i=.5;t=t*(1-i+i*Math.random())}return t=Math.floor(Math.min(this.max,this.min+t)),t}getNextTs(){return this.nextTs}isReady(){return Date.now()>this.nextTs}};var Wt=crypto,x=Wt.subtle,Je="AES-GCM";function Ht(s){return x.importKey("raw",s,Je,!1,["encrypt","decrypt"])}async function _e(s,e,t){t||(t=Wt.getRandomValues(new Uint8Array(12)));let i=await x.encrypt({name:Je,iv:t},e,s),r=new ArrayBuffer(t.byteLength+i.byteLength),n=new Uint8Array(r);return n.set(new Uint8Array(t),0),n.set(new Uint8Array(i),t.byteLength),r}async function Te(s,e){if(s.byteLength<12)throw new Error("Encrypted data is bad");if(s.byteLength===12)return new ArrayBuffer(0);let t=new Uint8Array(s,0,12),i=new Uint8Array(s,12);return await x.decrypt({name:Je,iv:t},e,i)}function se(s){return s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength)}function L(s){return se(new TextEncoder().encode(s))}function K(s){return new TextDecoder().decode(new Uint8Array(s))}function $t(s){let e=atob(s),t=e.length,i=new Uint8Array(t);for(let r=0;r<t;r++)i[r]=e.charCodeAt(r);return i.buffer}function Gt(s){return ji(new Uint8Array(s))}function ji(s){let e=[],t=s.byteLength;for(let i=0;i<t;i++)e.push(String.fromCharCode(s[i]));return btoa(e.join(""))}async function xe(s){return R(await oe(s))}async function oe(s){return x.digest("SHA-256",new Uint8Array(s))}function Ze(s){let e=s.length/2,t=new ArrayBuffer(e),i=new Uint8Array(t);for(let r=0;r<e;r++)i[r]=parseInt(s.substr(r*2,2),16);return t}function R(s){let e=new Uint8Array(s),t=[];for(let i=0;i<e.length;i++){let r=e[i];t.push((r>>>4).toString(16)),t.push((r&15).toString(16))}return t.join("")}function ze(s){if(s<=0)return"0 B";let e=["B","KB","MB","GB","TB","PB"],t=e.length-1,i=1024;for(let n=0;n<e.length;n++)if(s<Math.pow(i,n+1)){t=n;break}let r=s/Math.pow(i,t);return`${qi(r,t===0?0:2)} ${e[t]}`}function qi(s,e=2,t=".",i=","){let r=s<0?"-":"";s=Math.abs(s);let n=parseInt(s.toFixed(e),10)+"",o=n.length>3?n.length%3:0;return r+(o?n.substr(0,o)+i:"")+n.substr(o).replace(/(\d{3})(?=\d)/g,"$1"+i)+(e?t+Math.abs(s-Math.floor(s)).toFixed(e).slice(2):"")}var Ki=function(){let s=typeof process<"u"?process.platform:"";if(s==="win32")return"win";if(s==="darwin")return"mac";if(s==="linux")return"linux";if(s)return"unknown";let e=navigator.userAgent;return e.indexOf("Win")!==-1?"win":e.indexOf("Mac")!==-1?"mac":e.indexOf("X11")!==-1||e.indexOf("Linux")!==-1?"linux":"unknown"}(),Qt=navigator.userAgent.toLowerCase();var et=Ki==="win";var Gr=/^((?!chrome|android).)*safari/i.test(Qt),Xt=/android/i.test(Qt);var Wi=/[.?*+^$[\]\\(){}|-]/g;function Ie(s){return s.replace(Wi,"\\$&")}var Hi="\\/:"+(Xt?'*?<>"':""),$i='*"\\/<>:|?',Yt="#^[]|",Jt=et?$i:Hi,Gi=Jt.split("").join("\xA0"),zr=Yt.split("").join("\xA0"),Zt=new RegExp("["+Ie(Jt)+"]"),en=new RegExp("["+Ie(Yt)+"]"),Qi=/^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i;function zt(s){try{return Xi(s),!0}catch{return!1}}function Xi(s){if(et){let e=s.charAt(s.length-1);if(e==="."||e===" ")throw new Error("File names cannot end with a dot or a space.");let t=It(s);if(Qi.test(t))throw new Error("File name is forbidden: "+t)}if(s.split("/").some(e=>Zt.test(e)))throw new Error("File name cannot contain any of the following characters: "+Gi)}function ei(s,e="_"){let t=s.trim();if(t&&(t=s.replace(Zt,e),e.length===1)){let i=Ie(e),r=new RegExp(`${i}{2,}`,"g");t=t.replace(r,e)}return t}function Yi(s){return new Promise(e=>setTimeout(e,s))}var Le=class{constructor(e){this.server=null;this.localFiles={};this.serverFiles={};this.newServerFiles=[];this.version=0;this.initial=!0;this.ready=!1;this.syncing=!1;this.loaded=!1;this.backoff=new Ae(0,5*60*1e3,5e3,!0);this.fileRetry={};this.skippedFiles={};this.syncingPath="";this.scanSpecialFiles=!1;this.scanSpecialFileQueue=[];this.resolveStop=null;let{config:t}=e;this.host=t.host,this.token=e.token,this.vaultId=t.vaultId,this.continuous=e.continuous||!1,this.encryption=e.encryption,this.stateStore=e.stateStore,this.conflictStrategy=t.conflictStrategy||"merge",this.deviceName=t.deviceName||"Sync Client",this.adapter=new ye(P.default,D.default,ke.default,()=>!1,yt,"file:///",t.vaultPath),this.filter=new Se(t.configDir),this.filter.init(t.allowTypes||[],t.allowSpecialFiles||[],t.ignoreFolders||[]),this.loadState()}loadState(){this.version=this.stateStore.getVersion(),this.initial=this.stateStore.isInitial(),this.localFiles=this.stateStore.getAllLocalFiles(),this.serverFiles=this.stateStore.getAllServerFiles(),this.newServerFiles=this.stateStore.getPendingFiles()}handlePush(e){if(this.version=e.uid,this.initial&&e.deleted){this.stateStore.setVersion(this.version);return}let t=e.path,i={path:t,size:e.size,hash:e.hash,ctime:e.ctime,mtime:e.mtime,folder:e.folder,deleted:e.deleted,uid:e.uid,device:e.device,user:e.user};this.initial&&(i.initial=!0);let{newServerFiles:r}=this;if(e.wasJustPushed){for(let n=0;n<r.length;n++)r[n].path===t&&(r.splice(n,1),n-=1);this.stateStore.deletePendingFile(t),this.serverFiles[t]=i,this.stateStore.setServerFile(i),this.stateStore.setVersion(this.version);return}r.push(i),this.stateStore.addPendingFile(i),this.stateStore.setVersion(this.version),this.initial||console.debug(`Push: ${i.path} (${i.deleted?"deleted":"updated"})`),this.requestSync()}async sync(){let e=new Promise(i=>this.resolveStop=i),t=setInterval(this.requestSync.bind(this),30*1e3);try{if(!this.loaded){await this.adapter.watch(this.onChange.bind(this));for(let i in this.localFiles)Object.hasOwn(this.adapter.files,i)||(delete this.localFiles[i],this.stateStore.deleteLocalFile(i));this.loaded=!0}await this.requestSync(),await e}finally{clearInterval(t)}}stop(){this.server&&(this.server.disconnect(),this.server=null),this.ready=!1,this.stateStore.close(),this.adapter.stopWatch(),this.adapter.thingsHappening.cancel(),this.resolveStop&&(this.resolveStop(),this.resolveStop=null)}async requestSync(){if(!this.syncing){this.syncing=!0;try{let e=!0;for(;e;){try{this.syncingPath="",e=await this._sync();let i=this.syncingPath;i&&delete this.fileRetry[i]}catch(i){if(console.error("Sync error:",i),this.failedSync(this.syncingPath),e=!1,!this.continuous)throw this.syncing=!1,i}if(!e)return;let t=0;if(this.server){let i=Date.now()-this.server.lastNetworkRequestTs;t=Math.max(0,50-i)}await Yi(t)}}finally{this.syncing=!1}}}canSyncPath(e,t){let{fileRetry:i}=this;for(let r in i)if(i.hasOwnProperty(r)&&i[r].ts>e&&t.startsWith(r))return!1;return!0}canSyncLocalFile(e,t){if(!t.synctime)return!0;let i=t.size,r=i>10*1024,n=i>100*1024,o=r?n?30:20:10;return e-t.synctime>o*1e3}failedSync(e){if(!e)return;let t=Date.now(),i=this.fileRetry[e];i||(i=this.fileRetry[e]={count:0,ts:0});let r=i.count=i.count+1,n=Math.pow(2,r)*5*1e3;n=Math.min(n,5*60*1e3),i.ts=t+n}async getServer(){let{server:e}=this;if(e&&!e.isConnected()&&!e.isConnecting()&&(e.disconnect(),e=this.server=null,this.backoff.fail()),!e){if(!this.backoff.isReady())return this.log("Waiting to connect to server"),null;e=this.server=new Pe(this.encryption)}if(!e.hasConnection()){this.log("Connecting..."),this.ready=!1;try{let t=this.host.startsWith("127.0.0.1")||this.host.startsWith("localhost")?"ws://":"wss://";e.onDisconnect=()=>{this.ready=!1,this.log("Disconnected from server"),this.continuous&&this.requestSync()},await e.connect(t+this.host,this.token,this.vaultId,this.version,this.initial,this.deviceName,i=>{this.ready=!0,this.initial=!1,this.stateStore.setInitial(!1),this.version<i&&(this.version=i,this.stateStore.setVersion(this.version)),this.requestSync()},i=>this.handlePush(i)),this.log("Connection successful. Detecting changes..."),this.backoff.success()}catch(t){if(t.message&&t.message.includes("Your subscription to Obsidian Sync has expired"))throw console.error(t.message),this.stop(),t;if(t.message&&t.message.includes("Vault not found"))throw console.error("The connected remote vault no longer exists."),this.stop(),t;return console.error(t),e.disconnect(),e=this.server=null,this.backoff.fail(),null}}return e}async _sync(){let e=await this.getServer();if(!e)return!1;let t=Date.now(),i=0,r=this.filter.configDir,n=r+"/",{localFiles:o,serverFiles:a,newServerFiles:l,stateStore:c,filter:u,adapter:p}=this;try{let g={},h=this.scanSpecialFileQueue;if(this.scanSpecialFiles){this.scanSpecialFiles=!1,h=this.scanSpecialFileQueue=[];for(let f in o)Object.hasOwn(o,f)&&f.startsWith(".")&&(g[f]=o[f],delete o[f],c.deleteLocalFile(f));if(u.allowSpecialFiles.size>0&&await p.exists(r)){h.push(n+"config");let f=await p.list(r);for(let w of f.files)T(w)==="json"&&h.push(w);if(await p.exists(n+"themes")){let w=await p.list(n+"themes");for(let m of w.folders){let v=await p.list(m);for(let E of v.files){let S=O(E);(S==="manifest.json"||S==="theme.css")&&h.push(E)}}}if(await p.exists(n+"snippets")){let w=await p.list(n+"snippets");for(let m of w.files)T(m)==="css"&&h.push(m)}if(await p.exists(n+"plugins")){let w=await p.list(n+"plugins");for(let m of w.folders){let v=await p.list(m);for(let E of v.files){let S=O(E);u.isPluginFile(S)&&h.push(E)}}}}}for(;h.length>0;){let f=h.pop();if(!await p.exists(f)){delete o[f],c.deleteLocalFile(f);continue}let w=await p.stat(f);if(!w||w.type!=="file"){delete o[f],c.deleteLocalFile(f);continue}let m=o[f];m||(Object.hasOwn(g,f)?m=o[f]=g[f]:m=o[f]={path:f,previouspath:"",ctime:0,mtime:0,size:0,folder:!1,hash:"",synchash:"",synctime:0});let v=Math.ceil(w.mtime),E=Math.ceil(w.ctime),S=w.size;(!m.mtime||m.mtime!==v||m.size!==w.size)&&(m.hash=""),m.mtime=v,m.ctime=E,m.size=S,c.setLocalFile(m)}}catch(g){console.error("Failed to scan config files",g)}if(l.length>0)for(let g=0;g<l.length;g++){let h=l[g],f=h.path,w=a[f],m=o[f],v=(E,S)=>(E||this.log("Accepted",f),m&&(m.synctime=Date.now(),c.setLocalFile(m)),S||(a[f]=h,c.setServerFile(h)),l.splice(g,1),c.deletePendingFile(f),!0);if(!u.allowSyncFile(f,h.folder))return v(!0);if(!zt(f))return this.log("Ignoring remote file name with illegal characters",f,!0),v(!0,!0);if(Q(f).split("/").includes(".."))return v(!0);if(!this.canSyncPath(t,f)){i++;continue}if(this.syncingPath=f,m&&!m.folder&&!m.hash){this.log("Checking",f);let E=await p.readBinary(f);m.hash=await xe(E),c.setLocalFile(m)}if(m&&!m.folder&&!h.folder&&m.hash===h.hash)return v(!0);for(let E=g+1;E<l.length;E++)if(l[E].path===f)return this.log("Skipped",f),v(!0,!0);if(!m)return h.deleted?v(!0):(await this.syncFileDown(e,h),v());if(m.folder&&h.folder){if(h.deleted){try{let E=await p.list(f);if(E.files.length>0||E.folders.length>0)return v(!0)}catch{}this.log("Deleting",f);try{await p.rmdir(f,!0)}catch(E){let S=(E?E.message:"")||"Failed to delete folder";this.log(S,f,!0)}}return v(!0)}if(w&&(m.folder&&w.folder||m.hash===w.hash))return h.deleted?(this.log("Deleting",f),m.folder?await this.adapter.rmdir(f,!0):await this.adapter.remove(f),delete o[f],this.stateStore.deleteLocalFile(f),v()):(await this.syncFileDown(e,h),v());if(!m.folder&&h.folder)try{if((await p.stat(f)).type==="file"){let S=T(O(f)),_=S?f.substr(f.length-S.length-1):"",k=f.substr(0,f.length-_.length)+" (Conflicted copy)"+_;return this.log("Renaming conflicted file",f),await p.rename(f,k),!0}}catch{}if(h.initial&&h.mtime>m.mtime)return await this.syncFileDown(e,h),v();if(!h.initial&&!m.folder&&!h.folder&&!h.deleted&&T(f)==="md"&&h.hash!==m.synchash){this.logMerge("Merging conflicted file",f);let E=await this.adapter.read(f);if(!E)return await this.syncFileDown(e,h),v();let S="";if(w&&!w.deleted)try{S=K(await e.pull(w.uid))}catch(k){return this.logMerge("Merge failed. "+k.toString(),f,!0),v(!0)}let _;try{_=K(await e.pull(h.uid))}catch(k){return this.logMerge("Merge failed. "+k.toString(),f,!0),v(!0)}if(S===_||E===_||!_)return v();if(this.conflictStrategy==="conflict"){let k=new Date().toLocaleString("sv").replace(/[:\- ]/g,"").substring(0,12),mi=T(f),yi=Lt(f),Fi=ei(this.deviceName),bi=`${yi} (Conflicted copy ${Fi} ${k}).${mi}`;try{await p.write(bi,E,{ctime:m.ctime,mtime:m.mtime}),await p.write(f,_,{ctime:h.ctime,mtime:h.mtime}),this.logMerge("Conflicted copy stored",f)}catch{return v()}return v()}if(!S)return Math.abs(Date.now()-m.ctime)<3*60*1e3?(this.log("Downloading "+f),await p.write(f,_,{ctime:h.ctime,mtime:h.mtime}),v()):(h.mtime>m.mtime&&(this.log("Downloading "+f),await p.write(f,_,{ctime:h.ctime,mtime:h.mtime})),v());let H=Ut(S,E,_);return await p.write(f,H),this.logMerge("Merge successful",f),v()}if(!h.folder&&!h.deleted&&h.size>0&&f.startsWith(n)){if(T(f)==="json")try{this.log("Merging conflicted file",f);let E=JSON.parse(await p.read(f));if(E&&!Array.isArray(E)&&typeof E=="object"){let S=JSON.parse(K(await e.pull(h.uid)));if(S&&!Array.isArray(S)&&typeof S=="object"){for(let H in S)Object.hasOwn(S,H)&&(E[H]=S[H]);let _=L(JSON.stringify(E,void 0,2));return await p.writeBinary(f,_),this.log("Merge successful",f),v(!0)}}}catch(E){this.log("Merge failed. "+E.toString(),f,!0)}return await this.syncFileDown(e,h),v()}return this.log("Rejected server change",f),v(!0)}if(!this.ready)return!1;let d=null,F=null;for(let g in a){if(!Object.hasOwn(a,g))continue;let h=a[g];if(!Object.hasOwn(o,g)){if(h.deleted){delete a[g],c.deleteServerFile(g);continue}if(!u.allowSyncFile(g,h.folder))continue;h.folder?(!F||h.path.length>F.path.length)&&(F=h):(!d||h.path.length>d.path.length)&&(d=h)}}if(d){let g=d.path;return this.log("Deleting remote file",g),this.syncingPath=g,await e.push(g,null,!1,!0,0,0,"",null),d.deleted=!0,c.setServerFile(d),!0}if(F){let g=F.path;return this.log("Deleting remote folder",g),this.syncingPath=g,await e.push(g,null,!0,!0,0,0,"",null),F.deleted=!0,c.setServerFile(F),!0}let b=null,y=null;for(let g in o){if(!Object.hasOwn(o,g))continue;let h=o[g],f=a[g];if(!(f&&!f.deleted&&h.folder===f.folder&&h.ctime===f.ctime&&h.mtime===f.mtime&&h.size===f.size&&h.hash&&h.hash===f.hash)&&u.allowSyncFile(g,h.folder)){if(!this.canSyncPath(t,g)){i++;continue}if(process.platform==="linux"&&!h.folder&&f&&f.ctime&&(h.ctime===0||h.ctime>f.ctime)&&!f.folder&&!f.deleted&&(h.ctime=f.ctime),!h.folder&&h.size>e.perFileMax){this.logSkip(`File too large to sync (${ze(h.size)}, max ${ze(e.perFileMax)})`,g);continue}if(!f||f.deleted){if(!this.canSyncLocalFile(t,h)){i++;continue}h.folder?(!b||h.path.length<b.path.length)&&(b=h):(!y||h.size<y.size)&&(y=h);continue}if(!b){if(h.folder){if(!this.canSyncLocalFile(t,h)){i++;continue}f.folder||(!b||h.path.length<b.path.length)&&(b=h);continue}if(f.folder){if(!this.canSyncLocalFile(t,h)){i++;continue}F=f;continue}if(!h.hash||h.hash!==f.hash){if(!this.canSyncLocalFile(t,h)){i++;continue}(!y||h.size<y.size)&&(y=h)}}}}if(b){let g=b.path;return this.syncingPath=g,this.log("Uploading",g),await e.push(g,b.previouspath,!0,!1,0,0,"",null),Object.hasOwn(a,g)?a[g].deleted&&(a[g].deleted=!1):a[g]={uid:0,path:g,size:0,hash:"",ctime:0,mtime:0,folder:!0,deleted:!1,device:this.deviceName},c.setServerFile(a[g]),b.previouspath="",b.synctime=Date.now(),c.setLocalFile(b),!0}if(y){let g=y.path;this.log("New file",g),this.syncingPath=g;let h=a[g],{ctime:f,mtime:w}=y,m=await p.readBinary(g),v=y.hash=await xe(m);return c.setLocalFile(y),h&&!h.deleted&&h.hash===y.hash||(this.log("Uploading file",g),await e.push(g,y.previouspath,!1,!1,f,w,v,m),y.synchash=v,this.log("Upload complete",g),y.previouspath="",y.synctime=Date.now(),c.setLocalFile(y)),!0}return i===0?(this.log("Fully synced"),this.fileRetry={},this.continuous||this.stop(),!1):!0}onChange(e,t,i,r){if(e==="file-created"){let n=this.localFiles[t];n||(n=this.localFiles[t]={path:t,previouspath:"",folder:!1,ctime:0,mtime:0,size:0,hash:"",synctime:0,synchash:""}),r&&((n.mtime!==r.mtime||n.size!==r.size)&&(n.hash=""),n.ctime=r.ctime,n.mtime=r.mtime,n.size=r.size),this.stateStore.setLocalFile(n)}else if(e==="folder-created")this.localFiles[t]||(this.localFiles[t]={path:t,previouspath:"",folder:!0,ctime:0,mtime:0,size:0,hash:"",synctime:0,synchash:""},this.stateStore.setLocalFile(this.localFiles[t]));else if(e==="modified"){let n=this.localFiles[t];n&&r&&((n.mtime!==r.mtime||n.size!==r.size)&&(n.hash=""),n.ctime=r.ctime,n.mtime=r.mtime,n.size=r.size,this.stateStore.setLocalFile(n))}else if(e==="file-removed"||e==="folder-removed")delete this.localFiles[t],this.stateStore.deleteLocalFile(t);else if(e==="renamed"){let n=this.localFiles[i];n&&(delete this.localFiles[i],this.stateStore.deleteLocalFile(i),n.path=t,n.previouspath=i,this.localFiles[t]=n,this.stateStore.setLocalFile(n))}this.loaded&&e!=="raw"&&this.requestSync()}async syncFileDown(e,t){let i=t.path;if(this.log("Downloading",i),t.folder){await this.adapter.mkdir(i),this.log("Downloaded",i);return}let r=await e.pull(t.uid);if(!r)throw new Error("Failed to download file, no data.");let n=U(i);n&&await this.adapter.mkdir(n),await this.adapter.writeBinary(i,r,{ctime:t.ctime,mtime:t.mtime});let o=await xe(r);this.localFiles[i]&&(this.localFiles[i].hash=o,this.localFiles[i].synchash=o,this.stateStore.setLocalFile(this.localFiles[i])),this.log("Downloaded",i)}log(e,t,i=!1){i?t?console.error(e,t):console.error(e):t?console.log(e,t):console.log(e)}logMerge(e,t,i=!1){this.log(e,t,i)}logSkip(e,t){let{skippedFiles:i}=this;(!Object.hasOwn(i,t)||i[t]!==e)&&(i[t]=e,this.log(e,t,!0))}};var gi=require("commander");var ti=fetch,ii="https://"+["api","obsidian","md"].join("."),ae=class s extends Error{constructor(e){super(e.error),this.response=e,this.error=e.error,Object.setPrototypeOf(this,s.prototype)}};async function W(s,e,t){let{preflight:i,headers:r}=t||{};i&&await ti(ii+s,{method:"OPTIONS"}),r||(r={}),r["Content-Type"]="application/json";let n=await(await ti(ii+s,{method:"POST",body:JSON.stringify(e),headers:r})).json();if("error"in n)throw new ae(n);return n}async function tt(s,e,t){return W("/user/signin",{email:s,password:e,mfa:t},{preflight:!0,headers:{Origin:"https://obsidian.md"}})}function it(s){return W("/user/signout",{token:s})}function ri(s){return W("/user/info",{token:s})}function ni(s,e){return W("/vault/regions",{token:s,host:e})}function rt(s,e){return W("/vault/list",{token:s,supported_encryption_version:e})}function si(s,e,t,i,r,n){return W("/vault/create",{token:s,name:e,keyhash:t,salt:i,region:r,encryption_version:n})}function oi(s,e,t,i,r){return W("/vault/access",{token:s,vault_uid:e,keyhash:t,host:i,encryption_version:r})}var le=class s extends Error{constructor(e){super(e),Object.setPrototypeOf(this,s.prototype)}};function ai(s,e,t){return~(s-1)&e|s-1&t}function Ji(s,e){if(s.length!==e.length)return 0;let t=0;for(let i=0;i<s.length;i++)t|=s[i]^e[i];return 1&t-1>>>8}function li(s,e){return s.length===0||e.length===0?!1:Ji(s,e)!==0}function Ce(s){for(let e=0;e<s.length;e++)s[e]=0;return s}function Oe(s,e){for(let t=0;t<e.length;t++)s[t]^=e[t]}var A=class s{static{this.SIZE=16}static{this.R=135}constructor(){this.data=new Uint8Array(s.SIZE)}clear(){Ce(this.data)}clone(){let e=new s;return e.copy(this),e}copy(e){this.data.set(e.data)}dbl(){let e=0;for(let t=s.SIZE-1;t>=0;t--){let i=this.data[t]>>>7&255;this.data[t]=this.data[t]<<1|e,e=i}this.data[s.SIZE-1]^=ai(e,s.R,0),e=0}};var Y=crypto.subtle;var ce=class s{constructor(e){this.key=e}static async importKey(e,t){let i=await Y.deriveKey({name:"HKDF",salt:t,info:new TextEncoder().encode("ObsidianAesSivEnc"),hash:"SHA-256"},e,{name:"AES-CTR",length:256},!1,["encrypt"]);return new s(i)}async encryptCtr(e,t){let i=await Y.encrypt({name:"AES-CTR",counter:e,length:16},this.key,t);return new Uint8Array(i)}};var ue=class s{constructor(e){this._key=e;this._iv=new A;this._emptyPromise=Promise.resolve(this)}static async importKey(e,t){let i=await Y.deriveKey({name:"HKDF",salt:t,info:new TextEncoder().encode("ObsidianAesSivMac"),hash:"SHA-256"},e,{name:"AES-CBC",length:256},!1,["encrypt"]);return new s(i)}clear(){return this}async encryptBlock(e){let t={name:"AES-CBC",iv:this._iv.data},i=await Y.encrypt(t,this._key,e.data);return e.data.set(new Uint8Array(i,0,A.SIZE)),this._emptyPromise}};var fe=class s{constructor(e,t,i){this._cipher=e;this._subkey1=t;this._subkey2=i;this._bufferPos=0;this._finished=!1;this._buffer=new A}static async importKey(e,t){let i=await ue.importKey(e,t),r=new A;await i.encryptBlock(r),r.dbl();let n=r.clone();return n.dbl(),()=>new s(i,r,n)}async update(e){if(this._finished)throw new Error("Cannot update finished CMAC");let t=A.SIZE-this._bufferPos,i=0,r=e.length;if(r>t){for(let n=0;n<t;n++)this._buffer.data[this._bufferPos+n]^=e[n];r-=t,i+=t,await this._cipher.encryptBlock(this._buffer),this._bufferPos=0}for(;r>A.SIZE;){for(let n=0;n<A.SIZE;n++)this._buffer.data[n]^=e[i+n];r-=A.SIZE,i+=A.SIZE,await this._cipher.encryptBlock(this._buffer)}for(let n=0;n<r;n++)this._buffer.data[this._bufferPos++]^=e[i+n];return this}async finish(){if(!this._finished){let e=this._bufferPos<A.SIZE?this._subkey2:this._subkey1;Oe(this._buffer.data,e.data),this._bufferPos<A.SIZE&&(this._buffer.data[this._bufferPos]^=128),await this._cipher.encryptBlock(this._buffer),this._finished=!0}return this._buffer.data}};var he=class s{static async importKey(e,t){let i=await fe.importKey(e,t),r=await ce.importKey(e,t);return new s(i,r)}constructor(e,t){this.cmacFactory=e,this._ctr=t}async seal(e){let t=A.SIZE+e.length,i=new Uint8Array(t),r=await this._s2v(e);return i.set(r),ci(r),i.set(await this._ctr.encryptCtr(r,e),r.length),i}async open(e){if(e.length<A.SIZE)throw new le("AES-SIV: ciphertext is truncated");let t=e.subarray(0,A.SIZE),i=new Uint8Array(A.SIZE);i.set(t),ci(i);let r=await this._ctr.encryptCtr(i,e.subarray(A.SIZE)),n=await this._s2v(r);if(!li(n,t))throw Ce(r),new le("AES-SIV: ciphertext verification failure!");return r}async _s2v(e){let t=this.cmacFactory(),i=new A,r=new A;if(await t.update(i.data),r.data.set(await t.finish()),t=this.cmacFactory(),i.clear(),e.length>=A.SIZE){let n=e.length-A.SIZE;i.data.set(e.subarray(n)),await t.update(e.subarray(0,n))}else i.data.set(e),i.data[e.length]=128,r.dbl();return Oe(i.data,r.data),await t.update(i.data),t.finish()}};function ci(s){s[s.length-8]&=127,s[s.length-4]&=127}var lt=3,ct=3,ui=32,nt=32768,st=8,fi=1,Zi={N:nt,r:st,p:fi,maxmem:128*nt*st*2};async function ut(s,e){s=s.normalize("NFKC"),e=e.normalize("NFKC");let t=require&&require("crypto");if(t){let r=await new Promise((n,o)=>{t.scrypt(Buffer.from(s,"utf8"),Buffer.from(e,"utf8"),ui,Zi,(a,l)=>{a?o(a):n(l)})});return re(r)}let i=await window.scrypt.scrypt(new Uint8Array(L(s)),new Uint8Array(L(e)),nt,st,fi,ui);return se(i)}async function hi(s,e,t){switch(s){case 0:return ot.init(e);case 2:case 3:return at.init(e,t,s);default:throw new Error("Encryption version not supported")}}async function ft(s,e,t){switch(t){case 0:return R(await oe(s));case 2:case 3:let i=await x.importKey("raw",s,"HKDF",!1,["deriveKey"]),r=await x.deriveKey({name:"HKDF",salt:L(e),info:L("ObsidianKeyHash"),hash:"SHA-256"},i,{name:"AES-CBC",length:256},!0,["encrypt"]);return R(await x.exportKey("raw",r));default:throw new Error("Encryption version not supported")}}var ot=class s{constructor(e,t){this.encryptionVersion=0;this.keyHash=e,this.cryptoKey=t}static async init(e){if(e.byteLength!==32)throw new Error("Invalid encryption key");let t=R(await oe(e)),i=await Ht(e);return new s(t,i)}async deterministicEncodeStr(e){let t=L(e),i=await oe(t),r=new Uint8Array(i,0,12);return R(await _e(t,this.cryptoKey,r))}async deterministicDecodeStr(e){let t=Ze(e);return K(await Te(t,this.cryptoKey))}async encrypt(e){return _e(e,this.cryptoKey)}async decrypt(e){return Te(e,this.cryptoKey)}},at=class s{constructor(e,t,i,r){if(this.keyHash=e,this.cryptoKey=t,this.siv=i,r!==2&&r!==3)throw new Error("Invalid encryption version");this.encryptionVersion=r}static async init(e,t,i){if(e.byteLength!==32)throw new Error("Invalid encryption key");let r=await x.importKey("raw",e,"HKDF",!1,["deriveKey"]),n=L(t),o=await x.deriveKey({name:"HKDF",salt:n,info:L("ObsidianKeyHash"),hash:"SHA-256"},r,{name:"AES-CBC",length:256},!0,["encrypt"]),a=R(await x.exportKey("raw",o)),l=await he.importKey(r,n),c=await x.deriveKey({name:"HKDF",salt:new Uint8Array,info:L("ObsidianAesGcm"),hash:"SHA-256"},r,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"]);return new s(a,c,l,i)}async deterministicEncodeStr(e){let t=L(e),i=await this.siv.seal(new Uint8Array(t));return R(se(i))}async deterministicDecodeStr(e){let t=Ze(e),i=await this.siv.open(new Uint8Array(t));return K(se(i))}async encrypt(e){return _e(e,this.cryptoKey)}async decrypt(e){return Te(e,this.cryptoKey)}};var Re=class{constructor(e,t,i){this.refreshTimer=null;this.lockTime=0;this.fs=e,this.path=t,this.lockPath=i}acquire(){let{fs:e,lockPath:t}=this,i=this.path.dirname(t);e.mkdirSync(i,{recursive:!0});try{e.mkdirSync(t)}catch(r){if(r.code!=="EEXIST")throw r;let n;try{n=e.statSync(t).mtimeMs}catch(o){if(o.code==="ENOENT")return this.acquire();throw o}if(Date.now()-n<5e3)throw new J}if(this.lockTime=pi(),this.touch(),!this.verify())throw new J;this.refreshTimer=setInterval(()=>{this.lockTime=pi(),this.touch()},1e3)}release(){this.refreshTimer&&(clearInterval(this.refreshTimer),this.refreshTimer=null);try{this.verify()&&this.fs.rmdirSync(this.lockPath)}catch{}}touch(){try{let e=this.lockTime/1e3;this.fs.utimesSync(this.lockPath,e,e)}catch{}}verify(){try{let e=this.fs.statSync(this.lockPath).mtimeMs;return e===this.lockTime||Math.floor(e/1e3)===Math.floor(this.lockTime/1e3)}catch{return!1}}},J=class extends Error{constructor(){super("Failed to acquire lock.")}};function pi(){let s=Date.now();return s%1e3===0&&(s+=1),s}var C=new gi.Command,Z="ob";C.name(Z).description("Headless client for Obsidian services").version("1.0.0");C.command("login").description("Login to Obsidian account or display login status").option("--email <email>","Email address (prompted if omitted)").option("--password <password>","Password (prompted if omitted)").option("--mfa <code>","MFA code (prompted if omitted)").action(async s=>{try{let e=await I.getToken();if(e&&!s.email&&!s.password){let n=await ri(e);if(n){console.log(`Logged in as ${n.name} (${n.email})`);return}}if(e){try{await it(e)}catch{}await I.deleteToken()}let t=s.email||await pe("Email: ",!0),i=s.password||await pe("Password: "),r;try{r=await tt(t,i,s.mfa||"")}catch(n){if(n instanceof ae&&n.error.includes("2FA code")){if(n.error.includes("2FA code is incorrect"))throw n;let o=await pe("2FA code: ");r=await tt(t,i,o)}else throw n}await I.setToken(r.token),console.log(`Logged in as ${r.name} (${r.email})`)}catch(e){console.error("Login failed:",e.message||e),process.exit(2)}});C.command("logout").description("Logout from Obsidian account").action(async()=>{try{let s=await I.getToken();if(!s){console.log("No account logged in.");return}try{await it(s)}catch{}await I.deleteToken(),console.log("Logged out.")}catch(s){console.error("Logout failed:",s.message||s),process.exit(1)}});C.command("sync-list-remote").description("List available remote vaults").action(async()=>{try{let s=await Ne();console.log("Fetching vaults...");let e=await rt(s,ct);if(e.vaults.length===0&&e.shared.length===0){console.log("No vaults found.");return}console.log(`
7
+ `}return i.join("").replace(/%20/g," ")}};function Vt(s,e,t){let i=new me,r=i.diff_main(s,e,!0,0);r.length>2&&(i.diff_cleanupSemantic(r),i.diff_cleanupEfficiency(r));let n=i.patch_make(s,r);return i.patch_apply(n,t)[0]}var ye=["bmp","png","jpg","jpeg","gif","svg","webp","avif"],Fe=["mp3","wav","m4a","3gp","flac","ogg","oga","opus"],be=["mp4","webm","ogv","mov","mkv"],we=["pdf"],jt=["md"],Ye=["canvas"],qt=["base"];var Pr=jt.concat(Ye,qt),Ar=[].concat(ye,Fe,be,we,jt,Ye);var _r=[...ye,...Fe,...be,...we,...qt,...Ye];var ve=class{constructor(e){this.allowTypes=new Set(K);this.allowSpecialFiles=new Set(Me);this.ignoreFolders=[];this.filterCache={};this.configDir=e}init(e,t,i){this.filterCache={},this.allowTypes=new Set(e||K),this.allowSpecialFiles=new Set(t||[]),this.ignoreFolders=i||[]}clear(){this.filterCache={},this.allowTypes=new Set(K),this.allowSpecialFiles=new Set(Me),this.ignoreFolders=[]}clearCache(){this.filterCache={}}allowSyncFile(e,t){let{filterCache:i}=this;return Object.hasOwn(i,e)?i[e]:i[e]=this._allowSyncFile(e,t)}_allowSyncFile(e,t){for(let n of this.ignoreFolders)if(t&&e===n||e.startsWith(n+"/"))return!1;if(!t&&e.startsWith(this.configDir+"/")){let n=e.substring((this.configDir+"/").length),o=n.split("/");if(o.some(c=>c==="node_modules"||c.startsWith(".")))return!1;let a=C(n),l=T(a),u=null;return n==="workspace.json"||n==="workspace-mobile.json"?!1:(n==="app.json"||n==="types.json"?u="app":n==="appearance.json"?u="appearance":n==="hotkeys.json"?u="hotkey":n==="core-plugins.json"||n==="core-plugins-migration.json"?u="core-plugin":n==="community-plugins.json"?u="community-plugin":o[0]==="themes"&&o.length===3&&(a==="theme.css"||a==="manifest.json")||o[0]==="snippets"&&o.length===2&&l==="css"?u="appearance-data":o.length===1&&l==="json"?u="core-plugin-data":o[0]==="plugins"&&o.length===3&&this.isPluginFile(a)&&(u="community-plugin-data"),u&&this.allowSpecialFiles.has(u))}if(e.startsWith("."))return!1;if(t)return!0;if(e.startsWith("."))return!1;let i=T(C(e));if(i==="md"||i==="canvas"||i==="base")return!0;let{allowTypes:r}=this;return ye.includes(i)?r.has("image"):i==="webm"?r.has("audio")||r.has("video"):Fe.includes(i)?r.has("audio"):be.includes(i)?r.has("video"):we.includes(i)?r.has("pdf"):!!r.has("unsupported")}isPluginFile(e){return e==="manifest.json"||e==="main.js"||e==="styles.css"||e==="data.json"}};var ie=class{constructor(){this.promise=Promise.resolve()}queue(e){let t=this.promise.then(e,e);return this.promise=t,t}};function Se(){let s={promise:null,resolve:null,reject:null};return s.promise=new Promise((e,t)=>{s.resolve=e,s.reject=t}),s}var Je=WebSocket,Kt=URL,Ni=Object.getOwnPropertyDescriptor(Kt.prototype,"hostname").get,ki=String.prototype.endsWith,Wt={1e3:"Disconnected",1001:"Going Away",1002:"Protocol Error",1003:"Unsupported Data",1004:"(For future)",1005:"No Status Received",1006:"Disconnected",1007:"Invalid frame payload data",1008:"Policy Violation",1009:"Message too big",1010:"Missing Extension",1011:"Internal Error",1012:"Service Restart",1013:"Try Again Later",1014:"Bad Gateway",1015:"TLS Handshake"};function Mi(s){if(s>=0&&s<=999)return"(Unused)";if(s>=1016){if(s<=1999)return"(For WebSocket standard)";if(s<=2999)return"(For WebSocket extensions)";if(s<=3999)return"(For libraries and frameworks)";if(s<=4999)return"(For applications)"}return Wt.hasOwnProperty(s)?Wt[s]:"(Unknown)"}var Bi=20*1e3,Ui=10*1e3,Vi=2*60*1e3,Ee=class{constructor(e){this.socket=null;this.queue=new ie;this.notifyQueue=new ie;this.dataQueue=[];this.onDisconnect=null;this.perFileMax=199*1024*1024;this.userId=-1;this.justPushed=null;this.encryptionProvider=e}isConnecting(){let{socket:e}=this;return e&&e.readyState===Je.CONNECTING}isConnected(){let{socket:e}=this;return e&&e.readyState===Je.OPEN}hasConnection(){let{socket:e}=this;return!!e}async connect(e,t,i,r,n,o,a,l){if(this.hasConnection())return;this.onReady=a,this.onPush=l;let u=this.encryptionProvider.keyHash;return new Promise((c,p)=>{let d=new Kt(e),F=Ni.call(d);if(!ki.call(F,".obsidian.md")&&F!=="127.0.0.1")return p(new Error("Unable to connect to server."));let b=!1,y=h=>{b||(b=!0,this.disconnect(),p(h))},g=this.socket=new Je(d);g.binaryType="arraybuffer",g.onclose=h=>{h.code===1006?y(new Error("Unable to connect to server.")):y(new Error("Disconnected. Code: "+h.code+" "+Mi(h.code)))},g.onopen=()=>{this.lastMessageTs=Date.now(),this.heartbeat=setInterval(()=>{let h=Date.now()-this.lastMessageTs;if(h>Vi){this.disconnect();return}h>Ui&&this.send({op:"ping"})},Bi),this.send({op:"init",token:t,id:i,keyhash:u,version:r,initial:n,device:o,encryption_version:this.encryptionProvider.encryptionVersion})},g.onmessage=h=>{let f=h.data;if(typeof f!="string")return y(new Error("Server returned binary"));let v;try{v=JSON.parse(f)}catch(m){return console.error(m),y(new Error("Server JSON failed to parse: "+f))}if(v.op!=="pong"){if(v.status==="err"||v.res==="err")return y(new Error("Failed to authenticate: "+v.msg));if(v.res!=="ok")return y(new Error("Did not respond to login request: "+f));if(v.hasOwnProperty("perFileMax")){let m=v.perFileMax;if(!Number.isInteger(m)||isNaN(m)||m<0)return y(new Error("Unexpected value from server for max file size"));this.perFileMax=m}v.userId&&(this.userId=v.userId),c(),b=!0,g.onmessage=this.onMessage.bind(this),g.onclose=this.disconnect.bind(this),g.onerror=this.disconnect.bind(this)}}})}disconnect(){let e=!1;this.socket&&(this.socket.close(),this.socket=null,e=!0),this.heartbeat&&(clearInterval(this.heartbeat),this.heartbeat=null),this.responsePromise&&(this.responsePromise.reject(new Error("Disconnected")),this.responsePromise=null),this.dataPromise&&(this.dataPromise.reject(new Error("Disconnected")),this.dataPromise=null),e&&this.onDisconnect&&this.onDisconnect()}async pull(e){return this.queue.queue(async()=>{this.lastNetworkRequestTs=Date.now(),this.dataQueue.length=0;let t=await this.request({op:"pull",uid:e});if(!t.deleted){let i=t.size,r=t.pieces,n=new ArrayBuffer(i),o=0;for(let a=0;a<r;a++){let l=await this.dataResponse();new Uint8Array(n,o,l.byteLength).set(new Uint8Array(l)),o+=l.byteLength}return n.byteLength>0&&(n=await this.encryptionProvider.decrypt(n)),n}return null})}async push(e,t,i,r,n,o,a,l){return this.queue.queue(async()=>{this.lastNetworkRequestTs=Date.now();let u=await this.encryptionProvider.deterministicEncodeStr(e),c=t?await this.encryptionProvider.deterministicEncodeStr(t):null,p=i?"":T(C(e));if(i||r){this.justPushed={path:u,folder:i,deleted:r,mtime:0,hash:""},await this.request({op:"push",path:u,relatedpath:c,extension:p,hash:"",ctime:0,mtime:0,folder:i,deleted:r});return}l.byteLength>0&&(l=await this.encryptionProvider.encrypt(l)),a&&(a=await this.encryptionProvider.deterministicEncodeStr(a));let d=l.byteLength,F=2*1024*1024,b=Math.ceil(d/F);if(this.justPushed={path:u,folder:i,deleted:r,mtime:o,hash:a},(await this.request({op:"push",path:u,relatedpath:c,extension:p,hash:a,ctime:n,mtime:o,folder:i,deleted:r,size:d,pieces:b})).res==="ok"){this.justPushed=null;return}for(let g=0;g<b;g++){let h=g*F,f=Math.min(F,d-h);this.sendBinary(new Uint8Array(l,h,f)),await this.response()}this.justPushed=null})}async listDeleted(){return this.queue.queue(async()=>{let t=(await this.request({op:"deleted",suppressrenames:!0})).items;for(let i of t)i.path=await this.encryptionProvider.deterministicDecodeStr(i.path);return t})}async listHistory(e,t){return this.queue.queue(async()=>{let i=await this.encryptionProvider.deterministicEncodeStr(e),r=await this.request({op:"history",path:i,last:t}),n=r.items;for(let o of n)o.path=await this.encryptionProvider.deterministicDecodeStr(o.path),o.relatedpath=o.relatedpath&&await this.encryptionProvider.deterministicDecodeStr(o.relatedpath);return r})}async restore(e){return this.queue.queue(async()=>this.request({op:"restore",uid:e}))}async getUsernames(){return this.queue.queue(()=>this.request({op:"usernames"}))}async purge(){return this.queue.queue(()=>this.request({op:"purge"}))}async size(){return this.queue.queue(()=>this.request({op:"size"}))}onServerPush(e){let{justPushed:t}=this;t&&t.path===e.path&&t.folder===e.folder&&t.deleted===e.deleted&&t.mtime===e.mtime&&t.hash===e.hash&&(this.justPushed=null,e.wasJustPushed=!0),this.notifyQueue.queue(async()=>{e.path=await this.encryptionProvider.deterministicDecodeStr(e.path),e.hash&&(e.hash=await this.encryptionProvider.deterministicDecodeStr(e.hash)),this.onPush(e)})}response(){return(this.responsePromise=Se()).promise}dataResponse(){return this.dataQueue.length>0?Promise.resolve(this.dataQueue.shift()):(this.dataPromise=Se()).promise}async request(e,t=6e4){let i=this.responsePromise=Se();this.send(e);let r=new Error("Timeout"),n=setTimeout(()=>i.reject(r),t),o;try{o=await i.promise,clearTimeout(n)}catch(a){throw a===r&&this.disconnect(),a}if(o.err)throw new Error(o.err);return o}onMessage(e){if(this.lastMessageTs=Date.now(),typeof e.data=="string"){let t;try{t=JSON.parse(e.data)}catch{console.log(e.data),this.disconnect();return}let i=t.op;if(i==="pong")return;if(i==="ready"){this.notifyQueue.queue(async()=>{this.onReady(t.version)});return}if(i==="push"){this.onServerPush(t);return}let r=this.responsePromise;r&&(this.responsePromise=null,r.resolve(t))}else{let t=this.dataPromise;t?(this.dataPromise=null,t.resolve(e.data)):this.dataQueue.push(e.data)}}send(e){this.socket.send(JSON.stringify(e))}sendBinary(e){this.socket.send(e)}};var De=class{constructor(e,t,i,r){this.min=e||0,this.max=t||Number.MAX_VALUE,this.base=i||1e3,this.jitter=r||!0,this.count=0,this.nextTs=Date.now()}success(){this.count=0,this.nextTs=Date.now()+this.getTimeout()}fail(){this.count++,this.nextTs=Date.now()+this.getTimeout()}getTimeout(){if(this.count===0)return this.min;let e=this.count-1,t=this.base*Math.pow(2,e);if(this.jitter){let i=.5;t=t*(1-i+i*Math.random())}return t=Math.floor(Math.min(this.max,this.min+t)),t}getNextTs(){return this.nextTs}isReady(){return Date.now()>this.nextTs}};var Ht=crypto,x=Ht.subtle,Ze="AES-GCM";function Gt(s){return x.importKey("raw",s,Ze,!1,["encrypt","decrypt"])}async function Pe(s,e,t){t||(t=Ht.getRandomValues(new Uint8Array(12)));let i=await x.encrypt({name:Ze,iv:t},e,s),r=new ArrayBuffer(t.byteLength+i.byteLength),n=new Uint8Array(r);return n.set(new Uint8Array(t),0),n.set(new Uint8Array(i),t.byteLength),r}async function Ae(s,e){if(s.byteLength<12)throw new Error("Encrypted data is bad");if(s.byteLength===12)return new ArrayBuffer(0);let t=new Uint8Array(s,0,12),i=new Uint8Array(s,12);return await x.decrypt({name:Ze,iv:t},e,i)}function re(s){return s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength)}function I(s){return re(new TextEncoder().encode(s))}function V(s){return new TextDecoder().decode(new Uint8Array(s))}function $t(s){let e=atob(s),t=e.length,i=new Uint8Array(t);for(let r=0;r<t;r++)i[r]=e.charCodeAt(r);return i.buffer}function Qt(s){return ji(new Uint8Array(s))}function ji(s){let e=[],t=s.byteLength;for(let i=0;i<t;i++)e.push(String.fromCharCode(s[i]));return btoa(e.join(""))}async function _e(s){return O(await ne(s))}async function ne(s){return x.digest("SHA-256",new Uint8Array(s))}function ze(s){let e=s.length/2,t=new ArrayBuffer(e),i=new Uint8Array(t);for(let r=0;r<e;r++)i[r]=parseInt(s.substr(r*2,2),16);return t}function O(s){let e=new Uint8Array(s),t=[];for(let i=0;i<e.length;i++){let r=e[i];t.push((r>>>4).toString(16)),t.push((r&15).toString(16))}return t.join("")}function et(s){if(s<=0)return"0 B";let e=["B","KB","MB","GB","TB","PB"],t=e.length-1,i=1024;for(let n=0;n<e.length;n++)if(s<Math.pow(i,n+1)){t=n;break}let r=s/Math.pow(i,t);return`${qi(r,t===0?0:2)} ${e[t]}`}function qi(s,e=2,t=".",i=","){let r=s<0?"-":"";s=Math.abs(s);let n=parseInt(s.toFixed(e),10)+"",o=n.length>3?n.length%3:0;return r+(o?n.substr(0,o)+i:"")+n.substr(o).replace(/(\d{3})(?=\d)/g,"$1"+i)+(e?t+Math.abs(s-Math.floor(s)).toFixed(e).slice(2):"")}var Wi=function(){let s=typeof process<"u"?process.platform:"";if(s==="win32")return"win";if(s==="darwin")return"mac";if(s==="linux")return"linux";if(s)return"unknown";let e=navigator.userAgent;return e.indexOf("Win")!==-1?"win":e.indexOf("Mac")!==-1?"mac":e.indexOf("X11")!==-1||e.indexOf("Linux")!==-1?"linux":"unknown"}(),Xt=navigator.userAgent.toLowerCase();var tt=Wi==="win";var $r=/^((?!chrome|android).)*safari/i.test(Xt),Yt=/android/i.test(Xt);var Ki=/[.?*+^$[\]\\(){}|-]/g;function Te(s){return s.replace(Ki,"\\$&")}var Hi="\\/:"+(Yt?'*?<>"':""),Gi='*"\\/<>:|?',Jt="#^[]|",Zt=tt?Gi:Hi,$i=Zt.split("").join("\xA0"),zr=Jt.split("").join("\xA0"),zt=new RegExp("["+Te(Zt)+"]"),en=new RegExp("["+Te(Jt)+"]"),Qi=/^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i;function ei(s){try{return Xi(s),!0}catch{return!1}}function Xi(s){if(tt){let e=s.charAt(s.length-1);if(e==="."||e===" ")throw new Error("File names cannot end with a dot or a space.");let t=It(s);if(Qi.test(t))throw new Error("File name is forbidden: "+t)}if(s.split("/").some(e=>zt.test(e)))throw new Error("File name cannot contain any of the following characters: "+$i)}function ti(s,e="_"){let t=s.trim();if(t&&(t=s.replace(zt,e),e.length===1)){let i=Te(e),r=new RegExp(`${i}{2,}`,"g");t=t.replace(r,e)}return t}function Yi(s){return new Promise(e=>setTimeout(e,s))}var xe=class{constructor(e){this.server=null;this.localFiles={};this.serverFiles={};this.newServerFiles=[];this.version=0;this.initial=!0;this.ready=!1;this.syncing=!1;this.loaded=!1;this.backoff=new De(0,5*60*1e3,5e3,!0);this.fileRetry={};this.skippedFiles={};this.syncingPath="";this.scanSpecialFiles=!1;this.scanSpecialFileQueue=[];this.resolveStop=null;let{config:t}=e;this.host=t.host,this.token=e.token,this.vaultId=t.vaultId,this.continuous=e.continuous||!1,this.encryption=e.encryption;let i=vt(t.vaultId);this.stateStore=new de(i),this.conflictStrategy=t.conflictStrategy||"merge",this.deviceName=t.deviceName||"Sync Client",this.adapter=new ge(E.default,D.default,Re.default,()=>!1,yt,"file:///",t.vaultPath),this.filter=new ve(t.configDir),this.filter.init(t.allowTypes||[],t.allowSpecialFiles||[],t.ignoreFolders||[]),this.loadState()}loadState(){this.version=this.stateStore.getVersion(),this.initial=this.stateStore.isInitial(),this.localFiles=this.stateStore.getAllLocalFiles(),this.serverFiles=this.stateStore.getAllServerFiles(),this.newServerFiles=this.stateStore.getPendingFiles()}handlePush(e){if(this.version=e.uid,this.initial&&e.deleted){this.stateStore.setVersion(this.version);return}let t=e.path,i={path:t,size:e.size,hash:e.hash,ctime:e.ctime,mtime:e.mtime,folder:e.folder,deleted:e.deleted,uid:e.uid,device:e.device,user:e.user};this.initial&&(i.initial=!0);let{newServerFiles:r}=this;if(e.wasJustPushed){for(let n=0;n<r.length;n++)r[n].path===t&&(r.splice(n,1),n-=1);this.stateStore.deletePendingFile(t),this.serverFiles[t]=i,this.stateStore.setServerFile(i),this.stateStore.setVersion(this.version);return}r.push(i),this.stateStore.addPendingFile(i),this.stateStore.setVersion(this.version),this.initial||console.debug(`Push: ${i.path} (${i.deleted?"deleted":"updated"})`),this.requestSync()}async sync(){let e=new Promise(i=>this.resolveStop=i),t=setInterval(this.requestSync.bind(this),30*1e3);try{if(!this.loaded){await this.adapter.watch(this.onChange.bind(this));for(let i in this.localFiles)Object.hasOwn(this.adapter.files,i)||(delete this.localFiles[i],this.stateStore.deleteLocalFile(i));this.scanSpecialFiles=!0,this.loaded=!0}await this.requestSync(),await e}finally{clearInterval(t)}}stop(){this.server&&(this.server.disconnect(),this.server=null),this.ready=!1,this.continuous=!1,this.stateStore.close(),this.adapter.stopWatch(),this.adapter.thingsHappening.cancel(),this.resolveStop&&(this.resolveStop(),this.resolveStop=null)}async requestSync(){if(!this.syncing){this.syncing=!0;try{let e=!0;for(;e;){try{this.syncingPath="",e=await this._sync();let i=this.syncingPath;i&&delete this.fileRetry[i]}catch(i){if(console.error("Sync error:",i),this.failedSync(this.syncingPath),e=!1,!this.continuous)throw this.syncing=!1,i}if(!e)return;let t=0;if(this.server){let i=Date.now()-this.server.lastNetworkRequestTs;t=Math.max(0,50-i)}await Yi(t)}}finally{this.syncing=!1}}}canSyncPath(e,t){let{fileRetry:i}=this;for(let r in i)if(i.hasOwnProperty(r)&&i[r].ts>e&&t.startsWith(r))return!1;return!0}canSyncLocalFile(e,t){if(!t.synctime)return!0;let i=t.size,r=i>10*1024,n=i>100*1024,o=r?n?30:20:10;return e-t.synctime>o*1e3}failedSync(e){if(!e)return;let t=Date.now(),i=this.fileRetry[e];i||(i=this.fileRetry[e]={count:0,ts:0});let r=i.count=i.count+1,n=Math.pow(2,r)*5*1e3;n=Math.min(n,5*60*1e3),i.ts=t+n}async getServer(){let{server:e}=this;if(e&&!e.isConnected()&&!e.isConnecting()&&(e.disconnect(),e=this.server=null,this.backoff.fail()),!e){if(!this.backoff.isReady())return this.log("Waiting to connect to server"),null;e=this.server=new Ee(this.encryption)}if(!e.hasConnection()){this.log("Connecting..."),this.ready=!1;try{let t=this.host.startsWith("127.0.0.1")||this.host.startsWith("localhost")?"ws://":"wss://";e.onDisconnect=()=>{this.ready=!1,this.log("Disconnected from server"),this.continuous&&this.requestSync()},await e.connect(t+this.host,this.token,this.vaultId,this.version,this.initial,this.deviceName,i=>{this.ready=!0,this.initial=!1,this.stateStore.setInitial(!1),this.version<i&&(this.version=i,this.stateStore.setVersion(this.version)),this.requestSync()},i=>this.handlePush(i)),this.log("Connection successful. Detecting changes..."),this.backoff.success()}catch(t){if(t.message&&t.message.includes("Your subscription to Obsidian Sync has expired"))throw console.error(t.message),this.stop(),t;if(t.message&&t.message.includes("Vault not found"))throw console.error("The connected remote vault no longer exists."),this.stop(),t;return console.error(t),e.disconnect(),e=this.server=null,this.backoff.fail(),null}}return e}async _sync(){let e=await this.getServer();if(!e)return!1;let t=Date.now(),i=0,r=this.filter.configDir,n=r+"/",{localFiles:o,serverFiles:a,newServerFiles:l,stateStore:u,filter:c,adapter:p}=this;try{let g={},h=this.scanSpecialFileQueue;if(this.scanSpecialFiles){this.scanSpecialFiles=!1,h=this.scanSpecialFileQueue=[];for(let f in o)Object.hasOwn(o,f)&&f.startsWith(".")&&(g[f]=o[f],delete o[f],u.deleteLocalFile(f));if(c.allowSpecialFiles.size>0&&await p.exists(r)){h.push(n+"config");let f=await p.list(r);for(let v of f.files)T(v)==="json"&&h.push(v);if(await p.exists(n+"themes")){let v=await p.list(n+"themes");for(let m of v.folders){let S=await p.list(m);for(let w of S.files){let P=C(w);(P==="manifest.json"||P==="theme.css")&&h.push(w)}}}if(await p.exists(n+"snippets")){let v=await p.list(n+"snippets");for(let m of v.files)T(m)==="css"&&h.push(m)}if(await p.exists(n+"plugins")){let v=await p.list(n+"plugins");for(let m of v.folders){let S=await p.list(m);for(let w of S.files){let P=C(w);c.isPluginFile(P)&&h.push(w)}}}}}for(;h.length>0;){let f=h.pop();if(!await p.exists(f)){delete o[f],u.deleteLocalFile(f);continue}let v=await p.stat(f);if(!v||v.type!=="file"){delete o[f],u.deleteLocalFile(f);continue}let m=o[f];m||(Object.hasOwn(g,f)?m=o[f]=g[f]:m=o[f]={path:f,previouspath:"",ctime:0,mtime:0,size:0,folder:!1,hash:"",synchash:"",synctime:0});let S=Math.ceil(v.mtime),w=Math.ceil(v.ctime),P=v.size;(!m.mtime||m.mtime!==S||m.size!==v.size)&&(m.hash=""),m.mtime=S,m.ctime=w,m.size=P,u.setLocalFile(m)}}catch(g){console.error("Failed to scan config files",g)}if(l.length>0)for(let g=0;g<l.length;g++){let h=l[g],f=h.path,v=a[f],m=o[f],S=(w,P)=>(w||this.log("Accepted",f),m&&(m.synctime=Date.now(),u.setLocalFile(m)),P||(a[f]=h,u.setServerFile(h)),l.splice(g,1),u.deletePendingFile(f),!0);if(!c.allowSyncFile(f,h.folder))return S(!0);if(!ei(f))return this.log("Ignoring remote file name with illegal characters",f,!0),S(!0,!0);if(H(f).split("/").includes(".."))return S(!0);if(!this.canSyncPath(t,f)){i++;continue}if(this.syncingPath=f,m&&!m.folder&&!m.hash){this.log("Checking",f);let w=await p.readBinary(f);m.hash=await _e(w),u.setLocalFile(m)}if(m&&!m.folder&&!h.folder&&m.hash===h.hash)return S(!0);for(let w=g+1;w<l.length;w++)if(l[w].path===f)return this.log("Skipped",f),S(!0,!0);if(!m)return h.deleted?S(!0):(await this.syncFileDown(e,h),S());if(m.folder&&h.folder){if(h.deleted){try{let w=await p.list(f);if(w.files.length>0||w.folders.length>0)return S(!0)}catch{}this.log("Deleting",f);try{await p.rmdir(f,!0)}catch(w){let P=(w?w.message:"")||"Failed to delete folder";this.log(P,f,!0)}}return S(!0)}if(v&&(m.folder&&v.folder||m.hash===v.hash))return h.deleted?(this.log("Deleting",f),m.folder?await this.adapter.rmdir(f,!0):await this.adapter.remove(f),delete o[f],this.stateStore.deleteLocalFile(f),S()):(await this.syncFileDown(e,h),S());if(!m.folder&&h.folder)try{let w=await p.stat(f);if(w&&w.type==="file"){let P=T(C(f)),_=P?f.substr(f.length-P.length-1):"",R=f.substr(0,f.length-_.length)+" (Conflicted copy)"+_;return this.log("Renaming conflicted file",f),await p.rename(f,R),!0}}catch{}if(h.initial&&h.mtime>m.mtime)return await this.syncFileDown(e,h),S();if(!h.initial&&!m.folder&&!h.folder&&!h.deleted&&T(f)==="md"&&h.hash!==m.synchash){this.logMerge("Merging conflicted file",f);let w=await this.adapter.read(f);if(!w)return await this.syncFileDown(e,h),S();let P="";if(v&&!v.deleted)try{P=V(await e.pull(v.uid))}catch(R){return this.logMerge("Merge failed. "+R.toString(),f,!0),S(!0)}let _;try{_=V(await e.pull(h.uid))}catch(R){return this.logMerge("Merge failed. "+R.toString(),f,!0),S(!0)}if(P===_||w===_||!_)return S();if(this.conflictStrategy==="conflict"){let R=new Date().toLocaleString("sv").replace(/[:\- ]/g,"").substring(0,12),mi=T(f),yi=Lt(f),Fi=ti(this.deviceName),bi=`${yi} (Conflicted copy ${Fi} ${R}).${mi}`;try{await p.write(bi,w,{ctime:m.ctime,mtime:m.mtime}),await p.write(f,_,{ctime:h.ctime,mtime:h.mtime}),this.logMerge("Conflicted copy stored",f)}catch{return S()}return S()}if(!P)return Math.abs(Date.now()-m.ctime)<3*60*1e3?(this.log("Downloading "+f),await p.write(f,_,{ctime:h.ctime,mtime:h.mtime}),S()):(h.mtime>m.mtime&&(this.log("Downloading "+f),await p.write(f,_,{ctime:h.ctime,mtime:h.mtime})),S());let q=Vt(P,w,_);return await p.write(f,q),this.logMerge("Merge successful",f),S()}if(!h.folder&&!h.deleted&&h.size>0&&f.startsWith(n)){if(T(f)==="json")try{this.log("Merging conflicted file",f);let w=JSON.parse(await p.read(f));if(w&&!Array.isArray(w)&&typeof w=="object"){let P=JSON.parse(V(await e.pull(h.uid)));if(P&&!Array.isArray(P)&&typeof P=="object"){for(let q in P)Object.hasOwn(P,q)&&(w[q]=P[q]);let _=I(JSON.stringify(w,void 0,2));return await p.writeBinary(f,_),this.log("Merge successful",f),S(!0)}}}catch(w){this.log("Merge failed. "+w.toString(),f,!0)}return await this.syncFileDown(e,h),S()}return this.log("Rejected server change",f),S(!0)}if(!this.ready)return!1;let d=null,F=null;for(let g in a){if(!Object.hasOwn(a,g))continue;let h=a[g];if(!Object.hasOwn(o,g)){if(h.deleted){delete a[g],u.deleteServerFile(g);continue}if(!c.allowSyncFile(g,h.folder))continue;h.folder?(!F||h.path.length>F.path.length)&&(F=h):(!d||h.path.length>d.path.length)&&(d=h)}}if(d){let g=d.path;return this.log("Deleting remote file",g),this.syncingPath=g,await e.push(g,null,!1,!0,0,0,"",null),d.deleted=!0,u.setServerFile(d),!0}if(F){let g=F.path;return this.log("Deleting remote folder",g),this.syncingPath=g,await e.push(g,null,!0,!0,0,0,"",null),F.deleted=!0,u.setServerFile(F),!0}let b=null,y=null;for(let g in o){if(!Object.hasOwn(o,g))continue;let h=o[g],f=a[g];if(!(f&&!f.deleted&&h.folder===f.folder&&h.ctime===f.ctime&&h.mtime===f.mtime&&h.size===f.size&&h.hash&&h.hash===f.hash)&&c.allowSyncFile(g,h.folder)){if(!this.canSyncPath(t,g)){i++;continue}if(process.platform==="linux"&&!h.folder&&f&&f.ctime&&(h.ctime===0||h.ctime>f.ctime)&&!f.folder&&!f.deleted&&(h.ctime=f.ctime),!h.folder&&h.size>e.perFileMax){this.logSkip(`File too large to sync (${et(h.size)}, max ${et(e.perFileMax)})`,g);continue}if(!f||f.deleted){if(!this.canSyncLocalFile(t,h)){i++;continue}h.folder?(!b||h.path.length<b.path.length)&&(b=h):(!y||h.size<y.size)&&(y=h);continue}if(!b){if(h.folder){if(!this.canSyncLocalFile(t,h)){i++;continue}f.folder||(!b||h.path.length<b.path.length)&&(b=h);continue}if(f.folder){if(!this.canSyncLocalFile(t,h)){i++;continue}F=f;continue}if(!h.hash||h.hash!==f.hash){if(!this.canSyncLocalFile(t,h)){i++;continue}(!y||h.size<y.size)&&(y=h)}}}}if(b){let g=b.path;return this.syncingPath=g,this.log("Uploading",g),await e.push(g,b.previouspath,!0,!1,0,0,"",null),Object.hasOwn(a,g)?a[g].deleted&&(a[g].deleted=!1):a[g]={uid:0,path:g,size:0,hash:"",ctime:0,mtime:0,folder:!0,deleted:!1,device:this.deviceName},u.setServerFile(a[g]),b.previouspath="",b.synctime=Date.now(),u.setLocalFile(b),!0}if(y){let g=y.path;this.log("New file",g),this.syncingPath=g;let h=a[g],{ctime:f,mtime:v}=y,m=await p.readBinary(g),S=y.hash=await _e(m);return u.setLocalFile(y),h&&!h.deleted&&h.hash===y.hash||(this.log("Uploading file",g),await e.push(g,y.previouspath,!1,!1,f,v,S,m),y.synchash=S,this.log("Upload complete",g),y.previouspath="",y.synctime=Date.now(),u.setLocalFile(y)),!0}return i===0?(this.log("Fully synced"),this.fileRetry={},this.continuous||this.stop(),!1):!0}onChange(e,t,i,r){if(e==="file-created"){let n=this.localFiles[t];n||(n=this.localFiles[t]={path:t,previouspath:"",folder:!1,ctime:0,mtime:0,size:0,hash:"",synctime:0,synchash:""}),r&&((n.mtime!==r.mtime||n.size!==r.size)&&(n.hash=""),n.ctime=r.ctime,n.mtime=r.mtime,n.size=r.size),this.stateStore.setLocalFile(n)}else if(e==="folder-created")this.localFiles[t]||(this.localFiles[t]={path:t,previouspath:"",folder:!0,ctime:0,mtime:0,size:0,hash:"",synctime:0,synchash:""},this.stateStore.setLocalFile(this.localFiles[t]));else if(e==="modified"){let n=this.localFiles[t];n&&r&&((n.mtime!==r.mtime||n.size!==r.size)&&(n.hash=""),n.ctime=r.ctime,n.mtime=r.mtime,n.size=r.size,this.stateStore.setLocalFile(n))}else if(e==="file-removed"||e==="folder-removed")delete this.localFiles[t],this.stateStore.deleteLocalFile(t);else if(e==="renamed"){let n=this.localFiles[i];n&&(delete this.localFiles[i],this.stateStore.deleteLocalFile(i),n.path=t,n.previouspath=i,this.localFiles[t]=n,this.stateStore.setLocalFile(n))}if(e==="raw"&&t.startsWith(this.filter.configDir+"/")&&!t.endsWith(".sync.lock")){let n=this.scanSpecialFileQueue;if(n.includes(t))return;n.push(t),this.requestSync()}this.loaded&&e!=="raw"&&this.requestSync()}async syncFileDown(e,t){let i=t.path;if(this.log("Downloading",i),t.folder){await this.adapter.mkdir(i),this.log("Downloaded",i);return}let r=await e.pull(t.uid);if(!r)throw new Error("Failed to download file, no data.");let n=k(i);n&&await this.adapter.mkdir(n),await this.adapter.writeBinary(i,r,{ctime:t.ctime,mtime:t.mtime});let o=await _e(r);this.localFiles[i]&&(this.localFiles[i].hash=o,this.localFiles[i].synchash=o,this.stateStore.setLocalFile(this.localFiles[i])),this.log("Downloaded",i)}log(e,t,i=!1){i?t?console.error(e,t):console.error(e):t?console.log(e,t):console.log(e)}logMerge(e,t,i=!1){this.log(e,t,i)}logSkip(e,t){let{skippedFiles:i}=this;(!Object.hasOwn(i,t)||i[t]!==e)&&(i[t]=e,this.log(e,t,!0))}};var gi=require("commander");var ii=fetch,ri="https://"+["api","obsidian","md"].join("."),se=class s extends Error{constructor(e){super(e.error),this.response=e,this.error=e.error,Object.setPrototypeOf(this,s.prototype)}};async function j(s,e,t){let{preflight:i,headers:r}=t||{};i&&await ii(ri+s,{method:"OPTIONS"}),r||(r={}),r["Content-Type"]="application/json";let n=await(await ii(ri+s,{method:"POST",body:JSON.stringify(e),headers:r})).json();if("error"in n)throw new se(n);return n}async function it(s,e,t){return j("/user/signin",{email:s,password:e,mfa:t},{preflight:!0,headers:{Origin:"https://obsidian.md"}})}function rt(s){return j("/user/signout",{token:s})}function ni(s){return j("/user/info",{token:s})}function si(s,e){return j("/vault/regions",{token:s,host:e})}function nt(s,e){return j("/vault/list",{token:s,supported_encryption_version:e})}function oi(s,e,t,i,r,n){return j("/vault/create",{token:s,name:e,keyhash:t,salt:i,region:r,encryption_version:n})}function ai(s,e,t,i,r){return j("/vault/access",{token:s,vault_uid:e,keyhash:t,host:i,encryption_version:r})}var oe=class s extends Error{constructor(e){super(e),Object.setPrototypeOf(this,s.prototype)}};function li(s,e,t){return~(s-1)&e|s-1&t}function Ji(s,e){if(s.length!==e.length)return 0;let t=0;for(let i=0;i<s.length;i++)t|=s[i]^e[i];return 1&t-1>>>8}function ui(s,e){return s.length===0||e.length===0?!1:Ji(s,e)!==0}function Ie(s){for(let e=0;e<s.length;e++)s[e]=0;return s}function Le(s,e){for(let t=0;t<e.length;t++)s[t]^=e[t]}var A=class s{static{this.SIZE=16}static{this.R=135}constructor(){this.data=new Uint8Array(s.SIZE)}clear(){Ie(this.data)}clone(){let e=new s;return e.copy(this),e}copy(e){this.data.set(e.data)}dbl(){let e=0;for(let t=s.SIZE-1;t>=0;t--){let i=this.data[t]>>>7&255;this.data[t]=this.data[t]<<1|e,e=i}this.data[s.SIZE-1]^=li(e,s.R,0),e=0}};var $=crypto.subtle;var ae=class s{constructor(e){this.key=e}static async importKey(e,t){let i=await $.deriveKey({name:"HKDF",salt:t,info:new TextEncoder().encode("ObsidianAesSivEnc"),hash:"SHA-256"},e,{name:"AES-CTR",length:256},!1,["encrypt"]);return new s(i)}async encryptCtr(e,t){let i=await $.encrypt({name:"AES-CTR",counter:e,length:16},this.key,t);return new Uint8Array(i)}};var le=class s{constructor(e){this._key=e;this._iv=new A;this._emptyPromise=Promise.resolve(this)}static async importKey(e,t){let i=await $.deriveKey({name:"HKDF",salt:t,info:new TextEncoder().encode("ObsidianAesSivMac"),hash:"SHA-256"},e,{name:"AES-CBC",length:256},!1,["encrypt"]);return new s(i)}clear(){return this}async encryptBlock(e){let t={name:"AES-CBC",iv:this._iv.data},i=await $.encrypt(t,this._key,e.data);return e.data.set(new Uint8Array(i,0,A.SIZE)),this._emptyPromise}};var ue=class s{constructor(e,t,i){this._cipher=e;this._subkey1=t;this._subkey2=i;this._bufferPos=0;this._finished=!1;this._buffer=new A}static async importKey(e,t){let i=await le.importKey(e,t),r=new A;await i.encryptBlock(r),r.dbl();let n=r.clone();return n.dbl(),()=>new s(i,r,n)}async update(e){if(this._finished)throw new Error("Cannot update finished CMAC");let t=A.SIZE-this._bufferPos,i=0,r=e.length;if(r>t){for(let n=0;n<t;n++)this._buffer.data[this._bufferPos+n]^=e[n];r-=t,i+=t,await this._cipher.encryptBlock(this._buffer),this._bufferPos=0}for(;r>A.SIZE;){for(let n=0;n<A.SIZE;n++)this._buffer.data[n]^=e[i+n];r-=A.SIZE,i+=A.SIZE,await this._cipher.encryptBlock(this._buffer)}for(let n=0;n<r;n++)this._buffer.data[this._bufferPos++]^=e[i+n];return this}async finish(){if(!this._finished){let e=this._bufferPos<A.SIZE?this._subkey2:this._subkey1;Le(this._buffer.data,e.data),this._bufferPos<A.SIZE&&(this._buffer.data[this._bufferPos]^=128),await this._cipher.encryptBlock(this._buffer),this._finished=!0}return this._buffer.data}};var ce=class s{static async importKey(e,t){let i=await ue.importKey(e,t),r=await ae.importKey(e,t);return new s(i,r)}constructor(e,t){this.cmacFactory=e,this._ctr=t}async seal(e){let t=A.SIZE+e.length,i=new Uint8Array(t),r=await this._s2v(e);return i.set(r),ci(r),i.set(await this._ctr.encryptCtr(r,e),r.length),i}async open(e){if(e.length<A.SIZE)throw new oe("AES-SIV: ciphertext is truncated");let t=e.subarray(0,A.SIZE),i=new Uint8Array(A.SIZE);i.set(t),ci(i);let r=await this._ctr.encryptCtr(i,e.subarray(A.SIZE)),n=await this._s2v(r);if(!ui(n,t))throw Ie(r),new oe("AES-SIV: ciphertext verification failure!");return r}async _s2v(e){let t=this.cmacFactory(),i=new A,r=new A;if(await t.update(i.data),r.data.set(await t.finish()),t=this.cmacFactory(),i.clear(),e.length>=A.SIZE){let n=e.length-A.SIZE;i.data.set(e.subarray(n)),await t.update(e.subarray(0,n))}else i.data.set(e),i.data[e.length]=128,r.dbl();return Le(i.data,r.data),await t.update(i.data),t.finish()}};function ci(s){s[s.length-8]&=127,s[s.length-4]&=127}var ut=3,ct=3,fi=32,st=32768,ot=8,hi=1,Zi={N:st,r:ot,p:hi,maxmem:128*st*ot*2};async function ft(s,e){s=s.normalize("NFKC"),e=e.normalize("NFKC");let t=require&&require("crypto");if(t){let r=await new Promise((n,o)=>{t.scrypt(Buffer.from(s,"utf8"),Buffer.from(e,"utf8"),fi,Zi,(a,l)=>{a?o(a):n(l)})});return te(r)}let i=await window.scrypt.scrypt(new Uint8Array(I(s)),new Uint8Array(I(e)),st,ot,hi,fi);return re(i)}async function pi(s,e,t){switch(s){case 0:return at.init(e);case 2:case 3:return lt.init(e,t,s);default:throw new Error("Encryption version not supported")}}async function ht(s,e,t){switch(t){case 0:return O(await ne(s));case 2:case 3:let i=await x.importKey("raw",s,"HKDF",!1,["deriveKey"]),r=await x.deriveKey({name:"HKDF",salt:I(e),info:I("ObsidianKeyHash"),hash:"SHA-256"},i,{name:"AES-CBC",length:256},!0,["encrypt"]);return O(await x.exportKey("raw",r));default:throw new Error("Encryption version not supported")}}var at=class s{constructor(e,t){this.encryptionVersion=0;this.keyHash=e,this.cryptoKey=t}static async init(e){if(e.byteLength!==32)throw new Error("Invalid encryption key");let t=O(await ne(e)),i=await Gt(e);return new s(t,i)}async deterministicEncodeStr(e){let t=I(e),i=await ne(t),r=new Uint8Array(i,0,12);return O(await Pe(t,this.cryptoKey,r))}async deterministicDecodeStr(e){let t=ze(e);return V(await Ae(t,this.cryptoKey))}async encrypt(e){return Pe(e,this.cryptoKey)}async decrypt(e){return Ae(e,this.cryptoKey)}},lt=class s{constructor(e,t,i,r){if(this.keyHash=e,this.cryptoKey=t,this.siv=i,r!==2&&r!==3)throw new Error("Invalid encryption version");this.encryptionVersion=r}static async init(e,t,i){if(e.byteLength!==32)throw new Error("Invalid encryption key");let r=await x.importKey("raw",e,"HKDF",!1,["deriveKey"]),n=I(t),o=await x.deriveKey({name:"HKDF",salt:n,info:I("ObsidianKeyHash"),hash:"SHA-256"},r,{name:"AES-CBC",length:256},!0,["encrypt"]),a=O(await x.exportKey("raw",o)),l=await ce.importKey(r,n),u=await x.deriveKey({name:"HKDF",salt:new Uint8Array,info:I("ObsidianAesGcm"),hash:"SHA-256"},r,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"]);return new s(a,u,l,i)}async deterministicEncodeStr(e){let t=I(e),i=await this.siv.seal(new Uint8Array(t));return O(re(i))}async deterministicDecodeStr(e){let t=ze(e),i=await this.siv.open(new Uint8Array(t));return V(re(i))}async encrypt(e){return Pe(e,this.cryptoKey)}async decrypt(e){return Ae(e,this.cryptoKey)}};var Ce=class{constructor(e,t,i){this.refreshTimer=null;this.lockTime=0;this.isMs=!0;this.fs=e,this.path=t,this.lockPath=i}acquire(){let{fs:e,lockPath:t}=this,i=this.path.dirname(t);e.mkdirSync(i,{recursive:!0});try{e.mkdirSync(t)}catch(o){if(o.code!=="EEXIST")throw o;let a;try{a=e.statSync(t).mtimeMs}catch(l){if(l.code==="ENOENT")return this.acquire();throw l}if(Date.now()-a<5e3)throw new Q}let r=Date.now();if(r%1e3===0&&(r+=1),this.lockTime=r,this.touch(),this.get()%1e3===0&&(this.isMs=!1),this.set(),!this.verify())throw new Q;this.refreshTimer=setInterval(()=>this.set(),1e3)}release(){this.refreshTimer&&(clearInterval(this.refreshTimer),this.refreshTimer=null);try{this.verify()&&this.fs.rmdirSync(this.lockPath)}catch{}}set(){let e=Date.now();this.isMs||(e=Math.ceil(e/1e3)*1e3),this.lockTime=e,this.touch()}touch(){try{let e=this.lockTime/1e3;this.fs.utimesSync(this.lockPath,e,e)}catch{}}get(){try{return this.fs.statSync(this.lockPath).mtimeMs}catch{return 0}}verify(){return this.lockTime===this.get()}},Q=class extends Error{constructor(){super("Failed to acquire lock.")}};var L=new gi.Command,X="ob",{version:zi}=JSON.parse(E.default.readFileSync(D.default.join(__dirname,"package.json"),"utf-8"));L.name(X).description("Headless client for Obsidian services").version(zi);L.command("login").description("Login to Obsidian account or display login status").option("--email <email>","Email address (prompted if omitted)").option("--password <password>","Password (prompted if omitted)").option("--mfa <code>","MFA code (prompted if omitted)").action(async s=>{try{let e=J();if(e&&!s.email&&!s.password){let n=await ni(e);if(n){console.log(`Logged in as ${n.name} (${n.email})`);return}}if(e){try{await rt(e)}catch{}Ue()}let t=s.email||await fe("Email: ",!0),i=s.password||await fe("Password: "),r;try{r=await it(t,i,s.mfa||"")}catch(n){if(n instanceof se&&n.error.includes("2FA code")){if(n.error.includes("2FA code is incorrect"))throw n;let o=await fe("2FA code: ");r=await it(t,i,o)}else throw n}wt(r.token),console.log(`Logged in as ${r.name} (${r.email})`)}catch(e){console.error("Login failed:",e.message||e),process.exit(2)}});L.command("logout").description("Logout from Obsidian account").action(async()=>{try{let s=J();if(!s){console.log("No account logged in.");return}try{await rt(s)}catch{}Ue(),console.log("Logged out.")}catch(s){console.error("Logout failed:",s.message||s),process.exit(1)}});L.command("sync-list-remote").description("List available remote vaults").action(async()=>{try{let s=Oe();console.log("Fetching vaults...");let e=await nt(s,ct);if(e.vaults.length===0&&e.shared.length===0){console.log("No vaults found.");return}console.log(`
8
8
  Vaults:`);let t=i=>console.log(` ${i.id} "${i.name}" (${i.region})`);for(let i of e.vaults)t(i);if(e.shared.length>0){console.log(`
9
- Shared vaults:`);for(let i of e.shared)t(i)}}catch(s){console.error("Failed to list vaults:",s.message||s),process.exit(1)}});C.command("sync-list-local").description("List locally configured vaults").action(()=>{try{let s=qe();if(s.length===0){console.log("No vaults configured.");return}console.log("Configured vaults:");for(let e of s){let t=Ve(e);t&&(console.log(` ${e}`),console.log(` Path: ${t.vaultPath}`),console.log(` Host: ${t.host}`))}}catch(s){console.error("Failed to list vaults:",s.message||s),process.exit(1)}});C.command("sync-create-remote").description("Create a new remote vault").requiredOption("--name <name>","Vault name").option("--encryption <standard|e2ee>","Encryption").option("--password <encryption-password>","End-to-end encryption password (prompt if omitted)").option("--region <region>","Vault region (leave empty for automatic)").action(async s=>{try{let e=await Ne(),t=s.name,i=s.password;!i&&s.encryption!=="standard"&&(i=await pe("End-to-end encryption password (leave empty for standard encryption): "));let r=s.region||"";if(r){let c=(await ni(e)).regions;if(!c.some(u=>u.value===r)){console.error(`Invalid region: "${r}". Available regions:`);for(let u of c)console.error(` ${u.value} (${u.name})`);process.exit(1)}}console.log("Creating vault...");let n,o=null;if(i){n=R(crypto.getRandomValues(new Uint8Array(16)));let l=await ut(i,n);o=await ft(l,n,lt)}let a=await si(e,t,o,n,r,lt);console.log(`
9
+ Shared vaults:`);for(let i of e.shared)t(i)}}catch(s){console.error("Failed to list vaults:",s.message||s),process.exit(1)}});L.command("sync-list-local").description("List locally configured vaults").action(()=>{try{let s=We();if(s.length===0){console.log("No vaults configured.");return}console.log("Configured vaults:");for(let e of s){let t=je(e);t&&(console.log(` ${e}`),console.log(` Path: ${t.vaultPath}`),console.log(` Host: ${t.host}`))}}catch(s){console.error("Failed to list vaults:",s.message||s),process.exit(1)}});L.command("sync-create-remote").description("Create a new remote vault").requiredOption("--name <name>","Vault name").option("--encryption <standard|e2ee>","Encryption").option("--password <encryption-password>","End-to-end encryption password (prompt if omitted)").option("--region <region>","Vault region (leave empty for automatic)").action(async s=>{try{let e=Oe(),t=s.name,i=s.password;!i&&s.encryption!=="standard"&&(i=await fe("End-to-end encryption password (leave empty for standard encryption): "));let r=s.region||"";if(r){let u=(await si(e)).regions;if(!u.some(c=>c.value===r)){console.error(`Invalid region: "${r}". Available regions:`);for(let c of u)console.error(` ${c.value} (${c.name})`);process.exit(1)}}console.log("Creating vault...");let n,o=null;if(i){n=O(crypto.getRandomValues(new Uint8Array(16)));let l=await ft(i,n);o=await ht(l,n,ut)}let a=await oi(e,t,o,n,r,ut);console.log(`
10
10
  Vault created successfully!`),console.log(` Vault ID: ${a.id}`),console.log(` Vault name: ${a.name}`),console.log(` Region: ${a.region}`),console.log(` Encryption: ${i?"end-to-end":"managed"}`),console.log(`
11
- Run '${Z} sync-setup --vault "${a.id}"' to configure sync.`)}catch(e){console.error("Failed to create vault:",e.message||e),process.exit(1)}});C.command("sync-setup").description("Setup sync from a local path to a remote vault").requiredOption("--vault <vault>","Remote vault ID or name").option("--path <local-path>","Local vault path (use current directory if omitted)").option("--password <encryption-password>","End-to-end encryption password (prompted if omitted)").option("--device-name <name>","Device name to identify this client in the sync version history").option("--config-dir <name>","Config directory name (default: .obsidian)").action(async s=>{try{let e=await Ne(),t=s.vault,i=D.default.resolve(s.path||"."),r=s.password,n=s.deviceName||"",o=Ke(s.configDir);console.log("Fetching vault info...");let a=await rt(e,ct),l=[...a.vaults,...a.shared],c=l.find(b=>b.id===t);if(!c){let b=l.filter(y=>y.name===t);if(b.length===1)c=b[0];else if(b.length>1){console.error(`Multiple vaults named "${t}". Use the vault ID instead:`);for(let y of b)console.error(` ${y.id} "${y.name}"`);process.exit(1)}}c||(console.error(`Vault "${t}" not found.`),process.exit(3));let u=c.id;c.password?r=c.password:r||(r=await pe("End-to-end encryption password: ")),r||(console.error("Failed to validate password."),process.exit(2)),console.log("Setting up...");let p=await ut(r,c.salt),d=await ft(p,c.salt,c.encryption_version);try{await oi(e,u,d,c.host,c.encryption_version)}catch{console.error("Failed to validate password."),process.exit(2)}await I.setKey(u,{key:Gt(p),salt:c.salt,version:c.encryption_version});let F={vaultId:u,vaultName:c.name,vaultPath:i,host:c.host,conflictStrategy:"merge",deviceName:n,configDir:o};Ue(u),je(u,F),console.log(`
12
- Vault configured successfully!`),ht(F),P.default.existsSync(i)?P.default.readdirSync(i).filter(g=>!g.startsWith(".")).length>0&&(console.log(`
13
- Warning: Your local vault already contains some notes.`),console.log("If you start syncing, notes in your local vault will be merged with notes from your remote vault."),console.log("In case of conflicts, the most recent version of the note will be preserved.")):P.default.mkdirSync(i,{recursive:!0}),di(),console.log(`
14
- Run '${Z} sync' to start syncing.`)}catch(e){console.error("Setup failed:",e.message||e),process.exit(1)}});C.command("sync-config").description("Change sync configuration for a vault").option("--path <local-path>","Local vault path (use current directory if omitted)").option("--conflict-strategy <strategy>","Conflict resolution strategy (merge or conflict)").option("--excluded-folders <folders>","Folders to exclude, comma-separated (empty string to clear)").option("--file-types <types>","Attachment types to sync, comma-separated: image, audio, video, pdf, unsupported (empty to clear)").option("--configs <settings>","Config categories to sync, comma-separated: app, appearance, appearance-data, hotkey, core-plugin, core-plugin-data, community-plugin, community-plugin-data (empty to clear)").option("--device-name <name>","Device name to identify this client in the sync version history").option("--config-dir <name>","Config directory name (default: .obsidian)").action(s=>{try{let e=D.default.resolve(s.path||"."),t=te(e);t||(console.error(`No sync configuration found for ${e}`),console.error(`Run '${Z} sync-setup' first.`),process.exit(3));let i=!1;s.conflictStrategy!==void 0&&(s.conflictStrategy!=="merge"&&s.conflictStrategy!=="conflict"&&(console.error(`Invalid conflict strategy: "${s.conflictStrategy}". Must be "merge" or "conflict".`),process.exit(1)),t.conflictStrategy=s.conflictStrategy,i=!0),s.excludedFolders!==void 0&&(s.excludedFolders===""?delete t.ignoreFolders:t.ignoreFolders=s.excludedFolders.split(",").map(r=>r.trim()),i=!0),s.fileTypes!==void 0&&(s.fileTypes===""?delete t.allowTypes:t.allowTypes=Pt(s.fileTypes),i=!0),s.configs!==void 0&&(s.configs===""?delete t.allowSpecialFiles:t.allowSpecialFiles=At(s.configs),i=!0),s.deviceName!==void 0&&(t.deviceName=s.deviceName,i=!0),s.configDir!==void 0&&(t.configDir=Ke(s.configDir),i=!0),i?(je(t.vaultId,t),console.log("Configuration updated:")):console.log("No options provided. Current configuration:"),ht(t)}catch(e){console.error("Config update failed:",e.message||e),process.exit(1)}});C.command("sync-status").description("Show sync status for a vault").option("--path <local-path>","Local vault path (use current directory if omitted)").action(async s=>{try{let e=D.default.resolve(s.path||"."),t=te(e);t||(console.error(`No sync configuration found for ${e}`),process.exit(3)),await I.getToken()||console.log("Not logged in."),await I.getKey(t.vaultId)||console.log("End-to-end encryption key missing."),console.log("Sync Configuration:"),ht(t)}catch(e){console.error("Status check failed:",e.message||e),process.exit(1)}});C.command("sync-unlink").description("Disconnect a vault from sync and remove stored credentials").option("--path <local-path>","Local vault path (use current directory if omitted)").action(async s=>{try{let e=D.default.resolve(s.path||"."),t=te(e);t||(console.error(`No sync configuration found for ${e}`),process.exit(3)),await I.deleteKey(t.vaultId),Dt(t.vaultId),console.log(`Sync configuration removed for ${e}`)}catch(e){console.error("Unlink failed:",e.message||e),process.exit(1)}});C.command("sync").description("Sync a vault").option("--path <local-path>","Local vault path (use current directory if omitted)").option("--continuous","Run in continuous sync mode").action(async s=>{try{let e=D.default.resolve(s.path||"."),t=te(e);t||(console.error(`No sync configuration found for ${e}`),console.error(`Run '${Z} sync-setup' first.`),process.exit(3));let i=await Ne(),r=await I.getKey(t.vaultId);r||(console.error("Encryption key not found. Run setup again."),process.exit(2));let n=await hi(r.version,$t(r.key),r.salt),o=wt(t.vaultId),a=new de(o),l=_t(vt(t.vaultId));t.deviceName||(t.deviceName=We()),(!t.configDir||!t.configDir.startsWith("."))&&(t.configDir=".obsidian"),di();let c=new Re(P.default,D.default,St(t.vaultPath,t.configDir));c.acquire();let u;try{u=new Le({config:t,token:i,encryption:n,stateStore:a,continuous:s.continuous});let p=()=>{console.log(`
15
- Shutting down...`),u.stop(),c.release(),l(),process.exit(0)};process.on("SIGINT",p),process.on("SIGTERM",p),await u.sync()}finally{u?.stop(),c.release(),l()}process.exit(0)}catch(e){e instanceof J&&(console.error("Another sync instance is already running for this vault."),process.exit(1)),console.error("Sync failed:",e),process.exit(1)}});function ht(s){console.log(` Vault: ${s.vaultName} (${s.vaultId})`),console.log(` Local path: ${s.vaultPath}`),console.log(` Conflict strategy: ${s.conflictStrategy}`),console.log(` Device name: ${s.deviceName||We()}`),s.configDir&&console.log(` Config directory: ${s.configDir}`);let{allowTypes:e,allowSpecialFiles:t,ignoreFolders:i}=s;console.log(` File types: ${(e||G).join(", ")}`),console.log(` Configs: ${t?.length===0?"none (config syncing disabled)":(t||z).join(", ")}`),i&&i.length>0&&console.log(` Excluded folders: ${i.join(", ")}`)}function pe(s,e){return new Promise(t=>{if(process.stdin.isTTY){process.stdout.write(s),process.stdin.setRawMode(!0),process.stdin.resume();let i="",r=()=>{process.stdout.clearLine(0),process.stdout.cursorTo(0),process.stdout.write(s+(e?i:"*".repeat(i.length)))},n=o=>{let a=o.toString();a===`
11
+ Run '${X} sync-setup --vault "${a.id}"' to configure sync.`)}catch(e){console.error("Failed to create vault:",e.message||e),process.exit(1)}});L.command("sync-setup").description("Setup sync from a local path to a remote vault").requiredOption("--vault <vault>","Remote vault ID or name").option("--path <local-path>","Local vault path (use current directory if omitted)").option("--password <encryption-password>","End-to-end encryption password (prompted if omitted)").option("--device-name <name>","Device name to identify this client in the sync version history").option("--config-dir <name>","Config directory name (default: .obsidian)").action(async s=>{try{let e=Oe(),t=s.vault,i=D.default.resolve(s.path||"."),r=s.password,n=s.deviceName||"",o=Ke(s.configDir);console.log("Fetching vault info...");let a=await nt(e,ct),l=[...a.vaults,...a.shared],u=l.find(b=>b.id===t);if(!u){let b=l.filter(y=>y.name===t);if(b.length===1)u=b[0];else if(b.length>1){console.error(`Multiple vaults named "${t}". Use the vault ID instead:`);for(let y of b)console.error(` ${y.id} "${y.name}"`);process.exit(1)}}u||(console.error(`Vault "${t}" not found.`),process.exit(3));let c=u.id;u.password?r=u.password:r||(r=await fe("End-to-end encryption password: ")),r||(console.error("Failed to validate password."),process.exit(2)),console.log("Setting up...");let p=await ft(r,u.salt),d=await ht(p,u.salt,u.encryption_version);try{await ai(e,c,d,u.host,u.encryption_version)}catch{console.error("Failed to validate password."),process.exit(2)}let F={vaultId:c,vaultName:u.name,vaultPath:i,host:u.host,encryptionVersion:u.encryption_version,encryptionKey:Qt(p),encryptionSalt:u.salt,conflictStrategy:"merge",deviceName:n,configDir:o};Ve(c),qe(c,F),console.log(`
12
+ Vault configured successfully!`),pt(F),E.default.existsSync(i)?E.default.readdirSync(i).filter(g=>!g.startsWith(".")).length>0&&(console.log(`
13
+ Warning: Your local vault already contains some notes.`),console.log("If you start syncing, notes in your local vault will be merged with notes from your remote vault."),console.log("In case of conflicts, the most recent version of the note will be preserved.")):E.default.mkdirSync(i,{recursive:!0}),di(),console.log(`
14
+ Run '${X} sync' to start syncing.`)}catch(e){console.error("Setup failed:",e.message||e),process.exit(1)}});L.command("sync-config").description("Change sync configuration for a vault").option("--path <local-path>","Local vault path (use current directory if omitted)").option("--conflict-strategy <strategy>","Conflict resolution strategy (merge or conflict)").option("--excluded-folders <folders>","Folders to exclude, comma-separated (empty string to clear)").option("--file-types <types>","Attachment types to sync, comma-separated: image, audio, video, pdf, unsupported (empty to clear)").option("--configs <settings>","Config categories to sync, comma-separated: app, appearance, appearance-data, hotkey, core-plugin, core-plugin-data, community-plugin, community-plugin-data (empty to clear)").option("--device-name <name>","Device name to identify this client in the sync version history").option("--config-dir <name>","Config directory name (default: .obsidian)").action(s=>{try{let e=D.default.resolve(s.path||"."),t=z(e);t||(console.error(`No sync configuration found for ${e}`),console.error(`Run '${X} sync-setup' first.`),process.exit(3));let i=!1;s.conflictStrategy!==void 0&&(s.conflictStrategy!=="merge"&&s.conflictStrategy!=="conflict"&&(console.error(`Invalid conflict strategy: "${s.conflictStrategy}". Must be "merge" or "conflict".`),process.exit(1)),t.conflictStrategy=s.conflictStrategy,i=!0),s.excludedFolders!==void 0&&(s.excludedFolders===""?delete t.ignoreFolders:t.ignoreFolders=s.excludedFolders.split(",").map(r=>r.trim()),i=!0),s.fileTypes!==void 0&&(s.fileTypes===""?delete t.allowTypes:t.allowTypes=At(s.fileTypes),i=!0),s.configs!==void 0&&(s.configs===""?delete t.allowSpecialFiles:t.allowSpecialFiles=_t(s.configs),i=!0),s.deviceName!==void 0&&(t.deviceName=s.deviceName,i=!0),s.configDir!==void 0&&(t.configDir=Ke(s.configDir),i=!0),i?(qe(t.vaultId,t),console.log("Configuration updated:")):console.log("No options provided. Current configuration:"),pt(t)}catch(e){console.error("Config update failed:",e.message||e),process.exit(1)}});L.command("sync-status").description("Show sync status for a vault").option("--path <local-path>","Local vault path (use current directory if omitted)").action(async s=>{try{let e=D.default.resolve(s.path||"."),t=z(e);t||(console.error(`No sync configuration found for ${e}`),process.exit(3)),J()||console.log("Not logged in."),t.encryptionKey||console.log("End-to-end encryption key missing. Run setup again."),console.log("Sync Configuration:"),pt(t)}catch(e){console.error("Status check failed:",e.message||e),process.exit(1)}});L.command("sync-unlink").description("Disconnect a vault from sync and remove stored credentials").option("--path <local-path>","Local vault path (use current directory if omitted)").action(async s=>{try{let e=D.default.resolve(s.path||"."),t=z(e);t||(console.error(`No sync configuration found for ${e}`),process.exit(3)),Pt(t.vaultId),console.log(`Sync configuration removed for ${e}`)}catch(e){console.error("Unlink failed:",e.message||e),process.exit(1)}});L.command("sync").description("Sync a vault").option("--path <local-path>","Local vault path (use current directory if omitted)").option("--continuous","Run in continuous sync mode").action(async s=>{try{let e=D.default.resolve(s.path||"."),t=z(e);t||(console.error(`No sync configuration found for ${e}`),console.error(`Run '${X} sync-setup' first.`),process.exit(3));let i=Oe();(!t.encryptionKey||!t.encryptionSalt||t.encryptionVersion==null)&&(console.error("Encryption key not found. Run setup again."),process.exit(2));let r=await pi(t.encryptionVersion,$t(t.encryptionKey),t.encryptionSalt),n=Tt(St(t.vaultId));t.deviceName||(t.deviceName=He()),(!t.configDir||!t.configDir.startsWith("."))&&(t.configDir=".obsidian"),di();let o=new Ce(E.default,D.default,Dt(t.vaultPath,t.configDir));o.acquire();let a;try{a=new xe({config:t,token:i,encryption:r,continuous:s.continuous});let l=()=>{console.log(`
15
+ Received signal to shut down...`),a.stop()};process.on("SIGINT",l),process.on("SIGTERM",l),await a.sync()}catch{a?.stop()}finally{o.release(),n()}process.exit(0)}catch(e){e instanceof Q&&(console.error("Another sync instance is already running for this vault."),process.exit(1)),console.error("Sync failed:",e),process.exit(1)}});function pt(s){console.log(` Vault: ${s.vaultName} (${s.vaultId})`),console.log(` Local path: ${s.vaultPath}`),console.log(` Conflict strategy: ${s.conflictStrategy}`),console.log(` Device name: ${s.deviceName||He()}`),s.configDir&&console.log(` Config directory: ${s.configDir}`);let{allowTypes:e,allowSpecialFiles:t,ignoreFolders:i}=s;console.log(` File types: ${(e||K).join(", ")}`),console.log(` Configs: ${t?.length===0?"none (config syncing disabled)":(t||[]).join(", ")}`),i&&i.length>0&&console.log(` Excluded folders: ${i.join(", ")}`)}function fe(s,e){return new Promise(t=>{if(process.stdin.isTTY){process.stdout.write(s),process.stdin.setRawMode(!0),process.stdin.resume();let i="",r=()=>{process.stdout.clearLine(0),process.stdout.cursorTo(0),process.stdout.write(s+(e?i:"*".repeat(i.length)))},n=o=>{let a=o.toString();a===`
16
16
  `||a==="\r"?(process.stdin.setRawMode(!1),process.stdin.pause(),process.stdin.removeListener("data",n),process.stdout.write(`
17
- `),t(i)):a===""?(process.stdin.setRawMode(!1),process.exit(1)):a==="\x7F"||a==="\b"?(i=i.slice(0,-1),r()):(i+=a,process.stdout.write(e?a:"*".repeat(a.length)))};process.stdin.on("data",n)}else{let i="";process.stdin.setEncoding("utf-8"),process.stdin.on("data",r=>{i+=r}),process.stdin.on("end",()=>{t(i.trimEnd())}),process.stdin.resume()}})}function di(){(process.platform==="win32"||process.platform==="darwin")&&!mt()&&console.warn("Warning: btime native module failed to load. File creation times will not be preserved.")}async function Ne(){let s=await I.getToken();return s||(console.error(`No account logged in. Run "${Z} login" first.`),process.exit(2)),s}C.parse();
17
+ `),t(i)):a===""?(process.stdin.setRawMode(!1),process.exit(1)):a==="\x7F"||a==="\b"?(i=i.slice(0,-1),r()):(i+=a,process.stdout.write(e?a:"*".repeat(a.length)))};process.stdin.on("data",n)}else{let i="";process.stdin.setEncoding("utf-8"),process.stdin.on("data",r=>{i+=r}),process.stdin.on("end",()=>{t(i.trimEnd())}),process.stdin.resume()}})}function di(){(process.platform==="win32"||process.platform==="darwin")&&!mt()&&console.warn("Warning: btime native module failed to load. File creation times will not be preserved.")}function Oe(){let s=J();return s||(console.error(`No account logged in. Run "${X} login" first.`),process.exit(2)),s}L.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "obsidian-headless",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Headless client for Obsidian services",
5
5
  "main": "cli.js",
6
6
  "bin": {
@@ -40,7 +40,6 @@
40
40
  "license": "UNLICENSED",
41
41
  "dependencies": {
42
42
  "better-sqlite3": "12.6.2",
43
- "commander": "14.0.3",
44
- "keytar": "7.9.0"
43
+ "commander": "14.0.3"
45
44
  }
46
45
  }